diff --git a/browser/base/content/test/general/browser_parsable_css.js b/browser/base/content/test/general/browser_parsable_css.js index 47cd72115e8e..e4af70932d99 100644 --- a/browser/base/content/test/general/browser_parsable_css.js +++ b/browser/base/content/test/general/browser_parsable_css.js @@ -16,6 +16,9 @@ let whitelist = [ // The debugger uses cross-browser CSS. {sourceName: /devtools\/client\/debugger\/new\/styles.css/i, isFromDevTools: true}, + // reps uses cross-browser CSS. + {sourceName: /devtools\/client\/shared\/components\/reps.css/i, + isFromDevTools: true}, // PDFjs is futureproofing its pseudoselectors, and those rules are dropped. {sourceName: /web\/viewer\.css$/i, errorMessage: /Unknown pseudo-class.*(fullscreen|selection)/i, diff --git a/devtools/client/preferences/devtools.js b/devtools/client/preferences/devtools.js index 2f5deda86fa4..a0147b29ddb8 100644 --- a/devtools/client/preferences/devtools.js +++ b/devtools/client/preferences/devtools.js @@ -324,6 +324,9 @@ pref("devtools.webconsole.new-frontend-enabled", true); pref("devtools.webconsole.new-frontend-enabled", false); #endif +// Enable loading reps from a bundle +pref("devtools.webconsole.use-reps-bundle", false); + // Enable the experimental support for source maps in console (work in progress) pref("devtools.sourcemap.locations.enabled", false); diff --git a/devtools/client/shared/components/moz.build b/devtools/client/shared/components/moz.build index 0d67e90b553a..24a48fbb4dfe 100644 --- a/devtools/client/shared/components/moz.build +++ b/devtools/client/shared/components/moz.build @@ -16,6 +16,8 @@ DevToolsModules( 'h-split-box.js', 'notification-box.css', 'notification-box.js', + 'reps.css', + 'reps.js', 'search-box.js', 'sidebar-toggle.css', 'sidebar-toggle.js', diff --git a/devtools/client/shared/components/reps.css b/devtools/client/shared/components/reps.css new file mode 100644 index 000000000000..9f7138548a5d --- /dev/null +++ b/devtools/client/shared/components/reps.css @@ -0,0 +1,533 @@ +/* vim:set ts=2 sw=2 sts=2 et: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +.theme-dark, +.theme-light { + --number-color: var(--theme-highlight-green); + --string-color: var(--theme-highlight-orange); + --null-color: var(--theme-comment); + --object-color: var(--theme-body-color); + --caption-color: var(--theme-highlight-blue); + --location-color: var(--theme-content-color1); + --source-link-color: var(--theme-highlight-blue); + --node-color: var(--theme-highlight-bluegrey); + --reference-color: var(--theme-highlight-purple); +} + +.theme-firebug { + --number-color: #000088; + --string-color: #FF0000; + --null-color: #787878; + --object-color: DarkGreen; + --caption-color: #444444; + --location-color: #555555; + --source-link-color: blue; + --node-color: rgb(0, 0, 136); + --reference-color: rgb(102, 102, 255); +} + +/******************************************************************************/ + +.objectLink:hover { + cursor: pointer; + text-decoration: underline; +} + +.inline { + display: inline; + white-space: normal; +} + +.objectBox-object { + font-weight: bold; + color: var(--object-color); + white-space: pre-wrap; +} + +.objectBox-string, +.objectBox-text, +.objectLink-textNode, +.objectBox-table { + white-space: pre-wrap; +} + +.objectBox-number, +.objectLink-styleRule, +.objectLink-element, +.objectLink-textNode, +.objectBox-array > .length { + color: var(--number-color); +} + +.objectBox-string { + color: var(--string-color); +} + +.objectLink-function, +.objectBox-stackTrace, +.objectLink-profile { + color: var(--object-color); +} + +.objectLink-Location { + font-style: italic; + color: var(--location-color); +} + +.objectBox-null, +.objectBox-undefined, +.objectBox-hint, +.logRowHint { + font-style: italic; + color: var(--null-color); +} + +.objectLink-sourceLink { + position: absolute; + right: 4px; + top: 2px; + padding-left: 8px; + font-weight: bold; + color: var(--source-link-color); +} + +/******************************************************************************/ + +.objectLink-event, +.objectLink-eventLog, +.objectLink-regexp, +.objectLink-object, +.objectLink-Date { + font-weight: bold; + color: var(--object-color); + white-space: pre-wrap; +} + +/******************************************************************************/ + +.objectLink-object .nodeName, +.objectLink-NamedNodeMap .nodeName, +.objectLink-NamedNodeMap .objectEqual, +.objectLink-NamedNodeMap .arrayLeftBracket, +.objectLink-NamedNodeMap .arrayRightBracket, +.objectLink-Attr .attrEqual, +.objectLink-Attr .attrTitle { + color: var(--node-color); +} + +.objectLink-object .nodeName { + font-weight: normal; +} + +/******************************************************************************/ + +.objectLeftBrace, +.objectRightBrace, +.arrayLeftBracket, +.arrayRightBracket { + cursor: pointer; + font-weight: bold; +} + +.objectLeftBrace, +.arrayLeftBracket { + margin-right: 4px; +} + +.objectRightBrace, +.arrayRightBracket { + margin-left: 4px; +} + +/******************************************************************************/ +/* Cycle reference*/ + +.objectLink-Reference { + font-weight: bold; + color: var(--reference-color); +} + +.objectBox-array > .objectTitle { + font-weight: bold; + color: var(--object-color); +} + +.caption { + font-weight: bold; + color: var(--caption-color); +} + +/******************************************************************************/ +/* Themes */ + +.theme-dark .objectBox-null, +.theme-dark .objectBox-undefined, +.theme-light .objectBox-null, +.theme-light .objectBox-undefined { + font-style: normal; +} + +.theme-dark .objectBox-object, +.theme-light .objectBox-object { + font-weight: normal; + white-space: pre-wrap; +} + +.theme-dark .caption, +.theme-light .caption { + font-weight: normal; +} +:root.theme-light, +:root .theme-light { + --theme-search-overlays-semitransparent: rgba(221, 225, 228, 0.66); +} + +* { + box-sizing: border-box; +} + +html, +body { + height: 100%; + margin: 0; + padding: 0; + width: 100%; +} + +#mount { + display: flex; + height: 100%; +} + +::-webkit-scrollbar { + width: 8px; + height: 8px; + background: transparent; +} + +::-webkit-scrollbar-track { + border-radius: 8px; + background: transparent; +} + +::-webkit-scrollbar-thumb { + border-radius: 8px; + background: rgba(113, 113, 113, 0.5); +} + +:root.theme-dark .CodeMirror-scrollbar-filler { + background: transparent; +} +.landing-page { + flex: 1; + display: flex; + width: 100vw; + height: 100vh; + flex-direction: row; + align-items: stretch; + /* Customs properties */ + --title-font-size: 24px; + --ui-element-font-size: 16px; + --primary-line-height: 30px; + --secondary-line-height: 25px; + --base-spacing: 20px; + --base-transition: all 0.25s ease; +} + +.landing-page .sidebar { + display: flex; + background-color: var(--theme-tab-toolbar-background); + width: 200px; + flex-direction: column; + border-right: 1px solid var(--theme-splitter-color); +} + +.landing-page .sidebar h1 { + color: var(--theme-body-color); + font-size: var(--title-font-size); + margin: 0; + line-height: var(--primary-line-height); + font-weight: normal; + padding: calc(2 * var(--base-spacing)) var(--base-spacing); +} + +.landing-page .sidebar ul { + list-style: none; + padding: 0; + line-height: var(--primary-line-height); + font-size: var(--ui-element-font-size); +} + +.landing-page .sidebar li { + padding: calc(var(--base-spacing) / 4) var(--base-spacing); +} + +.landing-page .sidebar li a { + color: var(--theme-body-color); +} + +.landing-page .sidebar li.selected { + background: var(--theme-highlight-bluegrey); + color: var(--theme-selection-color); + transition: var(--base-transition); +} + +.landing-page .sidebar li.selected a { + color: inherit; +} + +.landing-page .sidebar li:hover, +.landing-page .sidebar li:focus { + background: var(--theme-selection-background); + color: var(--theme-selection-color); + cursor: pointer; +} + +.landing-page .sidebar li:hover a, +.landing-page .sidebar li:focus a { + color: inherit; +} + +.landing-page .panel { + display: flex; + flex: 1; + flex-direction: column; + justify-content: space-between; +} + +.landing-page .panel header { + display: flex; + align-items: baseline; + margin: calc(2 * var(--base-spacing)) 0 0; + padding-bottom: var(--base-spacing); +} + +.landing-page .panel header input { + flex: 1; + color: var(--theme-body-color); + font-size: var(--ui-element-font-size); + border: 1px solid var(--theme-splitter-color); + padding: calc(var(--base-spacing) / 2); + margin: 0 var(--base-spacing); + transition: var(--base-transition); +} + +.landing-page .panel header input:focus { + border: 1px solid var(--theme-selection-background); +} + +.landing-page .panel .center-message { + font-size: var(--ui-element-font-size); + line-height: var(--secondary-line-height); + padding: calc(var(--base-spacing) / 2); +} + +.landing-page .center a { + color: var(--theme-highlight-bluegrey); + text-decoration: none; +} + +.landing-page .tab-group { + flex: 1; + overflow-y: auto; +} + +.landing-page .tab-list { + list-style: none; + padding: 0; + margin: 0; +} + +.landing-page .tab { + border-bottom: 1px solid var(--theme-splitter-color); + padding: calc(var(--base-spacing) / 2) var(--base-spacing); + font-family: sans-serif; +} + +.landing-page .tab-title { + line-height: var(--secondary-line-height); + font-size: var(--ui-element-font-size); + color: var(--theme-highlight-bluegrey); + word-break: break-all; +} + +.landing-page .tab-url { + color: var(--theme-comment); + word-break: break-all; +} + +.landing-page .tab:focus, +.landing-page .tab.active { + background: var(--theme-selection-background); + color: var(--theme-selection-color); + cursor: pointer; + transition: var(--base-transition); +} + +.landing-page .tab:focus .tab-title, +.landing-page .tab.active .tab-title { + color: inherit; +} + +.landing-page .tab:focus .tab-url, +.landing-page .tab.active .tab-url { + color: var(--theme-highlight-gray); +} + +.landing-page .panel .footer-note { + padding: var(--base-spacing) 0; + text-align: center; + font-size: 14px; + color: var(--theme-comment); +} +.quick-links { + display: flex; + justify-content: center; + flex-wrap: wrap; + background: rgba(255,255,255,0.25); + padding: 0.5rem 1rem; +} + +.quick-links button { + font-size: 1.2rem; + background: none; + border: none; + color: white; + margin: 0.5rem 0.25rem; + cursor: pointer; +} +.console-header { + background: var(--theme-highlight-pink); + color: white; + margin: 0; +} + +.console-header form { + display: flex; + padding: 1rem; +} + +.console-header h1 { + font-size: 14px; + font-weight: 100; + color: white; +} + +.console-header input { + background-color: var(--theme-highlight-pink); + flex: 1; + border: 1px solid white; + color: white; + font-size: 1.25rem; + padding: 0.25rem; + line-height: 2rem; + padding-left: 1rem; + margin: 0 1rem; +} + +.console-header ::-webkit-input-placeholder { + color: white; + font-size: 1rem; + line-height: 2rem; + margin: 0; +} + +.console-header .clear-button { + background: rgba(255,255,255,0.25); + border: 1px solid rgba(255,255,255,0.25); + color: white; + font-size: 1.2rem; +} +main { + --default-border: 1px solid var(--theme-splitter-color); + height: 100vh; + display: flex; + flex-direction: column; +} + +.expressions { + padding: 2em 1em; + flex: 1; + overflow-y: auto; +} + +.rep-row { + border: var(--default-border); + margin-bottom: 1em; +} + +.rep-input { + font-family: monospace; + background-color: var(--theme-toolbar-background-alt); + color: var(--theme-body-color); + padding: 0.5rem; +} + +.rep-input:before { + content: "\279C "; +} + +.reps { + display: flex; + flex-wrap: wrap; + padding: 1rem; + margin-bottom: 0.5rem; +} + +.rep-element + .rep-element { + margin-left: 0.5rem; +} + +.rep-element::before { + content: attr(data-mode) ":"; + background-color: var(--theme-toolbar-background);; + font-family: monospace; + display: inline-block; + font-size: 0.75rem; + padding: 0.1rem 0.25rem; + margin-right: 0.25rem; + border-radius: 0.25rem; +} + +.packet header { + display: flex; + background-color: var(--theme-toolbar-background-alt); + border-top: var(--default-border); + color: var(--theme-body-color); + padding: 0.5rem; +} + +.packet header::before { + display: inline-block; + padding-right: 0.5rem; +} + +.packet header.packet-expanded::before { + content: "\2212"; +} + +.packet header.packet-collapsed::before { + content: "+"; +} + +.copy-packet-button { + margin-left: auto; + margin-right: 0.5rem; +} + +.packet .packet-rep { + padding: 1rem; +} + +* { + box-sizing: border-box; +} + +html, body { + margin: 0; + padding: 0; +} + +/*# sourceMappingURL=bundle.css.map*/ \ No newline at end of file diff --git a/devtools/client/shared/components/reps.js b/devtools/client/shared/components/reps.js new file mode 100644 index 000000000000..c7e511ea0b38 --- /dev/null +++ b/devtools/client/shared/components/reps.js @@ -0,0 +1,35193 @@ +module.exports = +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // SingleModulePlugin +/******/ const smpCache = this.smpCache = this.smpCache || {}; +/******/ const smpMap = this.smpMap = this.smpMap || new Map(); +/******/ function sanitizeString(text) { +/******/ return text.replace(/__webpack_require__\(\d+\)/g,""); +/******/ } +/******/ function getModuleBody(id) { +/******/ if (smpCache.hasOwnProperty(id)) { +/******/ return smpCache[id]; +/******/ } +/******/ +/******/ const body = sanitizeString(String(modules[id])); +/******/ smpCache[id] = body; +/******/ return body; +/******/ } +/******/ if (!installedModules[moduleId]) { +/******/ const body = getModuleBody(moduleId); +/******/ if (smpMap.has(body)) { +/******/ installedModules[moduleId] = installedModules[smpMap.get(body)]; +/******/ } +/******/ else { +/******/ smpMap.set(body, moduleId) +/******/ } +/******/ } +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = "/assets/build"; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(1); + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + // require("./webconsole.css") + __webpack_require__(2); + + const React = __webpack_require__(6); + const ReactDOM = __webpack_require__(7); + const { createFactory } = React; + + const { bootstrap, L10N } = __webpack_require__(9); + const { isFirefoxPanel } = __webpack_require__(102); + + if (!isFirefoxPanel()) { + const { Provider } = __webpack_require__(29); + + const RepsConsole = createFactory(__webpack_require__(255)); + const { configureStore } = __webpack_require__(306); + + __webpack_require__(311); + L10N.setBundle(__webpack_require__(313)); + window.l10n = L10N; + + function onConnect({ client } = {}) { + if (!client) { + return; + } + + let store = configureStore({ + makeThunkArgs: (args, state) => { + return Object.assign({}, args, { client }); + } + }); + + ReactDOM.render(React.createElement(Provider, { store }, RepsConsole({ client })), root); + } + + let root = document.createElement("div"); + root.innerText = "Waiting for connection"; + + bootstrap(React, ReactDOM, root).then(onConnect, e => console.error("An error occured during the connection", e)).catch(e => console.error("An error occured in the onConnect function", e)); + } else { + const { MODE } = __webpack_require__(266); + const Rep = createFactory(__webpack_require__(267)); + const Grip = __webpack_require__(278); + const repUtils = __webpack_require__(305); + + module.exports = { + Rep, + Grip, + repUtils, + MODE + }; + } + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + // removed by extract-text-webpack-plugin + +/***/ }, +/* 3 */, +/* 4 */, +/* 5 */, +/* 6 */ +/***/ function(module, exports) { + + module.exports = require("devtools/client/shared/vendor/react"); + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + module.exports = __webpack_require__(8); + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + module.exports = require("devtools/client/shared/vendor/react-dom"); + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + /* global window, document, DebuggerConfig */ + + const { bindActionCreators, combineReducers } = __webpack_require__(10); + const { Provider } = __webpack_require__(29); + + const { DevToolsUtils, AppConstants } = __webpack_require__(38); + const { debugGlobal } = __webpack_require__(101); + const { setConfig, isEnabled, getValue, isDevelopment } = __webpack_require__(102); + const L10N = __webpack_require__(150); + + setConfig(({"title":"Reps","hotReloading":true,"environment":"development","theme":"light","firefox":{"proxyHost":"localhost:9000","webSocketConnection":false,"websocketHost":"localhost:6080","mcPath":"./firefox"},"development":{"serverPort":8000}})); + + // Set various flags before requiring app code. + if (isEnabled("logging.client")) { + DevToolsUtils.dumpn.wantLogging = true; + } + + const { getClient, firefox, chrome, startDebugging } = __webpack_require__(151); + const Root = __webpack_require__(220); + + // Using this static variable allows webpack to know at compile-time + // to avoid this require and not include it at all in the output. + if (false) { + const theme = getValue("theme"); + switch (theme) { + case "dark": + require("./lib/themes/dark-theme.css");break; + case "light": + require("./lib/themes/light-theme.css");break; + case "firebug": + require("./lib/themes/firebug-theme.css");break; + } + document.body.parentNode.classList.add(`theme-${ theme }`); + } + + function initApp() { + const configureStore = __webpack_require__(224); + const reducers = __webpack_require__(235); + const LaunchpadApp = __webpack_require__(240); + + const createStore = configureStore({ + log: getValue("logging.actions"), + makeThunkArgs: (args, state) => { + return Object.assign({}, args, { client: getClient(state) }); + } + }); + + const store = createStore(combineReducers(reducers)); + const actions = bindActionCreators(__webpack_require__(253), store.dispatch); + + debugGlobal("launchpadStore", store); + + if (isDevelopment()) { + AppConstants.DEBUG_JS_MODULES = true; + } + + return { store, actions, LaunchpadApp }; + } + + function renderRoot(_React, _ReactDOM, component, _store) { + const { createElement } = _React; + const mount = document.querySelector("#mount"); + + // bail in test environments that do not have a mount + if (!mount) { + return; + } + + const root = Root(); + mount.appendChild(root); + + if (component.props || component.propTypes) { + _ReactDOM.render(createElement(Provider, { store: _store }, createElement(component)), root); + } else { + root.appendChild(component); + } + } + + function getTargetFromQuery() { + const href = window.location.href; + const nodeMatch = href.match(/node-tab=([^&#]*)/); + const firefoxMatch = href.match(/firefox-tab=([^&#]*)/); + const chromeMatch = href.match(/chrome-tab=([^&#]*)/); + + if (nodeMatch) { + return { type: "node", param: nodeMatch[1] }; + } else if (firefoxMatch) { + return { type: "firefox", param: firefoxMatch[1] }; + } else if (chromeMatch) { + return { type: "chrome", param: chromeMatch[1] }; + } + + return null; + } + + function bootstrap(React, ReactDOM, App, appActions, appStore) { + const connTarget = getTargetFromQuery(); + if (connTarget) { + return startDebugging(connTarget, appActions).then(({ tab, client }) => { + debugGlobal("client", client.clientCommands); + renderRoot(React, ReactDOM, App, appStore); + return { tab, connTarget, client }; + }); + } + + const { store, actions, LaunchpadApp } = initApp(); + renderRoot(React, ReactDOM, LaunchpadApp, store); + chrome.connectClient().then(tabs => { + actions.newTabs(tabs); + }).catch(e => { + console.log("Connect to chrome:"); + console.log("https://github.com/devtools-html/debugger.html/blob/master/CONTRIBUTING.md#chrome"); + }); + + chrome.connectNodeClient().then(tabs => { + actions.newTabs(tabs); + }); + + return firefox.connectClient().then(tabs => { + actions.newTabs(tabs); + }); + } + + module.exports = { + bootstrap, + renderRoot, + debugGlobal, + L10N + }; + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined; + + var _createStore = __webpack_require__(11); + + var _createStore2 = _interopRequireDefault(_createStore); + + var _combineReducers = __webpack_require__(24); + + var _combineReducers2 = _interopRequireDefault(_combineReducers); + + var _bindActionCreators = __webpack_require__(26); + + var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators); + + var _applyMiddleware = __webpack_require__(27); + + var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware); + + var _compose = __webpack_require__(28); + + var _compose2 = _interopRequireDefault(_compose); + + var _warning = __webpack_require__(25); + + var _warning2 = _interopRequireDefault(_warning); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + /* + * This is a dummy function to check if the function name has been altered by minification. + * If the function has been minified and NODE_ENV !== 'production', warn the user. + */ + function isCrushed() {} + + if (false) { + (0, _warning2["default"])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.'); + } + + exports.createStore = _createStore2["default"]; + exports.combineReducers = _combineReducers2["default"]; + exports.bindActionCreators = _bindActionCreators2["default"]; + exports.applyMiddleware = _applyMiddleware2["default"]; + exports.compose = _compose2["default"]; + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports.ActionTypes = undefined; + exports["default"] = createStore; + + var _isPlainObject = __webpack_require__(12); + + var _isPlainObject2 = _interopRequireDefault(_isPlainObject); + + var _symbolObservable = __webpack_require__(22); + + var _symbolObservable2 = _interopRequireDefault(_symbolObservable); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + /** + * These are private action types reserved by Redux. + * For any unknown actions, you must return the current state. + * If the current state is undefined, you must return the initial state. + * Do not reference these action types directly in your code. + */ + var ActionTypes = exports.ActionTypes = { + INIT: '@@redux/INIT' + }; + + /** + * Creates a Redux store that holds the state tree. + * The only way to change the data in the store is to call `dispatch()` on it. + * + * There should only be a single store in your app. To specify how different + * parts of the state tree respond to actions, you may combine several reducers + * into a single reducer function by using `combineReducers`. + * + * @param {Function} reducer A function that returns the next state tree, given + * the current state tree and the action to handle. + * + * @param {any} [initialState] The initial state. You may optionally specify it + * to hydrate the state from the server in universal apps, or to restore a + * previously serialized user session. + * If you use `combineReducers` to produce the root reducer function, this must be + * an object with the same shape as `combineReducers` keys. + * + * @param {Function} enhancer The store enhancer. You may optionally specify it + * to enhance the store with third-party capabilities such as middleware, + * time travel, persistence, etc. The only store enhancer that ships with Redux + * is `applyMiddleware()`. + * + * @returns {Store} A Redux store that lets you read the state, dispatch actions + * and subscribe to changes. + */ + function createStore(reducer, initialState, enhancer) { + var _ref2; + + if (typeof initialState === 'function' && typeof enhancer === 'undefined') { + enhancer = initialState; + initialState = undefined; + } + + if (typeof enhancer !== 'undefined') { + if (typeof enhancer !== 'function') { + throw new Error('Expected the enhancer to be a function.'); + } + + return enhancer(createStore)(reducer, initialState); + } + + if (typeof reducer !== 'function') { + throw new Error('Expected the reducer to be a function.'); + } + + var currentReducer = reducer; + var currentState = initialState; + var currentListeners = []; + var nextListeners = currentListeners; + var isDispatching = false; + + function ensureCanMutateNextListeners() { + if (nextListeners === currentListeners) { + nextListeners = currentListeners.slice(); + } + } + + /** + * Reads the state tree managed by the store. + * + * @returns {any} The current state tree of your application. + */ + function getState() { + return currentState; + } + + /** + * Adds a change listener. It will be called any time an action is dispatched, + * and some part of the state tree may potentially have changed. You may then + * call `getState()` to read the current state tree inside the callback. + * + * You may call `dispatch()` from a change listener, with the following + * caveats: + * + * 1. The subscriptions are snapshotted just before every `dispatch()` call. + * If you subscribe or unsubscribe while the listeners are being invoked, this + * will not have any effect on the `dispatch()` that is currently in progress. + * However, the next `dispatch()` call, whether nested or not, will use a more + * recent snapshot of the subscription list. + * + * 2. The listener should not expect to see all state changes, as the state + * might have been updated multiple times during a nested `dispatch()` before + * the listener is called. It is, however, guaranteed that all subscribers + * registered before the `dispatch()` started will be called with the latest + * state by the time it exits. + * + * @param {Function} listener A callback to be invoked on every dispatch. + * @returns {Function} A function to remove this change listener. + */ + function subscribe(listener) { + if (typeof listener !== 'function') { + throw new Error('Expected listener to be a function.'); + } + + var isSubscribed = true; + + ensureCanMutateNextListeners(); + nextListeners.push(listener); + + return function unsubscribe() { + if (!isSubscribed) { + return; + } + + isSubscribed = false; + + ensureCanMutateNextListeners(); + var index = nextListeners.indexOf(listener); + nextListeners.splice(index, 1); + }; + } + + /** + * Dispatches an action. It is the only way to trigger a state change. + * + * The `reducer` function, used to create the store, will be called with the + * current state tree and the given `action`. Its return value will + * be considered the **next** state of the tree, and the change listeners + * will be notified. + * + * The base implementation only supports plain object actions. If you want to + * dispatch a Promise, an Observable, a thunk, or something else, you need to + * wrap your store creating function into the corresponding middleware. For + * example, see the documentation for the `redux-thunk` package. Even the + * middleware will eventually dispatch plain object actions using this method. + * + * @param {Object} action A plain object representing “what changed”. It is + * a good idea to keep actions serializable so you can record and replay user + * sessions, or use the time travelling `redux-devtools`. An action must have + * a `type` property which may not be `undefined`. It is a good idea to use + * string constants for action types. + * + * @returns {Object} For convenience, the same action object you dispatched. + * + * Note that, if you use a custom middleware, it may wrap `dispatch()` to + * return something else (for example, a Promise you can await). + */ + function dispatch(action) { + if (!(0, _isPlainObject2["default"])(action)) { + throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.'); + } + + if (typeof action.type === 'undefined') { + throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?'); + } + + if (isDispatching) { + throw new Error('Reducers may not dispatch actions.'); + } + + try { + isDispatching = true; + currentState = currentReducer(currentState, action); + } finally { + isDispatching = false; + } + + var listeners = currentListeners = nextListeners; + for (var i = 0; i < listeners.length; i++) { + listeners[i](); + } + + return action; + } + + /** + * Replaces the reducer currently used by the store to calculate the state. + * + * You might need this if your app implements code splitting and you want to + * load some of the reducers dynamically. You might also need this if you + * implement a hot reloading mechanism for Redux. + * + * @param {Function} nextReducer The reducer for the store to use instead. + * @returns {void} + */ + function replaceReducer(nextReducer) { + if (typeof nextReducer !== 'function') { + throw new Error('Expected the nextReducer to be a function.'); + } + + currentReducer = nextReducer; + dispatch({ type: ActionTypes.INIT }); + } + + /** + * Interoperability point for observable/reactive libraries. + * @returns {observable} A minimal observable of state changes. + * For more information, see the observable proposal: + * https://github.com/zenparsing/es-observable + */ + function observable() { + var _ref; + + var outerSubscribe = subscribe; + return _ref = { + /** + * The minimal observable subscription method. + * @param {Object} observer Any object that can be used as an observer. + * The observer object should have a `next` method. + * @returns {subscription} An object with an `unsubscribe` method that can + * be used to unsubscribe the observable from the store, and prevent further + * emission of values from the observable. + */ + + subscribe: function subscribe(observer) { + if (typeof observer !== 'object') { + throw new TypeError('Expected the observer to be an object.'); + } + + function observeState() { + if (observer.next) { + observer.next(getState()); + } + } + + observeState(); + var unsubscribe = outerSubscribe(observeState); + return { unsubscribe: unsubscribe }; + } + }, _ref[_symbolObservable2["default"]] = function () { + return this; + }, _ref; + } + + // When a store is created, an "INIT" action is dispatched so that every + // reducer returns their initial state. This effectively populates + // the initial state tree. + dispatch({ type: ActionTypes.INIT }); + + return _ref2 = { + dispatch: dispatch, + subscribe: subscribe, + getState: getState, + replaceReducer: replaceReducer + }, _ref2[_symbolObservable2["default"]] = observable, _ref2; + } + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + var baseGetTag = __webpack_require__(13), + getPrototype = __webpack_require__(19), + isObjectLike = __webpack_require__(21); + + /** `Object#toString` result references. */ + var objectTag = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike(value) || baseGetTag(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + module.exports = isPlainObject; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + var Symbol = __webpack_require__(14), + getRawTag = __webpack_require__(17), + objectToString = __webpack_require__(18); + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + value = Object(value); + return (symToStringTag && symToStringTag in value) + ? getRawTag(value) + : objectToString(value); + } + + module.exports = baseGetTag; + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + var root = __webpack_require__(15); + + /** Built-in value references. */ + var Symbol = root.Symbol; + + module.exports = Symbol; + + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + var freeGlobal = __webpack_require__(16); + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); + + module.exports = root; + + +/***/ }, +/* 16 */ +/***/ function(module, exports) { + + /* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + + module.exports = freeGlobal; + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + var Symbol = __webpack_require__(14); + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Built-in value references. */ + var symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + module.exports = getRawTag; + + +/***/ }, +/* 18 */ +/***/ function(module, exports) { + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + module.exports = objectToString; + + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + var overArg = __webpack_require__(20); + + /** Built-in value references. */ + var getPrototype = overArg(Object.getPrototypeOf, Object); + + module.exports = getPrototype; + + +/***/ }, +/* 20 */ +/***/ function(module, exports) { + + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + module.exports = overArg; + + +/***/ }, +/* 21 */ +/***/ function(module, exports) { + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + module.exports = isObjectLike; + + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global) {/* global window */ + 'use strict'; + + module.exports = __webpack_require__(23)(global || window || this); + + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) + +/***/ }, +/* 23 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = function symbolObservablePonyfill(root) { + var result; + var Symbol = root.Symbol; + + if (typeof Symbol === 'function') { + if (Symbol.observable) { + result = Symbol.observable; + } else { + result = Symbol('observable'); + Symbol.observable = result; + } + } else { + result = '@@observable'; + } + + return result; + }; + + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = combineReducers; + + var _createStore = __webpack_require__(11); + + var _isPlainObject = __webpack_require__(12); + + var _isPlainObject2 = _interopRequireDefault(_isPlainObject); + + var _warning = __webpack_require__(25); + + var _warning2 = _interopRequireDefault(_warning); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + function getUndefinedStateErrorMessage(key, action) { + var actionType = action && action.type; + var actionName = actionType && '"' + actionType.toString() + '"' || 'an action'; + + return 'Given action ' + actionName + ', reducer "' + key + '" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.'; + } + + function getUnexpectedStateShapeWarningMessage(inputState, reducers, action) { + var reducerKeys = Object.keys(reducers); + var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'initialState argument passed to createStore' : 'previous state received by the reducer'; + + if (reducerKeys.length === 0) { + return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.'; + } + + if (!(0, _isPlainObject2["default"])(inputState)) { + return 'The ' + argumentName + ' has unexpected type of "' + {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected argument to be an object with the following ' + ('keys: "' + reducerKeys.join('", "') + '"'); + } + + var unexpectedKeys = Object.keys(inputState).filter(function (key) { + return !reducers.hasOwnProperty(key); + }); + + if (unexpectedKeys.length > 0) { + return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.'); + } + } + + function assertReducerSanity(reducers) { + Object.keys(reducers).forEach(function (key) { + var reducer = reducers[key]; + var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT }); + + if (typeof initialState === 'undefined') { + throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.'); + } + + var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.'); + if (typeof reducer(undefined, { type: type }) === 'undefined') { + throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.'); + } + }); + } + + /** + * Turns an object whose values are different reducer functions, into a single + * reducer function. It will call every child reducer, and gather their results + * into a single state object, whose keys correspond to the keys of the passed + * reducer functions. + * + * @param {Object} reducers An object whose values correspond to different + * reducer functions that need to be combined into one. One handy way to obtain + * it is to use ES6 `import * as reducers` syntax. The reducers may never return + * undefined for any action. Instead, they should return their initial state + * if the state passed to them was undefined, and the current state for any + * unrecognized action. + * + * @returns {Function} A reducer function that invokes every reducer inside the + * passed object, and builds a state object with the same shape. + */ + function combineReducers(reducers) { + var reducerKeys = Object.keys(reducers); + var finalReducers = {}; + for (var i = 0; i < reducerKeys.length; i++) { + var key = reducerKeys[i]; + if (typeof reducers[key] === 'function') { + finalReducers[key] = reducers[key]; + } + } + var finalReducerKeys = Object.keys(finalReducers); + + var sanityError; + try { + assertReducerSanity(finalReducers); + } catch (e) { + sanityError = e; + } + + return function combination() { + var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; + var action = arguments[1]; + + if (sanityError) { + throw sanityError; + } + + if (false) { + var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action); + if (warningMessage) { + (0, _warning2["default"])(warningMessage); + } + } + + var hasChanged = false; + var nextState = {}; + for (var i = 0; i < finalReducerKeys.length; i++) { + var key = finalReducerKeys[i]; + var reducer = finalReducers[key]; + var previousStateForKey = state[key]; + var nextStateForKey = reducer(previousStateForKey, action); + if (typeof nextStateForKey === 'undefined') { + var errorMessage = getUndefinedStateErrorMessage(key, action); + throw new Error(errorMessage); + } + nextState[key] = nextStateForKey; + hasChanged = hasChanged || nextStateForKey !== previousStateForKey; + } + return hasChanged ? nextState : state; + }; + } + +/***/ }, +/* 25 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = warning; + /** + * Prints a warning in the console if it exists. + * + * @param {String} message The warning message. + * @returns {void} + */ + function warning(message) { + /* eslint-disable no-console */ + if (typeof console !== 'undefined' && typeof console.error === 'function') { + console.error(message); + } + /* eslint-enable no-console */ + try { + // This error was thrown as a convenience so that if you enable + // "break on all exceptions" in your console, + // it would pause the execution at this line. + throw new Error(message); + /* eslint-disable no-empty */ + } catch (e) {} + /* eslint-enable no-empty */ + } + +/***/ }, +/* 26 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = bindActionCreators; + function bindActionCreator(actionCreator, dispatch) { + return function () { + return dispatch(actionCreator.apply(undefined, arguments)); + }; + } + + /** + * Turns an object whose values are action creators, into an object with the + * same keys, but with every function wrapped into a `dispatch` call so they + * may be invoked directly. This is just a convenience method, as you can call + * `store.dispatch(MyActionCreators.doSomething())` yourself just fine. + * + * For convenience, you can also pass a single function as the first argument, + * and get a function in return. + * + * @param {Function|Object} actionCreators An object whose values are action + * creator functions. One handy way to obtain it is to use ES6 `import * as` + * syntax. You may also pass a single function. + * + * @param {Function} dispatch The `dispatch` function available on your Redux + * store. + * + * @returns {Function|Object} The object mimicking the original object, but with + * every action creator wrapped into the `dispatch` call. If you passed a + * function as `actionCreators`, the return value will also be a single + * function. + */ + function bindActionCreators(actionCreators, dispatch) { + if (typeof actionCreators === 'function') { + return bindActionCreator(actionCreators, dispatch); + } + + if (typeof actionCreators !== 'object' || actionCreators === null) { + throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'); + } + + var keys = Object.keys(actionCreators); + var boundActionCreators = {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var actionCreator = actionCreators[key]; + if (typeof actionCreator === 'function') { + boundActionCreators[key] = bindActionCreator(actionCreator, dispatch); + } + } + return boundActionCreators; + } + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + exports["default"] = applyMiddleware; + + var _compose = __webpack_require__(28); + + var _compose2 = _interopRequireDefault(_compose); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + /** + * Creates a store enhancer that applies middleware to the dispatch method + * of the Redux store. This is handy for a variety of tasks, such as expressing + * asynchronous actions in a concise manner, or logging every action payload. + * + * See `redux-thunk` package as an example of the Redux middleware. + * + * Because middleware is potentially asynchronous, this should be the first + * store enhancer in the composition chain. + * + * Note that each middleware will be given the `dispatch` and `getState` functions + * as named arguments. + * + * @param {...Function} middlewares The middleware chain to be applied. + * @returns {Function} A store enhancer applying the middleware. + */ + function applyMiddleware() { + for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) { + middlewares[_key] = arguments[_key]; + } + + return function (createStore) { + return function (reducer, initialState, enhancer) { + var store = createStore(reducer, initialState, enhancer); + var _dispatch = store.dispatch; + var chain = []; + + var middlewareAPI = { + getState: store.getState, + dispatch: function dispatch(action) { + return _dispatch(action); + } + }; + chain = middlewares.map(function (middleware) { + return middleware(middlewareAPI); + }); + _dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch); + + return _extends({}, store, { + dispatch: _dispatch + }); + }; + }; + } + +/***/ }, +/* 28 */ +/***/ function(module, exports) { + + "use strict"; + + exports.__esModule = true; + exports["default"] = compose; + /** + * Composes single-argument functions from right to left. The rightmost + * function can take multiple arguments as it provides the signature for + * the resulting composite function. + * + * @param {...Function} funcs The functions to compose. + * @returns {Function} A function obtained by composing the argument functions + * from right to left. For example, compose(f, g, h) is identical to doing + * (...args) => f(g(h(...args))). + */ + + function compose() { + for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) { + funcs[_key] = arguments[_key]; + } + + if (funcs.length === 0) { + return function (arg) { + return arg; + }; + } else { + var _ret = function () { + var last = funcs[funcs.length - 1]; + var rest = funcs.slice(0, -1); + return { + v: function v() { + return rest.reduceRight(function (composed, f) { + return f(composed); + }, last.apply(undefined, arguments)); + } + }; + }(); + + if (typeof _ret === "object") return _ret.v; + } + } + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports.connect = exports.Provider = undefined; + + var _Provider = __webpack_require__(30); + + var _Provider2 = _interopRequireDefault(_Provider); + + var _connect = __webpack_require__(33); + + var _connect2 = _interopRequireDefault(_connect); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + exports.Provider = _Provider2["default"]; + exports.connect = _connect2["default"]; + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = undefined; + + var _react = __webpack_require__(6); + + var _storeShape = __webpack_require__(31); + + var _storeShape2 = _interopRequireDefault(_storeShape); + + var _warning = __webpack_require__(32); + + var _warning2 = _interopRequireDefault(_warning); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var didWarnAboutReceivingStore = false; + function warnAboutReceivingStore() { + if (didWarnAboutReceivingStore) { + return; + } + didWarnAboutReceivingStore = true; + + (0, _warning2["default"])(' does not support changing `store` on the fly. ' + 'It is most likely that you see this error because you updated to ' + 'Redux 2.x and React Redux 2.x which no longer hot reload reducers ' + 'automatically. See https://github.com/reactjs/react-redux/releases/' + 'tag/v2.0.0 for the migration instructions.'); + } + + var Provider = function (_Component) { + _inherits(Provider, _Component); + + Provider.prototype.getChildContext = function getChildContext() { + return { store: this.store }; + }; + + function Provider(props, context) { + _classCallCheck(this, Provider); + + var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); + + _this.store = props.store; + return _this; + } + + Provider.prototype.render = function render() { + var children = this.props.children; + + return _react.Children.only(children); + }; + + return Provider; + }(_react.Component); + + exports["default"] = Provider; + + if (false) { + Provider.prototype.componentWillReceiveProps = function (nextProps) { + var store = this.store; + var nextStore = nextProps.store; + + if (store !== nextStore) { + warnAboutReceivingStore(); + } + }; + } + + Provider.propTypes = { + store: _storeShape2["default"].isRequired, + children: _react.PropTypes.element.isRequired + }; + Provider.childContextTypes = { + store: _storeShape2["default"].isRequired + }; + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + + var _react = __webpack_require__(6); + + exports["default"] = _react.PropTypes.shape({ + subscribe: _react.PropTypes.func.isRequired, + dispatch: _react.PropTypes.func.isRequired, + getState: _react.PropTypes.func.isRequired + }); + +/***/ }, +/* 32 */ +/***/ function(module, exports) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = warning; + /** + * Prints a warning in the console if it exists. + * + * @param {String} message The warning message. + * @returns {void} + */ + function warning(message) { + /* eslint-disable no-console */ + if (typeof console !== 'undefined' && typeof console.error === 'function') { + console.error(message); + } + /* eslint-enable no-console */ + try { + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + /* eslint-disable no-empty */ + } catch (e) {} + /* eslint-enable no-empty */ + } + +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + exports.__esModule = true; + exports["default"] = connect; + + var _react = __webpack_require__(6); + + var _storeShape = __webpack_require__(31); + + var _storeShape2 = _interopRequireDefault(_storeShape); + + var _shallowEqual = __webpack_require__(34); + + var _shallowEqual2 = _interopRequireDefault(_shallowEqual); + + var _wrapActionCreators = __webpack_require__(35); + + var _wrapActionCreators2 = _interopRequireDefault(_wrapActionCreators); + + var _warning = __webpack_require__(32); + + var _warning2 = _interopRequireDefault(_warning); + + var _isPlainObject = __webpack_require__(12); + + var _isPlainObject2 = _interopRequireDefault(_isPlainObject); + + var _hoistNonReactStatics = __webpack_require__(36); + + var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics); + + var _invariant = __webpack_require__(37); + + var _invariant2 = _interopRequireDefault(_invariant); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + + function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var defaultMapStateToProps = function defaultMapStateToProps(state) { + return {}; + }; // eslint-disable-line no-unused-vars + var defaultMapDispatchToProps = function defaultMapDispatchToProps(dispatch) { + return { dispatch: dispatch }; + }; + var defaultMergeProps = function defaultMergeProps(stateProps, dispatchProps, parentProps) { + return _extends({}, parentProps, stateProps, dispatchProps); + }; + + function getDisplayName(WrappedComponent) { + return WrappedComponent.displayName || WrappedComponent.name || 'Component'; + } + + var errorObject = { value: null }; + function tryCatch(fn, ctx) { + try { + return fn.apply(ctx); + } catch (e) { + errorObject.value = e; + return errorObject; + } + } + + // Helps track hot reloading. + var nextVersion = 0; + + function connect(mapStateToProps, mapDispatchToProps, mergeProps) { + var options = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; + + var shouldSubscribe = Boolean(mapStateToProps); + var mapState = mapStateToProps || defaultMapStateToProps; + + var mapDispatch = undefined; + if (typeof mapDispatchToProps === 'function') { + mapDispatch = mapDispatchToProps; + } else if (!mapDispatchToProps) { + mapDispatch = defaultMapDispatchToProps; + } else { + mapDispatch = (0, _wrapActionCreators2["default"])(mapDispatchToProps); + } + + var finalMergeProps = mergeProps || defaultMergeProps; + var _options$pure = options.pure; + var pure = _options$pure === undefined ? true : _options$pure; + var _options$withRef = options.withRef; + var withRef = _options$withRef === undefined ? false : _options$withRef; + + var checkMergedEquals = pure && finalMergeProps !== defaultMergeProps; + + // Helps track hot reloading. + var version = nextVersion++; + + return function wrapWithConnect(WrappedComponent) { + var connectDisplayName = 'Connect(' + getDisplayName(WrappedComponent) + ')'; + + function checkStateShape(props, methodName) { + if (!(0, _isPlainObject2["default"])(props)) { + (0, _warning2["default"])(methodName + '() in ' + connectDisplayName + ' must return a plain object. ' + ('Instead received ' + props + '.')); + } + } + + function computeMergedProps(stateProps, dispatchProps, parentProps) { + var mergedProps = finalMergeProps(stateProps, dispatchProps, parentProps); + if (false) { + checkStateShape(mergedProps, 'mergeProps'); + } + return mergedProps; + } + + var Connect = function (_Component) { + _inherits(Connect, _Component); + + Connect.prototype.shouldComponentUpdate = function shouldComponentUpdate() { + return !pure || this.haveOwnPropsChanged || this.hasStoreStateChanged; + }; + + function Connect(props, context) { + _classCallCheck(this, Connect); + + var _this = _possibleConstructorReturn(this, _Component.call(this, props, context)); + + _this.version = version; + _this.store = props.store || context.store; + + (0, _invariant2["default"])(_this.store, 'Could not find "store" in either the context or ' + ('props of "' + connectDisplayName + '". ') + 'Either wrap the root component in a , ' + ('or explicitly pass "store" as a prop to "' + connectDisplayName + '".')); + + var storeState = _this.store.getState(); + _this.state = { storeState: storeState }; + _this.clearCache(); + return _this; + } + + Connect.prototype.computeStateProps = function computeStateProps(store, props) { + if (!this.finalMapStateToProps) { + return this.configureFinalMapState(store, props); + } + + var state = store.getState(); + var stateProps = this.doStatePropsDependOnOwnProps ? this.finalMapStateToProps(state, props) : this.finalMapStateToProps(state); + + if (false) { + checkStateShape(stateProps, 'mapStateToProps'); + } + return stateProps; + }; + + Connect.prototype.configureFinalMapState = function configureFinalMapState(store, props) { + var mappedState = mapState(store.getState(), props); + var isFactory = typeof mappedState === 'function'; + + this.finalMapStateToProps = isFactory ? mappedState : mapState; + this.doStatePropsDependOnOwnProps = this.finalMapStateToProps.length !== 1; + + if (isFactory) { + return this.computeStateProps(store, props); + } + + if (false) { + checkStateShape(mappedState, 'mapStateToProps'); + } + return mappedState; + }; + + Connect.prototype.computeDispatchProps = function computeDispatchProps(store, props) { + if (!this.finalMapDispatchToProps) { + return this.configureFinalMapDispatch(store, props); + } + + var dispatch = store.dispatch; + + var dispatchProps = this.doDispatchPropsDependOnOwnProps ? this.finalMapDispatchToProps(dispatch, props) : this.finalMapDispatchToProps(dispatch); + + if (false) { + checkStateShape(dispatchProps, 'mapDispatchToProps'); + } + return dispatchProps; + }; + + Connect.prototype.configureFinalMapDispatch = function configureFinalMapDispatch(store, props) { + var mappedDispatch = mapDispatch(store.dispatch, props); + var isFactory = typeof mappedDispatch === 'function'; + + this.finalMapDispatchToProps = isFactory ? mappedDispatch : mapDispatch; + this.doDispatchPropsDependOnOwnProps = this.finalMapDispatchToProps.length !== 1; + + if (isFactory) { + return this.computeDispatchProps(store, props); + } + + if (false) { + checkStateShape(mappedDispatch, 'mapDispatchToProps'); + } + return mappedDispatch; + }; + + Connect.prototype.updateStatePropsIfNeeded = function updateStatePropsIfNeeded() { + var nextStateProps = this.computeStateProps(this.store, this.props); + if (this.stateProps && (0, _shallowEqual2["default"])(nextStateProps, this.stateProps)) { + return false; + } + + this.stateProps = nextStateProps; + return true; + }; + + Connect.prototype.updateDispatchPropsIfNeeded = function updateDispatchPropsIfNeeded() { + var nextDispatchProps = this.computeDispatchProps(this.store, this.props); + if (this.dispatchProps && (0, _shallowEqual2["default"])(nextDispatchProps, this.dispatchProps)) { + return false; + } + + this.dispatchProps = nextDispatchProps; + return true; + }; + + Connect.prototype.updateMergedPropsIfNeeded = function updateMergedPropsIfNeeded() { + var nextMergedProps = computeMergedProps(this.stateProps, this.dispatchProps, this.props); + if (this.mergedProps && checkMergedEquals && (0, _shallowEqual2["default"])(nextMergedProps, this.mergedProps)) { + return false; + } + + this.mergedProps = nextMergedProps; + return true; + }; + + Connect.prototype.isSubscribed = function isSubscribed() { + return typeof this.unsubscribe === 'function'; + }; + + Connect.prototype.trySubscribe = function trySubscribe() { + if (shouldSubscribe && !this.unsubscribe) { + this.unsubscribe = this.store.subscribe(this.handleChange.bind(this)); + this.handleChange(); + } + }; + + Connect.prototype.tryUnsubscribe = function tryUnsubscribe() { + if (this.unsubscribe) { + this.unsubscribe(); + this.unsubscribe = null; + } + }; + + Connect.prototype.componentDidMount = function componentDidMount() { + this.trySubscribe(); + }; + + Connect.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { + if (!pure || !(0, _shallowEqual2["default"])(nextProps, this.props)) { + this.haveOwnPropsChanged = true; + } + }; + + Connect.prototype.componentWillUnmount = function componentWillUnmount() { + this.tryUnsubscribe(); + this.clearCache(); + }; + + Connect.prototype.clearCache = function clearCache() { + this.dispatchProps = null; + this.stateProps = null; + this.mergedProps = null; + this.haveOwnPropsChanged = true; + this.hasStoreStateChanged = true; + this.haveStatePropsBeenPrecalculated = false; + this.statePropsPrecalculationError = null; + this.renderedElement = null; + this.finalMapDispatchToProps = null; + this.finalMapStateToProps = null; + }; + + Connect.prototype.handleChange = function handleChange() { + if (!this.unsubscribe) { + return; + } + + var storeState = this.store.getState(); + var prevStoreState = this.state.storeState; + if (pure && prevStoreState === storeState) { + return; + } + + if (pure && !this.doStatePropsDependOnOwnProps) { + var haveStatePropsChanged = tryCatch(this.updateStatePropsIfNeeded, this); + if (!haveStatePropsChanged) { + return; + } + if (haveStatePropsChanged === errorObject) { + this.statePropsPrecalculationError = errorObject.value; + } + this.haveStatePropsBeenPrecalculated = true; + } + + this.hasStoreStateChanged = true; + this.setState({ storeState: storeState }); + }; + + Connect.prototype.getWrappedInstance = function getWrappedInstance() { + (0, _invariant2["default"])(withRef, 'To access the wrapped instance, you need to specify ' + '{ withRef: true } as the fourth argument of the connect() call.'); + + return this.refs.wrappedInstance; + }; + + Connect.prototype.render = function render() { + var haveOwnPropsChanged = this.haveOwnPropsChanged; + var hasStoreStateChanged = this.hasStoreStateChanged; + var haveStatePropsBeenPrecalculated = this.haveStatePropsBeenPrecalculated; + var statePropsPrecalculationError = this.statePropsPrecalculationError; + var renderedElement = this.renderedElement; + + this.haveOwnPropsChanged = false; + this.hasStoreStateChanged = false; + this.haveStatePropsBeenPrecalculated = false; + this.statePropsPrecalculationError = null; + + if (statePropsPrecalculationError) { + throw statePropsPrecalculationError; + } + + var shouldUpdateStateProps = true; + var shouldUpdateDispatchProps = true; + if (pure && renderedElement) { + shouldUpdateStateProps = hasStoreStateChanged || haveOwnPropsChanged && this.doStatePropsDependOnOwnProps; + shouldUpdateDispatchProps = haveOwnPropsChanged && this.doDispatchPropsDependOnOwnProps; + } + + var haveStatePropsChanged = false; + var haveDispatchPropsChanged = false; + if (haveStatePropsBeenPrecalculated) { + haveStatePropsChanged = true; + } else if (shouldUpdateStateProps) { + haveStatePropsChanged = this.updateStatePropsIfNeeded(); + } + if (shouldUpdateDispatchProps) { + haveDispatchPropsChanged = this.updateDispatchPropsIfNeeded(); + } + + var haveMergedPropsChanged = true; + if (haveStatePropsChanged || haveDispatchPropsChanged || haveOwnPropsChanged) { + haveMergedPropsChanged = this.updateMergedPropsIfNeeded(); + } else { + haveMergedPropsChanged = false; + } + + if (!haveMergedPropsChanged && renderedElement) { + return renderedElement; + } + + if (withRef) { + this.renderedElement = (0, _react.createElement)(WrappedComponent, _extends({}, this.mergedProps, { + ref: 'wrappedInstance' + })); + } else { + this.renderedElement = (0, _react.createElement)(WrappedComponent, this.mergedProps); + } + + return this.renderedElement; + }; + + return Connect; + }(_react.Component); + + Connect.displayName = connectDisplayName; + Connect.WrappedComponent = WrappedComponent; + Connect.contextTypes = { + store: _storeShape2["default"] + }; + Connect.propTypes = { + store: _storeShape2["default"] + }; + + if (false) { + Connect.prototype.componentWillUpdate = function componentWillUpdate() { + if (this.version === version) { + return; + } + + // We are hot reloading! + this.version = version; + this.trySubscribe(); + this.clearCache(); + }; + } + + return (0, _hoistNonReactStatics2["default"])(Connect, WrappedComponent); + }; + } + +/***/ }, +/* 34 */ +/***/ function(module, exports) { + + "use strict"; + + exports.__esModule = true; + exports["default"] = shallowEqual; + function shallowEqual(objA, objB) { + if (objA === objB) { + return true; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } + + // Test for A's keys different from B. + var hasOwn = Object.prototype.hasOwnProperty; + for (var i = 0; i < keysA.length; i++) { + if (!hasOwn.call(objB, keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) { + return false; + } + } + + return true; + } + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + exports.__esModule = true; + exports["default"] = wrapActionCreators; + + var _redux = __webpack_require__(10); + + function wrapActionCreators(actionCreators) { + return function (dispatch) { + return (0, _redux.bindActionCreators)(actionCreators, dispatch); + }; + } + +/***/ }, +/* 36 */ +/***/ function(module, exports) { + + /** + * Copyright 2015, Yahoo! Inc. + * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ + 'use strict'; + + var REACT_STATICS = { + childContextTypes: true, + contextTypes: true, + defaultProps: true, + displayName: true, + getDefaultProps: true, + mixins: true, + propTypes: true, + type: true + }; + + var KNOWN_STATICS = { + name: true, + length: true, + prototype: true, + caller: true, + arguments: true, + arity: true + }; + + var isGetOwnPropertySymbolsAvailable = typeof Object.getOwnPropertySymbols === 'function'; + + module.exports = function hoistNonReactStatics(targetComponent, sourceComponent, customStatics) { + if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components + var keys = Object.getOwnPropertyNames(sourceComponent); + + /* istanbul ignore else */ + if (isGetOwnPropertySymbolsAvailable) { + keys = keys.concat(Object.getOwnPropertySymbols(sourceComponent)); + } + + for (var i = 0; i < keys.length; ++i) { + if (!REACT_STATICS[keys[i]] && !KNOWN_STATICS[keys[i]] && (!customStatics || !customStatics[keys[i]])) { + try { + targetComponent[keys[i]] = sourceComponent[keys[i]]; + } catch (error) { + + } + } + } + } + + return targetComponent; + }; + + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + + 'use strict'; + + /** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + + var invariant = function(condition, format, a, b, c, d, e, f) { + if (false) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + error.name = 'Invariant Violation'; + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } + }; + + module.exports = invariant; + + +/***/ }, +/* 38 */ +/***/ function(module, exports, __webpack_require__) { + + const { KeyShortcuts } = __webpack_require__(39); + const { DebuggerTransport } = __webpack_require__(77); + const { DebuggerClient } = __webpack_require__(89); + const PrefsHelper = __webpack_require__(93).PrefsHelper; + const { TargetFactory } = __webpack_require__(94); + const DevToolsUtils = __webpack_require__(78); + const AppConstants = __webpack_require__(80); + const EventEmitter = __webpack_require__(70); + const WebsocketTransport = __webpack_require__(95); + const Menu = __webpack_require__(96); + const MenuItem = __webpack_require__(97); + const Tree = __webpack_require__(98); + const sourceUtils = __webpack_require__(99); + const frame = __webpack_require__(100); + + module.exports = { + KeyShortcuts, + PrefsHelper, + DebuggerClient, + DebuggerTransport, + TargetFactory, + DevToolsUtils, + AppConstants, + EventEmitter, + WebsocketTransport, + Menu, + MenuItem, + Tree, + sourceUtils, + frame + }; + + +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const { Services: { appinfo }} = __webpack_require__(40); + const EventEmitter = __webpack_require__(70); + const isOSX = appinfo.OS === "Darwin"; + "use strict"; + + // List of electron keys mapped to DOM API (DOM_VK_*) key code + const ElectronKeysMapping = { + "F1": "DOM_VK_F1", + "F2": "DOM_VK_F2", + "F3": "DOM_VK_F3", + "F4": "DOM_VK_F4", + "F5": "DOM_VK_F5", + "F6": "DOM_VK_F6", + "F7": "DOM_VK_F7", + "F8": "DOM_VK_F8", + "F9": "DOM_VK_F9", + "F10": "DOM_VK_F10", + "F11": "DOM_VK_F11", + "F12": "DOM_VK_F12", + "F13": "DOM_VK_F13", + "F14": "DOM_VK_F14", + "F15": "DOM_VK_F15", + "F16": "DOM_VK_F16", + "F17": "DOM_VK_F17", + "F18": "DOM_VK_F18", + "F19": "DOM_VK_F19", + "F20": "DOM_VK_F20", + "F21": "DOM_VK_F21", + "F22": "DOM_VK_F22", + "F23": "DOM_VK_F23", + "F24": "DOM_VK_F24", + "Space": "DOM_VK_SPACE", + "Backspace": "DOM_VK_BACK_SPACE", + "Delete": "DOM_VK_DELETE", + "Insert": "DOM_VK_INSERT", + "Return": "DOM_VK_RETURN", + "Enter": "DOM_VK_RETURN", + "Up": "DOM_VK_UP", + "Down": "DOM_VK_DOWN", + "Left": "DOM_VK_LEFT", + "Right": "DOM_VK_RIGHT", + "Home": "DOM_VK_HOME", + "End": "DOM_VK_END", + "PageUp": "DOM_VK_PAGE_UP", + "PageDown": "DOM_VK_PAGE_DOWN", + "Escape": "DOM_VK_ESCAPE", + "Esc": "DOM_VK_ESCAPE", + "Tab": "DOM_VK_TAB", + "VolumeUp": "DOM_VK_VOLUME_UP", + "VolumeDown": "DOM_VK_VOLUME_DOWN", + "VolumeMute": "DOM_VK_VOLUME_MUTE", + "PrintScreen": "DOM_VK_PRINTSCREEN", + }; + + /** + * Helper to listen for keyboard events decribed in .properties file. + * + * let shortcuts = new KeyShortcuts({ + * window + * }); + * shortcuts.on("Ctrl+F", event => { + * // `event` is the KeyboardEvent which relates to the key shortcuts + * }); + * + * @param DOMWindow window + * The window object of the document to listen events from. + * @param DOMElement target + * Optional DOM Element on which we should listen events from. + * If omitted, we listen for all events fired on `window`. + */ + function KeyShortcuts({ window, target }) { + this.window = window; + this.target = target || window; + this.keys = new Map(); + this.eventEmitter = new EventEmitter(); + this.target.addEventListener("keydown", this); + } + + /* + * Parse an electron-like key string and return a normalized object which + * allow efficient match on DOM key event. The normalized object matches DOM + * API. + * + * @param DOMWindow window + * Any DOM Window object, just to fetch its `KeyboardEvent` object + * @param String str + * The shortcut string to parse, following this document: + * https://github.com/electron/electron/blob/master/docs/api/accelerator.md + */ + KeyShortcuts.parseElectronKey = function(window, str) { + let modifiers = str.split("+"); + let key = modifiers.pop(); + + let shortcut = { + ctrl: false, + meta: false, + alt: false, + shift: false, + // Set for character keys + key: undefined, + // Set for non-character keys + keyCode: undefined, + }; + for (let mod of modifiers) { + if (mod === "Alt") { + shortcut.alt = true; + } else if (["Command", "Cmd"].includes(mod)) { + shortcut.meta = true; + } else if (["CommandOrControl", "CmdOrCtrl"].includes(mod)) { + if (isOSX) { + shortcut.meta = true; + } else { + shortcut.ctrl = true; + } + } else if (["Control", "Ctrl"].includes(mod)) { + shortcut.ctrl = true; + } else if (mod === "Shift") { + shortcut.shift = true; + } else { + console.error("Unsupported modifier:", mod, "from key:", str); + return null; + } + } + + // Plus is a special case. It's a character key and shouldn't be matched + // against a keycode as it is only accessible via Shift/Capslock + if (key === "Plus") { + key = "+"; + } + + if (typeof key === "string" && key.length === 1) { + // Match any single character + shortcut.key = key.toLowerCase(); + } else if (key in ElectronKeysMapping) { + // Maps the others manually to DOM API DOM_VK_* + key = ElectronKeysMapping[key]; + shortcut.keyCode = window.KeyboardEvent[key]; + // Used only to stringify the shortcut + shortcut.keyCodeString = key; + shortcut.key = key; + } else { + console.error("Unsupported key:", key); + return null; + } + + return shortcut; + }; + + KeyShortcuts.stringify = function(shortcut) { + let list = []; + if (shortcut.alt) { + list.push("Alt"); + } + if (shortcut.ctrl) { + list.push("Ctrl"); + } + if (shortcut.meta) { + list.push("Cmd"); + } + if (shortcut.shift) { + list.push("Shift"); + } + let key; + if (shortcut.key) { + key = shortcut.key.toUpperCase(); + } else { + key = shortcut.keyCodeString; + } + list.push(key); + return list.join("+"); + }; + + KeyShortcuts.prototype = { + destroy() { + this.target.removeEventListener("keydown", this); + this.keys.clear(); + }, + + doesEventMatchShortcut(event, shortcut) { + if (shortcut.meta != event.metaKey) { + return false; + } + if (shortcut.ctrl != event.ctrlKey) { + return false; + } + if (shortcut.alt != event.altKey) { + return false; + } + // Shift is a special modifier, it may implicitely be required if the + // expected key is a special character accessible via shift. + if (shortcut.shift != event.shiftKey && event.key && + event.key.match(/[a-zA-Z]/)) { + return false; + } + if (shortcut.keyCode) { + return event.keyCode == shortcut.keyCode; + } else if (event.key in ElectronKeysMapping) { + return ElectronKeysMapping[event.key] === shortcut.key; + } + + // get the key from the keyCode if key is not provided. + let key = event.key || String.fromCharCode(event.keyCode); + + // For character keys, we match if the final character is the expected one. + // But for digits we also accept indirect match to please azerty keyboard, + // which requires Shift to be pressed to get digits. + return key.toLowerCase() == shortcut.key || + (shortcut.key.match(/[0-9]/) && + event.keyCode == shortcut.key.charCodeAt(0)); + }, + + handleEvent(event) { + for (let [key, shortcut] of this.keys) { + if (this.doesEventMatchShortcut(event, shortcut)) { + this.eventEmitter.emit(key, event); + } + } + }, + + on(key, listener) { + if (typeof listener !== "function") { + throw new Error("KeyShortcuts.on() expects a function as " + + "second argument"); + } + if (!this.keys.has(key)) { + let shortcut = KeyShortcuts.parseElectronKey(this.window, key); + // The key string is wrong and we were unable to compute the key shortcut + if (!shortcut) { + return; + } + this.keys.set(key, shortcut); + } + this.eventEmitter.on(key, listener); + }, + + off(key, listener) { + this.eventEmitter.off(key, listener); + }, + }; + exports.KeyShortcuts = KeyShortcuts; + + +/***/ }, +/* 40 */ +/***/ function(module, exports, __webpack_require__) { + + const Services = __webpack_require__(41); + const SplitBox = __webpack_require__(42); + // const SplitBoxCSS = require("./client/shared/components/splitter/SplitBox.css") + const Rep = __webpack_require__(44).Rep; + const repUtils = __webpack_require__(45); + const StringRep = __webpack_require__(48).StringRep; + + // const repCSS = require("./client/shared/components/reps/reps.css"); + const Grip = __webpack_require__(54).Grip; + const sprintf = __webpack_require__(69).sprintf; + + module.exports = { + Services, + SplitBox, + // SplitBoxCSS, + Rep, + repUtils, + StringRep, + // repCSS, + Grip, + sprintf + }; + + +/***/ }, +/* 41 */ +/***/ function(module, exports) { + + module.exports = require("Services"); + +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + const React = __webpack_require__(6); + const ReactDOM = __webpack_require__(7); + const Draggable = React.createFactory( + __webpack_require__(43)); + const { DOM: dom, PropTypes } = React; + + /** + * This component represents a Splitter. The splitter supports vertical + * as well as horizontal mode. + */ + const SplitBox = React.createClass({ + + propTypes: { + // Custom class name. You can use more names separated by a space. + className: PropTypes.string, + // Initial size of controlled panel. + initialSize: PropTypes.any, + // Optional initial width of controlled panel. + initialWidth: PropTypes.number, + // Optional initial height of controlled panel. + initialHeight: PropTypes.number, + // Left/top panel + startPanel: PropTypes.any, + // Left/top panel collapse state. + startPanelCollapsed: PropTypes.bool, + // Min panel size. + minSize: PropTypes.any, + // Max panel size. + maxSize: PropTypes.any, + // Right/bottom panel + endPanel: PropTypes.any, + // Right/bottom panel collapse state. + endPanelCollapsed: PropTypes.bool, + // True if the right/bottom panel should be controlled. + endPanelControl: PropTypes.bool, + // Size of the splitter handle bar. + splitterSize: PropTypes.number, + // True if the splitter bar is vertical (default is vertical). + vert: PropTypes.bool, + // Optional style properties passed into the splitbox + style: PropTypes.object + }, + + displayName: "SplitBox", + + getDefaultProps() { + return { + splitterSize: 5, + vert: true, + endPanelControl: false, + endPanelCollapsed: false, + startPanelCollapsed: false + }; + }, + + /** + * The state stores the current orientation (vertical or horizontal) + * and the current size (width/height). All these values can change + * during the component's life time. + */ + getInitialState() { + return { + vert: this.props.vert, + width: this.props.initialWidth || this.props.initialSize, + height: this.props.initialHeight || this.props.initialSize + }; + }, + + componentWillReceiveProps(nextProps) { + if (this.props.vert !== nextProps.vert) { + this.setState({ vert: nextProps.vert }); + } + }, + + // Dragging Events + + /** + * Set 'resizing' cursor on entire document during splitter dragging. + * This avoids cursor-flickering that happens when the mouse leaves + * the splitter bar area (happens frequently). + */ + onStartMove() { + const splitBox = ReactDOM.findDOMNode(this); + const doc = splitBox.ownerDocument; + let defaultCursor = doc.documentElement.style.cursor; + doc.documentElement.style.cursor = + (this.state.vert ? "ew-resize" : "ns-resize"); + + splitBox.classList.add("dragging"); + + this.setState({ + defaultCursor: defaultCursor + }); + }, + + onStopMove() { + const splitBox = ReactDOM.findDOMNode(this); + const doc = splitBox.ownerDocument; + doc.documentElement.style.cursor = this.state.defaultCursor; + + splitBox.classList.remove("dragging"); + }, + + screenX() { + const borderWidth = (window.outerWidth - window.innerWidth) / 2; + return window.screenX + borderWidth; + }, + + screenY() { + const borderHeignt = (window.outerHeight - window.innerHeight); + return window.screenY + borderHeignt; + }, + + /** + * Adjust size of the controlled panel. Depending on the current + * orientation we either remember the width or height of + * the splitter box. + */ + onMove(x, y) { + const node = ReactDOM.findDOMNode(this); + const doc = node.ownerDocument; + const win = doc.defaultView; + + let size; + let { endPanelControl } = this.props; + + if (this.state.vert) { + // Switch the control flag in case of RTL. Note that RTL + // has impact on vertical splitter only. + let dir = win.getComputedStyle(doc.documentElement).direction; + if (dir == "rtl") { + endPanelControl = !endPanelControl; + } + + let innerOffset = x - this.screenX(); + size = endPanelControl ? + (node.offsetLeft + node.offsetWidth) - innerOffset : + innerOffset - node.offsetLeft; + + this.setState({ + width: size + }); + } else { + let innerOffset = y - this.screenY(); + size = endPanelControl ? + (node.offsetTop + node.offsetHeight) - innerOffset : + innerOffset - node.offsetTop; + + this.setState({ + height: size + }); + } + }, + + // Rendering + preparePanelStyles() { + const vert = this.state.vert; + const { + minSize, maxSize, startPanelCollapsed, endPanelControl, + endPanelCollapsed } = this.props; + let leftPanelStyle, rightPanelStyle; + + // Set proper size for panels depending on the current state. + if (vert) { + let startWidth = endPanelControl ? null : this.state.width, + endWidth = endPanelControl ? this.state.width : null; + + leftPanelStyle = { + maxWidth: endPanelControl ? null : maxSize, + minWidth: endPanelControl ? null : minSize, + width: startPanelCollapsed ? 0 : startWidth + }; + rightPanelStyle = { + maxWidth: endPanelControl ? maxSize : null, + minWidth: endPanelControl ? minSize : null, + width: endPanelCollapsed ? 0 : endWidth + }; + } else { + leftPanelStyle = { + maxHeight: endPanelControl ? null : maxSize, + minHeight: endPanelControl ? null : minSize, + height: endPanelControl ? null : this.state.height + }; + rightPanelStyle = { + maxHeight: endPanelControl ? maxSize : null, + minHeight: endPanelControl ? minSize : null, + height: endPanelControl ? this.state.height : null + }; + } + + return { leftPanelStyle, rightPanelStyle }; + }, + + render() { + const vert = this.state.vert; + const { startPanel, endPanel, endPanelControl, splitterSize } = this.props; + + let style = Object.assign({}, this.props.style); + + // Calculate class names list. + let classNames = ["split-box"]; + classNames.push(vert ? "vert" : "horz"); + if (this.props.className) { + classNames = classNames.concat(this.props.className.split(" ")); + } + + const { leftPanelStyle, rightPanelStyle } = this.preparePanelStyles(); + + // Calculate splitter size + let splitterStyle = { + flex: `0 0 ${splitterSize}px` + }; + + return ( + dom.div({ + className: classNames.join(" "), + style: style }, + startPanel ? + dom.div({ + className: endPanelControl ? "uncontrolled" : "controlled", + style: leftPanelStyle }, + startPanel + ) : null, + Draggable({ + className: "splitter", + style: splitterStyle, + onStart: this.onStartMove, + onStop: this.onStopMove, + onMove: this.onMove + }), + endPanel ? + dom.div({ + className: endPanelControl ? "controlled" : "uncontrolled", + style: rightPanelStyle }, + endPanel + ) : null + ) + ); + } + }); + + module.exports = SplitBox; + + +/***/ }, +/* 43 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const React = __webpack_require__(6); + const ReactDOM = __webpack_require__(7); + const { DOM: dom, PropTypes } = React; + + const Draggable = React.createClass({ + displayName: "Draggable", + + propTypes: { + onMove: PropTypes.func.isRequired, + onStart: PropTypes.func, + onStop: PropTypes.func, + style: PropTypes.object, + className: PropTypes.string + }, + + startDragging(ev) { + ev.preventDefault(); + const doc = ReactDOM.findDOMNode(this).ownerDocument; + doc.addEventListener("mousemove", this.onMove); + doc.addEventListener("mouseup", this.onUp); + this.props.onStart && this.props.onStart(); + }, + + onMove(ev) { + ev.preventDefault(); + // Use screen coordinates so, moving mouse over iframes + // doesn't mangle (relative) coordinates. + this.props.onMove(ev.screenX, ev.screenY); + }, + + onUp(ev) { + ev.preventDefault(); + const doc = ReactDOM.findDOMNode(this).ownerDocument; + doc.removeEventListener("mousemove", this.onMove); + doc.removeEventListener("mouseup", this.onUp); + this.props.onStop && this.props.onStop(); + }, + + render() { + return dom.div({ + style: this.props.style, + className: this.props.className, + onMouseDown: this.startDragging + }); + } + }); + + module.exports = Draggable; + + +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + const { isGrip } = __webpack_require__(45); + + // Load all existing rep templates + const { Undefined } = __webpack_require__(46); + const { Null } = __webpack_require__(47); + const { StringRep } = __webpack_require__(48); + const { Number } = __webpack_require__(49); + const { ArrayRep } = __webpack_require__(50); + const { Obj } = __webpack_require__(52); + const { SymbolRep } = __webpack_require__(55); + + // DOM types (grips) + const { Attribute } = __webpack_require__(56); + const { DateTime } = __webpack_require__(57); + const { Document } = __webpack_require__(58); + const { Event } = __webpack_require__(59); + const { Func } = __webpack_require__(60); + const { RegExp } = __webpack_require__(61); + const { StyleSheet } = __webpack_require__(62); + const { TextNode } = __webpack_require__(63); + const { Window } = __webpack_require__(64); + const { ObjectWithText } = __webpack_require__(65); + const { ObjectWithURL } = __webpack_require__(66); + const { GripArray } = __webpack_require__(67); + const { GripMap } = __webpack_require__(68); + const { Grip } = __webpack_require__(54); + + // List of all registered template. + // XXX there should be a way for extensions to register a new + // or modify an existing rep. + let reps = [ + RegExp, + StyleSheet, + Event, + DateTime, + TextNode, + Attribute, + Func, + ArrayRep, + Document, + Window, + ObjectWithText, + ObjectWithURL, + GripArray, + GripMap, + Grip, + Undefined, + Null, + StringRep, + Number, + SymbolRep, + ]; + + /** + * Generic rep that is using for rendering native JS types or an object. + * The right template used for rendering is picked automatically according + * to the current value type. The value must be passed is as 'object' + * property. + */ + const Rep = React.createClass({ + displayName: "Rep", + + propTypes: { + object: React.PropTypes.any, + defaultRep: React.PropTypes.object, + mode: React.PropTypes.string + }, + + render: function () { + let rep = getRep(this.props.object, this.props.defaultRep); + return rep(this.props); + }, + }); + + // Helpers + + /** + * Return a rep object that is responsible for rendering given + * object. + * + * @param object {Object} Object to be rendered in the UI. This + * can be generic JS object as well as a grip (handle to a remote + * debuggee object). + * + * @param defaultObject {React.Component} The default template + * that should be used to render given object if none is found. + */ + function getRep(object, defaultRep = Obj) { + let type = typeof object; + if (type == "object" && object instanceof String) { + type = "string"; + } else if (type == "object" && object.type === "symbol") { + type = "symbol"; + } + + if (isGrip(object)) { + type = object.class; + } + + for (let i = 0; i < reps.length; i++) { + let rep = reps[i]; + try { + // supportsObject could return weight (not only true/false + // but a number), which would allow to priorities templates and + // support better extensibility. + if (rep.supportsObject(object, type)) { + return React.createFactory(rep.rep); + } + } catch (err) { + console.error(err); + } + } + + return React.createFactory(defaultRep.rep); + } + + // Exports from this module + exports.Rep = Rep; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* globals URLSearchParams */ + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + /** + * Create React factories for given arguments. + * Example: + * const { Rep } = createFactories(require("./rep")); + */ + function createFactories(args) { + let result = {}; + for (let p in args) { + result[p] = React.createFactory(args[p]); + } + return result; + } + + /** + * Returns true if the given object is a grip (see RDP protocol) + */ + function isGrip(object) { + return object && object.actor; + } + + function escapeNewLines(value) { + return value.replace(/\r/gm, "\\r").replace(/\n/gm, "\\n"); + } + + function cropMultipleLines(text, limit) { + return escapeNewLines(cropString(text, limit)); + } + + function cropString(text, limit, alternativeText) { + if (!alternativeText) { + alternativeText = "\u2026"; + } + + // Make sure it's a string. + text = text + ""; + + // Replace all non-printable characters, except of + // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D), + // with unicode replacement character (u+fffd). + // eslint-disable-next-line no-control-regex + let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g"); + text = text.replace(re, "\ufffd"); + + // Crop the string only if a limit is actually specified. + if (!limit || limit <= 0) { + return text; + } + + // Set the limit at least to the length of the alternative text + // plus one character of the original text. + if (limit <= alternativeText.length) { + limit = alternativeText.length + 1; + } + + let halfLimit = (limit - alternativeText.length) / 2; + + if (text.length > limit) { + return text.substr(0, Math.ceil(halfLimit)) + alternativeText + + text.substr(text.length - Math.floor(halfLimit)); + } + + return text; + } + + function parseURLParams(url) { + url = new URL(url); + return parseURLEncodedText(url.searchParams); + } + + function parseURLEncodedText(text) { + let params = []; + + // In case the text is empty just return the empty parameters + if (text == "") { + return params; + } + + let searchParams = new URLSearchParams(text); + let entries = [...searchParams.entries()]; + return entries.map(entry => { + return { + name: entry[0], + value: entry[1] + }; + }); + } + + function getFileName(url) { + let split = splitURLBase(url); + return split.name; + } + + function splitURLBase(url) { + if (!isDataURL(url)) { + return splitURLTrue(url); + } + return {}; + } + + function getURLDisplayString(url) { + return cropString(url); + } + + function isDataURL(url) { + return (url && url.substr(0, 5) == "data:"); + } + + function splitURLTrue(url) { + const reSplitFile = /(.*?):\/{2,3}([^\/]*)(.*?)([^\/]*?)($|\?.*)/; + let m = reSplitFile.exec(url); + + if (!m) { + return { + name: url, + path: url + }; + } else if (m[4] == "" && m[5] == "") { + return { + protocol: m[1], + domain: m[2], + path: m[3], + name: m[3] != "/" ? m[3] : m[2] + }; + } + + return { + protocol: m[1], + domain: m[2], + path: m[2] + m[3], + name: m[4] + m[5] + }; + } + + // Exports from this module + exports.createFactories = createFactories; + exports.isGrip = isGrip; + exports.cropString = cropString; + exports.cropMultipleLines = cropMultipleLines; + exports.parseURLParams = parseURLParams; + exports.parseURLEncodedText = parseURLEncodedText; + exports.getFileName = getFileName; + exports.getURLDisplayString = getURLDisplayString; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 46 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders undefined value + */ + const Undefined = React.createClass({ + displayName: "UndefinedRep", + + render: function () { + return ( + span({className: "objectBox objectBox-undefined"}, + "undefined" + ) + ); + }, + }); + + function supportsObject(object, type) { + if (object && object.type && object.type == "undefined") { + return true; + } + + return (type == "undefined"); + } + + // Exports from this module + + exports.Undefined = { + rep: Undefined, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 47 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders null value + */ + const Null = React.createClass({ + displayName: "NullRep", + + render: function () { + return ( + span({className: "objectBox objectBox-null"}, + "null" + ) + ); + }, + }); + + function supportsObject(object, type) { + if (object && object.type && object.type == "null") { + return true; + } + + return (object == null); + } + + // Exports from this module + + exports.Null = { + rep: Null, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 48 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const { cropMultipleLines } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a string. String value is enclosed within quotes. + */ + const StringRep = React.createClass({ + displayName: "StringRep", + + propTypes: { + useQuotes: React.PropTypes.bool, + }, + + getDefaultProps: function () { + return { + useQuotes: true, + }; + }, + + render: function () { + let text = this.props.object; + let member = this.props.member; + if (member && member.open) { + return ( + span({className: "objectBox objectBox-string"}, + "\"" + text + "\"" + ) + ); + } + + let croppedString = this.props.cropLimit ? + cropMultipleLines(text, this.props.cropLimit) : cropMultipleLines(text); + + let formattedString = this.props.useQuotes ? + "\"" + croppedString + "\"" : croppedString; + + return ( + span({className: "objectBox objectBox-string"}, formattedString + ) + ); + }, + }); + + function supportsObject(object, type) { + return (type == "string"); + } + + // Exports from this module + + exports.StringRep = { + rep: StringRep, + supportsObject: supportsObject, + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 49 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a number + */ + const Number = React.createClass({ + displayName: "Number", + + stringify: function (object) { + let isNegativeZero = Object.is(object, -0) || + (object.type && object.type == "-0"); + + return (isNegativeZero ? "-0" : String(object)); + }, + + render: function () { + let value = this.props.object; + + return ( + span({className: "objectBox objectBox-number"}, + this.stringify(value) + ) + ); + } + }); + + function supportsObject(object, type) { + return type == "boolean" || type == "number" || + (type == "object" && object.type == "-0"); + } + + // Exports from this module + + exports.Number = { + rep: Number, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 50 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const { createFactories } = __webpack_require__(45); + const { Caption } = createFactories(__webpack_require__(51)); + + // Shortcuts + const DOM = React.DOM; + + /** + * Renders an array. The array is enclosed by left and right bracket + * and the max number of rendered items depends on the current mode. + */ + let ArrayRep = React.createClass({ + displayName: "ArrayRep", + + getTitle: function (object, context) { + return "[" + object.length + "]"; + }, + + arrayIterator: function (array, max) { + let items = []; + let delim; + + for (let i = 0; i < array.length && i < max; i++) { + try { + let value = array[i]; + + delim = (i == array.length - 1 ? "" : ", "); + + items.push(ItemRep({ + key: i, + object: value, + // Hardcode tiny mode to avoid recursive handling. + mode: "tiny", + delim: delim + })); + } catch (exc) { + items.push(ItemRep({ + key: i, + object: exc, + mode: "tiny", + delim: delim + })); + } + } + + if (array.length > max) { + let objectLink = this.props.objectLink || DOM.span; + items.push(Caption({ + key: "more", + object: objectLink({ + object: this.props.object + }, (array.length - max) + " more…") + })); + } + + return items; + }, + + /** + * Returns true if the passed object is an array with additional (custom) + * properties, otherwise returns false. Custom properties should be + * displayed in extra expandable section. + * + * Example array with a custom property. + * let arr = [0, 1]; + * arr.myProp = "Hello"; + * + * @param {Array} array The array object. + */ + hasSpecialProperties: function (array) { + function isInteger(x) { + let y = parseInt(x, 10); + if (isNaN(y)) { + return false; + } + return x === y.toString(); + } + + let props = Object.getOwnPropertyNames(array); + for (let i = 0; i < props.length; i++) { + let p = props[i]; + + // Valid indexes are skipped + if (isInteger(p)) { + continue; + } + + // Ignore standard 'length' property, anything else is custom. + if (p != "length") { + return true; + } + } + + return false; + }, + + // Event Handlers + + onToggleProperties: function (event) { + }, + + onClickBracket: function (event) { + }, + + render: function () { + let mode = this.props.mode || "short"; + let object = this.props.object; + let items; + let brackets; + let needSpace = function (space) { + return space ? { left: "[ ", right: " ]"} : { left: "[", right: "]"}; + }; + + if (mode == "tiny") { + let isEmpty = object.length === 0; + items = DOM.span({className: "length"}, isEmpty ? "" : object.length); + brackets = needSpace(false); + } else { + let max = (mode == "short") ? 3 : 300; + items = this.arrayIterator(object, max); + brackets = needSpace(items.length > 0); + } + + let objectLink = this.props.objectLink || DOM.span; + + return ( + DOM.span({ + className: "objectBox objectBox-array"}, + objectLink({ + className: "arrayLeftBracket", + object: object + }, brackets.left), + items, + objectLink({ + className: "arrayRightBracket", + object: object + }, brackets.right), + DOM.span({ + className: "arrayProperties", + role: "group"} + ) + ) + ); + }, + }); + + /** + * Renders array item. Individual values are separated by a comma. + */ + let ItemRep = React.createFactory(React.createClass({ + displayName: "ItemRep", + + render: function () { + const { Rep } = createFactories(__webpack_require__(44)); + + let object = this.props.object; + let delim = this.props.delim; + let mode = this.props.mode; + return ( + DOM.span({}, + Rep({object: object, mode: mode}), + delim + ) + ); + } + })); + + function supportsObject(object, type) { + return Array.isArray(object) || + Object.prototype.toString.call(object) === "[object Arguments]"; + } + + // Exports from this module + exports.ArrayRep = { + rep: ArrayRep, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 51 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const DOM = React.DOM; + + /** + * Renders a caption. This template is used by other components + * that needs to distinguish between a simple text/value and a label. + */ + const Caption = React.createClass({ + displayName: "Caption", + + render: function () { + return ( + DOM.span({"className": "caption"}, this.props.object) + ); + }, + }); + + // Exports from this module + exports.Caption = Caption; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 52 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const { createFactories } = __webpack_require__(45); + const { Caption } = createFactories(__webpack_require__(51)); + const { PropRep } = createFactories(__webpack_require__(53)); + // Shortcuts + const { span } = React.DOM; + /** + * Renders an object. An object is represented by a list of its + * properties enclosed in curly brackets. + */ + const Obj = React.createClass({ + displayName: "Obj", + + propTypes: { + object: React.PropTypes.object, + mode: React.PropTypes.string, + }, + + getTitle: function (object) { + let className = object && object.class ? object.class : "Object"; + if (this.props.objectLink) { + return this.props.objectLink({ + object: object + }, className); + } + return className; + }, + + safePropIterator: function (object, max) { + max = (typeof max === "undefined") ? 3 : max; + try { + return this.propIterator(object, max); + } catch (err) { + console.error(err); + } + return []; + }, + + propIterator: function (object, max) { + let isInterestingProp = (t, value) => { + // Do not pick objects, it could cause recursion. + return (t == "boolean" || t == "number" || (t == "string" && value)); + }; + + // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=945377 + if (Object.prototype.toString.call(object) === "[object Generator]") { + object = Object.getPrototypeOf(object); + } + + // Object members with non-empty values are preferred since it gives the + // user a better overview of the object. + let props = this.getProps(object, max, isInterestingProp); + + if (props.length <= max) { + // There are not enough props yet (or at least, not enough props to + // be able to know whether we should print "more…" or not). + // Let's display also empty members and functions. + props = props.concat(this.getProps(object, max, (t, value) => { + return !isInterestingProp(t, value); + })); + } + + if (props.length > max) { + props.pop(); + let objectLink = this.props.objectLink || span; + + props.push(Caption({ + key: "more", + object: objectLink({ + object: object + }, (Object.keys(object).length - max) + " more…") + })); + } else if (props.length > 0) { + // Remove the last comma. + props[props.length - 1] = React.cloneElement( + props[props.length - 1], { delim: "" }); + } + + return props; + }, + + getProps: function (object, max, filter) { + let props = []; + + max = max || 3; + if (!object) { + return props; + } + + // Hardcode tiny mode to avoid recursive handling. + let mode = "tiny"; + + try { + for (let name in object) { + if (props.length > max) { + return props; + } + + let value; + try { + value = object[name]; + } catch (exc) { + continue; + } + + let t = typeof value; + if (filter(t, value)) { + props.push(PropRep({ + key: name, + mode: mode, + name: name, + object: value, + equal: ": ", + delim: ", ", + })); + } + } + } catch (err) { + console.error(err); + } + + return props; + }, + + render: function () { + let object = this.props.object; + let props = this.safePropIterator(object); + let objectLink = this.props.objectLink || span; + + if (this.props.mode == "tiny" || !props.length) { + return ( + span({className: "objectBox objectBox-object"}, + objectLink({className: "objectTitle"}, this.getTitle(object)) + ) + ); + } + + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, " { "), + props, + objectLink({ + className: "objectRightBrace", + object: object + }, " }") + ) + ); + }, + }); + function supportsObject(object, type) { + return true; + } + + // Exports from this module + exports.Obj = { + rep: Obj, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 53 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + const React = __webpack_require__(6); + const { createFactories } = __webpack_require__(45); + const { span } = React.DOM; + + /** + * Property for Obj (local JS objects), Grip (remote JS objects) + * and GripMap (remote JS maps and weakmaps) reps. + * It's used to render object properties. + */ + let PropRep = React.createFactory(React.createClass({ + displayName: "PropRep", + + propTypes: { + // Property name. + name: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.object, + ]).isRequired, + // Equal character rendered between property name and value. + equal: React.PropTypes.string, + // Delimiter character used to separate individual properties. + delim: React.PropTypes.string, + mode: React.PropTypes.string, + }, + + render: function () { + const { Grip } = __webpack_require__(54); + let { Rep } = createFactories(__webpack_require__(44)); + + let key; + // The key can be a simple string, for plain objects, + // or another object for maps and weakmaps. + if (typeof this.props.name === "string") { + key = span({"className": "nodeName"}, this.props.name); + } else { + key = Rep({ + object: this.props.name, + mode: this.props.mode || "tiny", + defaultRep: Grip, + objectLink: this.props.objectLink, + }); + } + + return ( + span({}, + key, + span({ + "className": "objectEqual" + }, this.props.equal), + Rep(this.props), + span({ + "className": "objectComma" + }, this.props.delim) + ) + ); + } + })); + + // Exports from this module + exports.PropRep = PropRep; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 54 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + // Dependencies + const { createFactories, isGrip } = __webpack_require__(45); + const { Caption } = createFactories(__webpack_require__(51)); + const { PropRep } = createFactories(__webpack_require__(53)); + // Shortcuts + const { span } = React.DOM; + + /** + * Renders generic grip. Grip is client representation + * of remote JS object and is used as an input object + * for this rep component. + */ + const GripRep = React.createClass({ + displayName: "Grip", + + propTypes: { + object: React.PropTypes.object.isRequired, + mode: React.PropTypes.string, + isInterestingProp: React.PropTypes.func + }, + + getTitle: function (object) { + if (this.props.objectLink) { + return this.props.objectLink({ + object: object + }, object.class); + } + return object.class || "Object"; + }, + + safePropIterator: function (object, max) { + max = (typeof max === "undefined") ? 3 : max; + try { + return this.propIterator(object, max); + } catch (err) { + console.error(err); + } + return []; + }, + + propIterator: function (object, max) { + // Property filter. Show only interesting properties to the user. + let isInterestingProp = this.props.isInterestingProp || ((type, value) => { + return ( + type == "boolean" || + type == "number" || + (type == "string" && value.length != 0) + ); + }); + + let ownProperties = object.preview ? object.preview.ownProperties : []; + let indexes = this.getPropIndexes(ownProperties, max, isInterestingProp); + if (indexes.length < max && indexes.length < object.ownPropertyLength) { + // There are not enough props yet. Then add uninteresting props to display them. + indexes = indexes.concat( + this.getPropIndexes(ownProperties, max - indexes.length, (t, value, name) => { + return !isInterestingProp(t, value, name); + }) + ); + } + + let props = this.getProps(ownProperties, indexes); + if (props.length < object.ownPropertyLength) { + // There are some undisplayed props. Then display "more...". + let objectLink = this.props.objectLink || span; + + props.push(Caption({ + key: "more", + object: objectLink({ + object: object + }, ((object ? object.ownPropertyLength : 0) - max) + " more…") + })); + } else if (props.length > 0) { + // Remove the last comma. + // NOTE: do not change comp._store.props directly to update a property, + // it should be re-rendered or cloned with changed props + let last = props.length - 1; + props[last] = React.cloneElement(props[last], { + delim: "" + }); + } + + return props; + }, + + /** + * Get props ordered by index. + * + * @param {Object} ownProperties Props object. + * @param {Array} indexes Indexes of props. + * @return {Array} Props. + */ + getProps: function (ownProperties, indexes) { + let props = []; + + if (!ownProperties || ownProperties.length == 0) { + return props; + } + + // Make indexes ordered by ascending. + indexes.sort(function (a, b) { + return a - b; + }); + + indexes.forEach((i) => { + let name = Object.keys(ownProperties)[i]; + let prop = ownProperties[name]; + let value = prop.value !== undefined ? prop.value : prop; + props.push(PropRep(Object.assign({}, this.props, { + key: name, + mode: "tiny", + name: name, + object: value, + equal: ": ", + delim: ", ", + defaultRep: Grip + }))); + }); + + return props; + }, + + /** + * Get the indexes of props in the object. + * + * @param {Object} ownProperties Props object. + * @param {Number} max The maximum length of indexes array. + * @param {Function} filter Filter the props you want. + * @return {Array} Indexes of interesting props in the object. + */ + getPropIndexes: function (ownProperties, max, filter) { + let indexes = []; + + try { + let i = 0; + for (let name in ownProperties) { + if (indexes.length >= max) { + return indexes; + } + + let prop = ownProperties[name]; + let value = prop.value !== undefined ? prop.value : prop; + + // Type is specified in grip's "class" field and for primitive + // values use typeof. + let type = (value.class || typeof value); + type = type.toLowerCase(); + + if (filter(type, value, name)) { + indexes.push(i); + } + i++; + } + } catch (err) { + console.error(err); + } + + return indexes; + }, + + render: function () { + let object = this.props.object; + let props = this.safePropIterator(object, + (this.props.mode == "long") ? 100 : 3); + + let objectLink = this.props.objectLink || span; + if (this.props.mode == "tiny" || !props.length) { + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, "") + ) + ); + } + + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, " { "), + props, + objectLink({ + className: "objectRightBrace", + object: object + }, " }") + ) + ); + }, + }); + + // Registration + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + return (object.preview && object.preview.ownProperties); + } + + let Grip = { + rep: GripRep, + supportsObject: supportsObject + }; + + // Exports from this module + exports.Grip = Grip; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 55 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a symbol. + */ + const SymbolRep = React.createClass({ + displayName: "SymbolRep", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + render: function () { + let {object} = this.props; + let {name} = object; + + return ( + span({className: "objectBox objectBox-symbol"}, + `Symbol(${name || ""})` + ) + ); + }, + }); + + function supportsObject(object, type) { + return (type == "symbol"); + } + + // Exports from this module + exports.SymbolRep = { + rep: SymbolRep, + supportsObject: supportsObject, + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 56 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { createFactories, isGrip } = __webpack_require__(45); + const { StringRep } = __webpack_require__(48); + + // Shortcuts + const { span } = React.DOM; + const { rep: StringRepFactory } = createFactories(StringRep); + + /** + * Renders DOM attribute + */ + let Attribute = React.createClass({ + displayName: "Attr", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + getTitle: function (grip) { + return grip.preview.nodeName; + }, + + render: function () { + let grip = this.props.object; + let value = grip.preview.value; + let objectLink = this.props.objectLink || span; + + return ( + objectLink({className: "objectLink-Attr"}, + span({}, + span({className: "attrTitle"}, + this.getTitle(grip) + ), + span({className: "attrEqual"}, + "=" + ), + StringRepFactory({object: value}) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (type == "Attr" && grip.preview); + } + + exports.Attribute = { + rep: Attribute, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 57 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Used to render JS built-in Date() object. + */ + let DateTime = React.createClass({ + displayName: "Date", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return this.props.objectLink({ + object: grip + }, grip.class + " "); + } + return ""; + }, + + render: function () { + let grip = this.props.object; + return ( + span({className: "objectBox"}, + this.getTitle(grip), + span({className: "Date"}, + new Date(grip.preview.timestamp).toISOString() + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (type == "Date" && grip.preview); + } + + // Exports from this module + exports.DateTime = { + rep: DateTime, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 58 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, getURLDisplayString } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders DOM document object. + */ + let Document = React.createClass({ + displayName: "Document", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + getLocation: function (grip) { + let location = grip.preview.location; + return location ? getURLDisplayString(location) : ""; + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return span({className: "objectBox"}, + this.props.objectLink({ + object: grip + }, grip.class + " ") + ); + } + return ""; + }, + + getTooltip: function (doc) { + return doc.location.href; + }, + + render: function () { + let grip = this.props.object; + + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(grip), + span({className: "objectPropValue"}, + this.getLocation(grip) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + + return (object.preview && type == "HTMLDocument"); + } + + // Exports from this module + exports.Document = { + rep: Document, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 59 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { createFactories, isGrip } = __webpack_require__(45); + const { rep } = createFactories(__webpack_require__(54).Grip); + + /** + * Renders DOM event objects. + */ + let Event = React.createClass({ + displayName: "event", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + render: function () { + // Use `Object.assign` to keep `this.props` without changes because: + // 1. JSON.stringify/JSON.parse is slow. + // 2. Immutable.js is planned for the future. + let props = Object.assign({}, this.props); + props.object = Object.assign({}, this.props.object); + props.object.preview = Object.assign({}, this.props.object.preview); + props.object.preview.ownProperties = props.object.preview.properties; + delete props.object.preview.properties; + props.object.ownPropertyLength = + Object.keys(props.object.preview.ownProperties).length; + + switch (props.object.class) { + case "MouseEvent": + props.isInterestingProp = (type, value, name) => { + return (name == "clientX" || + name == "clientY" || + name == "layerX" || + name == "layerY"); + }; + break; + case "KeyboardEvent": + props.isInterestingProp = (type, value, name) => { + return (name == "key" || + name == "charCode" || + name == "keyCode"); + }; + break; + case "MessageEvent": + props.isInterestingProp = (type, value, name) => { + return (name == "isTrusted" || + name == "data"); + }; + break; + } + return rep(props); + } + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (grip.preview && grip.preview.kind == "DOMEvent"); + } + + // Exports from this module + exports.Event = { + rep: Event, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 60 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, cropString } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * This component represents a template for Function objects. + */ + let Func = React.createClass({ + displayName: "Func", + + propTypes: { + object: React.PropTypes.object.isRequired + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return this.props.objectLink({ + object: grip + }, "function "); + } + return ""; + }, + + summarizeFunction: function (grip) { + let name = grip.userDisplayName || grip.displayName || grip.name || "function"; + return cropString(name + "()", 100); + }, + + render: function () { + let grip = this.props.object; + + return ( + span({className: "objectBox objectBox-function"}, + this.getTitle(grip), + this.summarizeFunction(grip) + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return (type == "function"); + } + + return (type == "Function"); + } + + // Exports from this module + + exports.Func = { + rep: Func, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 61 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a grip object with regular expression. + */ + let RegExp = React.createClass({ + displayName: "regexp", + + propTypes: { + object: React.PropTypes.object.isRequired, + }, + + getSource: function (grip) { + return grip.displayString; + }, + + render: function () { + let grip = this.props.object; + let objectLink = this.props.objectLink || span; + + return ( + span({className: "objectBox objectBox-regexp"}, + objectLink({ + object: grip, + className: "regexpSource" + }, this.getSource(grip)) + ) + ); + }, + }); + + // Registration + + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + + return (type == "RegExp"); + } + + // Exports from this module + exports.RegExp = { + rep: RegExp, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 62 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, getURLDisplayString } = __webpack_require__(45); + + // Shortcuts + const DOM = React.DOM; + + /** + * Renders a grip representing CSSStyleSheet + */ + let StyleSheet = React.createClass({ + displayName: "object", + + propTypes: { + object: React.PropTypes.object.isRequired, + }, + + getTitle: function (grip) { + let title = "StyleSheet "; + if (this.props.objectLink) { + return DOM.span({className: "objectBox"}, + this.props.objectLink({ + object: grip + }, title) + ); + } + return title; + }, + + getLocation: function (grip) { + // Embedded stylesheets don't have URL and so, no preview. + let url = grip.preview ? grip.preview.url : ""; + return url ? getURLDisplayString(url) : ""; + }, + + render: function () { + let grip = this.props.object; + + return ( + DOM.span({className: "objectBox objectBox-object"}, + this.getTitle(grip), + DOM.span({className: "objectPropValue"}, + this.getLocation(grip) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + + return (type == "CSSStyleSheet"); + } + + // Exports from this module + + exports.StyleSheet = { + rep: StyleSheet, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 63 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, cropMultipleLines } = __webpack_require__(45); + + // Shortcuts + const DOM = React.DOM; + + /** + * Renders DOM #text node. + */ + let TextNode = React.createClass({ + displayName: "TextNode", + + propTypes: { + object: React.PropTypes.object.isRequired, + mode: React.PropTypes.string, + }, + + getTextContent: function (grip) { + return cropMultipleLines(grip.preview.textContent); + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return this.props.objectLink({ + object: grip + }, "#text"); + } + return ""; + }, + + render: function () { + let grip = this.props.object; + let mode = this.props.mode || "short"; + + if (mode == "short" || mode == "tiny") { + return ( + DOM.span({className: "objectBox objectBox-textNode"}, + this.getTitle(grip), + "\"" + this.getTextContent(grip) + "\"" + ) + ); + } + + let objectLink = this.props.objectLink || DOM.span; + return ( + DOM.span({className: "objectBox objectBox-textNode"}, + this.getTitle(grip), + objectLink({ + object: grip + }, "<"), + DOM.span({className: "nodeTag"}, "TextNode"), + " textContent=\"", + DOM.span({className: "nodeValue"}, + this.getTextContent(grip) + ), + "\"", + objectLink({ + object: grip + }, ">;") + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (grip.preview && grip.class == "Text"); + } + + // Exports from this module + exports.TextNode = { + rep: TextNode, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 64 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, getURLDisplayString } = __webpack_require__(45); + + // Shortcuts + const DOM = React.DOM; + + /** + * Renders a grip representing a window. + */ + let Window = React.createClass({ + displayName: "Window", + + propTypes: { + object: React.PropTypes.object.isRequired, + mode: React.PropTypes.string + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return DOM.span({className: "objectBox"}, + this.props.objectLink({ + object: grip + }, grip.class + " ") + ); + } + return ""; + }, + + getLocation: function (grip) { + return getURLDisplayString(grip.preview.url); + }, + + getDisplayValue: function (grip) { + if (this.props.mode === "tiny") { + return grip.isGlobal ? "Global" : "Window"; + } else { + return this.getLocation(grip); + } + }, + + render: function () { + let grip = this.props.object; + + return ( + DOM.span({className: "objectBox objectBox-Window"}, + this.getTitle(grip), + DOM.span({className: "objectPropValue"}, + this.getDisplayValue(grip) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(object, type) { + if (!isGrip(object)) { + return false; + } + + return (object.preview && type == "Window"); + } + + // Exports from this module + exports.Window = { + rep: Window, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 65 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a grip object with textual data. + */ + let ObjectWithText = React.createClass({ + displayName: "ObjectWithText", + + propTypes: { + object: React.PropTypes.object.isRequired, + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return span({className: "objectBox"}, + this.props.objectLink({ + object: grip + }, this.getType(grip) + " ") + ); + } + return ""; + }, + + getType: function (grip) { + return grip.class; + }, + + getDescription: function (grip) { + return "\"" + grip.preview.text + "\""; + }, + + render: function () { + let grip = this.props.object; + return ( + span({className: "objectBox objectBox-" + this.getType(grip)}, + this.getTitle(grip), + span({className: "objectPropValue"}, + this.getDescription(grip) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (grip.preview && grip.preview.kind == "ObjectWithText"); + } + + // Exports from this module + exports.ObjectWithText = { + rep: ObjectWithText, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 66 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // ReactJS + const React = __webpack_require__(6); + + // Reps + const { isGrip, getURLDisplayString } = __webpack_require__(45); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders a grip object with URL data. + */ + let ObjectWithURL = React.createClass({ + displayName: "ObjectWithURL", + + propTypes: { + object: React.PropTypes.object.isRequired, + }, + + getTitle: function (grip) { + if (this.props.objectLink) { + return span({className: "objectBox"}, + this.props.objectLink({ + object: grip + }, this.getType(grip) + " ") + ); + } + return ""; + }, + + getType: function (grip) { + return grip.class; + }, + + getDescription: function (grip) { + return getURLDisplayString(grip.preview.url); + }, + + render: function () { + let grip = this.props.object; + return ( + span({className: "objectBox objectBox-" + this.getType(grip)}, + this.getTitle(grip), + span({className: "objectPropValue"}, + this.getDescription(grip) + ) + ) + ); + }, + }); + + // Registration + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (grip.preview && grip.preview.kind == "ObjectWithURL"); + } + + // Exports from this module + exports.ObjectWithURL = { + rep: ObjectWithURL, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 67 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const { createFactories, isGrip } = __webpack_require__(45); + const { Caption } = createFactories(__webpack_require__(51)); + + // Shortcuts + const { span } = React.DOM; + + /** + * Renders an array. The array is enclosed by left and right bracket + * and the max number of rendered items depends on the current mode. + */ + let GripArray = React.createClass({ + displayName: "GripArray", + + propTypes: { + object: React.PropTypes.object.isRequired, + mode: React.PropTypes.string, + provider: React.PropTypes.object, + }, + + getLength: function (grip) { + return grip.preview ? grip.preview.length : 0; + }, + + getTitle: function (object, context) { + let objectLink = this.props.objectLink || span; + if (this.props.mode != "tiny") { + return objectLink({ + object: object + }, object.class + " "); + } + return ""; + }, + + arrayIterator: function (grip, max) { + let items = []; + + if (!grip.preview || !grip.preview.length) { + return items; + } + + let array = grip.preview.items; + if (!array) { + return items; + } + + let delim; + // number of grip.preview.items is limited to 10, but we may have more + // items in grip-array + let delimMax = grip.preview.length > array.length ? + array.length : array.length - 1; + let provider = this.props.provider; + + for (let i = 0; i < array.length && i < max; i++) { + try { + let itemGrip = array[i]; + let value = provider ? provider.getValue(itemGrip) : itemGrip; + + delim = (i == delimMax ? "" : ", "); + + items.push(GripArrayItem(Object.assign({}, this.props, { + key: i, + object: value, + delim: delim} + ))); + } catch (exc) { + items.push(GripArrayItem(Object.assign({}, this.props, { + object: exc, + delim: delim, + key: i} + ))); + } + } + if (array.length > max || grip.preview.length > array.length) { + let objectLink = this.props.objectLink || span; + let leftItemNum = grip.preview.length - max > 0 ? + grip.preview.length - max : grip.preview.length - array.length; + items.push(Caption({ + key: "more", + object: objectLink({ + object: this.props.object + }, leftItemNum + " more…") + })); + } + + return items; + }, + + render: function () { + let mode = this.props.mode || "short"; + let object = this.props.object; + + let items; + let brackets; + let needSpace = function (space) { + return space ? { left: "[ ", right: " ]"} : { left: "[", right: "]"}; + }; + + if (mode == "tiny") { + let objectLength = this.getLength(object); + let isEmpty = objectLength === 0; + items = span({className: "length"}, isEmpty ? "" : objectLength); + brackets = needSpace(false); + } else { + let max = (mode == "short") ? 3 : 300; + items = this.arrayIterator(object, max); + brackets = needSpace(items.length > 0); + } + + let objectLink = this.props.objectLink || span; + let title = this.getTitle(object); + + return ( + span({ + className: "objectBox objectBox-array"}, + title, + objectLink({ + className: "arrayLeftBracket", + object: object + }, brackets.left), + items, + objectLink({ + className: "arrayRightBracket", + object: object + }, brackets.right), + span({ + className: "arrayProperties", + role: "group"} + ) + ) + ); + }, + }); + + /** + * Renders array item. Individual values are separated by + * a delimiter (a comma by default). + */ + let GripArrayItem = React.createFactory(React.createClass({ + displayName: "GripArrayItem", + + propTypes: { + delim: React.PropTypes.string, + }, + + render: function () { + let { Rep } = createFactories(__webpack_require__(44)); + + return ( + span({}, + Rep(Object.assign({}, this.props, { + mode: "tiny" + })), + this.props.delim + ) + ); + } + })); + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + + return (grip.preview && grip.preview.kind == "ArrayLike"); + } + + // Exports from this module + exports.GripArray = { + rep: GripArray, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 68 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + // Make this available to both AMD and CJS environments + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) { + // Dependencies + const React = __webpack_require__(6); + const { createFactories, isGrip } = __webpack_require__(45); + const { Caption } = createFactories(__webpack_require__(51)); + const { PropRep } = createFactories(__webpack_require__(53)); + + // Shortcuts + const { span } = React.DOM; + /** + * Renders an map. A map is represented by a list of its + * entries enclosed in curly brackets. + */ + const GripMap = React.createClass({ + displayName: "GripMap", + + propTypes: { + object: React.PropTypes.object, + mode: React.PropTypes.string, + }, + + getTitle: function (object) { + let title = object && object.class ? object.class : "Map"; + if (this.props.objectLink) { + return this.props.objectLink({ + object: object + }, title); + } + return title; + }, + + safeEntriesIterator: function (object, max) { + max = (typeof max === "undefined") ? 3 : max; + try { + return this.entriesIterator(object, max); + } catch (err) { + console.error(err); + } + return []; + }, + + entriesIterator: function (object, max) { + // Entry filter. Show only interesting entries to the user. + let isInterestingEntry = this.props.isInterestingEntry || ((type, value) => { + return ( + type == "boolean" || + type == "number" || + (type == "string" && value.length != 0) + ); + }); + + let mapEntries = object.preview && object.preview.entries + ? object.preview.entries : []; + + let indexes = this.getEntriesIndexes(mapEntries, max, isInterestingEntry); + if (indexes.length < max && indexes.length < mapEntries.length) { + // There are not enough entries yet, so we add uninteresting entries. + indexes = indexes.concat( + this.getEntriesIndexes(mapEntries, max - indexes.length, (t, value, name) => { + return !isInterestingEntry(t, value, name); + }) + ); + } + + let entries = this.getEntries(mapEntries, indexes); + if (entries.length < mapEntries.length) { + // There are some undisplayed entries. Then display "more…". + let objectLink = this.props.objectLink || span; + + entries.push(Caption({ + key: "more", + object: objectLink({ + object: object + }, `${mapEntries.length - max} more…`) + })); + } + + return entries; + }, + + /** + * Get entries ordered by index. + * + * @param {Array} entries Entries array. + * @param {Array} indexes Indexes of entries. + * @return {Array} Array of PropRep. + */ + getEntries: function (entries, indexes) { + // Make indexes ordered by ascending. + indexes.sort(function (a, b) { + return a - b; + }); + + return indexes.map((index, i) => { + let [key, entryValue] = entries[index]; + let value = entryValue.value !== undefined ? entryValue.value : entryValue; + + return PropRep({ + // key, + name: key, + equal: ": ", + object: value, + // Do not add a trailing comma on the last entry + // if there won't be a "more..." item. + delim: (i < indexes.length - 1 || indexes.length < entries.length) ? ", " : "", + mode: "tiny", + objectLink: this.props.objectLink, + }); + }); + }, + + /** + * Get the indexes of entries in the map. + * + * @param {Array} entries Entries array. + * @param {Number} max The maximum length of indexes array. + * @param {Function} filter Filter the entry you want. + * @return {Array} Indexes of filtered entries in the map. + */ + getEntriesIndexes: function (entries, max, filter) { + return entries + .reduce((indexes, [key, entry], i) => { + if (indexes.length < max) { + let value = (entry && entry.value !== undefined) ? entry.value : entry; + // Type is specified in grip's "class" field and for primitive + // values use typeof. + let type = (value && value.class ? value.class : typeof value).toLowerCase(); + + if (filter(type, value, key)) { + indexes.push(i); + } + } + + return indexes; + }, []); + }, + + render: function () { + let object = this.props.object; + let props = this.safeEntriesIterator(object, + (this.props.mode == "long") ? 100 : 3); + + let objectLink = this.props.objectLink || span; + if (this.props.mode == "tiny") { + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, "") + ) + ); + } + + return ( + span({className: "objectBox objectBox-object"}, + this.getTitle(object), + objectLink({ + className: "objectLeftBrace", + object: object + }, " { "), + props, + objectLink({ + className: "objectRightBrace", + object: object + }, " }") + ) + ); + }, + }); + + function supportsObject(grip, type) { + if (!isGrip(grip)) { + return false; + } + return (grip.preview && grip.preview.kind == "MapLike"); + } + + // Exports from this module + exports.GripMap = { + rep: GripMap, + supportsObject: supportsObject + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 69 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * Copyright (c) 2007-2016, Alexandru Marasteanu + * 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 this software 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 AUTHORS OR COPYRIGHT HOLDERS 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. + * + */ + + /* globals window, exports, define */ + + (function(window) { + 'use strict' + + var re = { + not_string: /[^s]/, + not_bool: /[^t]/, + not_type: /[^T]/, + not_primitive: /[^v]/, + number: /[diefg]/, + numeric_arg: /bcdiefguxX/, + json: /[j]/, + not_json: /[^j]/, + text: /^[^\x25]+/, + modulo: /^\x25{2}/, + placeholder: /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijosStTuvxX])/, + key: /^([a-z_][a-z_\d]*)/i, + key_access: /^\.([a-z_][a-z_\d]*)/i, + index_access: /^\[(\d+)\]/, + sign: /^[\+\-]/ + } + + function sprintf() { + var key = arguments[0], cache = sprintf.cache + if (!(cache[key] && cache.hasOwnProperty(key))) { + cache[key] = sprintf.parse(key) + } + return sprintf.format.call(null, cache[key], arguments) + } + + sprintf.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length, is_positive = true, sign = '' + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]) + if (node_type === 'string') { + output[output.length] = parse_tree[i] + } + else if (node_type === 'array') { + match = parse_tree[i] // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor] + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw new Error(sprintf('[sprintf] property "%s" does not exist', match[2][k])) + } + arg = arg[match[2][k]] + } + } + else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]] + } + else { // positional argument (implicit) + arg = argv[cursor++] + } + + if (re.not_type.test(match[8]) && re.not_primitive.test(match[8]) && get_type(arg) == 'function') { + arg = arg() + } + + if (re.numeric_arg.test(match[8]) && (get_type(arg) != 'number' && isNaN(arg))) { + throw new TypeError(sprintf("[sprintf] expecting number but found %s", get_type(arg))) + } + + if (re.number.test(match[8])) { + is_positive = arg >= 0 + } + + switch (match[8]) { + case 'b': + arg = parseInt(arg, 10).toString(2) + break + case 'c': + arg = String.fromCharCode(parseInt(arg, 10)) + break + case 'd': + case 'i': + arg = parseInt(arg, 10) + break + case 'j': + arg = JSON.stringify(arg, null, match[6] ? parseInt(match[6]) : 0) + break + case 'e': + arg = match[7] ? parseFloat(arg).toExponential(match[7]) : parseFloat(arg).toExponential() + break + case 'f': + arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg) + break + case 'g': + arg = match[7] ? parseFloat(arg).toPrecision(match[7]) : parseFloat(arg) + break + case 'o': + arg = arg.toString(8) + break + case 's': + case 'S': + arg = String(arg) + arg = (match[7] ? arg.substring(0, match[7]) : arg) + break + case 't': + arg = String(!!arg) + arg = (match[7] ? arg.substring(0, match[7]) : arg) + break + case 'T': + arg = get_type(arg) + arg = (match[7] ? arg.substring(0, match[7]) : arg) + break + case 'u': + arg = parseInt(arg, 10) >>> 0 + break + case 'v': + arg = arg.valueOf() + arg = (match[7] ? arg.substring(0, match[7]) : arg) + break + case 'x': + arg = parseInt(arg, 10).toString(16) + break + case 'X': + arg = parseInt(arg, 10).toString(16).toUpperCase() + break + } + if (re.json.test(match[8])) { + output[output.length] = arg + } + else { + if (re.number.test(match[8]) && (!is_positive || match[3])) { + sign = is_positive ? '+' : '-' + arg = arg.toString().replace(re.sign, '') + } + else { + sign = '' + } + pad_character = match[4] ? match[4] === '0' ? '0' : match[4].charAt(1) : ' ' + pad_length = match[6] - (sign + arg).length + pad = match[6] ? (pad_length > 0 ? str_repeat(pad_character, pad_length) : '') : '' + output[output.length] = match[5] ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg) + } + } + } + return output.join('') + } + + sprintf.cache = {} + + sprintf.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0 + while (_fmt) { + if ((match = re.text.exec(_fmt)) !== null) { + parse_tree[parse_tree.length] = match[0] + } + else if ((match = re.modulo.exec(_fmt)) !== null) { + parse_tree[parse_tree.length] = '%' + } + else if ((match = re.placeholder.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1 + var field_list = [], replacement_field = match[2], field_match = [] + if ((field_match = re.key.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = re.key_access.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + } + else if ((field_match = re.index_access.exec(replacement_field)) !== null) { + field_list[field_list.length] = field_match[1] + } + else { + throw new SyntaxError("[sprintf] failed to parse named argument key") + } + } + } + else { + throw new SyntaxError("[sprintf] failed to parse named argument key") + } + match[2] = field_list + } + else { + arg_names |= 2 + } + if (arg_names === 3) { + throw new Error("[sprintf] mixing positional and named placeholders is not (yet) supported") + } + parse_tree[parse_tree.length] = match + } + else { + throw new SyntaxError("[sprintf] unexpected placeholder") + } + _fmt = _fmt.substring(match[0].length) + } + return parse_tree + } + + var vsprintf = function(fmt, argv, _argv) { + _argv = (argv || []).slice(0) + _argv.splice(0, 0, fmt) + return sprintf.apply(null, _argv) + } + + /** + * helpers + */ + function get_type(variable) { + if (typeof variable === 'number') { + return 'number' + } + else if (typeof variable === 'string') { + return 'string' + } + else { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase() + } + } + + var preformattedPadding = { + '0': ['', '0', '00', '000', '0000', '00000', '000000', '0000000'], + ' ': ['', ' ', ' ', ' ', ' ', ' ', ' ', ' '], + '_': ['', '_', '__', '___', '____', '_____', '______', '_______'], + } + function str_repeat(input, multiplier) { + if (multiplier >= 0 && multiplier <= 7 && preformattedPadding[input]) { + return preformattedPadding[input][multiplier] + } + return Array(multiplier + 1).join(input) + } + + /** + * export to either browser or node.js + */ + if (true) { + exports.sprintf = sprintf + exports.vsprintf = vsprintf + } + else { + window.sprintf = sprintf + window.vsprintf = vsprintf + + if (typeof define === 'function' && define.amd) { + define(function() { + return { + sprintf: sprintf, + vsprintf: vsprintf + } + }) + } + } + })(typeof window === 'undefined' ? this : window); + + +/***/ }, +/* 70 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + /** + * EventEmitter. + */ + + var EventEmitter = function EventEmitter() {}; + module.exports = EventEmitter; + + const { Cu } = __webpack_require__(71); + const promise = __webpack_require__(76); + + /** + * Decorate an object with event emitter functionality. + * + * @param Object aObjectToDecorate + * Bind all public methods of EventEmitter to + * the aObjectToDecorate object. + */ + EventEmitter.decorate = function EventEmitter_decorate (aObjectToDecorate) { + let emitter = new EventEmitter(); + aObjectToDecorate.on = emitter.on.bind(emitter); + aObjectToDecorate.off = emitter.off.bind(emitter); + aObjectToDecorate.once = emitter.once.bind(emitter); + aObjectToDecorate.emit = emitter.emit.bind(emitter); + }; + + EventEmitter.prototype = { + /** + * Connect a listener. + * + * @param string aEvent + * The event name to which we're connecting. + * @param function aListener + * Called when the event is fired. + */ + on: function EventEmitter_on(aEvent, aListener) { + if (!this._eventEmitterListeners) + this._eventEmitterListeners = new Map(); + if (!this._eventEmitterListeners.has(aEvent)) { + this._eventEmitterListeners.set(aEvent, []); + } + this._eventEmitterListeners.get(aEvent).push(aListener); + }, + + /** + * Listen for the next time an event is fired. + * + * @param string aEvent + * The event name to which we're connecting. + * @param function aListener + * (Optional) Called when the event is fired. Will be called at most + * one time. + * @return promise + * A promise which is resolved when the event next happens. The + * resolution value of the promise is the first event argument. If + * you need access to second or subsequent event arguments (it's rare + * that this is needed) then use aListener + */ + once: function EventEmitter_once(aEvent, aListener) { + let deferred = promise.defer(); + + let handler = (aEvent, aFirstArg, ...aRest) => { + this.off(aEvent, handler); + if (aListener) { + aListener.apply(null, [aEvent, aFirstArg, ...aRest]); + } + deferred.resolve(aFirstArg); + }; + + handler._originalListener = aListener; + this.on(aEvent, handler); + + return deferred.promise; + }, + + /** + * Remove a previously-registered event listener. Works for events + * registered with either on or once. + * + * @param string aEvent + * The event name whose listener we're disconnecting. + * @param function aListener + * The listener to remove. + */ + off: function EventEmitter_off(aEvent, aListener) { + if (!this._eventEmitterListeners) + return; + let listeners = this._eventEmitterListeners.get(aEvent); + if (listeners) { + this._eventEmitterListeners.set(aEvent, listeners.filter(l => { + return l !== aListener && l._originalListener !== aListener; + })); + } + }, + + /** + * Emit an event. All arguments to this method will + * be sent to listener functions. + */ + emit: function EventEmitter_emit(aEvent) { + if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(aEvent)) { + return; + } + + let originalListeners = this._eventEmitterListeners.get(aEvent); + for (let listener of this._eventEmitterListeners.get(aEvent)) { + // If the object was destroyed during event emission, stop + // emitting. + if (!this._eventEmitterListeners) { + break; + } + + // If listeners were removed during emission, make sure the + // event handler we're going to fire wasn't removed. + if (originalListeners === this._eventEmitterListeners.get(aEvent) || + this._eventEmitterListeners.get(aEvent).some(l => l === listener)) { + try { + listener.apply(null, arguments); + } + catch (ex) { + // Prevent a bad listener from interfering with the others. + let msg = ex + ": " + ex.stack; + //console.error(msg); + console.log(msg); + } + } + } + }, + }; + + +/***/ }, +/* 71 */ +/***/ function(module, exports, __webpack_require__) { + + /* + * A sham for https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/chrome + */ + + var { inDOMUtils } = __webpack_require__(72); + + var ourServices = { + inIDOMUtils: inDOMUtils, + nsIClipboardHelper: { + copyString: () => {} + }, + nsIXULChromeRegistry: { + isLocaleRTL: () => {return false;} + }, + nsIDOMParser: { + + }, + }; + + module.exports = { + Cc: name => { + if(typeof console !== "undefined") { + console.log('Cc sham for', name); + } + return { + getService: (name) => ourServices[name], + createInstance: (iface) => ourServices[iface], + }; + }, + CC: (name, iface, method) => { + if(typeof console !== "undefined") { + console.log('CC sham for', name, iface, method); + } + return { + }; + }, + Ci: { + nsIThread: { + "DISPATCH_NORMAL":0, + "DISPATCH_SYNC":1 + }, + nsIDOMNode: typeof HTMLElement !== "undefined" ? HTMLElement : null, + nsIFocusManager: { + MOVEFOCUS_BACKWARD: 2, + MOVEFOCUS_FORWARD: 1, + }, + nsIDOMKeyEvent: { + + }, + nsIDOMCSSRule: {"UNKNOWN_RULE":0,"STYLE_RULE":1,"CHARSET_RULE":2,"IMPORT_RULE":3,"MEDIA_RULE":4,"FONT_FACE_RULE":5,"PAGE_RULE":6,"KEYFRAMES_RULE":7,"KEYFRAME_RULE":8,"MOZ_KEYFRAMES_RULE":7,"MOZ_KEYFRAME_RULE":8,"NAMESPACE_RULE":10,"COUNTER_STYLE_RULE":11,"SUPPORTS_RULE":12,"FONT_FEATURE_VALUES_RULE":14}, + inIDOMUtils: "inIDOMUtils", + nsIClipboardHelper: "nsIClipboardHelper", + nsIXULChromeRegistry: "nsIXULChromeRegistry", + }, + Cu: { + reportError: msg => { (typeof console !== "undefined") ? console.error(msg) : dump(msg) }, + callFunctionWithAsyncStack: fn => fn(), + }, + Cr: {}, + components: { + isSuccessCode: () => (returnCode & 0x80000000) === 0, + } + }; + + +/***/ }, +/* 72 */ +/***/ function(module, exports, __webpack_require__) { + + // A sham for inDOMUtils. + + "use strict"; + + var { CSSLexer } = __webpack_require__(73); + var { cssColors } = __webpack_require__(74); + var { cssProperties } = __webpack_require__(75); + + var cssRGBMap; + + // From inIDOMUtils.idl. + var EXCLUDE_SHORTHANDS = (1 << 0); + var INCLUDE_ALIASES = (1 << 1); + var TYPE_LENGTH = 0; + var TYPE_PERCENTAGE = 1; + var TYPE_COLOR = 2; + var TYPE_URL = 3; + var TYPE_ANGLE = 4; + var TYPE_FREQUENCY = 5; + var TYPE_TIME = 6; + var TYPE_GRADIENT = 7; + var TYPE_TIMING_FUNCTION = 8; + var TYPE_IMAGE_RECT = 9; + var TYPE_NUMBER = 10; + + function getCSSLexer(text) { + return new CSSLexer(text); + } + + function rgbToColorName(r, g, b) { + if (!cssRGBMap) { + cssRGBMap = new Map(); + for (let name in cssColors) { + cssRGBMap.set(JSON.stringify(cssColors[name]), name); + } + } + let value = cssRGBMap.get(JSON.stringify([r, g, b])); + if (!value) { + throw new Error("no such color"); + } + return value; + } + + // Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js + function _hslValue(n1, n2, hue) { + if (hue > 6.0) { + hue -= 6.0; + } else if (hue < 0.0) { + hue += 6.0; + } + var val; + if (hue < 1.0) { + val = n1 + (n2 - n1) * hue; + } else if (hue < 3.0) { + val = n2; + } else if (hue < 4.0) { + val = n1 + (n2 - n1) * (4.0 - hue); + } else { + val = n1; + } + return val; + } + + // Taken from dom/tests/mochitest/ajax/mochikit/MochiKit/Color.js + // and then modified. + function hslToRGB([hue, saturation, lightness]) { + var red; + var green; + var blue; + if (saturation === 0) { + red = lightness; + green = lightness; + blue = lightness; + } else { + var m2; + if (lightness <= 0.5) { + m2 = lightness * (1.0 + saturation); + } else { + m2 = lightness + saturation - (lightness * saturation); + } + var m1 = (2.0 * lightness) - m2; + var f = _hslValue; + var h6 = hue * 6.0; + red = f(m1, m2, h6 + 2); + green = f(m1, m2, h6); + blue = f(m1, m2, h6 - 2); + } + return [red, green, blue]; + } + + function colorToRGBA(name) { + name = name.trim().toLowerCase(); + if (name in cssColors) { + return cssColors[name]; + } + + if (name === "transparent") { + return [0, 0, 0, 0]; + } + + let lexer = getCSSLexer(name); + + let getToken = function() { + while (true) { + let token = lexer.nextToken(); + if (!token || token.tokenType !== "comment" || + token.tokenType !== "whitespace") { + return token; + } + } + }; + + let requireComma = function(token) { + if (token.tokenType !== "symbol" || token.text !== ",") { + return null; + } + return getToken(); + }; + + let func = getToken(); + if (!func || func.tokenType !== "function") { + return null; + } + let alpha = false; + if (func.text === "rgb" || func.text === "hsl") { + // Nothing. + } else if (func.text === "rgba" || func.text === "hsla") { + alpha = true; + } else { + return null; + } + + let vals = []; + for (let i = 0; i < 3; ++i) { + let token = getToken(); + if (i > 0) { + token = requireComma(token); + } + if (token.tokenType !== "number" || !token.isInteger) { + return null; + } + let num = token.number; + if (num < 0) { + num = 0; + } else if (num > 255) { + num = 255; + } + vals.push(num); + } + + if (func.text === "hsl" || func.text === "hsla") { + vals = hslToRGB(vals); + } + + if (alpha) { + let token = requireComma(getToken()); + if (token.tokenType !== "number") { + return null; + } + let num = token.number; + if (num < 0) { + num = 0; + } else if (num > 1) { + num = 1; + } + vals.push(num); + } else { + vals.push(1); + } + + let parenToken = getToken(); + if (!parenToken || parenToken.tokenType !== "symbol" || + parenToken.text !== ")") { + return null; + } + if (getToken() !== null) { + return null; + } + + return vals; + } + + function isValidCSSColor(name) { + return colorToRGBA(name) !== null; + } + + function isVariable(name) { + return name.startsWith("--"); + } + + function cssPropertyIsShorthand(name) { + if (isVariable(name)) { + return false; + } + if (!(name in cssProperties)) { + throw Error("unknown property " + name); + } + return !!cssProperties[name].subproperties; + } + + function getSubpropertiesForCSSProperty(name) { + if (isVariable(name)) { + return [name]; + } + if (!(name in cssProperties)) { + throw Error("unknown property " + name); + } + if ("subproperties" in cssProperties[name]) { + return cssProperties[name].subproperties.slice(); + } + return [name]; + } + + function getCSSValuesForProperty(name) { + if (isVariable(name)) { + return ["initial", "inherit", "unset"]; + } + if (!(name in cssProperties)) { + throw Error("unknown property " + name); + } + return cssProperties[name].values.slice(); + } + + function getCSSPropertyNames(flags) { + let names = Object.keys(cssProperties); + if ((flags & EXCLUDE_SHORTHANDS) !== 0) { + names = names.filter((name) => cssProperties[name].subproperties); + } + if ((flags & INCLUDE_ALIASES) === 0) { + names = names.filter((name) => !cssProperties[name].alias); + } + return names; + } + + function cssPropertySupportsType(name, type) { + if (isVariable(name)) { + return false; + } + if (!(name in cssProperties)) { + throw Error("unknown property " + name); + } + return (cssProperties[name].supports & (1 << type)) !== 0; + } + + function isInheritedProperty(name) { + if (isVariable(name)) { + return true; + } + if (!(name in cssProperties)) { + return false; + } + return cssProperties[name].inherited; + } + + function cssPropertyIsValid(name, value) { + if (isVariable(name)) { + return true; + } + if (!(name in cssProperties)) { + return false; + } + let elt = document.createElement("div"); + elt.style = name + ":" + value; + return elt.style.length > 0; + } + + exports.inDOMUtils = { + getCSSLexer, + rgbToColorName, + colorToRGBA, + isValidCSSColor, + cssPropertyIsShorthand, + getSubpropertiesForCSSProperty, + getCSSValuesForProperty, + getCSSPropertyNames, + cssPropertySupportsType, + isInheritedProperty, + cssPropertyIsValid, + + // Constants. + EXCLUDE_SHORTHANDS, + INCLUDE_ALIASES, + TYPE_LENGTH, + TYPE_PERCENTAGE, + TYPE_COLOR, + TYPE_URL, + TYPE_ANGLE, + TYPE_FREQUENCY, + TYPE_TIME, + TYPE_GRADIENT, + TYPE_TIMING_FUNCTION, + TYPE_IMAGE_RECT, + TYPE_NUMBER, + }; + + +/***/ }, +/* 73 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict"; + + (function (root, factory) { + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, + // Rhino, and plain browser loading. + if (true) { + !(__WEBPACK_AMD_DEFINE_ARRAY__ = [exports], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else if (typeof exports !== 'undefined') { + factory(exports); + } else { + factory(root); + } + }(this, function (exports) { + + function between(num, first, last) { return num >= first && num <= last; } + function digit(code) { return between(code, 0x30,0x39); } + function hexdigit(code) { return digit(code) || between(code, 0x41,0x46) || between(code, 0x61,0x66); } + function uppercaseletter(code) { return between(code, 0x41,0x5a); } + function lowercaseletter(code) { return between(code, 0x61,0x7a); } + function letter(code) { return uppercaseletter(code) || lowercaseletter(code); } + function nonascii(code) { return code >= 0x80; } + function namestartchar(code) { return letter(code) || nonascii(code) || code == 0x5f; } + function namechar(code) { return namestartchar(code) || digit(code) || code == 0x2d; } + function nonprintable(code) { return between(code, 0,8) || code == 0xb || between(code, 0xe,0x1f) || code == 0x7f; } + function newline(code) { return code == 0xa; } + function whitespace(code) { return newline(code) || code == 9 || code == 0x20; } + + var maximumallowedcodepoint = 0x10ffff; + + var InvalidCharacterError = function(message) { + this.message = message; + }; + InvalidCharacterError.prototype = new Error; + InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + + function stringFromCode(code) { + if(code <= 0xffff) return String.fromCharCode(code); + // Otherwise, encode astral char as surrogate pair. + code -= Math.pow(2, 20); + var lead = Math.floor(code/Math.pow(2, 10)) + 0xd800; + var trail = code % Math.pow(2, 10) + 0xdc00; + return String.fromCharCode(lead) + String.fromCharCode(trail); + } + + function* tokenize(str, options) { + if (options === undefined) { + options = {}; + } + if (options.loc === undefined) { + options.loc = false; + } + if (options.offsets === undefined) { + options.offsets = false; + } + if (options.keepComments === undefined) { + options.keepComments = false; + } + if (options.startOffset === undefined) { + options.startOffset = 0; + } + + var i = options.startOffset - 1; + var code; + + // Line number information. + var line = 0; + var column = 0; + // The only use of lastLineLength is in reconsume(). + var lastLineLength = 0; + var incrLineno = function() { + line += 1; + lastLineLength = column; + column = 0; + }; + var locStart = {line:line, column:column}; + var offsetStart = i; + + var codepoint = function(i) { + if(i >= str.length) { + return -1; + } + return str.charCodeAt(i); + }; + var next = function(num) { + if(num === undefined) + num = 1; + if(num > 3) + throw "Spec Error: no more than three codepoints of lookahead."; + + var rcode; + for (var offset = i + 1; num-- > 0; ++offset) { + rcode = codepoint(offset); + if (rcode === 0xd && codepoint(offset+1) === 0xa) { + ++offset; + rcode = 0xa; + } else if (rcode === 0xd || rcode === 0xc) { + rcode = 0xa; + } else if (rcode === 0x0) { + rcode = 0xfffd; + } + } + + return rcode; + }; + var consume = function(num) { + if(num === undefined) + num = 1; + while(num-- > 0) { + ++i; + code = codepoint(i); + if (code === 0xd && codepoint(i+1) === 0xa) { + ++i; + code = 0xa; + } else if (code === 0xd || code === 0xc) { + code = 0xa; + } else if (code === 0x0) { + code = 0xfffd; + } + if(newline(code)) incrLineno(); + else column++; + } + return true; + }; + var reconsume = function() { + i -= 1; // This is ok even in the \r\n case. + if (newline(code)) { + line -= 1; + column = lastLineLength; + } else { + column -= 1; + } + return true; + }; + var eof = function(codepoint) { + if(codepoint === undefined) codepoint = code; + return codepoint == -1; + }; + var donothing = function() {}; + var parseerror = function() { console.log("Parse error at index " + i + ", processing codepoint 0x" + code.toString(16) + ".");return true; }; + + var consumeAToken = function() { + consume(); + if (!options.keepComments) { + while(code == 0x2f && next() == 0x2a) { + consumeAComment(); + consume(); + } + } + locStart.line = line; + locStart.column = column; + offsetStart = i; + if(whitespace(code)) { + while(whitespace(next())) consume(); + return new WhitespaceToken; + } + else if(code == 0x2f && next() == 0x2a) return consumeAComment(); + else if(code == 0x22) return consumeAStringToken(); + else if(code == 0x23) { + if(namechar(next()) || areAValidEscape(next(1), next(2))) { + var token = new HashToken(); + if(wouldStartAnIdentifier(next(1), next(2), next(3))) { + token.type = "id"; + token.tokenType = "id"; + } + token.value = consumeAName(); + token.text = token.value; + return token; + } else { + return new DelimToken(code); + } + } + else if(code == 0x24) { + if(next() == 0x3d) { + consume(); + return new SuffixMatchToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x27) return consumeAStringToken(); + else if(code == 0x28) return new OpenParenToken(); + else if(code == 0x29) return new CloseParenToken(); + else if(code == 0x2a) { + if(next() == 0x3d) { + consume(); + return new SubstringMatchToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x2b) { + if(startsWithANumber()) { + reconsume(); + return consumeANumericToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x2c) return new CommaToken(); + else if(code == 0x2d) { + if(startsWithANumber()) { + reconsume(); + return consumeANumericToken(); + } else if(next(1) == 0x2d && next(2) == 0x3e) { + consume(2); + return new CDCToken(); + } else if(startsWithAnIdentifier()) { + reconsume(); + return consumeAnIdentlikeToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x2e) { + if(startsWithANumber()) { + reconsume(); + return consumeANumericToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x3a) return new ColonToken; + else if(code == 0x3b) return new SemicolonToken; + else if(code == 0x3c) { + if(next(1) == 0x21 && next(2) == 0x2d && next(3) == 0x2d) { + consume(3); + return new CDOToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x40) { + if(wouldStartAnIdentifier(next(1), next(2), next(3))) { + return new AtKeywordToken(consumeAName()); + } else { + return new DelimToken(code); + } + } + else if(code == 0x5b) return new OpenSquareToken(); + else if(code == 0x5c) { + if(startsWithAValidEscape()) { + reconsume(); + return consumeAnIdentlikeToken(); + } else { + parseerror(); + return new DelimToken(code); + } + } + else if(code == 0x5d) return new CloseSquareToken(); + else if(code == 0x5e) { + if(next() == 0x3d) { + consume(); + return new PrefixMatchToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x7b) return new OpenCurlyToken(); + else if(code == 0x7c) { + if(next() == 0x3d) { + consume(); + return new DashMatchToken(); + // } else if(next() == 0x7c) { + // consume(); + // return new ColumnToken(); + } else { + return new DelimToken(code); + } + } + else if(code == 0x7d) return new CloseCurlyToken(); + else if(code == 0x7e) { + if(next() == 0x3d) { + consume(); + return new IncludeMatchToken(); + } else { + return new DelimToken(code); + } + } + else if(digit(code)) { + reconsume(); + return consumeANumericToken(); + } + else if(namestartchar(code)) { + reconsume(); + return consumeAnIdentlikeToken(); + } + else if(eof()) return new EOFToken(); + else return new DelimToken(code); + }; + + var consumeAComment = function() { + consume(); + var comment = ""; + while(true) { + consume(); + if(code == 0x2a && next() == 0x2f) { + consume(); + break; + } else if(eof()) { + break; + } + comment += stringFromCode(code); + } + return new CommentToken(comment); + }; + + var consumeANumericToken = function() { + var num = consumeANumber(); + var token; + if(wouldStartAnIdentifier(next(1), next(2), next(3))) { + token = new DimensionToken(); + token.value = num.value; + token.repr = num.repr; + token.type = num.type; + token.unit = consumeAName(); + token.text = token.unit; + } else if(next() == 0x25) { + consume(); + token = new PercentageToken(); + token.value = num.value; + token.repr = num.repr; + } else { + var token = new NumberToken(); + token.value = num.value; + token.repr = num.repr; + token.type = num.type; + } + token.number = token.value; + token.isInteger = token.type === "integer"; + // FIXME hasSign + return token; + }; + + var consumeAnIdentlikeToken = function() { + var str = consumeAName(); + if(str.toLowerCase() == "url" && next() == 0x28) { + consume(); + while(whitespace(next(1)) && whitespace(next(2))) + consume(); + if((next() == 0x22 || next() == 0x27) || + (whitespace(next()) && (next(2) == 0x22 || next(2) == 0x27))) { + while(whitespace(next())) + consume(); + consume(); + let str = consumeAStringToken(); + while(whitespace(next())) + consume(); + // The closing paren. + consume(); + return new URLToken(str.text); + } else { + return consumeAURLToken(); + } + } else if(next() == 0x28) { + consume(); + return new FunctionToken(str); + } else { + return new IdentToken(str); + } + }; + + var consumeAStringToken = function(endingCodePoint) { + if(endingCodePoint === undefined) endingCodePoint = code; + var string = ""; + while(consume()) { + if(code == endingCodePoint || eof()) { + return new StringToken(string); + } else if(newline(code)) { + reconsume(); + return new BadStringToken(string); + } else if(code == 0x5c) { + if(eof(next())) { + donothing(); + } else if(newline(next())) { + consume(); + } else { + string += stringFromCode(consumeEscape()); + } + } else { + string += stringFromCode(code); + } + } + }; + + var consumeAURLToken = function() { + var token = new URLToken(""); + while(whitespace(next())) consume(); + if(eof(next())) return token; + while(consume()) { + if(code == 0x29 || eof()) { + break; + } else if(whitespace(code)) { + while(whitespace(next())) + consume(); + if(next() == 0x29 || eof(next())) { + consume(); + break; + } else { + consumeTheRemnantsOfABadURL(); + return new BadURLToken(); + } + } else if(code == 0x22 || code == 0x27 || code == 0x28 || nonprintable(code)) { + parseerror(); + consumeTheRemnantsOfABadURL(); + return new BadURLToken(); + } else if(code == 0x5c) { + if(startsWithAValidEscape()) { + token.value += stringFromCode(consumeEscape()); + } else { + parseerror(); + consumeTheRemnantsOfABadURL(); + return new BadURLToken(); + } + } else { + token.value += stringFromCode(code); + } + } + token.text = token.value; + return token; + }; + + var consumeEscape = function() { + // Assume the the current character is the \ + // and the next code point is not a newline. + consume(); + if(hexdigit(code)) { + // Consume 1-6 hex digits + var digits = [code]; + for(var total = 0; total < 5; total++) { + if(hexdigit(next())) { + consume(); + digits.push(code); + } else { + break; + } + } + if(whitespace(next())) consume(); + var value = parseInt(digits.map(function(x){return String.fromCharCode(x);}).join(''), 16); + if( value > maximumallowedcodepoint ) value = 0xfffd; + return value; + } else if(eof()) { + return 0xfffd; + } else { + return code; + } + }; + + var areAValidEscape = function(c1, c2) { + if(c1 != 0x5c) return false; + if(newline(c2)) return false; + return true; + }; + var startsWithAValidEscape = function() { + return areAValidEscape(code, next()); + }; + + var wouldStartAnIdentifier = function(c1, c2, c3) { + if(c1 == 0x2d) { + return namestartchar(c2) || c2 == 0x2d || areAValidEscape(c2, c3); + } else if(namestartchar(c1)) { + return true; + } else if(c1 == 0x5c) { + return areAValidEscape(c1, c2); + } else { + return false; + } + }; + var startsWithAnIdentifier = function() { + return wouldStartAnIdentifier(code, next(1), next(2)); + }; + + var wouldStartANumber = function(c1, c2, c3) { + if(c1 == 0x2b || c1 == 0x2d) { + if(digit(c2)) return true; + if(c2 == 0x2e && digit(c3)) return true; + return false; + } else if(c1 == 0x2e) { + if(digit(c2)) return true; + return false; + } else if(digit(c1)) { + return true; + } else { + return false; + } + }; + var startsWithANumber = function() { + return wouldStartANumber(code, next(1), next(2)); + }; + + var consumeAName = function() { + var result = ""; + while(consume()) { + if(namechar(code)) { + result += stringFromCode(code); + } else if(startsWithAValidEscape()) { + result += stringFromCode(consumeEscape()); + } else { + reconsume(); + return result; + } + } + }; + + var consumeANumber = function() { + var repr = []; + var type = "integer"; + if(next() == 0x2b || next() == 0x2d) { + consume(); + repr += stringFromCode(code); + } + while(digit(next())) { + consume(); + repr += stringFromCode(code); + } + if(next(1) == 0x2e && digit(next(2))) { + consume(); + repr += stringFromCode(code); + consume(); + repr += stringFromCode(code); + type = "number"; + while(digit(next())) { + consume(); + repr += stringFromCode(code); + } + } + var c1 = next(1), c2 = next(2), c3 = next(3); + if((c1 == 0x45 || c1 == 0x65) && digit(c2)) { + consume(); + repr += stringFromCode(code); + consume(); + repr += stringFromCode(code); + type = "number"; + while(digit(next())) { + consume(); + repr += stringFromCode(code); + } + } else if((c1 == 0x45 || c1 == 0x65) && (c2 == 0x2b || c2 == 0x2d) && digit(c3)) { + consume(); + repr += stringFromCode(code); + consume(); + repr += stringFromCode(code); + consume(); + repr += stringFromCode(code); + type = "number"; + while(digit(next())) { + consume(); + repr += stringFromCode(code); + } + } + var value = convertAStringToANumber(repr); + return {type:type, value:value, repr:repr}; + }; + + var convertAStringToANumber = function(string) { + // CSS's number rules are identical to JS, afaik. + return +string; + }; + + var consumeTheRemnantsOfABadURL = function() { + while(consume()) { + if(code == 0x2d || eof()) { + return; + } else if(startsWithAValidEscape()) { + consumeEscape(); + donothing(); + } else { + donothing(); + } + } + }; + + + + var iterationCount = 0; + while(!eof(next())) { + var token = consumeAToken(); + if (options.loc) { + token.loc = {}; + token.loc.start = {line:locStart.line, column:locStart.column}; + token.loc.end = {line:line, column:column}; + } + if (options.offsets) { + token.startOffset = offsetStart; + token.endOffset = i + 1; + } + yield token; + iterationCount++; + if(iterationCount > str.length*2) return "I'm infinite-looping!"; + } + } + + function CSSParserToken() { throw "Abstract Base Class"; } + CSSParserToken.prototype.toJSON = function() { + return {token: this.tokenType}; + }; + CSSParserToken.prototype.toString = function() { return this.tokenType; }; + CSSParserToken.prototype.toSource = function() { return ''+this; }; + + function BadStringToken(text) { + this.text = text; + return this; + } + BadStringToken.prototype = Object.create(CSSParserToken.prototype); + BadStringToken.prototype.tokenType = "bad_string"; + + function BadURLToken() { return this; } + BadURLToken.prototype = Object.create(CSSParserToken.prototype); + BadURLToken.prototype.tokenType = "bad_url"; + + function WhitespaceToken() { return this; } + WhitespaceToken.prototype = Object.create(CSSParserToken.prototype); + WhitespaceToken.prototype.tokenType = "whitespace"; + WhitespaceToken.prototype.toString = function() { return "WS"; }; + WhitespaceToken.prototype.toSource = function() { return " "; }; + + function CDOToken() { return this; } + CDOToken.prototype = Object.create(CSSParserToken.prototype); + CDOToken.prototype.tokenType = "htmlcomment"; + CDOToken.prototype.toSource = function() { return ""; }; + + function ColonToken() { return this; } + ColonToken.prototype = Object.create(CSSParserToken.prototype); + ColonToken.prototype.tokenType = "symbol"; + ColonToken.prototype.text = ":"; + + function SemicolonToken() { return this; } + SemicolonToken.prototype = Object.create(CSSParserToken.prototype); + SemicolonToken.prototype.tokenType = "symbol"; + SemicolonToken.prototype.text = ";"; + + function CommaToken() { return this; } + CommaToken.prototype = Object.create(CSSParserToken.prototype); + CommaToken.prototype.tokenType = "symbol"; + CommaToken.prototype.text = ","; + + function GroupingToken() { throw "Abstract Base Class"; } + GroupingToken.prototype = Object.create(CSSParserToken.prototype); + + function OpenCurlyToken() { this.value = "{"; this.mirror = "}"; return this; } + OpenCurlyToken.prototype = Object.create(GroupingToken.prototype); + OpenCurlyToken.prototype.tokenType = "symbol"; + OpenCurlyToken.prototype.text = "{"; + + function CloseCurlyToken() { this.value = "}"; this.mirror = "{"; return this; } + CloseCurlyToken.prototype = Object.create(GroupingToken.prototype); + CloseCurlyToken.prototype.tokenType = "symbol"; + CloseCurlyToken.prototype.text = "}"; + + function OpenSquareToken() { this.value = "["; this.mirror = "]"; return this; } + OpenSquareToken.prototype = Object.create(GroupingToken.prototype); + OpenSquareToken.prototype.tokenType = "symbol"; + OpenSquareToken.prototype.text = "["; + + function CloseSquareToken() { this.value = "]"; this.mirror = "["; return this; } + CloseSquareToken.prototype = Object.create(GroupingToken.prototype); + CloseSquareToken.prototype.tokenType = "symbol"; + CloseSquareToken.prototype.text = "]"; + + function OpenParenToken() { this.value = "("; this.mirror = ")"; return this; } + OpenParenToken.prototype = Object.create(GroupingToken.prototype); + OpenParenToken.prototype.tokenType = "symbol"; + OpenParenToken.prototype.text = "("; + + function CloseParenToken() { this.value = ")"; this.mirror = "("; return this; } + CloseParenToken.prototype = Object.create(GroupingToken.prototype); + CloseParenToken.prototype.tokenType = "symbol"; + CloseParenToken.prototype.text = ")"; + + function IncludeMatchToken() { return this; } + IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype); + IncludeMatchToken.prototype.tokenType = "includes"; + + function DashMatchToken() { return this; } + DashMatchToken.prototype = Object.create(CSSParserToken.prototype); + DashMatchToken.prototype.tokenType = "dashmatch"; + + function PrefixMatchToken() { return this; } + PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype); + PrefixMatchToken.prototype.tokenType = "beginsmatch"; + + function SuffixMatchToken() { return this; } + SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype); + SuffixMatchToken.prototype.tokenType = "endsmatch"; + + function SubstringMatchToken() { return this; } + SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype); + SubstringMatchToken.prototype.tokenType = "containsmatch"; + + function ColumnToken() { return this; } + ColumnToken.prototype = Object.create(CSSParserToken.prototype); + ColumnToken.prototype.tokenType = "||"; + + function EOFToken() { return this; } + EOFToken.prototype = Object.create(CSSParserToken.prototype); + EOFToken.prototype.tokenType = "EOF"; + EOFToken.prototype.toSource = function() { return ""; }; + + function DelimToken(code) { + this.value = stringFromCode(code); + this.text = this.value; + return this; + } + DelimToken.prototype = Object.create(CSSParserToken.prototype); + DelimToken.prototype.tokenType = "symbol"; + DelimToken.prototype.toString = function() { return "DELIM("+this.value+")"; }; + DelimToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + return json; + }; + DelimToken.prototype.toSource = function() { + if(this.value == "\\") + return "\\\n"; + else + return this.value; + }; + + function StringValuedToken() { throw "Abstract Base Class"; } + StringValuedToken.prototype = Object.create(CSSParserToken.prototype); + StringValuedToken.prototype.ASCIIMatch = function(str) { + return this.value.toLowerCase() == str.toLowerCase(); + }; + StringValuedToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + return json; + }; + + function IdentToken(val) { + this.value = val; + this.text = val; + } + IdentToken.prototype = Object.create(StringValuedToken.prototype); + IdentToken.prototype.tokenType = "ident"; + IdentToken.prototype.toString = function() { return "IDENT("+this.value+")"; }; + IdentToken.prototype.toSource = function() { + return escapeIdent(this.value); + }; + + function FunctionToken(val) { + this.value = val; + this.text = val; + this.mirror = ")"; + } + FunctionToken.prototype = Object.create(StringValuedToken.prototype); + FunctionToken.prototype.tokenType = "function"; + FunctionToken.prototype.toString = function() { return "FUNCTION("+this.value+")"; }; + FunctionToken.prototype.toSource = function() { + return escapeIdent(this.value) + "("; + }; + + function AtKeywordToken(val) { + this.value = val; + this.text = val; + } + AtKeywordToken.prototype = Object.create(StringValuedToken.prototype); + AtKeywordToken.prototype.tokenType = "at"; + AtKeywordToken.prototype.toString = function() { return "AT("+this.value+")"; }; + AtKeywordToken.prototype.toSource = function() { + return "@" + escapeIdent(this.value); + }; + + function HashToken(val) { + this.value = val; + this.text = val; + this.type = "unrestricted"; + } + HashToken.prototype = Object.create(StringValuedToken.prototype); + HashToken.prototype.tokenType = "hash"; + HashToken.prototype.toString = function() { return "HASH("+this.value+")"; }; + HashToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + json.type = this.type; + return json; + }; + HashToken.prototype.toSource = function() { + if(this.type == "id") { + return "#" + escapeIdent(this.value); + } else { + return "#" + escapeHash(this.value); + } + }; + + function StringToken(val) { + this.value = val; + this.text = val; + } + StringToken.prototype = Object.create(StringValuedToken.prototype); + StringToken.prototype.tokenType = "string"; + StringToken.prototype.toString = function() { + return '"' + escapeString(this.value) + '"'; + }; + + function CommentToken(val) { + this.value = val; + } + CommentToken.prototype = Object.create(StringValuedToken.prototype); + CommentToken.prototype.tokenType = "comment"; + CommentToken.prototype.toString = function() { + return '/*' + this.value + '*/'; + } + CommentToken.prototype.toSource = CommentToken.prototype.toString; + + function URLToken(val) { + this.value = val; + this.text = val; + } + URLToken.prototype = Object.create(StringValuedToken.prototype); + URLToken.prototype.tokenType = "url"; + URLToken.prototype.toString = function() { return "URL("+this.value+")"; }; + URLToken.prototype.toSource = function() { + return 'url("' + escapeString(this.value) + '")'; + }; + + function NumberToken() { + this.value = null; + this.type = "integer"; + this.repr = ""; + } + NumberToken.prototype = Object.create(CSSParserToken.prototype); + NumberToken.prototype.tokenType = "number"; + NumberToken.prototype.toString = function() { + if(this.type == "integer") + return "INT("+this.value+")"; + return "NUMBER("+this.value+")"; + }; + NumberToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + json.type = this.type; + json.repr = this.repr; + return json; + }; + NumberToken.prototype.toSource = function() { return this.repr; }; + + function PercentageToken() { + this.value = null; + this.repr = ""; + } + PercentageToken.prototype = Object.create(CSSParserToken.prototype); + PercentageToken.prototype.tokenType = "percentage"; + PercentageToken.prototype.toString = function() { return "PERCENTAGE("+this.value+")"; }; + PercentageToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + json.repr = this.repr; + return json; + }; + PercentageToken.prototype.toSource = function() { return this.repr + "%"; }; + + function DimensionToken() { + this.value = null; + this.type = "integer"; + this.repr = ""; + this.unit = ""; + } + DimensionToken.prototype = Object.create(CSSParserToken.prototype); + DimensionToken.prototype.tokenType = "dimension"; + DimensionToken.prototype.toString = function() { return "DIM("+this.value+","+this.unit+")"; }; + DimensionToken.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.value = this.value; + json.type = this.type; + json.repr = this.repr; + json.unit = this.unit; + return json; + }; + DimensionToken.prototype.toSource = function() { + var source = this.repr; + var unit = escapeIdent(this.unit); + if(unit[0].toLowerCase() == "e" && (unit[1] == "-" || between(unit.charCodeAt(1), 0x30, 0x39))) { + // Unit is ambiguous with scinot + // Remove the leading "e", replace with escape. + unit = "\\65 " + unit.slice(1, unit.length); + } + return source+unit; + }; + + function escapeIdent(string) { + string = ''+string; + var result = ''; + var firstcode = string.charCodeAt(0); + for(var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + if(code === 0x0) { + throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); + } + + if( + between(code, 0x1, 0x1f) || code == 0x7f || + (i === 0 && between(code, 0x30, 0x39)) || + (i == 1 && between(code, 0x30, 0x39) && firstcode == 0x2d) + ) { + result += '\\' + code.toString(16) + ' '; + } else if( + code >= 0x80 || + code == 0x2d || + code == 0x5f || + between(code, 0x30, 0x39) || + between(code, 0x41, 0x5a) || + between(code, 0x61, 0x7a) + ) { + result += string[i]; + } else { + result += '\\' + string[i]; + } + } + return result; + } + + function escapeHash(string) { + // Escapes the contents of "unrestricted"-type hash tokens. + // Won't preserve the ID-ness of "id"-type hash tokens; + // use escapeIdent() for that. + string = ''+string; + var result = ''; + for(var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + if(code === 0x0) { + throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); + } + + if( + code >= 0x80 || + code == 0x2d || + code == 0x5f || + between(code, 0x30, 0x39) || + between(code, 0x41, 0x5a) || + between(code, 0x61, 0x7a) + ) { + result += string[i]; + } else { + result += '\\' + code.toString(16) + ' '; + } + } + return result; + } + + function escapeString(string) { + string = ''+string; + var result = ''; + for(var i = 0; i < string.length; i++) { + var code = string.charCodeAt(i); + + if(code === 0x0) { + throw new InvalidCharacterError('Invalid character: the input contains U+0000.'); + } + + if(between(code, 0x1, 0x1f) || code == 0x7f) { + result += '\\' + code.toString(16) + ' '; + } else if(code == 0x22 || code == 0x5c) { + result += '\\' + string[i]; + } else { + result += string[i]; + } + } + return result; + } + + // Exportation. + exports.tokenize = tokenize; + exports.IdentToken = IdentToken; + exports.FunctionToken = FunctionToken; + exports.AtKeywordToken = AtKeywordToken; + exports.HashToken = HashToken; + exports.StringToken = StringToken; + exports.BadStringToken = BadStringToken; + exports.URLToken = URLToken; + exports.BadURLToken = BadURLToken; + exports.DelimToken = DelimToken; + exports.NumberToken = NumberToken; + exports.PercentageToken = PercentageToken; + exports.DimensionToken = DimensionToken; + exports.IncludeMatchToken = IncludeMatchToken; + exports.DashMatchToken = DashMatchToken; + exports.PrefixMatchToken = PrefixMatchToken; + exports.SuffixMatchToken = SuffixMatchToken; + exports.SubstringMatchToken = SubstringMatchToken; + exports.ColumnToken = ColumnToken; + exports.WhitespaceToken = WhitespaceToken; + exports.CDOToken = CDOToken; + exports.CDCToken = CDCToken; + exports.ColonToken = ColonToken; + exports.SemicolonToken = SemicolonToken; + exports.CommaToken = CommaToken; + exports.OpenParenToken = OpenParenToken; + exports.CloseParenToken = CloseParenToken; + exports.OpenSquareToken = OpenSquareToken; + exports.CloseSquareToken = CloseSquareToken; + exports.OpenCurlyToken = OpenCurlyToken; + exports.CloseCurlyToken = CloseCurlyToken; + exports.EOFToken = EOFToken; + exports.CSSParserToken = CSSParserToken; + exports.GroupingToken = GroupingToken; + + function TokenStream(tokens) { + // Assume that tokens is a iterator. + this.tokens = tokens; + this.token = undefined; + this.stored = []; + } + TokenStream.prototype.consume = function(num) { + if(num === undefined) num = 1; + while (num-- > 0) { + if (this.stored.length > 0) { + this.token = this.stored.shift(); + } else { + var n = this.tokens.next(); + while (!n.done && n.value instanceof CommentToken) { + n = this.tokens.next(); + } + if (n.done) { + this.token = new EOFToken(); + break; + } + this.token = n.value; + } + } + //console.log(this.i, this.token); + return true; + }; + TokenStream.prototype.next = function() { + if (this.stored.length === 0) { + var n = this.tokens.next(); + while (!n.done && n.value instanceof CommentToken) { + n = this.tokens.next(); + } + if (n.done) + return new EOFToken(); + this.stored.push(n.value); + } + return this.stored[0]; + }; + TokenStream.prototype.reconsume = function() { + this.stored.unshift(this.token); + }; + + function parseerror(s, msg) { + console.log("Parse error at token " + s.i + ": " + s.token + ".\n" + msg); + return true; + } + function donothing(){ return true; } + + function consumeAListOfRules(s, topLevel) { + var rules = []; + var rule; + while(s.consume()) { + if(s.token instanceof WhitespaceToken) { + continue; + } else if(s.token instanceof EOFToken) { + return rules; + } else if(s.token instanceof CDOToken || s.token instanceof CDCToken) { + if(topLevel == "top-level") continue; + s.reconsume(); + if(rule = consumeAQualifiedRule(s)) rules.push(rule); + } else if(s.token instanceof AtKeywordToken) { + s.reconsume(); + if(rule = consumeAnAtRule(s)) rules.push(rule); + } else { + s.reconsume(); + if(rule = consumeAQualifiedRule(s)) rules.push(rule); + } + } + } + + function consumeAnAtRule(s) { + s.consume(); + var rule = new AtRule(s.token.value); + while(s.consume()) { + if(s.token instanceof SemicolonToken || s.token instanceof EOFToken) { + return rule; + } else if(s.token instanceof OpenCurlyToken) { + rule.value = consumeASimpleBlock(s); + return rule; + } else { + s.reconsume(); + rule.prelude.push(consumeAComponentValue(s)); + } + } + } + + function consumeAQualifiedRule(s) { + var rule = new QualifiedRule(); + while(s.consume()) { + if(s.token instanceof EOFToken) { + parseerror(s, "Hit EOF when trying to parse the prelude of a qualified rule."); + return; + } else if(s.token instanceof OpenCurlyToken) { + rule.value = consumeASimpleBlock(s); + return rule; + } else { + s.reconsume(); + rule.prelude.push(consumeAComponentValue(s)); + } + } + } + + function consumeAListOfDeclarations(s) { + var decls = []; + while(s.consume()) { + if(s.token instanceof WhitespaceToken || s.token instanceof SemicolonToken) { + donothing(); + } else if(s.token instanceof EOFToken) { + return decls; + } else if(s.token instanceof AtKeywordToken) { + s.reconsume(); + decls.push(consumeAnAtRule(s)); + } else if(s.token instanceof IdentToken) { + var temp = [s.token]; + while(!(s.next() instanceof SemicolonToken || s.next() instanceof EOFToken)) + temp.push(consumeAComponentValue(s)); + var decl; + if(decl = consumeADeclaration(new TokenStream(temp))) decls.push(decl); + } else { + parseerror(s); + s.reconsume(); + while(!(s.next() instanceof SemicolonToken || s.next() instanceof EOFToken)) + consumeAComponentValue(s); + } + } + } + + function consumeADeclaration(s) { + // Assumes that the next input token will be an ident token. + s.consume(); + var decl = new Declaration(s.token.value); + while(s.next() instanceof WhitespaceToken) s.consume(); + if(!(s.next() instanceof ColonToken)) { + parseerror(s); + return; + } else { + s.consume(); + } + while(!(s.next() instanceof EOFToken)) { + decl.value.push(consumeAComponentValue(s)); + } + var foundImportant = false; + for(var i = decl.value.length - 1; i >= 0; i--) { + if(decl.value[i] instanceof WhitespaceToken) { + continue; + } else if(decl.value[i] instanceof IdentToken && decl.value[i].ASCIIMatch("important")) { + foundImportant = true; + } else if(foundImportant && decl.value[i] instanceof DelimToken && decl.value[i].value == "!") { + decl.value.splice(i, decl.value.length); + decl.important = true; + break; + } else { + break; + } + } + return decl; + } + + function consumeAComponentValue(s) { + s.consume(); + if(s.token instanceof OpenCurlyToken || s.token instanceof OpenSquareToken || s.token instanceof OpenParenToken) + return consumeASimpleBlock(s); + if(s.token instanceof FunctionToken) + return consumeAFunction(s); + return s.token; + } + + function consumeASimpleBlock(s) { + var mirror = s.token.mirror; + var block = new SimpleBlock(s.token.value); + block.startToken = s.token; + while(s.consume()) { + if(s.token instanceof EOFToken || (s.token instanceof GroupingToken && s.token.value == mirror)) + return block; + else { + s.reconsume(); + block.value.push(consumeAComponentValue(s)); + } + } + } + + function consumeAFunction(s) { + var func = new Func(s.token.value); + while(s.consume()) { + if(s.token instanceof EOFToken || s.token instanceof CloseParenToken) + return func; + else { + s.reconsume(); + func.value.push(consumeAComponentValue(s)); + } + } + } + + function normalizeInput(input) { + if(typeof input == "string") + return new TokenStream(tokenize(input)); + if(input instanceof TokenStream) + return input; + if(typeof (input.next) == "function") + return new TokenStream(input); + if(input.length !== undefined) + return new TokenStream(input[Symbol.iterator]()); + else throw SyntaxError(input); + } + + function parseAStylesheet(s) { + s = normalizeInput(s); + var sheet = new Stylesheet(); + sheet.value = consumeAListOfRules(s, "top-level"); + return sheet; + } + + function parseAListOfRules(s) { + s = normalizeInput(s); + return consumeAListOfRules(s); + } + + function parseARule(s) { + s = normalizeInput(s); + while(s.next() instanceof WhitespaceToken) s.consume(); + if(s.next() instanceof EOFToken) throw SyntaxError(); + var rule; + var startToken = s.next(); + if(startToken instanceof AtKeywordToken) { + rule = consumeAnAtRule(s); + } else { + rule = consumeAQualifiedRule(s); + if(!rule) throw SyntaxError(); + } + rule.startToken = startToken; + rule.endToken = s.token; + return rule; + } + + function parseADeclaration(s) { + s = normalizeInput(s); + while(s.next() instanceof WhitespaceToken) s.consume(); + if(!(s.next() instanceof IdentToken)) throw SyntaxError(); + var decl = consumeADeclaration(s); + if(decl) + return decl; + else + throw SyntaxError(); + } + + function parseAListOfDeclarations(s) { + s = normalizeInput(s); + return consumeAListOfDeclarations(s); + } + + function parseAComponentValue(s) { + s = normalizeInput(s); + while(s.next() instanceof WhitespaceToken) s.consume(); + if(s.next() instanceof EOFToken) throw SyntaxError(); + var val = consumeAComponentValue(s); + if(!val) throw SyntaxError(); + while(s.next() instanceof WhitespaceToken) s.consume(); + if(s.next() instanceof EOFToken) + return val; + throw SyntaxError(); + } + + function parseAListOfComponentValues(s) { + s = normalizeInput(s); + var vals = []; + while(true) { + var val = consumeAComponentValue(s); + if(val instanceof EOFToken) + return vals; + else + vals.push(val); + } + } + + function parseACommaSeparatedListOfComponentValues(s) { + s = normalizeInput(s); + var listOfCVLs = []; + while(true) { + var vals = []; + while(true) { + var val = consumeAComponentValue(s); + if(val instanceof EOFToken) { + listOfCVLs.push(vals); + return listOfCVLs; + } else if(val instanceof CommaToken) { + listOfCVLs.push(vals); + break; + } else { + vals.push(val); + } + } + } + } + + + function CSSParserRule() { throw "Abstract Base Class"; } + CSSParserRule.prototype.toString = function(indent) { + return JSON.stringify(this,null,indent); + }; + CSSParserRule.prototype.toJSON = function() { + return {type:this.type, value:this.value}; + }; + + function Stylesheet() { + this.value = []; + return this; + } + Stylesheet.prototype = Object.create(CSSParserRule.prototype); + Stylesheet.prototype.type = "STYLESHEET"; + + function AtRule(name) { + this.name = name; + this.prelude = []; + this.value = null; + return this; + } + AtRule.prototype = Object.create(CSSParserRule.prototype); + AtRule.prototype.type = "AT-RULE"; + AtRule.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.name = this.name; + json.prelude = this.prelude; + return json; + }; + + function QualifiedRule() { + this.prelude = []; + this.value = []; + return this; + } + QualifiedRule.prototype = Object.create(CSSParserRule.prototype); + QualifiedRule.prototype.type = "QUALIFIED-RULE"; + QualifiedRule.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.prelude = this.prelude; + return json; + }; + + function Declaration(name) { + this.name = name; + this.value = []; + this.important = false; + return this; + } + Declaration.prototype = Object.create(CSSParserRule.prototype); + Declaration.prototype.type = "DECLARATION"; + Declaration.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.name = this.name; + json.important = this.important; + return json; + }; + + function SimpleBlock(type) { + this.name = type; + this.value = []; + return this; + } + SimpleBlock.prototype = Object.create(CSSParserRule.prototype); + SimpleBlock.prototype.type = "BLOCK"; + SimpleBlock.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.name = this.name; + return json; + }; + + function Func(name) { + this.name = name; + this.value = []; + return this; + } + Func.prototype = Object.create(CSSParserRule.prototype); + Func.prototype.type = "FUNCTION"; + Func.prototype.toJSON = function() { + var json = this.constructor.prototype.constructor.prototype.toJSON.call(this); + json.name = this.name; + return json; + }; + + function CSSLexer(text) { + this.stream = tokenize(text, { + loc: true, + offsets: true, + keepComments: true + }); + this.lineNumber = 0; + this.columnNumber = 0; + return this; + } + + CSSLexer.prototype.performEOFFixup = function(input, preserveBackslash) { + // Just lie for now. + return ""; + }; + + CSSLexer.prototype.nextToken = function() { + if (!this.stream) { + return null; + } + let v = this.stream.next(); + if (v.done || v.value.tokenType === "EOF") { + this.stream = null; + return null; + } + this.lineNumber = v.value.loc.start.line; + this.columnNumber = v.value.loc.start.column; + return v.value; + }; + + // Exportation. + exports.CSSParserRule = CSSParserRule; + exports.Stylesheet = Stylesheet; + exports.AtRule = AtRule; + exports.QualifiedRule = QualifiedRule; + exports.Declaration = Declaration; + exports.SimpleBlock = SimpleBlock; + exports.Func = Func; + exports.parseAStylesheet = parseAStylesheet; + exports.parseAListOfRules = parseAListOfRules; + exports.parseARule = parseARule; + exports.parseADeclaration = parseADeclaration; + exports.parseAListOfDeclarations = parseAListOfDeclarations; + exports.parseAComponentValue = parseAComponentValue; + exports.parseAListOfComponentValues = parseAListOfComponentValues; + exports.parseACommaSeparatedListOfComponentValues = parseACommaSeparatedListOfComponentValues; + exports.CSSLexer = CSSLexer; + + })); + + +/***/ }, +/* 74 */ +/***/ function(module, exports) { + + // auto-generated from nsColorNameList.h + var cssColors = { + 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: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + 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], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + 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], + }; + module.exports = { cssColors }; + + +/***/ }, +/* 75 */ +/***/ function(module, exports) { + + // auto-generated by means you would rather not know + var cssProperties = { + "-moz-appearance": { + inherited: false, + supports: 0, + values: ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window", ], + }, + "-moz-outline-radius-topleft": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-outline-radius-topright": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-outline-radius-bottomright": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-outline-radius-bottomleft": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-tab-size": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "animation-delay": { + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "animation-direction": { + inherited: false, + supports: 0, + values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], + }, + "animation-duration": { + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "animation-fill-mode": { + inherited: false, + supports: 0, + values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], + }, + "animation-iteration-count": { + inherited: false, + supports: 1024, + values: ["infinite", "inherit", "initial", "unset", ], + }, + "animation-name": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "none", "unset", ], + }, + "animation-play-state": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "paused", "running", "unset", ], + }, + "animation-timing-function": { + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "background-attachment": { + inherited: false, + supports: 0, + values: ["fixed", "inherit", "initial", "local", "scroll", "unset", ], + }, + "background-clip": { + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "background-color": { + inherited: false, + supports: 4, + values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "background-image": { + inherited: false, + supports: 648, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "background-blend-mode": { + inherited: false, + supports: 0, + values: ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset", ], + }, + "background-origin": { + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "background-position": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "background-repeat": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "no-repeat", "repeat", "repeat-x", "repeat-y", "unset", ], + }, + "background-size": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-binding": { + inherited: false, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "block-size": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "border-block-end-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-block-end-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-block-end-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-block-start-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-block-start-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-block-start-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-bottom-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-bottom-colors": { + inherited: false, + supports: 4, + values: ["inherit", "initial", "unset", ], + }, + "border-bottom-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-bottom-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-collapse": { + inherited: true, + supports: 0, + values: ["collapse", "inherit", "initial", "separate", "unset", ], + }, + "border-image-source": { + inherited: false, + supports: 648, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "border-image-slice": { + inherited: false, + supports: 1026, + values: ["inherit", "initial", "unset", ], + }, + "border-image-width": { + inherited: false, + supports: 1027, + values: ["inherit", "initial", "unset", ], + }, + "border-image-outset": { + inherited: false, + supports: 1025, + values: ["inherit", "initial", "unset", ], + }, + "border-image-repeat": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "border-inline-end-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-inline-end-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-inline-end-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-inline-start-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-inline-start-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-inline-start-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-left-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-left-colors": { + inherited: false, + supports: 4, + values: ["inherit", "initial", "unset", ], + }, + "border-left-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-left-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-right-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-right-colors": { + inherited: false, + supports: 4, + values: ["inherit", "initial", "unset", ], + }, + "border-right-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-right-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-spacing": { + inherited: true, + supports: 1, + values: ["inherit", "initial", "unset", ], + }, + "border-top-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-top-colors": { + inherited: false, + supports: 4, + values: ["inherit", "initial", "unset", ], + }, + "border-top-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-top-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-top-left-radius": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "border-top-right-radius": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "border-bottom-right-radius": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "border-bottom-left-radius": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "bottom": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "box-decoration-break": { + inherited: false, + supports: 0, + values: ["clone", "inherit", "initial", "slice", "unset", ], + }, + "box-shadow": { + inherited: false, + supports: 5, + values: ["inherit", "initial", "unset", ], + }, + "box-sizing": { + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "caption-side": { + inherited: true, + supports: 0, + values: ["bottom", "bottom-outside", "inherit", "initial", "left", "right", "top", "top-outside", "unset", ], + }, + "clear": { + inherited: false, + supports: 0, + values: ["both", "inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset", ], + }, + "clip": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "color": { + inherited: true, + supports: 4, + values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-column-count": { + inherited: false, + supports: 1024, + values: ["auto", "inherit", "initial", "unset", ], + }, + "-moz-column-fill": { + inherited: false, + supports: 0, + values: ["auto", "balance", "inherit", "initial", "unset", ], + }, + "-moz-column-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "-moz-column-gap": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], + }, + "-moz-column-rule-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-column-rule-style": { + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "-moz-column-rule-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "contain": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "layout", "none", "paint", "strict", "style", "unset", ], + }, + "content": { + inherited: false, + supports: 8, + values: ["inherit", "initial", "unset", ], + }, + "-moz-control-character-visibility": { + inherited: true, + supports: 0, + values: ["hidden", "inherit", "initial", "unset", "visible", ], + }, + "counter-increment": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "counter-reset": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "cursor": { + inherited: true, + supports: 8, + values: ["inherit", "initial", "unset", ], + }, + "direction": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "ltr", "rtl", "unset", ], + }, + "display": { + inherited: false, + supports: 0, + values: ["-moz-box", "-moz-deck", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-popup", "-moz-stack", "block", "contents", "flex", "grid", "inherit", "initial", "inline", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "none", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "unset", ], + }, + "empty-cells": { + inherited: true, + supports: 0, + values: ["hide", "inherit", "initial", "show", "unset", ], + }, + "align-content": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "align-items": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "align-self": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "flex-basis": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "flex-direction": { + inherited: false, + supports: 0, + values: ["column", "column-reverse", "inherit", "initial", "row", "row-reverse", "unset", ], + }, + "flex-grow": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "flex-shrink": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "flex-wrap": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "nowrap", "unset", "wrap", "wrap-reverse", ], + }, + "order": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "justify-content": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "justify-items": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "justify-self": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "float": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "inline-end", "inline-start", "left", "none", "right", "unset", ], + }, + "-moz-float-edge": { + inherited: false, + supports: 0, + values: ["content-box", "inherit", "initial", "margin-box", "unset", ], + }, + "font-family": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-feature-settings": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-kerning": { + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "none", "normal", "unset", ], + }, + "font-language-override": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "normal", "unset", ], + }, + "font-size": { + inherited: true, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "large", "larger", "medium", "small", "smaller", "unset", "x-large", "x-small", "xx-large", "xx-small", ], + }, + "font-size-adjust": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "none", "unset", ], + }, + "font-stretch": { + inherited: true, + supports: 0, + values: ["condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "normal", "semi-condensed", "semi-expanded", "ultra-condensed", "ultra-expanded", "unset", ], + }, + "font-style": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "italic", "normal", "oblique", "unset", ], + }, + "font-synthesis": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-variant-alternates": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-variant-caps": { + inherited: true, + supports: 0, + values: ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "titling-caps", "unicase", "unset", ], + }, + "font-variant-east-asian": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-variant-ligatures": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-variant-numeric": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "font-variant-position": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "normal", "sub", "super", "unset", ], + }, + "font-weight": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-moz-force-broken-image-icon": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-auto-flow": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "grid-auto-columns": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "grid-auto-rows": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "grid-template-areas": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "grid-template-columns": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "grid-template-rows": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "grid-column-start": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-column-end": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-row-start": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-row-end": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-column-gap": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "grid-row-gap": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "height": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "image-orientation": { + inherited: true, + supports: 16, + values: ["inherit", "initial", "unset", ], + }, + "-moz-image-region": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "ime-mode": { + inherited: false, + supports: 0, + values: ["active", "auto", "disabled", "inactive", "inherit", "initial", "normal", "unset", ], + }, + "inline-size": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "left": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "letter-spacing": { + inherited: true, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], + }, + "line-height": { + inherited: true, + supports: 1027, + values: ["-moz-block-height", "inherit", "initial", "normal", "unset", ], + }, + "list-style-image": { + inherited: true, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "list-style-position": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "inside", "outside", "unset", ], + }, + "list-style-type": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "margin-block-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-block-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-bottom": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-inline-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-inline-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-left": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-right": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "margin-top": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "marker-offset": { + inherited: false, + supports: 1, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "max-block-size": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "none", "unset", ], + }, + "max-height": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], + }, + "max-inline-size": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], + }, + "max-width": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "calc", "inherit", "initial", "none", "unset", ], + }, + "min-height": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "min-block-size": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "min-inline-size": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "min-width": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "mix-blend-mode": { + inherited: false, + supports: 0, + values: ["color", "color-burn", "color-dodge", "darken", "difference", "exclusion", "hard-light", "hue", "inherit", "initial", "lighten", "luminosity", "multiply", "normal", "overlay", "saturation", "screen", "soft-light", "unset", ], + }, + "isolation": { + inherited: false, + supports: 0, + values: ["auto", "inherit", "initial", "isolate", "unset", ], + }, + "object-fit": { + inherited: false, + supports: 0, + values: ["contain", "cover", "fill", "inherit", "initial", "none", "scale-down", "unset", ], + }, + "object-position": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "offset-block-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "offset-block-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "offset-inline-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "offset-inline-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "opacity": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-moz-orient": { + inherited: false, + supports: 0, + values: ["block", "horizontal", "inherit", "initial", "inline", "unset", "vertical", ], + }, + "outline-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "outline-style": { + inherited: false, + supports: 0, + values: ["auto", "dashed", "dotted", "double", "groove", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "outline-width": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "outline-offset": { + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "overflow-x": { + inherited: false, + supports: 0, + values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], + }, + "overflow-y": { + inherited: false, + supports: 0, + values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], + }, + "padding-block-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-block-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-bottom": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-inline-end": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-inline-start": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-left": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-right": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "padding-top": { + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "page-break-after": { + inherited: false, + supports: 0, + values: ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset", ], + }, + "page-break-before": { + inherited: false, + supports: 0, + values: ["always", "auto", "avoid", "inherit", "initial", "left", "right", "unset", ], + }, + "page-break-inside": { + inherited: false, + supports: 0, + values: ["auto", "avoid", "inherit", "initial", "unset", ], + }, + "paint-order": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "pointer-events": { + inherited: true, + supports: 0, + values: ["all", "auto", "fill", "inherit", "initial", "none", "painted", "stroke", "unset", "visible", "visiblefill", "visiblepainted", "visiblestroke", ], + }, + "position": { + inherited: false, + supports: 0, + values: ["absolute", "fixed", "inherit", "initial", "relative", "static", "sticky", "unset", ], + }, + "quotes": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "resize": { + inherited: false, + supports: 0, + values: ["both", "horizontal", "inherit", "initial", "none", "unset", "vertical", ], + }, + "right": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "ruby-align": { + inherited: true, + supports: 0, + values: ["center", "inherit", "initial", "space-around", "space-between", "start", "unset", ], + }, + "ruby-position": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "over", "under", "unset", ], + }, + "scroll-behavior": { + inherited: false, + supports: 0, + values: ["auto", "inherit", "initial", "smooth", "unset", ], + }, + "scroll-snap-coordinate": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "scroll-snap-destination": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "scroll-snap-points-x": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "scroll-snap-points-y": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "scroll-snap-type-x": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], + }, + "scroll-snap-type-y": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], + }, + "table-layout": { + inherited: false, + supports: 0, + values: ["auto", "fixed", "inherit", "initial", "unset", ], + }, + "text-align": { + inherited: true, + supports: 0, + values: ["-moz-center", "-moz-left", "-moz-right", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset", ], + }, + "-moz-text-align-last": { + inherited: true, + supports: 0, + values: ["auto", "center", "end", "inherit", "initial", "justify", "left", "right", "start", "unset", ], + }, + "text-decoration-color": { + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "text-decoration-line": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "text-decoration-style": { + inherited: false, + supports: 0, + values: ["-moz-none", "dashed", "dotted", "double", "inherit", "initial", "solid", "unset", "wavy", ], + }, + "text-indent": { + inherited: true, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "text-orientation": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "mixed", "sideways", "sideways-right", "unset", "upright", ], + }, + "text-overflow": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "text-shadow": { + inherited: true, + supports: 5, + values: ["inherit", "initial", "unset", ], + }, + "-moz-text-size-adjust": { + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "none", "unset", ], + }, + "text-transform": { + inherited: true, + supports: 0, + values: ["capitalize", "full-width", "inherit", "initial", "lowercase", "none", "unset", "uppercase", ], + }, + "transform": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "transform-box": { + inherited: false, + supports: 0, + values: ["border-box", "fill-box", "inherit", "initial", "unset", "view-box", ], + }, + "transform-origin": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "perspective-origin": { + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "perspective": { + inherited: false, + supports: 1, + values: ["inherit", "initial", "none", "unset", ], + }, + "transform-style": { + inherited: false, + supports: 0, + values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], + }, + "backface-visibility": { + inherited: false, + supports: 0, + values: ["hidden", "inherit", "initial", "unset", "visible", ], + }, + "top": { + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "transition-delay": { + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "transition-duration": { + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "transition-property": { + inherited: false, + supports: 0, + values: ["all", "inherit", "initial", "none", "unset", ], + }, + "transition-timing-function": { + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "unicode-bidi": { + inherited: false, + supports: 0, + values: ["-moz-isolate", "-moz-isolate-override", "-moz-plaintext", "bidi-override", "embed", "inherit", "initial", "normal", "unset", ], + }, + "-moz-user-focus": { + inherited: true, + supports: 0, + values: ["ignore", "inherit", "initial", "none", "normal", "select-after", "select-all", "select-before", "select-menu", "select-same", "unset", ], + }, + "-moz-user-input": { + inherited: true, + supports: 0, + values: ["auto", "disabled", "enabled", "inherit", "initial", "none", "unset", ], + }, + "-moz-user-modify": { + inherited: true, + supports: 0, + values: ["inherit", "initial", "read-only", "read-write", "unset", "write-only", ], + }, + "-moz-user-select": { + inherited: false, + supports: 0, + values: ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset", ], + }, + "vertical-align": { + inherited: false, + supports: 3, + values: ["-moz-calc", "-moz-middle-with-baseline", "baseline", "bottom", "calc", "inherit", "initial", "middle", "sub", "super", "text-bottom", "text-top", "top", "unset", ], + }, + "visibility": { + inherited: true, + supports: 0, + values: ["collapse", "hidden", "inherit", "initial", "unset", "visible", ], + }, + "white-space": { + inherited: true, + supports: 0, + values: ["-moz-pre-space", "inherit", "initial", "normal", "nowrap", "pre", "pre-line", "pre-wrap", "unset", ], + }, + "width": { + inherited: false, + supports: 3, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "-moz-window-dragging": { + inherited: true, + supports: 0, + values: ["drag", "inherit", "initial", "no-drag", "unset", ], + }, + "word-break": { + inherited: true, + supports: 0, + values: ["break-all", "inherit", "initial", "keep-all", "normal", "unset", ], + }, + "word-spacing": { + inherited: true, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "normal", "unset", ], + }, + "word-wrap": { + inherited: true, + supports: 0, + values: ["break-word", "inherit", "initial", "normal", "unset", ], + }, + "hyphens": { + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "manual", "none", "unset", ], + }, + "writing-mode": { + inherited: true, + supports: 0, + values: ["horizontal-tb", "inherit", "initial", "lr", "lr-tb", "rl", "rl-tb", "sideways-lr", "sideways-rl", "tb", "tb-rl", "unset", "vertical-lr", "vertical-rl", ], + }, + "z-index": { + inherited: false, + supports: 1024, + values: ["auto", "inherit", "initial", "unset", ], + }, + "-moz-box-align": { + inherited: false, + supports: 0, + values: ["baseline", "center", "end", "inherit", "initial", "start", "stretch", "unset", ], + }, + "-moz-box-direction": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "normal", "reverse", "unset", ], + }, + "-moz-box-flex": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-moz-box-orient": { + inherited: false, + supports: 0, + values: ["block-axis", "horizontal", "inherit", "initial", "inline-axis", "unset", "vertical", ], + }, + "-moz-box-pack": { + inherited: false, + supports: 0, + values: ["center", "end", "inherit", "initial", "justify", "start", "unset", ], + }, + "-moz-box-ordinal-group": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-moz-stack-sizing": { + inherited: false, + supports: 0, + values: ["ignore", "inherit", "initial", "stretch-to-fit", "unset", ], + }, + "clip-path": { + inherited: false, + supports: 8, + values: ["inherit", "initial", "unset", ], + }, + "clip-rule": { + inherited: true, + supports: 0, + values: ["evenodd", "inherit", "initial", "nonzero", "unset", ], + }, + "color-interpolation": { + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "linearrgb", "srgb", "unset", ], + }, + "color-interpolation-filters": { + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "linearrgb", "srgb", "unset", ], + }, + "dominant-baseline": { + inherited: false, + supports: 0, + values: ["alphabetic", "auto", "central", "hanging", "ideographic", "inherit", "initial", "mathematical", "middle", "no-change", "reset-size", "text-after-edge", "text-before-edge", "unset", "use-script", ], + }, + "fill": { + inherited: true, + supports: 12, + values: ["inherit", "initial", "unset", ], + }, + "fill-opacity": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "fill-rule": { + inherited: true, + supports: 0, + values: ["evenodd", "inherit", "initial", "nonzero", "unset", ], + }, + "filter": { + inherited: false, + supports: 8, + values: ["inherit", "initial", "unset", ], + }, + "flood-color": { + inherited: false, + supports: 4, + values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "flood-opacity": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "image-rendering": { + inherited: true, + supports: 0, + values: ["-moz-crisp-edges", "auto", "inherit", "initial", "optimizequality", "optimizespeed", "unset", ], + }, + "lighting-color": { + inherited: false, + supports: 4, + values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "marker-end": { + inherited: true, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "marker-mid": { + inherited: true, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "marker-start": { + inherited: true, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "mask": { + inherited: false, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "mask-type": { + inherited: false, + supports: 0, + values: ["alpha", "inherit", "initial", "luminance", "unset", ], + }, + "shape-rendering": { + inherited: true, + supports: 0, + values: ["auto", "crispedges", "geometricprecision", "inherit", "initial", "optimizespeed", "unset", ], + }, + "stop-color": { + inherited: false, + supports: 4, + values: ["aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "stop-opacity": { + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "stroke": { + inherited: true, + supports: 12, + values: ["inherit", "initial", "unset", ], + }, + "stroke-dasharray": { + inherited: true, + supports: 1027, + values: ["inherit", "initial", "unset", ], + }, + "stroke-dashoffset": { + inherited: true, + supports: 1027, + values: ["inherit", "initial", "unset", ], + }, + "stroke-linecap": { + inherited: true, + supports: 0, + values: ["butt", "inherit", "initial", "round", "square", "unset", ], + }, + "stroke-linejoin": { + inherited: true, + supports: 0, + values: ["bevel", "inherit", "initial", "miter", "round", "unset", ], + }, + "stroke-miterlimit": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "stroke-opacity": { + inherited: true, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "stroke-width": { + inherited: true, + supports: 1027, + values: ["inherit", "initial", "unset", ], + }, + "text-anchor": { + inherited: true, + supports: 0, + values: ["end", "inherit", "initial", "middle", "start", "unset", ], + }, + "text-rendering": { + inherited: true, + supports: 0, + values: ["auto", "geometricprecision", "inherit", "initial", "optimizelegibility", "optimizespeed", "unset", ], + }, + "vector-effect": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "non-scaling-stroke", "none", "unset", ], + }, + "will-change": { + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-moz-outline-radius": { + subproperties: ["-moz-outline-radius-topleft", "-moz-outline-radius-topright", "-moz-outline-radius-bottomright", "-moz-outline-radius-bottomleft", ], + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "all": { + subproperties: ["-moz-appearance", "-moz-outline-radius-topleft", "-moz-outline-radius-topright", "-moz-outline-radius-bottomright", "-moz-outline-radius-bottomleft", "-moz-tab-size", "-x-system-font", "animation-delay", "animation-direction", "animation-duration", "animation-fill-mode", "animation-iteration-count", "animation-name", "animation-play-state", "animation-timing-function", "background-attachment", "background-clip", "background-color", "background-image", "background-blend-mode", "background-origin", "background-position", "background-repeat", "background-size", "-moz-binding", "block-size", "border-block-end-color", "border-block-end-style", "border-block-end-width", "border-block-start-color", "border-block-start-style", "border-block-start-width", "border-bottom-color", "-moz-border-bottom-colors", "border-bottom-style", "border-bottom-width", "border-collapse", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", "border-inline-end-color", "border-inline-end-style", "border-inline-end-width", "border-inline-start-color", "border-inline-start-style", "border-inline-start-width", "border-left-color", "-moz-border-left-colors", "border-left-style", "border-left-width", "border-right-color", "-moz-border-right-colors", "border-right-style", "border-right-width", "border-spacing", "border-top-color", "-moz-border-top-colors", "border-top-style", "border-top-width", "border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", "bottom", "box-decoration-break", "box-shadow", "box-sizing", "caption-side", "clear", "clip", "color", "-moz-column-count", "-moz-column-fill", "-moz-column-width", "-moz-column-gap", "-moz-column-rule-color", "-moz-column-rule-style", "-moz-column-rule-width", "contain", "content", "-moz-control-character-visibility", "counter-increment", "counter-reset", "cursor", "display", "empty-cells", "align-content", "align-items", "align-self", "flex-basis", "flex-direction", "flex-grow", "flex-shrink", "flex-wrap", "order", "justify-content", "justify-items", "justify-self", "float", "-moz-float-edge", "font-family", "font-feature-settings", "font-kerning", "font-language-override", "font-size", "font-size-adjust", "-moz-osx-font-smoothing", "font-stretch", "font-style", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", "font-weight", "-moz-force-broken-image-icon", "grid-auto-flow", "grid-auto-columns", "grid-auto-rows", "grid-template-areas", "grid-template-columns", "grid-template-rows", "grid-column-start", "grid-column-end", "grid-row-start", "grid-row-end", "grid-column-gap", "grid-row-gap", "height", "image-orientation", "-moz-image-region", "ime-mode", "inline-size", "left", "letter-spacing", "line-height", "list-style-image", "list-style-position", "list-style-type", "margin-block-end", "margin-block-start", "margin-bottom", "margin-inline-end", "margin-inline-start", "margin-left", "margin-right", "margin-top", "marker-offset", "max-block-size", "max-height", "max-inline-size", "max-width", "-moz-min-font-size-ratio", "min-height", "min-block-size", "min-inline-size", "min-width", "mix-blend-mode", "isolation", "object-fit", "object-position", "offset-block-end", "offset-block-start", "offset-inline-end", "offset-inline-start", "opacity", "-moz-orient", "outline-color", "outline-style", "outline-width", "outline-offset", "overflow-clip-box", "overflow-x", "overflow-y", "padding-block-end", "padding-block-start", "padding-bottom", "padding-inline-end", "padding-inline-start", "padding-left", "padding-right", "padding-top", "page-break-after", "page-break-before", "page-break-inside", "paint-order", "pointer-events", "position", "quotes", "resize", "right", "ruby-align", "ruby-position", "scroll-behavior", "scroll-snap-coordinate", "scroll-snap-destination", "scroll-snap-points-x", "scroll-snap-points-y", "scroll-snap-type-x", "scroll-snap-type-y", "table-layout", "text-align", "-moz-text-align-last", "text-combine-upright", "text-decoration-color", "text-decoration-line", "text-decoration-style", "text-indent", "text-orientation", "text-overflow", "text-shadow", "-moz-text-size-adjust", "text-transform", "transform", "transform-box", "transform-origin", "perspective-origin", "perspective", "transform-style", "backface-visibility", "top", "-moz-top-layer", "touch-action", "transition-delay", "transition-duration", "transition-property", "transition-timing-function", "-moz-user-focus", "-moz-user-input", "-moz-user-modify", "-moz-user-select", "vertical-align", "visibility", "white-space", "width", "-moz-window-dragging", "-moz-window-shadow", "word-break", "word-spacing", "word-wrap", "hyphens", "writing-mode", "z-index", "-moz-box-align", "-moz-box-direction", "-moz-box-flex", "-moz-box-orient", "-moz-box-pack", "-moz-box-ordinal-group", "-moz-stack-sizing", "clip-path", "clip-rule", "color-interpolation", "color-interpolation-filters", "dominant-baseline", "fill", "fill-opacity", "fill-rule", "filter", "flood-color", "flood-opacity", "image-rendering", "lighting-color", "marker-end", "marker-mid", "marker-start", "mask", "mask-type", "shape-rendering", "stop-color", "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-anchor", "text-rendering", "vector-effect", "will-change", ], + inherited: false, + supports: 2015, + values: ["-moz-all", "-moz-available", "-moz-block-height", "-moz-box", "-moz-calc", "-moz-center", "-moz-crisp-edges", "-moz-deck", "-moz-element", "-moz-fit-content", "-moz-grid", "-moz-grid-group", "-moz-grid-line", "-moz-groupbox", "-moz-gtk-info-bar", "-moz-hidden-unscrollable", "-moz-image-rect", "-moz-inline-box", "-moz-inline-grid", "-moz-inline-stack", "-moz-left", "-moz-linear-gradient", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-max-content", "-moz-middle-with-baseline", "-moz-min-content", "-moz-none", "-moz-popup", "-moz-pre-space", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-right", "-moz-stack", "-moz-text", "-moz-use-text-color", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "absolute", "active", "aliceblue", "all", "all-petite-caps", "all-small-caps", "alpha", "alphabetic", "alternate", "alternate-reverse", "always", "antiquewhite", "aqua", "aquamarine", "auto", "avoid", "azure", "backwards", "balance", "baseline", "beige", "bevel", "bisque", "black", "blanchedalmond", "block", "block-axis", "blue", "blueviolet", "border-box", "both", "bottom", "bottom-outside", "break-all", "break-word", "brown", "burlywood", "butt", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "cadetblue", "calc", "capitalize", "caret", "center", "central", "chartreuse", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "chocolate", "clone", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse", "condensed", "contain", "content-box", "contents", "coral", "cornflowerblue", "cornsilk", "cover", "crimson", "crispedges", "cubic-bezier", "currentColor", "cyan", "darkblue", "darkcyan", "darken", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dialog", "difference", "dimgray", "dimgrey", "disabled", "dodgerblue", "dotted", "double", "drag", "dualbutton", "ease", "ease-in", "ease-in-out", "ease-out", "element", "elements", "enabled", "end", "evenodd", "exclusion", "expanded", "extra-condensed", "extra-expanded", "fill", "fill-box", "firebrick", "fixed", "flat", "flex", "floralwhite", "forestgreen", "forwards", "fuchsia", "full-width", "gainsboro", "geometricprecision", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "grid", "groove", "groupbox", "hanging", "hard-light", "hidden", "hide", "honeydew", "horizontal", "horizontal-tb", "hotpink", "hsl", "hsla", "hue", "ideographic", "ignore", "inactive", "indianred", "indigo", "infinite", "inherit", "initial", "inline", "inline-axis", "inline-block", "inline-end", "inline-flex", "inline-grid", "inline-start", "inline-table", "inset", "inside", "isolate", "italic", "ivory", "justify", "keep-all", "khaki", "large", "larger", "lavender", "lavenderblush", "lawngreen", "layout", "left", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lighten", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear", "linear-gradient", "linearrgb", "linen", "list-item", "listbox", "listitem", "local", "lowercase", "lr", "lr-tb", "luminance", "luminosity", "magenta", "mandatory", "manual", "margin-box", "maroon", "mathematical", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "middle", "midnightblue", "mintcream", "mistyrose", "miter", "mixed", "moccasin", "multiply", "navajowhite", "navy", "no-change", "no-drag", "no-repeat", "non-scaling-stroke", "none", "nonzero", "normal", "nowrap", "number-input", "oblique", "oldlace", "olive", "olivedrab", "optimizelegibility", "optimizequality", "optimizespeed", "orange", "orangered", "orchid", "outset", "outside", "over", "overlay", "padding-box", "paint", "painted", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "paused", "peachpuff", "peru", "petite-caps", "pink", "plum", "powderblue", "pre", "pre-line", "pre-wrap", "preserve-3d", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "proximity", "purple", "radial-gradient", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "read-only", "read-write", "rebeccapurple", "red", "relative", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "reset-size", "resizer", "resizerpanel", "reverse", "rgb", "rgba", "ridge", "right", "rl", "rl-tb", "rosybrown", "round", "row", "row-reverse", "royalblue", "ruby", "ruby-base", "ruby-base-container", "ruby-text", "ruby-text-container", "running", "saddlebrown", "salmon", "sandybrown", "saturation", "scale-down", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "screen", "scroll", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "seagreen", "searchfield", "seashell", "select-after", "select-all", "select-before", "select-menu", "select-same", "semi-condensed", "semi-expanded", "separate", "separator", "show", "sideways", "sideways-lr", "sideways-right", "sideways-rl", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "slice", "small", "small-caps", "smaller", "smooth", "snow", "soft-light", "solid", "space-around", "space-between", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "springgreen", "square", "srgb", "start", "static", "statusbar", "statusbarpanel", "steelblue", "step-end", "step-start", "steps", "sticky", "stretch", "stretch-to-fit", "strict", "stroke", "style", "sub", "super", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row", "table-row-group", "tabpanel", "tabpanels", "tan", "tb", "tb-rl", "teal", "text", "text-after-edge", "text-before-edge", "text-bottom", "text-top", "textfield", "textfield-multiline", "thick", "thin", "thistle", "titling-caps", "toggle", "tomato", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "top", "top-outside", "transparent", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "tri-state", "turquoise", "ultra-condensed", "ultra-expanded", "under", "unicase", "unset", "uppercase", "upright", "url", "use-script", "vertical", "vertical-lr", "vertical-rl", "view-box", "violet", "visible", "visiblefill", "visiblepainted", "visiblestroke", "wavy", "wheat", "white", "whitesmoke", "window", "wrap", "wrap-reverse", "write-only", "x-large", "x-small", "xx-large", "xx-small", "yellow", "yellowgreen", ], + }, + "animation": { + subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], + inherited: false, + supports: 1344, + values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], + }, + "background": { + subproperties: ["background-color", "background-image", "background-repeat", "background-attachment", "background-position", "background-clip", "background-origin", "background-size", ], + inherited: false, + supports: 655, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "border-box", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "content-box", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "fixed", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear-gradient", "linen", "local", "magenta", "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "no-repeat", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "padding-box", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "radial-gradient", "rebeccapurple", "red", "repeat", "repeat-x", "repeat-y", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "scroll", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "url", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border": { + subproperties: ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width", "border-top-style", "border-right-style", "border-bottom-style", "border-left-style", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "-moz-border-top-colors", "-moz-border-right-colors", "-moz-border-bottom-colors", "-moz-border-left-colors", "border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linear-gradient", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "radial-gradient", "rebeccapurple", "red", "repeating-linear-gradient", "repeating-radial-gradient", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "url", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-block-end": { + subproperties: ["border-block-end-width", "border-block-end-style", "border-block-end-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-block-start": { + subproperties: ["border-block-start-width", "border-block-start-style", "border-block-start-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-bottom": { + subproperties: ["border-bottom-width", "border-bottom-style", "border-bottom-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-color": { + subproperties: ["border-top-color", "border-right-color", "border-bottom-color", "border-left-color", ], + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-image": { + subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], + inherited: false, + supports: 1675, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "border-inline-end": { + subproperties: ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-inline-start": { + subproperties: ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-left": { + subproperties: ["border-left-width", "border-left-style", "border-left-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-right": { + subproperties: ["border-right-width", "border-right-style", "border-right-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-style": { + subproperties: ["border-top-style", "border-right-style", "border-bottom-style", "border-left-style", ], + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "border-top": { + subproperties: ["border-top-width", "border-top-style", "border-top-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "border-width": { + subproperties: ["border-top-width", "border-right-width", "border-bottom-width", "border-left-width", ], + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "border-radius": { + subproperties: ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", ], + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-columns": { + subproperties: ["-moz-column-count", "-moz-column-width", ], + inherited: false, + supports: 1025, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "-moz-column-rule": { + subproperties: ["-moz-column-rule-width", "-moz-column-rule-style", "-moz-column-rule-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "flex": { + subproperties: ["flex-grow", "flex-shrink", "flex-basis", ], + inherited: false, + supports: 1027, + values: ["-moz-available", "-moz-calc", "-moz-fit-content", "-moz-max-content", "-moz-min-content", "auto", "calc", "inherit", "initial", "unset", ], + }, + "flex-flow": { + subproperties: ["flex-direction", "flex-wrap", ], + inherited: false, + supports: 0, + values: ["column", "column-reverse", "inherit", "initial", "nowrap", "row", "row-reverse", "unset", "wrap", "wrap-reverse", ], + }, + "font": { + subproperties: ["font-family", "font-style", "font-weight", "font-size", "line-height", "font-size-adjust", "font-stretch", "-x-system-font", "font-feature-settings", "font-language-override", "font-kerning", "font-synthesis", "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", ], + inherited: true, + supports: 1027, + values: ["-moz-block-height", "-moz-calc", "all-petite-caps", "all-small-caps", "auto", "calc", "condensed", "expanded", "extra-condensed", "extra-expanded", "inherit", "initial", "italic", "large", "larger", "medium", "none", "normal", "oblique", "petite-caps", "semi-condensed", "semi-expanded", "small", "small-caps", "smaller", "sub", "super", "titling-caps", "ultra-condensed", "ultra-expanded", "unicase", "unset", "x-large", "x-small", "xx-large", "xx-small", ], + }, + "font-variant": { + subproperties: ["font-variant-alternates", "font-variant-caps", "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", "font-variant-position", ], + inherited: true, + supports: 0, + values: ["all-petite-caps", "all-small-caps", "inherit", "initial", "normal", "petite-caps", "small-caps", "sub", "super", "titling-caps", "unicase", "unset", ], + }, + "grid-template": { + subproperties: ["grid-template-areas", "grid-template-columns", "grid-template-rows", ], + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "grid": { + subproperties: ["grid-template-areas", "grid-template-columns", "grid-template-rows", "grid-auto-flow", "grid-auto-columns", "grid-auto-rows", "grid-column-gap", "grid-row-gap", ], + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "grid-column": { + subproperties: ["grid-column-start", "grid-column-end", ], + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-row": { + subproperties: ["grid-row-start", "grid-row-end", ], + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-area": { + subproperties: ["grid-row-start", "grid-column-start", "grid-row-end", "grid-column-end", ], + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "grid-gap": { + subproperties: ["grid-column-gap", "grid-row-gap", ], + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "list-style": { + subproperties: ["list-style-type", "list-style-image", "list-style-position", ], + inherited: true, + supports: 8, + values: ["inherit", "initial", "inside", "none", "outside", "unset", "url", ], + }, + "margin": { + subproperties: ["margin-top", "margin-right", "margin-bottom", "margin-left", ], + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "outline": { + subproperties: ["outline-width", "outline-style", "outline-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "auto", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "overflow": { + subproperties: ["overflow-x", "overflow-y", ], + inherited: false, + supports: 0, + values: ["-moz-hidden-unscrollable", "auto", "hidden", "inherit", "initial", "scroll", "unset", "visible", ], + }, + "padding": { + subproperties: ["padding-top", "padding-right", "padding-bottom", "padding-left", ], + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "scroll-snap-type": { + subproperties: ["scroll-snap-type-x", "scroll-snap-type-y", ], + inherited: false, + supports: 0, + values: ["inherit", "initial", "mandatory", "none", "proximity", "unset", ], + }, + "text-decoration": { + subproperties: ["text-decoration-color", "text-decoration-line", "text-decoration-style", ], + inherited: false, + supports: 4, + values: ["-moz-none", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wavy", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "transition": { + subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], + inherited: false, + supports: 320, + values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], + }, + "marker": { + subproperties: ["marker-start", "marker-mid", "marker-end", ], + inherited: true, + supports: 8, + values: ["inherit", "initial", "none", "unset", "url", ], + }, + "-moz-transform": { + alias: true, + subproperties: ["transform", ], + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-moz-transform-origin": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-perspective-origin": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-moz-perspective": { + alias: true, + inherited: false, + supports: 1, + values: ["inherit", "initial", "none", "unset", ], + }, + "-moz-transform-style": { + alias: true, + inherited: false, + supports: 0, + values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], + }, + "-moz-backface-visibility": { + alias: true, + inherited: false, + supports: 0, + values: ["hidden", "inherit", "initial", "unset", "visible", ], + }, + "-moz-border-image": { + alias: true, + subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], + inherited: false, + supports: 1675, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "-moz-transition": { + alias: true, + subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], + inherited: false, + supports: 320, + values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], + }, + "-moz-transition-delay": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-moz-transition-duration": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-moz-transition-property": { + alias: true, + inherited: false, + supports: 0, + values: ["all", "inherit", "initial", "none", "unset", ], + }, + "-moz-transition-timing-function": { + alias: true, + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "-moz-animation": { + alias: true, + subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], + inherited: false, + supports: 1344, + values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], + }, + "-moz-animation-delay": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-moz-animation-direction": { + alias: true, + inherited: false, + supports: 0, + values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], + }, + "-moz-animation-duration": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-moz-animation-fill-mode": { + alias: true, + inherited: false, + supports: 0, + values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], + }, + "-moz-animation-iteration-count": { + alias: true, + inherited: false, + supports: 1024, + values: ["infinite", "inherit", "initial", "unset", ], + }, + "-moz-animation-name": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "none", "unset", ], + }, + "-moz-animation-play-state": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "paused", "running", "unset", ], + }, + "-moz-animation-timing-function": { + alias: true, + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "-moz-box-sizing": { + alias: true, + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "-moz-font-feature-settings": { + alias: true, + inherited: true, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-moz-font-language-override": { + alias: true, + inherited: true, + supports: 0, + values: ["inherit", "initial", "normal", "unset", ], + }, + "-moz-padding-end": { + alias: true, + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "-moz-padding-start": { + alias: true, + inherited: false, + supports: 3, + values: ["-moz-calc", "calc", "inherit", "initial", "unset", ], + }, + "-moz-margin-end": { + alias: true, + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "-moz-margin-start": { + alias: true, + inherited: false, + supports: 3, + values: ["-moz-calc", "auto", "calc", "inherit", "initial", "unset", ], + }, + "-moz-border-end": { + alias: true, + subproperties: ["border-inline-end-width", "border-inline-end-style", "border-inline-end-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-end-color": { + alias: true, + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-end-style": { + alias: true, + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "-moz-border-end-width": { + alias: true, + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "-moz-border-start": { + alias: true, + subproperties: ["border-inline-start-width", "border-inline-start-style", "border-inline-start-color", ], + inherited: false, + supports: 5, + values: ["-moz-calc", "-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "calc", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "dashed", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "dotted", "double", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "groove", "hidden", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "inset", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", "maroon", "medium", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", "navajowhite", "navy", "none", "oldlace", "olive", "olivedrab", "orange", "orangered", "orchid", "outset", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", "rgb", "rgba", "ridge", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "solid", "springgreen", "steelblue", "tan", "teal", "thick", "thin", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-start-color": { + alias: true, + inherited: false, + supports: 4, + values: ["-moz-use-text-color", "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "currentColor", "cyan", "darkblue", "darkcyan", "darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey", "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", "hotpink", "hsl", "hsla", "indianred", "indigo", "inherit", "initial", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "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", "rgb", "rgba", "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "teal", "thistle", "tomato", "transparent", "turquoise", "unset", "violet", "wheat", "white", "whitesmoke", "yellow", "yellowgreen", ], + }, + "-moz-border-start-style": { + alias: true, + inherited: false, + supports: 0, + values: ["dashed", "dotted", "double", "groove", "hidden", "inherit", "initial", "inset", "none", "outset", "ridge", "solid", "unset", ], + }, + "-moz-border-start-width": { + alias: true, + inherited: false, + supports: 1, + values: ["-moz-calc", "calc", "inherit", "initial", "medium", "thick", "thin", "unset", ], + }, + "-moz-hyphens": { + alias: true, + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "manual", "none", "unset", ], + }, + "-webkit-animation": { + alias: true, + subproperties: ["animation-duration", "animation-timing-function", "animation-delay", "animation-direction", "animation-fill-mode", "animation-iteration-count", "animation-play-state", "animation-name", ], + inherited: false, + supports: 1344, + values: ["alternate", "alternate-reverse", "backwards", "both", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "forwards", "infinite", "inherit", "initial", "linear", "none", "normal", "paused", "reverse", "running", "step-end", "step-start", "steps", "unset", ], + }, + "-webkit-animation-delay": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-animation-direction": { + alias: true, + inherited: false, + supports: 0, + values: ["alternate", "alternate-reverse", "inherit", "initial", "normal", "reverse", "unset", ], + }, + "-webkit-animation-duration": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-animation-fill-mode": { + alias: true, + inherited: false, + supports: 0, + values: ["backwards", "both", "forwards", "inherit", "initial", "none", "unset", ], + }, + "-webkit-animation-iteration-count": { + alias: true, + inherited: false, + supports: 1024, + values: ["infinite", "inherit", "initial", "unset", ], + }, + "-webkit-animation-name": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "none", "unset", ], + }, + "-webkit-animation-play-state": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "paused", "running", "unset", ], + }, + "-webkit-animation-timing-function": { + alias: true, + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "-webkit-text-size-adjust": { + alias: true, + inherited: true, + supports: 0, + values: ["auto", "inherit", "initial", "none", "unset", ], + }, + "-webkit-transform": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-transform-origin": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-transform-style": { + alias: true, + inherited: false, + supports: 0, + values: ["flat", "inherit", "initial", "preserve-3d", "unset", ], + }, + "-webkit-backface-visibility": { + alias: true, + inherited: false, + supports: 0, + values: ["hidden", "inherit", "initial", "unset", "visible", ], + }, + "-webkit-perspective": { + alias: true, + inherited: false, + supports: 1, + values: ["inherit", "initial", "none", "unset", ], + }, + "-webkit-perspective-origin": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-transition": { + alias: true, + subproperties: ["transition-property", "transition-duration", "transition-timing-function", "transition-delay", ], + inherited: false, + supports: 320, + values: ["all", "cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "none", "step-end", "step-start", "steps", "unset", ], + }, + "-webkit-transition-delay": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-transition-duration": { + alias: true, + inherited: false, + supports: 64, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-transition-property": { + alias: true, + inherited: false, + supports: 0, + values: ["all", "inherit", "initial", "none", "unset", ], + }, + "-webkit-transition-timing-function": { + alias: true, + inherited: false, + supports: 256, + values: ["cubic-bezier", "ease", "ease-in", "ease-in-out", "ease-out", "inherit", "initial", "linear", "step-end", "step-start", "steps", "unset", ], + }, + "-webkit-border-radius": { + alias: true, + subproperties: ["border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", ], + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-top-left-radius": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-top-right-radius": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-bottom-left-radius": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-bottom-right-radius": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-appearance": { + alias: true, + inherited: false, + supports: 0, + values: ["-moz-gtk-info-bar", "-moz-mac-disclosure-button-closed", "-moz-mac-disclosure-button-open", "-moz-mac-fullscreen-button", "-moz-mac-help-button", "-moz-mac-vibrancy-dark", "-moz-mac-vibrancy-light", "-moz-win-borderless-glass", "-moz-win-browsertabbar-toolbox", "-moz-win-communications-toolbox", "-moz-win-exclude-glass", "-moz-win-glass", "-moz-win-media-toolbox", "-moz-window-button-box", "-moz-window-button-box-maximized", "-moz-window-button-close", "-moz-window-button-maximize", "-moz-window-button-minimize", "-moz-window-button-restore", "-moz-window-frame-bottom", "-moz-window-frame-left", "-moz-window-frame-right", "-moz-window-titlebar", "-moz-window-titlebar-maximized", "button", "button-arrow-down", "button-arrow-next", "button-arrow-previous", "button-arrow-up", "button-bevel", "button-focus", "caret", "checkbox", "checkbox-container", "checkbox-label", "checkmenuitem", "dialog", "dualbutton", "groupbox", "inherit", "initial", "listbox", "listitem", "menuarrow", "menubar", "menucheckbox", "menuimage", "menuitem", "menuitemtext", "menulist", "menulist-button", "menulist-text", "menulist-textfield", "menupopup", "menuradio", "menuseparator", "meterbar", "meterchunk", "none", "number-input", "progressbar", "progressbar-vertical", "progresschunk", "progresschunk-vertical", "radio", "radio-container", "radio-label", "radiomenuitem", "range", "range-thumb", "resizer", "resizerpanel", "scale-horizontal", "scale-vertical", "scalethumb-horizontal", "scalethumb-vertical", "scalethumbend", "scalethumbstart", "scalethumbtick", "scrollbar", "scrollbar-small", "scrollbarbutton-down", "scrollbarbutton-left", "scrollbarbutton-right", "scrollbarbutton-up", "scrollbarthumb-horizontal", "scrollbarthumb-vertical", "scrollbartrack-horizontal", "scrollbartrack-vertical", "searchfield", "separator", "spinner", "spinner-downbutton", "spinner-textfield", "spinner-upbutton", "splitter", "statusbar", "statusbarpanel", "tab", "tab-scroll-arrow-back", "tab-scroll-arrow-forward", "tabpanel", "tabpanels", "textfield", "textfield-multiline", "toolbar", "toolbarbutton", "toolbarbutton-dropdown", "toolbargripper", "toolbox", "tooltip", "treeheader", "treeheadercell", "treeheadersortarrow", "treeitem", "treeline", "treetwisty", "treetwistyopen", "treeview", "unset", "window", ], + }, + "-webkit-background-clip": { + alias: true, + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "-webkit-background-origin": { + alias: true, + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "-webkit-background-size": { + alias: true, + inherited: false, + supports: 3, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-image": { + alias: true, + subproperties: ["border-image-source", "border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat", ], + inherited: false, + supports: 1675, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "-webkit-border-image-outset": { + alias: true, + inherited: false, + supports: 1025, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-image-repeat": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-image-slice": { + alias: true, + inherited: false, + supports: 1026, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-border-image-source": { + alias: true, + inherited: false, + supports: 648, + values: ["-moz-element", "-moz-image-rect", "-moz-linear-gradient", "-moz-radial-gradient", "-moz-repeating-linear-gradient", "-moz-repeating-radial-gradient", "inherit", "initial", "linear-gradient", "none", "radial-gradient", "repeating-linear-gradient", "repeating-radial-gradient", "unset", "url", ], + }, + "-webkit-border-image-width": { + alias: true, + inherited: false, + supports: 1027, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-box-shadow": { + alias: true, + inherited: false, + supports: 5, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-box-sizing": { + alias: true, + inherited: false, + supports: 0, + values: ["border-box", "content-box", "inherit", "initial", "padding-box", "unset", ], + }, + "-webkit-box-flex": { + alias: true, + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-box-ordinal-group": { + alias: true, + inherited: false, + supports: 1024, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-box-align": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-box-pack": { + alias: true, + inherited: false, + supports: 0, + values: ["inherit", "initial", "unset", ], + }, + "-webkit-user-select": { + alias: true, + inherited: false, + supports: 0, + values: ["-moz-all", "-moz-none", "-moz-text", "all", "auto", "element", "elements", "inherit", "initial", "none", "text", "toggle", "tri-state", "unset", ], + }, + }; + module.exports = { cssProperties }; + + +/***/ }, +/* 76 */ +/***/ function(module, exports) { + + /* + * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/Promise.jsm + */ + + /** + * Promise.jsm is mostly the Promise web API with a `defer` method. Just drop this in here, + * and use the native web API (although building with webpack/babel, it may replace this + * with it's own version if we want to target environments that do not have `Promise`. + */ + + let p = typeof window != "undefined" ? window.Promise : Promise; + p.defer = function defer() { + var resolve, reject; + var promise = new Promise(function() { + resolve = arguments[0]; + reject = arguments[1]; + }); + return { + resolve: resolve, + reject: reject, + promise: promise + }; + } + + module.exports = p; + + +/***/ }, +/* 77 */ +/***/ function(module, exports, __webpack_require__) { + + /* eslint-env browser */ + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + // TODO: Get rid of this code once the marionette server loads transport.js as + // an SDK module (see bug 1000814) + + "use strict"; + + const DevToolsUtils = __webpack_require__(78); + const { dumpn, dumpv } = DevToolsUtils; + const StreamUtils = __webpack_require__(84); + const { Packet, JSONPacket, BulkPacket } = + __webpack_require__(85); + const promise = __webpack_require__(76); + const EventEmitter = __webpack_require__(70); + const utf8 = __webpack_require__(88); + + const PACKET_HEADER_MAX = 200; + + /** + * An adapter that handles data transfers between the debugger client and + * server. It can work with both nsIPipe and nsIServerSocket transports so + * long as the properly created input and output streams are specified. + * (However, for intra-process connections, LocalDebuggerTransport, below, + * is more efficient than using an nsIPipe pair with DebuggerTransport.) + * + * @param input nsIAsyncInputStream + * The input stream. + * @param output nsIAsyncOutputStream + * The output stream. + * + * Given a DebuggerTransport instance dt: + * 1) Set dt.hooks to a packet handler object (described below). + * 2) Call dt.ready() to begin watching for input packets. + * 3) Call dt.send() / dt.startBulkSend() to send packets. + * 4) Call dt.close() to close the connection, and disengage from the event + * loop. + * + * A packet handler is an object with the following methods: + * + * - onPacket(packet) - called when we have received a complete packet. + * |packet| is the parsed form of the packet --- a JavaScript value, not + * a JSON-syntax string. + * + * - onBulkPacket(packet) - called when we have switched to bulk packet + * receiving mode. |packet| is an object containing: + * * actor: Name of actor that will receive the packet + * * type: Name of actor's method that should be called on receipt + * * length: Size of the data to be read + * * stream: This input stream should only be used directly if you can ensure + * that you will read exactly |length| bytes and will not close the + * stream when reading is complete + * * done: If you use the stream directly (instead of |copyTo| below), you + * must signal completion by resolving / rejecting this deferred. + * If it's rejected, the transport will be closed. If an Error is + * supplied as a rejection value, it will be logged via |dumpn|. + * If you do use |copyTo|, resolving is taken care of for you when + * copying completes. + * * copyTo: A helper function for getting your data out of the stream that + * meets the stream handling requirements above, and has the + * following signature: + * @param output nsIAsyncOutputStream + * The stream to copy to. + * @return Promise + * The promise is resolved when copying completes or rejected if any + * (unexpected) errors occur. + * This object also emits "progress" events for each chunk that is + * copied. See stream-utils.js. + * + * - onClosed(reason) - called when the connection is closed. |reason| is + * an optional nsresult or object, typically passed when the transport is + * closed due to some error in a underlying stream. + * + * See ./packets.js and the Remote Debugging Protocol specification for more + * details on the format of these packets. + */ + function DebuggerTransport(socket) { + EventEmitter.decorate(this); + + this._socket = socket; + + // The current incoming (possibly partial) header, which will determine which + // type of Packet |_incoming| below will become. + this._incomingHeader = ""; + // The current incoming Packet object + this._incoming = null; + // A queue of outgoing Packet objects + this._outgoing = []; + + this.hooks = null; + this.active = false; + + this._incomingEnabled = true; + this._outgoingEnabled = true; + + this.close = this.close.bind(this); + } + + DebuggerTransport.prototype = { + /** + * Transmit an object as a JSON packet. + * + * This method returns immediately, without waiting for the entire + * packet to be transmitted, registering event handlers as needed to + * transmit the entire packet. Packets are transmitted in the order + * they are passed to this method. + */ + send: function(object) { + this.emit("send", object); + + let packet = new JSONPacket(this); + packet.object = object; + this._outgoing.push(packet); + this._flushOutgoing(); + }, + + /** + * Transmit streaming data via a bulk packet. + * + * This method initiates the bulk send process by queuing up the header data. + * The caller receives eventual access to a stream for writing. + * + * N.B.: Do *not* attempt to close the stream handed to you, as it will + * continue to be used by this transport afterwards. Most users should + * instead use the provided |copyFrom| function instead. + * + * @param header Object + * This is modeled after the format of JSON packets above, but does not + * actually contain the data, but is instead just a routing header: + * * actor: Name of actor that will receive the packet + * * type: Name of actor's method that should be called on receipt + * * length: Size of the data to be sent + * @return Promise + * The promise will be resolved when you are allowed to write to the + * stream with an object containing: + * * stream: This output stream should only be used directly if + * you can ensure that you will write exactly |length| + * bytes and will not close the stream when writing is + * complete + * * done: If you use the stream directly (instead of |copyFrom| + * below), you must signal completion by resolving / + * rejecting this deferred. If it's rejected, the + * transport will be closed. If an Error is supplied as + * a rejection value, it will be logged via |dumpn|. If + * you do use |copyFrom|, resolving is taken care of for + * you when copying completes. + * * copyFrom: A helper function for getting your data onto the + * stream that meets the stream handling requirements + * above, and has the following signature: + * @param input nsIAsyncInputStream + * The stream to copy from. + * @return Promise + * The promise is resolved when copying completes or + * rejected if any (unexpected) errors occur. + * This object also emits "progress" events for each chunk + * that is copied. See stream-utils.js. + */ + startBulkSend: function(header) { + this.emit("startBulkSend", header); + + let packet = new BulkPacket(this); + packet.header = header; + this._outgoing.push(packet); + this._flushOutgoing(); + return packet.streamReadyForWriting; + }, + + /** + * Close the transport. + * @param reason nsresult / object (optional) + * The status code or error message that corresponds to the reason for + * closing the transport (likely because a stream closed or failed). + */ + close: function(reason) { + this.emit("onClosed", reason); + + this.active = false; + this._socket.close(); + this._destroyIncoming(); + this._destroyAllOutgoing(); + if (this.hooks) { + this.hooks.onClosed(reason); + this.hooks = null; + } + if (reason) { + dumpn("Transport closed: " + DevToolsUtils.safeErrorString(reason)); + } else { + dumpn("Transport closed."); + } + }, + + /** + * The currently outgoing packet (at the top of the queue). + */ + get _currentOutgoing() { + return this._outgoing[0]; + }, + + /** + * Flush data to the outgoing stream. Waits until the output stream notifies + * us that it is ready to be written to (via onOutputStreamReady). + */ + _flushOutgoing: function() { + if (!this._outgoingEnabled || this._outgoing.length === 0) { + return; + } + + // If the top of the packet queue has nothing more to send, remove it. + if (this._currentOutgoing.done) { + this._finishCurrentOutgoing(); + } + + if (this._outgoing.length > 0) { + setTimeout(this.onOutputStreamReady.bind(this), 0); + } + }, + + /** + * Pause this transport's attempts to write to the output stream. This is + * used when we've temporarily handed off our output stream for writing bulk + * data. + */ + pauseOutgoing: function() { + this._outgoingEnabled = false; + }, + + /** + * Resume this transport's attempts to write to the output stream. + */ + resumeOutgoing: function() { + this._outgoingEnabled = true; + this._flushOutgoing(); + }, + + // nsIOutputStreamCallback + /** + * This is called when the output stream is ready for more data to be written. + * The current outgoing packet will attempt to write some amount of data, but + * may not complete. + */ + onOutputStreamReady: DevToolsUtils.makeInfallible(function() { + if (!this._outgoingEnabled || this._outgoing.length === 0) { + return; + } + + try { + this._currentOutgoing.write({ + write: data => { + let count = data.length; + this._socket.send(data); + return count; + } + }); + } catch(e) { + if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) { + this.close(e.result); + return; + } else { + throw e; + } + } + + this._flushOutgoing(); + }, "DebuggerTransport.prototype.onOutputStreamReady"), + + /** + * Remove the current outgoing packet from the queue upon completion. + */ + _finishCurrentOutgoing: function() { + if (this._currentOutgoing) { + this._currentOutgoing.destroy(); + this._outgoing.shift(); + } + }, + + /** + * Clear the entire outgoing queue. + */ + _destroyAllOutgoing: function() { + for (let packet of this._outgoing) { + packet.destroy(); + } + this._outgoing = []; + }, + + /** + * Initialize the input stream for reading. Once this method has been called, + * we watch for packets on the input stream, and pass them to the appropriate + * handlers via this.hooks. + */ + ready: function() { + this.active = true; + this._waitForIncoming(); + }, + + /** + * Asks the input stream to notify us (via onInputStreamReady) when it is + * ready for reading. + */ + _waitForIncoming: function() { + if (this._incomingEnabled && !this._socket.onmessage) { + this._socket.onmessage = this.onInputStreamReady.bind(this); + } + }, + + /** + * Pause this transport's attempts to read from the input stream. This is + * used when we've temporarily handed off our input stream for reading bulk + * data. + */ + pauseIncoming: function() { + this._incomingEnabled = false; + }, + + /** + * Resume this transport's attempts to read from the input stream. + */ + resumeIncoming: function() { + this._incomingEnabled = true; + this._flushIncoming(); + this._waitForIncoming(); + }, + + // nsIInputStreamCallback + /** + * Called when the stream is either readable or closed. + */ + onInputStreamReady: + DevToolsUtils.makeInfallible(function(event) { + let data = event.data; + // TODO: ws-tcp-proxy decodes utf-8, but the transport expects to see the + // encoded bytes. Simplest step is to re-encode for now. + data = utf8.encode(data); + let stream = { + available() { + return data.length; + }, + readBytes(count) { + let result = data.slice(0, count); + data = data.slice(count); + return result; + }, + }; + + try { + while (data && this._incomingEnabled && + this._processIncoming(stream, stream.available())) {} + this._waitForIncoming(); + } catch(e) { + if (e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) { + this.close(e.result); + } else { + throw e; + } + } + }, "DebuggerTransport.prototype.onInputStreamReady"), + + /** + * Process the incoming data. Will create a new currently incoming Packet if + * needed. Tells the incoming Packet to read as much data as it can, but + * reading may not complete. The Packet signals that its data is ready for + * delivery by calling one of this transport's _on*Ready methods (see + * ./packets.js and the _on*Ready methods below). + * @return boolean + * Whether incoming stream processing should continue for any + * remaining data. + */ + _processIncoming: function(stream, count) { + dumpv("Data available: " + count); + + if (!count) { + dumpv("Nothing to read, skipping"); + return false; + } + + try { + if (!this._incoming) { + dumpv("Creating a new packet from incoming"); + + if (!this._readHeader(stream)) { + return false; // Not enough data to read packet type + } + + // Attempt to create a new Packet by trying to parse each possible + // header pattern. + this._incoming = Packet.fromHeader(this._incomingHeader, this); + if (!this._incoming) { + throw new Error("No packet types for header: " + + this._incomingHeader); + } + } + + if (!this._incoming.done) { + // We have an incomplete packet, keep reading it. + dumpv("Existing packet incomplete, keep reading"); + this._incoming.read(stream); + } + } catch(e) { + let msg = "Error reading incoming packet: (" + e + " - " + e.stack + ")"; + dumpn(msg); + + // Now in an invalid state, shut down the transport. + this.close(); + return false; + } + + if (!this._incoming.done) { + // Still not complete, we'll wait for more data. + dumpv("Packet not done, wait for more"); + return true; + } + + // Ready for next packet + this._flushIncoming(); + return true; + }, + + /** + * Read as far as we can into the incoming data, attempting to build up a + * complete packet header (which terminates with ":"). We'll only read up to + * PACKET_HEADER_MAX characters. + * @return boolean + * True if we now have a complete header. + */ + _readHeader: function(stream) { + let amountToRead = PACKET_HEADER_MAX - this._incomingHeader.length; + this._incomingHeader += + StreamUtils.delimitedRead(stream, ":", amountToRead); + if (dumpv.wantVerbose) { + dumpv("Header read: " + this._incomingHeader); + } + + if (this._incomingHeader.endsWith(":")) { + if (dumpv.wantVerbose) { + dumpv("Found packet header successfully: " + this._incomingHeader); + } + return true; + } + + if (this._incomingHeader.length >= PACKET_HEADER_MAX) { + throw new Error("Failed to parse packet header!"); + } + + // Not enough data yet. + return false; + }, + + /** + * If the incoming packet is done, log it as needed and clear the buffer. + */ + _flushIncoming: function() { + if (!this._incoming.done) { + return; + } + if (dumpn.wantLogging) { + dumpn("Got: " + this._incoming); + } + this._destroyIncoming(); + }, + + /** + * Handler triggered by an incoming JSONPacket completing it's |read| method. + * Delivers the packet to this.hooks.onPacket. + */ + _onJSONObjectReady: function(object) { + DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { + // Ensure the transport is still alive by the time this runs. + if (this.active) { + this.emit("onPacket", object); + this.hooks.onPacket(object); + } + }, "DebuggerTransport instance's this.hooks.onPacket")); + }, + + /** + * Handler triggered by an incoming BulkPacket entering the |read| phase for + * the stream portion of the packet. Delivers info about the incoming + * streaming data to this.hooks.onBulkPacket. See the main comment on the + * transport at the top of this file for more details. + */ + _onBulkReadReady: function(...args) { + DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { + // Ensure the transport is still alive by the time this runs. + if (this.active) { + this.emit("onBulkPacket", ...args); + this.hooks.onBulkPacket(...args); + } + }, "DebuggerTransport instance's this.hooks.onBulkPacket")); + }, + + /** + * Remove all handlers and references related to the current incoming packet, + * either because it is now complete or because the transport is closing. + */ + _destroyIncoming: function() { + if (this._incoming) { + this._incoming.destroy(); + } + this._incomingHeader = ""; + this._incoming = null; + } + + }; + + exports.DebuggerTransport = DebuggerTransport; + + /** + * An adapter that handles data transfers between the debugger client and + * server when they both run in the same process. It presents the same API as + * DebuggerTransport, but instead of transmitting serialized messages across a + * connection it merely calls the packet dispatcher of the other side. + * + * @param other LocalDebuggerTransport + * The other endpoint for this debugger connection. + * + * @see DebuggerTransport + */ + function LocalDebuggerTransport(other) { + EventEmitter.decorate(this); + + this.other = other; + this.hooks = null; + + /* + * A packet number, shared between this and this.other. This isn't used + * by the protocol at all, but it makes the packet traces a lot easier to + * follow. + */ + this._serial = this.other ? this.other._serial : { count: 0 }; + this.close = this.close.bind(this); + } + + LocalDebuggerTransport.prototype = { + /** + * Transmit a message by directly calling the onPacket handler of the other + * endpoint. + */ + send: function(packet) { + this.emit("send", packet); + + let serial = this._serial.count++; + if (dumpn.wantLogging) { + /* Check 'from' first, as 'echo' packets have both. */ + if (packet.from) { + dumpn("Packet " + serial + " sent from " + uneval(packet.from)); + } else if (packet.to) { + dumpn("Packet " + serial + " sent to " + uneval(packet.to)); + } + } + this._deepFreeze(packet); + let other = this.other; + if (other) { + DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { + // Avoid the cost of JSON.stringify() when logging is disabled. + if (dumpn.wantLogging) { + dumpn("Received packet " + serial + ": " + JSON.stringify(packet, null, 2)); + } + if (other.hooks) { + other.emit("onPacket", packet); + other.hooks.onPacket(packet); + } + }, "LocalDebuggerTransport instance's this.other.hooks.onPacket")); + } + }, + + /** + * Send a streaming bulk packet directly to the onBulkPacket handler of the + * other endpoint. + * + * This case is much simpler than the full DebuggerTransport, since there is + * no primary stream we have to worry about managing while we hand it off to + * others temporarily. Instead, we can just make a single use pipe and be + * done with it. + */ + startBulkSend: function({actor, type, length}) { + this.emit("startBulkSend", {actor, type, length}); + + let serial = this._serial.count++; + + dumpn("Sent bulk packet " + serial + " for actor " + actor); + if (!this.other) { + return; + } + + let pipe = new Pipe(true, true, 0, 0, null); + + DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => { + dumpn("Received bulk packet " + serial); + if (!this.other.hooks) { + return; + } + + // Receiver + let deferred = promise.defer(); + let packet = { + actor: actor, + type: type, + length: length, + copyTo: (output) => { + let copying = + StreamUtils.copyStream(pipe.inputStream, output, length); + deferred.resolve(copying); + return copying; + }, + stream: pipe.inputStream, + done: deferred + }; + + this.other.emit("onBulkPacket", packet); + this.other.hooks.onBulkPacket(packet); + + // Await the result of reading from the stream + deferred.promise.then(() => pipe.inputStream.close(), this.close); + }, "LocalDebuggerTransport instance's this.other.hooks.onBulkPacket")); + + // Sender + let sendDeferred = promise.defer(); + + // The remote transport is not capable of resolving immediately here, so we + // shouldn't be able to either. + DevToolsUtils.executeSoon(() => { + let copyDeferred = promise.defer(); + + sendDeferred.resolve({ + copyFrom: (input) => { + let copying = + StreamUtils.copyStream(input, pipe.outputStream, length); + copyDeferred.resolve(copying); + return copying; + }, + stream: pipe.outputStream, + done: copyDeferred + }); + + // Await the result of writing to the stream + copyDeferred.promise.then(() => pipe.outputStream.close(), this.close); + }); + + return sendDeferred.promise; + }, + + /** + * Close the transport. + */ + close: function() { + this.emit("close"); + + if (this.other) { + // Remove the reference to the other endpoint before calling close(), to + // avoid infinite recursion. + let other = this.other; + this.other = null; + other.close(); + } + if (this.hooks) { + try { + this.hooks.onClosed(); + } catch(ex) { + console.error(ex); + } + this.hooks = null; + } + }, + + /** + * An empty method for emulating the DebuggerTransport API. + */ + ready: function() {}, + + /** + * Helper function that makes an object fully immutable. + */ + _deepFreeze: function(object) { + Object.freeze(object); + for (let prop in object) { + // Freeze the properties that are objects, not on the prototype, and not + // already frozen. Note that this might leave an unfrozen reference + // somewhere in the object if there is an already frozen object containing + // an unfrozen object. + if (object.hasOwnProperty(prop) && typeof object === "object" && + !Object.isFrozen(object)) { + this._deepFreeze(o[prop]); + } + } + } + }; + + exports.LocalDebuggerTransport = LocalDebuggerTransport; + + /** + * A transport for the debugging protocol that uses nsIMessageSenders to + * exchange packets with servers running in child processes. + * + * In the parent process, |sender| should be the nsIMessageSender for the + * child process. In a child process, |sender| should be the child process + * message manager, which sends packets to the parent. + * + * |prefix| is a string included in the message names, to distinguish + * multiple servers running in the same child process. + * + * This transport exchanges messages named 'debug::packet', where + * is |prefix|, whose data is the protocol packet. + */ + function ChildDebuggerTransport(sender, prefix) { + EventEmitter.decorate(this); + + this._sender = sender.QueryInterface(Ci.nsIMessageSender); + this._messageName = "debug:" + prefix + ":packet"; + } + + /* + * To avoid confusion, we use 'message' to mean something that + * nsIMessageSender conveys, and 'packet' to mean a remote debugging + * protocol packet. + */ + ChildDebuggerTransport.prototype = { + constructor: ChildDebuggerTransport, + + hooks: null, + + ready: function () { + this._sender.addMessageListener(this._messageName, this); + }, + + close: function () { + this._sender.removeMessageListener(this._messageName, this); + this.emit("onClosed"); + this.hooks.onClosed(); + }, + + receiveMessage: function ({data}) { + this.emit("onPacket", data); + this.hooks.onPacket(data); + }, + + send: function (packet) { + this.emit("send", packet); + this._sender.sendAsyncMessage(this._messageName, packet); + }, + + startBulkSend: function() { + throw new Error("Can't send bulk data to child processes."); + } + }; + + exports.ChildDebuggerTransport = ChildDebuggerTransport; + + // WorkerDebuggerTransport is defined differently depending on whether we are + // on the main thread or a worker thread. In the former case, we are required + // by the devtools loader, and isWorker will be false. Otherwise, we are + // required by the worker loader, and isWorker will be true. + // + // Each worker debugger supports only a single connection to the main thread. + // However, its theoretically possible for multiple servers to connect to the + // same worker. Consequently, each transport has a connection id, to allow + // messages from multiple connections to be multiplexed on a single channel. + + if (typeof WorkerGlobalScope === 'undefined') { // i.e. not in a worker + (function () { // Main thread + /** + * A transport that uses a WorkerDebugger to send packets from the main + * thread to a worker thread. + */ + function WorkerDebuggerTransport(dbg, id) { + this._dbg = dbg; + this._id = id; + this.onMessage = this._onMessage.bind(this); + } + + WorkerDebuggerTransport.prototype = { + constructor: WorkerDebuggerTransport, + + ready: function () { + this._dbg.addListener(this); + }, + + close: function () { + this._dbg.removeListener(this); + if (this.hooks) { + this.hooks.onClosed(); + } + }, + + send: function (packet) { + this._dbg.postMessage(JSON.stringify({ + type: "message", + id: this._id, + message: packet + })); + }, + + startBulkSend: function () { + throw new Error("Can't send bulk data from worker threads!"); + }, + + _onMessage: function (message) { + let packet = JSON.parse(message); + if (packet.type !== "message" || packet.id !== this._id) { + return; + } + + if (this.hooks) { + this.hooks.onPacket(packet.message); + } + } + }; + + exports.WorkerDebuggerTransport = WorkerDebuggerTransport; + }).call(this); + } else { + (function () { // Worker thread + /* + * A transport that uses a WorkerDebuggerGlobalScope to send packets from a + * worker thread to the main thread. + */ + function WorkerDebuggerTransport(scope, id) { + this._scope = scope; + this._id = id; + this._onMessage = this._onMessage.bind(this); + } + + WorkerDebuggerTransport.prototype = { + constructor: WorkerDebuggerTransport, + + ready: function () { + this._scope.addEventListener("message", this._onMessage); + }, + + close: function () { + this._scope.removeEventListener("message", this._onMessage); + if (this.hooks) { + this.hooks.onClosed(); + } + }, + + send: function (packet) { + this._scope.postMessage(JSON.stringify({ + type: "message", + id: this._id, + message: packet + })); + }, + + startBulkSend: function () { + throw new Error("Can't send bulk data from worker threads!"); + }, + + _onMessage: function (event) { + let packet = JSON.parse(event.data); + if (packet.type !== "message" || packet.id !== this._id) { + return; + } + + if (this.hooks) { + this.hooks.onPacket(packet.message); + } + } + }; + + exports.WorkerDebuggerTransport = WorkerDebuggerTransport; + }).call(this); + } + + +/***/ }, +/* 78 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + /* General utilities used throughout devtools. */ + var { Ci, Cu, Cc, components } = __webpack_require__(71); + const { Services } = __webpack_require__(40); + var promise = __webpack_require__(76); + + const { FileUtils } = __webpack_require__(79); + + /** + * Turn the error |aError| into a string, without fail. + */ + exports.safeErrorString = function safeErrorString(aError) { + try { + let errorString = aError.toString(); + if (typeof errorString == "string") { + // Attempt to attach a stack to |errorString|. If it throws an error, or + // isn't a string, don't use it. + try { + if (aError.stack) { + let stack = aError.stack.toString(); + if (typeof stack == "string") { + errorString += "\nStack: " + stack; + } + } + } catch (ee) { } + + // Append additional line and column number information to the output, + // since it might not be part of the stringified error. + if (typeof aError.lineNumber == "number" && typeof aError.columnNumber == "number") { + errorString += "Line: " + aError.lineNumber + ", column: " + aError.columnNumber; + } + + return errorString; + } + } catch (ee) { } + + // We failed to find a good error description, so do the next best thing. + return Object.prototype.toString.call(aError); + }; + + /** + * Report that |aWho| threw an exception, |aException|. + */ + exports.reportException = function reportException(aWho, aException) { + let msg = aWho + " threw an exception: " + exports.safeErrorString(aException); + + console.log(msg); + + // if (Cu && console.error) { + // /* + // * Note that the xpcshell test harness registers an observer for + // * console messages, so when we're running tests, this will cause + // * the test to quit. + // */ + // console.error(msg); + // } + }; + + /** + * Given a handler function that may throw, return an infallible handler + * function that calls the fallible handler, and logs any exceptions it + * throws. + * + * @param aHandler function + * A handler function, which may throw. + * @param aName string + * A name for aHandler, for use in error messages. If omitted, we use + * aHandler.name. + * + * (SpiderMonkey does generate good names for anonymous functions, but we + * don't have a way to get at them from JavaScript at the moment.) + */ + exports.makeInfallible = function makeInfallible(aHandler, aName) { + if (!aName) + aName = aHandler.name; + + return function(/* arguments */) { + // try { + return aHandler.apply(this, arguments); + // } catch (ex) { + // let who = "Handler function"; + // if (aName) { + // who += " " + aName; + // } + // return exports.reportException(who, ex); + // } + }; + }; + + /** + * Waits for the next tick in the event loop to execute a callback. + */ + exports.executeSoon = function executeSoon(aFn) { + setTimeout(aFn, 0); + }; + + /** + * Waits for the next tick in the event loop. + * + * @return Promise + * A promise that is resolved after the next tick in the event loop. + */ + exports.waitForTick = function waitForTick() { + let deferred = promise.defer(); + exports.executeSoon(deferred.resolve); + return deferred.promise; + }; + + /** + * Waits for the specified amount of time to pass. + * + * @param number aDelay + * The amount of time to wait, in milliseconds. + * @return Promise + * A promise that is resolved after the specified amount of time passes. + */ + exports.waitForTime = function waitForTime(aDelay) { + let deferred = promise.defer(); + setTimeout(deferred.resolve, aDelay); + return deferred.promise; + }; + + /** + * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over + * very large arrays by yielding to the browser and continuing execution on the + * next tick. + * + * @param Array aArray + * The array being iterated over. + * @param Function aFn + * The function called on each item in the array. If a promise is + * returned by this function, iterating over the array will be paused + * until the respective promise is resolved. + * @returns Promise + * A promise that is resolved once the whole array has been iterated + * over, and all promises returned by the aFn callback are resolved. + */ + exports.yieldingEach = function yieldingEach(aArray, aFn) { + const deferred = promise.defer(); + + let i = 0; + let len = aArray.length; + let outstanding = [deferred.promise]; + + (function loop() { + const start = Date.now(); + + while (i < len) { + // Don't block the main thread for longer than 16 ms at a time. To + // maintain 60fps, you have to render every frame in at least 16ms; we + // aren't including time spent in non-JS here, but this is Good + // Enough(tm). + if (Date.now() - start > 16) { + exports.executeSoon(loop); + return; + } + + try { + outstanding.push(aFn(aArray[i], i++)); + } catch (e) { + deferred.reject(e); + return; + } + } + + deferred.resolve(); + }()); + + return promise.all(outstanding); + }; + + /** + * Like XPCOMUtils.defineLazyGetter, but with a |this| sensitive getter that + * allows the lazy getter to be defined on a prototype and work correctly with + * instances. + * + * @param Object aObject + * The prototype object to define the lazy getter on. + * @param String aKey + * The key to define the lazy getter on. + * @param Function aCallback + * The callback that will be called to determine the value. Will be + * called with the |this| value of the current instance. + */ + exports.defineLazyPrototypeGetter = + function defineLazyPrototypeGetter(aObject, aKey, aCallback) { + Object.defineProperty(aObject, aKey, { + configurable: true, + get: function() { + const value = aCallback.call(this); + + Object.defineProperty(this, aKey, { + configurable: true, + writable: true, + value: value + }); + + return value; + } + }); + }; + + /** + * Safely get the property value from a Debugger.Object for a given key. Walks + * the prototype chain until the property is found. + * + * @param Debugger.Object aObject + * The Debugger.Object to get the value from. + * @param String aKey + * The key to look for. + * @return Any + */ + exports.getProperty = function getProperty(aObj, aKey) { + let root = aObj; + try { + do { + const desc = aObj.getOwnPropertyDescriptor(aKey); + if (desc) { + if ("value" in desc) { + return desc.value; + } + // Call the getter if it's safe. + return exports.hasSafeGetter(desc) ? desc.get.call(root).return : undefined; + } + aObj = aObj.proto; + } while (aObj); + } catch (e) { + // If anything goes wrong report the error and return undefined. + exports.reportException("getProperty", e); + } + return undefined; + }; + + /** + * Determines if a descriptor has a getter which doesn't call into JavaScript. + * + * @param Object aDesc + * The descriptor to check for a safe getter. + * @return Boolean + * Whether a safe getter was found. + */ + exports.hasSafeGetter = function hasSafeGetter(aDesc) { + // Scripted functions that are CCWs will not appear scripted until after + // unwrapping. + try { + let fn = aDesc.get.unwrap(); + return fn && fn.callable && fn.class == "Function" && fn.script === undefined; + } catch (e) { + // Avoid exception 'Object in compartment marked as invisible to Debugger' + return false; + } + }; + + /** + * Check if it is safe to read properties and execute methods from the given JS + * object. Safety is defined as being protected from unintended code execution + * from content scripts (or cross-compartment code). + * + * See bugs 945920 and 946752 for discussion. + * + * @type Object aObj + * The object to check. + * @return Boolean + * True if it is safe to read properties from aObj, or false otherwise. + */ + exports.isSafeJSObject = function isSafeJSObject(aObj) { + // If we are running on a worker thread, Cu is not available. In this case, + // we always return false, just to be on the safe side. + if (isWorker) { + return false; + } + + if (Cu.getGlobalForObject(aObj) == + Cu.getGlobalForObject(exports.isSafeJSObject)) { + return true; // aObj is not a cross-compartment wrapper. + } + + let principal = Cu.getObjectPrincipal(aObj); + if (Services.scriptSecurityManager.isSystemPrincipal(principal)) { + return true; // allow chrome objects + } + + return Cu.isXrayWrapper(aObj); + }; + + exports.dumpn = function dumpn(str) { + if (exports.dumpn.wantLogging) { + console.log("DBG-SERVER: " + str + "\n"); + } + }; + + // We want wantLogging to be writable. The exports object is frozen by the + // loader, so define it on dumpn instead. + exports.dumpn.wantLogging = false; + + /** + * A verbose logger for low-level tracing. + */ + exports.dumpv = function(msg) { + if (exports.dumpv.wantVerbose) { + exports.dumpn(msg); + } + }; + + // We want wantLogging to be writable. The exports object is frozen by the + // loader, so define it on dumpn instead. + exports.dumpv.wantVerbose = false; + + /** + * Utility function for updating an object with the properties of + * other objects. + * + * @param aTarget Object + * The object being updated. + * @param aNewAttrs Object + * The rest params are objects to update aTarget with. You + * can pass as many as you like. + */ + exports.update = function update(aTarget, ...aArgs) { + for (let attrs of aArgs) { + for (let key in attrs) { + let desc = Object.getOwnPropertyDescriptor(attrs, key); + + if (desc) { + Object.defineProperty(aTarget, key, desc); + } + } + } + + return aTarget; + }; + + /** + * Utility function for getting the values from an object as an array + * + * @param aObject Object + * The object to iterate over + */ + exports.values = function values(aObject) { + return Object.keys(aObject).map(k => aObject[k]); + }; + + /** + * Defines a getter on a specified object that will be created upon first use. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter to define on aObject. + * @param aLambda + * A function that returns what the getter should return. This will + * only ever be called once. + */ + exports.defineLazyGetter = function defineLazyGetter(aObject, aName, aLambda) { + Object.defineProperty(aObject, aName, { + get: function() { + delete aObject[aName]; + return aObject[aName] = aLambda.apply(aObject); + }, + configurable: true, + enumerable: true + }); + }; + + // DEPRECATED: use DevToolsUtils.assert(condition, message) instead! + let haveLoggedDeprecationMessage = false; + exports.dbg_assert = function dbg_assert(cond, e) { + if (!haveLoggedDeprecationMessage) { + haveLoggedDeprecationMessage = true; + const deprecationMessage = "DevToolsUtils.dbg_assert is deprecated! Use DevToolsUtils.assert instead!" + + Error().stack; + console.log(deprecationMessage); + if (typeof console === "object" && console && console.warn) { + console.warn(deprecationMessage); + } + } + + if (!cond) { + return e; + } + }; + + const { AppConstants } = __webpack_require__(80); + + /** + * No operation. The empty function. + */ + exports.noop = function() { }; + + function reallyAssert(condition, message) { + if (!condition) { + const err = new Error("Assertion failure: " + message); + exports.reportException("DevToolsUtils.assert", err); + throw err; + } + } + + /** + * DevToolsUtils.assert(condition, message) + * + * @param Boolean condition + * @param String message + * + * Assertions are enabled when any of the following are true: + * - This is a DEBUG_JS_MODULES build + * - This is a DEBUG build + * - DevToolsUtils.testing is set to true + * + * If assertions are enabled, then `condition` is checked and if false-y, the + * assertion failure is logged and then an error is thrown. + * + * If assertions are not enabled, then this function is a no-op. + * + * This is an improvement over `dbg_assert`, which doesn't actually cause any + * fatal behavior, and is therefore much easier to accidentally ignore. + */ + Object.defineProperty(exports, "assert", { + get: () => (AppConstants.DEBUG || AppConstants.DEBUG_JS_MODULES || this.testing) + ? reallyAssert + : exports.noop, + }); + + /** + * Defines a getter on a specified object for a module. The module will not + * be imported until first use. + * + * @param aObject + * The object to define the lazy getter on. + * @param aName + * The name of the getter to define on aObject for the module. + * @param aResource + * The URL used to obtain the module. + * @param aSymbol + * The name of the symbol exported by the module. + * This parameter is optional and defaults to aName. + */ + exports.defineLazyModuleGetter = function defineLazyModuleGetter(aObject, aName, + aResource, + aSymbol) + { + this.defineLazyGetter(aObject, aName, function XPCU_moduleLambda() { + var temp = {}; + Cu.import(aResource, temp); + return temp[aSymbol || aName]; + }); + }; + + const { NetUtil } = __webpack_require__(81); + + const { TextDecoder, OS } = __webpack_require__(82); + + const NetworkHelper = __webpack_require__(83); + + /** + * Performs a request to load the desired URL and returns a promise. + * + * @param aURL String + * The URL we will request. + * @param aOptions Object + * An object with the following optional properties: + * - loadFromCache: if false, will bypass the cache and + * always load fresh from the network (default: true) + * - policy: the nsIContentPolicy type to apply when fetching the URL + * - window: the window to get the loadGroup from + * - charset: the charset to use if the channel doesn't provide one + * @returns Promise that resolves with an object with the following members on + * success: + * - content: the document at that URL, as a string, + * - contentType: the content type of the document + * + * If an error occurs, the promise is rejected with that error. + * + * XXX: It may be better to use nsITraceableChannel to get to the sources + * without relying on caching when we can (not for eval, etc.): + * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/ + */ + function mainThreadFetch(aURL, aOptions = { loadFromCache: true, + policy: Ci.nsIContentPolicy.TYPE_OTHER, + window: null, + charset: null }) { + // Create a channel. + let url = aURL.split(" -> ").pop(); + let channel; + try { + channel = newChannelForURL(url, aOptions); + } catch (ex) { + return promise.reject(ex); + } + + // Set the channel options. + channel.loadFlags = aOptions.loadFromCache + ? channel.LOAD_FROM_CACHE + : channel.LOAD_BYPASS_CACHE; + + if (aOptions.window) { + // Respect private browsing. + channel.loadGroup = aOptions.window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocumentLoader) + .loadGroup; + } + + let deferred = promise.defer(); + let onResponse = (stream, status, request) => { + if (!components.isSuccessCode(status)) { + deferred.reject(new Error(`Failed to fetch ${url}. Code ${status}.`)); + return; + } + + try { + // We cannot use NetUtil to do the charset conversion as if charset + // information is not available and our default guess is wrong the method + // might fail and we lose the stream data. This means we can't fall back + // to using the locale default encoding (bug 1181345). + + // Read and decode the data according to the locale default encoding. + let available = stream.available(); + let source = NetUtil.readInputStreamToString(stream, available); + stream.close(); + + // If the channel or the caller has correct charset information, the + // content will be decoded correctly. If we have to fall back to UTF-8 and + // the guess is wrong, the conversion fails and convertToUnicode returns + // the input unmodified. Essentially we try to decode the data as UTF-8 + // and if that fails, we use the locale specific default encoding. This is + // the best we can do if the source does not provide charset info. + let charset = channel.contentCharset || aOptions.charset || "UTF-8"; + let unicodeSource = NetworkHelper.convertToUnicode(source, charset); + + deferred.resolve({ + content: unicodeSource, + contentType: request.contentType + }); + } catch (ex) { + let uri = request.originalURI; + if (ex.name === "NS_BASE_STREAM_CLOSED" && uri instanceof Ci.nsIFileURL) { + // Empty files cause NS_BASE_STREAM_CLOSED exception. Use OS.File to + // differentiate between empty files and other errors (bug 1170864). + // This can be removed when bug 982654 is fixed. + + uri.QueryInterface(Ci.nsIFileURL); + let result = OS.File.read(uri.file.path).then(bytes => { + // Convert the bytearray to a String. + let decoder = new TextDecoder(); + let content = decoder.decode(bytes); + + // We can't detect the contentType without opening a channel + // and that failed already. This is the best we can do here. + return { + content, + contentType: "text/plain" + }; + }); + + deferred.resolve(result); + } else { + deferred.reject(ex); + } + } + }; + + // Open the channel + try { + NetUtil.asyncFetch(channel, onResponse); + } catch (ex) { + return promise.reject(ex); + } + + return deferred.promise; + } + + /** + * Opens a channel for given URL. Tries a bit harder than NetUtil.newChannel. + * + * @param {String} url - The URL to open a channel for. + * @param {Object} options - The options object passed to @method fetch. + * @return {nsIChannel} - The newly created channel. Throws on failure. + */ + function newChannelForURL(url, { policy }) { + let channelOptions = { + contentPolicyType: policy, + loadUsingSystemPrincipal: true, + uri: url + }; + + try { + return NetUtil.newChannel(channelOptions); + } catch (e) { + // In the xpcshell tests, the script url is the absolute path of the test + // file, which will make a malformed URI error be thrown. Add the file + // scheme to see if it helps. + channelOptions.uri = "file://" + url; + + return NetUtil.newChannel(channelOptions); + } + } + + // Fetch is defined differently depending on whether we are on the main thread + // or a worker thread. + if (typeof WorkerGlobalScope === "undefined") { // i.e. not in a worker + exports.fetch = mainThreadFetch; + } else { + // Services is not available in worker threads, nor is there any other way + // to fetch a URL. We need to enlist the help from the main thread here, by + // issuing an rpc request, to fetch the URL on our behalf. + exports.fetch = function(url, options) { + return rpc("fetch", url, options); + }; + } + + /** + * Returns a promise that is resolved or rejected when all promises have settled + * (resolved or rejected). + * + * This differs from Promise.all, which will reject immediately after the first + * rejection, instead of waiting for the remaining promises to settle. + * + * @param values + * Iterable of promises that may be pending, resolved, or rejected. When + * when all promises have settled (resolved or rejected), the returned + * promise will be resolved or rejected as well. + * + * @return A new promise that is fulfilled when all values have settled + * (resolved or rejected). Its resolution value will be an array of all + * resolved values in the given order, or undefined if values is an + * empty array. The reject reason will be forwarded from the first + * promise in the list of given promises to be rejected. + */ + exports.settleAll = values => { + if (values === null || typeof (values[Symbol.iterator]) != "function") { + throw new Error("settleAll() expects an iterable."); + } + + let deferred = promise.defer(); + + values = Array.isArray(values) ? values : [...values]; + let countdown = values.length; + let resolutionValues = new Array(countdown); + let rejectionValue; + let rejectionOccurred = false; + + if (!countdown) { + deferred.resolve(resolutionValues); + return deferred.promise; + } + + function checkForCompletion() { + if (--countdown > 0) { + return; + } + if (!rejectionOccurred) { + deferred.resolve(resolutionValues); + } else { + deferred.reject(rejectionValue); + } + } + + for (let i = 0; i < values.length; i++) { + let index = i; + let value = values[i]; + let resolver = result => { + resolutionValues[index] = result; + checkForCompletion(); + }; + let rejecter = error => { + if (!rejectionOccurred) { + rejectionValue = error; + rejectionOccurred = true; + } + checkForCompletion(); + }; + + if (value && typeof (value.then) == "function") { + value.then(resolver, rejecter); + } else { + // Given value is not a promise, forward it as a resolution value. + resolver(value); + } + } + + return deferred.promise; + }; + + /** + * When the testing flag is set, various behaviors may be altered from + * production mode, typically to enable easier testing or enhanced debugging. + */ + var testing = false; + Object.defineProperty(exports, "testing", { + get: function() { + return testing; + }, + set: function(state) { + testing = state; + } + }); + + /** + * Open the file at the given path for reading. + * + * @param {String} filePath + * + * @returns Promise + */ + exports.openFileStream = function(filePath) { + return new Promise((resolve, reject) => { + const uri = NetUtil.newURI(new FileUtils.File(filePath)); + NetUtil.asyncFetch( + { uri, loadUsingSystemPrincipal: true }, + (stream, result) => { + if (!components.isSuccessCode(result)) { + reject(new Error(`Could not open "${filePath}": result = ${result}`)); + return; + } + + resolve(stream); + } + ); + }); + }; + + exports.isGenerator = function(fn) { + if (typeof fn !== "function") { + return false; + } + let proto = Object.getPrototypeOf(fn); + if (!proto) { + return false; + } + let ctor = proto.constructor; + if (!ctor) { + return false; + } + return ctor.name == "GeneratorFunction"; + }; + + exports.isPromise = function(p) { + return p && typeof p.then === "function"; + }; + + /** + * Return true if `thing` is a SavedFrame, false otherwise. + */ + exports.isSavedFrame = function(thing) { + return Object.prototype.toString.call(thing) === "[object SavedFrame]"; + }; + + +/***/ }, +/* 79 */ +/***/ function(module, exports) { + + /* + * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/FileUtils.jsm + */ + + +/***/ }, +/* 80 */ +/***/ function(module, exports) { + + /* + * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/AppConstants.jsm + */ + + module.exports = { AppConstants: {} }; + + +/***/ }, +/* 81 */ +/***/ function(module, exports) { + + /* + * A sham for https://dxr.mozilla.org/mozilla-central/source/netwerk/base/NetUtil.jsm + */ + + +/***/ }, +/* 82 */ +/***/ function(module, exports) { + + /* + * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/components/osfile/osfile.jsm + */ + + +/***/ }, +/* 83 */ +/***/ function(module, exports, __webpack_require__) { + + /* vim:set ts=2 sw=2 sts=2 et: */ + /* + * Software License Agreement (BSD License) + * + * Copyright (c) 2007, Parakey Inc. + * All rights reserved. + * + * Redistribution and use of this software 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 Parakey Inc. nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission of Parakey Inc. + * + * 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. + */ + + /* + * Creator: + * Joe Hewitt + * Contributors + * John J. Barton (IBM Almaden) + * Jan Odvarko (Mozilla Corp.) + * Max Stepanov (Aptana Inc.) + * Rob Campbell (Mozilla Corp.) + * Hans Hillen (Paciello Group, Mozilla) + * Curtis Bartley (Mozilla Corp.) + * Mike Collins (IBM Almaden) + * Kevin Decker + * Mike Ratcliffe (Comartis AG) + * Hernan Rodríguez Colmeiro + * Austin Andrews + * Christoph Dorn + * Steven Roussey (AppCenter Inc, Network54) + * Mihai Sucan (Mozilla Corp.) + */ + + "use strict"; + + const {components, Cc, Ci, Cu} = __webpack_require__(71); + const { NetUtil } = __webpack_require__(81); + const DevToolsUtils = __webpack_require__(78); + + // The cache used in the `nsIURL` function. + const gNSURLStore = new Map(); + + /** + * Helper object for networking stuff. + * + * Most of the following functions have been taken from the Firebug source. They + * have been modified to match the Firefox coding rules. + */ + var NetworkHelper = { + /** + * Converts aText with a given aCharset to unicode. + * + * @param string aText + * Text to convert. + * @param string aCharset + * Charset to convert the text to. + * @returns string + * Converted text. + */ + convertToUnicode: function NH_convertToUnicode(aText, aCharset) + { + let conv = Cc("@mozilla.org/intl/scriptableunicodeconverter"). + createInstance(Ci.nsIScriptableUnicodeConverter); + try { + conv.charset = aCharset || "UTF-8"; + return conv.ConvertToUnicode(aText); + } + catch (ex) { + return aText; + } + }, + + /** + * Reads all available bytes from aStream and converts them to aCharset. + * + * @param nsIInputStream aStream + * @param string aCharset + * @returns string + * UTF-16 encoded string based on the content of aStream and aCharset. + */ + readAndConvertFromStream: function NH_readAndConvertFromStream(aStream, aCharset) + { + let text = null; + try { + text = NetUtil.readInputStreamToString(aStream, aStream.available()) + return this.convertToUnicode(text, aCharset); + } + catch (err) { + return text; + } + }, + + /** + * Reads the posted text from aRequest. + * + * @param nsIHttpChannel aRequest + * @param string aCharset + * The content document charset, used when reading the POSTed data. + * @returns string or null + * Returns the posted string if it was possible to read from aRequest + * otherwise null. + */ + readPostTextFromRequest: function NH_readPostTextFromRequest(aRequest, aCharset) + { + if (aRequest instanceof Ci.nsIUploadChannel) { + let iStream = aRequest.uploadStream; + + let isSeekableStream = false; + if (iStream instanceof Ci.nsISeekableStream) { + isSeekableStream = true; + } + + let prevOffset; + if (isSeekableStream) { + prevOffset = iStream.tell(); + iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); + } + + // Read data from the stream. + let text = this.readAndConvertFromStream(iStream, aCharset); + + // Seek locks the file, so seek to the beginning only if necko hasn't + // read it yet, since necko doesn't seek to 0 before reading (at lest + // not till 459384 is fixed). + if (isSeekableStream && prevOffset == 0) { + iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); + } + return text; + } + return null; + }, + + /** + * Reads the posted text from the page's cache. + * + * @param nsIDocShell aDocShell + * @param string aCharset + * @returns string or null + * Returns the posted string if it was possible to read from + * aDocShell otherwise null. + */ + readPostTextFromPage: function NH_readPostTextFromPage(aDocShell, aCharset) + { + let webNav = aDocShell.QueryInterface(Ci.nsIWebNavigation); + return this.readPostTextFromPageViaWebNav(webNav, aCharset); + }, + + /** + * Reads the posted text from the page's cache, given an nsIWebNavigation + * object. + * + * @param nsIWebNavigation aWebNav + * @param string aCharset + * @returns string or null + * Returns the posted string if it was possible to read from + * aWebNav, otherwise null. + */ + readPostTextFromPageViaWebNav: + function NH_readPostTextFromPageViaWebNav(aWebNav, aCharset) + { + if (aWebNav instanceof Ci.nsIWebPageDescriptor) { + let descriptor = aWebNav.currentDescriptor; + + if (descriptor instanceof Ci.nsISHEntry && descriptor.postData && + descriptor instanceof Ci.nsISeekableStream) { + descriptor.seek(NS_SEEK_SET, 0); + + return this.readAndConvertFromStream(descriptor, aCharset); + } + } + return null; + }, + + /** + * Gets the web appId that is associated with aRequest. + * + * @param nsIHttpChannel aRequest + * @returns number|null + * The appId for the given request, if available. + */ + getAppIdForRequest: function NH_getAppIdForRequest(aRequest) + { + try { + return this.getRequestLoadContext(aRequest).appId; + } catch (ex) { + // request loadContent is not always available. + } + return null; + }, + + /** + * Gets the topFrameElement that is associated with aRequest. This + * works in single-process and multiprocess contexts. It may cross + * the content/chrome boundary. + * + * @param nsIHttpChannel aRequest + * @returns nsIDOMElement|null + * The top frame element for the given request. + */ + getTopFrameForRequest: function NH_getTopFrameForRequest(aRequest) + { + try { + return this.getRequestLoadContext(aRequest).topFrameElement; + } catch (ex) { + // request loadContent is not always available. + } + return null; + }, + + /** + * Gets the nsIDOMWindow that is associated with aRequest. + * + * @param nsIHttpChannel aRequest + * @returns nsIDOMWindow or null + */ + getWindowForRequest: function NH_getWindowForRequest(aRequest) + { + try { + return this.getRequestLoadContext(aRequest).associatedWindow; + } catch (ex) { + // TODO: bug 802246 - getWindowForRequest() throws on b2g: there is no + // associatedWindow property. + } + return null; + }, + + /** + * Gets the nsILoadContext that is associated with aRequest. + * + * @param nsIHttpChannel aRequest + * @returns nsILoadContext or null + */ + getRequestLoadContext: function NH_getRequestLoadContext(aRequest) + { + try { + return aRequest.notificationCallbacks.getInterface(Ci.nsILoadContext); + } catch (ex) { } + + try { + return aRequest.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext); + } catch (ex) { } + + return null; + }, + + /** + * Determines whether the request has been made for the top level document. + * + * @param nsIHttpChannel aRequest + * @returns Boolean True if the request represents the top level document. + */ + isTopLevelLoad: function(aRequest) + { + if (aRequest instanceof Ci.nsIChannel) { + let loadInfo = aRequest.loadInfo; + if (loadInfo && loadInfo.parentOuterWindowID == loadInfo.outerWindowID) { + return (aRequest.loadFlags & Ci.nsIChannel.LOAD_DOCUMENT_URI); + } + } + + return false; + }, + + /** + * Loads the content of aUrl from the cache. + * + * @param string aUrl + * URL to load the cached content for. + * @param string aCharset + * Assumed charset of the cached content. Used if there is no charset + * on the channel directly. + * @param function aCallback + * Callback that is called with the loaded cached content if available + * or null if something failed while getting the cached content. + */ + loadFromCache: function NH_loadFromCache(aUrl, aCharset, aCallback) + { + let channel = NetUtil.newChannel({uri: aUrl, loadUsingSystemPrincipal: true}); + + // Ensure that we only read from the cache and not the server. + channel.loadFlags = Ci.nsIRequest.LOAD_FROM_CACHE | + Ci.nsICachingChannel.LOAD_ONLY_FROM_CACHE | + Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; + + NetUtil.asyncFetch( + channel, + (aInputStream, aStatusCode, aRequest) => { + if (!components.isSuccessCode(aStatusCode)) { + aCallback(null); + return; + } + + // Try to get the encoding from the channel. If there is none, then use + // the passed assumed aCharset. + let aChannel = aRequest.QueryInterface(Ci.nsIChannel); + let contentCharset = aChannel.contentCharset || aCharset; + + // Read the content of the stream using contentCharset as encoding. + aCallback(this.readAndConvertFromStream(aInputStream, contentCharset)); + }); + }, + + /** + * Parse a raw Cookie header value. + * + * @param string aHeader + * The raw Cookie header value. + * @return array + * Array holding an object for each cookie. Each object holds the + * following properties: name and value. + */ + parseCookieHeader: function NH_parseCookieHeader(aHeader) + { + let cookies = aHeader.split(";"); + let result = []; + + cookies.forEach(function(aCookie) { + let equal = aCookie.indexOf("="); + let name = aCookie.substr(0, equal); + let value = aCookie.substr(equal + 1); + result.push({name: unescape(name.trim()), + value: unescape(value.trim())}); + }); + + return result; + }, + + /** + * Parse a raw Set-Cookie header value. + * + * @param string aHeader + * The raw Set-Cookie header value. + * @return array + * Array holding an object for each cookie. Each object holds the + * following properties: name, value, secure (boolean), httpOnly + * (boolean), path, domain and expires (ISO date string). + */ + parseSetCookieHeader: function NH_parseSetCookieHeader(aHeader) + { + let rawCookies = aHeader.split(/\r\n|\n|\r/); + let cookies = []; + + rawCookies.forEach(function(aCookie) { + let equal = aCookie.indexOf("="); + let name = unescape(aCookie.substr(0, equal).trim()); + let parts = aCookie.substr(equal + 1).split(";"); + let value = unescape(parts.shift().trim()); + + let cookie = {name: name, value: value}; + + parts.forEach(function(aPart) { + let part = aPart.trim(); + if (part.toLowerCase() == "secure") { + cookie.secure = true; + } + else if (part.toLowerCase() == "httponly") { + cookie.httpOnly = true; + } + else if (part.indexOf("=") > -1) { + let pair = part.split("="); + pair[0] = pair[0].toLowerCase(); + if (pair[0] == "path" || pair[0] == "domain") { + cookie[pair[0]] = pair[1]; + } + else if (pair[0] == "expires") { + try { + pair[1] = pair[1].replace(/-/g, ' '); + cookie.expires = new Date(pair[1]).toISOString(); + } + catch (ex) { } + } + } + }); + + cookies.push(cookie); + }); + + return cookies; + }, + + // This is a list of all the mime category maps jviereck could find in the + // firebug code base. + mimeCategoryMap: { + "text/plain": "txt", + "text/html": "html", + "text/xml": "xml", + "text/xsl": "txt", + "text/xul": "txt", + "text/css": "css", + "text/sgml": "txt", + "text/rtf": "txt", + "text/x-setext": "txt", + "text/richtext": "txt", + "text/javascript": "js", + "text/jscript": "txt", + "text/tab-separated-values": "txt", + "text/rdf": "txt", + "text/xif": "txt", + "text/ecmascript": "js", + "text/vnd.curl": "txt", + "text/x-json": "json", + "text/x-js": "txt", + "text/js": "txt", + "text/vbscript": "txt", + "view-source": "txt", + "view-fragment": "txt", + "application/xml": "xml", + "application/xhtml+xml": "xml", + "application/atom+xml": "xml", + "application/rss+xml": "xml", + "application/vnd.mozilla.maybe.feed": "xml", + "application/vnd.mozilla.xul+xml": "xml", + "application/javascript": "js", + "application/x-javascript": "js", + "application/x-httpd-php": "txt", + "application/rdf+xml": "xml", + "application/ecmascript": "js", + "application/http-index-format": "txt", + "application/json": "json", + "application/x-js": "txt", + "multipart/mixed": "txt", + "multipart/x-mixed-replace": "txt", + "image/svg+xml": "svg", + "application/octet-stream": "bin", + "image/jpeg": "image", + "image/jpg": "image", + "image/gif": "image", + "image/png": "image", + "image/bmp": "image", + "application/x-shockwave-flash": "flash", + "video/x-flv": "flash", + "audio/mpeg3": "media", + "audio/x-mpeg-3": "media", + "video/mpeg": "media", + "video/x-mpeg": "media", + "audio/ogg": "media", + "application/ogg": "media", + "application/x-ogg": "media", + "application/x-midi": "media", + "audio/midi": "media", + "audio/x-mid": "media", + "audio/x-midi": "media", + "music/crescendo": "media", + "audio/wav": "media", + "audio/x-wav": "media", + "text/json": "json", + "application/x-json": "json", + "application/json-rpc": "json", + "application/x-web-app-manifest+json": "json", + "application/manifest+json": "json" + }, + + /** + * Check if the given MIME type is a text-only MIME type. + * + * @param string aMimeType + * @return boolean + */ + isTextMimeType: function NH_isTextMimeType(aMimeType) + { + if (aMimeType.indexOf("text/") == 0) { + return true; + } + + // XML and JSON often come with custom MIME types, so in addition to the + // standard "application/xml" and "application/json", we also look for + // variants like "application/x-bigcorp+xml". For JSON we allow "+json" and + // "-json" as suffixes. + if (/^application\/\w+(?:[\.-]\w+)*(?:\+xml|[-+]json)$/.test(aMimeType)) { + return true; + } + + let category = this.mimeCategoryMap[aMimeType] || null; + switch (category) { + case "txt": + case "js": + case "json": + case "css": + case "html": + case "svg": + case "xml": + return true; + + default: + return false; + } + }, + + /** + * Takes a securityInfo object of nsIRequest, the nsIRequest itself and + * extracts security information from them. + * + * @param object securityInfo + * The securityInfo object of a request. If null channel is assumed + * to be insecure. + * @param object httpActivity + * The httpActivity object for the request with at least members + * { private, hostname }. + * + * @return object + * Returns an object containing following members: + * - state: The security of the connection used to fetch this + * request. Has one of following string values: + * * "insecure": the connection was not secure (only http) + * * "weak": the connection has minor security issues + * * "broken": secure connection failed (e.g. expired cert) + * * "secure": the connection was properly secured. + * If state == broken: + * - errorMessage: full error message from nsITransportSecurityInfo. + * If state == secure: + * - protocolVersion: one of TLSv1, TLSv1.1, TLSv1.2. + * - cipherSuite: the cipher suite used in this connection. + * - cert: information about certificate used in this connection. + * See parseCertificateInfo for the contents. + * - hsts: true if host uses Strict Transport Security, false otherwise + * - hpkp: true if host uses Public Key Pinning, false otherwise + * If state == weak: Same as state == secure and + * - weaknessReasons: list of reasons that cause the request to be + * considered weak. See getReasonsForWeakness. + */ + parseSecurityInfo: function NH_parseSecurityInfo(securityInfo, httpActivity) { + const info = { + state: "insecure", + }; + + // The request did not contain any security info. + if (!securityInfo) { + return info; + } + + /** + * Different scenarios to consider here and how they are handled: + * - request is HTTP, the connection is not secure + * => securityInfo is null + * => state === "insecure" + * + * - request is HTTPS, the connection is secure + * => .securityState has STATE_IS_SECURE flag + * => state === "secure" + * + * - request is HTTPS, the connection has security issues + * => .securityState has STATE_IS_INSECURE flag + * => .errorCode is an NSS error code. + * => state === "broken" + * + * - request is HTTPS, the connection was terminated before the security + * could be validated + * => .securityState has STATE_IS_INSECURE flag + * => .errorCode is NOT an NSS error code. + * => .errorMessage is not available. + * => state === "insecure" + * + * - request is HTTPS but it uses a weak cipher or old protocol, see + * http://hg.mozilla.org/mozilla-central/annotate/def6ed9d1c1a/ + * security/manager/ssl/nsNSSCallbacks.cpp#l1233 + * - request is mixed content (which makes no sense whatsoever) + * => .securityState has STATE_IS_BROKEN flag + * => .errorCode is NOT an NSS error code + * => .errorMessage is not available + * => state === "weak" + */ + + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + securityInfo.QueryInterface(Ci.nsISSLStatusProvider); + + const wpl = Ci.nsIWebProgressListener; + const NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1'] + .getService(Ci.nsINSSErrorsService); + const SSLStatus = securityInfo.SSLStatus; + if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) { + const state = securityInfo.securityState; + + let uri = null; + if (httpActivity.channel && httpActivity.channel.URI) { + uri = httpActivity.channel.URI; + } + if (uri && !uri.schemeIs("https") && !uri.schemeIs("wss")) { + // it is not enough to look at the transport security info - schemes other than + // https and wss are subject to downgrade/etc at the scheme level and should + // always be considered insecure + info.state = "insecure"; + } else if (state & wpl.STATE_IS_SECURE) { + // The connection is secure if the scheme is sufficient + info.state = "secure"; + } else if (state & wpl.STATE_IS_BROKEN) { + // The connection is not secure, there was no error but there's some + // minor security issues. + info.state = "weak"; + info.weaknessReasons = this.getReasonsForWeakness(state); + } else if (state & wpl.STATE_IS_INSECURE) { + // This was most likely an https request that was aborted before + // validation. Return info as info.state = insecure. + return info; + } else { + DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo", + "Security state " + state + " has no known STATE_IS_* flags."); + return info; + } + + // Cipher suite. + info.cipherSuite = SSLStatus.cipherName; + + // Protocol version. + info.protocolVersion = this.formatSecurityProtocol(SSLStatus.protocolVersion); + + // Certificate. + info.cert = this.parseCertificateInfo(SSLStatus.serverCert); + + // HSTS and HPKP if available. + if (httpActivity.hostname) { + const sss = Cc("@mozilla.org/ssservice;1") + .getService(Ci.nsISiteSecurityService); + + + // SiteSecurityService uses different storage if the channel is + // private. Thus we must give isSecureHost correct flags or we + // might get incorrect results. + let flags = (httpActivity.private) ? + Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + + let host = httpActivity.hostname; + + info.hsts = sss.isSecureHost(sss.HEADER_HSTS, host, flags); + info.hpkp = sss.isSecureHost(sss.HEADER_HPKP, host, flags); + } else { + DevToolsUtils.reportException("NetworkHelper.parseSecurityInfo", + "Could not get HSTS/HPKP status as hostname is not available."); + info.hsts = false; + info.hpkp = false; + } + + } else { + // The connection failed. + info.state = "broken"; + info.errorMessage = securityInfo.errorMessage; + } + + return info; + }, + + /** + * Takes an nsIX509Cert and returns an object with certificate information. + * + * @param nsIX509Cert cert + * The certificate to extract the information from. + * @return object + * An object with following format: + * { + * subject: { commonName, organization, organizationalUnit }, + * issuer: { commonName, organization, organizationUnit }, + * validity: { start, end }, + * fingerprint: { sha1, sha256 } + * } + */ + parseCertificateInfo: function NH_parseCertifificateInfo(cert) { + let info = {}; + if (cert) { + info.subject = { + commonName: cert.commonName, + organization: cert.organization, + organizationalUnit: cert.organizationalUnit, + }; + + info.issuer = { + commonName: cert.issuerCommonName, + organization: cert.issuerOrganization, + organizationUnit: cert.issuerOrganizationUnit, + }; + + info.validity = { + start: cert.validity.notBeforeLocalDay, + end: cert.validity.notAfterLocalDay, + }; + + info.fingerprint = { + sha1: cert.sha1Fingerprint, + sha256: cert.sha256Fingerprint, + }; + } else { + DevToolsUtils.reportException("NetworkHelper.parseCertificateInfo", + "Secure connection established without certificate."); + } + + return info; + }, + + /** + * Takes protocolVersion of SSLStatus object and returns human readable + * description. + * + * @param Number version + * One of nsISSLStatus version constants. + * @return string + * One of TLSv1, TLSv1.1, TLSv1.2 if @param version is valid, + * Unknown otherwise. + */ + formatSecurityProtocol: function NH_formatSecurityProtocol(version) { + switch (version) { + case Ci.nsISSLStatus.TLS_VERSION_1: + return "TLSv1"; + case Ci.nsISSLStatus.TLS_VERSION_1_1: + return "TLSv1.1"; + case Ci.nsISSLStatus.TLS_VERSION_1_2: + return "TLSv1.2"; + default: + DevToolsUtils.reportException("NetworkHelper.formatSecurityProtocol", + "protocolVersion " + version + " is unknown."); + return "Unknown"; + } + }, + + /** + * Takes the securityState bitfield and returns reasons for weak connection + * as an array of strings. + * + * @param Number state + * nsITransportSecurityInfo.securityState. + * + * @return Array[String] + * List of weakness reasons. A subset of { cipher } where + * * cipher: The cipher suite is consireded to be weak (RC4). + */ + getReasonsForWeakness: function NH_getReasonsForWeakness(state) { + const wpl = Ci.nsIWebProgressListener; + + // If there's non-fatal security issues the request has STATE_IS_BROKEN + // flag set. See http://hg.mozilla.org/mozilla-central/file/44344099d119 + // /security/manager/ssl/nsNSSCallbacks.cpp#l1233 + let reasons = []; + + if (state & wpl.STATE_IS_BROKEN) { + let isCipher = state & wpl.STATE_USES_WEAK_CRYPTO; + + if (isCipher) { + reasons.push("cipher"); + } + + if (!isCipher) { + DevToolsUtils.reportException("NetworkHelper.getReasonsForWeakness", + "STATE_IS_BROKEN without a known reason. Full state was: " + state); + } + } + + return reasons; + }, + + /** + * Parse a url's query string into its components + * + * @param string aQueryString + * The query part of a url + * @return array + * Array of query params {name, value} + */ + parseQueryString: function(aQueryString) { + // Make sure there's at least one param available. + // Be careful here, params don't necessarily need to have values, so + // no need to verify the existence of a "=". + if (!aQueryString) { + return; + } + + // Turn the params string into an array containing { name: value } tuples. + let paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map(e => { + let param = e.split("="); + return { + name: param[0] ? NetworkHelper.convertToUnicode(unescape(param[0])) : "", + value: param[1] ? NetworkHelper.convertToUnicode(unescape(param[1])) : "" + }}); + + return paramsArray; + }, + + /** + * Helper for getting an nsIURL instance out of a string. + */ + nsIURL: function(aUrl, aStore = gNSURLStore) { + if (aStore.has(aUrl)) { + return aStore.get(aUrl); + } + + let uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL); + aStore.set(aUrl, uri); + return uri; + } + }; + + for (let prop of Object.getOwnPropertyNames(NetworkHelper)) { + exports[prop] = NetworkHelper[prop]; + } + + +/***/ }, +/* 84 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const { Ci, Cc, Cr, CC } = __webpack_require__(71); + const { Services } = __webpack_require__(40); + const { dumpv } = __webpack_require__(78); + const EventEmitter = __webpack_require__(70); + const promise = __webpack_require__(76); + + const IOUtil = Cc("@mozilla.org/io-util;1").getService(Ci.nsIIOUtil); + + const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", + "nsIScriptableInputStream", "init"); + + const BUFFER_SIZE = 0x8000; + + /** + * This helper function (and its companion object) are used by bulk senders and + * receivers to read and write data in and out of other streams. Functions that + * make use of this tool are passed to callers when it is time to read or write + * bulk data. It is highly recommended to use these copier functions instead of + * the stream directly because the copier enforces the agreed upon length. + * Since bulk mode reuses an existing stream, the sender and receiver must write + * and read exactly the agreed upon amount of data, or else the entire transport + * will be left in a invalid state. Additionally, other methods of stream + * copying (such as NetUtil.asyncCopy) close the streams involved, which would + * terminate the debugging transport, and so it is avoided here. + * + * Overall, this *works*, but clearly the optimal solution would be able to just + * use the streams directly. If it were possible to fully implement + * nsIInputStream / nsIOutputStream in JS, wrapper streams could be created to + * enforce the length and avoid closing, and consumers could use familiar stream + * utilities like NetUtil.asyncCopy. + * + * The function takes two async streams and copies a precise number of bytes + * from one to the other. Copying begins immediately, but may complete at some + * future time depending on data size. Use the returned promise to know when + * it's complete. + * + * @param input nsIAsyncInputStream + * The stream to copy from. + * @param output nsIAsyncOutputStream + * The stream to copy to. + * @param length Integer + * The amount of data that needs to be copied. + * @return Promise + * The promise is resolved when copying completes or rejected if any + * (unexpected) errors occur. + */ + function copyStream(input, output, length) { + let copier = new StreamCopier(input, output, length); + return copier.copy(); + } + + function StreamCopier(input, output, length) { + EventEmitter.decorate(this); + this._id = StreamCopier._nextId++; + this.input = input; + // Save off the base output stream, since we know it's async as we've required + this.baseAsyncOutput = output; + if (IOUtil.outputStreamIsBuffered(output)) { + this.output = output; + } else { + this.output = Cc("@mozilla.org/network/buffered-output-stream;1") + .createInstance(Ci.nsIBufferedOutputStream); + this.output.init(output, BUFFER_SIZE); + } + this._length = length; + this._amountLeft = length; + this._deferred = promise.defer(); + + this._copy = this._copy.bind(this); + this._flush = this._flush.bind(this); + this._destroy = this._destroy.bind(this); + + // Copy promise's then method up to this object. + // Allows the copier to offer a promise interface for the simple succeed or + // fail scenarios, but also emit events (due to the EventEmitter) for other + // states, like progress. + this.then = this._deferred.promise.then.bind(this._deferred.promise); + this.then(this._destroy, this._destroy); + + // Stream ready callback starts as |_copy|, but may switch to |_flush| at end + // if flushing would block the output stream. + this._streamReadyCallback = this._copy; + } + StreamCopier._nextId = 0; + + StreamCopier.prototype = { + + copy: function() { + // Dispatch to the next tick so that it's possible to attach a progress + // event listener, even for extremely fast copies (like when testing). + Services.tm.currentThread.dispatch(() => { + try { + this._copy(); + } catch (e) { + this._deferred.reject(e); + } + }, 0); + return this; + }, + + _copy: function() { + let bytesAvailable = this.input.available(); + let amountToCopy = Math.min(bytesAvailable, this._amountLeft); + this._debug("Trying to copy: " + amountToCopy); + + let bytesCopied; + try { + bytesCopied = this.output.writeFrom(this.input, amountToCopy); + } catch (e) { + if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK) { + this._debug("Base stream would block, will retry"); + this._debug("Waiting for output stream"); + this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread); + return; + } else { + throw e; + } + } + + this._amountLeft -= bytesCopied; + this._debug("Copied: " + bytesCopied + + ", Left: " + this._amountLeft); + this._emitProgress(); + + if (this._amountLeft === 0) { + this._debug("Copy done!"); + this._flush(); + return; + } + + this._debug("Waiting for input stream"); + this.input.asyncWait(this, 0, 0, Services.tm.currentThread); + }, + + _emitProgress: function() { + this.emit("progress", { + bytesSent: this._length - this._amountLeft, + totalBytes: this._length + }); + }, + + _flush: function() { + try { + this.output.flush(); + } catch (e) { + if (e.result == Cr.NS_BASE_STREAM_WOULD_BLOCK || + e.result == Cr.NS_ERROR_FAILURE) { + this._debug("Flush would block, will retry"); + this._streamReadyCallback = this._flush; + this._debug("Waiting for output stream"); + this.baseAsyncOutput.asyncWait(this, 0, 0, Services.tm.currentThread); + return; + } else { + throw e; + } + } + this._deferred.resolve(); + }, + + _destroy: function() { + this._destroy = null; + this._copy = null; + this._flush = null; + this.input = null; + this.output = null; + }, + + // nsIInputStreamCallback + onInputStreamReady: function() { + this._streamReadyCallback(); + }, + + // nsIOutputStreamCallback + onOutputStreamReady: function() { + this._streamReadyCallback(); + }, + + _debug: function(msg) { + // Prefix logs with the copier ID, which makes logs much easier to + // understand when several copiers are running simultaneously + dumpv("Copier: " + this._id + " " + msg); + } + + }; + + /** + * Read from a stream, one byte at a time, up to the next |delimiter| + * character, but stopping if we've read |count| without finding it. Reading + * also terminates early if there are less than |count| bytes available on the + * stream. In that case, we only read as many bytes as the stream currently has + * to offer. + * TODO: This implementation could be removed if bug 984651 is fixed, which + * provides a native version of the same idea. + * @param stream nsIInputStream + * The input stream to read from. + * @param delimiter string + * The character we're trying to find. + * @param count integer + * The max number of characters to read while searching. + * @return string + * The data collected. If the delimiter was found, this string will + * end with it. + */ + function delimitedRead(stream, delimiter, count) { + dumpv("Starting delimited read for " + delimiter + " up to " + + count + " bytes"); + + let scriptableStream; + if (stream.readBytes) { + scriptableStream = stream; + } else { + scriptableStream = new ScriptableInputStream(stream); + } + + let data = ""; + + // Don't exceed what's available on the stream + count = Math.min(count, stream.available()); + + if (count <= 0) { + return data; + } + + let char; + while (char !== delimiter && count > 0) { + char = scriptableStream.readBytes(1); + count--; + data += char; + } + + return data; + } + + module.exports = { + copyStream: copyStream, + delimitedRead: delimitedRead + }; + + +/***/ }, +/* 85 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + /** + * Packets contain read / write functionality for the different packet types + * supported by the debugging protocol, so that a transport can focus on + * delivery and queue management without worrying too much about the specific + * packet types. + * + * They are intended to be "one use only", so a new packet should be + * instantiated for each incoming or outgoing packet. + * + * A complete Packet type should expose at least the following: + * * read(stream, scriptableStream) + * Called when the input stream has data to read + * * write(stream) + * Called when the output stream is ready to write + * * get done() + * Returns true once the packet is done being read / written + * * destroy() + * Called to clean up at the end of use + */ + + const { Cc, Ci, Cu } = __webpack_require__(71); + const DevToolsUtils = __webpack_require__(78); + const { dumpn, dumpv } = DevToolsUtils; + const StreamUtils = __webpack_require__(84); + const promise = __webpack_require__(76); + + /*DevToolsUtils.defineLazyGetter(this, "unicodeConverter", () => { + const unicodeConverter = Cc("@mozilla.org/intl/scriptableunicodeconverter") + .createInstance(Ci.nsIScriptableUnicodeConverter); + unicodeConverter.charset = "UTF-8"; + return unicodeConverter; + });*/ + const utf8 = __webpack_require__(86); + + // The transport's previous check ensured the header length did not exceed 20 + // characters. Here, we opt for the somewhat smaller, but still large limit of + // 1 TiB. + const PACKET_LENGTH_MAX = Math.pow(2, 40); + + /** + * A generic Packet processing object (extended by two subtypes below). + */ + function Packet(transport) { + this._transport = transport; + this._length = 0; + } + + /** + * Attempt to initialize a new Packet based on the incoming packet header we've + * received so far. We try each of the types in succession, trying JSON packets + * first since they are much more common. + * @param header string + * The packet header string to attempt parsing. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + * @return Packet + * The parsed packet of the matching type, or null if no types matched. + */ + Packet.fromHeader = function(header, transport) { + return JSONPacket.fromHeader(header, transport) || + BulkPacket.fromHeader(header, transport); + }; + + Packet.prototype = { + + get length() { + return this._length; + }, + + set length(length) { + if (length > PACKET_LENGTH_MAX) { + throw Error("Packet length " + length + " exceeds the max length of " + + PACKET_LENGTH_MAX); + } + this._length = length; + }, + + destroy: function() { + this._transport = null; + } + + }; + + exports.Packet = Packet; + + /** + * With a JSON packet (the typical packet type sent via the transport), data is + * transferred as a JSON packet serialized into a string, with the string length + * prepended to the packet, followed by a colon ([length]:[packet]). The + * contents of the JSON packet are specified in the Remote Debugging Protocol + * specification. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + */ + function JSONPacket(transport) { + Packet.call(this, transport); + this._data = ""; + this._done = false; + } + + /** + * Attempt to initialize a new JSONPacket based on the incoming packet header + * we've received so far. + * @param header string + * The packet header string to attempt parsing. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + * @return JSONPacket + * The parsed packet, or null if it's not a match. + */ + JSONPacket.fromHeader = function(header, transport) { + let match = this.HEADER_PATTERN.exec(header); + + if (!match) { + return null; + } + + dumpv("Header matches JSON packet"); + let packet = new JSONPacket(transport); + packet.length = +match[1]; + return packet; + }; + + JSONPacket.HEADER_PATTERN = /^(\d+):$/; + + JSONPacket.prototype = Object.create(Packet.prototype); + + Object.defineProperty(JSONPacket.prototype, "object", { + /** + * Gets the object (not the serialized string) being read or written. + */ + get: function() { return this._object; }, + + /** + * Sets the object to be sent when write() is called. + */ + set: function(object) { + this._object = object; + let data = JSON.stringify(object); + this._data = data; + this.length = this._data.length; + } + }); + + JSONPacket.prototype.read = function(stream, scriptableStream) { + dumpv("Reading JSON packet"); + + // Read in more packet data. + this._readData(stream, scriptableStream); + + if (!this.done) { + // Don't have a complete packet yet. + return; + } + + let json = this._data; + try { + json = utf8.decode(json); + this._object = JSON.parse(json); + } catch(e) { + let msg = "Error parsing incoming packet: " + json + " (" + e + + " - " + e.stack + ")"; + if (console.error) { + console.error(msg); + } + dumpn(msg); + return; + } + + this._transport._onJSONObjectReady(this._object); + } + + JSONPacket.prototype._readData = function(stream, scriptableStream) { + if (!scriptableStream) { + scriptableStream = stream; + } + if (dumpv.wantVerbose) { + dumpv("Reading JSON data: _l: " + this.length + " dL: " + + this._data.length + " sA: " + stream.available()); + } + let bytesToRead = Math.min(this.length - this._data.length, + stream.available()); + this._data += scriptableStream.readBytes(bytesToRead); + this._done = this._data.length === this.length; + } + + JSONPacket.prototype.write = function(stream) { + dumpv("Writing JSON packet"); + + if (this._outgoing === undefined) { + // Format the serialized packet to a buffer + this._outgoing = this.length + ":" + this._data; + } + + let written = stream.write(this._outgoing, this._outgoing.length); + this._outgoing = this._outgoing.slice(written); + this._done = !this._outgoing.length; + } + + Object.defineProperty(JSONPacket.prototype, "done", { + get: function() { return this._done; } + }); + + JSONPacket.prototype.toString = function() { + return JSON.stringify(this._object, null, 2); + } + + exports.JSONPacket = JSONPacket; + + /** + * With a bulk packet, data is transferred by temporarily handing over the + * transport's input or output stream to the application layer for writing data + * directly. This can be much faster for large data sets, and avoids various + * stages of copies and data duplication inherent in the JSON packet type. The + * bulk packet looks like: + * + * bulk [actor] [type] [length]:[data] + * + * The interpretation of the data portion depends on the kind of actor and the + * packet's type. See the Remote Debugging Protocol Stream Transport spec for + * more details. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + */ + function BulkPacket(transport) { + Packet.call(this, transport); + this._done = false; + this._readyForWriting = promise.defer(); + } + + /** + * Attempt to initialize a new BulkPacket based on the incoming packet header + * we've received so far. + * @param header string + * The packet header string to attempt parsing. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + * @return BulkPacket + * The parsed packet, or null if it's not a match. + */ + BulkPacket.fromHeader = function(header, transport) { + let match = this.HEADER_PATTERN.exec(header); + + if (!match) { + return null; + } + + dumpv("Header matches bulk packet"); + let packet = new BulkPacket(transport); + packet.header = { + actor: match[1], + type: match[2], + length: +match[3] + }; + return packet; + }; + + BulkPacket.HEADER_PATTERN = /^bulk ([^: ]+) ([^: ]+) (\d+):$/; + + BulkPacket.prototype = Object.create(Packet.prototype); + + BulkPacket.prototype.read = function(stream) { + dumpv("Reading bulk packet, handing off input stream"); + + // Temporarily pause monitoring of the input stream + this._transport.pauseIncoming(); + + let deferred = promise.defer(); + + this._transport._onBulkReadReady({ + actor: this.actor, + type: this.type, + length: this.length, + copyTo: (output) => { + dumpv("CT length: " + this.length); + let copying = StreamUtils.copyStream(stream, output, this.length); + deferred.resolve(copying); + return copying; + }, + stream: stream, + done: deferred + }); + + // Await the result of reading from the stream + deferred.promise.then(() => { + dumpv("onReadDone called, ending bulk mode"); + this._done = true; + this._transport.resumeIncoming(); + }, this._transport.close); + + // Ensure this is only done once + this.read = () => { + throw new Error("Tried to read() a BulkPacket's stream multiple times."); + }; + } + + BulkPacket.prototype.write = function(stream) { + dumpv("Writing bulk packet"); + + if (this._outgoingHeader === undefined) { + dumpv("Serializing bulk packet header"); + // Format the serialized packet header to a buffer + this._outgoingHeader = "bulk " + this.actor + " " + this.type + " " + + this.length + ":"; + } + + // Write the header, or whatever's left of it to write. + if (this._outgoingHeader.length) { + dumpv("Writing bulk packet header"); + let written = stream.write(this._outgoingHeader, + this._outgoingHeader.length); + this._outgoingHeader = this._outgoingHeader.slice(written); + return; + } + + dumpv("Handing off output stream"); + + // Temporarily pause the monitoring of the output stream + this._transport.pauseOutgoing(); + + let deferred = promise.defer(); + + this._readyForWriting.resolve({ + copyFrom: (input) => { + dumpv("CF length: " + this.length); + let copying = StreamUtils.copyStream(input, stream, this.length); + deferred.resolve(copying); + return copying; + }, + stream: stream, + done: deferred + }); + + // Await the result of writing to the stream + deferred.promise.then(() => { + dumpv("onWriteDone called, ending bulk mode"); + this._done = true; + this._transport.resumeOutgoing(); + }, this._transport.close); + + // Ensure this is only done once + this.write = () => { + throw new Error("Tried to write() a BulkPacket's stream multiple times."); + }; + } + + Object.defineProperty(BulkPacket.prototype, "streamReadyForWriting", { + get: function() { + return this._readyForWriting.promise; + } + }); + + Object.defineProperty(BulkPacket.prototype, "header", { + get: function() { + return { + actor: this.actor, + type: this.type, + length: this.length + }; + }, + + set: function(header) { + this.actor = header.actor; + this.type = header.type; + this.length = header.length; + }, + }); + + Object.defineProperty(BulkPacket.prototype, "done", { + get: function() { return this._done; }, + }); + + + BulkPacket.prototype.toString = function() { + return "Bulk: " + JSON.stringify(this.header, null, 2); + } + + exports.BulkPacket = BulkPacket; + + /** + * RawPacket is used to test the transport's error handling of malformed + * packets, by writing data directly onto the stream. + * @param transport DebuggerTransport + * The transport instance that will own the packet. + * @param data string + * The raw string to send out onto the stream. + */ + function RawPacket(transport, data) { + Packet.call(this, transport); + this._data = data; + this.length = data.length; + this._done = false; + } + + RawPacket.prototype = Object.create(Packet.prototype); + + RawPacket.prototype.read = function(stream) { + // This hasn't yet been needed for testing. + throw Error("Not implmented."); + } + + RawPacket.prototype.write = function(stream) { + let written = stream.write(this._data, this._data.length); + this._data = this._data.slice(written); + this._done = !this._data.length; + } + + Object.defineProperty(RawPacket.prototype, "done", { + get: function() { return this._done; } + }); + + exports.RawPacket = RawPacket; + + +/***/ }, +/* 86 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/utf8js v2.0.0 by @mathias */ + ;(function(root) { + + // Detect free variables `exports` + var freeExports = typeof exports == 'object' && exports; + + // Detect free variable `module` + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + + // Detect free variable `global`, from Node.js or Browserified code, + // and use it as `root` + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + + // Taken from https://mths.be/punycode + function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + var value; + var extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + // Taken from https://mths.be/punycode + function ucs2encode(array) { + var length = array.length; + var index = -1; + var value; + var output = ''; + while (++index < length) { + value = array[index]; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + } + return output; + } + + function checkScalarValue(codePoint) { + if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { + throw Error( + 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + + ' is not a scalar value' + ); + } + } + /*--------------------------------------------------------------------------*/ + + function createByte(codePoint, shift) { + return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); + } + + function encodeCodePoint(codePoint) { + if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence + symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); + } + else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence + checkScalarValue(codePoint); + symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); + symbol += createByte(codePoint, 6); + } + else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence + symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); + symbol += createByte(codePoint, 12); + symbol += createByte(codePoint, 6); + } + symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); + return symbol; + } + + function utf8encode(string) { + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint); + } + return byteString; + } + + /*--------------------------------------------------------------------------*/ + + function readContinuationByte() { + if (byteIndex >= byteCount) { + throw Error('Invalid byte index'); + } + + var continuationByte = byteArray[byteIndex] & 0xFF; + byteIndex++; + + if ((continuationByte & 0xC0) == 0x80) { + return continuationByte & 0x3F; + } + + // If we end up here, it’s not a continuation byte + throw Error('Invalid continuation byte'); + } + + function decodeSymbol() { + var byte1; + var byte2; + var byte3; + var byte4; + var codePoint; + + if (byteIndex > byteCount) { + throw Error('Invalid byte index'); + } + + if (byteIndex == byteCount) { + return false; + } + + // Read first byte + byte1 = byteArray[byteIndex] & 0xFF; + byteIndex++; + + // 1-byte sequence (no continuation bytes) + if ((byte1 & 0x80) == 0) { + return byte1; + } + + // 2-byte sequence + if ((byte1 & 0xE0) == 0xC0) { + var byte2 = readContinuationByte(); + codePoint = ((byte1 & 0x1F) << 6) | byte2; + if (codePoint >= 0x80) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 3-byte sequence (may include unpaired surrogates) + if ((byte1 & 0xF0) == 0xE0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; + if (codePoint >= 0x0800) { + checkScalarValue(codePoint); + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 4-byte sequence + if ((byte1 & 0xF8) == 0xF0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | + (byte3 << 0x06) | byte4; + if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { + return codePoint; + } + } + + throw Error('Invalid UTF-8 detected'); + } + + var byteArray; + var byteCount; + var byteIndex; + function utf8decode(byteString) { + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol()) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + + /*--------------------------------------------------------------------------*/ + + var utf8 = { + 'version': '2.0.0', + 'encode': utf8encode, + 'decode': utf8decode + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + true + ) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return utf8; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = utf8; + } else { // in Narwhal or RingoJS v0.7.0- + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + for (var key in utf8) { + hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); + } + } + } else { // in Rhino or a web browser + root.utf8 = utf8; + } + + }(this)); + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(87)(module), (function() { return this; }()))) + +/***/ }, +/* 87 */ +/***/ function(module, exports) { + + module.exports = function(module) { + if(!module.webpackPolyfill) { + module.deprecate = function() {}; + module.paths = []; + // module.parent = undefined by default + module.children = []; + module.webpackPolyfill = 1; + } + return module; + } + + +/***/ }, +/* 88 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/utf8js v2.0.0 by @mathias */ + ;(function(root) { + + // Detect free variables `exports` + var freeExports = typeof exports == 'object' && exports; + + // Detect free variable `module` + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + + // Detect free variable `global`, from Node.js or Browserified code, + // and use it as `root` + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } + + /*--------------------------------------------------------------------------*/ + + var stringFromCharCode = String.fromCharCode; + + // Taken from https://mths.be/punycode + function ucs2decode(string) { + var output = []; + var counter = 0; + var length = string.length; + var value; + var extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + // Taken from https://mths.be/punycode + function ucs2encode(array) { + var length = array.length; + var index = -1; + var value; + var output = ''; + while (++index < length) { + value = array[index]; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + } + return output; + } + + function checkScalarValue(codePoint) { + if (codePoint >= 0xD800 && codePoint <= 0xDFFF) { + throw Error( + 'Lone surrogate U+' + codePoint.toString(16).toUpperCase() + + ' is not a scalar value' + ); + } + } + /*--------------------------------------------------------------------------*/ + + function createByte(codePoint, shift) { + return stringFromCharCode(((codePoint >> shift) & 0x3F) | 0x80); + } + + function encodeCodePoint(codePoint) { + if ((codePoint & 0xFFFFFF80) == 0) { // 1-byte sequence + return stringFromCharCode(codePoint); + } + var symbol = ''; + if ((codePoint & 0xFFFFF800) == 0) { // 2-byte sequence + symbol = stringFromCharCode(((codePoint >> 6) & 0x1F) | 0xC0); + } + else if ((codePoint & 0xFFFF0000) == 0) { // 3-byte sequence + checkScalarValue(codePoint); + symbol = stringFromCharCode(((codePoint >> 12) & 0x0F) | 0xE0); + symbol += createByte(codePoint, 6); + } + else if ((codePoint & 0xFFE00000) == 0) { // 4-byte sequence + symbol = stringFromCharCode(((codePoint >> 18) & 0x07) | 0xF0); + symbol += createByte(codePoint, 12); + symbol += createByte(codePoint, 6); + } + symbol += stringFromCharCode((codePoint & 0x3F) | 0x80); + return symbol; + } + + function utf8encode(string) { + var codePoints = ucs2decode(string); + var length = codePoints.length; + var index = -1; + var codePoint; + var byteString = ''; + while (++index < length) { + codePoint = codePoints[index]; + byteString += encodeCodePoint(codePoint); + } + return byteString; + } + + /*--------------------------------------------------------------------------*/ + + function readContinuationByte() { + if (byteIndex >= byteCount) { + throw Error('Invalid byte index'); + } + + var continuationByte = byteArray[byteIndex] & 0xFF; + byteIndex++; + + if ((continuationByte & 0xC0) == 0x80) { + return continuationByte & 0x3F; + } + + // If we end up here, it’s not a continuation byte + throw Error('Invalid continuation byte'); + } + + function decodeSymbol() { + var byte1; + var byte2; + var byte3; + var byte4; + var codePoint; + + if (byteIndex > byteCount) { + throw Error('Invalid byte index'); + } + + if (byteIndex == byteCount) { + return false; + } + + // Read first byte + byte1 = byteArray[byteIndex] & 0xFF; + byteIndex++; + + // 1-byte sequence (no continuation bytes) + if ((byte1 & 0x80) == 0) { + return byte1; + } + + // 2-byte sequence + if ((byte1 & 0xE0) == 0xC0) { + var byte2 = readContinuationByte(); + codePoint = ((byte1 & 0x1F) << 6) | byte2; + if (codePoint >= 0x80) { + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 3-byte sequence (may include unpaired surrogates) + if ((byte1 & 0xF0) == 0xE0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3; + if (codePoint >= 0x0800) { + checkScalarValue(codePoint); + return codePoint; + } else { + throw Error('Invalid continuation byte'); + } + } + + // 4-byte sequence + if ((byte1 & 0xF8) == 0xF0) { + byte2 = readContinuationByte(); + byte3 = readContinuationByte(); + byte4 = readContinuationByte(); + codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | + (byte3 << 0x06) | byte4; + if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) { + return codePoint; + } + } + + throw Error('Invalid UTF-8 detected'); + } + + var byteArray; + var byteCount; + var byteIndex; + function utf8decode(byteString) { + byteArray = ucs2decode(byteString); + byteCount = byteArray.length; + byteIndex = 0; + var codePoints = []; + var tmp; + while ((tmp = decodeSymbol()) !== false) { + codePoints.push(tmp); + } + return ucs2encode(codePoints); + } + + /*--------------------------------------------------------------------------*/ + + var utf8 = { + 'version': '2.0.0', + 'encode': utf8encode, + 'decode': utf8decode + }; + + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + true + ) { + !(__WEBPACK_AMD_DEFINE_RESULT__ = function() { + return utf8; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = utf8; + } else { // in Narwhal or RingoJS v0.7.0- + var object = {}; + var hasOwnProperty = object.hasOwnProperty; + for (var key in utf8) { + hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]); + } + } + } else { // in Rhino or a web browser + root.utf8 = utf8; + } + + }(this)); + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(87)(module), (function() { return this; }()))) + +/***/ }, +/* 89 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const { Ci, Cu, components } = __webpack_require__(71); + const { Services } = __webpack_require__(40); + const DevToolsUtils = __webpack_require__(78); + + // WARNING I swapped the sync one for the async one here + // const promise = require("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise; + const promise = __webpack_require__(76); + + const events = __webpack_require__(90); + const { WebConsoleClient } = __webpack_require__(92); + /* const { DebuggerSocket } = require("../shared/security/socket");*/ + /* const Authentication = require("../shared/security/auth");*/ + + const noop = () => {}; + + /** + * TODO: Get rid of this API in favor of EventTarget (bug 1042642) + * + * Add simple event notification to a prototype object. Any object that has + * some use for event notifications or the observer pattern in general can be + * augmented with the necessary facilities by passing its prototype to this + * function. + * + * @param aProto object + * The prototype object that will be modified. + */ + function eventSource(aProto) { + /** + * Add a listener to the event source for a given event. + * + * @param aName string + * The event to listen for. + * @param aListener function + * Called when the event is fired. If the same listener + * is added more than once, it will be called once per + * addListener call. + */ + aProto.addListener = function(aName, aListener) { + if (typeof aListener != "function") { + throw TypeError("Listeners must be functions."); + } + + if (!this._listeners) { + this._listeners = {}; + } + + this._getListeners(aName).push(aListener); + }; + + /** + * Add a listener to the event source for a given event. The + * listener will be removed after it is called for the first time. + * + * @param aName string + * The event to listen for. + * @param aListener function + * Called when the event is fired. + */ + aProto.addOneTimeListener = function(aName, aListener) { + let l = (...args) => { + this.removeListener(aName, l); + aListener.apply(null, args); + }; + this.addListener(aName, l); + }; + + /** + * Remove a listener from the event source previously added with + * addListener(). + * + * @param aName string + * The event name used during addListener to add the listener. + * @param aListener function + * The callback to remove. If addListener was called multiple + * times, all instances will be removed. + */ + aProto.removeListener = function(aName, aListener) { + if (!this._listeners || (aListener && !this._listeners[aName])) { + return; + } + + if (!aListener) { + this._listeners[aName] = []; + } + else { + this._listeners[aName] = + this._listeners[aName].filter(function(l) { return l != aListener; }); + } + }; + + /** + * Returns the listeners for the specified event name. If none are defined it + * initializes an empty list and returns that. + * + * @param aName string + * The event name. + */ + aProto._getListeners = function(aName) { + if (aName in this._listeners) { + return this._listeners[aName]; + } + this._listeners[aName] = []; + return this._listeners[aName]; + }; + + /** + * Notify listeners of an event. + * + * @param aName string + * The event to fire. + * @param arguments + * All arguments will be passed along to the listeners, + * including the name argument. + */ + aProto.emit = function() { + if (!this._listeners) { + return; + } + + let name = arguments[0]; + let listeners = this._getListeners(name).slice(0); + + for (let listener of listeners) { + try { + listener.apply(null, arguments); + } catch (e) { + // Prevent a bad listener from interfering with the others. + DevToolsUtils.reportException("notify event '" + name + "'", e); + } + } + }; + } + + /** + * Set of protocol messages that affect thread state, and the + * state the actor is in after each message. + */ + const ThreadStateTypes = { + "paused": "paused", + "resumed": "attached", + "detached": "detached" + }; + + /** + * Set of protocol messages that are sent by the server without a prior request + * by the client. + */ + const UnsolicitedNotifications = { + "consoleAPICall": "consoleAPICall", + "eventNotification": "eventNotification", + "fileActivity": "fileActivity", + "lastPrivateContextExited": "lastPrivateContextExited", + "logMessage": "logMessage", + "networkEvent": "networkEvent", + "networkEventUpdate": "networkEventUpdate", + "newGlobal": "newGlobal", + "newScript": "newScript", + "tabDetached": "tabDetached", + "tabListChanged": "tabListChanged", + "reflowActivity": "reflowActivity", + "addonListChanged": "addonListChanged", + "workerListChanged": "workerListChanged", + "serviceWorkerRegistrationListChanged": "serviceWorkerRegistrationList", + "tabNavigated": "tabNavigated", + "frameUpdate": "frameUpdate", + "pageError": "pageError", + "documentLoad": "documentLoad", + "enteredFrame": "enteredFrame", + "exitedFrame": "exitedFrame", + "appOpen": "appOpen", + "appClose": "appClose", + "appInstall": "appInstall", + "appUninstall": "appUninstall", + "evaluationResult": "evaluationResult", + "newSource": "newSource", + "updatedSource": "updatedSource", + }; + + /** + * Set of pause types that are sent by the server and not as an immediate + * response to a client request. + */ + const UnsolicitedPauses = { + "resumeLimit": "resumeLimit", + "debuggerStatement": "debuggerStatement", + "breakpoint": "breakpoint", + "DOMEvent": "DOMEvent", + "watchpoint": "watchpoint", + "exception": "exception" + }; + + /** + * Creates a client for the remote debugging protocol server. This client + * provides the means to communicate with the server and exchange the messages + * required by the protocol in a traditional JavaScript API. + */ + const DebuggerClient = exports.DebuggerClient = function(aTransport) + { + this._transport = aTransport; + this._transport.hooks = this; + + // Map actor ID to client instance for each actor type. + this._clients = new Map(); + + this._pendingRequests = new Map(); + this._activeRequests = new Map(); + this._eventsEnabled = true; + + this.traits = {}; + + this.request = this.request.bind(this); + this.localTransport = this._transport.onOutputStreamReady === undefined; + + /* + * As the first thing on the connection, expect a greeting packet from + * the connection's root actor. + */ + this.mainRoot = null; + this.expectReply("root", (aPacket) => { + this.mainRoot = new RootClient(this, aPacket); + this.emit("connected", aPacket.applicationType, aPacket.traits); + }); + }; + + /** + * A declarative helper for defining methods that send requests to the server. + * + * @param aPacketSkeleton + * The form of the packet to send. Can specify fields to be filled from + * the parameters by using the |args| function. + * @param telemetry + * The unique suffix of the telemetry histogram id. + * @param before + * The function to call before sending the packet. Is passed the packet, + * and the return value is used as the new packet. The |this| context is + * the instance of the client object we are defining a method for. + * @param after + * The function to call after the response is received. It is passed the + * response, and the return value is considered the new response that + * will be passed to the callback. The |this| context is the instance of + * the client object we are defining a method for. + * @return Request + * The `Request` object that is a Promise object and resolves once + * we receive the response. (See request method for more details) + */ + DebuggerClient.requester = function(aPacketSkeleton, config = {}) { + let { telemetry, before, after } = config; + return DevToolsUtils.makeInfallible(function(...args) { + let histogram, startTime; + if (telemetry) { + let transportType = this._transport.onOutputStreamReady === undefined + ? "LOCAL_" + : "REMOTE_"; + let histogramId = "DEVTOOLS_DEBUGGER_RDP_" + + transportType + telemetry + "_MS"; + histogram = Services.telemetry.getHistogramById(histogramId); + startTime = +new Date(); + } + let outgoingPacket = { + to: aPacketSkeleton.to || this.actor + }; + + let maxPosition = -1; + for (let k of Object.keys(aPacketSkeleton)) { + if (aPacketSkeleton[k] instanceof DebuggerClient.Argument) { + let { position } = aPacketSkeleton[k]; + outgoingPacket[k] = aPacketSkeleton[k].getArgument(args); + maxPosition = Math.max(position, maxPosition); + } else { + outgoingPacket[k] = aPacketSkeleton[k]; + } + } + + if (before) { + outgoingPacket = before.call(this, outgoingPacket); + } + + return this.request(outgoingPacket, DevToolsUtils.makeInfallible((aResponse) => { + if (after) { + let { from } = aResponse; + aResponse = after.call(this, aResponse); + if (!aResponse.from) { + aResponse.from = from; + } + } + + // The callback is always the last parameter. + let thisCallback = args[maxPosition + 1]; + if (thisCallback) { + thisCallback(aResponse); + } + + if (histogram) { + histogram.add(+new Date() - startTime); + } + }, "DebuggerClient.requester request callback")); + }, "DebuggerClient.requester"); + }; + + function args(aPos) { + return new DebuggerClient.Argument(aPos); + } + + DebuggerClient.Argument = function(aPosition) { + this.position = aPosition; + }; + + DebuggerClient.Argument.prototype.getArgument = function(aParams) { + if (!(this.position in aParams)) { + throw new Error("Bad index into params: " + this.position); + } + return aParams[this.position]; + }; + + // Expose these to save callers the trouble of importing DebuggerSocket + DebuggerClient.socketConnect = function(options) { + // Defined here instead of just copying the function to allow lazy-load + return DebuggerSocket.connect(options); + }; + DevToolsUtils.defineLazyGetter(DebuggerClient, "Authenticators", () => { + return Authentication.Authenticators; + }); + DevToolsUtils.defineLazyGetter(DebuggerClient, "AuthenticationResult", () => { + return Authentication.AuthenticationResult; + }); + + DebuggerClient.prototype = { + /** + * Connect to the server and start exchanging protocol messages. + * + * @param aOnConnected function + * If specified, will be called when the greeting packet is + * received from the debugging server. + * + * @return Promise + * Resolves once connected with an array whose first element + * is the application type, by default "browser", and the second + * element is the traits object (help figure out the features + * and behaviors of the server we connect to. See RootActor). + */ + connect: function(aOnConnected) { + return Promise.race([ + new Promise((resolve, reject) => { + this.emit("connect"); + + // Also emit the event on the |DebuggerClient| object (not on the instance), + // so it's possible to track all instances. + events.emit(DebuggerClient, "connect", this); + + this.addOneTimeListener("connected", (aName, aApplicationType, aTraits) => { + this.traits = aTraits; + if (aOnConnected) { + aOnConnected(aApplicationType, aTraits); + } + resolve([aApplicationType, aTraits]); + }); + + this._transport.ready(); + }), + new Promise((resolve, reject) => { + setTimeout(() => reject(new Error("Connect timeout error")), 6000); + }) + ]); + }, + + /** + * Shut down communication with the debugging server. + * + * @param aOnClosed function + * If specified, will be called when the debugging connection + * has been closed. + */ + close: function(aOnClosed) { + // Disable detach event notifications, because event handlers will be in a + // cleared scope by the time they run. + this._eventsEnabled = false; + + let cleanup = () => { + this._transport.close(); + this._transport = null; + }; + + // If the connection is already closed, + // there is no need to detach client + // as we won't be able to send any message. + if (this._closed) { + cleanup(); + if (aOnClosed) { + aOnClosed(); + } + return; + } + + if (aOnClosed) { + this.addOneTimeListener("closed", function(aEvent) { + aOnClosed(); + }); + } + + // Call each client's `detach` method by calling + // lastly registered ones first to give a chance + // to detach child clients first. + let clients = [...this._clients.values()]; + this._clients.clear(); + const detachClients = () => { + let client = clients.pop(); + if (!client) { + // All clients detached. + cleanup(); + return; + } + if (client.detach) { + client.detach(detachClients); + return; + } + detachClients(); + }; + detachClients(); + }, + + /* + * This function exists only to preserve DebuggerClient's interface; + * new code should say 'client.mainRoot.listTabs()'. + */ + listTabs: function(aOnResponse) { return this.mainRoot.listTabs(aOnResponse); }, + + /* + * This function exists only to preserve DebuggerClient's interface; + * new code should say 'client.mainRoot.listAddons()'. + */ + listAddons: function(aOnResponse) { return this.mainRoot.listAddons(aOnResponse); }, + + getTab: function(aFilter) { return this.mainRoot.getTab(aFilter); }, + + /** + * Attach to a tab actor. + * + * @param string aTabActor + * The actor ID for the tab to attach. + * @param function aOnResponse + * Called with the response packet and a TabClient + * (which will be undefined on error). + */ + attachTab: function(aTabActor, aOnResponse = noop) { + if (this._clients.has(aTabActor)) { + let cachedTab = this._clients.get(aTabActor); + let cachedResponse = { + cacheDisabled: cachedTab.cacheDisabled, + javascriptEnabled: cachedTab.javascriptEnabled, + traits: cachedTab.traits, + }; + DevToolsUtils.executeSoon(() => aOnResponse(cachedResponse, cachedTab)); + return promise.resolve([cachedResponse, cachedTab]); + } + + let packet = { + to: aTabActor, + type: "attach" + }; + return this.request(packet).then(aResponse => { + let tabClient; + if (!aResponse.error) { + tabClient = new TabClient(this, aResponse); + this.registerClient(tabClient); + } + aOnResponse(aResponse, tabClient); + return [aResponse, tabClient]; + }); + }, + + attachWorker: function DC_attachWorker(aWorkerActor, aOnResponse = noop) { + let workerClient = this._clients.get(aWorkerActor); + if (workerClient !== undefined) { + let response = { + from: workerClient.actor, + type: "attached", + url: workerClient.url + }; + DevToolsUtils.executeSoon(() => aOnResponse(response, workerClient)); + return promise.resolve([response, workerClient]); + } + + return this.request({ to: aWorkerActor, type: "attach" }).then(aResponse => { + if (aResponse.error) { + aOnResponse(aResponse, null); + return [aResponse, null]; + } + + let workerClient = new WorkerClient(this, aResponse); + this.registerClient(workerClient); + aOnResponse(aResponse, workerClient); + return [aResponse, workerClient]; + }); + }, + + /** + * Attach to an addon actor. + * + * @param string aAddonActor + * The actor ID for the addon to attach. + * @param function aOnResponse + * Called with the response packet and a AddonClient + * (which will be undefined on error). + */ + attachAddon: function DC_attachAddon(aAddonActor, aOnResponse = noop) { + let packet = { + to: aAddonActor, + type: "attach" + }; + return this.request(packet).then(aResponse => { + let addonClient; + if (!aResponse.error) { + addonClient = new AddonClient(this, aAddonActor); + this.registerClient(addonClient); + this.activeAddon = addonClient; + } + aOnResponse(aResponse, addonClient); + return [aResponse, addonClient]; + }); + }, + + /** + * Attach to a Web Console actor. + * + * @param string aConsoleActor + * The ID for the console actor to attach to. + * @param array aListeners + * The console listeners you want to start. + * @param function aOnResponse + * Called with the response packet and a WebConsoleClient + * instance (which will be undefined on error). + */ + attachConsole: + function(aConsoleActor, aListeners, aOnResponse = noop) { + let packet = { + to: aConsoleActor, + type: "startListeners", + listeners: aListeners, + }; + + return this.request(packet).then(aResponse => { + let consoleClient; + if (!aResponse.error) { + if (this._clients.has(aConsoleActor)) { + consoleClient = this._clients.get(aConsoleActor); + } else { + consoleClient = new WebConsoleClient(this, aResponse); + this.registerClient(consoleClient); + } + } + aOnResponse(aResponse, consoleClient); + return [aResponse, consoleClient]; + }); + }, + + /** + * Attach to a global-scoped thread actor for chrome debugging. + * + * @param string aThreadActor + * The actor ID for the thread to attach. + * @param function aOnResponse + * Called with the response packet and a ThreadClient + * (which will be undefined on error). + * @param object aOptions + * Configuration options. + * - useSourceMaps: whether to use source maps or not. + */ + attachThread: function(aThreadActor, aOnResponse = noop, aOptions = {}) { + if (this._clients.has(aThreadActor)) { + let client = this._clients.get(aThreadActor); + DevToolsUtils.executeSoon(() => aOnResponse({}, client)); + return promise.resolve([{}, client]); + } + + let packet = { + to: aThreadActor, + type: "attach", + options: aOptions + }; + return this.request(packet).then(aResponse => { + if (!aResponse.error) { + var threadClient = new ThreadClient(this, aThreadActor); + this.registerClient(threadClient); + } + aOnResponse(aResponse, threadClient); + return [aResponse, threadClient]; + }); + }, + + /** + * Attach to a trace actor. + * + * @param string aTraceActor + * The actor ID for the tracer to attach. + * @param function aOnResponse + * Called with the response packet and a TraceClient + * (which will be undefined on error). + */ + attachTracer: function(aTraceActor, aOnResponse = noop) { + if (this._clients.has(aTraceActor)) { + let client = this._clients.get(aTraceActor); + DevToolsUtils.executeSoon(() => aOnResponse({}, client)); + return promise.resolve([{}, client]); + } + + let packet = { + to: aTraceActor, + type: "attach" + }; + return this.request(packet).then(aResponse => { + if (!aResponse.error) { + var traceClient = new TraceClient(this, aTraceActor); + this.registerClient(traceClient); + } + aOnResponse(aResponse, traceClient); + return [aResponse, traceClient]; + }); + }, + + /** + * Fetch the ChromeActor for the main process or ChildProcessActor for a + * a given child process ID. + * + * @param number aId + * The ID for the process to attach (returned by `listProcesses`). + * Connected to the main process if omitted, or is 0. + */ + getProcess: function(aId) { + let packet = { + to: "root", + type: "getProcess" + }; + if (typeof (aId) == "number") { + packet.id = aId; + } + return this.request(packet); + }, + + /** + * Release an object actor. + * + * @param string aActor + * The actor ID to send the request to. + * @param aOnResponse function + * If specified, will be called with the response packet when + * debugging server responds. + */ + release: DebuggerClient.requester({ + to: args(0), + type: "release" + }, { + telemetry: "RELEASE" + }), + + /** + * Send a request to the debugging server. + * + * @param aRequest object + * A JSON packet to send to the debugging server. + * @param aOnResponse function + * If specified, will be called with the JSON response packet when + * debugging server responds. + * @return Request + * This object emits a number of events to allow you to respond to + * different parts of the request lifecycle. + * It is also a Promise object, with a `then` method, that is resolved + * whenever a JSON or a Bulk response is received; and is rejected + * if the response is an error. + * Note: This return value can be ignored if you are using JSON alone, + * because the callback provided in |aOnResponse| will be bound to the + * "json-reply" event automatically. + * + * Events emitted: + * * json-reply: The server replied with a JSON packet, which is + * passed as event data. + * * bulk-reply: The server replied with bulk data, which you can read + * using the event data object containing: + * * actor: Name of actor that received the packet + * * type: Name of actor's method that was called on receipt + * * length: Size of the data to be read + * * stream: This input stream should only be used directly if you + * can ensure that you will read exactly |length| bytes + * and will not close the stream when reading is complete + * * done: If you use the stream directly (instead of |copyTo| + * below), you must signal completion by resolving / + * rejecting this deferred. If it's rejected, the + * transport will be closed. If an Error is supplied as a + * rejection value, it will be logged via |dumpn|. If you + * do use |copyTo|, resolving is taken care of for you + * when copying completes. + * * copyTo: A helper function for getting your data out of the + * stream that meets the stream handling requirements + * above, and has the following signature: + * @param output nsIAsyncOutputStream + * The stream to copy to. + * @return Promise + * The promise is resolved when copying completes or + * rejected if any (unexpected) errors occur. + * This object also emits "progress" events for each chunk + * that is copied. See stream-utils.js. + */ + request: function(aRequest, aOnResponse) { + if (!this.mainRoot) { + throw Error("Have not yet received a hello packet from the server."); + } + let type = aRequest.type || ""; + if (!aRequest.to) { + throw Error("'" + type + "' request packet has no destination."); + } + if (this._closed) { + let msg = "'" + type + "' request packet to " + + "'" + aRequest.to + "' " + + "can't be sent as the connection is closed."; + let resp = { error: "connectionClosed", message: msg }; + if (aOnResponse) { + aOnResponse(resp); + } + return promise.reject(resp); + } + + let request = new Request(aRequest); + request.format = "json"; + request.stack = components.stack; + if (aOnResponse) { + request.on("json-reply", aOnResponse); + } + + this._sendOrQueueRequest(request); + + // Implement a Promise like API on the returned object + // that resolves/rejects on request response + let deferred = promise.defer(); + function listenerJson(resp) { + request.off("json-reply", listenerJson); + request.off("bulk-reply", listenerBulk); + if (resp.error) { + deferred.reject(resp); + } else { + deferred.resolve(resp); + } + } + function listenerBulk(resp) { + request.off("json-reply", listenerJson); + request.off("bulk-reply", listenerBulk); + deferred.resolve(resp); + } + request.on("json-reply", listenerJson); + request.on("bulk-reply", listenerBulk); + request.then = deferred.promise.then.bind(deferred.promise); + + return request; + }, + + /** + * Transmit streaming data via a bulk request. + * + * This method initiates the bulk send process by queuing up the header data. + * The caller receives eventual access to a stream for writing. + * + * Since this opens up more options for how the server might respond (it could + * send back either JSON or bulk data), and the returned Request object emits + * events for different stages of the request process that you may want to + * react to. + * + * @param request Object + * This is modeled after the format of JSON packets above, but does not + * actually contain the data, but is instead just a routing header: + * * actor: Name of actor that will receive the packet + * * type: Name of actor's method that should be called on receipt + * * length: Size of the data to be sent + * @return Request + * This object emits a number of events to allow you to respond to + * different parts of the request lifecycle. + * + * Events emitted: + * * bulk-send-ready: Ready to send bulk data to the server, using the + * event data object containing: + * * stream: This output stream should only be used directly if + * you can ensure that you will write exactly |length| + * bytes and will not close the stream when writing is + * complete + * * done: If you use the stream directly (instead of |copyFrom| + * below), you must signal completion by resolving / + * rejecting this deferred. If it's rejected, the + * transport will be closed. If an Error is supplied as + * a rejection value, it will be logged via |dumpn|. If + * you do use |copyFrom|, resolving is taken care of for + * you when copying completes. + * * copyFrom: A helper function for getting your data onto the + * stream that meets the stream handling requirements + * above, and has the following signature: + * @param input nsIAsyncInputStream + * The stream to copy from. + * @return Promise + * The promise is resolved when copying completes or + * rejected if any (unexpected) errors occur. + * This object also emits "progress" events for each chunk + * that is copied. See stream-utils.js. + * * json-reply: The server replied with a JSON packet, which is + * passed as event data. + * * bulk-reply: The server replied with bulk data, which you can read + * using the event data object containing: + * * actor: Name of actor that received the packet + * * type: Name of actor's method that was called on receipt + * * length: Size of the data to be read + * * stream: This input stream should only be used directly if you + * can ensure that you will read exactly |length| bytes + * and will not close the stream when reading is complete + * * done: If you use the stream directly (instead of |copyTo| + * below), you must signal completion by resolving / + * rejecting this deferred. If it's rejected, the + * transport will be closed. If an Error is supplied as a + * rejection value, it will be logged via |dumpn|. If you + * do use |copyTo|, resolving is taken care of for you + * when copying completes. + * * copyTo: A helper function for getting your data out of the + * stream that meets the stream handling requirements + * above, and has the following signature: + * @param output nsIAsyncOutputStream + * The stream to copy to. + * @return Promise + * The promise is resolved when copying completes or + * rejected if any (unexpected) errors occur. + * This object also emits "progress" events for each chunk + * that is copied. See stream-utils.js. + */ + startBulkRequest: function(request) { + if (!this.traits.bulk) { + throw Error("Server doesn't support bulk transfers"); + } + if (!this.mainRoot) { + throw Error("Have not yet received a hello packet from the server."); + } + if (!request.type) { + throw Error("Bulk packet is missing the required 'type' field."); + } + if (!request.actor) { + throw Error("'" + request.type + "' bulk packet has no destination."); + } + if (!request.length) { + throw Error("'" + request.type + "' bulk packet has no length."); + } + + request = new Request(request); + request.format = "bulk"; + + this._sendOrQueueRequest(request); + + return request; + }, + + /** + * If a new request can be sent immediately, do so. Otherwise, queue it. + */ + _sendOrQueueRequest(request) { + let actor = request.actor; + if (!this._activeRequests.has(actor)) { + this._sendRequest(request); + } else { + this._queueRequest(request); + } + }, + + /** + * Send a request. + * @throws Error if there is already an active request in flight for the same + * actor. + */ + _sendRequest(request) { + let actor = request.actor; + this.expectReply(actor, request); + + if (request.format === "json") { + this._transport.send(request.request); + return false; + } + + this._transport.startBulkSend(request.request).then((...args) => { + request.emit("bulk-send-ready", ...args); + }); + }, + + /** + * Queue a request to be sent later. Queues are only drained when an in + * flight request to a given actor completes. + */ + _queueRequest(request) { + let actor = request.actor; + let queue = this._pendingRequests.get(actor) || []; + queue.push(request); + this._pendingRequests.set(actor, queue); + }, + + /** + * Attempt the next request to a given actor (if any). + */ + _attemptNextRequest(actor) { + if (this._activeRequests.has(actor)) { + return; + } + let queue = this._pendingRequests.get(actor); + if (!queue) { + return; + } + let request = queue.shift(); + if (queue.length === 0) { + this._pendingRequests.delete(actor); + } + this._sendRequest(request); + }, + + /** + * Arrange to hand the next reply from |aActor| to the handler bound to + * |aRequest|. + * + * DebuggerClient.prototype.request / startBulkRequest usually takes care of + * establishing the handler for a given request, but in rare cases (well, + * greetings from new root actors, is the only case at the moment) we must be + * prepared for a "reply" that doesn't correspond to any request we sent. + */ + expectReply: function(aActor, aRequest) { + if (this._activeRequests.has(aActor)) { + throw Error("clashing handlers for next reply from " + uneval(aActor)); + } + + // If a handler is passed directly (as it is with the handler for the root + // actor greeting), create a dummy request to bind this to. + if (typeof aRequest === "function") { + let handler = aRequest; + aRequest = new Request(); + aRequest.on("json-reply", handler); + } + + this._activeRequests.set(aActor, aRequest); + }, + + // Transport hooks. + + /** + * Called by DebuggerTransport to dispatch incoming packets as appropriate. + * + * @param aPacket object + * The incoming packet. + */ + onPacket: function(aPacket) { + if (!aPacket.from) { + DevToolsUtils.reportException( + "onPacket", + new Error("Server did not specify an actor, dropping packet: " + + JSON.stringify(aPacket))); + return; + } + + // If we have a registered Front for this actor, let it handle the packet + // and skip all the rest of this unpleasantness. + let front = this.getActor(aPacket.from); + if (front) { + front.onPacket(aPacket); + return; + } + + if (this._clients.has(aPacket.from) && aPacket.type) { + let client = this._clients.get(aPacket.from); + let type = aPacket.type; + if (client.events.indexOf(type) != -1) { + client.emit(type, aPacket); + // we ignore the rest, as the client is expected to handle this packet. + return; + } + } + + let activeRequest; + // See if we have a handler function waiting for a reply from this + // actor. (Don't count unsolicited notifications or pauses as + // replies.) + if (this._activeRequests.has(aPacket.from) && + !(aPacket.type in UnsolicitedNotifications) && + !(aPacket.type == ThreadStateTypes.paused && + aPacket.why.type in UnsolicitedPauses)) { + activeRequest = this._activeRequests.get(aPacket.from); + this._activeRequests.delete(aPacket.from); + } + + // If there is a subsequent request for the same actor, hand it off to the + // transport. Delivery of packets on the other end is always async, even + // in the local transport case. + this._attemptNextRequest(aPacket.from); + + // Packets that indicate thread state changes get special treatment. + if (aPacket.type in ThreadStateTypes && + this._clients.has(aPacket.from) && + typeof this._clients.get(aPacket.from)._onThreadState == "function") { + this._clients.get(aPacket.from)._onThreadState(aPacket); + } + + // TODO: Bug 1151156 - Remove once Gecko 40 is on b2g-stable. + if (!this.traits.noNeedToFakeResumptionOnNavigation) { + // On navigation the server resumes, so the client must resume as well. + // We achieve that by generating a fake resumption packet that triggers + // the client's thread state change listeners. + if (aPacket.type == UnsolicitedNotifications.tabNavigated && + this._clients.has(aPacket.from) && + this._clients.get(aPacket.from).thread) { + let thread = this._clients.get(aPacket.from).thread; + let resumption = { from: thread._actor, type: "resumed" }; + thread._onThreadState(resumption); + } + } + + // Only try to notify listeners on events, not responses to requests + // that lack a packet type. + if (aPacket.type) { + this.emit(aPacket.type, aPacket); + } + + if (activeRequest) { + let emitReply = () => activeRequest.emit("json-reply", aPacket); + if (activeRequest.stack) { + Cu.callFunctionWithAsyncStack(emitReply, activeRequest.stack, + "DevTools RDP"); + } else { + emitReply(); + } + } + }, + + /** + * Called by the DebuggerTransport to dispatch incoming bulk packets as + * appropriate. + * + * @param packet object + * The incoming packet, which contains: + * * actor: Name of actor that will receive the packet + * * type: Name of actor's method that should be called on receipt + * * length: Size of the data to be read + * * stream: This input stream should only be used directly if you can + * ensure that you will read exactly |length| bytes and will + * not close the stream when reading is complete + * * done: If you use the stream directly (instead of |copyTo| + * below), you must signal completion by resolving / + * rejecting this deferred. If it's rejected, the transport + * will be closed. If an Error is supplied as a rejection + * value, it will be logged via |dumpn|. If you do use + * |copyTo|, resolving is taken care of for you when copying + * completes. + * * copyTo: A helper function for getting your data out of the stream + * that meets the stream handling requirements above, and has + * the following signature: + * @param output nsIAsyncOutputStream + * The stream to copy to. + * @return Promise + * The promise is resolved when copying completes or rejected + * if any (unexpected) errors occur. + * This object also emits "progress" events for each chunk + * that is copied. See stream-utils.js. + */ + onBulkPacket: function(packet) { + let { actor, type, length } = packet; + + if (!actor) { + DevToolsUtils.reportException( + "onBulkPacket", + new Error("Server did not specify an actor, dropping bulk packet: " + + JSON.stringify(packet))); + return; + } + + // See if we have a handler function waiting for a reply from this + // actor. + if (!this._activeRequests.has(actor)) { + return; + } + + let activeRequest = this._activeRequests.get(actor); + this._activeRequests.delete(actor); + + // If there is a subsequent request for the same actor, hand it off to the + // transport. Delivery of packets on the other end is always async, even + // in the local transport case. + this._attemptNextRequest(actor); + + activeRequest.emit("bulk-reply", packet); + }, + + /** + * Called by DebuggerTransport when the underlying stream is closed. + * + * @param aStatus nsresult + * The status code that corresponds to the reason for closing + * the stream. + */ + onClosed: function(aStatus) { + this._closed = true; + this.emit("closed"); + + // Reject all pending and active requests + let reject = function(type, request, actor) { + // Server can send packets on its own and client only pass a callback + // to expectReply, so that there is no request object. + let msg; + if (request.request) { + msg = "'" + request.request.type + "' " + type + " request packet" + + " to '" + actor + "' " + + "can't be sent as the connection just closed."; + } else { + msg = "server side packet from '" + actor + "' can't be received " + + "as the connection just closed."; + } + let packet = { error: "connectionClosed", message: msg }; + request.emit("json-reply", packet); + }; + + let pendingRequests = new Map(this._pendingRequests); + this._pendingRequests.clear(); + pendingRequests.forEach((list, actor) => { + list.forEach(request => reject("pending", request, actor)); + }); + let activeRequests = new Map(this._activeRequests); + this._activeRequests.clear(); + activeRequests.forEach(reject.bind(null, "active")); + + // The |_pools| array on the client-side currently is used only by + // protocol.js to store active fronts, mirroring the actor pools found in + // the server. So, read all usages of "pool" as "protocol.js front". + // + // In the normal case where we shutdown cleanly, the toolbox tells each tool + // to close, and they each call |destroy| on any fronts they were using. + // When |destroy| or |cleanup| is called on a protocol.js front, it also + // removes itself from the |_pools| array. Once the toolbox has shutdown, + // the connection is closed, and we reach here. All fronts (should have + // been) |destroy|ed, so |_pools| should empty. + // + // If the connection instead aborts unexpectedly, we may end up here with + // all fronts used during the life of the connection. So, we call |cleanup| + // on them clear their state, reject pending requests, and remove themselves + // from |_pools|. This saves the toolbox from hanging indefinitely, in case + // it waits for some server response before shutdown that will now never + // arrive. + for (let pool of this._pools) { + pool.cleanup(); + } + }, + + registerClient: function(client) { + let actorID = client.actor; + if (!actorID) { + throw new Error("DebuggerServer.registerClient expects " + + "a client instance with an `actor` attribute."); + } + if (!Array.isArray(client.events)) { + throw new Error("DebuggerServer.registerClient expects " + + "a client instance with an `events` attribute " + + "that is an array."); + } + if (client.events.length > 0 && typeof (client.emit) != "function") { + throw new Error("DebuggerServer.registerClient expects " + + "a client instance with non-empty `events` array to" + + "have an `emit` function."); + } + if (this._clients.has(actorID)) { + throw new Error("DebuggerServer.registerClient already registered " + + "a client for this actor."); + } + this._clients.set(actorID, client); + }, + + unregisterClient: function(client) { + let actorID = client.actor; + if (!actorID) { + throw new Error("DebuggerServer.unregisterClient expects " + + "a Client instance with a `actor` attribute."); + } + this._clients.delete(actorID); + }, + + /** + * Actor lifetime management, echos the server's actor pools. + */ + __pools: null, + get _pools() { + if (this.__pools) { + return this.__pools; + } + this.__pools = new Set(); + return this.__pools; + }, + + addActorPool: function(pool) { + this._pools.add(pool); + }, + removeActorPool: function(pool) { + this._pools.delete(pool); + }, + getActor: function(actorID) { + let pool = this.poolFor(actorID); + return pool ? pool.get(actorID) : null; + }, + + poolFor: function(actorID) { + for (let pool of this._pools) { + if (pool.has(actorID)) return pool; + } + return null; + }, + + /** + * Currently attached addon. + */ + activeAddon: null + }; + + eventSource(DebuggerClient.prototype); + + function Request(request) { + this.request = request; + } + + Request.prototype = { + + on: function(type, listener) { + events.on(this, type, listener); + }, + + off: function(type, listener) { + events.off(this, type, listener); + }, + + once: function(type, listener) { + events.once(this, type, listener); + }, + + emit: function(type, ...args) { + events.emit(this, type, ...args); + }, + + get actor() { return this.request.to || this.request.actor; } + + }; + + /** + * Creates a tab client for the remote debugging protocol server. This client + * is a front to the tab actor created in the server side, hiding the protocol + * details in a traditional JavaScript API. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aForm object + * The protocol form for this tab. + */ + function TabClient(aClient, aForm) { + this.client = aClient; + this._actor = aForm.from; + this._threadActor = aForm.threadActor; + this.javascriptEnabled = aForm.javascriptEnabled; + this.cacheDisabled = aForm.cacheDisabled; + this.thread = null; + this.request = this.client.request; + this.traits = aForm.traits || {}; + this.events = ["workerListChanged"]; + } + + TabClient.prototype = { + get actor() { return this._actor; }, + get _transport() { return this.client._transport; }, + + /** + * Attach to a thread actor. + * + * @param object aOptions + * Configuration options. + * - useSourceMaps: whether to use source maps or not. + * @param function aOnResponse + * Called with the response packet and a ThreadClient + * (which will be undefined on error). + */ + attachThread: function(aOptions = {}, aOnResponse = noop) { + if (this.thread) { + DevToolsUtils.executeSoon(() => aOnResponse({}, this.thread)); + return promise.resolve([{}, this.thread]); + } + + let packet = { + to: this._threadActor, + type: "attach", + options: aOptions + }; + return this.request(packet).then(aResponse => { + if (!aResponse.error) { + this.thread = new ThreadClient(this, this._threadActor); + this.client.registerClient(this.thread); + } + aOnResponse(aResponse, this.thread); + return [aResponse, this.thread]; + }); + }, + + /** + * Detach the client from the tab actor. + * + * @param function aOnResponse + * Called with the response packet. + */ + detach: DebuggerClient.requester({ + type: "detach" + }, { + before: function(aPacket) { + if (this.thread) { + this.thread.detach(); + } + return aPacket; + }, + after: function(aResponse) { + this.client.unregisterClient(this); + return aResponse; + }, + telemetry: "TABDETACH" + }), + + /** + * Bring the window to the front. + */ + focus: DebuggerClient.requester({ + type: "focus" + }, {}), + + /** + * Reload the page in this tab. + * + * @param [optional] object options + * An object with a `force` property indicating whether or not + * this reload should skip the cache + */ + reload: function(options = { force: false }) { + return this._reload(options); + }, + _reload: DebuggerClient.requester({ + type: "reload", + options: args(0) + }, { + telemetry: "RELOAD" + }), + + /** + * Navigate to another URL. + * + * @param string url + * The URL to navigate to. + */ + navigateTo: DebuggerClient.requester({ + type: "navigateTo", + url: args(0) + }, { + telemetry: "NAVIGATETO" + }), + + /** + * Reconfigure the tab actor. + * + * @param object aOptions + * A dictionary object of the new options to use in the tab actor. + * @param function aOnResponse + * Called with the response packet. + */ + reconfigure: DebuggerClient.requester({ + type: "reconfigure", + options: args(0) + }, { + telemetry: "RECONFIGURETAB" + }), + + listWorkers: DebuggerClient.requester({ + type: "listWorkers" + }, { + telemetry: "LISTWORKERS" + }), + + attachWorker: function(aWorkerActor, aOnResponse) { + this.client.attachWorker(aWorkerActor, aOnResponse); + }, + + /** + * Resolve a location ({ url, line, column }) to its current + * source mapping location. + * + * @param {String} arg[0].url + * @param {Number} arg[0].line + * @param {Number?} arg[0].column + */ + resolveLocation: DebuggerClient.requester({ + type: "resolveLocation", + location: args(0) + }), + }; + + eventSource(TabClient.prototype); + + function WorkerClient(aClient, aForm) { + this.client = aClient; + this._actor = aForm.from; + this._isClosed = false; + this._url = aForm.url; + + this._onClose = this._onClose.bind(this); + + this.addListener("close", this._onClose); + + this.traits = {}; + } + + WorkerClient.prototype = { + get _transport() { + return this.client._transport; + }, + + get request() { + return this.client.request; + }, + + get actor() { + return this._actor; + }, + + get url() { + return this._url; + }, + + get isClosed() { + return this._isClosed; + }, + + detach: DebuggerClient.requester({ type: "detach" }, { + after: function(aResponse) { + if (this.thread) { + this.client.unregisterClient(this.thread); + } + this.client.unregisterClient(this); + return aResponse; + }, + + telemetry: "WORKERDETACH" + }), + + attachThread: function(aOptions = {}, aOnResponse = noop) { + if (this.thread) { + let response = [{ + type: "connected", + threadActor: this.thread._actor, + consoleActor: this.consoleActor, + }, this.thread]; + DevToolsUtils.executeSoon(() => aOnResponse(response)); + return response; + } + + // The connect call on server doesn't attach the thread as of version 44. + return this.request({ + to: this._actor, + type: "connect", + options: aOptions, + }).then(connectReponse => { + if (connectReponse.error) { + aOnResponse(connectReponse, null); + return [connectResponse, null]; + } + + return this.request({ + to: connectReponse.threadActor, + type: "attach", + options: aOptions + }).then(attachResponse => { + if (attachResponse.error) { + aOnResponse(attachResponse, null); + } + + this.thread = new ThreadClient(this, connectReponse.threadActor); + this.consoleActor = connectReponse.consoleActor; + this.client.registerClient(this.thread); + + aOnResponse(connectReponse, this.thread); + return [connectResponse, this.thread]; + }); + }); + }, + + _onClose: function() { + this.removeListener("close", this._onClose); + + if (this.thread) { + this.client.unregisterClient(this.thread); + } + this.client.unregisterClient(this); + this._isClosed = true; + }, + + reconfigure: function() { + return Promise.resolve(); + }, + + events: ["close"] + }; + + eventSource(WorkerClient.prototype); + + function AddonClient(aClient, aActor) { + this._client = aClient; + this._actor = aActor; + this.request = this._client.request; + this.events = []; + } + + AddonClient.prototype = { + get actor() { return this._actor; }, + get _transport() { return this._client._transport; }, + + /** + * Detach the client from the addon actor. + * + * @param function aOnResponse + * Called with the response packet. + */ + detach: DebuggerClient.requester({ + type: "detach" + }, { + after: function(aResponse) { + if (this._client.activeAddon === this) { + this._client.activeAddon = null; + } + this._client.unregisterClient(this); + return aResponse; + }, + telemetry: "ADDONDETACH" + }) + }; + + /** + * A RootClient object represents a root actor on the server. Each + * DebuggerClient keeps a RootClient instance representing the root actor + * for the initial connection; DebuggerClient's 'listTabs' and + * 'listChildProcesses' methods forward to that root actor. + * + * @param aClient object + * The client connection to which this actor belongs. + * @param aGreeting string + * The greeting packet from the root actor we're to represent. + * + * Properties of a RootClient instance: + * + * @property actor string + * The name of this child's root actor. + * @property applicationType string + * The application type, as given in the root actor's greeting packet. + * @property traits object + * The traits object, as given in the root actor's greeting packet. + */ + function RootClient(aClient, aGreeting) { + this._client = aClient; + this.actor = aGreeting.from; + this.applicationType = aGreeting.applicationType; + this.traits = aGreeting.traits; + } + exports.RootClient = RootClient; + + RootClient.prototype = { + constructor: RootClient, + + /** + * List the open tabs. + * + * @param function aOnResponse + * Called with the response packet. + */ + listTabs: DebuggerClient.requester({ type: "listTabs" }, + { telemetry: "LISTTABS" }), + + /** + * List the installed addons. + * + * @param function aOnResponse + * Called with the response packet. + */ + listAddons: DebuggerClient.requester({ type: "listAddons" }, + { telemetry: "LISTADDONS" }), + + /** + * List the registered workers. + * + * @param function aOnResponse + * Called with the response packet. + */ + listWorkers: DebuggerClient.requester({ type: "listWorkers" }, + { telemetry: "LISTWORKERS" }), + + /** + * List the registered service workers. + * + * @param function aOnResponse + * Called with the response packet. + */ + listServiceWorkerRegistrations: DebuggerClient.requester({ type: "listServiceWorkerRegistrations" }, + { telemetry: "LISTSERVICEWORKERREGISTRATIONS" }), + + /** + * List the running processes. + * + * @param function aOnResponse + * Called with the response packet. + */ + listProcesses: DebuggerClient.requester({ type: "listProcesses" }, + { telemetry: "LISTPROCESSES" }), + + /** + * Fetch the TabActor for the currently selected tab, or for a specific + * tab given as first parameter. + * + * @param [optional] object aFilter + * A dictionary object with following optional attributes: + * - outerWindowID: used to match tabs in parent process + * - tabId: used to match tabs in child processes + * - tab: a reference to xul:tab element + * If nothing is specified, returns the actor for the currently + * selected tab. + */ + getTab: function(aFilter) { + let packet = { + to: this.actor, + type: "getTab" + }; + + if (aFilter) { + if (typeof (aFilter.outerWindowID) == "number") { + packet.outerWindowID = aFilter.outerWindowID; + } else if (typeof (aFilter.tabId) == "number") { + packet.tabId = aFilter.tabId; + } else if ("tab" in aFilter) { + let browser = aFilter.tab.linkedBrowser; + if (browser.frameLoader.tabParent) { + // Tabs in child process + packet.tabId = browser.frameLoader.tabParent.tabId; + } else { + // Tabs in parent process + let windowUtils = browser.contentWindow + .QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils); + packet.outerWindowID = windowUtils.outerWindowID; + } + } else { + // Throw if a filter object have been passed but without + // any clearly idenfified filter. + throw new Error("Unsupported argument given to getTab request"); + } + } + + return this.request(packet); + }, + + /** + * Description of protocol's actors and methods. + * + * @param function aOnResponse + * Called with the response packet. + */ + protocolDescription: DebuggerClient.requester({ type: "protocolDescription" }, + { telemetry: "PROTOCOLDESCRIPTION" }), + + /* + * Methods constructed by DebuggerClient.requester require these forwards + * on their 'this'. + */ + get _transport() { return this._client._transport; }, + get request() { return this._client.request; } + }; + + /** + * Creates a thread client for the remote debugging protocol server. This client + * is a front to the thread actor created in the server side, hiding the + * protocol details in a traditional JavaScript API. + * + * @param aClient DebuggerClient|TabClient + * The parent of the thread (tab for tab-scoped debuggers, DebuggerClient + * for chrome debuggers). + * @param aActor string + * The actor ID for this thread. + */ + function ThreadClient(aClient, aActor) { + this._parent = aClient; + this.client = aClient instanceof DebuggerClient ? aClient : aClient.client; + this._actor = aActor; + this._frameCache = []; + this._scriptCache = {}; + this._pauseGrips = {}; + this._threadGrips = {}; + this.request = this.client.request; + } + + ThreadClient.prototype = { + _state: "paused", + get state() { return this._state; }, + get paused() { return this._state === "paused"; }, + + _pauseOnExceptions: false, + _ignoreCaughtExceptions: false, + _pauseOnDOMEvents: null, + + _actor: null, + get actor() { return this._actor; }, + + get _transport() { return this.client._transport; }, + + _assertPaused: function(aCommand) { + if (!this.paused) { + throw Error(aCommand + " command sent while not paused. Currently " + this._state); + } + }, + + /** + * Resume a paused thread. If the optional aLimit parameter is present, then + * the thread will also pause when that limit is reached. + * + * @param [optional] object aLimit + * An object with a type property set to the appropriate limit (next, + * step, or finish) per the remote debugging protocol specification. + * Use null to specify no limit. + * @param function aOnResponse + * Called with the response packet. + */ + _doResume: DebuggerClient.requester({ + type: "resume", + resumeLimit: args(0) + }, { + before: function(aPacket) { + this._assertPaused("resume"); + + // Put the client in a tentative "resuming" state so we can prevent + // further requests that should only be sent in the paused state. + this._state = "resuming"; + + if (this._pauseOnExceptions) { + aPacket.pauseOnExceptions = this._pauseOnExceptions; + } + if (this._ignoreCaughtExceptions) { + aPacket.ignoreCaughtExceptions = this._ignoreCaughtExceptions; + } + if (this._pauseOnDOMEvents) { + aPacket.pauseOnDOMEvents = this._pauseOnDOMEvents; + } + return aPacket; + }, + after: function(aResponse) { + if (aResponse.error) { + // There was an error resuming, back to paused state. + this._state = "paused"; + } + return aResponse; + }, + telemetry: "RESUME" + }), + + /** + * Reconfigure the thread actor. + * + * @param object aOptions + * A dictionary object of the new options to use in the thread actor. + * @param function aOnResponse + * Called with the response packet. + */ + reconfigure: DebuggerClient.requester({ + type: "reconfigure", + options: args(0) + }, { + telemetry: "RECONFIGURETHREAD" + }), + + /** + * Resume a paused thread. + */ + resume: function(aOnResponse) { + return this._doResume(null, aOnResponse); + }, + + /** + * Resume then pause without stepping. + * + * @param function aOnResponse + * Called with the response packet. + */ + resumeThenPause: function(aOnResponse) { + return this._doResume({ type: "break" }, aOnResponse); + }, + + /** + * Step over a function call. + * + * @param function aOnResponse + * Called with the response packet. + */ + stepOver: function(aOnResponse) { + return this._doResume({ type: "next" }, aOnResponse); + }, + + /** + * Step into a function call. + * + * @param function aOnResponse + * Called with the response packet. + */ + stepIn: function(aOnResponse) { + return this._doResume({ type: "step" }, aOnResponse); + }, + + /** + * Step out of a function call. + * + * @param function aOnResponse + * Called with the response packet. + */ + stepOut: function(aOnResponse) { + return this._doResume({ type: "finish" }, aOnResponse); + }, + + /** + * Immediately interrupt a running thread. + * + * @param function aOnResponse + * Called with the response packet. + */ + interrupt: function(aOnResponse) { + return this._doInterrupt(null, aOnResponse); + }, + + /** + * Pause execution right before the next JavaScript bytecode is executed. + * + * @param function aOnResponse + * Called with the response packet. + */ + breakOnNext: function(aOnResponse) { + return this._doInterrupt("onNext", aOnResponse); + }, + + /** + * Interrupt a running thread. + * + * @param function aOnResponse + * Called with the response packet. + */ + _doInterrupt: DebuggerClient.requester({ + type: "interrupt", + when: args(0) + }, { + telemetry: "INTERRUPT" + }), + + /** + * Enable or disable pausing when an exception is thrown. + * + * @param boolean aFlag + * Enables pausing if true, disables otherwise. + * @param function aOnResponse + * Called with the response packet. + */ + pauseOnExceptions: function(aPauseOnExceptions, + aIgnoreCaughtExceptions, + aOnResponse = noop) { + this._pauseOnExceptions = aPauseOnExceptions; + this._ignoreCaughtExceptions = aIgnoreCaughtExceptions; + + // Otherwise send the flag using a standard resume request. + if (!this.paused) { + return this.interrupt(aResponse => { + if (aResponse.error) { + // Can't continue if pausing failed. + aOnResponse(aResponse); + return aResponse; + } + return this.resume(aOnResponse); + }); + } + + aOnResponse(); + return promise.resolve(); + }, + + /** + * Enable pausing when the specified DOM events are triggered. Disabling + * pausing on an event can be realized by calling this method with the updated + * array of events that doesn't contain it. + * + * @param array|string events + * An array of strings, representing the DOM event types to pause on, + * or "*" to pause on all DOM events. Pass an empty array to + * completely disable pausing on DOM events. + * @param function onResponse + * Called with the response packet in a future turn of the event loop. + */ + pauseOnDOMEvents: function(events, onResponse = noop) { + this._pauseOnDOMEvents = events; + // If the debuggee is paused, the value of the array will be communicated in + // the next resumption. Otherwise we have to force a pause in order to send + // the array. + if (this.paused) { + DevToolsUtils.executeSoon(() => onResponse({})); + return {}; + } + return this.interrupt(response => { + // Can't continue if pausing failed. + if (response.error) { + onResponse(response); + return response; + } + return this.resume(onResponse); + }); + }, + + /** + * Send a clientEvaluate packet to the debuggee. Response + * will be a resume packet. + * + * @param string aFrame + * The actor ID of the frame where the evaluation should take place. + * @param string aExpression + * The expression that will be evaluated in the scope of the frame + * above. + * @param function aOnResponse + * Called with the response packet. + */ + eval: DebuggerClient.requester({ + type: "clientEvaluate", + frame: args(0), + expression: args(1) + }, { + before: function(aPacket) { + this._assertPaused("eval"); + // Put the client in a tentative "resuming" state so we can prevent + // further requests that should only be sent in the paused state. + this._state = "resuming"; + return aPacket; + }, + after: function(aResponse) { + if (aResponse.error) { + // There was an error resuming, back to paused state. + this._state = "paused"; + } + return aResponse; + }, + telemetry: "CLIENTEVALUATE" + }), + + /** + * Detach from the thread actor. + * + * @param function aOnResponse + * Called with the response packet. + */ + detach: DebuggerClient.requester({ + type: "detach" + }, { + after: function(aResponse) { + this.client.unregisterClient(this); + this._parent.thread = null; + return aResponse; + }, + telemetry: "THREADDETACH" + }), + + /** + * Release multiple thread-lifetime object actors. If any pause-lifetime + * actors are included in the request, a |notReleasable| error will return, + * but all the thread-lifetime ones will have been released. + * + * @param array actors + * An array with actor IDs to release. + */ + releaseMany: DebuggerClient.requester({ + type: "releaseMany", + actors: args(0), + }, { + telemetry: "RELEASEMANY" + }), + + /** + * Promote multiple pause-lifetime object actors to thread-lifetime ones. + * + * @param array actors + * An array with actor IDs to promote. + */ + threadGrips: DebuggerClient.requester({ + type: "threadGrips", + actors: args(0) + }, { + telemetry: "THREADGRIPS" + }), + + /** + * Return the event listeners defined on the page. + * + * @param aOnResponse Function + * Called with the thread's response. + */ + eventListeners: DebuggerClient.requester({ + type: "eventListeners" + }, { + telemetry: "EVENTLISTENERS" + }), + + /** + * Request the loaded sources for the current thread. + * + * @param aOnResponse Function + * Called with the thread's response. + */ + getSources: DebuggerClient.requester({ + type: "sources" + }, { + telemetry: "SOURCES" + }), + + /** + * Clear the thread's source script cache. A scriptscleared event + * will be sent. + */ + _clearScripts: function() { + if (Object.keys(this._scriptCache).length > 0) { + this._scriptCache = {}; + this.emit("scriptscleared"); + } + }, + + /** + * Request frames from the callstack for the current thread. + * + * @param aStart integer + * The number of the youngest stack frame to return (the youngest + * frame is 0). + * @param aCount integer + * The maximum number of frames to return, or null to return all + * frames. + * @param aOnResponse function + * Called with the thread's response. + */ + getFrames: DebuggerClient.requester({ + type: "frames", + start: args(0), + count: args(1) + }, { + telemetry: "FRAMES" + }), + + /** + * An array of cached frames. Clients can observe the framesadded and + * framescleared event to keep up to date on changes to this cache, + * and can fill it using the fillFrames method. + */ + get cachedFrames() { return this._frameCache; }, + + /** + * true if there are more stack frames available on the server. + */ + get moreFrames() { + return this.paused && (!this._frameCache || this._frameCache.length == 0 + || !this._frameCache[this._frameCache.length - 1].oldest); + }, + + /** + * Ensure that at least aTotal stack frames have been loaded in the + * ThreadClient's stack frame cache. A framesadded event will be + * sent when the stack frame cache is updated. + * + * @param aTotal number + * The minimum number of stack frames to be included. + * @param aCallback function + * Optional callback function called when frames have been loaded + * @returns true if a framesadded notification should be expected. + */ + fillFrames: function(aTotal, aCallback = noop) { + this._assertPaused("fillFrames"); + if (this._frameCache.length >= aTotal) { + return false; + } + + let numFrames = this._frameCache.length; + + this.getFrames(numFrames, aTotal - numFrames, (aResponse) => { + if (aResponse.error) { + aCallback(aResponse); + return; + } + + let threadGrips = DevToolsUtils.values(this._threadGrips); + + for (let i in aResponse.frames) { + let frame = aResponse.frames[i]; + if (!frame.where.source) { + // Older servers use urls instead, so we need to resolve + // them to source actors + for (let grip of threadGrips) { + if (grip instanceof SourceClient && grip.url === frame.url) { + frame.where.source = grip._form; + } + } + } + + this._frameCache[frame.depth] = frame; + } + + // If we got as many frames as we asked for, there might be more + // frames available. + this.emit("framesadded"); + + aCallback(aResponse); + }); + + return true; + }, + + /** + * Clear the thread's stack frame cache. A framescleared event + * will be sent. + */ + _clearFrames: function() { + if (this._frameCache.length > 0) { + this._frameCache = []; + this.emit("framescleared"); + } + }, + + /** + * Return a ObjectClient object for the given object grip. + * + * @param aGrip object + * A pause-lifetime object grip returned by the protocol. + */ + pauseGrip: function(aGrip) { + if (aGrip.actor in this._pauseGrips) { + return this._pauseGrips[aGrip.actor]; + } + + let client = new ObjectClient(this.client, aGrip); + this._pauseGrips[aGrip.actor] = client; + return client; + }, + + /** + * Get or create a long string client, checking the grip client cache if it + * already exists. + * + * @param aGrip Object + * The long string grip returned by the protocol. + * @param aGripCacheName String + * The property name of the grip client cache to check for existing + * clients in. + */ + _longString: function(aGrip, aGripCacheName) { + if (aGrip.actor in this[aGripCacheName]) { + return this[aGripCacheName][aGrip.actor]; + } + + let client = new LongStringClient(this.client, aGrip); + this[aGripCacheName][aGrip.actor] = client; + return client; + }, + + /** + * Return an instance of LongStringClient for the given long string grip that + * is scoped to the current pause. + * + * @param aGrip Object + * The long string grip returned by the protocol. + */ + pauseLongString: function(aGrip) { + return this._longString(aGrip, "_pauseGrips"); + }, + + /** + * Return an instance of LongStringClient for the given long string grip that + * is scoped to the thread lifetime. + * + * @param aGrip Object + * The long string grip returned by the protocol. + */ + threadLongString: function(aGrip) { + return this._longString(aGrip, "_threadGrips"); + }, + + /** + * Clear and invalidate all the grip clients from the given cache. + * + * @param aGripCacheName + * The property name of the grip cache we want to clear. + */ + _clearObjectClients: function(aGripCacheName) { + for (let id in this[aGripCacheName]) { + this[aGripCacheName][id].valid = false; + } + this[aGripCacheName] = {}; + }, + + /** + * Invalidate pause-lifetime grip clients and clear the list of current grip + * clients. + */ + _clearPauseGrips: function() { + this._clearObjectClients("_pauseGrips"); + }, + + /** + * Invalidate thread-lifetime grip clients and clear the list of current grip + * clients. + */ + _clearThreadGrips: function() { + this._clearObjectClients("_threadGrips"); + }, + + /** + * Handle thread state change by doing necessary cleanup and notifying all + * registered listeners. + */ + _onThreadState: function(aPacket) { + this._state = ThreadStateTypes[aPacket.type]; + // The debugger UI may not be initialized yet so we want to keep + // the packet around so it knows what to pause state to display + // when it's initialized + this._lastPausePacket = aPacket.type === "resumed" ? null : aPacket; + this._clearFrames(); + this._clearPauseGrips(); + aPacket.type === ThreadStateTypes.detached && this._clearThreadGrips(); + this.client._eventsEnabled && this.emit(aPacket.type, aPacket); + }, + + getLastPausePacket: function() { + return this._lastPausePacket; + }, + + /** + * Return an EnvironmentClient instance for the given environment actor form. + */ + environment: function(aForm) { + return new EnvironmentClient(this.client, aForm); + }, + + /** + * Return an instance of SourceClient for the given source actor form. + */ + source: function(aForm) { + if (aForm.actor in this._threadGrips) { + return this._threadGrips[aForm.actor]; + } + + return this._threadGrips[aForm.actor] = new SourceClient(this, aForm); + }, + + /** + * Request the prototype and own properties of mutlipleObjects. + * + * @param aOnResponse function + * Called with the request's response. + * @param actors [string] + * List of actor ID of the queried objects. + */ + getPrototypesAndProperties: DebuggerClient.requester({ + type: "prototypesAndProperties", + actors: args(0) + }, { + telemetry: "PROTOTYPESANDPROPERTIES" + }), + + events: ["newSource"] + }; + + eventSource(ThreadClient.prototype); + + /** + * Creates a tracing profiler client for the remote debugging protocol + * server. This client is a front to the trace actor created on the + * server side, hiding the protocol details in a traditional + * JavaScript API. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aActor string + * The actor ID for this thread. + */ + function TraceClient(aClient, aActor) { + this._client = aClient; + this._actor = aActor; + this._activeTraces = new Set(); + this._waitingPackets = new Map(); + this._expectedPacket = 0; + this.request = this._client.request; + this.events = []; + } + + TraceClient.prototype = { + get actor() { return this._actor; }, + get tracing() { return this._activeTraces.size > 0; }, + + get _transport() { return this._client._transport; }, + + /** + * Detach from the trace actor. + */ + detach: DebuggerClient.requester({ + type: "detach" + }, { + after: function(aResponse) { + this._client.unregisterClient(this); + return aResponse; + }, + telemetry: "TRACERDETACH" + }), + + /** + * Start a new trace. + * + * @param aTrace [string] + * An array of trace types to be recorded by the new trace. + * + * @param aName string + * The name of the new trace. + * + * @param aOnResponse function + * Called with the request's response. + */ + startTrace: DebuggerClient.requester({ + type: "startTrace", + name: args(1), + trace: args(0) + }, { + after: function(aResponse) { + if (aResponse.error) { + return aResponse; + } + + if (!this.tracing) { + this._waitingPackets.clear(); + this._expectedPacket = 0; + } + this._activeTraces.add(aResponse.name); + + return aResponse; + }, + telemetry: "STARTTRACE" + }), + + /** + * End a trace. If a name is provided, stop the named + * trace. Otherwise, stop the most recently started trace. + * + * @param aName string + * The name of the trace to stop. + * + * @param aOnResponse function + * Called with the request's response. + */ + stopTrace: DebuggerClient.requester({ + type: "stopTrace", + name: args(0) + }, { + after: function(aResponse) { + if (aResponse.error) { + return aResponse; + } + + this._activeTraces.delete(aResponse.name); + + return aResponse; + }, + telemetry: "STOPTRACE" + }) + }; + + /** + * Grip clients are used to retrieve information about the relevant object. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aGrip object + * A pause-lifetime object grip returned by the protocol. + */ + function ObjectClient(aClient, aGrip) + { + this._grip = aGrip; + this._client = aClient; + this.request = this._client.request; + } + exports.ObjectClient = ObjectClient; + + ObjectClient.prototype = { + get actor() { return this._grip.actor; }, + get _transport() { return this._client._transport; }, + + valid: true, + + get isFrozen() { + return this._grip.frozen; + }, + get isSealed() { + return this._grip.sealed; + }, + get isExtensible() { + return this._grip.extensible; + }, + + getDefinitionSite: DebuggerClient.requester({ + type: "definitionSite" + }, { + before: function(aPacket) { + if (this._grip.class != "Function") { + throw new Error("getDefinitionSite is only valid for function grips."); + } + return aPacket; + } + }), + + /** + * Request the names of a function's formal parameters. + * + * @param aOnResponse function + * Called with an object of the form: + * { parameterNames:[, ...] } + * where each is the name of a parameter. + */ + getParameterNames: DebuggerClient.requester({ + type: "parameterNames" + }, { + before: function(aPacket) { + if (this._grip.class !== "Function") { + throw new Error("getParameterNames is only valid for function grips."); + } + return aPacket; + }, + telemetry: "PARAMETERNAMES" + }), + + /** + * Request the names of the properties defined on the object and not its + * prototype. + * + * @param aOnResponse function Called with the request's response. + */ + getOwnPropertyNames: DebuggerClient.requester({ + type: "ownPropertyNames" + }, { + telemetry: "OWNPROPERTYNAMES" + }), + + /** + * Request the prototype and own properties of the object. + * + * @param aOnResponse function Called with the request's response. + */ + getPrototypeAndProperties: DebuggerClient.requester({ + type: "prototypeAndProperties" + }, { + telemetry: "PROTOTYPEANDPROPERTIES" + }), + + /** + * Request a PropertyIteratorClient instance to ease listing + * properties for this object. + * + * @param options Object + * A dictionary object with various boolean attributes: + * - ignoreSafeGetters Boolean + * If true, do not iterate over safe getters. + * - ignoreIndexedProperties Boolean + * If true, filters out Array items. + * e.g. properties names between `0` and `object.length`. + * - ignoreNonIndexedProperties Boolean + * If true, filters out items that aren't array items + * e.g. properties names that are not a number between `0` + * and `object.length`. + * - sort Boolean + * If true, the iterator will sort the properties by name + * before dispatching them. + * @param aOnResponse function Called with the client instance. + */ + enumProperties: DebuggerClient.requester({ + type: "enumProperties", + options: args(0) + }, { + after: function(aResponse) { + if (aResponse.iterator) { + return { iterator: new PropertyIteratorClient(this._client, aResponse.iterator) }; + } + return aResponse; + }, + telemetry: "ENUMPROPERTIES" + }), + + /** + * Request a PropertyIteratorClient instance to enumerate entries in a + * Map/Set-like object. + * + * @param aOnResponse function Called with the request's response. + */ + enumEntries: DebuggerClient.requester({ + type: "enumEntries" + }, { + before: function(packet) { + if (!["Map", "WeakMap", "Set", "WeakSet"].includes(this._grip.class)) { + throw new Error("enumEntries is only valid for Map/Set-like grips."); + } + return packet; + }, + after: function(response) { + if (response.iterator) { + return { + iterator: new PropertyIteratorClient(this._client, response.iterator) + }; + } + return response; + } + }), + + /** + * Request the property descriptor of the object's specified property. + * + * @param aName string The name of the requested property. + * @param aOnResponse function Called with the request's response. + */ + getProperty: DebuggerClient.requester({ + type: "property", + name: args(0) + }, { + telemetry: "PROPERTY" + }), + + /** + * Request the prototype of the object. + * + * @param aOnResponse function Called with the request's response. + */ + getPrototype: DebuggerClient.requester({ + type: "prototype" + }, { + telemetry: "PROTOTYPE" + }), + + /** + * Request the display string of the object. + * + * @param aOnResponse function Called with the request's response. + */ + getDisplayString: DebuggerClient.requester({ + type: "displayString" + }, { + telemetry: "DISPLAYSTRING" + }), + + /** + * Request the scope of the object. + * + * @param aOnResponse function Called with the request's response. + */ + getScope: DebuggerClient.requester({ + type: "scope" + }, { + before: function(aPacket) { + if (this._grip.class !== "Function") { + throw new Error("scope is only valid for function grips."); + } + return aPacket; + }, + telemetry: "SCOPE" + }), + + /** + * Request the promises directly depending on the current promise. + */ + getDependentPromises: DebuggerClient.requester({ + type: "dependentPromises" + }, { + before: function(aPacket) { + if (this._grip.class !== "Promise") { + throw new Error("getDependentPromises is only valid for promise " + + "grips."); + } + return aPacket; + } + }), + + /** + * Request the stack to the promise's allocation point. + */ + getPromiseAllocationStack: DebuggerClient.requester({ + type: "allocationStack" + }, { + before: function(aPacket) { + if (this._grip.class !== "Promise") { + throw new Error("getAllocationStack is only valid for promise grips."); + } + return aPacket; + } + }), + + /** + * Request the stack to the promise's fulfillment point. + */ + getPromiseFulfillmentStack: DebuggerClient.requester({ + type: "fulfillmentStack" + }, { + before: function(packet) { + if (this._grip.class !== "Promise") { + throw new Error("getPromiseFulfillmentStack is only valid for " + + "promise grips."); + } + return packet; + } + }), + + /** + * Request the stack to the promise's rejection point. + */ + getPromiseRejectionStack: DebuggerClient.requester({ + type: "rejectionStack" + }, { + before: function(packet) { + if (this._grip.class !== "Promise") { + throw new Error("getPromiseRejectionStack is only valid for " + + "promise grips."); + } + return packet; + } + }) + }; + + /** + * A PropertyIteratorClient provides a way to access to property names and + * values of an object efficiently, slice by slice. + * Note that the properties can be sorted in the backend, + * this is controled while creating the PropertyIteratorClient + * from ObjectClient.enumProperties. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aGrip Object + * A PropertyIteratorActor grip returned by the protocol via + * TabActor.enumProperties request. + */ + function PropertyIteratorClient(aClient, aGrip) { + this._grip = aGrip; + this._client = aClient; + this.request = this._client.request; + } + + PropertyIteratorClient.prototype = { + get actor() { return this._grip.actor; }, + + /** + * Get the total number of properties available in the iterator. + */ + get count() { return this._grip.count; }, + + /** + * Get one or more property names that correspond to the positions in the + * indexes parameter. + * + * @param indexes Array + * An array of property indexes. + * @param aCallback Function + * The function called when we receive the property names. + */ + names: DebuggerClient.requester({ + type: "names", + indexes: args(0) + }, {}), + + /** + * Get a set of following property value(s). + * + * @param start Number + * The index of the first property to fetch. + * @param count Number + * The number of properties to fetch. + * @param aCallback Function + * The function called when we receive the property values. + */ + slice: DebuggerClient.requester({ + type: "slice", + start: args(0), + count: args(1) + }, {}), + + /** + * Get all the property values. + * + * @param aCallback Function + * The function called when we receive the property values. + */ + all: DebuggerClient.requester({ + type: "all" + }, {}), + }; + + /** + * A LongStringClient provides a way to access "very long" strings from the + * debugger server. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aGrip Object + * A pause-lifetime long string grip returned by the protocol. + */ + function LongStringClient(aClient, aGrip) { + this._grip = aGrip; + this._client = aClient; + this.request = this._client.request; + } + exports.LongStringClient = LongStringClient; + + LongStringClient.prototype = { + get actor() { return this._grip.actor; }, + get length() { return this._grip.length; }, + get initial() { return this._grip.initial; }, + get _transport() { return this._client._transport; }, + + valid: true, + + /** + * Get the substring of this LongString from aStart to aEnd. + * + * @param aStart Number + * The starting index. + * @param aEnd Number + * The ending index. + * @param aCallback Function + * The function called when we receive the substring. + */ + substring: DebuggerClient.requester({ + type: "substring", + start: args(0), + end: args(1) + }, { + telemetry: "SUBSTRING" + }), + }; + + /** + * A SourceClient provides a way to access the source text of a script. + * + * @param aClient ThreadClient + * The thread client parent. + * @param aForm Object + * The form sent across the remote debugging protocol. + */ + function SourceClient(aClient, aForm) { + this._form = aForm; + this._isBlackBoxed = aForm.isBlackBoxed; + this._isPrettyPrinted = aForm.isPrettyPrinted; + this._activeThread = aClient; + this._client = aClient.client; + } + + SourceClient.prototype = { + get _transport() { + return this._client._transport; + }, + get isBlackBoxed() { + return this._isBlackBoxed; + }, + get isPrettyPrinted() { + return this._isPrettyPrinted; + }, + get actor() { + return this._form.actor; + }, + get request() { + return this._client.request; + }, + get url() { + return this._form.url; + }, + + /** + * Black box this SourceClient's source. + * + * @param aCallback Function + * The callback function called when we receive the response from the server. + */ + blackBox: DebuggerClient.requester({ + type: "blackbox" + }, { + telemetry: "BLACKBOX", + after: function(aResponse) { + if (!aResponse.error) { + this._isBlackBoxed = true; + if (this._activeThread) { + this._activeThread.emit("blackboxchange", this); + } + } + return aResponse; + } + }), + + /** + * Un-black box this SourceClient's source. + * + * @param aCallback Function + * The callback function called when we receive the response from the server. + */ + unblackBox: DebuggerClient.requester({ + type: "unblackbox" + }, { + telemetry: "UNBLACKBOX", + after: function(aResponse) { + if (!aResponse.error) { + this._isBlackBoxed = false; + if (this._activeThread) { + this._activeThread.emit("blackboxchange", this); + } + } + return aResponse; + } + }), + + /** + * Get Executable Lines from a source + * + * @param aCallback Function + * The callback function called when we receive the response from the server. + */ + getExecutableLines: function(cb = noop) { + let packet = { + to: this._form.actor, + type: "getExecutableLines" + }; + + return this._client.request(packet).then(res => { + cb(res.lines); + return res.lines; + }); + }, + + /** + * Get a long string grip for this SourceClient's source. + */ + source: function(aCallback = noop) { + let packet = { + to: this._form.actor, + type: "source" + }; + return this._client.request(packet).then(aResponse => { + return this._onSourceResponse(aResponse, aCallback); + }); + }, + + /** + * Pretty print this source's text. + */ + prettyPrint: function(aIndent, aCallback = noop) { + const packet = { + to: this._form.actor, + type: "prettyPrint", + indent: aIndent + }; + return this._client.request(packet).then(aResponse => { + if (!aResponse.error) { + this._isPrettyPrinted = true; + this._activeThread._clearFrames(); + this._activeThread.emit("prettyprintchange", this); + } + return this._onSourceResponse(aResponse, aCallback); + }); + }, + + /** + * Stop pretty printing this source's text. + */ + disablePrettyPrint: function(aCallback = noop) { + const packet = { + to: this._form.actor, + type: "disablePrettyPrint" + }; + return this._client.request(packet).then(aResponse => { + if (!aResponse.error) { + this._isPrettyPrinted = false; + this._activeThread._clearFrames(); + this._activeThread.emit("prettyprintchange", this); + } + return this._onSourceResponse(aResponse, aCallback); + }); + }, + + _onSourceResponse: function(aResponse, aCallback) { + if (aResponse.error) { + aCallback(aResponse); + return aResponse; + } + + if (typeof aResponse.source === "string") { + aCallback(aResponse); + return aResponse; + } + + let { contentType, source } = aResponse; + let longString = this._activeThread.threadLongString(source); + return longString.substring(0, longString.length).then(function(aResponse) { + if (aResponse.error) { + aCallback(aResponse); + return aReponse; + } + + let response = { + source: aResponse.substring, + contentType: contentType + }; + aCallback(response); + return response; + }); + }, + + /** + * Request to set a breakpoint in the specified location. + * + * @param object aLocation + * The location and condition of the breakpoint in + * the form of { line[, column, condition] }. + * @param function aOnResponse + * Called with the thread's response. + */ + setBreakpoint: function({ line, column, condition, noSliding }, aOnResponse = noop) { + // A helper function that sets the breakpoint. + let doSetBreakpoint = aCallback => { + let root = this._client.mainRoot; + let location = { + line: line, + column: column + }; + + let packet = { + to: this.actor, + type: "setBreakpoint", + location: location, + condition: condition, + noSliding: noSliding + }; + + // Backwards compatibility: send the breakpoint request to the + // thread if the server doesn't support Debugger.Source actors. + if (!root.traits.debuggerSourceActors) { + packet.to = this._activeThread.actor; + packet.location.url = this.url; + } + + return this._client.request(packet).then(aResponse => { + // Ignoring errors, since the user may be setting a breakpoint in a + // dead script that will reappear on a page reload. + let bpClient; + if (aResponse.actor) { + bpClient = new BreakpointClient( + this._client, + this, + aResponse.actor, + location, + root.traits.conditionalBreakpoints ? condition : undefined + ); + } + aOnResponse(aResponse, bpClient); + if (aCallback) { + aCallback(); + } + return [aResponse, bpClient]; + }); + }; + + // If the debuggee is paused, just set the breakpoint. + if (this._activeThread.paused) { + return doSetBreakpoint(); + } + // Otherwise, force a pause in order to set the breakpoint. + return this._activeThread.interrupt().then(aResponse => { + if (aResponse.error) { + // Can't set the breakpoint if pausing failed. + aOnResponse(aResponse); + return aResponse; + } + + const { type, why } = aResponse; + const cleanUp = type == "paused" && why.type == "interrupted" + ? () => this._activeThread.resume() + : noop; + + return doSetBreakpoint(cleanUp); + }); + } + }; + + /** + * Breakpoint clients are used to remove breakpoints that are no longer used. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aSourceClient SourceClient + * The source where this breakpoint exists + * @param aActor string + * The actor ID for this breakpoint. + * @param aLocation object + * The location of the breakpoint. This is an object with two properties: + * url and line. + * @param aCondition string + * The conditional expression of the breakpoint + */ + function BreakpointClient(aClient, aSourceClient, aActor, aLocation, aCondition) { + this._client = aClient; + this._actor = aActor; + this.location = aLocation; + this.location.actor = aSourceClient.actor; + this.location.url = aSourceClient.url; + this.source = aSourceClient; + this.request = this._client.request; + + // The condition property should only exist if it's a truthy value + if (aCondition) { + this.condition = aCondition; + } + } + + BreakpointClient.prototype = { + + _actor: null, + get actor() { return this._actor; }, + get _transport() { return this._client._transport; }, + + /** + * Remove the breakpoint from the server. + */ + remove: DebuggerClient.requester({ + type: "delete" + }, { + telemetry: "DELETE" + }), + + /** + * Determines if this breakpoint has a condition + */ + hasCondition: function() { + let root = this._client.mainRoot; + // XXX bug 990137: We will remove support for client-side handling of + // conditional breakpoints + if (root.traits.conditionalBreakpoints) { + return "condition" in this; + } else { + return "conditionalExpression" in this; + } + }, + + /** + * Get the condition of this breakpoint. Currently we have to + * support locally emulated conditional breakpoints until the + * debugger servers are updated (see bug 990137). We used a + * different property when moving it server-side to ensure that we + * are testing the right code. + */ + getCondition: function() { + let root = this._client.mainRoot; + if (root.traits.conditionalBreakpoints) { + return this.condition; + } else { + return this.conditionalExpression; + } + }, + + /** + * Set the condition of this breakpoint + */ + setCondition: function(gThreadClient, aCondition, noSliding) { + let root = this._client.mainRoot; + let deferred = promise.defer(); + + if (root.traits.conditionalBreakpoints) { + let info = { + line: this.location.line, + column: this.location.column, + condition: aCondition, + noSliding + }; + + // Remove the current breakpoint and add a new one with the + // condition. + this.remove(aResponse => { + if (aResponse && aResponse.error) { + deferred.reject(aResponse); + return; + } + + this.source.setBreakpoint(info, (aResponse, aNewBreakpoint) => { + if (aResponse && aResponse.error) { + deferred.reject(aResponse); + } else { + deferred.resolve(aNewBreakpoint); + } + }); + }); + } else { + // The property shouldn't even exist if the condition is blank + if (aCondition === "") { + delete this.conditionalExpression; + } + else { + this.conditionalExpression = aCondition; + } + deferred.resolve(this); + } + + return deferred.promise; + } + }; + + eventSource(BreakpointClient.prototype); + + /** + * Environment clients are used to manipulate the lexical environment actors. + * + * @param aClient DebuggerClient + * The debugger client parent. + * @param aForm Object + * The form sent across the remote debugging protocol. + */ + function EnvironmentClient(aClient, aForm) { + this._client = aClient; + this._form = aForm; + this.request = this._client.request; + } + exports.EnvironmentClient = EnvironmentClient; + + EnvironmentClient.prototype = { + + get actor() { + return this._form.actor; + }, + get _transport() { return this._client._transport; }, + + /** + * Fetches the bindings introduced by this lexical environment. + */ + getBindings: DebuggerClient.requester({ + type: "bindings" + }, { + telemetry: "BINDINGS" + }), + + /** + * Changes the value of the identifier whose name is name (a string) to that + * represented by value (a grip). + */ + assign: DebuggerClient.requester({ + type: "assign", + name: args(0), + value: args(1) + }, { + telemetry: "ASSIGN" + }) + }; + + eventSource(EnvironmentClient.prototype); + + +/***/ }, +/* 90 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(module) {/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + module.metadata = { + "stability": "unstable" + }; + + const UNCAUGHT_ERROR = 'An error event was emitted for which there was no listener.'; + const BAD_LISTENER = 'The event listener must be a function.'; + + const { ns } = __webpack_require__(91); + + const event = ns(); + + const EVENT_TYPE_PATTERN = /^on([A-Z]\w+$)/; + exports.EVENT_TYPE_PATTERN = EVENT_TYPE_PATTERN; + + // Utility function to access given event `target` object's event listeners for + // the specific event `type`. If listeners for this type does not exists they + // will be created. + const observers = function observers(target, type) { + if (!target) throw TypeError("Event target must be an object"); + let listeners = event(target); + return type in listeners ? listeners[type] : listeners[type] = []; + }; + + /** + * Registers an event `listener` that is called every time events of + * specified `type` is emitted on the given event `target`. + * @param {Object} target + * Event target object. + * @param {String} type + * The type of event. + * @param {Function} listener + * The listener function that processes the event. + */ + function on(target, type, listener) { + if (typeof(listener) !== 'function') + throw new Error(BAD_LISTENER); + + let listeners = observers(target, type); + if (!~listeners.indexOf(listener)) + listeners.push(listener); + } + exports.on = on; + + + var onceWeakMap = new WeakMap(); + + + /** + * Registers an event `listener` that is called only the next time an event + * of the specified `type` is emitted on the given event `target`. + * @param {Object} target + * Event target object. + * @param {String} type + * The type of the event. + * @param {Function} listener + * The listener function that processes the event. + */ + function once(target, type, listener) { + let replacement = function observer(...args) { + off(target, type, observer); + onceWeakMap.delete(listener); + listener.apply(target, args); + }; + onceWeakMap.set(listener, replacement); + on(target, type, replacement); + } + exports.once = once; + + /** + * Execute each of the listeners in order with the supplied arguments. + * All the exceptions that are thrown by listeners during the emit + * are caught and can be handled by listeners of 'error' event. Thrown + * exceptions are passed as an argument to an 'error' event listener. + * If no 'error' listener is registered exception will be logged into an + * error console. + * @param {Object} target + * Event target object. + * @param {String} type + * The type of event. + * @params {Object|Number|String|Boolean} args + * Arguments that will be passed to listeners. + */ + function emit (target, type, ...args) { + emitOnObject(target, type, target, ...args); + } + exports.emit = emit; + + /** + * A variant of emit that allows setting the this property for event listeners + */ + function emitOnObject(target, type, thisArg, ...args) { + let all = observers(target, '*').length; + let state = observers(target, type); + let listeners = state.slice(); + let count = listeners.length; + let index = 0; + + // If error event and there are no handlers (explicit or catch-all) + // then print error message to the console. + if (count === 0 && type === 'error' && all === 0) + console.exception(args[0]); + while (index < count) { + try { + let listener = listeners[index]; + // Dispatch only if listener is still registered. + if (~state.indexOf(listener)) + listener.apply(thisArg, args); + } + catch (error) { + // If exception is not thrown by a error listener and error listener is + // registered emit `error` event. Otherwise dump exception to the console. + if (type !== 'error') emit(target, 'error', error); + else console.exception(error); + } + index++; + } + // Also emit on `"*"` so that one could listen for all events. + if (type !== '*') emit(target, '*', type, ...args); + } + exports.emitOnObject = emitOnObject; + + /** + * Removes an event `listener` for the given event `type` on the given event + * `target`. If no `listener` is passed removes all listeners of the given + * `type`. If `type` is not passed removes all the listeners of the given + * event `target`. + * @param {Object} target + * The event target object. + * @param {String} type + * The type of event. + * @param {Function} listener + * The listener function that processes the event. + */ + function off(target, type, listener) { + let length = arguments.length; + if (length === 3) { + if (onceWeakMap.has(listener)) { + listener = onceWeakMap.get(listener); + onceWeakMap.delete(listener); + } + + let listeners = observers(target, type); + let index = listeners.indexOf(listener); + if (~index) + listeners.splice(index, 1); + } + else if (length === 2) { + observers(target, type).splice(0); + } + else if (length === 1) { + let listeners = event(target); + Object.keys(listeners).forEach(type => delete listeners[type]); + } + } + exports.off = off; + + /** + * Returns a number of event listeners registered for the given event `type` + * on the given event `target`. + */ + function count(target, type) { + return observers(target, type).length; + } + exports.count = count; + + /** + * Registers listeners on the given event `target` from the given `listeners` + * dictionary. Iterates over the listeners and if property name matches name + * pattern `onEventType` and property is a function, then registers it as + * an `eventType` listener on `target`. + * + * @param {Object} target + * The type of event. + * @param {Object} listeners + * Dictionary of listeners. + */ + function setListeners(target, listeners) { + Object.keys(listeners || {}).forEach(key => { + let match = EVENT_TYPE_PATTERN.exec(key); + let type = match && match[1].toLowerCase(); + if (!type) return; + + let listener = listeners[key]; + if (typeof(listener) === 'function') + on(target, type, listener); + }); + } + exports.setListeners = setListeners; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(87)(module))) + +/***/ }, +/* 91 */ +/***/ function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(module) {/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + module.metadata = { + "stability": "unstable" + }; + + const create = Object.create; + const prototypeOf = Object.getPrototypeOf; + + /** + * Returns a new namespace, function that may can be used to access an + * namespaced object of the argument argument. Namespaced object are associated + * with owner objects via weak references. Namespaced objects inherit from the + * owners ancestor namespaced object. If owner's ancestor is `null` then + * namespaced object inherits from given `prototype`. Namespaces can be used + * to define internal APIs that can be shared via enclosing `namespace` + * function. + * @examples + * const internals = ns(); + * internals(object).secret = secret; + */ + function ns() { + const map = new WeakMap(); + return function namespace(target) { + if (!target) // If `target` is not an object return `target` itself. + return target; + // If target has no namespaced object yet, create one that inherits from + // the target prototype's namespaced object. + if (!map.has(target)) + map.set(target, create(namespace(prototypeOf(target) || null))); + + return map.get(target); + }; + }; + + // `Namespace` is a e4x function in the scope, so we export the function also as + // `ns` as alias to avoid clashing. + exports.ns = ns; + exports.Namespace = ns; + + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(87)(module))) + +/***/ }, +/* 92 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */ + /* vim: set ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + const {Cc, Ci, Cu} = __webpack_require__(71); + const DevToolsUtils = __webpack_require__(78); + const EventEmitter = __webpack_require__(70); + const promise = __webpack_require__(76); + const {LongStringClient} = __webpack_require__(89); + + /** + * A WebConsoleClient is used as a front end for the WebConsoleActor that is + * created on the server, hiding implementation details. + * + * @param object aDebuggerClient + * The DebuggerClient instance we live for. + * @param object aResponse + * The response packet received from the "startListeners" request sent to + * the WebConsoleActor. + */ + function WebConsoleClient(aDebuggerClient, aResponse) + { + this._actor = aResponse.from; + this._client = aDebuggerClient; + this._longStrings = {}; + this.traits = aResponse.traits || {}; + this.events = []; + this._networkRequests = new Map(); + + this.pendingEvaluationResults = new Map(); + this.onEvaluationResult = this.onEvaluationResult.bind(this); + this.onNetworkEvent = this._onNetworkEvent.bind(this); + this.onNetworkEventUpdate = this._onNetworkEventUpdate.bind(this); + + this._client.addListener("evaluationResult", this.onEvaluationResult); + this._client.addListener("networkEvent", this.onNetworkEvent); + this._client.addListener("networkEventUpdate", this.onNetworkEventUpdate); + EventEmitter.decorate(this); + } + + exports.WebConsoleClient = WebConsoleClient; + + WebConsoleClient.prototype = { + _longStrings: null, + traits: null, + + /** + * Holds the network requests currently displayed by the Web Console. Each key + * represents the connection ID and the value is network request information. + * @private + * @type object + */ + _networkRequests: null, + + getNetworkRequest(actorId) { + return this._networkRequests.get(actorId); + }, + + hasNetworkRequest(actorId) { + return this._networkRequests.has(actorId); + }, + + removeNetworkRequest(actorId) { + this._networkRequests.delete(actorId); + }, + + getNetworkEvents() { + return this._networkRequests.values(); + }, + + get actor() { return this._actor; }, + + /** + * The "networkEvent" message type handler. We redirect any message to + * the UI for displaying. + * + * @private + * @param string type + * Message type. + * @param object packet + * The message received from the server. + */ + _onNetworkEvent: function (type, packet) + { + if (packet.from == this._actor) { + let actor = packet.eventActor; + let networkInfo = { + _type: "NetworkEvent", + timeStamp: actor.timeStamp, + node: null, + actor: actor.actor, + discardRequestBody: true, + discardResponseBody: true, + startedDateTime: actor.startedDateTime, + request: { + url: actor.url, + method: actor.method, + }, + isXHR: actor.isXHR, + response: {}, + timings: {}, + updates: [], // track the list of network event updates + private: actor.private, + fromCache: actor.fromCache + }; + this._networkRequests.set(actor.actor, networkInfo); + + this.emit("networkEvent", networkInfo); + } + }, + + /** + * The "networkEventUpdate" message type handler. We redirect any message to + * the UI for displaying. + * + * @private + * @param string type + * Message type. + * @param object packet + * The message received from the server. + */ + _onNetworkEventUpdate: function (type, packet) + { + let networkInfo = this.getNetworkRequest(packet.from); + if (!networkInfo) { + return; + } + + networkInfo.updates.push(packet.updateType); + + switch (packet.updateType) { + case "requestHeaders": + networkInfo.request.headersSize = packet.headersSize; + break; + case "requestPostData": + networkInfo.discardRequestBody = packet.discardRequestBody; + networkInfo.request.bodySize = packet.dataSize; + break; + case "responseStart": + networkInfo.response.httpVersion = packet.response.httpVersion; + networkInfo.response.status = packet.response.status; + networkInfo.response.statusText = packet.response.statusText; + networkInfo.response.headersSize = packet.response.headersSize; + networkInfo.response.remoteAddress = packet.response.remoteAddress; + networkInfo.response.remotePort = packet.response.remotePort; + networkInfo.discardResponseBody = packet.response.discardResponseBody; + break; + case "responseContent": + networkInfo.response.content = { + mimeType: packet.mimeType, + }; + networkInfo.response.bodySize = packet.contentSize; + networkInfo.response.transferredSize = packet.transferredSize; + networkInfo.discardResponseBody = packet.discardResponseBody; + break; + case "eventTimings": + networkInfo.totalTime = packet.totalTime; + break; + case "securityInfo": + networkInfo.securityInfo = packet.state; + break; + } + + this.emit("networkEventUpdate", { + packet: packet, + networkInfo + }); + }, + + /** + * Retrieve the cached messages from the server. + * + * @see this.CACHED_MESSAGES + * @param array types + * The array of message types you want from the server. See + * this.CACHED_MESSAGES for known types. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getCachedMessages: function WCC_getCachedMessages(types, aOnResponse) + { + let packet = { + to: this._actor, + type: "getCachedMessages", + messageTypes: types, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Inspect the properties of an object. + * + * @param string aActor + * The WebConsoleObjectActor ID to send the request to. + * @param function aOnResponse + * The function invoked when the response is received. + */ + inspectObjectProperties: + function WCC_inspectObjectProperties(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "inspectProperties", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Evaluate a JavaScript expression. + * + * @param string aString + * The code you want to evaluate. + * @param function aOnResponse + * The function invoked when the response is received. + * @param object [aOptions={}] + * Options for evaluation: + * + * - bindObjectActor: an ObjectActor ID. The OA holds a reference to + * a Debugger.Object that wraps a content object. This option allows + * you to bind |_self| to the D.O of the given OA, during string + * evaluation. + * + * See: Debugger.Object.executeInGlobalWithBindings() for information + * about bindings. + * + * Use case: the variable view needs to update objects and it does so + * by knowing the ObjectActor it inspects and binding |_self| to the + * D.O of the OA. As such, variable view sends strings like these for + * eval: + * _self["prop"] = value; + * + * - frameActor: a FrameActor ID. The FA holds a reference to + * a Debugger.Frame. This option allows you to evaluate the string in + * the frame of the given FA. + * + * - url: the url to evaluate the script as. Defaults to + * "debugger eval code". + * + * - selectedNodeActor: the NodeActor ID of the current selection in the + * Inspector, if such a selection exists. This is used by helper functions + * that can reference the currently selected node in the Inspector, like + * $0. + */ + evaluateJS: function WCC_evaluateJS(aString, aOnResponse, aOptions = {}) + { + let packet = { + to: this._actor, + type: "evaluateJS", + text: aString, + bindObjectActor: aOptions.bindObjectActor, + frameActor: aOptions.frameActor, + url: aOptions.url, + selectedNodeActor: aOptions.selectedNodeActor, + selectedObjectActor: aOptions.selectedObjectActor, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Evaluate a JavaScript expression asynchronously. + * See evaluateJS for parameter and response information. + */ + evaluateJSAsync: function(aString, aOnResponse, aOptions = {}) + { + // Pre-37 servers don't support async evaluation. + if (!this.traits.evaluateJSAsync) { + this.evaluateJS(aString, aOnResponse, aOptions); + return; + } + + let packet = { + to: this._actor, + type: "evaluateJSAsync", + text: aString, + bindObjectActor: aOptions.bindObjectActor, + frameActor: aOptions.frameActor, + url: aOptions.url, + selectedNodeActor: aOptions.selectedNodeActor, + selectedObjectActor: aOptions.selectedObjectActor, + }; + + this._client.request(packet, response => { + // Null check this in case the client has been detached while waiting + // for a response. + if (this.pendingEvaluationResults) { + this.pendingEvaluationResults.set(response.resultID, aOnResponse); + } + }); + }, + + /** + * Handler for the actors's unsolicited evaluationResult packet. + */ + onEvaluationResult: function(aNotification, aPacket) { + // The client on the main thread can receive notification packets from + // multiple webconsole actors: the one on the main thread and the ones + // on worker threads. So make sure we should be handling this request. + if (aPacket.from !== this._actor) { + return; + } + + // Find the associated callback based on this ID, and fire it. + // In a sync evaluation, this would have already been called in + // direct response to the client.request function. + let onResponse = this.pendingEvaluationResults.get(aPacket.resultID); + if (onResponse) { + onResponse(aPacket); + this.pendingEvaluationResults.delete(aPacket.resultID); + } else { + DevToolsUtils.reportException("onEvaluationResult", + "No response handler for an evaluateJSAsync result (resultID: " + aPacket.resultID + ")"); + } + }, + + /** + * Autocomplete a JavaScript expression. + * + * @param string aString + * The code you want to autocomplete. + * @param number aCursor + * Cursor location inside the string. Index starts from 0. + * @param function aOnResponse + * The function invoked when the response is received. + * @param string aFrameActor + * The id of the frame actor that made the call. + */ + autocomplete: function WCC_autocomplete(aString, aCursor, aOnResponse, aFrameActor) + { + let packet = { + to: this._actor, + type: "autocomplete", + text: aString, + cursor: aCursor, + frameActor: aFrameActor, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Clear the cache of messages (page errors and console API calls). + */ + clearMessagesCache: function WCC_clearMessagesCache() + { + let packet = { + to: this._actor, + type: "clearMessagesCache", + }; + this._client.request(packet); + }, + + /** + * Get Web Console-related preferences on the server. + * + * @param array aPreferences + * An array with the preferences you want to retrieve. + * @param function [aOnResponse] + * Optional function to invoke when the response is received. + */ + getPreferences: function WCC_getPreferences(aPreferences, aOnResponse) + { + let packet = { + to: this._actor, + type: "getPreferences", + preferences: aPreferences, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Set Web Console-related preferences on the server. + * + * @param object aPreferences + * An object with the preferences you want to change. + * @param function [aOnResponse] + * Optional function to invoke when the response is received. + */ + setPreferences: function WCC_setPreferences(aPreferences, aOnResponse) + { + let packet = { + to: this._actor, + type: "setPreferences", + preferences: aPreferences, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the request headers from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getRequestHeaders: function WCC_getRequestHeaders(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getRequestHeaders", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the request cookies from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getRequestCookies: function WCC_getRequestCookies(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getRequestCookies", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the request post data from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getRequestPostData: function WCC_getRequestPostData(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getRequestPostData", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the response headers from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getResponseHeaders: function WCC_getResponseHeaders(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getResponseHeaders", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the response cookies from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getResponseCookies: function WCC_getResponseCookies(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getResponseCookies", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the response content from the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getResponseContent: function WCC_getResponseContent(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getResponseContent", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the timing information for the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getEventTimings: function WCC_getEventTimings(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getEventTimings", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Retrieve the security information for the given NetworkEventActor. + * + * @param string aActor + * The NetworkEventActor ID. + * @param function aOnResponse + * The function invoked when the response is received. + */ + getSecurityInfo: function WCC_getSecurityInfo(aActor, aOnResponse) + { + let packet = { + to: aActor, + type: "getSecurityInfo", + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Send a HTTP request with the given data. + * + * @param string aData + * The details of the HTTP request. + * @param function aOnResponse + * The function invoked when the response is received. + */ + sendHTTPRequest: function WCC_sendHTTPRequest(aData, aOnResponse) { + let packet = { + to: this._actor, + type: "sendHTTPRequest", + request: aData + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Start the given Web Console listeners. + * + * @see this.LISTENERS + * @param array aListeners + * Array of listeners you want to start. See this.LISTENERS for + * known listeners. + * @param function aOnResponse + * Function to invoke when the server response is received. + */ + startListeners: function WCC_startListeners(aListeners, aOnResponse) + { + let packet = { + to: this._actor, + type: "startListeners", + listeners: aListeners, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Stop the given Web Console listeners. + * + * @see this.LISTENERS + * @param array aListeners + * Array of listeners you want to stop. See this.LISTENERS for + * known listeners. + * @param function aOnResponse + * Function to invoke when the server response is received. + */ + stopListeners: function WCC_stopListeners(aListeners, aOnResponse) + { + let packet = { + to: this._actor, + type: "stopListeners", + listeners: aListeners, + }; + this._client.request(packet, aOnResponse); + }, + + /** + * Return an instance of LongStringClient for the given long string grip. + * + * @param object aGrip + * The long string grip returned by the protocol. + * @return object + * The LongStringClient for the given long string grip. + */ + longString: function WCC_longString(aGrip) + { + if (aGrip.actor in this._longStrings) { + return this._longStrings[aGrip.actor]; + } + + let client = new LongStringClient(this._client, aGrip); + this._longStrings[aGrip.actor] = client; + return client; + }, + + /** + * Close the WebConsoleClient. This stops all the listeners on the server and + * detaches from the console actor. + * + * @param function aOnResponse + * Function to invoke when the server response is received. + */ + detach: function WCC_detach(aOnResponse) + { + this._client.removeListener("evaluationResult", this.onEvaluationResult); + this._client.removeListener("networkEvent", this.onNetworkEvent); + this._client.removeListener("networkEventUpdate", this.onNetworkEventUpdate); + this.stopListeners(null, aOnResponse); + this._longStrings = null; + this._client = null; + this.pendingEvaluationResults.clear(); + this.pendingEvaluationResults = null; + this.clearNetworkRequests(); + this._networkRequests = null; + }, + + clearNetworkRequests: function () { + this._networkRequests.clear(); + }, + + /** + * Fetches the full text of a LongString. + * + * @param object | string stringGrip + * The long string grip containing the corresponding actor. + * If you pass in a plain string (by accident or because you're lazy), + * then a promise of the same string is simply returned. + * @return object Promise + * A promise that is resolved when the full string contents + * are available, or rejected if something goes wrong. + */ + getString: function(stringGrip) { + // Make sure this is a long string. + if (typeof stringGrip != "object" || stringGrip.type != "longString") { + return promise.resolve(stringGrip); // Go home string, you're drunk. + } + + // Fetch the long string only once. + if (stringGrip._fullText) { + return stringGrip._fullText.promise; + } + + let deferred = stringGrip._fullText = promise.defer(); + let { actor, initial, length } = stringGrip; + let longStringClient = this.longString(stringGrip); + + longStringClient.substring(initial.length, length, aResponse => { + if (aResponse.error) { + DevToolsUtils.reportException("getString", + aResponse.error + ": " + aResponse.message); + + deferred.reject(aResponse); + return; + } + deferred.resolve(initial + aResponse.substring); + }); + + return deferred.promise; + } + }; + + +/***/ }, +/* 93 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const { Services } = __webpack_require__(40); + const EventEmitter = __webpack_require__(70); + + /** + * Shortcuts for lazily accessing and setting various preferences. + * Usage: + * let prefs = new Prefs("root.path.to.branch", { + * myIntPref: ["Int", "leaf.path.to.my-int-pref"], + * myCharPref: ["Char", "leaf.path.to.my-char-pref"], + * myJsonPref: ["Json", "leaf.path.to.my-json-pref"], + * myFloatPref: ["Float", "leaf.path.to.my-float-pref"] + * ... + * }); + * + * Get/set: + * prefs.myCharPref = "foo"; + * let aux = prefs.myCharPref; + * + * Observe: + * prefs.registerObserver(); + * prefs.on("pref-changed", (prefName, prefValue) => { + * ... + * }); + * + * @param string prefsRoot + * The root path to the required preferences branch. + * @param object prefsBlueprint + * An object containing { accessorName: [prefType, prefName] } keys. + */ + function PrefsHelper(prefsRoot = "", prefsBlueprint = {}) { + EventEmitter.decorate(this); + + let cache = new Map(); + + for (let accessorName in prefsBlueprint) { + let [prefType, prefName] = prefsBlueprint[accessorName]; + map(this, cache, accessorName, prefType, prefsRoot, prefName); + } + + let observer = makeObserver(this, cache, prefsRoot, prefsBlueprint); + this.registerObserver = () => observer.register(); + this.unregisterObserver = () => observer.unregister(); + } + + /** + * Helper method for getting a pref value. + * + * @param Map cache + * @param string prefType + * @param string prefsRoot + * @param string prefName + * @return any + */ + function get(cache, prefType, prefsRoot, prefName) { + let cachedPref = cache.get(prefName); + if (cachedPref !== undefined) { + return cachedPref; + } + let value = Services.prefs["get" + prefType + "Pref"]( + [prefsRoot, prefName].join(".") + ); + cache.set(prefName, value); + return value; + } + + /** + * Helper method for setting a pref value. + * + * @param Map cache + * @param string prefType + * @param string prefsRoot + * @param string prefName + * @param any value + */ + function set(cache, prefType, prefsRoot, prefName, value) { + Services.prefs["set" + prefType + "Pref"]( + [prefsRoot, prefName].join("."), + value + ); + cache.set(prefName, value); + } + + /** + * Maps a property name to a pref, defining lazy getters and setters. + * Supported types are "Bool", "Char", "Int", "Float" (sugar around "Char" + * type and casting), and "Json" (which is basically just sugar for "Char" + * using the standard JSON serializer). + * + * @param PrefsHelper self + * @param Map cache + * @param string accessorName + * @param string prefType + * @param string prefsRoot + * @param string prefName + * @param array serializer [optional] + */ + function map(self, cache, accessorName, prefType, prefsRoot, prefName, + serializer = { in: e => e, out: e => e }) { + if (prefName in self) { + throw new Error(`Can't use ${prefName} because it overrides a property` + + "on the instance."); + } + if (prefType == "Json") { + map(self, cache, accessorName, "Char", prefsRoot, prefName, { + in: JSON.parse, + out: JSON.stringify + }); + return; + } + if (prefType == "Float") { + map(self, cache, accessorName, "Char", prefsRoot, prefName, { + in: Number.parseFloat, + out: (n) => n + "" + }); + return; + } + + Object.defineProperty(self, accessorName, { + get: () => serializer.in(get(cache, prefType, prefsRoot, prefName)), + set: (e) => set(cache, prefType, prefsRoot, prefName, serializer.out(e)) + }); + } + + /** + * Finds the accessor for the provided pref, based on the blueprint object + * used in the constructor. + * + * @param PrefsHelper self + * @param object prefsBlueprint + * @return string + */ + function accessorNameForPref(somePrefName, prefsBlueprint) { + for (let accessorName in prefsBlueprint) { + let [, prefName] = prefsBlueprint[accessorName]; + if (somePrefName == prefName) { + return accessorName; + } + } + return ""; + } + + /** + * Creates a pref observer for `self`. + * + * @param PrefsHelper self + * @param Map cache + * @param string prefsRoot + * @param object prefsBlueprint + * @return object + */ + function makeObserver(self, cache, prefsRoot, prefsBlueprint) { + return { + register: function() { + this._branch = Services.prefs.getBranch(prefsRoot + "."); + this._branch.addObserver("", this, false); + }, + unregister: function() { + this._branch.removeObserver("", this); + }, + observe: function(subject, topic, prefName) { + // If this particular pref isn't handled by the blueprint object, + // even though it's in the specified branch, ignore it. + let accessorName = accessorNameForPref(prefName, prefsBlueprint); + if (!(accessorName in self)) { + return; + } + cache.delete(prefName); + self.emit("pref-changed", accessorName, self[accessorName]); + } + }; + } + + exports.PrefsHelper = PrefsHelper; + + +/***/ }, +/* 94 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const promise = __webpack_require__(76); + const EventEmitter = __webpack_require__(70); + + /* const { DebuggerServer } = require("../../server/main");*/ + const { DebuggerClient } = __webpack_require__(89); + + const targets = new WeakMap(); + const promiseTargets = new WeakMap(); + + /** + * Functions for creating Targets + */ + exports.TargetFactory = { + /** + * Construct a Target + * @param {XULTab} tab + * The tab to use in creating a new target. + * + * @return A target object + */ + forTab: function(tab) { + let target = targets.get(tab); + if (target == null) { + target = new TabTarget(tab); + targets.set(tab, target); + } + return target; + }, + + /** + * Return a promise of a Target for a remote tab. + * @param {Object} options + * The options object has the following properties: + * { + * form: the remote protocol form of a tab, + * client: a DebuggerClient instance + * (caller owns this and is responsible for closing), + * chrome: true if the remote target is the whole process + * } + * + * @return A promise of a target object + */ + forRemoteTab: function(options) { + let targetPromise = promiseTargets.get(options); + if (targetPromise == null) { + let target = new TabTarget(options); + targetPromise = target.makeRemote().then(() => target); + promiseTargets.set(options, targetPromise); + } + return targetPromise; + }, + + forWorker: function(workerClient) { + let target = targets.get(workerClient); + if (target == null) { + target = new WorkerTarget(workerClient); + targets.set(workerClient, target); + } + return target; + }, + + /** + * Creating a target for a tab that is being closed is a problem because it + * allows a leak as a result of coming after the close event which normally + * clears things up. This function allows us to ask if there is a known + * target for a tab without creating a target + * @return true/false + */ + isKnownTab: function(tab) { + return targets.has(tab); + }, + }; + + /** + * A Target represents something that we can debug. Targets are generally + * read-only. Any changes that you wish to make to a target should be done via + * a Tool that attaches to the target. i.e. a Target is just a pointer saying + * "the thing to debug is over there". + * + * Providing a generalized abstraction of a web-page or web-browser (available + * either locally or remotely) is beyond the scope of this class (and maybe + * also beyond the scope of this universe) However Target does attempt to + * abstract some common events and read-only properties common to many Tools. + * + * Supported read-only properties: + * - name, isRemote, url + * + * Target extends EventEmitter and provides support for the following events: + * - close: The target window has been closed. All tools attached to this + * target should close. This event is not currently cancelable. + * - navigate: The target window has navigated to a different URL + * + * Optional events: + * - will-navigate: The target window will navigate to a different URL + * - hidden: The target is not visible anymore (for TargetTab, another tab is + * selected) + * - visible: The target is visible (for TargetTab, tab is selected) + * + * Comparing Targets: 2 instances of a Target object can point at the same + * thing, so t1 !== t2 and t1 != t2 even when they represent the same object. + * To compare to targets use 't1.equals(t2)'. + */ + + /** + * A TabTarget represents a page living in a browser tab. Generally these will + * be web pages served over http(s), but they don't have to be. + */ + function TabTarget(tab) { + EventEmitter.decorate(this); + this.destroy = this.destroy.bind(this); + this._handleThreadState = this._handleThreadState.bind(this); + this.on("thread-resumed", this._handleThreadState); + this.on("thread-paused", this._handleThreadState); + this.activeTab = this.activeConsole = null; + // Only real tabs need initialization here. Placeholder objects for remote + // targets will be initialized after a makeRemote method call. + if (tab && !["client", "form", "chrome"].every(tab.hasOwnProperty, tab)) { + this._tab = tab; + this._setupListeners(); + } else { + this._form = tab.form; + this._client = tab.client; + this._chrome = tab.chrome; + } + // Default isTabActor to true if not explicitly specified + if (typeof tab.isTabActor == "boolean") { + this._isTabActor = tab.isTabActor; + } else { + this._isTabActor = true; + } + } + + TabTarget.prototype = { + _webProgressListener: null, + + /** + * Returns a promise for the protocol description from the root actor. Used + * internally with `target.actorHasMethod`. Takes advantage of caching if + * definition was fetched previously with the corresponding actor information. + * Actors are lazily loaded, so not only must the tool using a specific actor + * be in use, the actors are only registered after invoking a method (for + * performance reasons, added in bug 988237), so to use these actor detection + * methods, one must already be communicating with a specific actor of that + * type. + * + * Must be a remote target. + * + * @return {Promise} + * { + * "category": "actor", + * "typeName": "longstractor", + * "methods": [{ + * "name": "substring", + * "request": { + * "type": "substring", + * "start": { + * "_arg": 0, + * "type": "primitive" + * }, + * "end": { + * "_arg": 1, + * "type": "primitive" + * } + * }, + * "response": { + * "substring": { + * "_retval": "primitive" + * } + * } + * }], + * "events": {} + * } + */ + getActorDescription: function(actorName) { + if (!this.client) { + throw new Error("TabTarget#getActorDescription() can only be called on " + + "remote tabs."); + } + + let deferred = promise.defer(); + + if (this._protocolDescription && + this._protocolDescription.types[actorName]) { + deferred.resolve(this._protocolDescription.types[actorName]); + } else { + this.client.mainRoot.protocolDescription(description => { + this._protocolDescription = description; + deferred.resolve(description.types[actorName]); + }); + } + + return deferred.promise; + }, + + /** + * Returns a boolean indicating whether or not the specific actor + * type exists. Must be a remote target. + * + * @param {String} actorName + * @return {Boolean} + */ + hasActor: function(actorName) { + if (!this.client) { + throw new Error("TabTarget#hasActor() can only be called on remote " + + "tabs."); + } + if (this.form) { + return !!this.form[actorName + "Actor"]; + } + return false; + }, + + /** + * Queries the protocol description to see if an actor has + * an available method. The actor must already be lazily-loaded (read + * the restrictions in the `getActorDescription` comments), + * so this is for use inside of tool. Returns a promise that + * resolves to a boolean. Must be a remote target. + * + * @param {String} actorName + * @param {String} methodName + * @return {Promise} + */ + actorHasMethod: function(actorName, methodName) { + if (!this.client) { + throw new Error("TabTarget#actorHasMethod() can only be called on " + + "remote tabs."); + } + return this.getActorDescription(actorName).then(desc => { + if (desc && desc.methods) { + return !!desc.methods.find(method => method.name === methodName); + } + return false; + }); + }, + + /** + * Returns a trait from the root actor. + * + * @param {String} traitName + * @return {Mixed} + */ + getTrait: function(traitName) { + if (!this.client) { + throw new Error("TabTarget#getTrait() can only be called on remote " + + "tabs."); + } + + // If the targeted actor exposes traits and has a defined value for this + // traits, override the root actor traits + if (this.form.traits && traitName in this.form.traits) { + return this.form.traits[traitName]; + } + + return this.client.traits[traitName]; + }, + + get tab() { + return this._tab; + }, + + get form() { + return this._form; + }, + + // Get a promise of the root form returned by a listTabs request. This promise + // is cached. + get root() { + if (!this._root) { + this._root = this._getRoot(); + } + return this._root; + }, + + _getRoot: function() { + return new Promise((resolve, reject) => { + this.client.listTabs(response => { + if (response.error) { + reject(new Error(response.error + ": " + response.message)); + return; + } + + resolve(response); + }); + }); + }, + + get client() { + return this._client; + }, + + // Tells us if we are debugging content document + // or if we are debugging chrome stuff. + // Allows to controls which features are available against + // a chrome or a content document. + get chrome() { + return this._chrome; + }, + + // Tells us if the related actor implements TabActor interface + // and requires to call `attach` request before being used + // and `detach` during cleanup + get isTabActor() { + return this._isTabActor; + }, + + get window() { + // XXX - this is a footgun for e10s - there .contentWindow will be null, + // and even though .contentWindowAsCPOW *might* work, it will not work + // in all contexts. Consumers of .window need to be refactored to not + // rely on this. + // if (Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) { + // console.error("The .window getter on devtools' |target| object isn't " + + // "e10s friendly!\n" + Error().stack); + // } + // Be extra careful here, since this may be called by HS_getHudByWindow + // during shutdown. + if (this._tab && this._tab.linkedBrowser) { + return this._tab.linkedBrowser.contentWindow; + } + return null; + }, + + get name() { + if (this._tab && this._tab.linkedBrowser.contentDocument) { + return this._tab.linkedBrowser.contentDocument.title; + } + if (this.isAddon) { + return this._form.name; + } + return this._form.title; + }, + + get url() { + return this._tab ? this._tab.linkedBrowser.currentURI.spec : + this._form.url; + }, + + get isRemote() { + return !this.isLocalTab; + }, + + get isAddon() { + return !!(this._form && this._form.actor && + this._form.actor.match(/conn\d+\.addon\d+/)); + }, + + get isLocalTab() { + return !!this._tab; + }, + + get isMultiProcess() { + return !this.window; + }, + + get isThreadPaused() { + return !!this._isThreadPaused; + }, + + /** + * Adds remote protocol capabilities to the target, so that it can be used + * for tools that support the Remote Debugging Protocol even for local + * connections. + */ + makeRemote: function() { + if (this._remote) { + return this._remote.promise; + } + + this._remote = promise.defer(); + + if (this.isLocalTab) { + // Since a remote protocol connection will be made, let's start the + // DebuggerServer here, once and for all tools. + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + this._client = new DebuggerClient(DebuggerServer.connectPipe()); + // A local TabTarget will never perform chrome debugging. + this._chrome = false; + } + + this._setupRemoteListeners(); + + let attachTab = () => { + this._client.attachTab(this._form.actor, (response, tabClient) => { + if (!tabClient) { + this._remote.reject("Unable to attach to the tab"); + return; + } + this.activeTab = tabClient; + this.threadActor = response.threadActor; + attachConsole(); + }); + }; + + let onConsoleAttached = (response, consoleClient) => { + if (!consoleClient) { + this._remote.reject("Unable to attach to the console"); + return; + } + this.activeConsole = consoleClient; + this._remote.resolve(null); + }; + + let attachConsole = () => { + this._client.attachConsole(this._form.consoleActor, + [ "NetworkActivity" ], + onConsoleAttached); + }; + + if (this.isLocalTab) { + this._client.connect(() => { + this._client.getTab({ tab: this.tab }).then(response => { + this._form = response.tab; + attachTab(); + }); + }); + } else if (this.isTabActor) { + // In the remote debugging case, the protocol connection will have been + // already initialized in the connection screen code. + attachTab(); + } else { + // AddonActor and chrome debugging on RootActor doesn't inherits from + // TabActor and doesn't need to be attached. + attachConsole(); + } + + return this._remote.promise; + }, + + /** + * Listen to the different events. + */ + _setupListeners: function() { + this._webProgressListener = new TabWebProgressListener(this); + this.tab.linkedBrowser.addProgressListener(this._webProgressListener); + this.tab.addEventListener("TabClose", this); + this.tab.parentNode.addEventListener("TabSelect", this); + this.tab.ownerDocument.defaultView.addEventListener("unload", this); + }, + + /** + * Teardown event listeners. + */ + _teardownListeners: function() { + if (this._webProgressListener) { + this._webProgressListener.destroy(); + } + + this._tab.ownerDocument.defaultView.removeEventListener("unload", this); + this._tab.removeEventListener("TabClose", this); + this._tab.parentNode.removeEventListener("TabSelect", this); + }, + + /** + * Setup listeners for remote debugging, updating existing ones as necessary. + */ + _setupRemoteListeners: function() { + this.client.addListener("closed", this.destroy); + + this._onTabDetached = (aType, aPacket) => { + // We have to filter message to ensure that this detach is for this tab + if (aPacket.from == this._form.actor) { + this.destroy(); + } + }; + this.client.addListener("tabDetached", this._onTabDetached); + + this._onTabNavigated = (aType, aPacket) => { + let event = Object.create(null); + event.url = aPacket.url; + event.title = aPacket.title; + event.nativeConsoleAPI = aPacket.nativeConsoleAPI; + event.isFrameSwitching = aPacket.isFrameSwitching; + // Send any stored event payload (DOMWindow or nsIRequest) for backwards + // compatibility with non-remotable tools. + if (aPacket.state == "start") { + event._navPayload = this._navRequest; + this.emit("will-navigate", event); + this._navRequest = null; + } else { + event._navPayload = this._navWindow; + this.emit("navigate", event); + this._navWindow = null; + } + }; + this.client.addListener("tabNavigated", this._onTabNavigated); + + this._onFrameUpdate = (aType, aPacket) => { + this.emit("frame-update", aPacket); + }; + this.client.addListener("frameUpdate", this._onFrameUpdate); + }, + + /** + * Teardown listeners for remote debugging. + */ + _teardownRemoteListeners: function() { + this.client.removeListener("closed", this.destroy); + this.client.removeListener("tabNavigated", this._onTabNavigated); + this.client.removeListener("tabDetached", this._onTabDetached); + this.client.removeListener("frameUpdate", this._onFrameUpdate); + }, + + /** + * Handle tabs events. + */ + handleEvent: function(event) { + switch (event.type) { + case "TabClose": + case "unload": + this.destroy(); + break; + case "TabSelect": + if (this.tab.selected) { + this.emit("visible", event); + } else { + this.emit("hidden", event); + } + break; + } + }, + + /** + * Handle script status. + */ + _handleThreadState: function(event) { + switch (event) { + case "thread-resumed": + this._isThreadPaused = false; + break; + case "thread-paused": + this._isThreadPaused = true; + break; + } + }, + + /** + * Target is not alive anymore. + */ + destroy: function() { + // If several things call destroy then we give them all the same + // destruction promise so we're sure to destroy only once + if (this._destroyer) { + return this._destroyer.promise; + } + + this._destroyer = promise.defer(); + + // Before taking any action, notify listeners that destruction is imminent. + this.emit("close"); + + // First of all, do cleanup tasks that pertain to both remoted and + // non-remoted targets. + this.off("thread-resumed", this._handleThreadState); + this.off("thread-paused", this._handleThreadState); + + if (this._tab) { + this._teardownListeners(); + } + + let cleanupAndResolve = () => { + this._cleanup(); + this._destroyer.resolve(null); + }; + // If this target was not remoted, the promise will be resolved before the + // function returns. + if (this._tab && !this._client) { + cleanupAndResolve(); + } else if (this._client) { + // If, on the other hand, this target was remoted, the promise will be + // resolved after the remote connection is closed. + this._teardownRemoteListeners(); + + if (this.isLocalTab) { + // We started with a local tab and created the client ourselves, so we + // should close it. + this._client.close(cleanupAndResolve); + } else if (this.activeTab) { + // The client was handed to us, so we are not responsible for closing + // it. We just need to detach from the tab, if already attached. + // |detach| may fail if the connection is already dead, so proceed with + // cleanup directly after this. + this.activeTab.detach(); + cleanupAndResolve(); + } else { + cleanupAndResolve(); + } + } + + return this._destroyer.promise; + }, + + /** + * Clean up references to what this target points to. + */ + _cleanup: function() { + if (this._tab) { + targets.delete(this._tab); + } else { + promiseTargets.delete(this._form); + } + this.activeTab = null; + this.activeConsole = null; + this._client = null; + this._tab = null; + this._form = null; + this._remote = null; + }, + + toString: function() { + let id = this._tab ? this._tab : (this._form && this._form.actor); + return `TabTarget:${id}`; + }, + }; + + function WorkerTarget(workerClient) { + EventEmitter.decorate(this); + this._workerClient = workerClient; + } + + /** + * A WorkerTarget represents a worker. Unlike TabTarget, which can represent + * either a local or remote tab, WorkerTarget always represents a remote worker. + * Moreover, unlike TabTarget, which is constructed with a placeholder object + * for remote tabs (from which a TabClient can then be lazily obtained), + * WorkerTarget is constructed with a WorkerClient directly. + * + * WorkerClient is designed to mimic the interface of TabClient as closely as + * possible. This allows us to debug workers as if they were ordinary tabs, + * requiring only minimal changes to the rest of the frontend. + */ + WorkerTarget.prototype = { + destroy: function() {}, + + get isRemote() { + return true; + }, + + get isTabActor() { + return true; + }, + + get url() { + return this._workerClient.url; + }, + + get isWorkerTarget() { + return true; + }, + + get form() { + return { + consoleActor: this._workerClient.consoleActor + }; + }, + + get activeTab() { + return this._workerClient; + }, + + get client() { + return this._workerClient.client; + }, + + destroy: function() {}, + + hasActor: function(name) { + return false; + }, + + getTrait: function() { + return undefined; + }, + + makeRemote: function() { + return Promise.resolve(); + } + }; + + +/***/ }, +/* 95 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + const EventEmitter = __webpack_require__(70); + + function WebSocketDebuggerTransport(socket) { + EventEmitter.decorate(this); + + this.active = false; + this.hooks = null; + this.socket = socket; + } + + WebSocketDebuggerTransport.prototype = { + ready() { + if (this.active) { + return; + } + + this.socket.addEventListener("message", this); + this.socket.addEventListener("close", this); + + this.active = true; + }, + + send(object) { + this.emit("send", object); + if (this.socket) { + this.socket.send(JSON.stringify(object)); + } + }, + + startBulkSend() { + throw new Error("Bulk send is not supported by WebSocket transport"); + }, + + close() { + this.emit("close"); + this.active = false; + + this.socket.removeEventListener("message", this); + this.socket.removeEventListener("close", this); + this.socket.close(); + this.socket = null; + + if (this.hooks) { + this.hooks.onClosed(); + this.hooks = null; + } + }, + + handleEvent(event) { + switch (event.type) { + case "message": + this.onMessage(event); + break; + case "close": + this.close(); + break; + } + }, + + onMessage({ data }) { + if (typeof data !== "string") { + throw new Error("Binary messages are not supported by WebSocket transport"); + } + + let object = JSON.parse(data); + this.emit("packet", object); + if (this.hooks) { + this.hooks.onPacket(object); + } + }, + }; + + module.exports = WebSocketDebuggerTransport; + + +/***/ }, +/* 96 */ +/***/ function(module, exports, __webpack_require__) { + + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + const EventEmitter = __webpack_require__(70); + + /** + * A partial implementation of the Menu API provided by electron: + * https://github.com/electron/electron/blob/master/docs/api/menu.md. + * + * Extra features: + * - Emits an 'open' and 'close' event when the menu is opened/closed + + * @param String id (non standard) + * Needed so tests can confirm the XUL implementation is working + */ + function Menu({ id = null } = {}) { + this.menuitems = []; + this.id = id; + + Object.defineProperty(this, "items", { + get() { + return this.menuitems; + } + }); + + EventEmitter.decorate(this); + } + + /** + * Add an item to the end of the Menu + * + * @param {MenuItem} menuItem + */ + Menu.prototype.append = function (menuItem) { + this.menuitems.push(menuItem); + }; + + /** + * Add an item to a specified position in the menu + * + * @param {int} pos + * @param {MenuItem} menuItem + */ + Menu.prototype.insert = function (pos, menuItem) { + throw Error("Not implemented"); + }; + + /** + * Show the Menu at a specified location on the screen + * + * Missing features: + * - browserWindow - BrowserWindow (optional) - Default is null. + * - positioningItem Number - (optional) OS X + * + * @param {int} screenX + * @param {int} screenY + * @param Toolbox toolbox (non standard) + * Needed so we in which window to inject XUL + */ + Menu.prototype.popup = function (screenX, screenY, toolbox) { + let doc = toolbox.doc; + let popupset = doc.querySelector("popupset"); + // See bug 1285229, on Windows, opening the same popup multiple times in a + // row ends up duplicating the popup. The newly inserted popup doesn't + // dismiss the old one. So remove any previously displayed popup before + // opening a new one. + let popup = popupset.querySelector("menupopup[menu-api=\"true\"]"); + if (popup) { + popup.hidePopup(); + } + + popup = this.createPopup(doc) + popup.setAttribute("menu-api", "true"); + + if (this.id) { + popup.id = this.id; + } + this._createMenuItems(popup); + + // Remove the menu from the DOM once it's hidden. + popup.addEventListener("popuphidden", (e) => { + if (e.target === popup) { + popup.remove(); + this.emit("close", popup); + } + }); + + popup.addEventListener("popupshown", (e) => { + if (e.target === popup) { + this.emit("open", popup); + } + }); + + popupset.appendChild(popup); + popup.openPopupAtScreen(screenX, screenY, true); + }; + + Menu.prototype.createPopup = function(doc) { + return doc.createElement("menupopup"); + } + + Menu.prototype._createMenuItems = function (parent) { + let doc = parent.ownerDocument; + this.menuitems.forEach(item => { + if (!item.visible) { + return; + } + + if (item.submenu) { + let menupopup = doc.createElement("menupopup"); + item.submenu._createMenuItems(menupopup); + + let menu = doc.createElement("menu"); + menu.appendChild(menupopup); + menu.setAttribute("label", item.label); + if (item.disabled) { + menu.setAttribute("disabled", "true"); + } + if (item.accesskey) { + menu.setAttribute("accesskey", item.accesskey); + } + if (item.id) { + menu.id = item.id; + } + parent.appendChild(menu); + } else if (item.type === "separator") { + let menusep = doc.createElement("menuseparator"); + parent.appendChild(menusep); + } else { + let menuitem = doc.createElement("menuitem"); + menuitem.setAttribute("label", item.label); + menuitem.textContent = item.label; + menuitem.addEventListener("command", () => item.click()); + + if (item.type === "checkbox") { + menuitem.setAttribute("type", "checkbox"); + } + if (item.type === "radio") { + menuitem.setAttribute("type", "radio"); + } + if (item.disabled) { + menuitem.setAttribute("disabled", "true"); + } + if (item.checked) { + menuitem.setAttribute("checked", "true"); + } + if (item.accesskey) { + menuitem.setAttribute("accesskey", item.accesskey); + } + if (item.id) { + menuitem.id = item.id; + } + + parent.appendChild(menuitem); + } + }); + }; + + Menu.setApplicationMenu = () => { + throw Error("Not implemented"); + }; + + Menu.sendActionToFirstResponder = () => { + throw Error("Not implemented"); + }; + + Menu.buildFromTemplate = () => { + throw Error("Not implemented"); + }; + + module.exports = Menu; + + +/***/ }, +/* 97 */ +/***/ function(module, exports) { + + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + /** + * A partial implementation of the MenuItem API provided by electron: + * https://github.com/electron/electron/blob/master/docs/api/menu-item.md. + * + * Missing features: + * - id String - Unique within a single menu. If defined then it can be used + * as a reference to this item by the position attribute. + * - role String - Define the action of the menu item; when specified the + * click property will be ignored + * - sublabel String + * - accelerator Accelerator + * - icon NativeImage + * - position String - This field allows fine-grained definition of the + * specific location within a given menu. + * + * Implemented features: + * @param Object options + * Function click + * Will be called with click(menuItem, browserWindow) when the menu item + * is clicked + * String type + * Can be normal, separator, submenu, checkbox or radio + * String label + * Boolean enabled + * If false, the menu item will be greyed out and unclickable. + * Boolean checked + * Should only be specified for checkbox or radio type menu items. + * Menu submenu + * Should be specified for submenu type menu items. If submenu is specified, + * the type: 'submenu' can be omitted. If the value is not a Menu then it + * will be automatically converted to one using Menu.buildFromTemplate. + * Boolean visible + * If false, the menu item will be entirely hidden. + */ + function MenuItem({ + accesskey = null, + checked = false, + click = () => {}, + disabled = false, + label = "", + id = null, + submenu = null, + type = "normal", + visible = true, + } = { }) { + this.accesskey = accesskey; + this.checked = checked; + this.click = click; + this.disabled = disabled; + this.id = id; + this.label = label; + this.submenu = submenu; + this.type = type; + this.visible = visible; + } + + module.exports = MenuItem; + + +/***/ }, +/* 98 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + const { DOM: dom, createClass, createFactory, PropTypes } = __webpack_require__(6); + // const { ViewHelpers } = + // require("resource://devtools/client/shared/widgets/ViewHelpers.jsm"); + // let { VirtualScroll } = require("react-virtualized"); + // VirtualScroll = createFactory(VirtualScroll); + + const AUTO_EXPAND_DEPTH = 0; // depth + + /** + * An arrow that displays whether its node is expanded (▼) or collapsed + * (▶). When its node has no children, it is hidden. + */ + const ArrowExpander = createFactory(createClass({ + displayName: "ArrowExpander", + + shouldComponentUpdate(nextProps, nextState) { + return this.props.item !== nextProps.item + || this.props.visible !== nextProps.visible + || this.props.expanded !== nextProps.expanded; + }, + + render() { + const attrs = { + className: "arrow theme-twisty", + onClick: this.props.expanded + ? () => this.props.onCollapse(this.props.item) + : e => this.props.onExpand(this.props.item, e.altKey) + }; + + if (this.props.expanded) { + attrs.className += " open"; + } + + if (!this.props.visible) { + attrs.style = Object.assign({}, this.props.style || {}, { + visibility: "hidden" + }); + } + + return dom.div(attrs, this.props.children); + } + })); + + const TreeNode = createFactory(createClass({ + displayName: "TreeNode", + + componentDidMount() { + if (this.props.focused) { + this.refs.button.focus(); + } + }, + + componentDidUpdate() { + if (this.props.focused) { + this.refs.button.focus(); + } + }, + + shouldComponentUpdate(nextProps) { + return this.props.item !== nextProps.item || + this.props.focused !== nextProps.focused || + this.props.expanded !== nextProps.expanded; + }, + + render() { + const arrow = ArrowExpander({ + item: this.props.item, + expanded: this.props.expanded, + visible: this.props.hasChildren, + onExpand: this.props.onExpand, + onCollapse: this.props.onCollapse, + }); + + let isOddRow = this.props.index % 2; + return dom.div( + { + className: `tree-node div ${isOddRow ? "tree-node-odd" : ""}`, + onFocus: this.props.onFocus, + onClick: this.props.onFocus, + onBlur: this.props.onBlur, + style: { + padding: 0, + margin: 0 + } + }, + + this.props.renderItem(this.props.item, + this.props.depth, + this.props.focused, + arrow, + this.props.expanded), + + // XXX: OSX won't focus/blur regular elements even if you set tabindex + // unless there is an input/button child. + dom.button(this._buttonAttrs) + ); + }, + + _buttonAttrs: { + ref: "button", + style: { + opacity: 0, + width: "0 !important", + height: "0 !important", + padding: "0 !important", + outline: "none", + MozAppearance: "none", + // XXX: Despite resetting all of the above properties (and margin), the + // button still ends up with ~79px width, so we set a large negative + // margin to completely hide it. + MozMarginStart: "-1000px !important", + } + } + })); + + /** + * Create a function that calls the given function `fn` only once per animation + * frame. + * + * @param {Function} fn + * @returns {Function} + */ + function oncePerAnimationFrame(fn) { + let animationId = null; + let argsToPass = null; + return function(...args) { + argsToPass = args; + if (animationId !== null) { + return; + } + + animationId = requestAnimationFrame(() => { + fn.call(this, ...argsToPass); + animationId = null; + argsToPass = null; + }); + }; + } + + const NUMBER_OF_OFFSCREEN_ITEMS = 1; + + /** + * A generic tree component. See propTypes for the public API. + * + * @see `devtools/client/memory/components/test/mochitest/head.js` for usage + * @see `devtools/client/memory/components/heap.js` for usage + */ + const Tree = module.exports = createClass({ + displayName: "Tree", + + propTypes: { + // Required props + + // A function to get an item's parent, or null if it is a root. + getParent: PropTypes.func.isRequired, + // A function to get an item's children. + getChildren: PropTypes.func.isRequired, + // A function which takes an item and ArrowExpander and returns a + // component. + renderItem: PropTypes.func.isRequired, + // A function which returns the roots of the tree (forest). + getRoots: PropTypes.func.isRequired, + // A function to get a unique key for the given item. + getKey: PropTypes.func.isRequired, + // A function to get whether an item is expanded or not. If an item is not + // expanded, then it must be collapsed. + isExpanded: PropTypes.func.isRequired, + // The height of an item in the tree including margin and padding, in + // pixels. + itemHeight: PropTypes.number.isRequired, + + // Optional props + + // The currently focused item, if any such item exists. + focused: PropTypes.any, + // Handle when a new item is focused. + onFocus: PropTypes.func, + // The depth to which we should automatically expand new items. + autoExpandDepth: PropTypes.number, + // Should auto expand all new items or just the new items under the first + // root item. + autoExpandAll: PropTypes.bool, + // Optional event handlers for when items are expanded or collapsed. + onExpand: PropTypes.func, + onCollapse: PropTypes.func, + }, + + getDefaultProps() { + return { + autoExpandDepth: AUTO_EXPAND_DEPTH, + autoExpandAll: true + }; + }, + + getInitialState() { + return { + scroll: 0, + height: window.innerHeight, + seen: new Set(), + }; + }, + + componentDidMount() { + window.addEventListener("resize", this._updateHeight); + this._autoExpand(this.props); + this._updateHeight(); + }, + + componentWillUnmount() { + window.removeEventListener("resize", this._updateHeight); + }, + + componentWillReceiveProps(nextProps) { + this._autoExpand(nextProps); + this._updateHeight(); + }, + + _autoExpand(props) { + if (!props.autoExpandDepth) { + return; + } + + // Automatically expand the first autoExpandDepth levels for new items. Do + // not use the usual DFS infrastructure because we don't want to ignore + // collapsed nodes. + const autoExpand = (item, currentDepth) => { + if (currentDepth >= props.autoExpandDepth || + this.state.seen.has(item)) { + return; + } + + props.onExpand(item); + this.state.seen.add(item); + + const children = props.getChildren(item); + const length = children.length; + for (let i = 0; i < length; i++) { + autoExpand(children[i], currentDepth + 1); + } + }; + + const roots = props.getRoots(); + const length = roots.length; + if (props.autoExpandAll) { + for (let i = 0; i < length; i++) { + autoExpand(roots[i], 0); + } + } else if (length != 0) { + autoExpand(roots[0], 0); + } + }, + + render() { + const traversal = this._dfsFromRoots(); + + // Remove `NUMBER_OF_OFFSCREEN_ITEMS` from `begin` and add `2 * + // NUMBER_OF_OFFSCREEN_ITEMS` to `end` so that the top and bottom of the + // page are filled with the `NUMBER_OF_OFFSCREEN_ITEMS` previous and next + // items respectively, rather than whitespace if the item is not in full + // view. + // const begin = Math.max(((this.state.scroll / this.props.itemHeight) | 0) - NUMBER_OF_OFFSCREEN_ITEMS, 0); + // const end = begin + (2 * NUMBER_OF_OFFSCREEN_ITEMS) + ((this.state.height / this.props.itemHeight) | 0); + // const toRender = traversal; + + // const nodes = [ + // dom.div({ + // key: "top-spacer", + // style: { + // padding: 0, + // margin: 0, + // height: begin * this.props.itemHeight + "px" + // } + // }) + // ]; + + const renderItem = i => { + let { item, depth } = traversal[i]; + return TreeNode({ + key: this.props.getKey(item, i), + index: i, + item: item, + depth: depth, + renderItem: this.props.renderItem, + focused: this.props.focused === item, + expanded: this.props.isExpanded(item), + hasChildren: !!this.props.getChildren(item).length, + onExpand: this._onExpand, + onCollapse: this._onCollapse, + onFocus: () => this._focus(i, item), + }); + }; + + // nodes.push(dom.div({ + // key: "bottom-spacer", + // style: { + // padding: 0, + // margin: 0, + // height: (traversal.length - 1 - end) * this.props.itemHeight + "px" + // } + // })); + + const style = Object.assign({}, this.props.style || {}, { + padding: 0, + margin: 0 + }); + + return dom.div( + { + className: "tree", + ref: "tree", + onKeyDown: this._onKeyDown, + onKeyPress: this._preventArrowKeyScrolling, + onKeyUp: this._preventArrowKeyScrolling, + onScroll: this._onScroll, + style + }, + // VirtualScroll({ + // width: this.props.width, + // height: this.props.height, + // rowsCount: traversal.length, + // rowHeight: this.props.itemHeight, + // rowRenderer: renderItem + // }) + traversal.map((v, i) => renderItem(i)) + ); + }, + + _preventArrowKeyScrolling(e) { + switch (e.key) { + case "ArrowUp": + case "ArrowDown": + case "ArrowLeft": + case "ArrowRight": + e.preventDefault(); + e.stopPropagation(); + if (e.nativeEvent) { + if (e.nativeEvent.preventDefault) { + e.nativeEvent.preventDefault(); + } + if (e.nativeEvent.stopPropagation) { + e.nativeEvent.stopPropagation(); + } + } + } + }, + + /** + * Updates the state's height based on clientHeight. + */ + _updateHeight() { + this.setState({ + height: this.refs.tree.clientHeight + }); + }, + + /** + * Perform a pre-order depth-first search from item. + */ + _dfs(item, maxDepth = Infinity, traversal = [], _depth = 0) { + traversal.push({ item, depth: _depth }); + + if (!this.props.isExpanded(item)) { + return traversal; + } + + const nextDepth = _depth + 1; + + if (nextDepth > maxDepth) { + return traversal; + } + + const children = this.props.getChildren(item); + const length = children.length; + for (let i = 0; i < length; i++) { + this._dfs(children[i], maxDepth, traversal, nextDepth); + } + + return traversal; + }, + + /** + * Perform a pre-order depth-first search over the whole forest. + */ + _dfsFromRoots(maxDepth = Infinity) { + const traversal = []; + + const roots = this.props.getRoots(); + const length = roots.length; + for (let i = 0; i < length; i++) { + this._dfs(roots[i], maxDepth, traversal); + } + + return traversal; + }, + + /** + * Expands current row. + * + * @param {Object} item + * @param {Boolean} expandAllChildren + */ + _onExpand: oncePerAnimationFrame(function(item, expandAllChildren) { + if (this.props.onExpand) { + this.props.onExpand(item); + + if (expandAllChildren) { + const children = this._dfs(item); + const length = children.length; + for (let i = 0; i < length; i++) { + this.props.onExpand(children[i].item); + } + } + } + }), + + /** + * Collapses current row. + * + * @param {Object} item + */ + _onCollapse: oncePerAnimationFrame(function(item) { + if (this.props.onCollapse) { + this.props.onCollapse(item); + } + }), + + /** + * Sets the passed in item to be the focused item. + * + * @param {Number} index + * The index of the item in a full DFS traversal (ignoring collapsed + * nodes). Ignored if `item` is undefined. + * + * @param {Object|undefined} item + * The item to be focused, or undefined to focus no item. + */ + _focus(index, item) { + if (item !== undefined) { + const itemStartPosition = index * this.props.itemHeight; + const itemEndPosition = (index + 1) * this.props.itemHeight; + + // Note that if the height of the viewport (this.state.height) is less than + // `this.props.itemHeight`, we could accidentally try and scroll both up and + // down in a futile attempt to make both the item's start and end positions + // visible. Instead, give priority to the start of the item by checking its + // position first, and then using an "else if", rather than a separate "if", + // for the end position. + if (this.state.scroll > itemStartPosition) { + this.refs.tree.scrollTop = itemStartPosition; + } else if ((this.state.scroll + this.state.height) < itemEndPosition) { + this.refs.tree.scrollTop = itemEndPosition - this.state.height; + } + } + + if (this.props.onFocus) { + this.props.onFocus(item); + } + }, + + /** + * Sets the state to have no focused item. + */ + _onBlur() { + this._focus(0, undefined); + }, + + /** + * Fired on a scroll within the tree's container, updates + * the stored position of the view port to handle virtual view rendering. + * + * @param {Event} e + */ + _onScroll: oncePerAnimationFrame(function(e) { + this.setState({ + scroll: Math.max(this.refs.tree.scrollTop, 0), + height: this.refs.tree.clientHeight + }); + }), + + /** + * Handles key down events in the tree's container. + * + * @param {Event} e + */ + _onKeyDown(e) { + if (this.props.focused == null) { + return; + } + + // Allow parent nodes to use navigation arrows with modifiers. + if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { + return; + } + + this._preventArrowKeyScrolling(e); + + switch (e.key) { + case "ArrowUp": + this._focusPrevNode(); + return; + + case "ArrowDown": + this._focusNextNode(); + return; + + case "ArrowLeft": + if (this.props.isExpanded(this.props.focused) + && this.props.getChildren(this.props.focused).length) { + this._onCollapse(this.props.focused); + } else { + this._focusParentNode(); + } + return; + + case "ArrowRight": + if (!this.props.isExpanded(this.props.focused)) { + this._onExpand(this.props.focused); + } else { + this._focusNextNode(); + } + return; + } + }, + + /** + * Sets the previous node relative to the currently focused item, to focused. + */ + _focusPrevNode: oncePerAnimationFrame(function() { + // Start a depth first search and keep going until we reach the currently + // focused node. Focus the previous node in the DFS, if it exists. If it + // doesn't exist, we're at the first node already. + + let prev; + let prevIndex; + + const traversal = this._dfsFromRoots(); + const length = traversal.length; + for (let i = 0; i < length; i++) { + const item = traversal[i].item; + if (item === this.props.focused) { + break; + } + prev = item; + prevIndex = i; + } + + if (prev === undefined) { + return; + } + + this._focus(prevIndex, prev); + }), + + /** + * Handles the down arrow key which will focus either the next child + * or sibling row. + */ + _focusNextNode: oncePerAnimationFrame(function() { + // Start a depth first search and keep going until we reach the currently + // focused node. Focus the next node in the DFS, if it exists. If it + // doesn't exist, we're at the last node already. + + const traversal = this._dfsFromRoots(); + const length = traversal.length; + let i = 0; + + while (i < length) { + if (traversal[i].item === this.props.focused) { + break; + } + i++; + } + + if (i + 1 < traversal.length) { + this._focus(i + 1, traversal[i + 1].item); + } + }), + + /** + * Handles the left arrow key, going back up to the current rows' + * parent row. + */ + _focusParentNode: oncePerAnimationFrame(function() { + const parent = this.props.getParent(this.props.focused); + if (!parent) { + return; + } + + const traversal = this._dfsFromRoots(); + const length = traversal.length; + let parentIndex = 0; + for (; parentIndex < length; parentIndex++) { + if (traversal[parentIndex].item === parent) { + break; + } + } + + this._focus(parentIndex, parent); + }), + }); + + +/***/ }, +/* 99 */ +/***/ function(module, exports) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + "use strict"; + + // const { LocalizationHelper } = require("devtools/shared/l10n"); + // + // const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); + // const UNKNOWN_SOURCE_STRING = l10n.getStr("frame.unknownSource"); + + const l10n = { + getStr: () => {} + } + + // Character codes used in various parsing helper functions. + const CHAR_CODE_A = "a".charCodeAt(0); + const CHAR_CODE_C = "c".charCodeAt(0); + const CHAR_CODE_D = "d".charCodeAt(0); + const CHAR_CODE_E = "e".charCodeAt(0); + const CHAR_CODE_F = "f".charCodeAt(0); + const CHAR_CODE_H = "h".charCodeAt(0); + const CHAR_CODE_I = "i".charCodeAt(0); + const CHAR_CODE_J = "j".charCodeAt(0); + const CHAR_CODE_L = "l".charCodeAt(0); + const CHAR_CODE_M = "m".charCodeAt(0); + const CHAR_CODE_O = "o".charCodeAt(0); + const CHAR_CODE_P = "p".charCodeAt(0); + const CHAR_CODE_R = "r".charCodeAt(0); + const CHAR_CODE_S = "s".charCodeAt(0); + const CHAR_CODE_T = "t".charCodeAt(0); + const CHAR_CODE_U = "u".charCodeAt(0); + const CHAR_CODE_COLON = ":".charCodeAt(0); + const CHAR_CODE_SLASH = "/".charCodeAt(0); + const CHAR_CODE_CAP_S = "S".charCodeAt(0); + + // The cache used in the `parseURL` function. + const gURLStore = new Map(); + // The cache used in the `getSourceNames` function. + const gSourceNamesStore = new Map(); + + /** + * Takes a string and returns an object containing all the properties + * available on an URL instance, with additional properties (fileName), + * Leverages caching. + * + * @param {String} location + * @return {Object?} An object containing most properties available + * in https://developer.mozilla.org/en-US/docs/Web/API/URL + */ + + function parseURL(location) { + let url = gURLStore.get(location); + + if (url !== void 0) { + return url; + } + + try { + url = new URL(location); + // The callers were generally written to expect a URL from + // sdk/url, which is subtly different. So, work around some + // important differences here. + url = { + href: url.href, + protocol: url.protocol, + host: url.host, + hostname: url.hostname, + port: url.port || null, + pathname: url.pathname, + search: url.search, + hash: url.hash, + username: url.username, + password: url.password, + origin: url.origin, + }; + + // Definitions: + // Example: https://foo.com:8888/file.js + // `hostname`: "foo.com" + // `host`: "foo.com:8888" + let isChrome = isChromeScheme(location); + + url.fileName = url.pathname ? + (url.pathname.slice(url.pathname.lastIndexOf("/") + 1) || "/") : + "/"; + + if (isChrome) { + url.hostname = null; + url.host = null; + } + + gURLStore.set(location, url); + return url; + } catch (e) { + gURLStore.set(location, null); + return null; + } + } + + /** + * Parse a source into a short and long name as well as a host name. + * + * @param {String} source + * The source to parse. Can be a URI or names like "(eval)" or + * "self-hosted". + * @return {Object} + * An object with the following properties: + * - {String} short: A short name for the source. + * - "http://page.com/test.js#go?q=query" -> "test.js" + * - {String} long: The full, long name for the source, with + hash/query stripped. + * - "http://page.com/test.js#go?q=query" -> "http://page.com/test.js" + * - {String?} host: If available, the host name for the source. + * - "http://page.com/test.js#go?q=query" -> "page.com" + */ + function getSourceNames(source) { + let data = gSourceNamesStore.get(source); + + if (data) { + return data; + } + + let short, long, host; + const sourceStr = source ? String(source) : ""; + + // If `data:...` uri + if (isDataScheme(sourceStr)) { + let commaIndex = sourceStr.indexOf(","); + if (commaIndex > -1) { + // The `short` name for a data URI becomes `data:` followed by the actual + // encoded content, omitting the MIME type, and charset. + short = `data:${sourceStr.substring(commaIndex + 1)}`.slice(0, 100); + let result = { short, long: sourceStr }; + gSourceNamesStore.set(source, result); + return result; + } + } + + // If Scratchpad URI, like "Scratchpad/1"; no modifications, + // and short/long are the same. + if (isScratchpadScheme(sourceStr)) { + let result = { short: sourceStr, long: sourceStr }; + gSourceNamesStore.set(source, result); + return result; + } + + const parsedUrl = parseURL(sourceStr); + + if (!parsedUrl) { + // Malformed URI. + long = sourceStr; + short = sourceStr.slice(0, 100); + } else { + host = parsedUrl.host; + + long = parsedUrl.href; + if (parsedUrl.hash) { + long = long.replace(parsedUrl.hash, ""); + } + if (parsedUrl.search) { + long = long.replace(parsedUrl.search, ""); + } + + short = parsedUrl.fileName; + // If `short` is just a slash, and we actually have a path, + // strip the slash and parse again to get a more useful short name. + // e.g. "http://foo.com/bar/" -> "bar", rather than "/" + if (short === "/" && parsedUrl.pathname !== "/") { + short = parseURL(long.replace(/\/$/, "")).fileName; + } + } + + if (!short) { + if (!long) { + long = UNKNOWN_SOURCE_STRING; + } + short = long.slice(0, 100); + } + + let result = { short, long, host }; + gSourceNamesStore.set(source, result); + return result; + } + + // For the functions below, we assume that we will never access the location + // argument out of bounds, which is indeed the vast majority of cases. + // + // They are written this way because they are hot. Each frame is checked for + // being content or chrome when processing the profile. + + function isColonSlashSlash(location, i = 0) { + return location.charCodeAt(++i) === CHAR_CODE_COLON && + location.charCodeAt(++i) === CHAR_CODE_SLASH && + location.charCodeAt(++i) === CHAR_CODE_SLASH; + } + + /** + * Checks for a Scratchpad URI, like "Scratchpad/1" + */ + function isScratchpadScheme(location, i = 0) { + return location.charCodeAt(i) === CHAR_CODE_CAP_S && + location.charCodeAt(++i) === CHAR_CODE_C && + location.charCodeAt(++i) === CHAR_CODE_R && + location.charCodeAt(++i) === CHAR_CODE_A && + location.charCodeAt(++i) === CHAR_CODE_T && + location.charCodeAt(++i) === CHAR_CODE_C && + location.charCodeAt(++i) === CHAR_CODE_H && + location.charCodeAt(++i) === CHAR_CODE_P && + location.charCodeAt(++i) === CHAR_CODE_A && + location.charCodeAt(++i) === CHAR_CODE_D && + location.charCodeAt(++i) === CHAR_CODE_SLASH; + } + + function isDataScheme(location, i = 0) { + return location.charCodeAt(i) === CHAR_CODE_D && + location.charCodeAt(++i) === CHAR_CODE_A && + location.charCodeAt(++i) === CHAR_CODE_T && + location.charCodeAt(++i) === CHAR_CODE_A && + location.charCodeAt(++i) === CHAR_CODE_COLON; + } + + function isContentScheme(location, i = 0) { + let firstChar = location.charCodeAt(i); + + switch (firstChar) { + // "http://" or "https://" + case CHAR_CODE_H: + if (location.charCodeAt(++i) === CHAR_CODE_T && + location.charCodeAt(++i) === CHAR_CODE_T && + location.charCodeAt(++i) === CHAR_CODE_P) { + if (location.charCodeAt(i + 1) === CHAR_CODE_S) { + ++i; + } + return isColonSlashSlash(location, i); + } + return false; + + // "file://" + case CHAR_CODE_F: + if (location.charCodeAt(++i) === CHAR_CODE_I && + location.charCodeAt(++i) === CHAR_CODE_L && + location.charCodeAt(++i) === CHAR_CODE_E) { + return isColonSlashSlash(location, i); + } + return false; + + // "app://" + case CHAR_CODE_A: + if (location.charCodeAt(++i) == CHAR_CODE_P && + location.charCodeAt(++i) == CHAR_CODE_P) { + return isColonSlashSlash(location, i); + } + return false; + + default: + return false; + } + } + + function isChromeScheme(location, i = 0) { + let firstChar = location.charCodeAt(i); + + switch (firstChar) { + // "chrome://" + case CHAR_CODE_C: + if (location.charCodeAt(++i) === CHAR_CODE_H && + location.charCodeAt(++i) === CHAR_CODE_R && + location.charCodeAt(++i) === CHAR_CODE_O && + location.charCodeAt(++i) === CHAR_CODE_M && + location.charCodeAt(++i) === CHAR_CODE_E) { + return isColonSlashSlash(location, i); + } + return false; + + // "resource://" + case CHAR_CODE_R: + if (location.charCodeAt(++i) === CHAR_CODE_E && + location.charCodeAt(++i) === CHAR_CODE_S && + location.charCodeAt(++i) === CHAR_CODE_O && + location.charCodeAt(++i) === CHAR_CODE_U && + location.charCodeAt(++i) === CHAR_CODE_R && + location.charCodeAt(++i) === CHAR_CODE_C && + location.charCodeAt(++i) === CHAR_CODE_E) { + return isColonSlashSlash(location, i); + } + return false; + + // "jar:file://" + case CHAR_CODE_J: + if (location.charCodeAt(++i) === CHAR_CODE_A && + location.charCodeAt(++i) === CHAR_CODE_R && + location.charCodeAt(++i) === CHAR_CODE_COLON && + location.charCodeAt(++i) === CHAR_CODE_F && + location.charCodeAt(++i) === CHAR_CODE_I && + location.charCodeAt(++i) === CHAR_CODE_L && + location.charCodeAt(++i) === CHAR_CODE_E) { + return isColonSlashSlash(location, i); + } + return false; + + default: + return false; + } + } + + /** + * A utility method to get the file name from a sourcemapped location + * The sourcemap location can be in any form. This method returns a + * formatted file name for different cases like Windows or OSX. + * @param source + * @returns String + */ + function getSourceMappedFile(source) { + // If sourcemapped source is a OSX path, return + // the characters after last "/". + // If sourcemapped source is a Windowss path, return + // the characters after last "\\". + if (source.lastIndexOf("/") >= 0) { + source = source.slice(source.lastIndexOf("/") + 1); + } else if (source.lastIndexOf("\\") >= 0) { + source = source.slice(source.lastIndexOf("\\") + 1); + } + return source; + } + + exports.parseURL = parseURL; + exports.getSourceNames = getSourceNames; + exports.isScratchpadScheme = isScratchpadScheme; + exports.isChromeScheme = isChromeScheme; + exports.isContentScheme = isContentScheme; + exports.isDataScheme = isDataScheme; + exports.getSourceMappedFile = getSourceMappedFile; + + +/***/ }, +/* 100 */ +/***/ function(module, exports, __webpack_require__) { + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + "use strict"; + + const { DOM: dom, createClass, PropTypes } = __webpack_require__(6); + const { getSourceNames, parseURL, + isScratchpadScheme, getSourceMappedFile } = __webpack_require__(99); + // const { LocalizationHelper } = require("devtools/shared/l10n"); + // + // const l10n = new LocalizationHelper("devtools/client/locales/components.properties"); + // const webl10n = new LocalizationHelper("devtools/client/locales/webconsole.properties"); + + const l10n = { getStr: () => {} }; + const webl10n = { getStr: () => {} }; + + module.exports = createClass({ + displayName: "Frame", + + propTypes: { + // SavedFrame, or an object containing all the required properties. + frame: PropTypes.shape({ + functionDisplayName: PropTypes.string, + source: PropTypes.string.isRequired, + line: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), + column: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), + }).isRequired, + // Clicking on the frame link -- probably should link to the debugger. + onClick: PropTypes.func.isRequired, + // Option to display a function name before the source link. + showFunctionName: PropTypes.bool, + // Option to display a function name even if it's anonymous. + showAnonymousFunctionName: PropTypes.bool, + // Option to display a host name after the source link. + showHost: PropTypes.bool, + // Option to display a host name if the filename is empty or just '/' + showEmptyPathAsHost: PropTypes.bool, + // Option to display a full source instead of just the filename. + showFullSourceUrl: PropTypes.bool, + // Service to enable the source map feature for console. + sourceMapService: PropTypes.object, + }, + + getDefaultProps() { + return { + showFunctionName: false, + showAnonymousFunctionName: false, + showHost: false, + showEmptyPathAsHost: false, + showFullSourceUrl: false, + }; + }, + + componentWillMount() { + const sourceMapService = this.props.sourceMapService; + if (sourceMapService) { + const source = this.getSource(); + sourceMapService.subscribe(source, this.onSourceUpdated); + } + }, + + componentWillUnmount() { + const sourceMapService = this.props.sourceMapService; + if (sourceMapService) { + const source = this.getSource(); + sourceMapService.unsubscribe(source, this.onSourceUpdated); + } + }, + + /** + * Component method to update the FrameView when a resolved location is available + * @param event + * @param location + */ + onSourceUpdated(event, location, resolvedLocation) { + const frame = this.getFrame(resolvedLocation); + this.setState({ + frame, + isSourceMapped: true, + }); + }, + + /** + * Utility method to convert the Frame object to the + * Source Object model required by SourceMapService + * @param frame + * @returns {{url: *, line: *, column: *}} + */ + getSource(frame) { + frame = frame || this.props.frame; + const { source, line, column } = frame; + return { + url: source, + line, + column, + }; + }, + + /** + * Utility method to convert the Source object model to the + * Frame object model required by FrameView class. + * @param source + * @returns {{source: *, line: *, column: *, functionDisplayName: *}} + */ + getFrame(source) { + const { url, line, column } = source; + return { + source: url, + line, + column, + functionDisplayName: this.props.frame.functionDisplayName, + }; + }, + + render() { + let frame, isSourceMapped; + let { + onClick, + showFunctionName, + showAnonymousFunctionName, + showHost, + showEmptyPathAsHost, + showFullSourceUrl + } = this.props; + + if (this.state && this.state.isSourceMapped) { + frame = this.state.frame; + isSourceMapped = this.state.isSourceMapped; + } else { + frame = this.props.frame; + } + + let source = frame.source ? String(frame.source) : ""; + let line = frame.line != void 0 ? Number(frame.line) : null; + let column = frame.column != void 0 ? Number(frame.column) : null; + + const { short, long, host } = getSourceNames(source); + // Reparse the URL to determine if we should link this; `getSourceNames` + // has already cached this indirectly. We don't want to attempt to + // link to "self-hosted" and "(unknown)". However, we do want to link + // to Scratchpad URIs. + // Source mapped sources might not necessary linkable, but they + // are still valid in the debugger. + const isLinkable = !!(isScratchpadScheme(source) || parseURL(source)) + || isSourceMapped; + const elements = []; + const sourceElements = []; + let sourceEl; + + let tooltip = long; + + // If the source is linkable and line > 0 + const shouldDisplayLine = isLinkable && line; + + // Exclude all falsy values, including `0`, as even + // a number 0 for line doesn't make sense, and should not be displayed. + // If source isn't linkable, don't attempt to append line and column + // info, as this probably doesn't make sense. + if (shouldDisplayLine) { + tooltip += `:${line}`; + // Intentionally exclude 0 + if (column) { + tooltip += `:${column}`; + } + } + + let attributes = { + "data-url": long, + className: "frame-link", + }; + + if (showFunctionName) { + let functionDisplayName = frame.functionDisplayName; + if (!functionDisplayName && showAnonymousFunctionName) { + functionDisplayName = webl10n.getStr("stacktrace.anonymousFunction"); + } + + if (functionDisplayName) { + elements.push( + dom.span({ className: "frame-link-function-display-name" }, + functionDisplayName), + " " + ); + } + } + + let displaySource = showFullSourceUrl ? long : short; + if (isSourceMapped) { + displaySource = getSourceMappedFile(displaySource); + } else if (showEmptyPathAsHost && (displaySource === "" || displaySource === "/")) { + displaySource = host; + } + + sourceElements.push(dom.span({ + className: "frame-link-filename", + }, displaySource)); + + // If source is linkable, and we have a line number > 0 + if (shouldDisplayLine) { + let lineInfo = `:${line}`; + // Add `data-line` attribute for testing + attributes["data-line"] = line; + + // Intentionally exclude 0 + if (column) { + lineInfo += `:${column}`; + // Add `data-column` attribute for testing + attributes["data-column"] = column; + } + + sourceElements.push(dom.span({ className: "frame-link-line" }, lineInfo)); + } + + // Inner el is useful for achieving ellipsis on the left and correct LTR/RTL + // ordering. See CSS styles for frame-link-source-[inner] and bug 1290056. + let sourceInnerEl = dom.span({ + className: "frame-link-source-inner", + title: isLinkable ? + l10n.getFormatStr("frame.viewsourceindebugger", tooltip) : tooltip, + }, sourceElements); + + // If source is not a URL (self-hosted, eval, etc.), don't make + // it an anchor link, as we can't link to it. + if (isLinkable) { + sourceEl = dom.a({ + onClick: e => { + e.preventDefault(); + onClick(this.getSource(frame)); + }, + href: source, + className: "frame-link-source", + draggable: false, + }, sourceInnerEl); + } else { + sourceEl = dom.span({ + className: "frame-link-source", + }, sourceInnerEl); + } + elements.push(sourceEl); + + if (showHost && host) { + elements.push(" ", dom.span({ className: "frame-link-host" }, host)); + } + + return dom.span(attributes, ...elements); + } + }); + + +/***/ }, +/* 101 */ +/***/ function(module, exports, __webpack_require__) { + + const { isDevelopment, isTesting } = __webpack_require__(102); + + function debugGlobal(field, value) { + if (isDevelopment() || isTesting()) { + window[field] = value; + } + } + + module.exports = { + debugGlobal + }; + +/***/ }, +/* 102 */ +/***/ function(module, exports, __webpack_require__) { + + const feature = __webpack_require__(103); + + module.exports = feature; + + +/***/ }, +/* 103 */ +/***/ function(module, exports, __webpack_require__) { + + const pick = __webpack_require__(104); + let config; + + const flag = __webpack_require__(149); + + /** + * Gets a config value for a given key + * e.g "chrome.webSocketPort" + */ + function getValue(key) { + return pick(config, key); + } + + function isEnabled(key) { + return config.features && config.features[key]; + } + + function isDevelopment() { + if (isFirefoxPanel()) { + // Default to production if compiling for the Firefox panel + return ("production") === "development"; + } + return ("production") !== "production"; + } + + function isTesting() { + return flag.testing; + } + + function isFirefoxPanel() { + return ("firefox-panel") == "firefox-panel"; + } + + function isApplication() { + return ("firefox-panel") == "application"; + } + + function isFirefox() { + return /firefox/i.test(navigator.userAgent); + } + + function setConfig(value) { + config = value; + } + + function getConfig() { + return config; + } + + module.exports = { + isEnabled, + getValue, + isDevelopment, + isTesting, + isFirefoxPanel, + isApplication, + isFirefox, + getConfig, + setConfig + }; + + +/***/ }, +/* 104 */ +/***/ function(module, exports, __webpack_require__) { + + var baseGet = __webpack_require__(105); + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + module.exports = get; + + +/***/ }, +/* 105 */ +/***/ function(module, exports, __webpack_require__) { + + var castPath = __webpack_require__(106), + toKey = __webpack_require__(148); + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + module.exports = baseGet; + + +/***/ }, +/* 106 */ +/***/ function(module, exports, __webpack_require__) { + + var isArray = __webpack_require__(107), + isKey = __webpack_require__(108), + stringToPath = __webpack_require__(110), + toString = __webpack_require__(145); + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + module.exports = castPath; + + +/***/ }, +/* 107 */ +/***/ function(module, exports) { + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + module.exports = isArray; + + +/***/ }, +/* 108 */ +/***/ function(module, exports, __webpack_require__) { + + var isArray = __webpack_require__(107), + isSymbol = __webpack_require__(109); + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + module.exports = isKey; + + +/***/ }, +/* 109 */ +/***/ function(module, exports, __webpack_require__) { + + var baseGetTag = __webpack_require__(13), + isObjectLike = __webpack_require__(21); + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + module.exports = isSymbol; + + +/***/ }, +/* 110 */ +/***/ function(module, exports, __webpack_require__) { + + var memoizeCapped = __webpack_require__(111); + + /** Used to match property names within property paths. */ + var reLeadingDot = /^\./, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (reLeadingDot.test(string)) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + module.exports = stringToPath; + + +/***/ }, +/* 111 */ +/***/ function(module, exports, __webpack_require__) { + + var memoize = __webpack_require__(112); + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + module.exports = memoizeCapped; + + +/***/ }, +/* 112 */ +/***/ function(module, exports, __webpack_require__) { + + var MapCache = __webpack_require__(113); + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = MapCache; + + module.exports = memoize; + + +/***/ }, +/* 113 */ +/***/ function(module, exports, __webpack_require__) { + + var mapCacheClear = __webpack_require__(114), + mapCacheDelete = __webpack_require__(139), + mapCacheGet = __webpack_require__(142), + mapCacheHas = __webpack_require__(143), + mapCacheSet = __webpack_require__(144); + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + 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]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = mapCacheClear; + MapCache.prototype['delete'] = mapCacheDelete; + MapCache.prototype.get = mapCacheGet; + MapCache.prototype.has = mapCacheHas; + MapCache.prototype.set = mapCacheSet; + + module.exports = MapCache; + + +/***/ }, +/* 114 */ +/***/ function(module, exports, __webpack_require__) { + + var Hash = __webpack_require__(115), + ListCache = __webpack_require__(130), + Map = __webpack_require__(138); + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; + } + + module.exports = mapCacheClear; + + +/***/ }, +/* 115 */ +/***/ function(module, exports, __webpack_require__) { + + var hashClear = __webpack_require__(116), + hashDelete = __webpack_require__(126), + hashGet = __webpack_require__(127), + hashHas = __webpack_require__(128), + hashSet = __webpack_require__(129); + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + 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]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = hashClear; + Hash.prototype['delete'] = hashDelete; + Hash.prototype.get = hashGet; + Hash.prototype.has = hashHas; + Hash.prototype.set = hashSet; + + module.exports = Hash; + + +/***/ }, +/* 116 */ +/***/ function(module, exports, __webpack_require__) { + + var nativeCreate = __webpack_require__(117); + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; + this.size = 0; + } + + module.exports = hashClear; + + +/***/ }, +/* 117 */ +/***/ function(module, exports, __webpack_require__) { + + var getNative = __webpack_require__(118); + + /* Built-in method references that are verified to be native. */ + var nativeCreate = getNative(Object, 'create'); + + module.exports = nativeCreate; + + +/***/ }, +/* 118 */ +/***/ function(module, exports, __webpack_require__) { + + var baseIsNative = __webpack_require__(119), + getValue = __webpack_require__(125); + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + module.exports = getNative; + + +/***/ }, +/* 119 */ +/***/ function(module, exports, __webpack_require__) { + + var isFunction = __webpack_require__(120), + isMasked = __webpack_require__(122), + isObject = __webpack_require__(121), + toSource = __webpack_require__(124); + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); + } + + module.exports = baseIsNative; + + +/***/ }, +/* 120 */ +/***/ function(module, exports, __webpack_require__) { + + var baseGetTag = __webpack_require__(13), + isObject = __webpack_require__(121); + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + module.exports = isFunction; + + +/***/ }, +/* 121 */ +/***/ function(module, exports) { + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + module.exports = isObject; + + +/***/ }, +/* 122 */ +/***/ function(module, exports, __webpack_require__) { + + var coreJsData = __webpack_require__(123); + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + module.exports = isMasked; + + +/***/ }, +/* 123 */ +/***/ function(module, exports, __webpack_require__) { + + var root = __webpack_require__(15); + + /** Used to detect overreaching core-js shims. */ + var coreJsData = root['__core-js_shared__']; + + module.exports = coreJsData; + + +/***/ }, +/* 124 */ +/***/ function(module, exports) { + + /** Used for built-in method references. */ + var funcProto = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + module.exports = toSource; + + +/***/ }, +/* 125 */ +/***/ function(module, exports) { + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue(object, key) { + return object == null ? undefined : object[key]; + } + + module.exports = getValue; + + +/***/ }, +/* 126 */ +/***/ function(module, exports) { + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + module.exports = hashDelete; + + +/***/ }, +/* 127 */ +/***/ function(module, exports, __webpack_require__) { + + var nativeCreate = __webpack_require__(117); + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + 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; + } + + module.exports = hashGet; + + +/***/ }, +/* 128 */ +/***/ function(module, exports, __webpack_require__) { + + var nativeCreate = __webpack_require__(117); + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); + } + + module.exports = hashHas; + + +/***/ }, +/* 129 */ +/***/ function(module, exports, __webpack_require__) { + + var nativeCreate = __webpack_require__(117); + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + 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; + } + + module.exports = hashSet; + + +/***/ }, +/* 130 */ +/***/ function(module, exports, __webpack_require__) { + + var listCacheClear = __webpack_require__(131), + listCacheDelete = __webpack_require__(132), + listCacheGet = __webpack_require__(135), + listCacheHas = __webpack_require__(136), + listCacheSet = __webpack_require__(137); + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + 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]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = listCacheClear; + ListCache.prototype['delete'] = listCacheDelete; + ListCache.prototype.get = listCacheGet; + ListCache.prototype.has = listCacheHas; + ListCache.prototype.set = listCacheSet; + + module.exports = ListCache; + + +/***/ }, +/* 131 */ +/***/ function(module, exports) { + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + module.exports = listCacheClear; + + +/***/ }, +/* 132 */ +/***/ function(module, exports, __webpack_require__) { + + var assocIndexOf = __webpack_require__(133); + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + 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; + } + + module.exports = listCacheDelete; + + +/***/ }, +/* 133 */ +/***/ function(module, exports, __webpack_require__) { + + var eq = __webpack_require__(134); + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; + } + + module.exports = assocIndexOf; + + +/***/ }, +/* 134 */ +/***/ function(module, exports) { + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + module.exports = eq; + + +/***/ }, +/* 135 */ +/***/ function(module, exports, __webpack_require__) { + + var assocIndexOf = __webpack_require__(133); + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + module.exports = listCacheGet; + + +/***/ }, +/* 136 */ +/***/ function(module, exports, __webpack_require__) { + + var assocIndexOf = __webpack_require__(133); + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; + } + + module.exports = listCacheHas; + + +/***/ }, +/* 137 */ +/***/ function(module, exports, __webpack_require__) { + + var assocIndexOf = __webpack_require__(133); + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + 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; + } + + module.exports = listCacheSet; + + +/***/ }, +/* 138 */ +/***/ function(module, exports, __webpack_require__) { + + var getNative = __webpack_require__(118), + root = __webpack_require__(15); + + /* Built-in method references that are verified to be native. */ + var Map = getNative(root, 'Map'); + + module.exports = Map; + + +/***/ }, +/* 139 */ +/***/ function(module, exports, __webpack_require__) { + + var getMapData = __webpack_require__(140); + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + module.exports = mapCacheDelete; + + +/***/ }, +/* 140 */ +/***/ function(module, exports, __webpack_require__) { + + var isKeyable = __webpack_require__(141); + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + module.exports = getMapData; + + +/***/ }, +/* 141 */ +/***/ function(module, exports) { + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + module.exports = isKeyable; + + +/***/ }, +/* 142 */ +/***/ function(module, exports, __webpack_require__) { + + var getMapData = __webpack_require__(140); + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return getMapData(this, key).get(key); + } + + module.exports = mapCacheGet; + + +/***/ }, +/* 143 */ +/***/ function(module, exports, __webpack_require__) { + + var getMapData = __webpack_require__(140); + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return getMapData(this, key).has(key); + } + + module.exports = mapCacheHas; + + +/***/ }, +/* 144 */ +/***/ function(module, exports, __webpack_require__) { + + var getMapData = __webpack_require__(140); + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + 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; + } + + module.exports = mapCacheSet; + + +/***/ }, +/* 145 */ +/***/ function(module, exports, __webpack_require__) { + + var baseToString = __webpack_require__(146); + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } + + module.exports = toString; + + +/***/ }, +/* 146 */ +/***/ function(module, exports, __webpack_require__) { + + var Symbol = __webpack_require__(14), + arrayMap = __webpack_require__(147), + isArray = __webpack_require__(107), + isSymbol = __webpack_require__(109); + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + module.exports = baseToString; + + +/***/ }, +/* 147 */ +/***/ function(module, exports) { + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + module.exports = arrayMap; + + +/***/ }, +/* 148 */ +/***/ function(module, exports, __webpack_require__) { + + var isSymbol = __webpack_require__(109); + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + module.exports = toKey; + + +/***/ }, +/* 149 */ +/***/ function(module, exports) { + + module.exports = require("devtools/shared/flags"); + +/***/ }, +/* 150 */ +/***/ function(module, exports, __webpack_require__) { + + const { sprintf } = __webpack_require__(40); + let strings = {}; + + function setBundle(bundle) { + strings = bundle; + } + + function getStr(key) { + if (!strings[key]) { + throw new Error(`L10N key ${ key } cannot be found.`); + } + return strings[key]; + } + + function getFormatStr(name, ...args) { + return sprintf(getStr(name), ...args); + } + + module.exports = { + getStr, + getFormatStr, + setBundle + }; + +/***/ }, +/* 151 */ +/***/ function(module, exports, __webpack_require__) { + + const { Task } = __webpack_require__(152); + const firefox = __webpack_require__(153); + const chrome = __webpack_require__(215); + const { createSource } = __webpack_require__(214); + + let clientType = null; + function getClient() { + if (clientType === "chrome" || clientType === "node") { + return chrome.clientCommands; + } + + return firefox.clientCommands; + } + + function startDebugging(connTarget, actions) { + if (connTarget.type === "node") { + return startDebuggingNode(connTarget.param, actions); + } + + const target = connTarget.type === "chrome" ? chrome : firefox; + return startDebuggingTab(target, connTarget.param, actions); + } + + function startDebuggingNode(tabId, actions) { + return Task.spawn(function* () { + clientType = "node"; + + const tabs = yield chrome.connectNodeClient(); + const tab = tabs.find(t => t.id.indexOf(tabId) !== -1); + + yield chrome.connectNode(tab.tab); + chrome.initPage(actions, { clientType }); + + return { tabs, tab, client: chrome }; + }); + } + + function startDebuggingTab(targetEnv, tabId, actions) { + return Task.spawn(function* () { + const tabs = yield targetEnv.connectClient(); + const tab = tabs.find(t => t.id.indexOf(tabId) !== -1); + yield targetEnv.connectTab(tab.tab); + + clientType = targetEnv === firefox ? "firefox" : "chrome"; + targetEnv.initPage(actions, { clientType }); + + return { tabs, tab, client: targetEnv }; + }); + } + + module.exports = { + getClient, + startDebugging, + firefox, + chrome, + createSource + }; + + +/***/ }, +/* 152 */ +/***/ function(module, exports) { + + /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ + /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */ + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + + /** + * This object provides the public module functions. + */ + const Task = { + // XXX: Not sure if this works in all cases... + async: function (task) { + return function () { + return Task.spawn(task, this, arguments); + }; + }, + + /** + * Creates and starts a new task. + * @param task A generator function + * @return A promise, resolved when the task terminates + */ + spawn: function (task, scope, args) { + return new Promise(function (resolve, reject) { + const iterator = task.apply(scope, args); + + const callNext = lastValue => { + const iteration = iterator.next(lastValue); + Promise.resolve(iteration.value).then(value => { + if (iteration.done) { + resolve(value); + } else { + callNext(value); + } + }).catch(error => { + reject(error); + iterator.throw(error); + }); + }; + + callNext(undefined); + }); + } + }; + + module.exports = { Task }; + +/***/ }, +/* 153 */ +/***/ function(module, exports, __webpack_require__) { + + const { DebuggerClient, DebuggerTransport, + TargetFactory, WebsocketTransport } = __webpack_require__(38); + const defer = __webpack_require__(154); + const { getValue } = __webpack_require__(102); + const { Tab } = __webpack_require__(155); + const { setupCommands, clientCommands } = __webpack_require__(212); + const { setupEvents, clientEvents } = __webpack_require__(213); + + let debuggerClient = null; + let threadClient = null; + let tabTarget = null; + + function getThreadClient() { + return threadClient; + } + + function setThreadClient(client) { + threadClient = client; + } + + function getTabTarget() { + return tabTarget; + } + + function setTabTarget(target) { + tabTarget = target; + } + + function lookupTabTarget(tab) { + const options = { client: debuggerClient, form: tab, chrome: false }; + return TargetFactory.forRemoteTab(options); + } + + function createTabs(tabs) { + return tabs.map(tab => { + return Tab({ + title: tab.title, + url: tab.url, + id: tab.actor, + tab, + clientType: "firefox" + }); + }); + } + + function connectClient() { + const deferred = defer(); + const useProxy = !getValue("firefox.webSocketConnection"); + const firefoxHost = getValue(useProxy ? "firefox.proxyHost" : "firefox.webSocketHost"); + + const socket = new WebSocket(`ws://${ firefoxHost }`); + const transport = useProxy ? new DebuggerTransport(socket) : new WebsocketTransport(socket); + debuggerClient = new DebuggerClient(transport); + + debuggerClient.connect().then(() => { + return debuggerClient.listTabs().then(response => { + deferred.resolve(createTabs(response.tabs)); + }); + }).catch(err => { + console.log(err); + deferred.resolve([]); + }); + + return deferred.promise; + } + + function connectTab(tab) { + return new Promise((resolve, reject) => { + window.addEventListener("beforeunload", () => { + getTabTarget() && getTabTarget().destroy(); + }); + + lookupTabTarget(tab).then(target => { + tabTarget = target; + target.activeTab.attachThread({}, (res, _threadClient) => { + threadClient = _threadClient; + threadClient.resume(); + resolve(); + }); + }); + }); + } + + function initPage(actions) { + tabTarget = getTabTarget(); + threadClient = getThreadClient(); + setupCommands({ threadClient, tabTarget, debuggerClient }); + + if (actions) { + // Listen to all the requested events. + setupEvents({ threadClient, actions }); + Object.keys(clientEvents).forEach(eventName => { + threadClient.addListener(eventName, clientEvents[eventName]); + }); + } + } + + module.exports = { + connectClient, + connectTab, + clientCommands, + clientEvents, + getThreadClient, + setThreadClient, + getTabTarget, + setTabTarget, + initPage + }; + +/***/ }, +/* 154 */ +/***/ function(module, exports) { + + module.exports = function defer() { + let resolve, reject; + let promise = new Promise(function () { + resolve = arguments[0]; + reject = arguments[1]; + }); + return { + resolve: resolve, + reject: reject, + promise: promise + }; + }; + +/***/ }, +/* 155 */ +/***/ function(module, exports, __webpack_require__) { + + const t = __webpack_require__(156); + + const Tab = t.struct({ + title: t.String, + url: t.String, + id: t.String, + tab: t.Object, + clientType: t.enums.of(["chrome", "firefox", "node"]) + }, "Tab"); + + const SourceText = t.struct({ + text: t.String, + contentType: t.String + }); + + const Source = t.struct({ + id: t.String, + url: t.union([t.String, t.Nil]), + isPrettyPrinted: t.Boolean, + sourceMapURL: t.union([t.String, t.Nil]) + }, "Source"); + + const Location = t.struct({ + sourceId: t.String, + line: t.Number, + column: t.union([t.Number, t.Nil]) + }, "Location"); + + const Breakpoint = t.struct({ + id: t.String, + loading: t.Boolean, + disabled: t.Boolean, + text: t.String, + condition: t.union([t.String, t.Nil]) + }); + + const BreakpointResult = t.struct({ + id: t.String, + actualLocation: Location + }); + + const Frame = t.struct({ + id: t.String, + displayName: t.String, + location: Location, + this: t.union([t.Object, t.Nil]), + scope: t.union([t.Object, t.Nil]), + scopeChain: t.union([t.Array, t.Nil]) + }, "Frame"); + + module.exports = { + Tab, + Source, + SourceText, + Location, + Breakpoint, + BreakpointResult, + Frame + }; + +/***/ }, +/* 156 */ +/***/ function(module, exports, __webpack_require__) { + + /*! @preserve + * + * tcomb.js - Type checking and DDD for JavaScript + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2016 Giulio Canti + * + */ + + // core + var t = __webpack_require__(157); + + // types + t.Any = __webpack_require__(163); + t.Array = __webpack_require__(171); + t.Boolean = __webpack_require__(172); + t.Date = __webpack_require__(174); + t.Error = __webpack_require__(175); + t.Function = __webpack_require__(176); + t.Nil = __webpack_require__(177); + t.Number = __webpack_require__(178); + t.Integer = __webpack_require__(180); + t.IntegerT = t.Integer; + t.Object = __webpack_require__(186); + t.RegExp = __webpack_require__(187); + t.String = __webpack_require__(188); + t.Type = __webpack_require__(189); + t.TypeT = t.Type; + + // short alias are deprecated + t.Arr = t.Array; + t.Bool = t.Boolean; + t.Dat = t.Date; + t.Err = t.Error; + t.Func = t.Function; + t.Num = t.Number; + t.Obj = t.Object; + t.Re = t.RegExp; + t.Str = t.String; + + // combinators + t.dict = __webpack_require__(190); + t.declare = __webpack_require__(191); + t.enums = __webpack_require__(194); + t.irreducible = __webpack_require__(164); + t.list = __webpack_require__(195); + t.maybe = __webpack_require__(196); + t.refinement = __webpack_require__(181); + t.struct = __webpack_require__(198); + t.tuple = __webpack_require__(204); + t.union = __webpack_require__(205); + t.func = __webpack_require__(206); + t.intersection = __webpack_require__(207); + t.subtype = t.refinement; + t.inter = __webpack_require__(208); // IE8 alias + t['interface'] = t.inter; + + // functions + t.assert = t; + t.update = __webpack_require__(210); + t.mixin = __webpack_require__(192); + t.isType = __webpack_require__(168); + t.is = __webpack_require__(185); + t.getTypeName = __webpack_require__(167); + t.match = __webpack_require__(211); + + module.exports = t; + + +/***/ }, +/* 157 */ +/***/ function(module, exports, __webpack_require__) { + + var isFunction = __webpack_require__(158); + var isNil = __webpack_require__(159); + var fail = __webpack_require__(160); + var stringify = __webpack_require__(161); + + function assert(guard, message) { + if (guard !== true) { + if (isFunction(message)) { // handle lazy messages + message = message(); + } + else if (isNil(message)) { // use a default message + message = 'Assert failed (turn on "Pause on exceptions" in your Source panel)'; + } + assert.fail(message); + } + } + + assert.fail = fail; + assert.stringify = stringify; + + module.exports = assert; + +/***/ }, +/* 158 */ +/***/ function(module, exports) { + + module.exports = function isFunction(x) { + return typeof x === 'function'; + }; + +/***/ }, +/* 159 */ +/***/ function(module, exports) { + + module.exports = function isNil(x) { + return x === null || x === void 0; + }; + +/***/ }, +/* 160 */ +/***/ function(module, exports) { + + module.exports = function fail(message) { + throw new TypeError('[tcomb] ' + message); + }; + +/***/ }, +/* 161 */ +/***/ function(module, exports, __webpack_require__) { + + var getFunctionName = __webpack_require__(162); + + function replacer(key, value) { + if (typeof value === 'function') { + return getFunctionName(value); + } + return value; + } + + module.exports = function stringify(x) { + try { // handle "Converting circular structure to JSON" error + return JSON.stringify(x, replacer, 2); + } + catch (e) { + return String(x); + } + }; + +/***/ }, +/* 162 */ +/***/ function(module, exports) { + + module.exports = function getFunctionName(f) { + return f.displayName || f.name || ''; + }; + +/***/ }, +/* 163 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + + module.exports = irreducible('Any', function () { return true; }); + + +/***/ }, +/* 164 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isString = __webpack_require__(165); + var isFunction = __webpack_require__(158); + var forbidNewOperator = __webpack_require__(166); + + module.exports = function irreducible(name, predicate) { + + if (false) { + assert(isString(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to irreducible(name, predicate) (expected a string)'; }); + assert(isFunction(predicate), 'Invalid argument predicate ' + assert.stringify(predicate) + ' supplied to irreducible(name, predicate) (expected a function)'); + } + + function Irreducible(value, path) { + + if (false) { + forbidNewOperator(this, Irreducible); + path = path || [name]; + assert(predicate(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); }); + } + + return value; + } + + Irreducible.meta = { + kind: 'irreducible', + name: name, + predicate: predicate, + identity: true + }; + + Irreducible.displayName = name; + + Irreducible.is = predicate; + + return Irreducible; + }; + + +/***/ }, +/* 165 */ +/***/ function(module, exports) { + + module.exports = function isString(x) { + return typeof x === 'string'; + }; + +/***/ }, +/* 166 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var getTypeName = __webpack_require__(167); + + module.exports = function forbidNewOperator(x, type) { + assert(!(x instanceof type), function () { return 'Cannot use the new operator to instantiate the type ' + getTypeName(type); }); + }; + +/***/ }, +/* 167 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + var getFunctionName = __webpack_require__(162); + + module.exports = function getTypeName(ctor) { + if (isType(ctor)) { + return ctor.displayName; + } + return getFunctionName(ctor); + }; + +/***/ }, +/* 168 */ +/***/ function(module, exports, __webpack_require__) { + + var isFunction = __webpack_require__(158); + var isObject = __webpack_require__(169); + + module.exports = function isType(x) { + return isFunction(x) && isObject(x.meta); + }; + +/***/ }, +/* 169 */ +/***/ function(module, exports, __webpack_require__) { + + var isNil = __webpack_require__(159); + var isArray = __webpack_require__(170); + + module.exports = function isObject(x) { + return !isNil(x) && typeof x === 'object' && !isArray(x); + }; + +/***/ }, +/* 170 */ +/***/ function(module, exports) { + + module.exports = function isArray(x) { + return Array.isArray ? Array.isArray(x) : x instanceof Array; + }; + +/***/ }, +/* 171 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isArray = __webpack_require__(170); + + module.exports = irreducible('Array', isArray); + + +/***/ }, +/* 172 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isBoolean = __webpack_require__(173); + + module.exports = irreducible('Boolean', isBoolean); + + +/***/ }, +/* 173 */ +/***/ function(module, exports) { + + module.exports = function isBoolean(x) { + return x === true || x === false; + }; + +/***/ }, +/* 174 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + + module.exports = irreducible('Date', function (x) { return x instanceof Date; }); + + +/***/ }, +/* 175 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + + module.exports = irreducible('Error', function (x) { return x instanceof Error; }); + + +/***/ }, +/* 176 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isFunction = __webpack_require__(158); + + module.exports = irreducible('Function', isFunction); + + +/***/ }, +/* 177 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isNil = __webpack_require__(159); + + module.exports = irreducible('Nil', isNil); + + +/***/ }, +/* 178 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isNumber = __webpack_require__(179); + + module.exports = irreducible('Number', isNumber); + + +/***/ }, +/* 179 */ +/***/ function(module, exports) { + + module.exports = function isNumber(x) { + return typeof x === 'number' && isFinite(x) && !isNaN(x); + }; + +/***/ }, +/* 180 */ +/***/ function(module, exports, __webpack_require__) { + + var refinement = __webpack_require__(181); + var Number = __webpack_require__(178); + + module.exports = refinement(Number, function (x) { return x % 1 === 0; }, 'Integer'); + + +/***/ }, +/* 181 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var forbidNewOperator = __webpack_require__(166); + var isIdentity = __webpack_require__(183); + var create = __webpack_require__(184); + var is = __webpack_require__(185); + var getTypeName = __webpack_require__(167); + var getFunctionName = __webpack_require__(162); + + function getDefaultName(type, predicate) { + return '{' + getTypeName(type) + ' | ' + getFunctionName(predicate) + '}'; + } + + function refinement(type, predicate, name) { + + if (false) { + assert(isFunction(type), function () { return 'Invalid argument type ' + assert.stringify(type) + ' supplied to refinement(type, predicate, [name]) combinator (expected a type)'; }); + assert(isFunction(predicate), function () { return 'Invalid argument predicate supplied to refinement(type, predicate, [name]) combinator (expected a function)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to refinement(type, predicate, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(type, predicate); + var identity = isIdentity(type); + + function Refinement(value, path) { + + if (false) { + if (identity) { + forbidNewOperator(this, Refinement); + } + path = path || [displayName]; + } + + var x = create(type, value, path); + + if (false) { + assert(predicate(x), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); }); + } + + return x; + } + + Refinement.meta = { + kind: 'subtype', + type: type, + predicate: predicate, + name: name, + identity: identity + }; + + Refinement.displayName = displayName; + + Refinement.is = function (x) { + return is(x, type) && predicate(x); + }; + + Refinement.update = function (instance, patch) { + return Refinement(assert.update(instance, patch)); + }; + + return Refinement; + } + + refinement.getDefaultName = getDefaultName; + module.exports = refinement; + + +/***/ }, +/* 182 */ +/***/ function(module, exports, __webpack_require__) { + + var isNil = __webpack_require__(159); + var isString = __webpack_require__(165); + + module.exports = function isTypeName(name) { + return isNil(name) || isString(name); + }; + +/***/ }, +/* 183 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var Boolean = __webpack_require__(172); + var isType = __webpack_require__(168); + var getTypeName = __webpack_require__(167); + + // return true if the type constructor behaves like the identity function + module.exports = function isIdentity(type) { + if (isType(type)) { + if (false) { + assert(Boolean.is(type.meta.identity), function () { return 'Invalid meta identity ' + assert.stringify(type.meta.identity) + ' supplied to type ' + getTypeName(type); }); + } + return type.meta.identity; + } + // for tcomb the other constructors, like ES6 classes, are identity-like + return true; + }; + +/***/ }, +/* 184 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + var getFunctionName = __webpack_require__(162); + var assert = __webpack_require__(157); + var stringify = __webpack_require__(161); + + // creates an instance of a type, handling the optional new operator + module.exports = function create(type, value, path) { + if (isType(type)) { + return !type.meta.identity && typeof value === 'object' && value !== null ? new type(value, path): type(value, path); + } + + if (false) { + // here type should be a class constructor and value some instance, just check membership and return the value + path = path || [getFunctionName(type)]; + assert(value instanceof type, function () { return 'Invalid value ' + stringify(value) + ' supplied to ' + path.join('/'); }); + } + + return value; + }; + +/***/ }, +/* 185 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + // returns true if x is an instance of type + module.exports = function is(x, type) { + if (isType(type)) { + return type.is(x); + } + return x instanceof type; // type should be a class constructor + }; + + +/***/ }, +/* 186 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isObject = __webpack_require__(169); + + module.exports = irreducible('Object', isObject); + + +/***/ }, +/* 187 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + + module.exports = irreducible('RegExp', function (x) { return x instanceof RegExp; }); + + +/***/ }, +/* 188 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isString = __webpack_require__(165); + + module.exports = irreducible('String', isString); + + +/***/ }, +/* 189 */ +/***/ function(module, exports, __webpack_require__) { + + var irreducible = __webpack_require__(164); + var isType = __webpack_require__(168); + + module.exports = irreducible('Type', isType); + +/***/ }, +/* 190 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var getTypeName = __webpack_require__(167); + var isIdentity = __webpack_require__(183); + var isObject = __webpack_require__(169); + var create = __webpack_require__(184); + var is = __webpack_require__(185); + + function getDefaultName(domain, codomain) { + return '{[key: ' + getTypeName(domain) + ']: ' + getTypeName(codomain) + '}'; + } + + function dict(domain, codomain, name) { + + if (false) { + assert(isFunction(domain), function () { return 'Invalid argument domain ' + assert.stringify(domain) + ' supplied to dict(domain, codomain, [name]) combinator (expected a type)'; }); + assert(isFunction(codomain), function () { return 'Invalid argument codomain ' + assert.stringify(codomain) + ' supplied to dict(domain, codomain, [name]) combinator (expected a type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to dict(domain, codomain, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(domain, codomain); + var domainNameCache = getTypeName(domain); + var codomainNameCache = getTypeName(codomain); + var identity = isIdentity(domain) && isIdentity(codomain); + + function Dict(value, path) { + + if (true) { + if (identity) { + return value; // just trust the input if elements must not be hydrated + } + } + + if (false) { + path = path || [displayName]; + assert(isObject(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); }); + } + + var idempotent = true; // will remain true if I can reutilise the input + var ret = {}; // make a temporary copy, will be discarded if idempotent remains true + for (var k in value) { + if (value.hasOwnProperty(k)) { + k = create(domain, k, ( false ? path.concat(domainNameCache) : null )); + var actual = value[k]; + var instance = create(codomain, actual, ( false ? path.concat(k + ': ' + codomainNameCache) : null )); + idempotent = idempotent && ( actual === instance ); + ret[k] = instance; + } + } + + if (idempotent) { // implements idempotency + ret = value; + } + + if (false) { + Object.freeze(ret); + } + + return ret; + } + + Dict.meta = { + kind: 'dict', + domain: domain, + codomain: codomain, + name: name, + identity: identity + }; + + Dict.displayName = displayName; + + Dict.is = function (x) { + if (!isObject(x)) { + return false; + } + for (var k in x) { + if (x.hasOwnProperty(k)) { + if (!is(k, domain) || !is(x[k], codomain)) { + return false; + } + } + } + return true; + }; + + Dict.update = function (instance, patch) { + return Dict(assert.update(instance, patch)); + }; + + return Dict; + } + + dict.getDefaultName = getDefaultName; + module.exports = dict; + + +/***/ }, +/* 191 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isType = __webpack_require__(168); + var isNil = __webpack_require__(159); + var mixin = __webpack_require__(192); + var getTypeName = __webpack_require__(167); + var isUnion = __webpack_require__(193); + + // All the .declare-d types should be clearly different from each other thus they should have + // different names when a name was not explicitly provided. + var nextDeclareUniqueId = 1; + + module.exports = function declare(name) { + if (false) { + assert(isTypeName(name), function () { return 'Invalid argument name ' + name + ' supplied to declare([name]) (expected a string)'; }); + } + + var type; + + function Declare(value, path) { + if (false) { + assert(!isNil(type), function () { return 'Type declared but not defined, don\'t forget to call .define on every declared type'; }); + if (isUnion(type)) { + assert(type.dispatch === Declare.dispatch, function () { return 'Please define the custom ' + name + '.dispatch function before calling ' + name + '.define()'; }); + } + } + return type(value, path); + } + + Declare.define = function (spec) { + if (false) { + assert(isType(spec), function () { return 'Invalid argument type ' + assert.stringify(spec) + ' supplied to define(type) (expected a type)'; }); + assert(isNil(type), function () { return 'Declare.define(type) can only be invoked once'; }); + assert(isNil(spec.meta.name) && Object.keys(spec.prototype).length === 0, function () { return 'Invalid argument type ' + assert.stringify(spec) + ' supplied to define(type) (expected a fresh, unnamed type)'; }); + } + + if (isUnion(spec) && Declare.hasOwnProperty('dispatch')) { + spec.dispatch = Declare.dispatch; + } + type = spec; + mixin(Declare, type, true); // true because it overwrites Declare.displayName + if (name) { + type.displayName = Declare.displayName = name; + Declare.meta.name = name; + } + Declare.meta.identity = type.meta.identity; + Declare.prototype = type.prototype; + return Declare; + }; + + Declare.displayName = name || ( getTypeName(Declare) + "$" + nextDeclareUniqueId++ ); + // in general I can't say if this type will be an identity, for safety setting to false + Declare.meta = { identity: false }; + Declare.prototype = null; + return Declare; + }; + + +/***/ }, +/* 192 */ +/***/ function(module, exports, __webpack_require__) { + + var isNil = __webpack_require__(159); + var assert = __webpack_require__(157); + + // safe mixin, cannot override props unless specified + module.exports = function mixin(target, source, overwrite) { + if (isNil(source)) { return target; } + for (var k in source) { + if (source.hasOwnProperty(k)) { + if (overwrite !== true) { + if (false) { + assert(!target.hasOwnProperty(k) || target[k] === source[k], function () { return 'Invalid call to mixin(target, source, [overwrite]): cannot overwrite property "' + k + '" of target object'; }); + } + } + target[k] = source[k]; + } + } + return target; + }; + +/***/ }, +/* 193 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + module.exports = function isUnion(x) { + return isType(x) && ( x.meta.kind === 'union' ); + }; + +/***/ }, +/* 194 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var forbidNewOperator = __webpack_require__(166); + var isString = __webpack_require__(165); + var isObject = __webpack_require__(169); + + function getDefaultName(map) { + return Object.keys(map).map(function (k) { return assert.stringify(k); }).join(' | '); + } + + function enums(map, name) { + + if (false) { + assert(isObject(map), function () { return 'Invalid argument map ' + assert.stringify(map) + ' supplied to enums(map, [name]) combinator (expected a dictionary of String -> String | Number)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to enums(map, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(map); + + function Enums(value, path) { + + if (false) { + forbidNewOperator(this, Enums); + path = path || [displayName]; + assert(Enums.is(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/') + ' (expected one of ' + assert.stringify(Object.keys(map)) + ')'; }); + } + + return value; + } + + Enums.meta = { + kind: 'enums', + map: map, + name: name, + identity: true + }; + + Enums.displayName = displayName; + + Enums.is = function (x) { + return map.hasOwnProperty(x); + }; + + return Enums; + } + + enums.of = function (keys, name) { + keys = isString(keys) ? keys.split(' ') : keys; + var value = {}; + keys.forEach(function (k) { + value[k] = k; + }); + return enums(value, name); + }; + + enums.getDefaultName = getDefaultName; + module.exports = enums; + + + +/***/ }, +/* 195 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var getTypeName = __webpack_require__(167); + var isIdentity = __webpack_require__(183); + var create = __webpack_require__(184); + var is = __webpack_require__(185); + var isArray = __webpack_require__(170); + + function getDefaultName(type) { + return 'Array<' + getTypeName(type) + '>'; + } + + function list(type, name) { + + if (false) { + assert(isFunction(type), function () { return 'Invalid argument type ' + assert.stringify(type) + ' supplied to list(type, [name]) combinator (expected a type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to list(type, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(type); + var typeNameCache = getTypeName(type); + var identity = isIdentity(type); // the list is identity iif type is identity + + function List(value, path) { + + if (true) { + if (identity) { + return value; // just trust the input if elements must not be hydrated + } + } + + if (false) { + path = path || [displayName]; + assert(isArray(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/') + ' (expected an array of ' + typeNameCache + ')'; }); + } + + var idempotent = true; // will remain true if I can reutilise the input + var ret = []; // make a temporary copy, will be discarded if idempotent remains true + for (var i = 0, len = value.length; i < len; i++ ) { + var actual = value[i]; + var instance = create(type, actual, ( false ? path.concat(i + ': ' + typeNameCache) : null )); + idempotent = idempotent && ( actual === instance ); + ret.push(instance); + } + + if (idempotent) { // implements idempotency + ret = value; + } + + if (false) { + Object.freeze(ret); + } + + return ret; + } + + List.meta = { + kind: 'list', + type: type, + name: name, + identity: identity + }; + + List.displayName = displayName; + + List.is = function (x) { + return isArray(x) && x.every(function (e) { + return is(e, type); + }); + }; + + List.update = function (instance, patch) { + return List(assert.update(instance, patch)); + }; + + return List; + } + + list.getDefaultName = getDefaultName; + module.exports = list; + + +/***/ }, +/* 196 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var isMaybe = __webpack_require__(197); + var isIdentity = __webpack_require__(183); + var Any = __webpack_require__(163); + var create = __webpack_require__(184); + var Nil = __webpack_require__(177); + var forbidNewOperator = __webpack_require__(166); + var is = __webpack_require__(185); + var getTypeName = __webpack_require__(167); + + function getDefaultName(type) { + return '?' + getTypeName(type); + } + + function maybe(type, name) { + + if (isMaybe(type) || type === Any || type === Nil) { // makes the combinator idempotent and handle Any, Nil + return type; + } + + if (false) { + assert(isFunction(type), function () { return 'Invalid argument type ' + assert.stringify(type) + ' supplied to maybe(type, [name]) combinator (expected a type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to maybe(type, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(type); + var identity = isIdentity(type); + + function Maybe(value, path) { + if (false) { + if (identity) { + forbidNewOperator(this, Maybe); + } + } + return Nil.is(value) ? value : create(type, value, path); + } + + Maybe.meta = { + kind: 'maybe', + type: type, + name: name, + identity: identity + }; + + Maybe.displayName = displayName; + + Maybe.is = function (x) { + return Nil.is(x) || is(x, type); + }; + + return Maybe; + } + + maybe.getDefaultName = getDefaultName; + module.exports = maybe; + + +/***/ }, +/* 197 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + module.exports = function isMaybe(x) { + return isType(x) && ( x.meta.kind === 'maybe' ); + }; + +/***/ }, +/* 198 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var String = __webpack_require__(188); + var Function = __webpack_require__(176); + var isBoolean = __webpack_require__(173); + var isObject = __webpack_require__(169); + var isNil = __webpack_require__(159); + var create = __webpack_require__(184); + var getTypeName = __webpack_require__(167); + var dict = __webpack_require__(190); + var getDefaultInterfaceName = __webpack_require__(199); + var extend = __webpack_require__(200); + + function getDefaultName(props) { + return 'Struct' + getDefaultInterfaceName(props); + } + + function extendStruct(mixins, name) { + return extend(struct, mixins, name); + } + + function getOptions(options) { + if (!isObject(options)) { + options = isNil(options) ? {} : { name: options }; + } + if (!options.hasOwnProperty('strict')) { + options.strict = struct.strict; + } + if (!options.hasOwnProperty('defaultProps')) { + options.defaultProps = {}; + } + return options; + } + + function struct(props, options) { + + options = getOptions(options); + var name = options.name; + var strict = options.strict; + var defaultProps = options.defaultProps; + + if (false) { + assert(dict(String, Function).is(props), function () { return 'Invalid argument props ' + assert.stringify(props) + ' supplied to struct(props, [options]) combinator (expected a dictionary String -> Type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to struct(props, [options]) combinator (expected a string)'; }); + assert(isBoolean(strict), function () { return 'Invalid argument strict ' + assert.stringify(strict) + ' supplied to struct(props, [options]) combinator (expected a boolean)'; }); + assert(isObject(defaultProps), function () { return 'Invalid argument defaultProps ' + assert.stringify(defaultProps) + ' supplied to struct(props, [options]) combinator (expected an object)'; }); + } + + var displayName = name || getDefaultName(props); + + function Struct(value, path) { + + if (Struct.is(value)) { // implements idempotency + return value; + } + + if (false) { + path = path || [displayName]; + assert(isObject(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/') + ' (expected an object)'; }); + // strictness + if (strict) { + for (k in value) { + if (value.hasOwnProperty(k)) { + assert(props.hasOwnProperty(k), function () { return 'Invalid additional prop "' + k + '" supplied to ' + path.join('/'); }); + } + } + } + } + + if (!(this instanceof Struct)) { // `new` is optional + return new Struct(value, path); + } + + for (var k in props) { + if (props.hasOwnProperty(k)) { + var expected = props[k]; + var actual = value[k]; + // apply defaults + if (actual === undefined) { + actual = defaultProps[k]; + } + this[k] = create(expected, actual, ( false ? path.concat(k + ': ' + getTypeName(expected)) : null )); + } + } + + if (false) { + Object.freeze(this); + } + + } + + Struct.meta = { + kind: 'struct', + props: props, + name: name, + identity: false, + strict: strict, + defaultProps: defaultProps + }; + + Struct.displayName = displayName; + + Struct.is = function (x) { + return x instanceof Struct; + }; + + Struct.update = function (instance, patch) { + return new Struct(assert.update(instance, patch)); + }; + + Struct.extend = function (xs, name) { + return extendStruct([Struct].concat(xs), name); + }; + + return Struct; + } + + struct.strict = false; + struct.getOptions = getOptions; + struct.getDefaultName = getDefaultName; + struct.extend = extendStruct; + module.exports = struct; + + +/***/ }, +/* 199 */ +/***/ function(module, exports, __webpack_require__) { + + var getTypeName = __webpack_require__(167); + + function getDefaultInterfaceName(props) { + return '{' + Object.keys(props).map(function (prop) { + return prop + ': ' + getTypeName(props[prop]); + }).join(', ') + '}'; + } + + module.exports = getDefaultInterfaceName; + + +/***/ }, +/* 200 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isFunction = __webpack_require__(158); + var isArray = __webpack_require__(170); + var mixin = __webpack_require__(192); + var isStruct = __webpack_require__(201); + var isInterface = __webpack_require__(202); + var isObject = __webpack_require__(169); + var refinement = __webpack_require__(181); + var decompose = __webpack_require__(203); + + function compose(predicates, unrefinedType) { + return predicates.reduce(function (type, predicate) { + return refinement(type, predicate); + }, unrefinedType); + } + + function getProps(type) { + return isObject(type) ? type : type.meta.props; + } + + function getDefaultProps(type) { + return isObject(type) ? null : type.meta.defaultProps; + } + + function pushAll(arr, elements) { + Array.prototype.push.apply(arr, elements); + } + + function extend(combinator, mixins, options) { + if (false) { + assert(isFunction(combinator), function () { return 'Invalid argument combinator supplied to extend(combinator, mixins, options), expected a function'; }); + assert(isArray(mixins), function () { return 'Invalid argument mixins supplied to extend(combinator, mixins, options), expected an array'; }); + } + var props = {}; + var prototype = {}; + var predicates = []; + var defaultProps = {}; + mixins.forEach(function (x, i) { + var decomposition = decompose(x); + var unrefinedType = decomposition.unrefinedType; + if (false) { + assert(isObject(unrefinedType) || isStruct(unrefinedType) || isInterface(unrefinedType), function () { return 'Invalid argument mixins[' + i + '] supplied to extend(combinator, mixins, options), expected an object, struct, interface or a refinement (of struct or interface)'; }); + } + pushAll(predicates, decomposition.predicates); + mixin(props, getProps(unrefinedType)); + mixin(prototype, unrefinedType.prototype); + mixin(defaultProps, getDefaultProps(unrefinedType), true); + }); + options = combinator.getOptions(options); + options.defaultProps = mixin(defaultProps, options.defaultProps, true); + var result = compose(predicates, combinator(props, options)); + mixin(result.prototype, prototype); + return result; + } + + module.exports = extend; + +/***/ }, +/* 201 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + module.exports = function isStruct(x) { + return isType(x) && ( x.meta.kind === 'struct' ); + }; + +/***/ }, +/* 202 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + module.exports = function isInterface(x) { + return isType(x) && ( x.meta.kind === 'interface' ); + }; + +/***/ }, +/* 203 */ +/***/ function(module, exports, __webpack_require__) { + + var isType = __webpack_require__(168); + + function isRefinement(type) { + return isType(type) && type.meta.kind === 'subtype'; + } + + function getPredicates(type) { + return isRefinement(type) ? + [type.meta.predicate].concat(getPredicates(type.meta.type)) : + []; + } + + function getUnrefinedType(type) { + return isRefinement(type) ? + getUnrefinedType(type.meta.type) : + type; + } + + function decompose(type) { + return { + predicates: getPredicates(type), + unrefinedType: getUnrefinedType(type) + }; + } + + module.exports = decompose; + +/***/ }, +/* 204 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var getTypeName = __webpack_require__(167); + var isIdentity = __webpack_require__(183); + var isArray = __webpack_require__(170); + var create = __webpack_require__(184); + var is = __webpack_require__(185); + + function getDefaultName(types) { + return '[' + types.map(getTypeName).join(', ') + ']'; + } + + function tuple(types, name) { + + if (false) { + assert(isArray(types) && types.every(isFunction), function () { return 'Invalid argument types ' + assert.stringify(types) + ' supplied to tuple(types, [name]) combinator (expected an array of types)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to tuple(types, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(types); + var identity = types.every(isIdentity); + + function Tuple(value, path) { + + if (true) { + if (identity) { + return value; + } + } + + if (false) { + path = path || [displayName]; + assert(isArray(value) && value.length === types.length, function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/') + ' (expected an array of length ' + types.length + ')'; }); + } + + var idempotent = true; + var ret = []; + for (var i = 0, len = types.length; i < len; i++) { + var expected = types[i]; + var actual = value[i]; + var instance = create(expected, actual, ( false ? path.concat(i + ': ' + getTypeName(expected)) : null )); + idempotent = idempotent && ( actual === instance ); + ret.push(instance); + } + + if (idempotent) { // implements idempotency + ret = value; + } + + if (false) { + Object.freeze(ret); + } + + return ret; + } + + Tuple.meta = { + kind: 'tuple', + types: types, + name: name, + identity: identity + }; + + Tuple.displayName = displayName; + + Tuple.is = function (x) { + return isArray(x) && + x.length === types.length && + types.every(function (type, i) { + return is(x[i], type); + }); + }; + + Tuple.update = function (instance, patch) { + return Tuple(assert.update(instance, patch)); + }; + + return Tuple; + } + + tuple.getDefaultName = getDefaultName; + module.exports = tuple; + +/***/ }, +/* 205 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var getTypeName = __webpack_require__(167); + var isIdentity = __webpack_require__(183); + var isArray = __webpack_require__(170); + var create = __webpack_require__(184); + var is = __webpack_require__(185); + var forbidNewOperator = __webpack_require__(166); + var isUnion = __webpack_require__(193); + var isNil = __webpack_require__(159); + + function getDefaultName(types) { + return types.map(getTypeName).join(' | '); + } + + function union(types, name) { + + if (false) { + assert(isArray(types) && types.every(isFunction) && types.length >= 2, function () { return 'Invalid argument types ' + assert.stringify(types) + ' supplied to union(types, [name]) combinator (expected an array of at least 2 types)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to union(types, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(types); + var identity = types.every(isIdentity); + + function Union(value, path) { + + if (true) { + if (identity) { + return value; + } + } + + var type = Union.dispatch(value); + if (!type && Union.is(value)) { + return value; + } + + if (false) { + if (identity) { + forbidNewOperator(this, Union); + } + path = path || [displayName]; + assert(isFunction(type), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/') + ' (no constructor returned by dispatch)'; }); + path[path.length - 1] += '(' + getTypeName(type) + ')'; + } + + return create(type, value, path); + } + + Union.meta = { + kind: 'union', + types: types, + name: name, + identity: identity + }; + + Union.displayName = displayName; + + Union.is = function (x) { + return types.some(function (type) { + return is(x, type); + }); + }; + + Union.dispatch = function (x) { // default dispatch implementation + for (var i = 0, len = types.length; i < len; i++ ) { + var type = types[i]; + if (isUnion(type)) { // handle union of unions + var t = type.dispatch(x); + if (!isNil(t)) { + return t; + } + } + else if (is(x, type)) { + return type; + } + } + }; + + Union.update = function (instance, patch) { + return Union(assert.update(instance, patch)); + }; + + return Union; + } + + union.getDefaultName = getDefaultName; + module.exports = union; + + + +/***/ }, +/* 206 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var FunctionType = __webpack_require__(176); + var isArray = __webpack_require__(170); + var list = __webpack_require__(195); + var isObject = __webpack_require__(169); + var create = __webpack_require__(184); + var isNil = __webpack_require__(159); + var isBoolean = __webpack_require__(173); + var tuple = __webpack_require__(204); + var getFunctionName = __webpack_require__(162); + var getTypeName = __webpack_require__(167); + var isType = __webpack_require__(168); + + function getDefaultName(domain, codomain) { + return '(' + domain.map(getTypeName).join(', ') + ') => ' + getTypeName(codomain); + } + + function isInstrumented(f) { + return FunctionType.is(f) && isObject(f.instrumentation); + } + + function getOptionalArgumentsIndex(types) { + var end = types.length; + var areAllMaybes = false; + for (var i = end - 1; i >= 0; i--) { + var type = types[i]; + if (!isType(type) || type.meta.kind !== 'maybe') { + return (i + 1); + } else { + areAllMaybes = true; + } + } + return areAllMaybes ? 0 : end; + } + + function func(domain, codomain, name) { + + domain = isArray(domain) ? domain : [domain]; // handle handy syntax for unary functions + + if (false) { + assert(list(FunctionType).is(domain), function () { return 'Invalid argument domain ' + assert.stringify(domain) + ' supplied to func(domain, codomain, [name]) combinator (expected an array of types)'; }); + assert(FunctionType.is(codomain), function () { return 'Invalid argument codomain ' + assert.stringify(codomain) + ' supplied to func(domain, codomain, [name]) combinator (expected a type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to func(domain, codomain, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(domain, codomain); + var domainLength = domain.length; + var optionalArgumentsIndex = getOptionalArgumentsIndex(domain); + + function FuncType(value, path) { + + if (!isInstrumented(value)) { // automatically instrument the function + return FuncType.of(value); + } + + if (false) { + path = path || [displayName]; + assert(FuncType.is(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); }); + } + + return value; + } + + FuncType.meta = { + kind: 'func', + domain: domain, + codomain: codomain, + name: name, + identity: true + }; + + FuncType.displayName = displayName; + + FuncType.is = function (x) { + return isInstrumented(x) && + x.instrumentation.domain.length === domainLength && + x.instrumentation.domain.every(function (type, i) { + return type === domain[i]; + }) && + x.instrumentation.codomain === codomain; + }; + + FuncType.of = function (f, curried) { + + if (false) { + assert(FunctionType.is(f), function () { return 'Invalid argument f supplied to func.of ' + displayName + ' (expected a function)'; }); + assert(isNil(curried) || isBoolean(curried), function () { return 'Invalid argument curried ' + assert.stringify(curried) + ' supplied to func.of ' + displayName + ' (expected a boolean)'; }); + } + + if (FuncType.is(f)) { // makes FuncType.of idempotent + return f; + } + + function fn() { + var args = Array.prototype.slice.call(arguments); + var argsLength = args.length; + + if (false) { + // type-check arguments + var tupleLength = curried ? argsLength : Math.max(argsLength, optionalArgumentsIndex); + tuple(domain.slice(0, tupleLength), 'arguments of function ' + displayName)(args); + } + + if (curried && argsLength < domainLength) { + if (false) { + assert(argsLength > 0, 'Invalid arguments.length = 0 for curried function ' + displayName); + } + var g = Function.prototype.bind.apply(f, [this].concat(args)); + var newDomain = func(domain.slice(argsLength), codomain); + return newDomain.of(g, true); + } + else { + return create(codomain, f.apply(this, args)); + } + } + + fn.instrumentation = { + domain: domain, + codomain: codomain, + f: f + }; + + fn.displayName = getFunctionName(f); + + return fn; + + }; + + return FuncType; + + } + + func.getDefaultName = getDefaultName; + func.getOptionalArgumentsIndex = getOptionalArgumentsIndex; + module.exports = func; + + +/***/ }, +/* 207 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var isFunction = __webpack_require__(158); + var isArray = __webpack_require__(170); + var forbidNewOperator = __webpack_require__(183); + var is = __webpack_require__(185); + var getTypeName = __webpack_require__(167); + var isIdentity = __webpack_require__(183); + + function getDefaultName(types) { + return types.map(getTypeName).join(' & '); + } + + function intersection(types, name) { + + if (false) { + assert(isArray(types) && types.every(isFunction) && types.length >= 2, function () { return 'Invalid argument types ' + assert.stringify(types) + ' supplied to intersection(types, [name]) combinator (expected an array of at least 2 types)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to intersection(types, [name]) combinator (expected a string)'; }); + } + + var displayName = name || getDefaultName(types); + var identity = types.every(isIdentity); + + function Intersection(value, path) { + + if (false) { + if (identity) { + forbidNewOperator(this, Intersection); + } + path = path || [displayName]; + assert(Intersection.is(value), function () { return 'Invalid value ' + assert.stringify(value) + ' supplied to ' + path.join('/'); }); + } + + return value; + } + + Intersection.meta = { + kind: 'intersection', + types: types, + name: name, + identity: identity + }; + + Intersection.displayName = displayName; + + Intersection.is = function (x) { + return types.every(function (type) { + return is(x, type); + }); + }; + + Intersection.update = function (instance, patch) { + return Intersection(assert.update(instance, patch)); + }; + + return Intersection; + } + + intersection.getDefaultName = getDefaultName; + module.exports = intersection; + + + +/***/ }, +/* 208 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isTypeName = __webpack_require__(182); + var String = __webpack_require__(188); + var Function = __webpack_require__(176); + var isBoolean = __webpack_require__(173); + var isObject = __webpack_require__(169); + var isNil = __webpack_require__(159); + var create = __webpack_require__(184); + var getTypeName = __webpack_require__(167); + var dict = __webpack_require__(190); + var getDefaultInterfaceName = __webpack_require__(199); + var isIdentity = __webpack_require__(183); + var is = __webpack_require__(185); + var extend = __webpack_require__(200); + var assign = __webpack_require__(209); + + function extendInterface(mixins, name) { + return extend(inter, mixins, name); + } + + function getOptions(options) { + if (!isObject(options)) { + options = isNil(options) ? {} : { name: options }; + } + if (!options.hasOwnProperty('strict')) { + options.strict = inter.strict; + } + return options; + } + + function inter(props, options) { + + options = getOptions(options); + var name = options.name; + var strict = options.strict; + + if (false) { + assert(dict(String, Function).is(props), function () { return 'Invalid argument props ' + assert.stringify(props) + ' supplied to interface(props, [options]) combinator (expected a dictionary String -> Type)'; }); + assert(isTypeName(name), function () { return 'Invalid argument name ' + assert.stringify(name) + ' supplied to interface(props, [options]) combinator (expected a string)'; }); + assert(isBoolean(strict), function () { return 'Invalid argument strict ' + assert.stringify(strict) + ' supplied to struct(props, [options]) combinator (expected a boolean)'; }); + } + + var displayName = name || getDefaultInterfaceName(props); + var identity = Object.keys(props).map(function (prop) { return props[prop]; }).every(isIdentity); + + function Interface(value, path) { + + if (true) { + if (identity) { + return value; // just trust the input if elements must not be hydrated + } + } + + if (false) { + path = path || [displayName]; + assert(!isNil(value), function () { return 'Invalid value ' + value + ' supplied to ' + path.join('/'); }); + // strictness + if (strict) { + for (var k in value) { + assert(props.hasOwnProperty(k), function () { return 'Invalid additional prop "' + k + '" supplied to ' + path.join('/'); }); + } + } + } + + var idempotent = true; + var ret = identity ? {} : assign({}, value); + for (var prop in props) { + var expected = props[prop]; + var actual = value[prop]; + var instance = create(expected, actual, ( false ? path.concat(prop + ': ' + getTypeName(expected)) : null )); + idempotent = idempotent && ( actual === instance ); + ret[prop] = instance; + } + + if (idempotent) { // implements idempotency + ret = value; + } + + if (false) { + Object.freeze(ret); + } + + return ret; + + } + + Interface.meta = { + kind: 'interface', + props: props, + name: name, + identity: identity, + strict: strict + }; + + Interface.displayName = displayName; + + Interface.is = function (x) { + if (isNil(x)) { + return false; + } + if (strict) { + for (var k in x) { + if (!props.hasOwnProperty(k)) { + return false; + } + } + } + for (var prop in props) { + if (!is(x[prop], props[prop])) { + return false; + } + } + return true; + }; + + Interface.update = function (instance, patch) { + return Interface(assert.update(instance, patch)); + }; + + Interface.extend = function (xs, name) { + return extendInterface([Interface].concat(xs), name); + }; + + return Interface; + } + + inter.strict = false; + inter.getOptions = getOptions; + inter.getDefaultName = getDefaultInterfaceName; + inter.extend = extendInterface; + module.exports = inter; + + +/***/ }, +/* 209 */ +/***/ function(module, exports) { + + function assign(x, y) { + for (var k in y) { + x[k] = y[k]; + } + return x; + } + + module.exports = assign; + +/***/ }, +/* 210 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isObject = __webpack_require__(169); + var isFunction = __webpack_require__(158); + var isArray = __webpack_require__(170); + var isNumber = __webpack_require__(179); + var assign = __webpack_require__(209); + + function getShallowCopy(x) { + if (isObject(x)) { + if (x instanceof Date || x instanceof RegExp) { + return x; + } + return assign({}, x); + } + if (isArray(x)) { + return x.concat(); + } + return x; + } + + function isCommand(k) { + return update.commands.hasOwnProperty(k); + } + + function getCommand(k) { + return update.commands[k]; + } + + function update(instance, patch) { + + if (false) { + assert(isObject(patch), function () { return 'Invalid argument patch ' + assert.stringify(patch) + ' supplied to function update(instance, patch): expected an object containing commands'; }); + } + + var value = instance; + var isChanged = false; + var newValue; + for (var k in patch) { + if (patch.hasOwnProperty(k)) { + if (isCommand(k)) { + newValue = getCommand(k)(patch[k], value); + if (newValue !== instance) { + isChanged = true; + value = newValue; + } else { + value = instance; + } + } + else { + if (value === instance) { + value = getShallowCopy(instance); + } + newValue = update(value[k], patch[k]); + isChanged = isChanged || ( newValue !== value[k] ); + value[k] = newValue; + } + } + } + return isChanged ? value : instance; + } + + // built-in commands + + function $apply(f, value) { + if (false) { + assert(isFunction(f), 'Invalid argument f supplied to immutability helper { $apply: f } (expected a function)'); + } + return f(value); + } + + function $push(elements, arr) { + if (false) { + assert(isArray(elements), 'Invalid argument elements supplied to immutability helper { $push: elements } (expected an array)'); + assert(isArray(arr), 'Invalid value supplied to immutability helper $push (expected an array)'); + } + if (elements.length > 0) { + return arr.concat(elements); + } + return arr; + } + + function $remove(keys, obj) { + if (false) { + assert(isArray(keys), 'Invalid argument keys supplied to immutability helper { $remove: keys } (expected an array)'); + assert(isObject(obj), 'Invalid value supplied to immutability helper $remove (expected an object)'); + } + if (keys.length > 0) { + obj = getShallowCopy(obj); + for (var i = 0, len = keys.length; i < len; i++ ) { + delete obj[keys[i]]; + } + } + return obj; + } + + function $set(value) { + return value; + } + + function $splice(splices, arr) { + if (false) { + assert(isArray(splices) && splices.every(isArray), 'Invalid argument splices supplied to immutability helper { $splice: splices } (expected an array of arrays)'); + assert(isArray(arr), 'Invalid value supplied to immutability helper $splice (expected an array)'); + } + if (splices.length > 0) { + arr = getShallowCopy(arr); + return splices.reduce(function (acc, splice) { + acc.splice.apply(acc, splice); + return acc; + }, arr); + } + return arr; + } + + function $swap(config, arr) { + if (false) { + assert(isObject(config), 'Invalid argument config supplied to immutability helper { $swap: config } (expected an object)'); + assert(isNumber(config.from), 'Invalid argument config.from supplied to immutability helper { $swap: config } (expected a number)'); + assert(isNumber(config.to), 'Invalid argument config.to supplied to immutability helper { $swap: config } (expected a number)'); + assert(isArray(arr), 'Invalid value supplied to immutability helper $swap (expected an array)'); + } + if (config.from !== config.to) { + arr = getShallowCopy(arr); + var element = arr[config.to]; + arr[config.to] = arr[config.from]; + arr[config.from] = element; + } + return arr; + } + + function $unshift(elements, arr) { + if (false) { + assert(isArray(elements), 'Invalid argument elements supplied to immutability helper {$unshift: elements} (expected an array)'); + assert(isArray(arr), 'Invalid value supplied to immutability helper $unshift (expected an array)'); + } + if (elements.length > 0) { + return elements.concat(arr); + } + return arr; + } + + function $merge(whatToMerge, value) { + var isChanged = false; + var result = getShallowCopy(value); + for (var k in whatToMerge) { + if (whatToMerge.hasOwnProperty(k)) { + result[k] = whatToMerge[k]; + isChanged = isChanged || ( result[k] !== value[k] ); + } + } + return isChanged ? result : value; + } + + update.commands = { + $apply: $apply, + $push: $push, + $remove: $remove, + $set: $set, + $splice: $splice, + $swap: $swap, + $unshift: $unshift, + $merge: $merge + }; + + module.exports = update; + + +/***/ }, +/* 211 */ +/***/ function(module, exports, __webpack_require__) { + + var assert = __webpack_require__(157); + var isFunction = __webpack_require__(158); + var isType = __webpack_require__(168); + var Any = __webpack_require__(163); + + module.exports = function match(x) { + var type, guard, f, count; + for (var i = 1, len = arguments.length; i < len; ) { + type = arguments[i]; + guard = arguments[i + 1]; + f = arguments[i + 2]; + + if (isFunction(f) && !isType(f)) { + i = i + 3; + } + else { + f = guard; + guard = Any.is; + i = i + 2; + } + + if (false) { + count = (count || 0) + 1; + assert(isType(type), function () { return 'Invalid type in clause #' + count; }); + assert(isFunction(guard), function () { return 'Invalid guard in clause #' + count; }); + assert(isFunction(f), function () { return 'Invalid block in clause #' + count; }); + } + + if (type.is(x) && guard(x)) { + return f(x); + } + } + assert.fail('Match error'); + }; + + +/***/ }, +/* 212 */ +/***/ function(module, exports, __webpack_require__) { + + const { BreakpointResult, Location } = __webpack_require__(155); + const defer = __webpack_require__(154); + + let bpClients; + let threadClient; + let tabTarget; + let debuggerClient; + let propertiesRequestCache = new Set(); + + function setupCommands(dependencies) { + threadClient = dependencies.threadClient; + tabTarget = dependencies.tabTarget; + debuggerClient = dependencies.debuggerClient; + bpClients = {}; + } + + function resume() { + return new Promise(resolve => { + threadClient.resume(resolve); + }); + } + + function stepIn() { + return new Promise(resolve => { + threadClient.stepIn(resolve); + }); + } + + function stepOver() { + return new Promise(resolve => { + threadClient.stepOver(resolve); + }); + } + + function stepOut() { + return new Promise(resolve => { + threadClient.stepOut(resolve); + }); + } + + function breakOnNext() { + return threadClient.breakOnNext(); + } + + function sourceContents(sourceId) { + const sourceClient = threadClient.source({ actor: sourceId }); + return sourceClient.source(); + } + + function setBreakpoint(location, condition, noSliding) { + const sourceClient = threadClient.source({ actor: location.sourceId }); + + return sourceClient.setBreakpoint({ + line: location.line, + column: location.column, + condition, + noSliding + }).then(res => onNewBreakpoint(location, res)); + } + + function onNewBreakpoint(location, res) { + const bpClient = res[1]; + let actualLocation = res[0].actualLocation; + bpClients[bpClient.actor] = bpClient; + + // Firefox only returns `actualLocation` if it actually changed, + // but we want it always to exist. Format `actualLocation` if it + // exists, otherwise use `location`. + actualLocation = actualLocation ? { + sourceId: actualLocation.source.actor, + line: actualLocation.line, + column: actualLocation.column + } : location; + + return BreakpointResult({ + id: bpClient.actor, + actualLocation: Location(actualLocation) + }); + } + + function removeBreakpoint(breakpointId) { + const bpClient = bpClients[breakpointId]; + bpClients[breakpointId] = null; + return bpClient.remove(); + } + + function setBreakpointCondition(breakpointId, location, condition, noSliding) { + let bpClient = bpClients[breakpointId]; + bpClients[breakpointId] = null; + + return bpClient.setCondition(threadClient, condition, noSliding).then(_bpClient => onNewBreakpoint(location, [{}, _bpClient])); + } + + function evaluate(script, { frameId }) { + const params = frameId ? { frameActor: frameId } : {}; + const deferred = defer(); + + tabTarget.activeConsole.evaluateJS(script, result => { + deferred.resolve(result); + }, params); + + return deferred.promise; + } + + function debuggeeCommand(script) { + tabTarget.activeConsole.evaluateJS(script, () => {}); + + const consoleActor = tabTarget.form.consoleActor; + const request = debuggerClient._activeRequests.get(consoleActor); + request.emit("json-reply", {}); + debuggerClient._activeRequests.delete(consoleActor); + + return Promise.resolve(); + } + + function navigate(url) { + return tabTarget.activeTab.navigateTo(url); + } + + function reload() { + return tabTarget.activeTab.reload(); + } + + function getProperties(grip) { + if (propertiesRequestCache.has(grip.actor)) { + return Promise.resolve(); + } + + propertiesRequestCache.add(grip.actor); + const objClient = threadClient.pauseGrip(grip); + + return objClient.getPrototypeAndProperties().then(resp => { + return resp; + }); + } + + function pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) { + return threadClient.pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions); + } + + function prettyPrint(sourceId, indentSize) { + const sourceClient = threadClient.source({ actor: sourceId }); + return sourceClient.prettyPrint(indentSize); + } + + function disablePrettyPrint(sourceId) { + const sourceClient = threadClient.source({ actor: sourceId }); + return sourceClient.disablePrettyPrint(); + } + + function interrupt() { + return threadClient.interrupt(); + } + + function eventListeners() { + return threadClient.eventListeners(); + } + + function pauseGrip(func) { + return threadClient.pauseGrip(func); + } + + const clientCommands = { + interrupt, + eventListeners, + pauseGrip, + resume, + stepIn, + stepOut, + stepOver, + breakOnNext, + sourceContents, + setBreakpoint, + removeBreakpoint, + setBreakpointCondition, + evaluate, + debuggeeCommand, + navigate, + reload, + getProperties, + pauseOnExceptions, + prettyPrint, + disablePrettyPrint + }; + + module.exports = { + setupCommands, + clientCommands + }; + +/***/ }, +/* 213 */ +/***/ function(module, exports, __webpack_require__) { + + let paused = (() => { + var _ref = _asyncToGenerator(function* (_, packet) { + // If paused by an explicit interrupt, which are generated by the + // slow script dialog and internal events such as setting + // breakpoints, ignore the event. + if (packet.why.type === "interrupted" && !packet.why.onNext) { + return; + } + + // Eagerly fetch the frames + const response = yield threadClient.getFrames(0, CALL_STACK_PAGE_SIZE); + const frames = response.frames.map(createFrame); + + const pause = Object.assign({}, packet, { + frame: createFrame(packet.frame), + frames: frames + }); + + actions.paused(pause); + }); + + return function paused(_x, _x2) { + return _ref.apply(this, arguments); + }; + })(); + + function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + + const { createFrame, createSource } = __webpack_require__(214); + const { isEnabled } = __webpack_require__(102); + + const CALL_STACK_PAGE_SIZE = 1000; + + let threadClient; + let actions; + + function setupEvents(dependencies) { + threadClient = dependencies.threadClient; + actions = dependencies.actions; + } + + function resumed(_, packet) { + actions.resumed(packet); + } + + function newSource(_, { source }) { + actions.newSource(createSource(source)); + + if (isEnabled("eventListeners")) { + actions.fetchEventListeners(); + } + } + + const clientEvents = { + paused, + resumed, + newSource + }; + + module.exports = { + setupEvents, + clientEvents + }; + +/***/ }, +/* 214 */ +/***/ function(module, exports, __webpack_require__) { + + const { Source, Frame, Location } = __webpack_require__(155); + + function createFrame(frame) { + let title; + if (frame.type == "call") { + let c = frame.callee; + title = c.name || c.userDisplayName || c.displayName || "(anonymous)"; + } else { + title = `(${ frame.type })`; + } + + return Frame({ + id: frame.actor, + displayName: title, + location: Location({ + sourceId: frame.where.source.actor, + line: frame.where.line, + column: frame.where.column + }), + this: frame.this, + scope: frame.environment + }); + } + + function createSource(source) { + return Source({ + id: source.actor, + url: source.url, + isPrettyPrinted: false, + sourceMapURL: source.sourceMapURL + }); + } + + module.exports = { createFrame, createSource }; + +/***/ }, +/* 215 */ +/***/ function(module, exports, __webpack_require__) { + + const CDP = __webpack_require__(216); + const { getValue } = __webpack_require__(102); + const networkRequest = __webpack_require__(217); + const { setupCommands, clientCommands } = __webpack_require__(218); + const { setupEvents, clientEvents } = __webpack_require__(219); + const { Tab } = __webpack_require__(155); + + // TODO: figure out a way to avoid patching native prototypes. + // Unfortunately the Chrome client requires it to work. + + Array.prototype.peekLast = function () { + // eslint-disable-line + return this[this.length - 1]; + }; + + let connection; + + function createTabs(tabs, { type, clientType } = {}) { + return tabs.filter(tab => { + return tab.type == type; + }).map(tab => { + return Tab({ + title: tab.title, + url: tab.url, + id: tab.id, + tab, + clientType + }); + }); + } + + window.criRequest = function (options, callback) { + const { host, port, path } = options; + const url = `http://${ host }:${ port }${ path }`; + + networkRequest(url).then(res => callback(null, res.content)).catch(err => callback(err)); + }; + + function connectClient() { + if (!getValue("chrome.debug")) { + return Promise.resolve(createTabs([])); + } + + return CDP.List({ + port: getValue("chrome.port"), + host: getValue("chrome.host") + }).then(tabs => createTabs(tabs, { + clientType: "chrome", type: "page" + })); + } + + function connectNodeClient() { + if (!getValue("node.debug")) { + return Promise.resolve(createTabs([])); + } + + return CDP.List({ + port: getValue("node.port"), + host: getValue("node.host") + }).then(tabs => createTabs(tabs, { + clientType: "node", type: "node" + })); + } + + function connectTab(tab) { + return CDP({ tab: tab.webSocketDebuggerUrl }).then(conn => { + connection = conn; + }); + } + + function connectNode(tab) { + return CDP({ tab: tab.webSocketDebuggerUrl }).then(conn => { + connection = conn; + }); + } + + function initPage(actions, { clientType }) { + const { Debugger, Runtime, Page } = connection; + + setupCommands({ Debugger, Runtime, Page }); + setupEvents({ actions, Page, clientType }); + + Debugger.enable(); + Debugger.setPauseOnExceptions({ state: "none" }); + Debugger.setAsyncCallStackDepth({ maxDepth: 0 }); + + Runtime.enable(); + + if (clientType == "node") { + Runtime.runIfWaitingForDebugger(); + } + + if (clientType == "chrome") { + Page.enable(); + } + + Debugger.scriptParsed(clientEvents.scriptParsed); + Debugger.scriptFailedToParse(clientEvents.scriptFailedToParse); + Debugger.paused(clientEvents.paused); + Debugger.resumed(clientEvents.resumed); + } + + module.exports = { + connectClient, + connectNodeClient, + clientCommands, + connectNode, + connectTab, + initPage + }; + +/***/ }, +/* 216 */ +/***/ function(module, exports) { + + module.exports=function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){(function(t){"use strict";var i=n(2),r=n(3),o=n(41);e.exports=function(e,n){"function"==typeof e&&(n=e,e=void 0);var r=new i;return"function"==typeof n?(t.nextTick(function(){new o(e,r)}),r.on("connect",n)):new Promise(function(t,n){r.on("connect",t),r.on("error",n),r.on("disconnect",function(){n(new Error("Disconnected"))}),new o(e,r)})},e.exports.listTabs=r.List,e.exports.spawnTab=r.New,e.exports.closeTab=r.Close,e.exports.Protocol=r.Protocol,e.exports.List=r.List,e.exports.New=r.New,e.exports.Activate=r.Activate,e.exports.Close=r.Close,e.exports.Version=r.Version}).call(t,n(1))},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function i(){throw new Error("clearTimeout has not been defined")}function r(e){if(d===setTimeout)return setTimeout(e,0);if((d===n||!d)&&setTimeout)return d=setTimeout,setTimeout(e,0);try{return d(e,0)}catch(t){try{return d.call(null,e,0)}catch(t){return d.call(this,e,0)}}}function o(e){if(l===clearTimeout)return clearTimeout(e);if((l===i||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(e);try{return l(e)}catch(t){try{return l.call(null,e)}catch(t){return l.call(this,e)}}}function a(){f&&u&&(f=!1,u.length?h=u.concat(h):y=-1,h.length&&s())}function s(){if(!f){var e=r(a);f=!0;for(var t=h.length;t;){for(u=h,h=[];++y1)for(var n=1;n0&&this._events[e].length>r&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(e,t){function n(){this.removeListener(e,n),r||(r=!0,t.apply(this,arguments))}if(!i(t))throw TypeError("listener must be a function");var r=!1;return n.listener=t,this.on(e,n),this},n.prototype.removeListener=function(e,t){var n,r,a,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(n=this._events[e],a=n.length,r=-1,n===t||i(n.listener)&&n.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(o(n)){for(s=a;s-- >0;)if(n[s]===t||n[s].listener&&n[s].listener===t){r=s;break}if(r<0)return this;1===n.length?(n.length=0,delete this._events[e]):n.splice(r,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},n.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[e],i(n))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},n.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[]},n.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(i(t))return 1;if(t)return t.length}return 0},n.listenerCount=function(e,t){return e.listenerCount(t)}},function(e,t,n){(function(t){"use strict";function i(e,t){e.host=e.host||c.HOST,e.port=e.port||c.PORT,d(s,e,t)}function r(e){return function(t,n){return"function"==typeof t&&(n=t,t=void 0),t=t||{},"function"!=typeof n?new Promise(function(n,i){e(t,function(e,t){e?i(e):n(t)})}):void e(t,n)}}function o(e,n,i){function r(e){return e.split(".").map(function(e){return parseInt(e)})}var o=n["WebKit-Version"],a=n["V8-Version"],s=o.match(/\s\(@(\b[0-9a-f]{5,40}\b)/),c=s[1],l=c<=202666,m=void 0;if(l)m=["https://src.chromium.org/blink/trunk/Source/devtools/protocol.json?p="+c];else{var u="53.0.2758.1",h="55.0.2854.3",f=r(n.Browser.split("/")[1]),y=f[2]<=r(u)[2],g=f[2]<=r(h)[2];y?m=["https://chromium.googlesource.com/chromium/src/+/"+c+"/third_party/WebKit/Source/devtools/protocol.json?format=TEXT"]:g?m=["https://chromium.googlesource.com/chromium/src/+/"+c+"/third_party/WebKit/Source/core/inspector/browser_protocol.json?format=TEXT","https://chromium.googlesource.com/chromium/src/+/"+c+"/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json?format=TEXT"]:a?m=["https://chromium.googlesource.com/chromium/src/+/"+c+"/third_party/WebKit/Source/core/inspector/browser_protocol.json?format=TEXT","https://chromium.googlesource.com/v8/v8/+/"+a+"/src/inspector/js_protocol.json?format=TEXT"]:(console.error("Warning: the protocol might be outdated, see: https://groups.google.com/d/topic/chrome-debugging-protocol/HjyOKainKus/discussion"),m=["https://chromium.googlesource.com/chromium/src/+/"+c+"/third_party/WebKit/Source/core/inspector/browser_protocol.json?format=TEXT","https://chromium.googlesource.com/chromium/src/+/"+h+"/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json?format=TEXT"])}var b=[];m.forEach(function(e){d(p,e,function(e,n){var r=void 0;if(!e)try{l||(n=new t(n,"base64").toString()),r=JSON.parse(n)}catch(e){}if(b.push(r),b.length===m.length){if(b.indexOf(void 0)!==-1)return void i(new Error("Cannot fetch from Chromium repo"));b.forEach(function(e,t){0!==t&&Array.prototype.push.apply(b[0].domains,e.domains)}),i(null,b[0])}})})}function a(e,t,n){e.path="/json/protocol",i(e,function(e,t){e?n(e):n(null,JSON.parse(t))})}var s=n(8),p=n(37),c=n(38),d=n(39);e.exports.Protocol=r(function(t,i){if(!t.remote){var r=n(40);return void i(null,{remote:!1,descriptor:r})}e.exports.Version(t,function(e,n){if(e)return void i(e);var r=(n[0]||n).Browser,s=void 0;if(r.match(/^Chrome\//))s=o;else if(r.match(/^Microsoft Edge /))s=a;else{if(!r.match(/^node.js\//))return void i(new Error("Unknown implementation"));s=a}s(t,n,function(e,t){return e?void i(e):void i(null,{remote:!0,descriptor:t})})})}),e.exports.List=r(function(e,t){e.path="/json/list",i(e,function(e,n){e?t(e):t(null,JSON.parse(n))})}),e.exports.New=r(function(e,t){e.path="/json/new",Object.prototype.hasOwnProperty.call(e,"url")&&(e.path+="?"+e.url),i(e,function(e,n){e?t(e):t(null,JSON.parse(n))})}),e.exports.Activate=r(function(e,t){e.path="/json/activate/"+e.id,i(e,function(e){t(e?e:null)})}),e.exports.Close=r(function(e,t){e.path="/json/close/"+e.id,i(e,function(e){t(e?e:null)})}),e.exports.Version=r(function(e,t){e.path="/json/version",i(e,function(e,n){e?t(e):t(null,JSON.parse(n))})})}).call(t,n(4).Buffer)},function(e,t,n){(function(e,i){"use strict";function r(){try{var e=new Uint8Array(1);return e.__proto__={__proto__:Uint8Array.prototype,foo:function(){return 42}},42===e.foo()&&"function"==typeof e.subarray&&0===e.subarray(1,1).byteLength}catch(e){return!1}}function o(){return e.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function a(t,n){if(o()=o())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+o().toString(16)+" bytes");return 0|e}function y(t){return+t!=t&&(t=0),e.alloc(+t)}function g(t,n){if(e.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var i=t.length;if(0===i)return 0;for(var r=!1;;)switch(n){case"ascii":case"latin1":case"binary":return i;case"utf8":case"utf-8":case void 0:return z(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*i;case"hex":return i>>>1;case"base64":return Y(t).length;default:if(r)return z(t).length;n=(""+n).toLowerCase(),r=!0}}function b(e,t,n){var i=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if(n>>>=0,t>>>=0,n<=t)return"";for(e||(e="utf8");;)switch(e){case"hex":return D(this,t,n);case"utf8":case"utf-8":return j(this,t,n);case"ascii":return E(this,t,n);case"latin1":case"binary":return A(this,t,n);case"base64":return $(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return P(this,t,n);default:if(i)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),i=!0}}function v(e,t,n){var i=e[t];e[t]=e[n],e[n]=i}function w(t,n,i,r,o){if(0===t.length)return-1;if("string"==typeof i?(r=i,i=0):i>2147483647?i=2147483647:i<-2147483648&&(i=-2147483648),i=+i,isNaN(i)&&(i=o?0:t.length-1),i<0&&(i=t.length+i),i>=t.length){if(o)return-1;i=t.length-1}else if(i<0){if(!o)return-1;i=0}if("string"==typeof n&&(n=e.from(n,r)),e.isBuffer(n))return 0===n.length?-1:S(t,n,i,r,o);if("number"==typeof n)return n&=255,e.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(t,n,i):Uint8Array.prototype.lastIndexOf.call(t,n,i):S(t,[n],i,r,o);throw new TypeError("val must be string, number or Buffer")}function S(e,t,n,i,r){function o(e,t){return 1===a?e[t]:e.readUInt16BE(t*a)}var a=1,s=e.length,p=t.length;if(void 0!==i&&(i=String(i).toLowerCase(),"ucs2"===i||"ucs-2"===i||"utf16le"===i||"utf-16le"===i)){if(e.length<2||t.length<2)return-1;a=2,s/=2,p/=2,n/=2}var c;if(r){var d=-1;for(c=n;cs&&(n=s-p),c=n;c>=0;c--){for(var l=!0,m=0;mr&&(i=r)):i=r;var o=t.length;if(o%2!==0)throw new TypeError("Invalid hex string");i>o/2&&(i=o/2);for(var a=0;a239?4:o>223?3:o>191?2:1;if(r+s<=n){var p,c,d,l;switch(s){case 1:o<128&&(a=o);break;case 2:p=e[r+1],128===(192&p)&&(l=(31&o)<<6|63&p,l>127&&(a=l));break;case 3:p=e[r+1],c=e[r+2],128===(192&p)&&128===(192&c)&&(l=(15&o)<<12|(63&p)<<6|63&c,l>2047&&(l<55296||l>57343)&&(a=l));break;case 4:p=e[r+1],c=e[r+2],d=e[r+3],128===(192&p)&&128===(192&c)&&128===(192&d)&&(l=(15&o)<<18|(63&p)<<12|(63&c)<<6|63&d,l>65535&&l<1114112&&(a=l))}}null===a?(a=65533,s=1):a>65535&&(a-=65536,i.push(a>>>10&1023|55296),a=56320|1023&a),i.push(a),r+=s}return O(i)}function O(e){var t=e.length;if(t<=ee)return String.fromCharCode.apply(String,e);for(var n="",i=0;ii)&&(n=i);for(var r="",o=t;on)throw new RangeError("Trying to access beyond buffer length")}function N(t,n,i,r,o,a){if(!e.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(n>o||nt.length)throw new RangeError("Index out of range")}function M(e,t,n,i){t<0&&(t=65535+t+1);for(var r=0,o=Math.min(e.length-n,2);r>>8*(i?r:1-r)}function q(e,t,n,i){t<0&&(t=4294967295+t+1);for(var r=0,o=Math.min(e.length-n,4);r>>8*(i?r:3-r)&255}function U(e,t,n,i,r,o){if(n+i>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function _(e,t,n,i,r){return r||U(e,t,n,4,3.4028234663852886e38,-3.4028234663852886e38),Q.write(e,t,n,i,23,4),n+4}function F(e,t,n,i,r){return r||U(e,t,n,8,1.7976931348623157e308,-1.7976931348623157e308),Q.write(e,t,n,i,52,8),n+8}function B(e){if(e=W(e).replace(te,""),e.length<2)return"";for(;e.length%4!==0;)e+="=";return e}function W(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function H(e){return e<16?"0"+e.toString(16):e.toString(16)}function z(e,t){t=t||1/0;for(var n,i=e.length,r=null,o=[],a=0;a55295&&n<57344){if(!r){if(n>56319){(t-=3)>-1&&o.push(239,191,189);continue}if(a+1===i){(t-=3)>-1&&o.push(239,191,189);continue}r=n;continue}if(n<56320){(t-=3)>-1&&o.push(239,191,189),r=n;continue}n=(r-55296<<10|n-56320)+65536}else r&&(t-=3)>-1&&o.push(239,191,189);if(r=null,n<128){if((t-=1)<0)break;o.push(n)}else if(n<2048){if((t-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function V(e){for(var t=[],n=0;n>8,r=n%256,o.push(r),o.push(i);return o}function Y(e){return K.toByteArray(B(e))}function G(e,t,n,i){for(var r=0;r=t.length||r>=e.length);++r)t[r+n]=e[r];return r}function J(e){return e!==e}var K=n(5),Q=n(6),Z=n(7);t.Buffer=e,t.SlowBuffer=y,t.INSPECT_MAX_BYTES=50,e.TYPED_ARRAY_SUPPORT=void 0!==i.TYPED_ARRAY_SUPPORT?i.TYPED_ARRAY_SUPPORT:r(),t.kMaxLength=o(),e.poolSize=8192,e._augment=function(t){return t.__proto__=e.prototype,t},e.from=function(e,t,n){return s(null,e,t,n)},e.TYPED_ARRAY_SUPPORT&&(e.prototype.__proto__=Uint8Array.prototype,e.__proto__=Uint8Array,"undefined"!=typeof Symbol&&Symbol.species&&e[Symbol.species]===e&&Object.defineProperty(e,Symbol.species,{value:null,configurable:!0})),e.alloc=function(e,t,n){return c(null,e,t,n)},e.allocUnsafe=function(e){return d(null,e)},e.allocUnsafeSlow=function(e){return d(null,e)},e.isBuffer=function(e){return!(null==e||!e._isBuffer)},e.compare=function(t,n){if(!e.isBuffer(t)||!e.isBuffer(n))throw new TypeError("Arguments must be Buffers");if(t===n)return 0;for(var i=t.length,r=n.length,o=0,a=Math.min(i,r);o0&&(e=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(e+=" ... ")),""},e.prototype.compare=function(t,n,i,r,o){if(!e.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===n&&(n=0),void 0===i&&(i=t?t.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),n<0||i>t.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&n>=i)return 0;if(r>=o)return-1;if(n>=i)return 1;if(n>>>=0,i>>>=0,r>>>=0,o>>>=0,this===t)return 0;for(var a=o-r,s=i-n,p=Math.min(a,s),c=this.slice(r,o),d=t.slice(n,i),l=0;lr)&&(n=r),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");i||(i="utf8");for(var o=!1;;)switch(i){case"hex":return x(this,e,t,n);case"utf8":case"utf-8":return I(this,e,t,n);case"ascii":return T(this,e,t,n);case"latin1":case"binary":return R(this,e,t,n);case"base64":return k(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return C(this,e,t,n);default:if(o)throw new TypeError("Unknown encoding: "+i);i=(""+i).toLowerCase(),o=!0}},e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var ee=4096;e.prototype.slice=function(t,n){var i=this.length;t=~~t,n=void 0===n?i:~~n,t<0?(t+=i,t<0&&(t=0)):t>i&&(t=i),n<0?(n+=i,n<0&&(n=0)):n>i&&(n=i),n0&&(r*=256);)i+=this[e+--t]*r;return i},e.prototype.readUInt8=function(e,t){return t||L(e,1,this.length),this[e]},e.prototype.readUInt16LE=function(e,t){return t||L(e,2,this.length),this[e]|this[e+1]<<8},e.prototype.readUInt16BE=function(e,t){return t||L(e,2,this.length),this[e]<<8|this[e+1]},e.prototype.readUInt32LE=function(e,t){return t||L(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},e.prototype.readUInt32BE=function(e,t){return t||L(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},e.prototype.readIntLE=function(e,t,n){e|=0,t|=0,n||L(e,t,this.length);for(var i=this[e],r=1,o=0;++o=r&&(i-=Math.pow(2,8*t)),i},e.prototype.readIntBE=function(e,t,n){e|=0,t|=0,n||L(e,t,this.length);for(var i=t,r=1,o=this[e+--i];i>0&&(r*=256);)o+=this[e+--i]*r;return r*=128,o>=r&&(o-=Math.pow(2,8*t)),o},e.prototype.readInt8=function(e,t){return t||L(e,1,this.length),128&this[e]?(255-this[e]+1)*-1:this[e]},e.prototype.readInt16LE=function(e,t){t||L(e,2,this.length);var n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},e.prototype.readInt16BE=function(e,t){t||L(e,2,this.length);var n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},e.prototype.readInt32LE=function(e,t){return t||L(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},e.prototype.readInt32BE=function(e,t){return t||L(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},e.prototype.readFloatLE=function(e,t){return t||L(e,4,this.length),Q.read(this,e,!0,23,4)},e.prototype.readFloatBE=function(e,t){return t||L(e,4,this.length),Q.read(this,e,!1,23,4)},e.prototype.readDoubleLE=function(e,t){return t||L(e,8,this.length),Q.read(this,e,!0,52,8)},e.prototype.readDoubleBE=function(e,t){return t||L(e,8,this.length),Q.read(this,e,!1,52,8)},e.prototype.writeUIntLE=function(e,t,n,i){if(e=+e,t|=0,n|=0,!i){var r=Math.pow(2,8*n)-1;N(this,e,t,n,r,0)}var o=1,a=0;for(this[t]=255&e;++a=0&&(a*=256);)this[t+o]=e/a&255;return t+n},e.prototype.writeUInt8=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,1,255,0),e.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[n]=255&t,n+1},e.prototype.writeUInt16LE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,2,65535,0),e.TYPED_ARRAY_SUPPORT?(this[n]=255&t,this[n+1]=t>>>8):M(this,t,n,!0),n+2},e.prototype.writeUInt16BE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,2,65535,0),e.TYPED_ARRAY_SUPPORT?(this[n]=t>>>8,this[n+1]=255&t):M(this,t,n,!1),n+2},e.prototype.writeUInt32LE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,4,4294967295,0),e.TYPED_ARRAY_SUPPORT?(this[n+3]=t>>>24,this[n+2]=t>>>16,this[n+1]=t>>>8,this[n]=255&t):q(this,t,n,!0),n+4},e.prototype.writeUInt32BE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,4,4294967295,0),e.TYPED_ARRAY_SUPPORT?(this[n]=t>>>24,this[n+1]=t>>>16,this[n+2]=t>>>8,this[n+3]=255&t):q(this,t,n,!1),n+4},e.prototype.writeIntLE=function(e,t,n,i){if(e=+e,t|=0,!i){var r=Math.pow(2,8*n-1);N(this,e,t,n,r-1,-r)}var o=0,a=1,s=0;for(this[t]=255&e;++o>0)-s&255;return t+n},e.prototype.writeIntBE=function(e,t,n,i){if(e=+e,t|=0,!i){var r=Math.pow(2,8*n-1);N(this,e,t,n,r-1,-r)}var o=n-1,a=1,s=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===s&&0!==this[t+o+1]&&(s=1),this[t+o]=(e/a>>0)-s&255;return t+n},e.prototype.writeInt8=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,1,127,-128),e.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[n]=255&t,n+1},e.prototype.writeInt16LE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,2,32767,-32768),e.TYPED_ARRAY_SUPPORT?(this[n]=255&t,this[n+1]=t>>>8):M(this,t,n,!0),n+2},e.prototype.writeInt16BE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,2,32767,-32768),e.TYPED_ARRAY_SUPPORT?(this[n]=t>>>8,this[n+1]=255&t):M(this,t,n,!1),n+2},e.prototype.writeInt32LE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,4,2147483647,-2147483648),e.TYPED_ARRAY_SUPPORT?(this[n]=255&t,this[n+1]=t>>>8,this[n+2]=t>>>16,this[n+3]=t>>>24):q(this,t,n,!0),n+4},e.prototype.writeInt32BE=function(t,n,i){return t=+t,n|=0,i||N(this,t,n,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),e.TYPED_ARRAY_SUPPORT?(this[n]=t>>>24,this[n+1]=t>>>16,this[n+2]=t>>>8,this[n+3]=255&t):q(this,t,n,!1),n+4},e.prototype.writeFloatLE=function(e,t,n){return _(this,e,t,!0,n)},e.prototype.writeFloatBE=function(e,t,n){return _(this,e,t,!1,n)},e.prototype.writeDoubleLE=function(e,t,n){return F(this,e,t,!0,n)},e.prototype.writeDoubleBE=function(e,t,n){return F(this,e,t,!1,n)},e.prototype.copy=function(t,n,i,r){if(i||(i=0),r||0===r||(r=this.length),n>=t.length&&(n=t.length),n||(n=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),t.length-n=0;--o)t[o+n]=this[o+i];else if(a<1e3||!e.TYPED_ARRAY_SUPPORT)for(o=0;o>>=0,i=void 0===i?this.length:i>>>0,t||(t=0);var a;if("number"==typeof t)for(a=n;a0)throw new Error("Invalid string. Length must be a multiple of 4");return"="===e[t-2]?2:"="===e[t-1]?1:0}function i(e){return 3*e.length/4-n(e)}function r(e){var t,i,r,o,a,s,p=e.length;a=n(e),s=new d(3*p/4-a),r=a>0?p-4:p;var l=0;for(t=0,i=0;t>16&255,s[l++]=o>>8&255,s[l++]=255&o;return 2===a?(o=c[e.charCodeAt(t)]<<2|c[e.charCodeAt(t+1)]>>4,s[l++]=255&o):1===a&&(o=c[e.charCodeAt(t)]<<10|c[e.charCodeAt(t+1)]<<4|c[e.charCodeAt(t+2)]>>2,s[l++]=o>>8&255,s[l++]=255&o),s}function o(e){return p[e>>18&63]+p[e>>12&63]+p[e>>6&63]+p[63&e]}function a(e,t,n){for(var i,r=[],a=t;ad?d:c+s));return 1===i?(t=e[n-1],r+=p[t>>2],r+=p[t<<4&63],r+="=="):2===i&&(t=(e[n-2]<<8)+e[n-1],r+=p[t>>10],r+=p[t>>4&63],r+=p[t<<2&63],r+="="),o.push(r),o.join("")}t.byteLength=i,t.toByteArray=r,t.fromByteArray=s;for(var p=[],c=[],d="undefined"!=typeof Uint8Array?Uint8Array:Array,l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",m=0,u=l.length;m>1,d=-7,l=n?r-1:0,m=n?-1:1,u=e[t+l];for(l+=m,o=u&(1<<-d)-1,u>>=-d,d+=s;d>0;o=256*o+e[t+l],l+=m,d-=8);for(a=o&(1<<-d)-1,o>>=-d,d+=i;d>0;a=256*a+e[t+l],l+=m,d-=8);if(0===o)o=1-c;else{if(o===p)return a?NaN:(u?-1:1)*(1/0);a+=Math.pow(2,i),o-=c}return(u?-1:1)*a*Math.pow(2,o-i)},t.write=function(e,t,n,i,r,o){var a,s,p,c=8*o-r-1,d=(1<>1,m=23===r?Math.pow(2,-24)-Math.pow(2,-77):0,u=i?0:o-1,h=i?1:-1,f=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,a=d):(a=Math.floor(Math.log(t)/Math.LN2),t*(p=Math.pow(2,-a))<1&&(a--,p*=2),t+=a+l>=1?m/p:m*Math.pow(2,1-l),t*p>=2&&(a++,p/=2),a+l>=d?(s=0,a=d):a+l>=1?(s=(t*p-1)*Math.pow(2,r),a+=l):(s=t*Math.pow(2,l-1)*Math.pow(2,r),a=0));r>=8;e[n+u]=255&s,u+=h,s/=256,r-=8);for(a=a<0;e[n+u]=255&a,u+=h,a/=256,c-=8);e[n+u-h]|=128*f}},function(e,t){var n={}.toString;e.exports=Array.isArray||function(e){return"[object Array]"==n.call(e)}},function(e,t,n){var i=e.exports,r=(n(2).EventEmitter,n(9)),o=n(31);i.request=function(e,t){"string"==typeof e&&(e=o.parse(e)),e||(e={}),e.host||e.port||(e.port=parseInt(window.location.port,10)),!e.host&&e.hostname&&(e.host=e.hostname),e.protocol||(e.scheme?e.protocol=e.scheme+":":e.protocol=window.location.protocol),e.host||(e.host=window.location.hostname||window.location.host),/:/.test(e.host)&&(e.port||(e.port=e.host.split(":")[1]),e.host=e.host.split(":")[0]),e.port||(e.port="https:"==e.protocol?443:80); + var n=new r(new a,e);return t&&n.on("response",t),n},i.get=function(e,t){e.method="GET";var n=i.request(e,t);return n.end(),n},i.Agent=function(){},i.Agent.defaultMaxSockets=4;var a=function(){if("undefined"==typeof window)throw new Error("no window object present");if(window.XMLHttpRequest)return window.XMLHttpRequest;if(window.ActiveXObject){for(var e=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Microsoft.XMLHTTP"],t=0;t0)if(t.ended&&!r){var s=new Error("stream.push() after EOF");e.emit("error",s)}else if(t.endEmitted&&r){var s=new Error("stream.unshift() after end event");e.emit("error",s)}else!t.decoder||r||i||(n=t.decoder.write(n)),r||(t.reading=!1),t.flowing&&0===t.length&&!t.sync?(e.emit("data",n),e.read(0)):(t.length+=t.objectMode?1:n.length,r?t.buffer.unshift(n):t.buffer.push(n),t.needReadable&&l(e)),u(e,t);else r||(t.reading=!1);return a(t)}function a(e){return!e.ended&&(e.needReadable||e.length=O)e=O;else{e--;for(var t=1;t<32;t<<=1)e|=e>>t;e++}return e}function p(e,t){return 0===t.length&&t.ended?0:t.objectMode?0===e?0:1:isNaN(e)||C.isNull(e)?t.flowing&&t.buffer.length?t.buffer[0].length:t.length:e<=0?0:(e>t.highWaterMark&&(t.highWaterMark=s(e)),e>t.length?t.ended?t.length:(t.needReadable=!0,0):e)}function c(e,t){var n=null;return C.isBuffer(t)||C.isString(t)||C.isNullOrUndefined(t)||e.objectMode||(n=new TypeError("Invalid non-string/buffer chunk")),n}function d(e,t){if(t.decoder&&!t.ended){var n=t.decoder.end();n&&n.length&&(t.buffer.push(n),t.length+=t.objectMode?1:n.length)}t.ended=!0,l(e)}function l(e){var n=e._readableState;n.needReadable=!1,n.emittedReadable||(j("emitReadable",n.flowing),n.emittedReadable=!0,n.sync?t.nextTick(function(){m(e)}):m(e))}function m(e){j("emit readable"),e.emit("readable"),b(e)}function u(e,n){n.readingMore||(n.readingMore=!0,t.nextTick(function(){h(e,n)}))}function h(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=r)n=o?i.join(""):T.concat(i,r),i.length=0;else if(e0)throw new Error("endReadable called on non-empty stream");n.endEmitted||(n.ended=!0,t.nextTick(function(){n.endEmitted||0!==n.length||(n.endEmitted=!0,e.readable=!1,e.emit("end"))}))}function S(e,t){for(var n=0,i=e.length;n0)&&(t.emittedReadable=!1),0===e&&t.needReadable&&(t.length>=t.highWaterMark||t.ended))return j("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?w(this):l(this),null;if(e=p(e,t),0===e&&t.ended)return 0===t.length&&w(this),null;var i=t.needReadable;j("need readable",i),(0===t.length||t.length-e0?v(e,t):null,C.isNull(r)&&(t.needReadable=!0,e=0),t.length-=e,0!==t.length||t.ended||(t.needReadable=!0),n!==e&&t.ended&&0===t.length&&w(this),C.isNull(r)||this.emit("data",r),r},r.prototype._read=function(e){this.emit("error",new Error("not implemented"))},r.prototype.pipe=function(e,n){function i(e){j("onunpipe"),e===l&&o()}function r(){j("onend"),e.end()}function o(){j("cleanup"),e.removeListener("close",p),e.removeListener("finish",c),e.removeListener("drain",y),e.removeListener("error",s),e.removeListener("unpipe",i),l.removeListener("end",r),l.removeListener("end",o),l.removeListener("data",a),!m.awaitDrain||e._writableState&&!e._writableState.needDrain||y()}function a(t){j("ondata");var n=e.write(t);!1===n&&(j("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++,l.pause())}function s(t){j("onerror",t),d(),e.removeListener("error",s),0===R.listenerCount(e,"error")&&e.emit("error",t)}function p(){e.removeListener("finish",c),d()}function c(){j("onfinish"),e.removeListener("close",p),d()}function d(){j("unpipe"),l.unpipe(e)}var l=this,m=this._readableState;switch(m.pipesCount){case 0:m.pipes=e;break;case 1:m.pipes=[m.pipes,e];break;default:m.pipes.push(e)}m.pipesCount+=1,j("pipe count=%d opts=%j",m.pipesCount,n);var u=(!n||n.end!==!1)&&e!==t.stdout&&e!==t.stderr,h=u?r:o;m.endEmitted?t.nextTick(h):l.once("end",h),e.on("unpipe",i);var y=f(l);return e.on("drain",y),l.on("data",a),e._events&&e._events.error?I(e._events.error)?e._events.error.unshift(s):e._events.error=[s,e._events.error]:e.on("error",s),e.once("close",p),e.once("finish",c),e.emit("pipe",l),m.flowing||(j("pipe resume"),l.resume()),e},r.prototype.unpipe=function(e){var t=this._readableState;if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this),this);if(!e){var n=t.pipes,i=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var r=0;r1){for(var n=[],i=0;i=this.charLength-this.charReceived?this.charLength-this.charReceived:e.length;if(e.copy(this.charBuffer,this.charReceived,0,n),this.charReceived+=n,this.charReceived=55296&&i<=56319)){if(this.charReceived=this.charLength=0,0===e.length)return t;break}this.charLength+=this.surrogateSize,t=""}this.detectIncompleteChar(e);var r=e.length;this.charLength&&(e.copy(this.charBuffer,0,e.length-this.charReceived,r),r-=this.charReceived),t+=e.toString(this.encoding,0,r);var r=t.length-1,i=t.charCodeAt(r);if(i>=55296&&i<=56319){var o=this.surrogateSize;return this.charLength+=o,this.charReceived+=o,this.charBuffer.copy(this.charBuffer,o,0,o),e.copy(this.charBuffer,0,0,o),t.substring(0,r)}return t},c.prototype.detectIncompleteChar=function(e){for(var t=e.length>=3?3:e.length;t>0;t--){var n=e[e.length-t];if(1==t&&n>>5==6){this.charLength=2;break}if(t<=2&&n>>4==14){this.charLength=3;break}if(t<=3&&n>>3==30){this.charLength=4;break}}this.charReceived=t},c.prototype.end=function(e){var t="";if(e&&e.length&&(t=this.write(e)),this.charReceived){var n=this.charReceived,i=this.charBuffer,r=this.encoding;t+=i.slice(0,n).toString(r)}return t}},function(e,t,n){function i(e,t){this.afterTransform=function(e,n){return r(t,e,n)},this.needTransform=!1,this.transforming=!1,this.writecb=null,this.writechunk=null}function r(e,t,n){var i=e._transformState;i.transforming=!1;var r=i.writecb;if(!r)return e.emit("error",new Error("no writecb in Transform class"));i.writechunk=null,i.writecb=null,p.isNullOrUndefined(n)||e.push(n),r&&r(t);var o=e._readableState;o.reading=!1,(o.needReadable||o.lengththis.offset&&(this.emit("data",t.slice(this.offset)),this.offset=t.length))};var p=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},function(e,t,n){(function(e,i){function r(e,n){var i={seen:[],stylize:a};return arguments.length>=3&&(i.depth=arguments[2]),arguments.length>=4&&(i.colors=arguments[3]),f(n)?i.showHidden=n:n&&t._extend(i,n),S(i.showHidden)&&(i.showHidden=!1),S(i.depth)&&(i.depth=2),S(i.colors)&&(i.colors=!1),S(i.customInspect)&&(i.customInspect=!0),i.colors&&(i.stylize=o),p(i,e,i.depth)}function o(e,t){var n=r.styles[t];return n?"["+r.colors[n][0]+"m"+e+"["+r.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function p(e,n,i){if(e.customInspect&&n&&k(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var r=n.inspect(i,e);return v(r)||(r=p(e,r,i)),r}var o=c(e,n);if(o)return o;var a=Object.keys(n),f=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),R(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return d(n);if(0===a.length){if(k(n)){var y=n.name?": "+n.name:"";return e.stylize("[Function"+y+"]","special")}if(x(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(T(n))return e.stylize(Date.prototype.toString.call(n),"date");if(R(n))return d(n)}var g="",b=!1,w=["{","}"];if(h(n)&&(b=!0,w=["[","]"]),k(n)){var S=n.name?": "+n.name:"";g=" [Function"+S+"]"}if(x(n)&&(g=" "+RegExp.prototype.toString.call(n)),T(n)&&(g=" "+Date.prototype.toUTCString.call(n)),R(n)&&(g=" "+d(n)),0===a.length&&(!b||0==n.length))return w[0]+g+w[1];if(i<0)return x(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special");e.seen.push(n);var I;return I=b?l(e,n,i,f,a):a.map(function(t){return m(e,n,i,f,t,b)}),e.seen.pop(),u(I,g,w)}function c(e,t){if(S(t))return e.stylize("undefined","undefined");if(v(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return b(t)?e.stylize(""+t,"number"):f(t)?e.stylize(""+t,"boolean"):y(t)?e.stylize("null","null"):void 0}function d(e){return"["+Error.prototype.toString.call(e)+"]"}function l(e,t,n,i,r){for(var o=[],a=0,s=t.length;a-1&&(s=o?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n"))):s=e.stylize("[Circular]","special")),S(a)){if(o&&r.match(/^\d+$/))return s;a=JSON.stringify(""+r),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function u(e,t,n){var i=0,r=e.reduce(function(e,t){return i++,t.indexOf("\n")>=0&&i++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return r>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function h(e){return Array.isArray(e)}function f(e){return"boolean"==typeof e}function y(e){return null===e}function g(e){return null==e}function b(e){return"number"==typeof e}function v(e){return"string"==typeof e}function w(e){return"symbol"==typeof e}function S(e){return void 0===e}function x(e){return I(e)&&"[object RegExp]"===$(e)}function I(e){return"object"==typeof e&&null!==e}function T(e){return I(e)&&"[object Date]"===$(e)}function R(e){return I(e)&&("[object Error]"===$(e)||e instanceof Error)}function k(e){return"function"==typeof e}function C(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function $(e){return Object.prototype.toString.call(e)}function j(e){return e<10?"0"+e.toString(10):e.toString(10)}function O(){var e=new Date,t=[j(e.getHours()),j(e.getMinutes()),j(e.getSeconds())].join(":");return[e.getDate(),L[e.getMonth()],t].join(" ")}function E(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var A=/%[sdj%]/g;t.format=function(e){if(!v(e)){for(var t=[],n=0;n=o)return e;switch(e){case"%s":return String(i[n++]);case"%d":return Number(i[n++]);case"%j":try{return JSON.stringify(i[n++])}catch(e){return"[Circular]"}default:return e}}),s=i[n];n>8-o%1*8)){if(r=t.charCodeAt(o+=.75),r>255)throw new e("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range.");n=n<<8|r}return s}),n.atob||(n.atob=function(t){if(t=t.replace(/=+$/,""),t.length%4==1)throw new e("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,r,o=0,a=0,s="";r=t.charAt(a++);~r&&(n=o%4?64*n+r:r,o++%4)?s+=String.fromCharCode(255&n>>(-2*o&6)):0)r=i.indexOf(r);return s})}()},function(e,t,n){function i(){this.protocol=null,this.slashes=null,this.auth=null,this.host=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.query=null,this.pathname=null,this.path=null,this.href=null}function r(e,t,n){if(e&&c(e)&&e instanceof i)return e;var r=new i;return r.parse(e,t,n),r}function o(e){return p(e)&&(e=r(e)),e instanceof i?e.format():i.prototype.format.call(e)}function a(e,t){return r(e,!1,!0).resolve(t)}function s(e,t){return e?r(e,!1,!0).resolveObject(t):t}function p(e){return"string"==typeof e}function c(e){return"object"==typeof e&&null!==e}function d(e){return null===e}function l(e){return null==e}var m=n(32);t.parse=r,t.resolve=a,t.resolveObject=s,t.format=o,t.Url=i;var u=/^([a-z0-9.+-]+:)/i,h=/:[0-9]*$/,f=["<",">",'"',"`"," ","\r","\n","\t"],y=["{","}","|","\\","^","`"].concat(f),g=["'"].concat(y),b=["%","/","?",";","#"].concat(g),v=["/","?","#"],w=255,S=/^[a-z0-9A-Z_-]{0,63}$/,x=/^([a-z0-9A-Z_-]{0,63})(.*)$/,I={javascript:!0,"javascript:":!0},T={javascript:!0,"javascript:":!0},R={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0},k=n(34);i.prototype.parse=function(e,t,n){if(!p(e))throw new TypeError("Parameter 'url' must be a string, not "+typeof e);var i=e;i=i.trim();var r=u.exec(i);if(r){r=r[0];var o=r.toLowerCase();this.protocol=o,i=i.substr(r.length)}if(n||r||i.match(/^\/\/[^@\/]+@[^@\/]+/)){var a="//"===i.substr(0,2);!a||r&&T[r]||(i=i.substr(2),this.slashes=!0)}if(!T[r]&&(a||r&&!R[r])){for(var s=-1,c=0;c127?"x":$[O];if(!j.match(S)){var A=y.slice(0,c),D=y.slice(c+1),P=$.match(x);P&&(A.push(P[1]),D.unshift(P[2])),D.length&&(i="/"+D.join(".")+i),this.hostname=A.join(".");break}}}if(this.hostname.length>w?this.hostname="":this.hostname=this.hostname.toLowerCase(),!f){for(var L=this.hostname.split("."),N=[],c=0;c0)&&n.host.split("@");y&&(n.auth=y.shift(),n.host=n.hostname=y.shift())}return n.search=e.search,n.query=e.query,d(n.pathname)&&d(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.href=n.format(),n}if(!h.length)return n.pathname=null,n.search?n.path="/"+n.search:n.path=null,n.href=n.format(),n;for(var g=h.slice(-1)[0],b=(n.host||e.host)&&("."===g||".."===g)||""===g,v=0,w=h.length;w>=0;w--)g=h[w],"."==g?h.splice(w,1):".."===g?(h.splice(w,1),v++):v&&(h.splice(w,1),v--);if(!m&&!u)for(;v--;v)h.unshift("..");!m||""===h[0]||h[0]&&"/"===h[0].charAt(0)||h.unshift(""),b&&"/"!==h.join("/").substr(-1)&&h.push("");var S=""===h[0]||h[0]&&"/"===h[0].charAt(0);if(f){n.hostname=n.host=S?"":h.length?h.shift():"";var y=!!(n.host&&n.host.indexOf("@")>0)&&n.host.split("@");y&&(n.auth=y.shift(),n.host=n.hostname=y.shift())}return m=m||n.host&&h.length,m&&!S&&h.unshift(""),h.length?n.pathname=h.join("/"):(n.pathname=null,n.path=null),d(n.pathname)&&d(n.search)||(n.path=(n.pathname?n.pathname:"")+(n.search?n.search:"")),n.auth=e.auth||n.auth,n.slashes=n.slashes||e.slashes,n.href=n.format(),n},i.prototype.parseHost=function(){var e=this.host,t=h.exec(e);t&&(t=t[0],":"!==t&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)}},function(e,t,n){var i;(function(e,r){!function(o){function a(e){throw RangeError(A[e])}function s(e,t){for(var n=e.length,i=[];n--;)i[n]=t(e[n]);return i}function p(e,t){var n=e.split("@"),i="";n.length>1&&(i=n[0]+"@",e=n[1]),e=e.replace(E,".");var r=e.split("."),o=s(r,t).join(".");return i+o}function c(e){for(var t,n,i=[],r=0,o=e.length;r=55296&&t<=56319&&r65535&&(e-=65536,t+=L(e>>>10&1023|55296),e=56320|1023&e),t+=L(e)}).join("")}function l(e){return e-48<10?e-22:e-65<26?e-65:e-97<26?e-97:S}function m(e,t){return e+22+75*(e<26)-((0!=t)<<5)}function u(e,t,n){var i=0;for(e=n?P(e/R):e>>1,e+=P(e/t);e>D*I>>1;i+=S)e=P(e/D);return P(i+(D+1)*e/(e+T))}function h(e){var t,n,i,r,o,s,p,c,m,h,f=[],y=e.length,g=0,b=C,v=k;for(n=e.lastIndexOf($),n<0&&(n=0),i=0;i=128&&a("not-basic"),f.push(e.charCodeAt(i));for(r=n>0?n+1:0;r=y&&a("invalid-input"),c=l(e.charCodeAt(r++)),(c>=S||c>P((w-g)/s))&&a("overflow"),g+=c*s,m=p<=v?x:p>=v+I?I:p-v,!(cP(w/h)&&a("overflow"),s*=h;t=f.length+1,v=u(g-o,t,0==o),P(g/t)>w-b&&a("overflow"),b+=P(g/t),g%=t,f.splice(g++,0,b)}return d(f)}function f(e){var t,n,i,r,o,s,p,d,l,h,f,y,g,b,v,T=[];for(e=c(e),y=e.length,t=C,n=0,o=k,s=0;s=t&&fP((w-n)/g)&&a("overflow"),n+=(p-t)*g,t=p,s=0;sw&&a("overflow"),f==t){for(d=n,l=S;h=l<=o?x:l>=o+I?I:l-o,!(d= 0x80 (not a basic code point)","invalid-input":"Invalid input"},D=S-x,P=Math.floor,L=String.fromCharCode;v={version:"1.3.2",ucs2:{decode:c,encode:d},decode:h,encode:f,toASCII:g,toUnicode:y},i=function(){return v}.call(t,n,t,e),!(void 0!==i&&(e.exports=i))}(this)}).call(t,n(33)(e),function(){return this}())},function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children=[],e.webpackPolyfill=1),e}},function(e,t,n){"use strict";t.decode=t.parse=n(35),t.encode=t.stringify=n(36)},function(e,t){"use strict";function n(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,t,i,r){t=t||"&",i=i||"=";var o={};if("string"!=typeof e||0===e.length)return o;var a=/\+/g;e=e.split(t);var s=1e3;r&&"number"==typeof r.maxKeys&&(s=r.maxKeys);var p=e.length;s>0&&p>s&&(p=s);for(var c=0;c=0?(d=h.substr(0,f),l=h.substr(f+1)):(d=h,l=""),m=decodeURIComponent(d),u=decodeURIComponent(l),n(o,m)?Array.isArray(o[m])?o[m].push(u):o[m]=[o[m],u]:o[m]=u}return o}},function(e,t){"use strict";var n=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,t,i,r){return t=t||"&",i=i||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map(function(r){var o=encodeURIComponent(n(r))+i;return Array.isArray(e[r])?e[r].map(function(e){return o+encodeURIComponent(n(e))}).join(t):o+encodeURIComponent(n(e[r]))}).join(t):r?encodeURIComponent(n(r))+i+encodeURIComponent(n(e)):""}},function(e,t,n){var i=n(8),r=e.exports;for(var o in i)i.hasOwnProperty(o)&&(r[o]=i[o]);r.request=function(e,t){return e||(e={}),e.scheme="https",i.request.call(this,e,t)}},function(e,t){"use strict";e.exports.HOST="localhost",e.exports.PORT=9222},function(e,t){e.exports=function(e,t,n){window.criRequest(t,n)}},function(e,t){e.exports={version:{major:"1",minor:"2"},domains:[{domain:"Inspector",experimental:!0,types:[],commands:[{name:"enable",description:"Enables inspector domain notifications."},{name:"disable",description:"Disables inspector domain notifications."}],events:[{name:"detached",description:"Fired when remote debugging connection is about to be terminated. Contains detach reason.",parameters:[{name:"reason",type:"string",description:"The reason why connection has been terminated."}]},{name:"targetCrashed",description:"Fired when debugging target has crashed"}]},{domain:"Memory",experimental:!0,types:[{id:"PressureLevel",type:"string",enum:["moderate","critical"],description:"Memory pressure level."}],commands:[{name:"getDOMCounters",returns:[{name:"documents",type:"integer"},{name:"nodes",type:"integer"},{name:"jsEventListeners",type:"integer"}]},{name:"setPressureNotificationsSuppressed",description:"Enable/disable suppressing memory pressure notifications in all processes.",parameters:[{name:"suppressed",type:"boolean",description:"If true, memory pressure notifications will be suppressed."}]},{name:"simulatePressureNotification",description:"Simulate a memory pressure notification in all processes.",parameters:[{name:"level",$ref:"PressureLevel",description:"Memory pressure level of the notification."}]}]},{domain:"Page",description:"Actions and events related to the inspected page belong to the page domain.",dependencies:["Debugger","DOM"],types:[{id:"ResourceType",type:"string",enum:["Document","Stylesheet","Image","Media","Font","Script","TextTrack","XHR","Fetch","EventSource","WebSocket","Manifest","Other"],description:"Resource type as it was perceived by the rendering engine."},{id:"FrameId",type:"string",description:"Unique frame identifier."},{id:"Frame",type:"object",description:"Information about the Frame on the page.",properties:[{name:"id",type:"string",description:"Frame unique identifier."},{name:"parentId",type:"string",optional:!0,description:"Parent frame identifier."},{name:"loaderId",$ref:"Network.LoaderId",description:"Identifier of the loader associated with this frame."},{name:"name",type:"string",optional:!0,description:"Frame's name as specified in the tag."},{name:"url",type:"string",description:"Frame document's URL."},{name:"securityOrigin",type:"string",description:"Frame document's security origin."},{name:"mimeType",type:"string",description:"Frame document's mimeType as determined by the browser."}]},{id:"FrameResource",type:"object",description:"Information about the Resource on the page.",properties:[{name:"url",type:"string",description:"Resource URL."},{name:"type",$ref:"ResourceType",description:"Type of this resource."},{name:"mimeType",type:"string",description:"Resource mimeType as determined by the browser."},{name:"lastModified",$ref:"Network.Timestamp",description:"last-modified timestamp as reported by server.",optional:!0},{name:"contentSize",type:"number",description:"Resource content size.",optional:!0},{name:"failed",type:"boolean",optional:!0,description:"True if the resource failed to load."},{name:"canceled",type:"boolean",optional:!0,description:"True if the resource was canceled during loading."}],experimental:!0},{id:"FrameResourceTree",type:"object",description:"Information about the Frame hierarchy along with their cached resources.",properties:[{name:"frame",$ref:"Frame",description:"Frame information for this tree item."},{name:"childFrames",type:"array",optional:!0,items:{$ref:"FrameResourceTree"},description:"Child frames."},{name:"resources",type:"array",items:{$ref:"FrameResource"},description:"Information about frame resources."}],experimental:!0},{id:"ScriptIdentifier",type:"string",description:"Unique script identifier.",experimental:!0},{id:"NavigationEntry",type:"object",description:"Navigation history entry.",properties:[{name:"id",type:"integer",description:"Unique id of the navigation history entry."},{name:"url",type:"string",description:"URL of the navigation history entry."},{name:"title",type:"string",description:"Title of the navigation history entry."}],experimental:!0},{id:"ScreencastFrameMetadata",type:"object",description:"Screencast frame metadata.",properties:[{name:"offsetTop",type:"number",experimental:!0,description:"Top offset in DIP."},{name:"pageScaleFactor",type:"number",experimental:!0,description:"Page scale factor."},{name:"deviceWidth",type:"number",experimental:!0,description:"Device screen width in DIP."},{name:"deviceHeight",type:"number",experimental:!0,description:"Device screen height in DIP."},{name:"scrollOffsetX",type:"number",experimental:!0,description:"Position of horizontal scroll in CSS pixels."},{name:"scrollOffsetY",type:"number",experimental:!0,description:"Position of vertical scroll in CSS pixels."},{name:"timestamp",type:"number",optional:!0,experimental:!0,description:"Frame swap timestamp."}],experimental:!0},{id:"DialogType",description:"Javascript dialog type.",type:"string",enum:["alert","confirm","prompt","beforeunload"],experimental:!0},{id:"AppManifestError",description:"Error while paring app manifest.",type:"object",properties:[{name:"message",type:"string",description:"Error message."},{name:"critical",type:"integer",description:"If criticial, this is a non-recoverable parse error."},{name:"line",type:"integer",description:"Error line."},{name:"column",type:"integer",description:"Error column."}],experimental:!0},{id:"NavigationResponse",description:"Proceed: allow the navigation; Cancel: cancel the navigation; CancelAndIgnore: cancels the navigation and makes the requester of the navigation acts like the request was never made.",type:"string",enum:["Proceed","Cancel","CancelAndIgnore"],experimental:!0},{id:"LayoutViewport",type:"object",description:"Layout viewport position and dimensions.",experimental:!0,properties:[{name:"pageX",type:"integer",description:"Horizontal offset relative to the document (CSS pixels)."},{name:"pageY",type:"integer",description:"Vertical offset relative to the document (CSS pixels)."},{name:"clientWidth",type:"integer",description:"Width (CSS pixels), excludes scrollbar if present."},{name:"clientHeight",type:"integer",description:"Height (CSS pixels), excludes scrollbar if present."}]},{id:"VisualViewport",type:"object",description:"Visual viewport position, dimensions, and scale.",experimental:!0,properties:[{name:"offsetX",type:"number",description:"Horizontal offset relative to the layout viewport (CSS pixels)."},{name:"offsetY",type:"number",description:"Vertical offset relative to the layout viewport (CSS pixels)."},{name:"pageX",type:"number",description:"Horizontal offset relative to the document (CSS pixels)."},{name:"pageY",type:"number",description:"Vertical offset relative to the document (CSS pixels)."},{name:"clientWidth",type:"number",description:"Width (CSS pixels), excludes scrollbar if present."},{name:"clientHeight",type:"number",description:"Height (CSS pixels), excludes scrollbar if present."},{name:"scale",type:"number",description:"Scale relative to the ideal viewport (size at width=device-width)."}]}],commands:[{name:"enable",description:"Enables page domain notifications."},{name:"disable",description:"Disables page domain notifications."},{name:"addScriptToEvaluateOnLoad",parameters:[{name:"scriptSource",type:"string"}],returns:[{name:"identifier",$ref:"ScriptIdentifier",description:"Identifier of the added script."}],experimental:!0},{name:"removeScriptToEvaluateOnLoad",parameters:[{name:"identifier",$ref:"ScriptIdentifier"}],experimental:!0},{name:"setAutoAttachToCreatedPages",parameters:[{name:"autoAttach",type:"boolean",description:"If true, browser will open a new inspector window for every page created from this one."}],description:"Controls whether browser will open a new inspector window for connected pages.",experimental:!0},{name:"reload",parameters:[{name:"ignoreCache",type:"boolean",optional:!0,description:"If true, browser cache is ignored (as if the user pressed Shift+refresh)."},{name:"scriptToEvaluateOnLoad",type:"string",optional:!0,description:"If set, the script will be injected into all frames of the inspected page after reload."}],description:"Reloads given page optionally ignoring the cache."},{name:"navigate",parameters:[{name:"url",type:"string",description:"URL to navigate the page to."}],returns:[{name:"frameId",$ref:"FrameId",experimental:!0,description:"Frame id that will be navigated."}],description:"Navigates current page to the given URL."},{name:"stopLoading",description:"Force the page stop all navigations and pending resource fetches.",experimental:!0},{name:"getNavigationHistory",returns:[{name:"currentIndex",type:"integer",description:"Index of the current navigation history entry."},{name:"entries",type:"array",items:{$ref:"NavigationEntry"},description:"Array of navigation history entries."}],description:"Returns navigation history for the current page.",experimental:!0},{name:"navigateToHistoryEntry",parameters:[{name:"entryId",type:"integer",description:"Unique id of the entry to navigate to."}],description:"Navigates current page to the given history entry.",experimental:!0},{name:"getCookies",returns:[{name:"cookies",type:"array",items:{$ref:"Network.Cookie"},description:"Array of cookie objects."}],description:"Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the cookies field.",experimental:!0,redirect:"Network"},{name:"deleteCookie",parameters:[{name:"cookieName",type:"string",description:"Name of the cookie to remove."},{name:"url",type:"string",description:"URL to match cooke domain and path."}],description:"Deletes browser cookie with given name, domain and path.",experimental:!0,redirect:"Network"},{name:"getResourceTree",description:"Returns present frame / resource tree structure.",returns:[{name:"frameTree",$ref:"FrameResourceTree",description:"Present frame / resource tree structure."}],experimental:!0},{name:"getResourceContent",description:"Returns content of the given resource.",parameters:[{name:"frameId",$ref:"FrameId",description:"Frame id to get resource for."},{name:"url",type:"string",description:"URL of the resource to get content for."}],returns:[{name:"content",type:"string",description:"Resource content."},{name:"base64Encoded",type:"boolean",description:"True, if content was served as base64."}],experimental:!0},{name:"searchInResource",description:"Searches for given string in resource content.",parameters:[{name:"frameId",$ref:"FrameId",description:"Frame id for resource to search in."},{name:"url",type:"string",description:"URL of the resource to search in."},{name:"query",type:"string",description:"String to search for."},{name:"caseSensitive",type:"boolean",optional:!0,description:"If true, search is case sensitive."},{name:"isRegex",type:"boolean",optional:!0,description:"If true, treats string parameter as regex."}],returns:[{name:"result",type:"array",items:{$ref:"Debugger.SearchMatch"},description:"List of search matches."}],experimental:!0},{name:"setDocumentContent",description:"Sets given markup as the document's HTML.",parameters:[{name:"frameId",$ref:"FrameId",description:"Frame id to set HTML for."},{name:"html",type:"string",description:"HTML content to set."}],experimental:!0},{name:"setDeviceMetricsOverride",description:'Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media query results).',parameters:[{name:"width",type:"integer",description:"Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override."},{name:"height",type:"integer",description:"Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override."},{name:"deviceScaleFactor",type:"number",description:"Overriding device scale factor value. 0 disables the override."},{name:"mobile",type:"boolean",description:"Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more."},{name:"fitWindow",type:"boolean",description:"Whether a view that exceeds the available browser window area should be scaled down to fit."},{name:"scale",type:"number",optional:!0,description:"Scale to apply to resulting view image. Ignored in |fitWindow| mode."},{name:"offsetX",type:"number",optional:!0,description:"X offset to shift resulting view image by. Ignored in |fitWindow| mode."},{name:"offsetY",type:"number",optional:!0,description:"Y offset to shift resulting view image by. Ignored in |fitWindow| mode."},{name:"screenWidth",type:"integer",optional:!0,description:"Overriding screen width value in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"screenHeight",type:"integer",optional:!0,description:"Overriding screen height value in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"positionX",type:"integer",optional:!0,description:"Overriding view X position on screen in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"positionY",type:"integer",optional:!0,description:"Overriding view Y position on screen in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"screenOrientation",$ref:"Emulation.ScreenOrientation",optional:!0,description:"Screen orientation override."}],redirect:"Emulation",experimental:!0},{name:"clearDeviceMetricsOverride",description:"Clears the overriden device metrics.",redirect:"Emulation",experimental:!0},{name:"setGeolocationOverride",description:"Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position unavailable.",parameters:[{name:"latitude",type:"number",optional:!0,description:"Mock latitude"},{name:"longitude",type:"number",optional:!0,description:"Mock longitude"},{name:"accuracy",type:"number",optional:!0,description:"Mock accuracy"}],redirect:"Emulation"},{name:"clearGeolocationOverride",description:"Clears the overriden Geolocation Position and Error.",redirect:"Emulation"},{name:"setDeviceOrientationOverride",description:"Overrides the Device Orientation.",parameters:[{name:"alpha",type:"number",description:"Mock alpha"},{name:"beta",type:"number",description:"Mock beta"},{name:"gamma",type:"number",description:"Mock gamma"}],redirect:"DeviceOrientation",experimental:!0},{name:"clearDeviceOrientationOverride",description:"Clears the overridden Device Orientation.",redirect:"DeviceOrientation",experimental:!0},{name:"setTouchEmulationEnabled",parameters:[{name:"enabled",type:"boolean",description:"Whether the touch event emulation should be enabled."},{name:"configuration",type:"string",enum:["mobile","desktop"],optional:!0,description:"Touch/gesture events configuration. Default: current platform."}],description:"Toggles mouse event-based touch event emulation.",experimental:!0,redirect:"Emulation"},{name:"captureScreenshot",description:"Capture page screenshot.",returns:[{name:"data",type:"string",description:"Base64-encoded image data (PNG)."}],experimental:!0},{name:"startScreencast",description:"Starts sending each frame using the screencastFrame event.",parameters:[{name:"format",type:"string",optional:!0,enum:["jpeg","png"],description:"Image compression format."},{name:"quality",type:"integer",optional:!0,description:"Compression quality from range [0..100]."},{name:"maxWidth",type:"integer",optional:!0,description:"Maximum screenshot width."},{name:"maxHeight",type:"integer",optional:!0,description:"Maximum screenshot height."},{name:"everyNthFrame",type:"integer",optional:!0,description:"Send every n-th frame."}],experimental:!0},{name:"stopScreencast",description:"Stops sending each frame in the screencastFrame.",experimental:!0},{name:"screencastFrameAck",description:"Acknowledges that a screencast frame has been received by the frontend.",parameters:[{name:"sessionId",type:"integer",description:"Frame number."}],experimental:!0},{name:"handleJavaScriptDialog",description:"Accepts or dismisses a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload).",parameters:[{name:"accept",type:"boolean",description:"Whether to accept or dismiss the dialog."},{name:"promptText",type:"string",optional:!0,description:"The text to enter into the dialog prompt before accepting. Used only if this is a prompt dialog."}]},{name:"setColorPickerEnabled",parameters:[{name:"enabled",type:"boolean",description:"Shows / hides color picker"}],description:"Shows / hides color picker",experimental:!0},{name:"configureOverlay",parameters:[{name:"suspended",type:"boolean",optional:!0,description:"Whether overlay should be suspended and not consume any resources."},{name:"message",type:"string",optional:!0,description:"Overlay message to display."}],experimental:!0,description:"Configures overlay."},{name:"getAppManifest",experimental:!0,returns:[{name:"url",type:"string",description:"Manifest location."},{name:"errors",type:"array",items:{$ref:"AppManifestError"}},{name:"data",type:"string",optional:!0,description:"Manifest content."}]},{name:"requestAppBanner",experimental:!0},{name:"setControlNavigations",parameters:[{name:"enabled",type:"boolean"}],description:"Toggles navigation throttling which allows programatic control over navigation and redirect response.",experimental:!0},{name:"processNavigation",parameters:[{name:"response",$ref:"NavigationResponse"},{name:"navigationId",type:"integer"}],description:"Should be sent in response to a navigationRequested or a redirectRequested event, telling the browser how to handle the navigation.",experimental:!0},{name:"getLayoutMetrics",description:"Returns metrics relating to the layouting of the page, such as viewport bounds/scale.",experimental:!0,returns:[{name:"layoutViewport",$ref:"LayoutViewport",description:"Metrics relating to the layout viewport."},{name:"visualViewport", + $ref:"VisualViewport",description:"Metrics relating to the visual viewport."}]}],events:[{name:"domContentEventFired",parameters:[{name:"timestamp",type:"number"}]},{name:"loadEventFired",parameters:[{name:"timestamp",type:"number"}]},{name:"frameAttached",description:"Fired when frame has been attached to its parent.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has been attached."},{name:"parentFrameId",$ref:"FrameId",description:"Parent frame identifier."}]},{name:"frameNavigated",description:"Fired once navigation of the frame has completed. Frame is now associated with the new loader.",parameters:[{name:"frame",$ref:"Frame",description:"Frame object."}]},{name:"frameDetached",description:"Fired when frame has been detached from its parent.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has been detached."}]},{name:"frameStartedLoading",description:"Fired when frame has started loading.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has started loading."}],experimental:!0},{name:"frameStoppedLoading",description:"Fired when frame has stopped loading.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has stopped loading."}],experimental:!0},{name:"frameScheduledNavigation",description:"Fired when frame schedules a potential navigation.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has scheduled a navigation."},{name:"delay",type:"number",description:"Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start."}],experimental:!0},{name:"frameClearedScheduledNavigation",description:"Fired when frame no longer has a scheduled navigation.",parameters:[{name:"frameId",$ref:"FrameId",description:"Id of the frame that has cleared its scheduled navigation."}],experimental:!0},{name:"frameResized",experimental:!0},{name:"javascriptDialogOpening",description:"Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) is about to open.",parameters:[{name:"message",type:"string",description:"Message that will be displayed by the dialog."},{name:"type",$ref:"DialogType",description:"Dialog type."}]},{name:"javascriptDialogClosed",description:"Fired when a JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload) has been closed.",parameters:[{name:"result",type:"boolean",description:"Whether dialog was confirmed."}]},{name:"screencastFrame",description:"Compressed image data requested by the startScreencast.",parameters:[{name:"data",type:"string",description:"Base64-encoded compressed image."},{name:"metadata",$ref:"ScreencastFrameMetadata",description:"Screencast frame metadata."},{name:"sessionId",type:"integer",description:"Frame number."}],experimental:!0},{name:"screencastVisibilityChanged",description:"Fired when the page with currently enabled screencast was shown or hidden .",parameters:[{name:"visible",type:"boolean",description:"True if the page is visible."}],experimental:!0},{name:"colorPicked",description:"Fired when a color has been picked.",parameters:[{name:"color",$ref:"DOM.RGBA",description:"RGBA of the picked color."}],experimental:!0},{name:"interstitialShown",description:"Fired when interstitial page was shown"},{name:"interstitialHidden",description:"Fired when interstitial page was hidden"},{name:"navigationRequested",description:"Fired when a navigation is started if navigation throttles are enabled. The navigation will be deferred until processNavigation is called.",parameters:[{name:"isInMainFrame",type:"boolean",description:"Whether the navigation is taking place in the main frame or in a subframe."},{name:"isRedirect",type:"boolean",description:"Whether the navigation has encountered a server redirect or not."},{name:"navigationId",type:"integer"},{name:"url",type:"string",description:"URL of requested navigation."}]}]},{domain:"Rendering",description:"This domain allows to control rendering of the page.",experimental:!0,commands:[{name:"setShowPaintRects",description:"Requests that backend shows paint rectangles",parameters:[{name:"result",type:"boolean",description:"True for showing paint rectangles"}]},{name:"setShowDebugBorders",description:"Requests that backend shows debug borders on layers",parameters:[{name:"show",type:"boolean",description:"True for showing debug borders"}]},{name:"setShowFPSCounter",description:"Requests that backend shows the FPS counter",parameters:[{name:"show",type:"boolean",description:"True for showing the FPS counter"}]},{name:"setShowScrollBottleneckRects",description:"Requests that backend shows scroll bottleneck rects",parameters:[{name:"show",type:"boolean",description:"True for showing scroll bottleneck rects"}]},{name:"setShowViewportSizeOnResize",description:"Paints viewport size upon main frame resize.",parameters:[{name:"show",type:"boolean",description:"Whether to paint size or not."}]}]},{domain:"Emulation",description:"This domain emulates different environments for the page.",types:[{id:"ScreenOrientation",type:"object",description:"Screen orientation.",properties:[{name:"type",type:"string",enum:["portraitPrimary","portraitSecondary","landscapePrimary","landscapeSecondary"],description:"Orientation type."},{name:"angle",type:"integer",description:"Orientation angle."}]},{id:"VirtualTimePolicy",type:"string",enum:["advance","pause","pauseIfNetworkFetchesPending"],experimental:!0,description:"advance: If the scheduler runs out of immediate work, the virtual time base may fast forward to allow the next delayed task (if any) to run; pause: The virtual time base may not advance; pauseIfNetworkFetchesPending: The virtual time base may not advance if there are any pending resource fetches."}],commands:[{name:"setDeviceMetricsOverride",description:'Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and "device-width"/"device-height"-related CSS media query results).',parameters:[{name:"width",type:"integer",description:"Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override."},{name:"height",type:"integer",description:"Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override."},{name:"deviceScaleFactor",type:"number",description:"Overriding device scale factor value. 0 disables the override."},{name:"mobile",type:"boolean",description:"Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more."},{name:"fitWindow",type:"boolean",description:"Whether a view that exceeds the available browser window area should be scaled down to fit."},{name:"scale",type:"number",optional:!0,experimental:!0,description:"Scale to apply to resulting view image. Ignored in |fitWindow| mode."},{name:"offsetX",type:"number",optional:!0,deprecated:!0,experimental:!0,description:"Not used."},{name:"offsetY",type:"number",optional:!0,deprecated:!0,experimental:!0,description:"Not used."},{name:"screenWidth",type:"integer",optional:!0,experimental:!0,description:"Overriding screen width value in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"screenHeight",type:"integer",optional:!0,experimental:!0,description:"Overriding screen height value in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"positionX",type:"integer",optional:!0,experimental:!0,description:"Overriding view X position on screen in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"positionY",type:"integer",optional:!0,experimental:!0,description:"Overriding view Y position on screen in pixels (minimum 0, maximum 10000000). Only used for |mobile==true|."},{name:"screenOrientation",$ref:"ScreenOrientation",optional:!0,description:"Screen orientation override."}]},{name:"clearDeviceMetricsOverride",description:"Clears the overriden device metrics."},{name:"forceViewport",description:"Overrides the visible area of the page. The change is hidden from the page, i.e. the observable scroll position and page scale does not change. In effect, the command moves the specified area of the page into the top-left corner of the frame.",experimental:!0,parameters:[{name:"x",type:"number",description:"X coordinate of top-left corner of the area (CSS pixels)."},{name:"y",type:"number",description:"Y coordinate of top-left corner of the area (CSS pixels)."},{name:"scale",type:"number",description:"Scale to apply to the area (relative to a page scale of 1.0)."}]},{name:"resetViewport",description:"Resets the visible area of the page to the original viewport, undoing any effects of the forceViewport command.",experimental:!0},{name:"resetPageScaleFactor",experimental:!0,description:"Requests that page scale factor is reset to initial values."},{name:"setPageScaleFactor",description:"Sets a specified page scale factor.",experimental:!0,parameters:[{name:"pageScaleFactor",type:"number",description:"Page scale factor."}]},{name:"setVisibleSize",description:"Resizes the frame/viewport of the page. Note that this does not affect the frame's container (e.g. browser window). Can be used to produce screenshots of the specified size. Not supported on Android.",experimental:!0,parameters:[{name:"width",type:"integer",description:"Frame width (DIP)."},{name:"height",type:"integer",description:"Frame height (DIP)."}]},{name:"setScriptExecutionDisabled",description:"Switches script execution in the page.",experimental:!0,parameters:[{name:"value",type:"boolean",description:"Whether script execution should be disabled in the page."}]},{name:"setGeolocationOverride",description:"Overrides the Geolocation Position or Error. Omitting any of the parameters emulates position unavailable.",experimental:!0,parameters:[{name:"latitude",type:"number",optional:!0,description:"Mock latitude"},{name:"longitude",type:"number",optional:!0,description:"Mock longitude"},{name:"accuracy",type:"number",optional:!0,description:"Mock accuracy"}]},{name:"clearGeolocationOverride",description:"Clears the overriden Geolocation Position and Error.",experimental:!0},{name:"setTouchEmulationEnabled",parameters:[{name:"enabled",type:"boolean",description:"Whether the touch event emulation should be enabled."},{name:"configuration",type:"string",enum:["mobile","desktop"],optional:!0,description:"Touch/gesture events configuration. Default: current platform."}],description:"Toggles mouse event-based touch event emulation."},{name:"setEmulatedMedia",parameters:[{name:"media",type:"string",description:"Media type to emulate. Empty string disables the override."}],description:"Emulates the given media for CSS media queries."},{name:"setCPUThrottlingRate",parameters:[{name:"rate",type:"number",description:"Throttling rate as a slowdown factor (1 is no throttle, 2 is 2x slowdown, etc)."}],experimental:!0,description:"Enables CPU throttling to emulate slow CPUs."},{name:"canEmulate",description:"Tells whether emulation is supported.",returns:[{name:"result",type:"boolean",description:"True if emulation is supported."}],experimental:!0},{name:"setVirtualTimePolicy",description:"Turns on virtual time for all frames (replacing real-time with a synthetic time source) and sets the current virtual time policy. Note this supersedes any previous time budget.",parameters:[{name:"policy",$ref:"VirtualTimePolicy"},{name:"budget",type:"integer",optional:!0,description:"If set, after this many virtual milliseconds have elapsed virtual time will be paused and a virtualTimeBudgetExpired event is sent."}],experimental:!0}],events:[{name:"virtualTimeBudgetExpired",experimental:!0,description:"Notification sent after the virual time budget for the current VirtualTimePolicy has run out."}]},{domain:"Security",description:"Security",experimental:!0,types:[{id:"CertificateId",type:"integer",description:"An internal certificate ID value."},{id:"SecurityState",type:"string",enum:["unknown","neutral","insecure","warning","secure","info"],description:"The security level of a page or resource."},{id:"SecurityStateExplanation",type:"object",properties:[{name:"securityState",$ref:"SecurityState",description:"Security state representing the severity of the factor being explained."},{name:"summary",type:"string",description:"Short phrase describing the type of factor."},{name:"description",type:"string",description:"Full text explanation of the factor."},{name:"hasCertificate",type:"boolean",description:"True if the page has a certificate."}],description:"An explanation of an factor contributing to the security state."},{id:"InsecureContentStatus",type:"object",properties:[{name:"ranMixedContent",type:"boolean",description:"True if the page was loaded over HTTPS and ran mixed (HTTP) content such as scripts."},{name:"displayedMixedContent",type:"boolean",description:"True if the page was loaded over HTTPS and displayed mixed (HTTP) content such as images."},{name:"ranContentWithCertErrors",type:"boolean",description:"True if the page was loaded over HTTPS without certificate errors, and ran content such as scripts that were loaded with certificate errors."},{name:"displayedContentWithCertErrors",type:"boolean",description:"True if the page was loaded over HTTPS without certificate errors, and displayed content such as images that were loaded with certificate errors."},{name:"ranInsecureContentStyle",$ref:"SecurityState",description:"Security state representing a page that ran insecure content."},{name:"displayedInsecureContentStyle",$ref:"SecurityState",description:"Security state representing a page that displayed insecure content."}],description:"Information about insecure content on the page."}],commands:[{name:"enable",description:"Enables tracking security state changes."},{name:"disable",description:"Disables tracking security state changes."},{name:"showCertificateViewer",description:"Displays native dialog with the certificate details."}],events:[{name:"securityStateChanged",description:"The security state of the page changed.",parameters:[{name:"securityState",$ref:"SecurityState",description:"Security state."},{name:"explanations",type:"array",items:{$ref:"SecurityStateExplanation"},description:"List of explanations for the security state. If the overall security state is `insecure` or `warning`, at least one corresponding explanation should be included.",optional:!0},{name:"insecureContentStatus",$ref:"InsecureContentStatus",description:"Information about insecure content on the page.",optional:!0},{name:"schemeIsCryptographic",type:"boolean",description:"True if the page was loaded over cryptographic transport such as HTTPS.",optional:!0}]}]},{domain:"Network",description:"Network domain allows tracking network activities of the page. It exposes information about http, file, data and other requests and responses, their headers, bodies, timing, etc.",dependencies:["Runtime","Security"],types:[{id:"LoaderId",type:"string",description:"Unique loader identifier."},{id:"RequestId",type:"string",description:"Unique request identifier."},{id:"Timestamp",type:"number",description:"Number of seconds since epoch."},{id:"Headers",type:"object",description:"Request / response headers as keys / values of JSON object."},{id:"ConnectionType",type:"string",enum:["none","cellular2g","cellular3g","cellular4g","bluetooth","ethernet","wifi","wimax","other"],description:"Loading priority of a resource request."},{id:"CookieSameSite",type:"string",enum:["Strict","Lax"],description:"Represents the cookie's 'SameSite' status: https://tools.ietf.org/html/draft-west-first-party-cookies"},{id:"ResourceTiming",type:"object",description:"Timing information for the request.",properties:[{name:"requestTime",type:"number",description:"Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime."},{name:"proxyStart",type:"number",description:"Started resolving proxy."},{name:"proxyEnd",type:"number",description:"Finished resolving proxy."},{name:"dnsStart",type:"number",description:"Started DNS address resolve."},{name:"dnsEnd",type:"number",description:"Finished DNS address resolve."},{name:"connectStart",type:"number",description:"Started connecting to the remote host."},{name:"connectEnd",type:"number",description:"Connected to the remote host."},{name:"sslStart",type:"number",description:"Started SSL handshake."},{name:"sslEnd",type:"number",description:"Finished SSL handshake."},{name:"workerStart",type:"number",description:"Started running ServiceWorker.",experimental:!0},{name:"workerReady",type:"number",description:"Finished Starting ServiceWorker.",experimental:!0},{name:"sendStart",type:"number",description:"Started sending request."},{name:"sendEnd",type:"number",description:"Finished sending request."},{name:"pushStart",type:"number",description:"Time the server started pushing request.",experimental:!0},{name:"pushEnd",type:"number",description:"Time the server finished pushing request.",experimental:!0},{name:"receiveHeadersEnd",type:"number",description:"Finished receiving response headers."}]},{id:"ResourcePriority",type:"string",enum:["VeryLow","Low","Medium","High","VeryHigh"],description:"Loading priority of a resource request."},{id:"Request",type:"object",description:"HTTP request data.",properties:[{name:"url",type:"string",description:"Request URL."},{name:"method",type:"string",description:"HTTP request method."},{name:"headers",$ref:"Headers",description:"HTTP request headers."},{name:"postData",type:"string",optional:!0,description:"HTTP POST request data."},{name:"mixedContentType",optional:!0,type:"string",enum:["blockable","optionally-blockable","none"],description:"The mixed content status of the request, as defined in http://www.w3.org/TR/mixed-content/"},{name:"initialPriority",$ref:"ResourcePriority",description:"Priority of the resource request at the time request is sent."}]},{id:"SignedCertificateTimestamp",type:"object",description:"Details of a signed certificate timestamp (SCT).",properties:[{name:"status",type:"string",description:"Validation status."},{name:"origin",type:"string",description:"Origin."},{name:"logDescription",type:"string",description:"Log name / description."},{name:"logId",type:"string",description:"Log ID."},{name:"timestamp",$ref:"Timestamp",description:"Issuance date."},{name:"hashAlgorithm",type:"string",description:"Hash algorithm."},{name:"signatureAlgorithm",type:"string",description:"Signature algorithm."},{name:"signatureData",type:"string",description:"Signature data."}]},{id:"SecurityDetails",type:"object",description:"Security details about a request.",properties:[{name:"protocol",type:"string",description:'Protocol name (e.g. "TLS 1.2" or "QUIC").'},{name:"keyExchange",type:"string",description:"Key Exchange used by the connection, or the empty string if not applicable."},{name:"keyExchangeGroup",type:"string",optional:!0,description:"(EC)DH group used by the connection, if applicable."},{name:"cipher",type:"string",description:"Cipher name."},{name:"mac",type:"string",optional:!0,description:"TLS MAC. Note that AEAD ciphers do not have separate MACs."},{name:"certificateId",$ref:"Security.CertificateId",description:"Certificate ID value."},{name:"subjectName",type:"string",description:"Certificate subject name."},{name:"sanList",type:"array",items:{type:"string"},description:"Subject Alternative Name (SAN) DNS names and IP addresses."},{name:"issuer",type:"string",description:"Name of the issuing CA."},{name:"validFrom",$ref:"Timestamp",description:"Certificate valid from date."},{name:"validTo",$ref:"Timestamp",description:"Certificate valid to (expiration) date"},{name:"signedCertificateTimestampList",type:"array",items:{$ref:"SignedCertificateTimestamp"},description:"List of signed certificate timestamps (SCTs)."}]},{id:"BlockedReason",type:"string",description:"The reason why request was blocked.",enum:["csp","mixed-content","origin","inspector","subresource-filter","other"],experimental:!0},{id:"Response",type:"object",description:"HTTP response data.",properties:[{name:"url",type:"string",description:"Response URL. This URL can be different from CachedResource.url in case of redirect."},{name:"status",type:"number",description:"HTTP response status code."},{name:"statusText",type:"string",description:"HTTP response status text."},{name:"headers",$ref:"Headers",description:"HTTP response headers."},{name:"headersText",type:"string",optional:!0,description:"HTTP response headers text."},{name:"mimeType",type:"string",description:"Resource mimeType as determined by the browser."},{name:"requestHeaders",$ref:"Headers",optional:!0,description:"Refined HTTP request headers that were actually transmitted over the network."},{name:"requestHeadersText",type:"string",optional:!0,description:"HTTP request headers text."},{name:"connectionReused",type:"boolean",description:"Specifies whether physical connection was actually reused for this request."},{name:"connectionId",type:"number",description:"Physical connection id that was actually used for this request."},{name:"remoteIPAddress",type:"string",optional:!0,experimental:!0,description:"Remote IP address."},{name:"remotePort",type:"integer",optional:!0,experimental:!0,description:"Remote port."},{name:"fromDiskCache",type:"boolean",optional:!0,description:"Specifies that the request was served from the disk cache."},{name:"fromServiceWorker",type:"boolean",optional:!0,description:"Specifies that the request was served from the ServiceWorker."},{name:"encodedDataLength",type:"number",optional:!1,description:"Total number of bytes received for this request so far."},{name:"timing",$ref:"ResourceTiming",optional:!0,description:"Timing information for the given request."},{name:"protocol",type:"string",optional:!0,description:"Protocol used to fetch this request."},{name:"securityState",$ref:"Security.SecurityState",description:"Security state of the request resource."},{name:"securityDetails",$ref:"SecurityDetails",optional:!0,description:"Security details for the request."}]},{id:"WebSocketRequest",type:"object",description:"WebSocket request data.",experimental:!0,properties:[{name:"headers",$ref:"Headers",description:"HTTP request headers."}]},{id:"WebSocketResponse",type:"object",description:"WebSocket response data.",experimental:!0,properties:[{name:"status",type:"number",description:"HTTP response status code."},{name:"statusText",type:"string",description:"HTTP response status text."},{name:"headers",$ref:"Headers",description:"HTTP response headers."},{name:"headersText",type:"string",optional:!0,description:"HTTP response headers text."},{name:"requestHeaders",$ref:"Headers",optional:!0,description:"HTTP request headers."},{name:"requestHeadersText",type:"string",optional:!0,description:"HTTP request headers text."}]},{id:"WebSocketFrame",type:"object",description:"WebSocket frame data.",experimental:!0,properties:[{name:"opcode",type:"number",description:"WebSocket frame opcode."},{name:"mask",type:"boolean",description:"WebSocke frame mask."},{name:"payloadData",type:"string",description:"WebSocke frame payload data."}]},{id:"CachedResource",type:"object",description:"Information about the cached resource.",properties:[{name:"url",type:"string",description:"Resource URL. This is the url of the original network request."},{name:"type",$ref:"Page.ResourceType",description:"Type of this resource."},{name:"response",$ref:"Response",optional:!0,description:"Cached response data."},{name:"bodySize",type:"number",description:"Cached response body size."}]},{id:"Initiator",type:"object",description:"Information about the request initiator.",properties:[{name:"type",type:"string",enum:["parser","script","other"],description:"Type of this initiator."},{name:"stack",$ref:"Runtime.StackTrace",optional:!0,description:"Initiator JavaScript stack trace, set for Script only."},{name:"url",type:"string",optional:!0,description:"Initiator URL, set for Parser type only."},{name:"lineNumber",type:"number",optional:!0,description:"Initiator line number, set for Parser type only (0-based)."}]},{id:"Cookie",type:"object",description:"Cookie object",properties:[{name:"name",type:"string",description:"Cookie name."},{name:"value",type:"string",description:"Cookie value."},{name:"domain",type:"string",description:"Cookie domain."},{name:"path",type:"string",description:"Cookie path."},{name:"expires",type:"number",description:"Cookie expiration date as the number of seconds since the UNIX epoch."},{name:"size",type:"integer",description:"Cookie size."},{name:"httpOnly",type:"boolean",description:"True if cookie is http-only."},{name:"secure",type:"boolean",description:"True if cookie is secure."},{name:"session",type:"boolean",description:"True in case of session cookie."},{name:"sameSite",$ref:"CookieSameSite",optional:!0,description:"Cookie SameSite type."}],experimental:!0}],commands:[{name:"enable",description:"Enables network tracking, network events will now be delivered to the client.",parameters:[{name:"maxTotalBufferSize",type:"integer",optional:!0,experimental:!0,description:"Buffer size in bytes to use when preserving network payloads (XHRs, etc)."},{name:"maxResourceBufferSize",type:"integer",optional:!0,experimental:!0,description:"Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc)."}]},{name:"disable",description:"Disables network tracking, prevents network events from being sent to the client."},{name:"setUserAgentOverride",description:"Allows overriding user agent with the given string.",parameters:[{name:"userAgent",type:"string",description:"User agent to use."}]},{name:"setExtraHTTPHeaders",description:"Specifies whether to always send extra HTTP headers with the requests from this page.",parameters:[{name:"headers",$ref:"Headers",description:"Map with extra HTTP headers."}]},{name:"getResponseBody",description:"Returns content served for the given request.",parameters:[{name:"requestId",$ref:"RequestId",description:"Identifier of the network request to get content for."}],returns:[{name:"body",type:"string",description:"Response body."},{name:"base64Encoded",type:"boolean",description:"True, if content was sent as base64."}]},{name:"addBlockedURL",description:"Blocks specific URL from loading.",parameters:[{name:"url",type:"string",description:"URL to block."}],experimental:!0},{name:"removeBlockedURL",description:"Cancels blocking of a specific URL from loading.",parameters:[{name:"url",type:"string",description:"URL to stop blocking."}],experimental:!0},{name:"replayXHR",description:"This method sends a new XMLHttpRequest which is identical to the original one. The following parameters should be identical: method, url, async, request body, extra headers, withCredentials attribute, user, password.",parameters:[{name:"requestId",$ref:"RequestId",description:"Identifier of XHR to replay."}],experimental:!0},{name:"setMonitoringXHREnabled",parameters:[{name:"enabled",type:"boolean",description:"Monitoring enabled state."}],description:"Toggles monitoring of XMLHttpRequest. If true, console will receive messages upon each XHR issued.",experimental:!0},{name:"canClearBrowserCache",description:"Tells whether clearing browser cache is supported.",returns:[{name:"result",type:"boolean",description:"True if browser cache can be cleared."}]},{name:"clearBrowserCache",description:"Clears browser cache."},{name:"canClearBrowserCookies",description:"Tells whether clearing browser cookies is supported.",returns:[{name:"result",type:"boolean",description:"True if browser cookies can be cleared."}]},{name:"clearBrowserCookies",description:"Clears browser cookies."},{name:"getCookies",returns:[{name:"cookies",type:"array",items:{$ref:"Cookie"},description:"Array of cookie objects."}],description:"Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the cookies field.",experimental:!0},{name:"deleteCookie",parameters:[{name:"cookieName",type:"string",description:"Name of the cookie to remove."},{name:"url",type:"string",description:"URL to match cooke domain and path."}],description:"Deletes browser cookie with given name, domain and path.",experimental:!0},{name:"setCookie",parameters:[{name:"url",type:"string",description:"The request-URI to associate with the setting of the cookie. This value can affect the default domain and path values of the created cookie."},{name:"name",type:"string",description:"The name of the cookie."},{name:"value",type:"string",description:"The value of the cookie."},{name:"domain",type:"string",optional:!0,description:"If omitted, the cookie becomes a host-only cookie."},{name:"path",type:"string",optional:!0,description:"Defaults to the path portion of the url parameter."},{name:"secure",type:"boolean",optional:!0,description:"Defaults ot false."},{name:"httpOnly",type:"boolean",optional:!0,description:"Defaults to false."},{name:"sameSite",$ref:"CookieSameSite",optional:!0,description:"Defaults to browser default behavior."},{name:"expirationDate",$ref:"Timestamp",optional:!0,description:"If omitted, the cookie becomes a session cookie."}],returns:[{name:"success",type:"boolean",description:"True if successfully set cookie."}],description:"Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.",experimental:!0},{name:"canEmulateNetworkConditions",description:"Tells whether emulation of network conditions is supported.",returns:[{name:"result",type:"boolean",description:"True if emulation of network conditions is supported."}],experimental:!0},{name:"emulateNetworkConditions",description:"Activates emulation of network conditions.",parameters:[{name:"offline",type:"boolean",description:"True to emulate internet disconnection."},{name:"latency",type:"number",description:"Additional latency (ms)."},{name:"downloadThroughput",type:"number",description:"Maximal aggregated download throughput."},{name:"uploadThroughput",type:"number",description:"Maximal aggregated upload throughput."},{name:"connectionType",$ref:"ConnectionType",optional:!0,description:"Connection type if known."}]},{name:"setCacheDisabled",parameters:[{name:"cacheDisabled",type:"boolean",description:"Cache disabled state."}],description:"Toggles ignoring cache for each request. If true, cache will not be used."},{name:"setBypassServiceWorker",parameters:[{name:"bypass",type:"boolean",description:"Bypass service worker and load from network."}],experimental:!0,description:"Toggles ignoring of service worker for each request."},{name:"setDataSizeLimitsForTest",parameters:[{name:"maxTotalSize",type:"integer",description:"Maximum total buffer size."},{name:"maxResourceSize",type:"integer",description:"Maximum per-resource size."}],description:"For testing.",experimental:!0},{name:"getCertificate",description:"Returns the DER-encoded certificate.",parameters:[{name:"origin",type:"string",description:"Origin to get certificate for."}],returns:[{name:"tableNames",type:"array",items:{type:"string"}}],experimental:!0}],events:[{name:"resourceChangedPriority",description:"Fired when resource loading priority is changed",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"newPriority",$ref:"ResourcePriority",description:"New priority"},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."}],experimental:!0},{name:"requestWillBeSent",description:"Fired when page is about to send HTTP request.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"frameId",$ref:"Page.FrameId",description:"Frame identifier.",experimental:!0},{name:"loaderId",$ref:"LoaderId",description:"Loader identifier."},{name:"documentURL",type:"string",description:"URL of the document this request is loaded for." + },{name:"request",$ref:"Request",description:"Request data."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"wallTime",$ref:"Timestamp",experimental:!0,description:"UTC Timestamp."},{name:"initiator",$ref:"Initiator",description:"Request initiator."},{name:"redirectResponse",optional:!0,$ref:"Response",description:"Redirect response data."},{name:"type",$ref:"Page.ResourceType",optional:!0,experimental:!0,description:"Type of this resource."}]},{name:"requestServedFromCache",description:"Fired if request ended up loading from cache.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."}]},{name:"responseReceived",description:"Fired when HTTP response is available.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"frameId",$ref:"Page.FrameId",description:"Frame identifier.",experimental:!0},{name:"loaderId",$ref:"LoaderId",description:"Loader identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"type",$ref:"Page.ResourceType",description:"Resource type."},{name:"response",$ref:"Response",description:"Response data."}]},{name:"dataReceived",description:"Fired when data chunk was received over the network.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"dataLength",type:"integer",description:"Data chunk length."},{name:"encodedDataLength",type:"integer",description:"Actual bytes received (might be less than dataLength for compressed encodings)."}]},{name:"loadingFinished",description:"Fired when HTTP request has finished loading.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"encodedDataLength",type:"number",description:"Total number of bytes received for this request."}]},{name:"loadingFailed",description:"Fired when HTTP request has failed to load.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"type",$ref:"Page.ResourceType",description:"Resource type."},{name:"errorText",type:"string",description:"User friendly error message."},{name:"canceled",type:"boolean",optional:!0,description:"True if loading was canceled."},{name:"blockedReason",$ref:"BlockedReason",optional:!0,description:"The reason why loading was blocked, if any.",experimental:!0}]},{name:"webSocketWillSendHandshakeRequest",description:"Fired when WebSocket is about to initiate handshake.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"wallTime",$ref:"Timestamp",experimental:!0,description:"UTC Timestamp."},{name:"request",$ref:"WebSocketRequest",description:"WebSocket request data."}],experimental:!0},{name:"webSocketHandshakeResponseReceived",description:"Fired when WebSocket handshake response becomes available.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"response",$ref:"WebSocketResponse",description:"WebSocket response data."}],experimental:!0},{name:"webSocketCreated",description:"Fired upon WebSocket creation.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"url",type:"string",description:"WebSocket request URL."},{name:"initiator",$ref:"Initiator",optional:!0,description:"Request initiator."}],experimental:!0},{name:"webSocketClosed",description:"Fired when WebSocket is closed.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."}],experimental:!0},{name:"webSocketFrameReceived",description:"Fired when WebSocket frame is received.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"response",$ref:"WebSocketFrame",description:"WebSocket response data."}],experimental:!0},{name:"webSocketFrameError",description:"Fired when WebSocket frame error occurs.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"errorMessage",type:"string",description:"WebSocket frame error message."}],experimental:!0},{name:"webSocketFrameSent",description:"Fired when WebSocket frame is sent.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"response",$ref:"WebSocketFrame",description:"WebSocket response data."}],experimental:!0},{name:"eventSourceMessageReceived",description:"Fired when EventSource message is received.",parameters:[{name:"requestId",$ref:"RequestId",description:"Request identifier."},{name:"timestamp",$ref:"Timestamp",description:"Timestamp."},{name:"eventName",type:"string",description:"Message type."},{name:"eventId",type:"string",description:"Message identifier."},{name:"data",type:"string",description:"Message content."}],experimental:!0}]},{domain:"Database",experimental:!0,types:[{id:"DatabaseId",type:"string",description:"Unique identifier of Database object.",experimental:!0},{id:"Database",type:"object",description:"Database object.",experimental:!0,properties:[{name:"id",$ref:"DatabaseId",description:"Database ID."},{name:"domain",type:"string",description:"Database domain."},{name:"name",type:"string",description:"Database name."},{name:"version",type:"string",description:"Database version."}]},{id:"Error",type:"object",description:"Database error.",properties:[{name:"message",type:"string",description:"Error message."},{name:"code",type:"integer",description:"Error code."}]}],commands:[{name:"enable",description:"Enables database tracking, database events will now be delivered to the client."},{name:"disable",description:"Disables database tracking, prevents database events from being sent to the client."},{name:"getDatabaseTableNames",parameters:[{name:"databaseId",$ref:"DatabaseId"}],returns:[{name:"tableNames",type:"array",items:{type:"string"}}]},{name:"executeSQL",parameters:[{name:"databaseId",$ref:"DatabaseId"},{name:"query",type:"string"}],returns:[{name:"columnNames",type:"array",optional:!0,items:{type:"string"}},{name:"values",type:"array",optional:!0,items:{type:"any"}},{name:"sqlError",$ref:"Error",optional:!0}]}],events:[{name:"addDatabase",parameters:[{name:"database",$ref:"Database"}]}]},{domain:"IndexedDB",dependencies:["Runtime"],experimental:!0,types:[{id:"DatabaseWithObjectStores",type:"object",description:"Database with an array of object stores.",properties:[{name:"name",type:"string",description:"Database name."},{name:"version",type:"integer",description:"Database version."},{name:"objectStores",type:"array",items:{$ref:"ObjectStore"},description:"Object stores in this database."}]},{id:"ObjectStore",type:"object",description:"Object store.",properties:[{name:"name",type:"string",description:"Object store name."},{name:"keyPath",$ref:"KeyPath",description:"Object store key path."},{name:"autoIncrement",type:"boolean",description:"If true, object store has auto increment flag set."},{name:"indexes",type:"array",items:{$ref:"ObjectStoreIndex"},description:"Indexes in this object store."}]},{id:"ObjectStoreIndex",type:"object",description:"Object store index.",properties:[{name:"name",type:"string",description:"Index name."},{name:"keyPath",$ref:"KeyPath",description:"Index key path."},{name:"unique",type:"boolean",description:"If true, index is unique."},{name:"multiEntry",type:"boolean",description:"If true, index allows multiple entries for a key."}]},{id:"Key",type:"object",description:"Key.",properties:[{name:"type",type:"string",enum:["number","string","date","array"],description:"Key type."},{name:"number",type:"number",optional:!0,description:"Number value."},{name:"string",type:"string",optional:!0,description:"String value."},{name:"date",type:"number",optional:!0,description:"Date value."},{name:"array",type:"array",optional:!0,items:{$ref:"Key"},description:"Array value."}]},{id:"KeyRange",type:"object",description:"Key range.",properties:[{name:"lower",$ref:"Key",optional:!0,description:"Lower bound."},{name:"upper",$ref:"Key",optional:!0,description:"Upper bound."},{name:"lowerOpen",type:"boolean",description:"If true lower bound is open."},{name:"upperOpen",type:"boolean",description:"If true upper bound is open."}]},{id:"DataEntry",type:"object",description:"Data entry.",properties:[{name:"key",$ref:"Runtime.RemoteObject",description:"Key object."},{name:"primaryKey",$ref:"Runtime.RemoteObject",description:"Primary key object."},{name:"value",$ref:"Runtime.RemoteObject",description:"Value object."}]},{id:"KeyPath",type:"object",description:"Key path.",properties:[{name:"type",type:"string",enum:["null","string","array"],description:"Key path type."},{name:"string",type:"string",optional:!0,description:"String value."},{name:"array",type:"array",optional:!0,items:{type:"string"},description:"Array value."}]}],commands:[{name:"enable",description:"Enables events from backend."},{name:"disable",description:"Disables events from backend."},{name:"requestDatabaseNames",parameters:[{name:"securityOrigin",type:"string",description:"Security origin."}],returns:[{name:"databaseNames",type:"array",items:{type:"string"},description:"Database names for origin."}],description:"Requests database names for given security origin."},{name:"requestDatabase",parameters:[{name:"securityOrigin",type:"string",description:"Security origin."},{name:"databaseName",type:"string",description:"Database name."}],returns:[{name:"databaseWithObjectStores",$ref:"DatabaseWithObjectStores",description:"Database with an array of object stores."}],description:"Requests database with given name in given frame."},{name:"requestData",parameters:[{name:"securityOrigin",type:"string",description:"Security origin."},{name:"databaseName",type:"string",description:"Database name."},{name:"objectStoreName",type:"string",description:"Object store name."},{name:"indexName",type:"string",description:"Index name, empty string for object store data requests."},{name:"skipCount",type:"integer",description:"Number of records to skip."},{name:"pageSize",type:"integer",description:"Number of records to fetch."},{name:"keyRange",$ref:"KeyRange",optional:!0,description:"Key range."}],returns:[{name:"objectStoreDataEntries",type:"array",items:{$ref:"DataEntry"},description:"Array of object store data entries."},{name:"hasMore",type:"boolean",description:"If true, there are more entries to fetch in the given range."}],description:"Requests data from object store or index."},{name:"clearObjectStore",parameters:[{name:"securityOrigin",type:"string",description:"Security origin."},{name:"databaseName",type:"string",description:"Database name."},{name:"objectStoreName",type:"string",description:"Object store name."}],returns:[],description:"Clears all entries from an object store."}]},{domain:"CacheStorage",experimental:!0,types:[{id:"CacheId",type:"string",description:"Unique identifier of the Cache object."},{id:"DataEntry",type:"object",description:"Data entry.",properties:[{name:"request",type:"string",description:"Request url spec."},{name:"response",type:"string",description:"Response stataus text."}]},{id:"Cache",type:"object",description:"Cache identifier.",properties:[{name:"cacheId",$ref:"CacheId",description:"An opaque unique id of the cache."},{name:"securityOrigin",type:"string",description:"Security origin of the cache."},{name:"cacheName",type:"string",description:"The name of the cache."}]}],commands:[{name:"requestCacheNames",parameters:[{name:"securityOrigin",type:"string",description:"Security origin."}],returns:[{name:"caches",type:"array",items:{$ref:"Cache"},description:"Caches for the security origin."}],description:"Requests cache names."},{name:"requestEntries",parameters:[{name:"cacheId",$ref:"CacheId",description:"ID of cache to get entries from."},{name:"skipCount",type:"integer",description:"Number of records to skip."},{name:"pageSize",type:"integer",description:"Number of records to fetch."}],returns:[{name:"cacheDataEntries",type:"array",items:{$ref:"DataEntry"},description:"Array of object store data entries."},{name:"hasMore",type:"boolean",description:"If true, there are more entries to fetch in the given range."}],description:"Requests data from cache."},{name:"deleteCache",parameters:[{name:"cacheId",$ref:"CacheId",description:"Id of cache for deletion."}],description:"Deletes a cache."},{name:"deleteEntry",parameters:[{name:"cacheId",$ref:"CacheId",description:"Id of cache where the entry will be deleted."},{name:"request",type:"string",description:"URL spec of the request."}],description:"Deletes a cache entry."}]},{domain:"DOMStorage",experimental:!0,description:"Query and modify DOM storage.",types:[{id:"StorageId",type:"object",description:"DOM Storage identifier.",experimental:!0,properties:[{name:"securityOrigin",type:"string",description:"Security origin for the storage."},{name:"isLocalStorage",type:"boolean",description:"Whether the storage is local storage (not session storage)."}]},{id:"Item",type:"array",description:"DOM Storage item.",experimental:!0,items:{type:"string"}}],commands:[{name:"enable",description:"Enables storage tracking, storage events will now be delivered to the client."},{name:"disable",description:"Disables storage tracking, prevents storage events from being sent to the client."},{name:"getDOMStorageItems",parameters:[{name:"storageId",$ref:"StorageId"}],returns:[{name:"entries",type:"array",items:{$ref:"Item"}}]},{name:"setDOMStorageItem",parameters:[{name:"storageId",$ref:"StorageId"},{name:"key",type:"string"},{name:"value",type:"string"}]},{name:"removeDOMStorageItem",parameters:[{name:"storageId",$ref:"StorageId"},{name:"key",type:"string"}]}],events:[{name:"domStorageItemsCleared",parameters:[{name:"storageId",$ref:"StorageId"}]},{name:"domStorageItemRemoved",parameters:[{name:"storageId",$ref:"StorageId"},{name:"key",type:"string"}]},{name:"domStorageItemAdded",parameters:[{name:"storageId",$ref:"StorageId"},{name:"key",type:"string"},{name:"newValue",type:"string"}]},{name:"domStorageItemUpdated",parameters:[{name:"storageId",$ref:"StorageId"},{name:"key",type:"string"},{name:"oldValue",type:"string"},{name:"newValue",type:"string"}]}]},{domain:"ApplicationCache",experimental:!0,types:[{id:"ApplicationCacheResource",type:"object",description:"Detailed application cache resource information.",properties:[{name:"url",type:"string",description:"Resource url."},{name:"size",type:"integer",description:"Resource size."},{name:"type",type:"string",description:"Resource type."}]},{id:"ApplicationCache",type:"object",description:"Detailed application cache information.",properties:[{name:"manifestURL",type:"string",description:"Manifest URL."},{name:"size",type:"number",description:"Application cache size."},{name:"creationTime",type:"number",description:"Application cache creation time."},{name:"updateTime",type:"number",description:"Application cache update time."},{name:"resources",type:"array",items:{$ref:"ApplicationCacheResource"},description:"Application cache resources."}]},{id:"FrameWithManifest",type:"object",description:"Frame identifier - manifest URL pair.",properties:[{name:"frameId",$ref:"Page.FrameId",description:"Frame identifier."},{name:"manifestURL",type:"string",description:"Manifest URL."},{name:"status",type:"integer",description:"Application cache status."}]}],commands:[{name:"getFramesWithManifests",returns:[{name:"frameIds",type:"array",items:{$ref:"FrameWithManifest"},description:"Array of frame identifiers with manifest urls for each frame containing a document associated with some application cache."}],description:"Returns array of frame identifiers with manifest urls for each frame containing a document associated with some application cache."},{name:"enable",description:"Enables application cache domain notifications."},{name:"getManifestForFrame",parameters:[{name:"frameId",$ref:"Page.FrameId",description:"Identifier of the frame containing document whose manifest is retrieved."}],returns:[{name:"manifestURL",type:"string",description:"Manifest URL for document in the given frame."}],description:"Returns manifest URL for document in the given frame."},{name:"getApplicationCacheForFrame",parameters:[{name:"frameId",$ref:"Page.FrameId",description:"Identifier of the frame containing document whose application cache is retrieved."}],returns:[{name:"applicationCache",$ref:"ApplicationCache",description:"Relevant application cache data for the document in given frame."}],description:"Returns relevant application cache data for the document in given frame."}],events:[{name:"applicationCacheStatusUpdated",parameters:[{name:"frameId",$ref:"Page.FrameId",description:"Identifier of the frame containing document whose application cache updated status."},{name:"manifestURL",type:"string",description:"Manifest URL."},{name:"status",type:"integer",description:"Updated application cache status."}]},{name:"networkStateUpdated",parameters:[{name:"isNowOnline",type:"boolean"}]}]},{domain:"DOM",description:"This domain exposes DOM read/write operations. Each DOM Node is represented with its mirror object that has an id. This id can be used to get additional information on the Node, resolve it into the JavaScript object wrapper, etc. It is important that client receives DOM events only for the nodes that are known to the client. Backend keeps track of the nodes that were sent to the client and never sends the same node twice. It is client's responsibility to collect information about the nodes that were sent to the client.

Note that iframe owner elements will return corresponding document elements as their child nodes.

",dependencies:["Runtime"],types:[{id:"NodeId",type:"integer",description:"Unique DOM node identifier."},{id:"BackendNodeId",type:"integer",description:"Unique DOM node identifier used to reference a node that may not have been pushed to the front-end.",experimental:!0},{id:"BackendNode",type:"object",properties:[{name:"nodeType",type:"integer",description:"Node's nodeType."},{name:"nodeName",type:"string",description:"Node's nodeName."},{name:"backendNodeId",$ref:"BackendNodeId"}],experimental:!0,description:"Backend node with a friendly name."},{id:"PseudoType",type:"string",enum:["first-line","first-letter","before","after","backdrop","selection","first-line-inherited","scrollbar","scrollbar-thumb","scrollbar-button","scrollbar-track","scrollbar-track-piece","scrollbar-corner","resizer","input-list-button"],description:"Pseudo element type."},{id:"ShadowRootType",type:"string",enum:["user-agent","open","closed"],description:"Shadow root type."},{id:"Node",type:"object",properties:[{name:"nodeId",$ref:"NodeId",description:"Node identifier that is passed into the rest of the DOM messages as the nodeId. Backend will only push node with given id once. It is aware of all requested nodes and will only fire DOM events for nodes known to the client."},{name:"backendNodeId",$ref:"BackendNodeId",description:"The BackendNodeId for this node.",experimental:!0},{name:"nodeType",type:"integer",description:"Node's nodeType."},{name:"nodeName",type:"string",description:"Node's nodeName."},{name:"localName",type:"string",description:"Node's localName."},{name:"nodeValue",type:"string",description:"Node's nodeValue."},{name:"childNodeCount",type:"integer",optional:!0,description:"Child count for Container nodes."},{name:"children",type:"array",optional:!0,items:{$ref:"Node"},description:"Child nodes of this node when requested with children."},{name:"attributes",type:"array",optional:!0,items:{type:"string"},description:"Attributes of the Element node in the form of flat array [name1, value1, name2, value2]."},{name:"documentURL",type:"string",optional:!0,description:"Document URL that Document or FrameOwner node points to."},{name:"baseURL",type:"string",optional:!0,description:"Base URL that Document or FrameOwner node uses for URL completion.",experimental:!0},{name:"publicId",type:"string",optional:!0,description:"DocumentType's publicId."},{name:"systemId",type:"string",optional:!0,description:"DocumentType's systemId."},{name:"internalSubset",type:"string",optional:!0,description:"DocumentType's internalSubset."},{name:"xmlVersion",type:"string",optional:!0,description:"Document's XML version in case of XML documents."},{name:"name",type:"string",optional:!0,description:"Attr's name."},{name:"value",type:"string",optional:!0,description:"Attr's value."},{name:"pseudoType",$ref:"PseudoType",optional:!0,description:"Pseudo element type for this node."},{name:"shadowRootType",$ref:"ShadowRootType",optional:!0,description:"Shadow root type."},{name:"frameId",$ref:"Page.FrameId",optional:!0,description:"Frame ID for frame owner elements.",experimental:!0},{name:"contentDocument",$ref:"Node",optional:!0,description:"Content document for frame owner elements."},{name:"shadowRoots",type:"array",optional:!0,items:{$ref:"Node"},description:"Shadow root list for given element host.",experimental:!0},{name:"templateContent",$ref:"Node",optional:!0,description:"Content document fragment for template elements.",experimental:!0},{name:"pseudoElements",type:"array",items:{$ref:"Node"},optional:!0,description:"Pseudo elements associated with this node.",experimental:!0},{name:"importedDocument",$ref:"Node",optional:!0,description:"Import document for the HTMLImport links."},{name:"distributedNodes",type:"array",items:{$ref:"BackendNode"},optional:!0,description:"Distributed nodes for given insertion point.",experimental:!0}],description:"DOM interaction is implemented in terms of mirror objects that represent the actual DOM nodes. DOMNode is a base node mirror type."},{id:"RGBA",type:"object",properties:[{name:"r",type:"integer",description:"The red component, in the [0-255] range."},{name:"g",type:"integer",description:"The green component, in the [0-255] range."},{name:"b",type:"integer",description:"The blue component, in the [0-255] range."},{name:"a",type:"number",optional:!0,description:"The alpha component, in the [0-1] range (default: 1)."}],description:"A structure holding an RGBA color."},{id:"Quad",type:"array",items:{type:"number"},minItems:8,maxItems:8,description:"An array of quad vertices, x immediately followed by y for each point, points clock-wise.",experimental:!0},{id:"BoxModel",type:"object",experimental:!0,properties:[{name:"content",$ref:"Quad",description:"Content box"},{name:"padding",$ref:"Quad",description:"Padding box"},{name:"border",$ref:"Quad",description:"Border box"},{name:"margin",$ref:"Quad",description:"Margin box"},{name:"width",type:"integer",description:"Node width"},{name:"height",type:"integer",description:"Node height"},{name:"shapeOutside",$ref:"ShapeOutsideInfo",optional:!0,description:"Shape outside coordinates"}],description:"Box model."},{id:"ShapeOutsideInfo",type:"object",experimental:!0,properties:[{name:"bounds",$ref:"Quad",description:"Shape bounds"},{name:"shape",type:"array",items:{type:"any"},description:"Shape coordinate details"},{name:"marginShape",type:"array",items:{type:"any"},description:"Margin shape bounds"}],description:"CSS Shape Outside details."},{id:"Rect",type:"object",experimental:!0,properties:[{name:"x",type:"number",description:"X coordinate"},{name:"y",type:"number",description:"Y coordinate"},{name:"width",type:"number",description:"Rectangle width"},{name:"height",type:"number",description:"Rectangle height"}],description:"Rectangle."},{id:"HighlightConfig",type:"object",properties:[{name:"showInfo",type:"boolean",optional:!0,description:"Whether the node info tooltip should be shown (default: false)."},{name:"showRulers",type:"boolean",optional:!0,description:"Whether the rulers should be shown (default: false)."},{name:"showExtensionLines",type:"boolean",optional:!0,description:"Whether the extension lines from node to the rulers should be shown (default: false)."},{name:"displayAsMaterial",type:"boolean",optional:!0,experimental:!0},{name:"contentColor",$ref:"RGBA",optional:!0,description:"The content box highlight fill color (default: transparent)."},{name:"paddingColor",$ref:"RGBA",optional:!0,description:"The padding highlight fill color (default: transparent)."},{name:"borderColor",$ref:"RGBA",optional:!0,description:"The border highlight fill color (default: transparent)."},{name:"marginColor",$ref:"RGBA",optional:!0,description:"The margin highlight fill color (default: transparent)."},{name:"eventTargetColor",$ref:"RGBA",optional:!0,experimental:!0,description:"The event target element highlight fill color (default: transparent)."},{name:"shapeColor",$ref:"RGBA",optional:!0,experimental:!0,description:"The shape outside fill color (default: transparent)."},{name:"shapeMarginColor",$ref:"RGBA",optional:!0,experimental:!0,description:"The shape margin fill color (default: transparent)."},{name:"selectorList",type:"string",optional:!0,description:"Selectors to highlight relevant nodes."}],description:"Configuration data for the highlighting of page elements."},{id:"InspectMode",type:"string",experimental:!0,enum:["searchForNode","searchForUAShadowDOM","none"]}],commands:[{name:"enable",description:"Enables DOM agent for the given page."},{name:"disable",description:"Disables DOM agent for the given page."},{name:"getDocument",parameters:[{name:"depth",type:"integer",optional:!0,description:"The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.",experimental:!0},{name:"pierce",type:"boolean",optional:!0,description:"Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false).",experimental:!0}],returns:[{name:"root",$ref:"Node",description:"Resulting node."}],description:"Returns the root DOM node (and optionally the subtree) to the caller."},{name:"collectClassNamesFromSubtree",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to collect class names."}],returns:[{name:"classNames",type:"array",items:{type:"string"},description:"Class name list."}],description:"Collects class names for the node with given id and all of it's child nodes.",experimental:!0},{name:"requestChildNodes",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to get children for."},{name:"depth",type:"integer",optional:!0,description:"The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.",experimental:!0},{name:"pierce",type:"boolean",optional:!0,description:"Whether or not iframes and shadow roots should be traversed when returning the sub-tree (default is false).",experimental:!0}],description:"Requests that children of the node with given id are returned to the caller in form of setChildNodes events where not only immediate children are retrieved, but all children down to the specified depth."},{name:"querySelector",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to query upon."},{name:"selector",type:"string",description:"Selector string."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Query selector result."}],description:"Executes querySelector on a given node."},{name:"querySelectorAll",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to query upon."},{name:"selector",type:"string",description:"Selector string."}],returns:[{name:"nodeIds",type:"array",items:{$ref:"NodeId"},description:"Query selector result."}],description:"Executes querySelectorAll on a given node."},{name:"setNodeName",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to set name for."},{name:"name",type:"string",description:"New node's name."}],returns:[{name:"nodeId",$ref:"NodeId",description:"New node's id."}],description:"Sets node name for a node with given id."},{name:"setNodeValue",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to set value for."},{name:"value",type:"string",description:"New node's value."}],description:"Sets node value for a node with given id."},{name:"removeNode",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to remove."}],description:"Removes node with given id."},{name:"setAttributeValue",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the element to set attribute for."},{name:"name",type:"string",description:"Attribute name."},{name:"value",type:"string",description:"Attribute value."}],description:"Sets attribute for an element with given id."},{name:"setAttributesAsText",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the element to set attributes for."},{name:"text",type:"string",description:"Text with a number of attributes. Will parse this text using HTML parser."},{name:"name",type:"string",optional:!0,description:"Attribute name to replace with new attributes derived from text in case text parsed successfully."}],description:"Sets attributes on element with given id. This method is useful when user edits some existing attribute value and types in several attribute name/value pairs."},{name:"removeAttribute",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the element to remove attribute from."},{name:"name",type:"string",description:"Name of the attribute to remove."}],description:"Removes attribute with given name from an element with given id."},{name:"getOuterHTML",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to get markup for."}],returns:[{name:"outerHTML",type:"string",description:"Outer HTML markup."}],description:"Returns node's HTML markup."},{name:"setOuterHTML",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to set markup for."},{name:"outerHTML",type:"string",description:"Outer HTML markup to set."}],description:"Sets node HTML markup, returns new node id."},{name:"performSearch",parameters:[{name:"query",type:"string",description:"Plain text or query selector or XPath search query."},{name:"includeUserAgentShadowDOM",type:"boolean",optional:!0,description:"True to search in user agent shadow DOM.",experimental:!0}],returns:[{name:"searchId",type:"string",description:"Unique search session identifier."},{name:"resultCount",type:"integer",description:"Number of search results."}],description:"Searches for a given string in the DOM tree. Use getSearchResults to access search results or cancelSearch to end this search session.",experimental:!0},{name:"getSearchResults",parameters:[{name:"searchId",type:"string",description:"Unique search session identifier."},{name:"fromIndex",type:"integer",description:"Start index of the search result to be returned."},{name:"toIndex",type:"integer",description:"End index of the search result to be returned."}],returns:[{name:"nodeIds",type:"array",items:{$ref:"NodeId"},description:"Ids of the search result nodes."}],description:"Returns search results from given fromIndex to given toIndex from the sarch with the given identifier.",experimental:!0},{name:"discardSearchResults",parameters:[{name:"searchId",type:"string",description:"Unique search session identifier."}],description:"Discards search results from the session with the given id. getSearchResults should no longer be called for that search.", + experimental:!0},{name:"requestNode",parameters:[{name:"objectId",$ref:"Runtime.RemoteObjectId",description:"JavaScript object id to convert into node."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Node id for given object."}],description:"Requests that the node is sent to the caller given the JavaScript node object reference. All nodes that form the path from the node to the root are also sent to the client as a series of setChildNodes notifications."},{name:"setInspectMode",experimental:!0,parameters:[{name:"mode",$ref:"InspectMode",description:"Set an inspection mode."},{name:"highlightConfig",$ref:"HighlightConfig",optional:!0,description:"A descriptor for the highlight appearance of hovered-over nodes. May be omitted if enabled == false."}],description:"Enters the 'inspect' mode. In this mode, elements that user is hovering over are highlighted. Backend then generates 'inspectNodeRequested' event upon element selection."},{name:"highlightRect",parameters:[{name:"x",type:"integer",description:"X coordinate"},{name:"y",type:"integer",description:"Y coordinate"},{name:"width",type:"integer",description:"Rectangle width"},{name:"height",type:"integer",description:"Rectangle height"},{name:"color",$ref:"RGBA",optional:!0,description:"The highlight fill color (default: transparent)."},{name:"outlineColor",$ref:"RGBA",optional:!0,description:"The highlight outline color (default: transparent)."}],description:"Highlights given rectangle. Coordinates are absolute with respect to the main frame viewport."},{name:"highlightQuad",parameters:[{name:"quad",$ref:"Quad",description:"Quad to highlight"},{name:"color",$ref:"RGBA",optional:!0,description:"The highlight fill color (default: transparent)."},{name:"outlineColor",$ref:"RGBA",optional:!0,description:"The highlight outline color (default: transparent)."}],description:"Highlights given quad. Coordinates are absolute with respect to the main frame viewport.",experimental:!0},{name:"highlightNode",parameters:[{name:"highlightConfig",$ref:"HighlightConfig",description:"A descriptor for the highlight appearance."},{name:"nodeId",$ref:"NodeId",optional:!0,description:"Identifier of the node to highlight."},{name:"backendNodeId",$ref:"BackendNodeId",optional:!0,description:"Identifier of the backend node to highlight."},{name:"objectId",$ref:"Runtime.RemoteObjectId",optional:!0,description:"JavaScript object id of the node to be highlighted.",experimental:!0}],description:"Highlights DOM node with given id or with the given JavaScript object wrapper. Either nodeId or objectId must be specified."},{name:"hideHighlight",description:"Hides DOM node highlight."},{name:"highlightFrame",parameters:[{name:"frameId",$ref:"Page.FrameId",description:"Identifier of the frame to highlight."},{name:"contentColor",$ref:"RGBA",optional:!0,description:"The content box highlight fill color (default: transparent)."},{name:"contentOutlineColor",$ref:"RGBA",optional:!0,description:"The content box highlight outline color (default: transparent)."}],description:"Highlights owner element of the frame with given id.",experimental:!0},{name:"pushNodeByPathToFrontend",parameters:[{name:"path",type:"string",description:"Path to node in the proprietary format."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Id of the node for given path."}],description:"Requests that the node is sent to the caller given its path. // FIXME, use XPath",experimental:!0},{name:"pushNodesByBackendIdsToFrontend",parameters:[{name:"backendNodeIds",type:"array",items:{$ref:"BackendNodeId"},description:"The array of backend node ids."}],returns:[{name:"nodeIds",type:"array",items:{$ref:"NodeId"},description:"The array of ids of pushed nodes that correspond to the backend ids specified in backendNodeIds."}],description:"Requests that a batch of nodes is sent to the caller given their backend node ids.",experimental:!0},{name:"setInspectedNode",parameters:[{name:"nodeId",$ref:"NodeId",description:"DOM node id to be accessible by means of $x command line API."}],description:"Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions).",experimental:!0},{name:"resolveNode",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to resolve."},{name:"objectGroup",type:"string",optional:!0,description:"Symbolic group name that can be used to release multiple objects."}],returns:[{name:"object",$ref:"Runtime.RemoteObject",description:"JavaScript object wrapper for given node."}],description:"Resolves JavaScript node object for given node id."},{name:"getAttributes",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to retrieve attibutes for."}],returns:[{name:"attributes",type:"array",items:{type:"string"},description:"An interleaved array of node attribute names and values."}],description:"Returns attributes for the specified node."},{name:"copyTo",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to copy."},{name:"targetNodeId",$ref:"NodeId",description:"Id of the element to drop the copy into."},{name:"insertBeforeNodeId",$ref:"NodeId",optional:!0,description:"Drop the copy before this node (if absent, the copy becomes the last child of targetNodeId)."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Id of the node clone."}],description:"Creates a deep copy of the specified node and places it into the target container before the given anchor.",experimental:!0},{name:"moveTo",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to move."},{name:"targetNodeId",$ref:"NodeId",description:"Id of the element to drop the moved node into."},{name:"insertBeforeNodeId",$ref:"NodeId",optional:!0,description:"Drop node before this one (if absent, the moved node becomes the last child of targetNodeId)."}],returns:[{name:"nodeId",$ref:"NodeId",description:"New id of the moved node."}],description:"Moves node into the new container, places it before the given anchor."},{name:"undo",description:"Undoes the last performed action.",experimental:!0},{name:"redo",description:"Re-does the last undone action.",experimental:!0},{name:"markUndoableState",description:"Marks last undoable state.",experimental:!0},{name:"focus",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to focus."}],description:"Focuses the given element.",experimental:!0},{name:"setFileInputFiles",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the file input node to set files for."},{name:"files",type:"array",items:{type:"string"},description:"Array of file paths to set."}],description:"Sets files for the given file input element.",experimental:!0},{name:"getBoxModel",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to get box model for."}],returns:[{name:"model",$ref:"BoxModel",description:"Box model for the node."}],description:"Returns boxes for the currently selected nodes.",experimental:!0},{name:"getNodeForLocation",parameters:[{name:"x",type:"integer",description:"X coordinate."},{name:"y",type:"integer",description:"Y coordinate."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Id of the node at given coordinates."}],description:"Returns node id at given location.",experimental:!0},{name:"getRelayoutBoundary",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node."}],returns:[{name:"nodeId",$ref:"NodeId",description:"Relayout boundary node id for the given node."}],description:"Returns the id of the nearest ancestor that is a relayout boundary.",experimental:!0},{name:"getHighlightObjectForTest",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node to get highlight object for."}],returns:[{name:"highlight",type:"object",description:"Highlight data for the node."}],description:"For testing.",experimental:!0}],events:[{name:"documentUpdated",description:"Fired when Document has been totally updated. Node ids are no longer valid."},{name:"inspectNodeRequested",parameters:[{name:"backendNodeId",$ref:"BackendNodeId",description:"Id of the node to inspect."}],description:"Fired when the node should be inspected. This happens after call to setInspectMode.",experimental:!0},{name:"setChildNodes",parameters:[{name:"parentId",$ref:"NodeId",description:"Parent node id to populate with children."},{name:"nodes",type:"array",items:{$ref:"Node"},description:"Child nodes array."}],description:"Fired when backend wants to provide client with the missing DOM structure. This happens upon most of the calls requesting node ids."},{name:"attributeModified",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node that has changed."},{name:"name",type:"string",description:"Attribute name."},{name:"value",type:"string",description:"Attribute value."}],description:"Fired when Element's attribute is modified."},{name:"attributeRemoved",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node that has changed."},{name:"name",type:"string",description:"A ttribute name."}],description:"Fired when Element's attribute is removed."},{name:"inlineStyleInvalidated",parameters:[{name:"nodeIds",type:"array",items:{$ref:"NodeId"},description:"Ids of the nodes for which the inline styles have been invalidated."}],description:"Fired when Element's inline style is modified via a CSS property modification.",experimental:!0},{name:"characterDataModified",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node that has changed."},{name:"characterData",type:"string",description:"New text value."}],description:"Mirrors DOMCharacterDataModified event."},{name:"childNodeCountUpdated",parameters:[{name:"nodeId",$ref:"NodeId",description:"Id of the node that has changed."},{name:"childNodeCount",type:"integer",description:"New node count."}],description:"Fired when Container's child node count has changed."},{name:"childNodeInserted",parameters:[{name:"parentNodeId",$ref:"NodeId",description:"Id of the node that has changed."},{name:"previousNodeId",$ref:"NodeId",description:"If of the previous siblint."},{name:"node",$ref:"Node",description:"Inserted node data."}],description:"Mirrors DOMNodeInserted event."},{name:"childNodeRemoved",parameters:[{name:"parentNodeId",$ref:"NodeId",description:"Parent id."},{name:"nodeId",$ref:"NodeId",description:"Id of the node that has been removed."}],description:"Mirrors DOMNodeRemoved event."},{name:"shadowRootPushed",parameters:[{name:"hostId",$ref:"NodeId",description:"Host element id."},{name:"root",$ref:"Node",description:"Shadow root."}],description:"Called when shadow root is pushed into the element.",experimental:!0},{name:"shadowRootPopped",parameters:[{name:"hostId",$ref:"NodeId",description:"Host element id."},{name:"rootId",$ref:"NodeId",description:"Shadow root id."}],description:"Called when shadow root is popped from the element.",experimental:!0},{name:"pseudoElementAdded",parameters:[{name:"parentId",$ref:"NodeId",description:"Pseudo element's parent element id."},{name:"pseudoElement",$ref:"Node",description:"The added pseudo element."}],description:"Called when a pseudo element is added to an element.",experimental:!0},{name:"pseudoElementRemoved",parameters:[{name:"parentId",$ref:"NodeId",description:"Pseudo element's parent element id."},{name:"pseudoElementId",$ref:"NodeId",description:"The removed pseudo element id."}],description:"Called when a pseudo element is removed from an element.",experimental:!0},{name:"distributedNodesUpdated",parameters:[{name:"insertionPointId",$ref:"NodeId",description:"Insertion point where distrubuted nodes were updated."},{name:"distributedNodes",type:"array",items:{$ref:"BackendNode"},description:"Distributed nodes for given insertion point."}],description:"Called when distrubution is changed.",experimental:!0},{name:"nodeHighlightRequested",parameters:[{name:"nodeId",$ref:"NodeId"}],experimental:!0}]},{domain:"CSS",experimental:!0,description:"This domain exposes CSS read/write operations. All CSS objects (stylesheets, rules, and styles) have an associated id used in subsequent operations on the related object. Each object type has a specific id structure, and those are not interchangeable between objects of different kinds. CSS objects can be loaded using the get*ForNode() calls (which accept a DOM node id). A client can also discover all the existing stylesheets with the getAllStyleSheets() method (or keeping track of the styleSheetAdded/styleSheetRemoved events) and subsequently load the required stylesheet contents using the getStyleSheet[Text]() methods.",dependencies:["DOM"],types:[{id:"StyleSheetId",type:"string"},{id:"StyleSheetOrigin",type:"string",enum:["injected","user-agent","inspector","regular"],description:'Stylesheet type: "injected" for stylesheets injected via extension, "user-agent" for user-agent stylesheets, "inspector" for stylesheets created by the inspector (i.e. those holding the "via inspector" rules), "regular" for regular stylesheets.'},{id:"PseudoElementMatches",type:"object",properties:[{name:"pseudoType",$ref:"DOM.PseudoType",description:"Pseudo element type."},{name:"matches",type:"array",items:{$ref:"RuleMatch"},description:"Matches of CSS rules applicable to the pseudo style."}],description:"CSS rule collection for a single pseudo style."},{id:"InheritedStyleEntry",type:"object",properties:[{name:"inlineStyle",$ref:"CSSStyle",optional:!0,description:"The ancestor node's inline style, if any, in the style inheritance chain."},{name:"matchedCSSRules",type:"array",items:{$ref:"RuleMatch"},description:"Matches of CSS rules matching the ancestor node in the style inheritance chain."}],description:"Inherited CSS rule collection from ancestor node."},{id:"RuleMatch",type:"object",properties:[{name:"rule",$ref:"CSSRule",description:"CSS rule in the match."},{name:"matchingSelectors",type:"array",items:{type:"integer"},description:"Matching selector indices in the rule's selectorList selectors (0-based)."}],description:"Match data for a CSS rule."},{id:"Value",type:"object",properties:[{name:"text",type:"string",description:"Value text."},{name:"range",$ref:"SourceRange",optional:!0,description:"Value range in the underlying resource (if available)."}],description:"Data for a simple selector (these are delimited by commas in a selector list)."},{id:"SelectorList",type:"object",properties:[{name:"selectors",type:"array",items:{$ref:"Value"},description:"Selectors in the list."},{name:"text",type:"string",description:"Rule selector text."}],description:"Selector list data."},{id:"CSSStyleSheetHeader",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",description:"The stylesheet identifier."},{name:"frameId",$ref:"Page.FrameId",description:"Owner frame identifier."},{name:"sourceURL",type:"string",description:"Stylesheet resource URL."},{name:"sourceMapURL",type:"string",optional:!0,description:"URL of source map associated with the stylesheet (if any)."},{name:"origin",$ref:"StyleSheetOrigin",description:"Stylesheet origin."},{name:"title",type:"string",description:"Stylesheet title."},{name:"ownerNode",$ref:"DOM.BackendNodeId",optional:!0,description:"The backend id for the owner node of the stylesheet."},{name:"disabled",type:"boolean",description:"Denotes whether the stylesheet is disabled."},{name:"hasSourceURL",type:"boolean",optional:!0,description:"Whether the sourceURL field value comes from the sourceURL comment."},{name:"isInline",type:"boolean",description:"Whether this stylesheet is created for STYLE tag by parser. This flag is not set for document.written STYLE tags."},{name:"startLine",type:"number",description:"Line offset of the stylesheet within the resource (zero based)."},{name:"startColumn",type:"number",description:"Column offset of the stylesheet within the resource (zero based)."}],description:"CSS stylesheet metainformation."},{id:"CSSRule",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",optional:!0,description:"The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from."},{name:"selectorList",$ref:"SelectorList",description:"Rule selector data."},{name:"origin",$ref:"StyleSheetOrigin",description:"Parent stylesheet's origin."},{name:"style",$ref:"CSSStyle",description:"Associated style declaration."},{name:"media",type:"array",items:{$ref:"CSSMedia"},optional:!0,description:"Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards."}],description:"CSS rule representation."},{id:"RuleUsage",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",description:"The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from."},{name:"range",$ref:"SourceRange",description:"Style declaration range in the enclosing stylesheet (if available)."},{name:"used",type:"boolean",description:"Indicates whether the rule was actually used by some element in the page."}],description:"CSS rule usage information.",experimental:!0},{id:"SourceRange",type:"object",properties:[{name:"startLine",type:"integer",description:"Start line of range."},{name:"startColumn",type:"integer",description:"Start column of range (inclusive)."},{name:"endLine",type:"integer",description:"End line of range"},{name:"endColumn",type:"integer",description:"End column of range (exclusive)."}],description:"Text range within a resource. All numbers are zero-based."},{id:"ShorthandEntry",type:"object",properties:[{name:"name",type:"string",description:"Shorthand name."},{name:"value",type:"string",description:"Shorthand value."},{name:"important",type:"boolean",optional:!0,description:'Whether the property has "!important" annotation (implies false if absent).'}]},{id:"CSSComputedStyleProperty",type:"object",properties:[{name:"name",type:"string",description:"Computed style property name."},{name:"value",type:"string",description:"Computed style property value."}]},{id:"CSSStyle",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",optional:!0,description:"The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from."},{name:"cssProperties",type:"array",items:{$ref:"CSSProperty"},description:"CSS properties in the style."},{name:"shorthandEntries",type:"array",items:{$ref:"ShorthandEntry"},description:"Computed values for all shorthands found in the style."},{name:"cssText",type:"string",optional:!0,description:"Style declaration text (if available)."},{name:"range",$ref:"SourceRange",optional:!0,description:"Style declaration range in the enclosing stylesheet (if available)."}],description:"CSS style representation."},{id:"CSSProperty",type:"object",properties:[{name:"name",type:"string",description:"The property name."},{name:"value",type:"string",description:"The property value."},{name:"important",type:"boolean",optional:!0,description:'Whether the property has "!important" annotation (implies false if absent).'},{name:"implicit",type:"boolean",optional:!0,description:"Whether the property is implicit (implies false if absent)."},{name:"text",type:"string",optional:!0,description:"The full property text as specified in the style."},{name:"parsedOk",type:"boolean",optional:!0,description:"Whether the property is understood by the browser (implies true if absent)."},{name:"disabled",type:"boolean",optional:!0,description:"Whether the property is disabled by the user (present for source-based properties only)."},{name:"range",$ref:"SourceRange",optional:!0,description:"The entire property range in the enclosing style declaration (if available)."}],description:"CSS property declaration data."},{id:"CSSMedia",type:"object",properties:[{name:"text",type:"string",description:"Media query text."},{name:"source",type:"string",enum:["mediaRule","importRule","linkedSheet","inlineSheet"],description:'Source of the media query: "mediaRule" if specified by a @media rule, "importRule" if specified by an @import rule, "linkedSheet" if specified by a "media" attribute in a linked stylesheet\'s LINK tag, "inlineSheet" if specified by a "media" attribute in an inline stylesheet\'s STYLE tag.'},{name:"sourceURL",type:"string",optional:!0,description:"URL of the document containing the media query description."},{name:"range",$ref:"SourceRange",optional:!0,description:"The associated rule (@media or @import) header range in the enclosing stylesheet (if available)."},{name:"styleSheetId",$ref:"StyleSheetId",optional:!0,description:"Identifier of the stylesheet containing this object (if exists)."},{name:"mediaList",type:"array",items:{$ref:"MediaQuery"},optional:!0,experimental:!0,description:"Array of media queries."}],description:"CSS media rule descriptor."},{id:"MediaQuery",type:"object",properties:[{name:"expressions",type:"array",items:{$ref:"MediaQueryExpression"},description:"Array of media query expressions."},{name:"active",type:"boolean",description:"Whether the media query condition is satisfied."}],description:"Media query descriptor.",experimental:!0},{id:"MediaQueryExpression",type:"object",properties:[{name:"value",type:"number",description:"Media query expression value."},{name:"unit",type:"string",description:"Media query expression units."},{name:"feature",type:"string",description:"Media query expression feature."},{name:"valueRange",$ref:"SourceRange",optional:!0,description:"The associated range of the value text in the enclosing stylesheet (if available)."},{name:"computedLength",type:"number",optional:!0,description:"Computed length of media query expression (if applicable)."}],description:"Media query expression descriptor.",experimental:!0},{id:"PlatformFontUsage",type:"object",properties:[{name:"familyName",type:"string",description:"Font's family name reported by platform."},{name:"isCustomFont",type:"boolean",description:"Indicates if the font was downloaded or resolved locally."},{name:"glyphCount",type:"number",description:"Amount of glyphs that were rendered with this font."}],description:"Information about amount of glyphs that were rendered with given font.",experimental:!0},{id:"CSSKeyframesRule",type:"object",properties:[{name:"animationName",$ref:"Value",description:"Animation name."},{name:"keyframes",type:"array",items:{$ref:"CSSKeyframeRule"},description:"List of keyframes."}],description:"CSS keyframes rule representation."},{id:"CSSKeyframeRule",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",optional:!0,description:"The css style sheet identifier (absent for user agent stylesheet and user-specified stylesheet rules) this rule came from."},{name:"origin",$ref:"StyleSheetOrigin",description:"Parent stylesheet's origin."},{name:"keyText",$ref:"Value",description:"Associated key text."},{name:"style",$ref:"CSSStyle",description:"Associated style declaration."}],description:"CSS keyframe rule representation."},{id:"StyleDeclarationEdit",type:"object",properties:[{name:"styleSheetId",$ref:"StyleSheetId",description:"The css style sheet identifier."},{name:"range",$ref:"SourceRange",description:"The range of the style text in the enclosing stylesheet."},{name:"text",type:"string",description:"New style text."}],description:"A descriptor of operation to mutate style declaration text."},{id:"InlineTextBox",type:"object",properties:[{name:"boundingBox",$ref:"DOM.Rect",description:"The absolute position bounding box."},{name:"startCharacterIndex",type:"integer",description:"The starting index in characters, for this post layout textbox substring."},{name:"numCharacters",type:"integer",description:"The number of characters in this post layout textbox substring."}],description:"Details of post layout rendered text positions. The exact layout should not be regarded as stable and may change between versions.",experimental:!0},{id:"LayoutTreeNode",type:"object",properties:[{name:"nodeId",$ref:"DOM.NodeId",description:"The id of the related DOM node matching one from DOM.GetDocument."},{name:"boundingBox",$ref:"DOM.Rect",description:"The absolute position bounding box."},{name:"layoutText",type:"string",optional:!0,description:"Contents of the LayoutText if any"},{name:"inlineTextNodes",type:"array",optional:!0,items:{$ref:"InlineTextBox"},description:"The post layout inline text nodes, if any."},{name:"styleIndex",type:"integer",optional:!0,description:"Index into the computedStyles array returned by getLayoutTreeAndStyles."}],description:"Details of an element in the DOM tree with a LayoutObject.",experimental:!0},{id:"ComputedStyle",type:"object",properties:[{name:"properties",type:"array",items:{$ref:"CSSComputedStyleProperty"}}],description:"A subset of the full ComputedStyle as defined by the request whitelist.",experimental:!0}],commands:[{name:"enable",description:"Enables the CSS agent for the given page. Clients should not assume that the CSS agent has been enabled until the result of this command is received."},{name:"disable",description:"Disables the CSS agent for the given page."},{name:"getMatchedStylesForNode",parameters:[{name:"nodeId",$ref:"DOM.NodeId"}],returns:[{name:"inlineStyle",$ref:"CSSStyle",optional:!0,description:"Inline style for the specified DOM node."},{name:"attributesStyle",$ref:"CSSStyle",optional:!0,description:'Attribute-defined element style (e.g. resulting from "width=20 height=100%").'},{name:"matchedCSSRules",type:"array",items:{$ref:"RuleMatch"},optional:!0,description:"CSS rules matching this node, from all applicable stylesheets."},{name:"pseudoElements",type:"array",items:{$ref:"PseudoElementMatches"},optional:!0,description:"Pseudo style matches for this node."},{name:"inherited",type:"array",items:{$ref:"InheritedStyleEntry"},optional:!0,description:"A chain of inherited styles (from the immediate node parent up to the DOM tree root)."},{name:"cssKeyframesRules",type:"array",items:{$ref:"CSSKeyframesRule"},optional:!0,description:"A list of CSS keyframed animations matching this node."}],description:"Returns requested styles for a DOM node identified by nodeId."},{name:"getInlineStylesForNode",parameters:[{name:"nodeId",$ref:"DOM.NodeId"}],returns:[{name:"inlineStyle",$ref:"CSSStyle",optional:!0,description:"Inline style for the specified DOM node."},{name:"attributesStyle",$ref:"CSSStyle",optional:!0,description:'Attribute-defined element style (e.g. resulting from "width=20 height=100%").'}],description:'Returns the styles defined inline (explicitly in the "style" attribute and implicitly, using DOM attributes) for a DOM node identified by nodeId.'},{name:"getComputedStyleForNode",parameters:[{name:"nodeId",$ref:"DOM.NodeId"}],returns:[{name:"computedStyle",type:"array",items:{$ref:"CSSComputedStyleProperty"},description:"Computed style for the specified DOM node."}],description:"Returns the computed style for a DOM node identified by nodeId."},{name:"getPlatformFontsForNode",parameters:[{name:"nodeId",$ref:"DOM.NodeId"}],returns:[{name:"fonts",type:"array",items:{$ref:"PlatformFontUsage"},description:"Usage statistics for every employed platform font."}],description:"Requests information about platform fonts which we used to render child TextNodes in the given node.",experimental:!0},{name:"getStyleSheetText",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"}],returns:[{name:"text",type:"string",description:"The stylesheet text."}],description:"Returns the current textual content and the URL for a stylesheet."},{name:"collectClassNames",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"}],returns:[{name:"classNames",type:"array",items:{type:"string"},description:"Class name list."}],description:"Returns all class names from specified stylesheet.",experimental:!0},{name:"setStyleSheetText",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"},{name:"text",type:"string"}],returns:[{name:"sourceMapURL",type:"string",optional:!0,description:"URL of source map associated with script (if any)."}],description:"Sets the new stylesheet text."},{name:"setRuleSelector",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"},{name:"range",$ref:"SourceRange"},{name:"selector",type:"string"}],returns:[{name:"selectorList",$ref:"SelectorList",description:"The resulting selector list after modification."}],description:"Modifies the rule selector."},{name:"setKeyframeKey",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"},{name:"range",$ref:"SourceRange"},{name:"keyText",type:"string"}],returns:[{name:"keyText",$ref:"Value",description:"The resulting key text after modification."}],description:"Modifies the keyframe rule key text."},{name:"setStyleTexts",parameters:[{name:"edits",type:"array",items:{$ref:"StyleDeclarationEdit"}}],returns:[{name:"styles",type:"array",items:{$ref:"CSSStyle"},description:"The resulting styles after modification."}],description:"Applies specified style edits one after another in the given order."},{name:"setMediaText",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"},{name:"range",$ref:"SourceRange"},{name:"text",type:"string"}],returns:[{name:"media",$ref:"CSSMedia",description:"The resulting CSS media rule after modification."}],description:"Modifies the rule selector."},{name:"createStyleSheet",parameters:[{name:"frameId",$ref:"Page.FrameId",description:'Identifier of the frame where "via-inspector" stylesheet should be created.'}],returns:[{name:"styleSheetId",$ref:"StyleSheetId",description:'Identifier of the created "via-inspector" stylesheet.'}],description:'Creates a new special "via-inspector" stylesheet in the frame with given frameId.'},{name:"addRule",parameters:[{name:"styleSheetId",$ref:"StyleSheetId",description:"The css style sheet identifier where a new rule should be inserted."},{name:"ruleText",type:"string",description:"The text of a new rule."},{name:"location",$ref:"SourceRange",description:"Text position of a new rule in the target style sheet."}],returns:[{name:"rule",$ref:"CSSRule",description:"The newly created rule."}],description:"Inserts a new rule with the given ruleText in a stylesheet with given styleSheetId, at the position specified by location."},{name:"forcePseudoState",parameters:[{name:"nodeId",$ref:"DOM.NodeId",description:"The element id for which to force the pseudo state."},{name:"forcedPseudoClasses",type:"array",items:{type:"string",enum:["active","focus","hover","visited"]},description:"Element pseudo classes to force when computing the element's style."}],description:"Ensures that the given node will have specified pseudo-classes whenever its style is computed by the browser."},{name:"getMediaQueries",returns:[{name:"medias",type:"array",items:{$ref:"CSSMedia"}}],description:"Returns all media queries parsed by the rendering engine.",experimental:!0},{name:"setEffectivePropertyValueForNode",parameters:[{name:"nodeId",$ref:"DOM.NodeId",description:"The element id for which to set property."},{name:"propertyName",type:"string"},{name:"value",type:"string"}],description:"Find a rule with the given active property for the given node and set the new value for this property",experimental:!0},{name:"getBackgroundColors",parameters:[{name:"nodeId",$ref:"DOM.NodeId",description:"Id of the node to get background colors for."}],returns:[{name:"backgroundColors",type:"array",items:{type:"string"},description:"The range of background colors behind this element, if it contains any visible text. If no visible text is present, this will be undefined. In the case of a flat background color, this will consist of simply that color. In the case of a gradient, this will consist of each of the color stops. For anything more complicated, this will be an empty array. Images will be ignored (as if the image had failed to load).", + optional:!0}],experimental:!0},{name:"getLayoutTreeAndStyles",parameters:[{name:"computedStyleWhitelist",type:"array",items:{type:"string"},description:"Whitelist of computed styles to return."}],returns:[{name:"layoutTreeNodes",type:"array",items:{$ref:"LayoutTreeNode"}},{name:"computedStyles",type:"array",items:{$ref:"ComputedStyle"}}],description:"For the main document and any content documents, return the LayoutTreeNodes and a whitelisted subset of the computed style. It only returns pushed nodes, on way to pull all nodes is to call DOM.getDocument with a depth of -1.",experimental:!0},{name:"startRuleUsageTracking",description:"Enables the selector recording.",experimental:!0},{name:"stopRuleUsageTracking",returns:[{name:"ruleUsage",type:"array",items:{$ref:"RuleUsage"}}],description:"The list of rules with an indication of whether these were used",experimental:!0}],events:[{name:"mediaQueryResultChanged",description:"Fires whenever a MediaQuery result changes (for example, after a browser window has been resized.) The current implementation considers only viewport-dependent media features."},{name:"fontsUpdated",description:"Fires whenever a web font gets loaded."},{name:"styleSheetChanged",parameters:[{name:"styleSheetId",$ref:"StyleSheetId"}],description:"Fired whenever a stylesheet is changed as a result of the client operation."},{name:"styleSheetAdded",parameters:[{name:"header",$ref:"CSSStyleSheetHeader",description:"Added stylesheet metainfo."}],description:"Fired whenever an active document stylesheet is added."},{name:"styleSheetRemoved",parameters:[{name:"styleSheetId",$ref:"StyleSheetId",description:"Identifier of the removed stylesheet."}],description:"Fired whenever an active document stylesheet is removed."}]},{domain:"IO",description:"Input/Output operations for streams produced by DevTools.",experimental:!0,types:[{id:"StreamHandle",type:"string"}],commands:[{name:"read",description:"Read a chunk of the stream",parameters:[{name:"handle",$ref:"StreamHandle",description:"Handle of the stream to read."},{name:"offset",type:"integer",optional:!0,description:"Seek to the specified offset before reading (if not specificed, proceed with offset following the last read)."},{name:"size",type:"integer",optional:!0,description:"Maximum number of bytes to read (left upon the agent discretion if not specified)."}],returns:[{name:"data",type:"string",description:"Data that were read."},{name:"eof",type:"boolean",description:"Set if the end-of-file condition occured while reading."}]},{name:"close",description:"Close the stream, discard any temporary backing storage.",parameters:[{name:"handle",$ref:"StreamHandle",description:"Handle of the stream to close."}]}]},{domain:"DOMDebugger",description:"DOM debugging allows setting breakpoints on particular DOM operations and events. JavaScript execution will stop on these operations as if there was a regular breakpoint set.",dependencies:["DOM","Debugger"],types:[{id:"DOMBreakpointType",type:"string",enum:["subtree-modified","attribute-modified","node-removed"],description:"DOM breakpoint type."},{id:"EventListener",type:"object",description:"Object event listener.",properties:[{name:"type",type:"string",description:"EventListener's type."},{name:"useCapture",type:"boolean",description:"EventListener's useCapture."},{name:"passive",type:"boolean",description:"EventListener's passive flag."},{name:"once",type:"boolean",description:"EventListener's once flag."},{name:"scriptId",$ref:"Runtime.ScriptId",description:"Script id of the handler code."},{name:"lineNumber",type:"integer",description:"Line number in the script (0-based)."},{name:"columnNumber",type:"integer",description:"Column number in the script (0-based)."},{name:"handler",$ref:"Runtime.RemoteObject",optional:!0,description:"Event handler function value."},{name:"originalHandler",$ref:"Runtime.RemoteObject",optional:!0,description:"Event original handler function value."},{name:"removeFunction",$ref:"Runtime.RemoteObject",optional:!0,description:"Event listener remove function."}],experimental:!0}],commands:[{name:"setDOMBreakpoint",parameters:[{name:"nodeId",$ref:"DOM.NodeId",description:"Identifier of the node to set breakpoint on."},{name:"type",$ref:"DOMBreakpointType",description:"Type of the operation to stop upon."}],description:"Sets breakpoint on particular operation with DOM."},{name:"removeDOMBreakpoint",parameters:[{name:"nodeId",$ref:"DOM.NodeId",description:"Identifier of the node to remove breakpoint from."},{name:"type",$ref:"DOMBreakpointType",description:"Type of the breakpoint to remove."}],description:"Removes DOM breakpoint that was set using setDOMBreakpoint."},{name:"setEventListenerBreakpoint",parameters:[{name:"eventName",type:"string",description:"DOM Event name to stop on (any DOM event will do)."},{name:"targetName",type:"string",optional:!0,description:'EventTarget interface name to stop on. If equal to "*" or not provided, will stop on any EventTarget.',experimental:!0}],description:"Sets breakpoint on particular DOM event."},{name:"removeEventListenerBreakpoint",parameters:[{name:"eventName",type:"string",description:"Event name."},{name:"targetName",type:"string",optional:!0,description:"EventTarget interface name.",experimental:!0}],description:"Removes breakpoint on particular DOM event."},{name:"setInstrumentationBreakpoint",parameters:[{name:"eventName",type:"string",description:"Instrumentation name to stop on."}],description:"Sets breakpoint on particular native event.",experimental:!0},{name:"removeInstrumentationBreakpoint",parameters:[{name:"eventName",type:"string",description:"Instrumentation name to stop on."}],description:"Removes breakpoint on particular native event.",experimental:!0},{name:"setXHRBreakpoint",parameters:[{name:"url",type:"string",description:"Resource URL substring. All XHRs having this substring in the URL will get stopped upon."}],description:"Sets breakpoint on XMLHttpRequest."},{name:"removeXHRBreakpoint",parameters:[{name:"url",type:"string",description:"Resource URL substring."}],description:"Removes breakpoint from XMLHttpRequest."},{name:"getEventListeners",experimental:!0,parameters:[{name:"objectId",$ref:"Runtime.RemoteObjectId",description:"Identifier of the object to return listeners for."}],returns:[{name:"listeners",type:"array",items:{$ref:"EventListener"},description:"Array of relevant listeners."}],description:"Returns event listeners of the given object."}]},{domain:"Target",description:"Supports additional targets discovery and allows to attach to them.",experimental:!0,types:[{id:"TargetID",type:"string"},{id:"BrowserContextID",type:"string"},{id:"TargetInfo",type:"object",properties:[{name:"targetId",$ref:"TargetID"},{name:"type",type:"string"},{name:"title",type:"string"},{name:"url",type:"string"}]},{id:"RemoteLocation",type:"object",properties:[{name:"host",type:"string"},{name:"port",type:"integer"}]}],commands:[{name:"setDiscoverTargets",description:"Controls whether to discover available targets and notify via targetCreated/targetDestroyed events.",parameters:[{name:"discover",type:"boolean",description:"Whether to discover available targets."}]},{name:"setAutoAttach",description:"Controls whether to automatically attach to new targets which are considered to be related to this one. When turned on, attaches to all existing related targets as well. When turned off, automatically detaches from all currently attached targets.",parameters:[{name:"autoAttach",type:"boolean",description:"Whether to auto-attach to related targets."},{name:"waitForDebuggerOnStart",type:"boolean",description:"Whether to pause new targets when attaching to them. Use Runtime.runIfWaitingForDebugger to run paused targets."}]},{name:"setAttachToFrames",parameters:[{name:"value",type:"boolean",description:"Whether to attach to frames."}]},{name:"setRemoteLocations",description:"Enables target discovery for the specified locations, when setDiscoverTargets was set to true.",parameters:[{name:"locations",type:"array",items:{$ref:"RemoteLocation"},description:"List of remote locations."}]},{name:"sendMessageToTarget",description:"Sends protocol message to the target with given id.",parameters:[{name:"targetId",type:"string"},{name:"message",type:"string"}]},{name:"getTargetInfo",description:"Returns information about a target.",parameters:[{name:"targetId",$ref:"TargetID"}],returns:[{name:"targetInfo",$ref:"TargetInfo"}]},{name:"activateTarget",description:"Activates (focuses) the target.",parameters:[{name:"targetId",$ref:"TargetID"}]},{name:"closeTarget",description:"Closes the target. If the target is a page that gets closed too.",parameters:[{name:"targetId",$ref:"TargetID"}],returns:[{name:"success",type:"boolean"}]},{name:"attachToTarget",description:"Attaches to the target with given id.",parameters:[{name:"targetId",$ref:"TargetID"}],returns:[{name:"success",type:"boolean",description:"Whether attach succeeded."}]},{name:"detachFromTarget",description:"Detaches from the target with given id.",parameters:[{name:"targetId",$ref:"TargetID"}]},{name:"createBrowserContext",description:"Creates a new empty BrowserContext. Similar to an incognito profile but you can have more than one.",returns:[{name:"browserContextId",$ref:"BrowserContextID",description:"The id of the context created."}]},{name:"disposeBrowserContext",description:"Deletes a BrowserContext, will fail of any open page uses it.",parameters:[{name:"browserContextId",$ref:"BrowserContextID"}],returns:[{name:"success",type:"boolean"}]},{name:"createTarget",description:"Creates a new page.",parameters:[{name:"url",type:"string",description:"The initial URL the page will be navigated to."},{name:"width",type:"integer",description:"Frame width in DIP (headless chrome only).",optional:!0},{name:"height",type:"integer",description:"Frame height in DIP (headless chrome only).",optional:!0},{name:"browserContextId",$ref:"BrowserContextID",description:"The browser context to create the page in (headless chrome only).",optional:!0}],returns:[{name:"targetId",$ref:"TargetID",description:"The id of the page opened."}]},{name:"getTargets",description:"Retrieves a list of available targets.",returns:[{name:"targetInfos",type:"array",items:{$ref:"TargetInfo"},description:"The list of targets."}]}],events:[{name:"targetCreated",description:"Issued when a possible inspection target is created.",parameters:[{name:"targetInfo",$ref:"TargetInfo"}]},{name:"targetDestroyed",description:"Issued when a target is destroyed.",parameters:[{name:"targetId",$ref:"TargetID"}]},{name:"attachedToTarget",description:"Issued when attached to target because of auto-attach or attachToTarget command.",parameters:[{name:"targetInfo",$ref:"TargetInfo"},{name:"waitingForDebugger",type:"boolean"}]},{name:"detachedFromTarget",description:"Issued when detached from target for any reason (including detachFromTarget command).",parameters:[{name:"targetId",$ref:"TargetID"}]},{name:"receivedMessageFromTarget",description:"Notifies about new protocol message from attached target.",parameters:[{name:"targetId",$ref:"TargetID"},{name:"message",type:"string"}]}]},{domain:"ServiceWorker",experimental:!0,types:[{id:"ServiceWorkerRegistration",type:"object",description:"ServiceWorker registration.",properties:[{name:"registrationId",type:"string"},{name:"scopeURL",type:"string"},{name:"isDeleted",type:"boolean"}]},{id:"ServiceWorkerVersionRunningStatus",type:"string",enum:["stopped","starting","running","stopping"]},{id:"ServiceWorkerVersionStatus",type:"string",enum:["new","installing","installed","activating","activated","redundant"]},{id:"ServiceWorkerVersion",type:"object",description:"ServiceWorker version.",properties:[{name:"versionId",type:"string"},{name:"registrationId",type:"string"},{name:"scriptURL",type:"string"},{name:"runningStatus",$ref:"ServiceWorkerVersionRunningStatus"},{name:"status",$ref:"ServiceWorkerVersionStatus"},{name:"scriptLastModified",type:"number",optional:!0,description:"The Last-Modified header value of the main script."},{name:"scriptResponseTime",type:"number",optional:!0,description:"The time at which the response headers of the main script were received from the server. For cached script it is the last time the cache entry was validated."},{name:"controlledClients",type:"array",optional:!0,items:{$ref:"Target.TargetID"}},{name:"targetId",$ref:"Target.TargetID",optional:!0}]},{id:"ServiceWorkerErrorMessage",type:"object",description:"ServiceWorker error message.",properties:[{name:"errorMessage",type:"string"},{name:"registrationId",type:"string"},{name:"versionId",type:"string"},{name:"sourceURL",type:"string"},{name:"lineNumber",type:"integer"},{name:"columnNumber",type:"integer"}]}],commands:[{name:"enable"},{name:"disable"},{name:"unregister",parameters:[{name:"scopeURL",type:"string"}]},{name:"updateRegistration",parameters:[{name:"scopeURL",type:"string"}]},{name:"startWorker",parameters:[{name:"scopeURL",type:"string"}]},{name:"skipWaiting",parameters:[{name:"scopeURL",type:"string"}]},{name:"stopWorker",parameters:[{name:"versionId",type:"string"}]},{name:"inspectWorker",parameters:[{name:"versionId",type:"string"}]},{name:"setForceUpdateOnPageLoad",parameters:[{name:"forceUpdateOnPageLoad",type:"boolean"}]},{name:"deliverPushMessage",parameters:[{name:"origin",type:"string"},{name:"registrationId",type:"string"},{name:"data",type:"string"}]},{name:"dispatchSyncEvent",parameters:[{name:"origin",type:"string"},{name:"registrationId",type:"string"},{name:"tag",type:"string"},{name:"lastChance",type:"boolean"}]}],events:[{name:"workerRegistrationUpdated",parameters:[{name:"registrations",type:"array",items:{$ref:"ServiceWorkerRegistration"}}]},{name:"workerVersionUpdated",parameters:[{name:"versions",type:"array",items:{$ref:"ServiceWorkerVersion"}}]},{name:"workerErrorReported",parameters:[{name:"errorMessage",$ref:"ServiceWorkerErrorMessage"}]}]},{domain:"Input",types:[{id:"TouchPoint",type:"object",experimental:!0,properties:[{name:"state",type:"string",enum:["touchPressed","touchReleased","touchMoved","touchStationary","touchCancelled"],description:"State of the touch point."},{name:"x",type:"integer",description:"X coordinate of the event relative to the main frame's viewport."},{name:"y",type:"integer",description:"Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},{name:"radiusX",type:"integer",optional:!0,description:"X radius of the touch area (default: 1)."},{name:"radiusY",type:"integer",optional:!0,description:"Y radius of the touch area (default: 1)."},{name:"rotationAngle",type:"number",optional:!0,description:"Rotation angle (default: 0.0)."},{name:"force",type:"number",optional:!0,description:"Force (default: 1.0)."},{name:"id",type:"number",optional:!0,description:"Identifier used to track touch sources between events, must be unique within an event."}]},{id:"GestureSourceType",type:"string",experimental:!0,enum:["default","touch","mouse"]}],commands:[{name:"dispatchKeyEvent",parameters:[{name:"type",type:"string",enum:["keyDown","keyUp","rawKeyDown","char"],description:"Type of the key event."},{name:"modifiers",type:"integer",optional:!0,description:"Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)."},{name:"timestamp",type:"number",optional:!0,description:"Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)."},{name:"text",type:"string",optional:!0,description:'Text as generated by processing a virtual key code with a keyboard layout. Not needed for for keyUp and rawKeyDown events (default: "")'},{name:"unmodifiedText",type:"string",optional:!0,description:'Text that would have been generated by the keyboard if no modifiers were pressed (except for shift). Useful for shortcut (accelerator) key handling (default: "").'},{name:"keyIdentifier",type:"string",optional:!0,description:"Unique key identifier (e.g., 'U+0041') (default: \"\")."},{name:"code",type:"string",optional:!0,description:"Unique DOM defined string value for each physical key (e.g., 'KeyA') (default: \"\")."},{name:"key",type:"string",optional:!0,description:"Unique DOM defined string value describing the meaning of the key in the context of active modifiers, keyboard layout, etc (e.g., 'AltGr') (default: \"\")."},{name:"windowsVirtualKeyCode",type:"integer",optional:!0,description:"Windows virtual key code (default: 0)."},{name:"nativeVirtualKeyCode",type:"integer",optional:!0,description:"Native virtual key code (default: 0)."},{name:"autoRepeat",type:"boolean",optional:!0,description:"Whether the event was generated from auto repeat (default: false)."},{name:"isKeypad",type:"boolean",optional:!0,description:"Whether the event was generated from the keypad (default: false)."},{name:"isSystemKey",type:"boolean",optional:!0,description:"Whether the event was a system key event (default: false)."}],description:"Dispatches a key event to the page."},{name:"dispatchMouseEvent",parameters:[{name:"type",type:"string",enum:["mousePressed","mouseReleased","mouseMoved"],description:"Type of the mouse event."},{name:"x",type:"integer",description:"X coordinate of the event relative to the main frame's viewport."},{name:"y",type:"integer",description:"Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},{name:"modifiers",type:"integer",optional:!0,description:"Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)."},{name:"timestamp",type:"number",optional:!0,description:"Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)."},{name:"button",type:"string",enum:["none","left","middle","right"],optional:!0,description:'Mouse button (default: "none").'},{name:"clickCount",type:"integer",optional:!0,description:"Number of times the mouse button was clicked (default: 0)."}],description:"Dispatches a mouse event to the page."},{name:"dispatchTouchEvent",experimental:!0,parameters:[{name:"type",type:"string",enum:["touchStart","touchEnd","touchMove"],description:"Type of the touch event."},{name:"touchPoints",type:"array",items:{$ref:"TouchPoint"},description:"Touch points."},{name:"modifiers",type:"integer",optional:!0,description:"Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)."},{name:"timestamp",type:"number",optional:!0,description:"Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)."}],description:"Dispatches a touch event to the page."},{name:"emulateTouchFromMouseEvent",experimental:!0,parameters:[{name:"type",type:"string",enum:["mousePressed","mouseReleased","mouseMoved","mouseWheel"],description:"Type of the mouse event."},{name:"x",type:"integer",description:"X coordinate of the mouse pointer in DIP."},{name:"y",type:"integer",description:"Y coordinate of the mouse pointer in DIP."},{name:"timestamp",type:"number",description:"Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970."},{name:"button",type:"string",enum:["none","left","middle","right"],description:"Mouse button."},{name:"deltaX",type:"number",optional:!0,description:"X delta in DIP for mouse wheel event (default: 0)."},{name:"deltaY",type:"number",optional:!0,description:"Y delta in DIP for mouse wheel event (default: 0)."},{name:"modifiers",type:"integer",optional:!0,description:"Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)."},{name:"clickCount",type:"integer",optional:!0,description:"Number of times the mouse button was clicked (default: 0)."}],description:"Emulates touch event from the mouse event parameters."},{name:"synthesizePinchGesture",parameters:[{name:"x",type:"integer",description:"X coordinate of the start of the gesture in CSS pixels."},{name:"y",type:"integer",description:"Y coordinate of the start of the gesture in CSS pixels."},{name:"scaleFactor",type:"number",description:"Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out)."},{name:"relativeSpeed",type:"integer",optional:!0,description:"Relative pointer speed in pixels per second (default: 800)."},{name:"gestureSourceType",$ref:"GestureSourceType",optional:!0,description:"Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)."}],description:"Synthesizes a pinch gesture over a time period by issuing appropriate touch events.",experimental:!0},{name:"synthesizeScrollGesture",parameters:[{name:"x",type:"integer",description:"X coordinate of the start of the gesture in CSS pixels."},{name:"y",type:"integer",description:"Y coordinate of the start of the gesture in CSS pixels."},{name:"xDistance",type:"integer",optional:!0,description:"The distance to scroll along the X axis (positive to scroll left)."},{name:"yDistance",type:"integer",optional:!0,description:"The distance to scroll along the Y axis (positive to scroll up)."},{name:"xOverscroll",type:"integer",optional:!0,description:"The number of additional pixels to scroll back along the X axis, in addition to the given distance."},{name:"yOverscroll",type:"integer",optional:!0,description:"The number of additional pixels to scroll back along the Y axis, in addition to the given distance."},{name:"preventFling",type:"boolean",optional:!0,description:"Prevent fling (default: true)."},{name:"speed",type:"integer",optional:!0,description:"Swipe speed in pixels per second (default: 800)."},{name:"gestureSourceType",$ref:"GestureSourceType",optional:!0,description:"Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)."},{name:"repeatCount",type:"integer",optional:!0,description:"The number of times to repeat the gesture (default: 0)."},{name:"repeatDelayMs",type:"integer",optional:!0,description:"The number of milliseconds delay between each repeat. (default: 250)."},{name:"interactionMarkerName",type:"string",optional:!0,description:'The name of the interaction markers to generate, if not empty (default: "").'}],description:"Synthesizes a scroll gesture over a time period by issuing appropriate touch events.",experimental:!0},{name:"synthesizeTapGesture",parameters:[{name:"x",type:"integer",description:"X coordinate of the start of the gesture in CSS pixels."},{name:"y",type:"integer",description:"Y coordinate of the start of the gesture in CSS pixels."},{name:"duration",type:"integer",optional:!0,description:"Duration between touchdown and touchup events in ms (default: 50)."},{name:"tapCount",type:"integer",optional:!0,description:"Number of times to perform the tap (e.g. 2 for double tap, default: 1)."},{name:"gestureSourceType",$ref:"GestureSourceType",optional:!0,description:"Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)."}],description:"Synthesizes a tap gesture over a time period by issuing appropriate touch events.",experimental:!0}],events:[]},{domain:"LayerTree",experimental:!0,dependencies:["DOM"],types:[{id:"LayerId",type:"string",description:"Unique Layer identifier."},{id:"SnapshotId",type:"string",description:"Unique snapshot identifier."},{id:"ScrollRect",type:"object",description:"Rectangle where scrolling happens on the main thread.",properties:[{name:"rect",$ref:"DOM.Rect",description:"Rectangle itself."},{name:"type",type:"string",enum:["RepaintsOnScroll","TouchEventHandler","WheelEventHandler"],description:"Reason for rectangle to force scrolling on the main thread"}]},{id:"PictureTile",type:"object",description:"Serialized fragment of layer picture along with its offset within the layer.",properties:[{name:"x",type:"number",description:"Offset from owning layer left boundary"},{name:"y",type:"number",description:"Offset from owning layer top boundary"},{name:"picture",type:"string",description:"Base64-encoded snapshot data."}]},{id:"Layer",type:"object",description:"Information about a compositing layer.",properties:[{name:"layerId",$ref:"LayerId",description:"The unique id for this layer."},{name:"parentLayerId",$ref:"LayerId",optional:!0,description:"The id of parent (not present for root)."},{name:"backendNodeId",$ref:"DOM.BackendNodeId",optional:!0,description:"The backend id for the node associated with this layer."},{name:"offsetX",type:"number",description:"Offset from parent layer, X coordinate."},{name:"offsetY",type:"number",description:"Offset from parent layer, Y coordinate."},{name:"width",type:"number",description:"Layer width."},{name:"height",type:"number",description:"Layer height."},{name:"transform",type:"array",items:{type:"number"},minItems:16,maxItems:16,optional:!0,description:"Transformation matrix for layer, default is identity matrix"},{name:"anchorX",type:"number",optional:!0,description:"Transform anchor point X, absent if no transform specified"},{name:"anchorY",type:"number",optional:!0,description:"Transform anchor point Y, absent if no transform specified"},{name:"anchorZ",type:"number",optional:!0,description:"Transform anchor point Z, absent if no transform specified"},{name:"paintCount",type:"integer",description:"Indicates how many time this layer has painted."},{name:"drawsContent",type:"boolean",description:"Indicates whether this layer hosts any content, rather than being used for transform/scrolling purposes only."},{name:"invisible",type:"boolean",optional:!0,description:"Set if layer is not visible."},{name:"scrollRects",type:"array",items:{$ref:"ScrollRect"},optional:!0,description:"Rectangles scrolling on main thread only."}]},{id:"PaintProfile",type:"array",description:"Array of timings, one per paint step.",items:{type:"number",description:"A time in seconds since the end of previous step (for the first step, time since painting started)"}}],commands:[{name:"enable",description:"Enables compositing tree inspection."},{name:"disable",description:"Disables compositing tree inspection."},{name:"compositingReasons",parameters:[{name:"layerId",$ref:"LayerId",description:"The id of the layer for which we want to get the reasons it was composited."}],description:"Provides the reasons why the given layer was composited.",returns:[{name:"compositingReasons",type:"array",items:{type:"string"},description:"A list of strings specifying reasons for the given layer to become composited."}]},{name:"makeSnapshot",parameters:[{name:"layerId",$ref:"LayerId",description:"The id of the layer."}],description:"Returns the layer snapshot identifier.",returns:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the layer snapshot."}]},{name:"loadSnapshot",parameters:[{name:"tiles",type:"array",items:{$ref:"PictureTile"},minItems:1,description:"An array of tiles composing the snapshot."}],description:"Returns the snapshot identifier.",returns:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the snapshot."}]},{name:"releaseSnapshot",parameters:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the layer snapshot."}],description:"Releases layer snapshot captured by the back-end."},{name:"profileSnapshot",parameters:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the layer snapshot."},{name:"minRepeatCount",type:"integer",optional:!0,description:"The maximum number of times to replay the snapshot (1, if not specified)."},{name:"minDuration",type:"number",optional:!0,description:"The minimum duration (in seconds) to replay the snapshot."},{name:"clipRect",$ref:"DOM.Rect",optional:!0,description:"The clip rectangle to apply when replaying the snapshot."}],returns:[{name:"timings",type:"array",items:{$ref:"PaintProfile"},description:"The array of paint profiles, one per run."}]},{name:"replaySnapshot",parameters:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the layer snapshot."},{name:"fromStep",type:"integer",optional:!0,description:"The first step to replay from (replay from the very start if not specified)."},{name:"toStep",type:"integer",optional:!0,description:"The last step to replay to (replay till the end if not specified)."},{name:"scale",type:"number",optional:!0,description:"The scale to apply while replaying (defaults to 1)."}],description:"Replays the layer snapshot and returns the resulting bitmap.",returns:[{name:"dataURL",type:"string",description:"A data: URL for resulting image."}]},{name:"snapshotCommandLog",parameters:[{name:"snapshotId",$ref:"SnapshotId",description:"The id of the layer snapshot."}],description:"Replays the layer snapshot and returns canvas log.",returns:[{name:"commandLog",type:"array",items:{type:"object"},description:"The array of canvas function calls."}]}],events:[{name:"layerTreeDidChange",parameters:[{name:"layers",type:"array",items:{$ref:"Layer"},optional:!0,description:"Layer tree, absent if not in the comspositing mode."}]},{name:"layerPainted",parameters:[{name:"layerId",$ref:"LayerId",description:"The id of the painted layer."},{name:"clip",$ref:"DOM.Rect",description:"Clip rectangle."}]}]},{domain:"DeviceOrientation",experimental:!0,commands:[{name:"setDeviceOrientationOverride",description:"Overrides the Device Orientation.",parameters:[{name:"alpha",type:"number",description:"Mock alpha"},{name:"beta",type:"number",description:"Mock beta"},{name:"gamma",type:"number",description:"Mock gamma"}]},{name:"clearDeviceOrientationOverride",description:"Clears the overridden Device Orientation."}]},{domain:"Tracing",dependencies:["IO"],experimental:!0,types:[{id:"MemoryDumpConfig",type:"object",description:'Configuration for memory dump. Used only when "memory-infra" category is enabled.'},{id:"TraceConfig",type:"object",properties:[{name:"recordMode",type:"string",optional:!0,enum:["recordUntilFull","recordContinuously","recordAsMuchAsPossible","echoToConsole"],description:"Controls how the trace buffer stores data."},{name:"enableSampling",type:"boolean",optional:!0,description:"Turns on JavaScript stack sampling."},{name:"enableSystrace",type:"boolean",optional:!0,description:"Turns on system tracing."},{name:"enableArgumentFilter",type:"boolean",optional:!0,description:"Turns on argument filter."},{name:"includedCategories",type:"array",items:{type:"string"},optional:!0,description:"Included category filters."},{name:"excludedCategories",type:"array",items:{type:"string"},optional:!0,description:"Excluded category filters."},{name:"syntheticDelays",type:"array",items:{type:"string"},optional:!0,description:"Configuration to synthesize the delays in tracing."},{name:"memoryDumpConfig",$ref:"MemoryDumpConfig",optional:!0,description:'Configuration for memory dump triggers. Used only when "memory-infra" category is enabled.'}]}],commands:[{name:"start",description:"Start trace events collection.",parameters:[{name:"categories",type:"string",optional:!0,deprecated:!0,description:"Category/tag filter"},{name:"options",type:"string",optional:!0,deprecated:!0,description:"Tracing options"},{name:"bufferUsageReportingInterval",type:"number",optional:!0,description:"If set, the agent will issue bufferUsage events at this interval, specified in milliseconds"},{name:"transferMode",type:"string",enum:["ReportEvents","ReturnAsStream"],optional:!0,description:"Whether to report trace events as series of dataCollected events or to save trace to a stream (defaults to ReportEvents)."},{name:"traceConfig",$ref:"TraceConfig",optional:!0,description:""}]},{name:"end",description:"Stop trace events collection."},{name:"getCategories",description:"Gets supported tracing categories.", + returns:[{name:"categories",type:"array",items:{type:"string"},description:"A list of supported tracing categories."}]},{name:"requestMemoryDump",description:"Request a global memory dump.",returns:[{name:"dumpGuid",type:"string",description:"GUID of the resulting global memory dump."},{name:"success",type:"boolean",description:"True iff the global memory dump succeeded."}]},{name:"recordClockSyncMarker",description:"Record a clock sync marker in the trace.",parameters:[{name:"syncId",type:"string",description:"The ID of this clock sync marker"}]}],events:[{name:"dataCollected",parameters:[{name:"value",type:"array",items:{type:"object"}}],description:"Contains an bucket of collected trace events. When tracing is stopped collected events will be send as a sequence of dataCollected events followed by tracingComplete event."},{name:"tracingComplete",description:"Signals that tracing is stopped and there is no trace buffers pending flush, all data were delivered via dataCollected events.",parameters:[{name:"stream",$ref:"IO.StreamHandle",optional:!0,description:"A handle of the stream that holds resulting trace data."}]},{name:"bufferUsage",parameters:[{name:"percentFull",type:"number",optional:!0,description:"A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size."},{name:"eventCount",type:"number",optional:!0,description:"An approximate number of events in the trace log."},{name:"value",type:"number",optional:!0,description:"A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size."}]}]},{domain:"Animation",experimental:!0,dependencies:["Runtime","DOM"],types:[{id:"Animation",type:"object",experimental:!0,properties:[{name:"id",type:"string",description:"Animation's id."},{name:"name",type:"string",description:"Animation's name."},{name:"pausedState",type:"boolean",experimental:!0,description:"Animation's internal paused state."},{name:"playState",type:"string",description:"Animation's play state."},{name:"playbackRate",type:"number",description:"Animation's playback rate."},{name:"startTime",type:"number",description:"Animation's start time."},{name:"currentTime",type:"number",description:"Animation's current time."},{name:"source",$ref:"AnimationEffect",description:"Animation's source animation node."},{name:"type",type:"string",enum:["CSSTransition","CSSAnimation","WebAnimation"],description:"Animation type of Animation."},{name:"cssId",type:"string",optional:!0,description:"A unique ID for Animation representing the sources that triggered this CSS animation/transition."}],description:"Animation instance."},{id:"AnimationEffect",type:"object",experimental:!0,properties:[{name:"delay",type:"number",description:"AnimationEffect's delay."},{name:"endDelay",type:"number",description:"AnimationEffect's end delay."},{name:"iterationStart",type:"number",description:"AnimationEffect's iteration start."},{name:"iterations",type:"number",description:"AnimationEffect's iterations."},{name:"duration",type:"number",description:"AnimationEffect's iteration duration."},{name:"direction",type:"string",description:"AnimationEffect's playback direction."},{name:"fill",type:"string",description:"AnimationEffect's fill mode."},{name:"backendNodeId",$ref:"DOM.BackendNodeId",description:"AnimationEffect's target node."},{name:"keyframesRule",$ref:"KeyframesRule",optional:!0,description:"AnimationEffect's keyframes."},{name:"easing",type:"string",description:"AnimationEffect's timing function."}],description:"AnimationEffect instance"},{id:"KeyframesRule",type:"object",properties:[{name:"name",type:"string",optional:!0,description:"CSS keyframed animation's name."},{name:"keyframes",type:"array",items:{$ref:"KeyframeStyle"},description:"List of animation keyframes."}],description:"Keyframes Rule"},{id:"KeyframeStyle",type:"object",properties:[{name:"offset",type:"string",description:"Keyframe's time offset."},{name:"easing",type:"string",description:"AnimationEffect's timing function."}],description:"Keyframe Style"}],commands:[{name:"enable",description:"Enables animation domain notifications."},{name:"disable",description:"Disables animation domain notifications."},{name:"getPlaybackRate",returns:[{name:"playbackRate",type:"number",description:"Playback rate for animations on page."}],description:"Gets the playback rate of the document timeline."},{name:"setPlaybackRate",parameters:[{name:"playbackRate",type:"number",description:"Playback rate for animations on page"}],description:"Sets the playback rate of the document timeline."},{name:"getCurrentTime",parameters:[{name:"id",type:"string",description:"Id of animation."}],returns:[{name:"currentTime",type:"number",description:"Current time of the page."}],description:"Returns the current time of the an animation."},{name:"setPaused",parameters:[{name:"animations",type:"array",items:{type:"string"},description:"Animations to set the pause state of."},{name:"paused",type:"boolean",description:"Paused state to set to."}],description:"Sets the paused state of a set of animations."},{name:"setTiming",parameters:[{name:"animationId",type:"string",description:"Animation id."},{name:"duration",type:"number",description:"Duration of the animation."},{name:"delay",type:"number",description:"Delay of the animation."}],description:"Sets the timing of an animation node."},{name:"seekAnimations",parameters:[{name:"animations",type:"array",items:{type:"string"},description:"List of animation ids to seek."},{name:"currentTime",type:"number",description:"Set the current time of each animation."}],description:"Seek a set of animations to a particular time within each animation."},{name:"releaseAnimations",parameters:[{name:"animations",type:"array",items:{type:"string"},description:"List of animation ids to seek."}],description:"Releases a set of animations to no longer be manipulated."},{name:"resolveAnimation",parameters:[{name:"animationId",type:"string",description:"Animation id."}],returns:[{name:"remoteObject",$ref:"Runtime.RemoteObject",description:"Corresponding remote object."}],description:"Gets the remote object of the Animation."}],events:[{name:"animationCreated",parameters:[{name:"id",type:"string",description:"Id of the animation that was created."}],description:"Event for each animation that has been created."},{name:"animationStarted",parameters:[{name:"animation",$ref:"Animation",description:"Animation that was started."}],description:"Event for animation that has been started."},{name:"animationCanceled",parameters:[{name:"id",type:"string",description:"Id of the animation that was cancelled."}],description:"Event for when an animation has been cancelled."}]},{domain:"Accessibility",experimental:!0,dependencies:["DOM"],types:[{id:"AXNodeId",type:"string",description:"Unique accessibility node identifier."},{id:"AXValueType",type:"string",enum:["boolean","tristate","booleanOrUndefined","idref","idrefList","integer","node","nodeList","number","string","computedString","token","tokenList","domRelation","role","internalRole","valueUndefined"],description:"Enum of possible property types."},{id:"AXValueSourceType",type:"string",enum:["attribute","implicit","style","contents","placeholder","relatedElement"],description:"Enum of possible property sources."},{id:"AXValueNativeSourceType",type:"string",enum:["figcaption","label","labelfor","labelwrapped","legend","tablecaption","title","other"],description:"Enum of possible native property sources (as a subtype of a particular AXValueSourceType)."},{id:"AXValueSource",type:"object",properties:[{name:"type",$ref:"AXValueSourceType",description:"What type of source this is."},{name:"value",$ref:"AXValue",description:"The value of this property source.",optional:!0},{name:"attribute",type:"string",description:"The name of the relevant attribute, if any.",optional:!0},{name:"attributeValue",$ref:"AXValue",description:"The value of the relevant attribute, if any.",optional:!0},{name:"superseded",type:"boolean",description:"Whether this source is superseded by a higher priority source.",optional:!0},{name:"nativeSource",$ref:"AXValueNativeSourceType",description:"The native markup source for this value, e.g. a