// Generated from: 8175aacaec380ecf859183ad62bee2a9aef180d2 Disable searching test because it's timing out on try on certain platforms for some reason

var Debugger =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(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 = "/public/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__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	var combineReducers = _require.combineReducers;
	
	var ReactDOM = __webpack_require__(16);
	
	var _require2 = __webpack_require__(18);
	
	var _require2$client = _require2.client;
	var getClient = _require2$client.getClient;
	var firefox = _require2$client.firefox;
	var renderRoot = _require2.renderRoot;
	var bootstrap = _require2.bootstrap;
	
	var _require3 = __webpack_require__(89);
	
	var getValue = _require3.getValue;
	var isFirefoxPanel = _require3.isFirefoxPanel;
	
	
	var configureStore = __webpack_require__(238);
	
	var reducers = __webpack_require__(249);
	var selectors = __webpack_require__(259);
	
	var App = __webpack_require__(260);
	
	var createStore = configureStore({
	  log: getValue("logging.actions"),
	  makeThunkArgs: (args, state) => {
	    return Object.assign({}, args, { client: getClient(state) });
	  }
	});
	
	var store = createStore(combineReducers(reducers));
	var actions = bindActionCreators(__webpack_require__(262), store.dispatch);
	
	if (!isFirefoxPanel()) {
	  L10N.setBundle(__webpack_require__(458));
	}
	
	window.appStore = store;
	
	// Expose the bound actions so external things can do things like
	// selecting a source.
	window.actions = {
	  selectSource: actions.selectSource,
	  selectSourceURL: actions.selectSourceURL
	};
	
	function unmountRoot() {
	  var mount = document.querySelector("#mount");
	  ReactDOM.unmountComponentAtNode(mount);
	}
	
	if (isFirefoxPanel()) {
	  (function () {
	    var sourceMap = __webpack_require__(264);
	    var prettyPrint = __webpack_require__(276);
	
	    module.exports = {
	      bootstrap: (_ref) => {
	        var threadClient = _ref.threadClient;
	        var tabTarget = _ref.tabTarget;
	        var toolbox = _ref.toolbox;
	        var L10N = _ref.L10N;
	
	        // TODO (jlast) remove when the panel has L10N
	        if (L10N) {
	          window.L10N = L10N;
	        } else {
	          window.L10N = __webpack_require__(459);
	          window.L10N.setBundle(__webpack_require__(458));
	        }
	
	        firefox.setThreadClient(threadClient);
	        firefox.setTabTarget(tabTarget);
	        renderRoot(React, ReactDOM, App, store);
	        return firefox.initPage(actions);
	      },
	      destroy: () => {
	        unmountRoot();
	        sourceMap.destroyWorker();
	        prettyPrint.destroyWorker();
	      },
	      store: store,
	      actions: actions,
	      selectors: selectors,
	      client: firefox.clientCommands
	    };
	  })();
	} else {
	  bootstrap(React, ReactDOM, App, actions, store);
	}

/***/ },
/* 2 */
/***/ function(module, exports) {

	module.exports = devtoolsRequire("devtools/client/shared/vendor/react");

/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;
	
	var _createStore = __webpack_require__(4);
	
	var _createStore2 = _interopRequireDefault(_createStore);
	
	var _combineReducers = __webpack_require__(11);
	
	var _combineReducers2 = _interopRequireDefault(_combineReducers);
	
	var _bindActionCreators = __webpack_require__(13);
	
	var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);
	
	var _applyMiddleware = __webpack_require__(14);
	
	var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);
	
	var _compose = __webpack_require__(15);
	
	var _compose2 = _interopRequireDefault(_compose);
	
	var _warning = __webpack_require__(12);
	
	var _warning2 = _interopRequireDefault(_warning);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
	
	/*
	* This is a dummy function to check if the function name has been altered by minification.
	* If the function has been minified and NODE_ENV !== 'production', warn the user.
	*/
	function isCrushed() {}
	
	if (false) {
	  (0, _warning2["default"])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
	}
	
	exports.createStore = _createStore2["default"];
	exports.combineReducers = _combineReducers2["default"];
	exports.bindActionCreators = _bindActionCreators2["default"];
	exports.applyMiddleware = _applyMiddleware2["default"];
	exports.compose = _compose2["default"];

/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports.ActionTypes = undefined;
	exports["default"] = createStore;
	
	var _isPlainObject = __webpack_require__(5);
	
	var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
	
	var _symbolObservable = __webpack_require__(9);
	
	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;
	}

/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	var getPrototype = __webpack_require__(6),
	    isObjectLike = __webpack_require__(8);
	
	/** `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);
	
	/**
	 * Used to resolve the
	 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	 * of values.
	 */
	var objectToString = objectProto.toString;
	
	/**
	 * 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) || objectToString.call(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;


/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {

	var overArg = __webpack_require__(7);
	
	/** Built-in value references. */
	var getPrototype = overArg(Object.getPrototypeOf, Object);
	
	module.exports = getPrototype;


/***/ },
/* 7 */
/***/ 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;


/***/ },
/* 8 */
/***/ 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;


/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(global) {/* global window */
	'use strict';
	
	module.exports = __webpack_require__(10)(global || window || this);
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))

/***/ },
/* 10 */
/***/ 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;
	};


/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports["default"] = combineReducers;
	
	var _createStore = __webpack_require__(4);
	
	var _isPlainObject = __webpack_require__(5);
	
	var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
	
	var _warning = __webpack_require__(12);
	
	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;
	  };
	}

/***/ },
/* 12 */
/***/ 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 */
	}

/***/ },
/* 13 */
/***/ 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;
	}

/***/ },
/* 14 */
/***/ 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__(15);
	
	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
	      });
	    };
	  };
	}

/***/ },
/* 15 */
/***/ 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;
	  }
	}

/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	module.exports = __webpack_require__(17);


/***/ },
/* 17 */
/***/ function(module, exports) {

	module.exports = devtoolsRequire("devtools/client/shared/vendor/react-dom");

/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {

	/* global window, document, DebuggerConfig */
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	var combineReducers = _require.combineReducers;
	
	var _require2 = __webpack_require__(19);
	
	var Provider = _require2.Provider;
	
	var _require3 = __webpack_require__(28);
	
	var DevToolsUtils = _require3.DevToolsUtils;
	var AppConstants = _require3.AppConstants;
	
	var _require4 = __webpack_require__(88);
	
	var injectGlobals = _require4.injectGlobals;
	var debugGlobal = _require4.debugGlobal;
	
	var _require5 = __webpack_require__(89);
	
	var setConfig = _require5.setConfig;
	var isEnabled = _require5.isEnabled;
	var getValue = _require5.getValue;
	var isDevelopment = _require5.isDevelopment;
	
	
	setConfig(({"environment":"firefox-panel","baseWorkerURL":"resource://devtools/client/debugger/new/","logging":false,"clientLogging":false,"features":{"tabs":true,"sourceMaps":true,"prettyPrint":true}}));
	
	// Set various flags before requiring app code.
	if (isEnabled("logging.client")) {
	  DevToolsUtils.dumpn.wantLogging = true;
	}
	
	var client = __webpack_require__(141);
	var getClient = client.getClient;
	var connectClients = client.connectClients;
	var startDebugging = client.startDebugging;
	
	
	var Root = __webpack_require__(210);
	
	// 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) {
	  var 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 }`);
	
	  window.L10N = require("./utils/L10N");
	}
	
	function initApp() {
	  var configureStore = __webpack_require__(216);
	  var reducers = __webpack_require__(226);
	  var LandingPage = __webpack_require__(231);
	
	  var createStore = configureStore({
	    log: getValue("logging.actions"),
	    makeThunkArgs: (args, state) => {
	      return Object.assign({}, args, { client: getClient(state) });
	    }
	  });
	
	  var store = createStore(combineReducers(reducers));
	  var actions = bindActionCreators(__webpack_require__(236), store.dispatch);
	
	  if (isDevelopment()) {
	    AppConstants.DEBUG_JS_MODULES = true;
	    injectGlobals({ store });
	  }
	
	  return { store, actions, LandingPage };
	}
	
	function renderRoot(_React, _ReactDOM, component, _store) {
	  var mount = document.querySelector("#mount");
	
	  // bail in test environments that do not have a mount
	  if (!mount) {
	    return;
	  }
	
	  _ReactDOM.render(_React.createElement(Provider, { store: _store }, Root(component)), mount);
	}
	
	function getTargetFromQuery() {
	  var href = window.location.href;
	  var nodeMatch = href.match(/ws=([^&#]*)/);
	  var firefoxMatch = href.match(/firefox-tab=([^&#]*)/);
	  var 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) {
	  var connTarget = getTargetFromQuery();
	  if (connTarget) {
	    startDebugging(connTarget, appActions).then(tabs => {
	      renderRoot(React, ReactDOM, App, appStore);
	    });
	  } else {
	    (function () {
	      var _initApp = initApp();
	
	      var store = _initApp.store;
	      var actions = _initApp.actions;
	      var LandingPage = _initApp.LandingPage;
	
	      renderRoot(React, ReactDOM, LandingPage, store);
	      connectClients(tabs => actions.newTabs(tabs));
	    })();
	  }
	}
	
	module.exports = {
	  bootstrap,
	  renderRoot,
	  debugGlobal,
	  client
	};

/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports.connect = exports.Provider = undefined;
	
	var _Provider = __webpack_require__(20);
	
	var _Provider2 = _interopRequireDefault(_Provider);
	
	var _connect = __webpack_require__(23);
	
	var _connect2 = _interopRequireDefault(_connect);
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
	
	exports.Provider = _Provider2["default"];
	exports.connect = _connect2["default"];

/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports["default"] = undefined;
	
	var _react = __webpack_require__(2);
	
	var _storeShape = __webpack_require__(21);
	
	var _storeShape2 = _interopRequireDefault(_storeShape);
	
	var _warning = __webpack_require__(22);
	
	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"])('<Provider> 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
	};

/***/ },
/* 21 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	
	var _react = __webpack_require__(2);
	
	exports["default"] = _react.PropTypes.shape({
	  subscribe: _react.PropTypes.func.isRequired,
	  dispatch: _react.PropTypes.func.isRequired,
	  getState: _react.PropTypes.func.isRequired
	});

/***/ },
/* 22 */
/***/ 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 */
	}

/***/ },
/* 23 */
/***/ 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__(2);
	
	var _storeShape = __webpack_require__(21);
	
	var _storeShape2 = _interopRequireDefault(_storeShape);
	
	var _shallowEqual = __webpack_require__(24);
	
	var _shallowEqual2 = _interopRequireDefault(_shallowEqual);
	
	var _wrapActionCreators = __webpack_require__(25);
	
	var _wrapActionCreators2 = _interopRequireDefault(_wrapActionCreators);
	
	var _warning = __webpack_require__(22);
	
	var _warning2 = _interopRequireDefault(_warning);
	
	var _isPlainObject = __webpack_require__(5);
	
	var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
	
	var _hoistNonReactStatics = __webpack_require__(26);
	
	var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics);
	
	var _invariant = __webpack_require__(27);
	
	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 <Provider>, ' + ('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);
	  };
	}

/***/ },
/* 24 */
/***/ 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;
	}

/***/ },
/* 25 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.__esModule = true;
	exports["default"] = wrapActionCreators;
	
	var _redux = __webpack_require__(3);
	
	function wrapActionCreators(actionCreators) {
	  return function (dispatch) {
	    return (0, _redux.bindActionCreators)(actionCreators, dispatch);
	  };
	}

/***/ },
/* 26 */
/***/ 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;
	};


/***/ },
/* 27 */
/***/ 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;


/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(29);
	
	var KeyShortcuts = _require.KeyShortcuts;
	
	var _require2 = __webpack_require__(67);
	
	var DebuggerTransport = _require2.DebuggerTransport;
	
	var _require3 = __webpack_require__(79);
	
	var DebuggerClient = _require3.DebuggerClient;
	
	var PrefsHelper = __webpack_require__(83).PrefsHelper;
	
	var _require4 = __webpack_require__(84);
	
	var TargetFactory = _require4.TargetFactory;
	
	var DevToolsUtils = __webpack_require__(68);
	var AppConstants = __webpack_require__(70);
	var EventEmitter = __webpack_require__(60);
	var WebsocketTransport = __webpack_require__(85);
	var Menu = __webpack_require__(86);
	var MenuItem = __webpack_require__(87);
	
	module.exports = {
	  KeyShortcuts,
	  PrefsHelper,
	  DebuggerClient,
	  DebuggerTransport,
	  TargetFactory,
	  DevToolsUtils,
	  AppConstants,
	  EventEmitter,
	  WebsocketTransport,
	  Menu,
	  MenuItem
	};

/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {

	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this
	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	var _require = __webpack_require__(30);
	
	var appinfo = _require.Services.appinfo;
	
	var EventEmitter = __webpack_require__(60);
	var isOSX = appinfo.OS === "Darwin";
	"use strict";
	
	// List of electron keys mapped to DOM API (DOM_VK_*) key code
	var 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(_ref) {
	  var window = _ref.window;
	  var target = _ref.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) {
	  var modifiers = str.split("+");
	  var key = modifiers.pop();
	
	  var shortcut = {
	    ctrl: false,
	    meta: false,
	    alt: false,
	    shift: false,
	    // Set for character keys
	    key: undefined,
	    // Set for non-character keys
	    keyCode: undefined
	  };
	  for (var 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) {
	  var 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");
	  }
	  var key = void 0;
	  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.
	    var 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 (var _ref2 of this.keys) {
	      var _ref3 = _slicedToArray(_ref2, 2);
	
	      var key = _ref3[0];
	      var shortcut = _ref3[1];
	
	      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)) {
	      var 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;

/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {

	var Services = __webpack_require__(31);
	var SplitBox = __webpack_require__(32);
	// const SplitBoxCSS = require("./client/shared/components/splitter/SplitBox.css")
	var rep = __webpack_require__(34).Rep;
	// const repCSS = require("./client/shared/components/reps/reps.css");
	var Grip = __webpack_require__(44).Grip;
	var sprintf = __webpack_require__(59).sprintf;
	
	module.exports = {
	  Services,
	  SplitBox,
	  // SplitBoxCSS,
	  rep,
	  // repCSS,
	  Grip,
	  sprintf
	};

/***/ },
/* 31 */
/***/ function(module, exports) {

	module.exports = devtoolsRequire("Services");

/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var ReactDOM = __webpack_require__(16);
	var Draggable = React.createFactory(__webpack_require__(33));
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	/**
	 * This component represents a Splitter. The splitter supports vertical
	 * as well as horizontal mode.
	 */
	
	var 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,
	    // Min panel size.
	    minSize: PropTypes.any,
	    // Max panel size.
	    maxSize: PropTypes.any,
	    // Right/bottom panel
	    endPanel: PropTypes.any,
	    // 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
	    };
	  },
	
	  /**
	   * 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
	    };
	  },
	
	  // 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() {
	    var splitBox = ReactDOM.findDOMNode(this);
	    var doc = splitBox.ownerDocument;
	    var 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() {
	    var splitBox = ReactDOM.findDOMNode(this);
	    var doc = splitBox.ownerDocument;
	    doc.documentElement.style.cursor = this.state.defaultCursor;
	
	    splitBox.classList.remove("dragging");
	  },
	
	  screenX() {
	    var borderWidth = (window.outerWidth - window.innerWidth) / 2;
	    return window.screenX + borderWidth;
	  },
	
	  screenY() {
	    var 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) {
	    var node = ReactDOM.findDOMNode(this);
	    var doc = node.ownerDocument;
	    var win = doc.defaultView;
	
	    var size = void 0;
	    var endPanelControl = this.props.endPanelControl;
	
	
	    if (this.state.vert) {
	      // Switch the control flag in case of RTL. Note that RTL
	      // has impact on vertical splitter only.
	      var dir = win.getComputedStyle(doc.documentElement).direction;
	      if (dir == "rtl") {
	        endPanelControl = !endPanelControl;
	      }
	
	      var innerOffset = x - this.screenX();
	      size = endPanelControl ? node.offsetLeft + node.offsetWidth - innerOffset : innerOffset - node.offsetLeft;
	
	      this.setState({
	        width: size
	      });
	    } else {
	      var _innerOffset = y - this.screenY();
	      size = endPanelControl ? node.offsetTop + node.offsetHeight - _innerOffset : _innerOffset - node.offsetTop;
	
	      this.setState({
	        height: size
	      });
	    }
	  },
	
	  // Rendering
	
	  render() {
	    var vert = this.state.vert;
	    var _props = this.props;
	    var startPanel = _props.startPanel;
	    var endPanel = _props.endPanel;
	    var endPanelControl = _props.endPanelControl;
	    var minSize = _props.minSize;
	    var maxSize = _props.maxSize;
	    var splitterSize = _props.splitterSize;
	
	
	    var style = Object.assign({}, this.props.style);
	
	    // Calculate class names list.
	    var classNames = ["split-box"];
	    classNames.push(vert ? "vert" : "horz");
	    if (this.props.className) {
	      classNames = classNames.concat(this.props.className.split(" "));
	    }
	
	    var leftPanelStyle = void 0;
	    var rightPanelStyle = void 0;
	
	    // Set proper size for panels depending on the current state.
	    if (vert) {
	      leftPanelStyle = {
	        maxWidth: endPanelControl ? null : maxSize,
	        minWidth: endPanelControl ? null : minSize,
	        width: endPanelControl ? null : this.state.width
	      };
	      rightPanelStyle = {
	        maxWidth: endPanelControl ? maxSize : null,
	        minWidth: endPanelControl ? minSize : null,
	        width: endPanelControl ? this.state.width : null
	      };
	    } 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
	      };
	    }
	
	    // Calculate splitter size
	    var 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;

/***/ },
/* 33 */
/***/ 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/. */
	
	var React = __webpack_require__(2);
	var ReactDOM = __webpack_require__(16);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	
	var 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();
	    var 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();
	    var 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;

/***/ },
/* 34 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	
	  // Load all existing rep templates
	
	  var _require2 = __webpack_require__(36);
	
	  var Undefined = _require2.Undefined;
	
	  var _require3 = __webpack_require__(37);
	
	  var Null = _require3.Null;
	
	  var _require4 = __webpack_require__(38);
	
	  var StringRep = _require4.StringRep;
	
	  var _require5 = __webpack_require__(39);
	
	  var Number = _require5.Number;
	
	  var _require6 = __webpack_require__(40);
	
	  var ArrayRep = _require6.ArrayRep;
	
	  var _require7 = __webpack_require__(42);
	
	  var Obj = _require7.Obj;
	
	  var _require8 = __webpack_require__(45);
	
	  var SymbolRep = _require8.SymbolRep;
	
	  // DOM types (grips)
	
	  var _require9 = __webpack_require__(46);
	
	  var Attribute = _require9.Attribute;
	
	  var _require10 = __webpack_require__(47);
	
	  var DateTime = _require10.DateTime;
	
	  var _require11 = __webpack_require__(48);
	
	  var Document = _require11.Document;
	
	  var _require12 = __webpack_require__(49);
	
	  var Event = _require12.Event;
	
	  var _require13 = __webpack_require__(50);
	
	  var Func = _require13.Func;
	
	  var _require14 = __webpack_require__(51);
	
	  var RegExp = _require14.RegExp;
	
	  var _require15 = __webpack_require__(52);
	
	  var StyleSheet = _require15.StyleSheet;
	
	  var _require16 = __webpack_require__(53);
	
	  var TextNode = _require16.TextNode;
	
	  var _require17 = __webpack_require__(54);
	
	  var Window = _require17.Window;
	
	  var _require18 = __webpack_require__(55);
	
	  var ObjectWithText = _require18.ObjectWithText;
	
	  var _require19 = __webpack_require__(56);
	
	  var ObjectWithURL = _require19.ObjectWithURL;
	
	  var _require20 = __webpack_require__(57);
	
	  var GripArray = _require20.GripArray;
	
	  var _require21 = __webpack_require__(58);
	
	  var GripMap = _require21.GripMap;
	
	  var _require22 = __webpack_require__(44);
	
	  var Grip = _require22.Grip;
	
	  // List of all registered template.
	  // XXX there should be a way for extensions to register a new
	  // or modify an existing rep.
	
	  var 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.
	   */
	  var Rep = React.createClass({
	    displayName: "Rep",
	
	    propTypes: {
	      object: React.PropTypes.any,
	      defaultRep: React.PropTypes.object,
	      mode: React.PropTypes.string
	    },
	
	    render: function () {
	      var 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) {
	    var defaultRep = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Obj;
	
	    var 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 (var i = 0; i < reps.length; i++) {
	      var 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__));

/***/ },
/* 35 */
/***/ 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
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
	  // Dependencies
	  var React = __webpack_require__(2);
	
	  /**
	   * Create React factories for given arguments.
	   * Example:
	   *   const { Rep } = createFactories(require("./rep"));
	   */
	  function createFactories(args) {
	    var result = {};
	    for (var 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 + "";
	
	    // 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;
	    }
	
	    var 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) {
	    var params = [];
	
	    // In case the text is empty just return the empty parameters
	    if (text == "") {
	      return params;
	    }
	
	    var searchParams = new URLSearchParams(text);
	    var entries = [].concat(_toConsumableArray(searchParams.entries()));
	    return entries.map(entry => {
	      return {
	        name: entry[0],
	        value: entry[1]
	      };
	    });
	  }
	
	  function getFileName(url) {
	    var 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) {
	    var reSplitFile = /(.*?):\/{2,3}([^\/]*)(.*?)([^\/]*?)($|\?.*)/;
	    var 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__));

/***/ },
/* 36 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  // Shortcuts
	  var span = React.DOM.span;
	
	  /**
	   * Renders undefined value
	   */
	
	  var 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__));

/***/ },
/* 37 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  // Shortcuts
	  var span = React.DOM.span;
	
	  /**
	   * Renders null value
	   */
	
	  var 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__));

/***/ },
/* 38 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var cropMultipleLines = _require.cropMultipleLines;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders a string. String value is enclosed within quotes.
	   */
	
	  var StringRep = React.createClass({
	    displayName: "StringRep",
	
	    propTypes: {
	      useQuotes: React.PropTypes.bool
	    },
	
	    getDefaultProps: function () {
	      return {
	        useQuotes: true
	      };
	    },
	
	    render: function () {
	      var text = this.props.object;
	      var member = this.props.member;
	      if (member && member.open) {
	        return span({ className: "objectBox objectBox-string" }, "\"" + text + "\"");
	      }
	
	      var croppedString = this.props.cropLimit ? cropMultipleLines(text, this.props.cropLimit) : cropMultipleLines(text);
	
	      var 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__));

/***/ },
/* 39 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  // Shortcuts
	  var span = React.DOM.span;
	
	  /**
	   * Renders a number
	   */
	
	  var Number = React.createClass({
	    displayName: "Number",
	
	    stringify: function (object) {
	      var isNegativeZero = Object.is(object, -0) || object.type && object.type == "-0";
	
	      return isNegativeZero ? "-0" : String(object);
	    },
	
	    render: function () {
	      var 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__));

/***/ },
/* 40 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	
	  var _createFactories = createFactories(__webpack_require__(41));
	
	  var Caption = _createFactories.Caption;
	
	  // Shortcuts
	
	  var 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.
	   */
	  var ArrayRep = React.createClass({
	    displayName: "ArrayRep",
	
	    getTitle: function (object, context) {
	      return "[" + object.length + "]";
	    },
	
	    arrayIterator: function (array, max) {
	      var items = [];
	      var delim = void 0;
	
	      for (var i = 0; i < array.length && i < max; i++) {
	        try {
	          var 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) {
	        var 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) {
	        var y = parseInt(x, 10);
	        if (isNaN(y)) {
	          return false;
	        }
	        return x === y.toString();
	      }
	
	      var props = Object.getOwnPropertyNames(array);
	      for (var i = 0; i < props.length; i++) {
	        var 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 () {
	      var mode = this.props.mode || "short";
	      var object = this.props.object;
	      var items = void 0;
	      var brackets = void 0;
	      var needSpace = function (space) {
	        return space ? { left: "[ ", right: " ]" } : { left: "[", right: "]" };
	      };
	
	      if (mode == "tiny") {
	        var isEmpty = object.length === 0;
	        items = DOM.span({ className: "length" }, isEmpty ? "" : object.length);
	        brackets = needSpace(false);
	      } else {
	        var max = mode == "short" ? 3 : 300;
	        items = this.arrayIterator(object, max);
	        brackets = needSpace(items.length > 0);
	      }
	
	      var 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.
	   */
	  var ItemRep = React.createFactory(React.createClass({
	    displayName: "ItemRep",
	
	    render: function () {
	      var _createFactories2 = createFactories(__webpack_require__(34));
	
	      var Rep = _createFactories2.Rep;
	
	
	      var object = this.props.object;
	      var delim = this.props.delim;
	      var 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__));

/***/ },
/* 41 */
/***/ 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
	  var React = __webpack_require__(2);
	  var 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.
	   */
	  var 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__));

/***/ },
/* 42 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	
	  var _createFactories = createFactories(__webpack_require__(41));
	
	  var Caption = _createFactories.Caption;
	
	  var _createFactories2 = createFactories(__webpack_require__(43));
	
	  var PropRep = _createFactories2.PropRep;
	  // Shortcuts
	
	  var span = React.DOM.span;
	  /**
	   * Renders an object. An object is represented by a list of its
	   * properties enclosed in curly brackets.
	   */
	
	  var Obj = React.createClass({
	    displayName: "Obj",
	
	    propTypes: {
	      object: React.PropTypes.object,
	      mode: React.PropTypes.string
	    },
	
	    getTitle: function (object) {
	      var 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) {
	      var 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.
	      var 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();
	        var 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) {
	      var props = [];
	
	      max = max || 3;
	      if (!object) {
	        return props;
	      }
	
	      // Hardcode tiny mode to avoid recursive handling.
	      var mode = "tiny";
	
	      try {
	        for (var name in object) {
	          if (props.length > max) {
	            return props;
	          }
	
	          var value = void 0;
	          try {
	            value = object[name];
	          } catch (exc) {
	            continue;
	          }
	
	          var 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 () {
	      var object = this.props.object;
	      var props = this.safePropIterator(object);
	      var 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__));

/***/ },
/* 43 */
/***/ 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) {
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var span = React.DOM.span;
	
	  /**
	   * 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.
	   */
	
	  var 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 () {
	      var _require2 = __webpack_require__(44);
	
	      var Grip = _require2.Grip;
	
	      var _createFactories = createFactories(__webpack_require__(34));
	
	      var Rep = _createFactories.Rep;
	
	
	      var key = void 0;
	      // 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	  // Dependencies
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var isGrip = _require.isGrip;
	
	  var _createFactories = createFactories(__webpack_require__(41));
	
	  var Caption = _createFactories.Caption;
	
	  var _createFactories2 = createFactories(__webpack_require__(43));
	
	  var PropRep = _createFactories2.PropRep;
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders generic grip. Grip is client representation
	   * of remote JS object and is used as an input object
	   * for this rep component.
	   */
	
	  var 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.
	      var isInterestingProp = this.props.isInterestingProp || ((type, value) => {
	        return type == "boolean" || type == "number" || type == "string" && value.length != 0;
	      });
	
	      var ownProperties = object.preview ? object.preview.ownProperties : [];
	      var 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);
	        }));
	      }
	
	      var props = this.getProps(ownProperties, indexes);
	      if (props.length < object.ownPropertyLength) {
	        // There are some undisplayed props. Then display "more...".
	        var 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
	        var 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) {
	      var props = [];
	
	      // Make indexes ordered by ascending.
	      indexes.sort(function (a, b) {
	        return a - b;
	      });
	
	      indexes.forEach(i => {
	        var name = Object.keys(ownProperties)[i];
	        var prop = ownProperties[name];
	        var 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) {
	      var indexes = [];
	
	      try {
	        var i = 0;
	        for (var name in ownProperties) {
	          if (indexes.length >= max) {
	            return indexes;
	          }
	
	          var prop = ownProperties[name];
	          var value = prop.value !== undefined ? prop.value : prop;
	
	          // Type is specified in grip's "class" field and for primitive
	          // values use typeof.
	          var 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 () {
	      var object = this.props.object;
	      var props = this.safePropIterator(object, this.props.mode == "long" ? 100 : 3);
	
	      var 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;
	  }
	
	  var 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__));

/***/ },
/* 45 */
/***/ 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
	  var React = __webpack_require__(2);
	
	  // Shortcuts
	  var span = React.DOM.span;
	
	  /**
	   * Renders a symbol.
	   */
	
	  var SymbolRep = React.createClass({
	    displayName: "SymbolRep",
	
	    propTypes: {
	      object: React.PropTypes.object.isRequired
	    },
	
	    render: function () {
	      var object = this.props.object;
	      var name = object.name;
	
	
	      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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var isGrip = _require.isGrip;
	
	  var _require2 = __webpack_require__(38);
	
	  var StringRep = _require2.StringRep;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  var _createFactories = createFactories(StringRep);
	
	  var StringRepFactory = _createFactories.rep;
	
	  /**
	   * Renders DOM attribute
	   */
	
	  var Attribute = React.createClass({
	    displayName: "Attr",
	
	    propTypes: {
	      object: React.PropTypes.object.isRequired
	    },
	
	    getTitle: function (grip) {
	      return grip.preview.nodeName;
	    },
	
	    render: function () {
	      var grip = this.props.object;
	      var value = grip.preview.value;
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Used to render JS built-in Date() object.
	   */
	
	  var 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 () {
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var getURLDisplayString = _require.getURLDisplayString;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders DOM document object.
	   */
	
	  var Document = React.createClass({
	    displayName: "Document",
	
	    propTypes: {
	      object: React.PropTypes.object.isRequired
	    },
	
	    getLocation: function (grip) {
	      var 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 () {
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var isGrip = _require.isGrip;
	
	  var _createFactories = createFactories(__webpack_require__(44).Grip);
	
	  var rep = _createFactories.rep;
	
	  /**
	   * Renders DOM event objects.
	   */
	
	  var 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.
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var cropString = _require.cropString;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * This component represents a template for Function objects.
	   */
	
	  var 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) {
	      var name = grip.userDisplayName || grip.displayName || grip.name || "function";
	      return cropString(name + "()", 100);
	    },
	
	    render: function () {
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders a grip object with regular expression.
	   */
	
	  var RegExp = React.createClass({
	    displayName: "regexp",
	
	    propTypes: {
	      object: React.PropTypes.object.isRequired
	    },
	
	    getSource: function (grip) {
	      return grip.displayString;
	    },
	
	    render: function () {
	      var grip = this.props.object;
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var getURLDisplayString = _require.getURLDisplayString;
	
	  // Shortcuts
	
	  var DOM = React.DOM;
	
	  /**
	   * Renders a grip representing CSSStyleSheet
	   */
	  var StyleSheet = React.createClass({
	    displayName: "object",
	
	    propTypes: {
	      object: React.PropTypes.object.isRequired
	    },
	
	    getTitle: function (grip) {
	      var 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.
	      var url = grip.preview ? grip.preview.url : "";
	      return url ? getURLDisplayString(url) : "";
	    },
	
	    render: function () {
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var cropMultipleLines = _require.cropMultipleLines;
	
	  // Shortcuts
	
	  var DOM = React.DOM;
	
	  /**
	   * Renders DOM #text node.
	   */
	  var 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 () {
	      var grip = this.props.object;
	      var mode = this.props.mode || "short";
	
	      if (mode == "short" || mode == "tiny") {
	        return DOM.span({ className: "objectBox objectBox-textNode" }, this.getTitle(grip), "\"" + this.getTextContent(grip) + "\"");
	      }
	
	      var 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__));

/***/ },
/* 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
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var getURLDisplayString = _require.getURLDisplayString;
	
	  // Shortcuts
	
	  var DOM = React.DOM;
	
	  /**
	   * Renders a grip representing a window.
	   */
	  var 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 () {
	      var 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__));

/***/ },
/* 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) {
	  // ReactJS
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders a grip object with textual data.
	   */
	
	  var 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 () {
	      var 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__));

/***/ },
/* 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
	  var React = __webpack_require__(2);
	
	  // Reps
	
	  var _require = __webpack_require__(35);
	
	  var isGrip = _require.isGrip;
	  var getURLDisplayString = _require.getURLDisplayString;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders a grip object with URL data.
	   */
	
	  var 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 () {
	      var 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__));

/***/ },
/* 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) {
	  // Dependencies
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var isGrip = _require.isGrip;
	
	  var _createFactories = createFactories(__webpack_require__(41));
	
	  var Caption = _createFactories.Caption;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	
	  /**
	   * Renders an array. The array is enclosed by left and right bracket
	   * and the max number of rendered items depends on the current mode.
	   */
	
	  var 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) {
	      var objectLink = this.props.objectLink || span;
	      if (this.props.mode != "tiny") {
	        return objectLink({
	          object: object
	        }, object.class + " ");
	      }
	      return "";
	    },
	
	    arrayIterator: function (grip, max) {
	      var items = [];
	
	      if (!grip.preview || !grip.preview.length) {
	        return items;
	      }
	
	      var array = grip.preview.items;
	      if (!array) {
	        return items;
	      }
	
	      var delim = void 0;
	      // number of grip.preview.items is limited to 10, but we may have more
	      // items in grip-array
	      var delimMax = grip.preview.length > array.length ? array.length : array.length - 1;
	      var provider = this.props.provider;
	
	      for (var i = 0; i < array.length && i < max; i++) {
	        try {
	          var itemGrip = array[i];
	          var 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) {
	        var objectLink = this.props.objectLink || span;
	        var 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 () {
	      var mode = this.props.mode || "short";
	      var object = this.props.object;
	
	      var items = void 0;
	      var brackets = void 0;
	      var needSpace = function (space) {
	        return space ? { left: "[ ", right: " ]" } : { left: "[", right: "]" };
	      };
	
	      if (mode == "tiny") {
	        var objectLength = this.getLength(object);
	        var isEmpty = objectLength === 0;
	        items = span({ className: "length" }, isEmpty ? "" : objectLength);
	        brackets = needSpace(false);
	      } else {
	        var max = mode == "short" ? 3 : 300;
	        items = this.arrayIterator(object, max);
	        brackets = needSpace(items.length > 0);
	      }
	
	      var objectLink = this.props.objectLink || span;
	      var 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).
	   */
	  var GripArrayItem = React.createFactory(React.createClass({
	    displayName: "GripArrayItem",
	
	    propTypes: {
	      delim: React.PropTypes.string
	    },
	
	    render: function () {
	      var _createFactories2 = createFactories(__webpack_require__(34));
	
	      var Rep = _createFactories2.Rep;
	
	
	      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__));

/***/ },
/* 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
	
	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports, module) {
	  // Dependencies
	  var React = __webpack_require__(2);
	
	  var _require = __webpack_require__(35);
	
	  var createFactories = _require.createFactories;
	  var isGrip = _require.isGrip;
	
	  var _createFactories = createFactories(__webpack_require__(41));
	
	  var Caption = _createFactories.Caption;
	
	  var _createFactories2 = createFactories(__webpack_require__(43));
	
	  var PropRep = _createFactories2.PropRep;
	
	  // Shortcuts
	
	  var span = React.DOM.span;
	  /**
	   * Renders an map. A map is represented by a list of its
	   * entries enclosed in curly brackets.
	   */
	
	  var GripMap = React.createClass({
	    displayName: "GripMap",
	
	    propTypes: {
	      object: React.PropTypes.object,
	      mode: React.PropTypes.string
	    },
	
	    getTitle: function (object) {
	      var 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.
	      var isInterestingEntry = this.props.isInterestingEntry || ((type, value) => {
	        return type == "boolean" || type == "number" || type == "string" && value.length != 0;
	      });
	
	      var mapEntries = object.preview && object.preview.entries ? object.preview.entries : [];
	
	      var 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);
	        }));
	      }
	
	      var entries = this.getEntries(mapEntries, indexes);
	      if (entries.length < mapEntries.length) {
	        // There are some undisplayed entries. Then display "more…".
	        var 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) => {
	        var _entries$index = _slicedToArray(entries[index], 2);
	
	        var key = _entries$index[0];
	        var entryValue = _entries$index[1];
	
	        var 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, _ref, i) => {
	        var _ref2 = _slicedToArray(_ref, 2);
	
	        var key = _ref2[0];
	        var entry = _ref2[1];
	
	        if (indexes.length < max) {
	          var value = entry && entry.value !== undefined ? entry.value : entry;
	          // Type is specified in grip's "class" field and for primitive
	          // values use typeof.
	          var type = (value && value.class ? value.class : typeof value).toLowerCase();
	
	          if (filter(type, value, key)) {
	            indexes.push(i);
	          }
	        }
	
	        return indexes;
	      }, []);
	    },
	
	    render: function () {
	      var object = this.props.object;
	      var props = this.safeEntriesIterator(object, this.props.mode == "long" ? 100 : 3);
	
	      var 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__));

/***/ },
/* 59 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Copyright (c) 2007-2016, Alexandru Marasteanu <hello [at) alexei (dot] ro>
	 * 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);

/***/ },
/* 60 */
/***/ 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;
	
	var _require = __webpack_require__(61);
	
	var Cu = _require.Cu;
	
	var promise = __webpack_require__(66);
	
	/**
	 * 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) {
	  var 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) {
	    var _this = this;
	
	    var deferred = promise.defer();
	
	    var handler = function (aEvent, aFirstArg) {
	      for (var _len = arguments.length, aRest = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
	        aRest[_key - 2] = arguments[_key];
	      }
	
	      _this.off(aEvent, handler);
	      if (aListener) {
	        aListener.apply(null, [aEvent, aFirstArg].concat(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;
	    var 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) {
	    var _this2 = this,
	        _arguments = arguments;
	
	    if (!this._eventEmitterListeners || !this._eventEmitterListeners.has(aEvent)) {
	      return;
	    }
	
	    var originalListeners = this._eventEmitterListeners.get(aEvent);
	
	    var _loop = function (listener) {
	      // If the object was destroyed during event emission, stop
	      // emitting.
	      if (!_this2._eventEmitterListeners) {
	        return "break";
	      }
	
	      // If listeners were removed during emission, make sure the
	      // event handler we're going to fire wasn't removed.
	      if (originalListeners === _this2._eventEmitterListeners.get(aEvent) || _this2._eventEmitterListeners.get(aEvent).some(l => l === listener)) {
	        try {
	          listener.apply(null, _arguments);
	        } catch (ex) {
	          // Prevent a bad listener from interfering with the others.
	          var msg = ex + ": " + ex.stack;
	          //console.error(msg);
	          console.log(msg);
	        }
	      }
	    };
	
	    for (var listener of this._eventEmitterListeners.get(aEvent)) {
	      var _ret = _loop(listener);
	
	      if (_ret === "break") break;
	    }
	  }
	};

/***/ },
/* 61 */
/***/ function(module, exports, __webpack_require__) {

	/*
	 * A sham for https://developer.mozilla.org/en-US/Add-ons/SDK/Low-Level_APIs/chrome
	 */
	
	var _require = __webpack_require__(62);
	
	var inDOMUtils = _require.inDOMUtils;
	
	
	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
	  }
	};

/***/ },
/* 62 */
/***/ function(module, exports, __webpack_require__) {

	// A sham for inDOMUtils.
	
	"use strict";
	
	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	var _require = __webpack_require__(63);
	
	var CSSLexer = _require.CSSLexer;
	
	var _require2 = __webpack_require__(64);
	
	var cssColors = _require2.cssColors;
	
	var _require3 = __webpack_require__(65);
	
	var cssProperties = _require3.cssProperties;
	
	
	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 (var name in cssColors) {
	      cssRGBMap.set(JSON.stringify(cssColors[name]), name);
	    }
	  }
	  var 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(_ref) {
	  var _ref2 = _slicedToArray(_ref, 3);
	
	  var hue = _ref2[0];
	  var saturation = _ref2[1];
	  var lightness = _ref2[2];
	
	  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];
	  }
	
	  var lexer = getCSSLexer(name);
	
	  var getToken = function () {
	    while (true) {
	      var token = lexer.nextToken();
	      if (!token || token.tokenType !== "comment" || token.tokenType !== "whitespace") {
	        return token;
	      }
	    }
	  };
	
	  var requireComma = function (token) {
	    if (token.tokenType !== "symbol" || token.text !== ",") {
	      return null;
	    }
	    return getToken();
	  };
	
	  var func = getToken();
	  if (!func || func.tokenType !== "function") {
	    return null;
	  }
	  var alpha = false;
	  if (func.text === "rgb" || func.text === "hsl") {
	    // Nothing.
	  } else if (func.text === "rgba" || func.text === "hsla") {
	    alpha = true;
	  } else {
	    return null;
	  }
	
	  var vals = [];
	  for (var i = 0; i < 3; ++i) {
	    var token = getToken();
	    if (i > 0) {
	      token = requireComma(token);
	    }
	    if (token.tokenType !== "number" || !token.isInteger) {
	      return null;
	    }
	    var 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) {
	    var _token = requireComma(getToken());
	    if (_token.tokenType !== "number") {
	      return null;
	    }
	    var _num = _token.number;
	    if (_num < 0) {
	      _num = 0;
	    } else if (_num > 1) {
	      _num = 1;
	    }
	    vals.push(_num);
	  } else {
	    vals.push(1);
	  }
	
	  var 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) {
	  var 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;
	  }
	  var 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
	};

/***/ },
/* 63 */
/***/ 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();
						var _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 CDCToken() {
			return this;
		}
		CDCToken.prototype = Object.create(CSSParserToken.prototype);
		CDCToken.prototype.tokenType = "htmlcomment";
		CDCToken.prototype.toSource = function () {
			return "-->";
		};
	
		function ColonToken() {
			return this;
		}
		ColonToken.prototype = Object.create(CSSParserToken.prototype);
		ColonToken.prototype.tokenType = "symbol";
		ColonToken.prototype.text = ":";
	
		function SemicolonToken() {
			return this;
		}
		SemicolonToken.prototype = Object.create(CSSParserToken.prototype);
		SemicolonToken.prototype.tokenType = "symbol";
		SemicolonToken.prototype.text = ";";
	
		function CommaToken() {
			return this;
		}
		CommaToken.prototype = Object.create(CSSParserToken.prototype);
		CommaToken.prototype.tokenType = "symbol";
		CommaToken.prototype.text = ",";
	
		function GroupingToken() {
			throw "Abstract Base Class";
		}
		GroupingToken.prototype = Object.create(CSSParserToken.prototype);
	
		function OpenCurlyToken() {
			this.value = "{";this.mirror = "}";return this;
		}
		OpenCurlyToken.prototype = Object.create(GroupingToken.prototype);
		OpenCurlyToken.prototype.tokenType = "symbol";
		OpenCurlyToken.prototype.text = "{";
	
		function CloseCurlyToken() {
			this.value = "}";this.mirror = "{";return this;
		}
		CloseCurlyToken.prototype = Object.create(GroupingToken.prototype);
		CloseCurlyToken.prototype.tokenType = "symbol";
		CloseCurlyToken.prototype.text = "}";
	
		function OpenSquareToken() {
			this.value = "[";this.mirror = "]";return this;
		}
		OpenSquareToken.prototype = Object.create(GroupingToken.prototype);
		OpenSquareToken.prototype.tokenType = "symbol";
		OpenSquareToken.prototype.text = "[";
	
		function CloseSquareToken() {
			this.value = "]";this.mirror = "[";return this;
		}
		CloseSquareToken.prototype = Object.create(GroupingToken.prototype);
		CloseSquareToken.prototype.tokenType = "symbol";
		CloseSquareToken.prototype.text = "]";
	
		function OpenParenToken() {
			this.value = "(";this.mirror = ")";return this;
		}
		OpenParenToken.prototype = Object.create(GroupingToken.prototype);
		OpenParenToken.prototype.tokenType = "symbol";
		OpenParenToken.prototype.text = "(";
	
		function CloseParenToken() {
			this.value = ")";this.mirror = "(";return this;
		}
		CloseParenToken.prototype = Object.create(GroupingToken.prototype);
		CloseParenToken.prototype.tokenType = "symbol";
		CloseParenToken.prototype.text = ")";
	
		function IncludeMatchToken() {
			return this;
		}
		IncludeMatchToken.prototype = Object.create(CSSParserToken.prototype);
		IncludeMatchToken.prototype.tokenType = "includes";
	
		function DashMatchToken() {
			return this;
		}
		DashMatchToken.prototype = Object.create(CSSParserToken.prototype);
		DashMatchToken.prototype.tokenType = "dashmatch";
	
		function PrefixMatchToken() {
			return this;
		}
		PrefixMatchToken.prototype = Object.create(CSSParserToken.prototype);
		PrefixMatchToken.prototype.tokenType = "beginsmatch";
	
		function SuffixMatchToken() {
			return this;
		}
		SuffixMatchToken.prototype = Object.create(CSSParserToken.prototype);
		SuffixMatchToken.prototype.tokenType = "endsmatch";
	
		function SubstringMatchToken() {
			return this;
		}
		SubstringMatchToken.prototype = Object.create(CSSParserToken.prototype);
		SubstringMatchToken.prototype.tokenType = "containsmatch";
	
		function ColumnToken() {
			return this;
		}
		ColumnToken.prototype = Object.create(CSSParserToken.prototype);
		ColumnToken.prototype.tokenType = "||";
	
		function EOFToken() {
			return this;
		}
		EOFToken.prototype = Object.create(CSSParserToken.prototype);
		EOFToken.prototype.tokenType = "EOF";
		EOFToken.prototype.toSource = function () {
			return "";
		};
	
		function DelimToken(code) {
			this.value = stringFromCode(code);
			this.text = this.value;
			return this;
		}
		DelimToken.prototype = Object.create(CSSParserToken.prototype);
		DelimToken.prototype.tokenType = "symbol";
		DelimToken.prototype.toString = function () {
			return "DELIM(" + this.value + ")";
		};
		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;
			}
			var 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;
	});

/***/ },
/* 64 */
/***/ 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 };

/***/ },
/* 65 */
/***/ 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};

/***/ },
/* 66 */
/***/ 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`.
	 */
	
	var 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;

/***/ },
/* 67 */
/***/ 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";
	
	var DevToolsUtils = __webpack_require__(68);
	var dumpn = DevToolsUtils.dumpn;
	var dumpv = DevToolsUtils.dumpv;
	
	var StreamUtils = __webpack_require__(74);
	
	var _require = __webpack_require__(75);
	
	var Packet = _require.Packet;
	var JSONPacket = _require.JSONPacket;
	var BulkPacket = _require.BulkPacket;
	
	var promise = __webpack_require__(66);
	var EventEmitter = __webpack_require__(60);
	var utf8 = __webpack_require__(78);
	
	var 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);
	
	    var 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);
	
	    var 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 => {
	          var 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 (var 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) {
	    var 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);
	    var stream = {
	      available() {
	        return data.length;
	      },
	      readBytes(count) {
	        var 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) {
	      var 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) {
	    var 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 () {
	    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	      args[_key] = arguments[_key];
	    }
	
	    DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
	      // Ensure the transport is still alive by the time this runs.
	      if (this.active) {
	        var _hooks;
	
	        this.emit.apply(this, ["onBulkPacket"].concat(args));
	        (_hooks = this.hooks).onBulkPacket.apply(_hooks, 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);
	
	    var 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);
	    var 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 (_ref) {
	    var actor = _ref.actor;
	    var type = _ref.type;
	    var length = _ref.length;
	
	    this.emit("startBulkSend", { actor, type, length });
	
	    var serial = this._serial.count++;
	
	    dumpn("Sent bulk packet " + serial + " for actor " + actor);
	    if (!this.other) {
	      return;
	    }
	
	    var pipe = new Pipe(true, true, 0, 0, null);
	
	    DevToolsUtils.executeSoon(DevToolsUtils.makeInfallible(() => {
	      dumpn("Received bulk packet " + serial);
	      if (!this.other.hooks) {
	        return;
	      }
	
	      // Receiver
	      var deferred = promise.defer();
	      var packet = {
	        actor: actor,
	        type: type,
	        length: length,
	        copyTo: output => {
	          var 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
	    var sendDeferred = promise.defer();
	
	    // The remote transport is not capable of resolving immediately here, so we
	    // shouldn't be able to either.
	    DevToolsUtils.executeSoon(() => {
	      var copyDeferred = promise.defer();
	
	      sendDeferred.resolve({
	        copyFrom: input => {
	          var 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.
	      var 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 (var 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:<prefix>:packet', where
	 * <prefix> is |prefix|, whose data is the protocol packet.
	 */
	function ChildDebuggerTransport(sender, prefix) {
	  EventEmitter.decorate(this);
	
	  this._sender = sender.QueryInterface(Ci.nsIMessageSender);
	  this._messageName = "debug:" + prefix + ":packet";
	}
	
	/*
	 * To avoid confusion, we use 'message' to mean something that
	 * nsIMessageSender conveys, and 'packet' to mean a remote debugging
	 * protocol packet.
	 */
	ChildDebuggerTransport.prototype = {
	  constructor: ChildDebuggerTransport,
	
	  hooks: null,
	
	  ready: function () {
	    this._sender.addMessageListener(this._messageName, this);
	  },
	
	  close: function () {
	    this._sender.removeMessageListener(this._messageName, this);
	    this.emit("onClosed");
	    this.hooks.onClosed();
	  },
	
	  receiveMessage: function (_ref2) {
	    var data = _ref2.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) {
	        var 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) {
	        var 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);
	}

/***/ },
/* 68 */
/***/ function(module, exports, __webpack_require__) {

	var _this = this;
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.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 _require = __webpack_require__(61);
	
	var Ci = _require.Ci;
	var Cu = _require.Cu;
	var Cc = _require.Cc;
	var components = _require.components;
	
	var _require2 = __webpack_require__(30);
	
	var Services = _require2.Services;
	
	var promise = __webpack_require__(66);
	
	var _require3 = __webpack_require__(69);
	
	var FileUtils = _require3.FileUtils;
	
	/**
	 * Turn the error |aError| into a string, without fail.
	 */
	
	exports.safeErrorString = function safeErrorString(aError) {
	  try {
	    var 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) {
	          var 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) {
	  var 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() {
	  var 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) {
	  var 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) {
	  var deferred = promise.defer();
	
	  var i = 0;
	  var len = aArray.length;
	  var outstanding = [deferred.promise];
	
	  (function loop() {
	    var 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 () {
	      var 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) {
	  var root = aObj;
	  try {
	    do {
	      var 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 {
	    var 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.
	  }
	
	  var 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) {
	  for (var _len = arguments.length, aArgs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	    aArgs[_key - 1] = arguments[_key];
	  }
	
	  for (var attrs of aArgs) {
	    for (var key in attrs) {
	      var 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!
	var haveLoggedDeprecationMessage = false;
	exports.dbg_assert = function dbg_assert(cond, e) {
	  if (!haveLoggedDeprecationMessage) {
	    haveLoggedDeprecationMessage = true;
	    var 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;
	  }
	};
	
	var _require4 = __webpack_require__(70);
	
	var AppConstants = _require4.AppConstants;
	
	/**
	 * No operation. The empty function.
	 */
	
	exports.noop = function () {};
	
	function reallyAssert(condition, message) {
	  if (!condition) {
	    var 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];
	  });
	};
	
	var _require5 = __webpack_require__(71);
	
	var NetUtil = _require5.NetUtil;
	
	var _require6 = __webpack_require__(72);
	
	var TextDecoder = _require6.TextDecoder;
	var OS = _require6.OS;
	
	
	var NetworkHelper = __webpack_require__(73);
	
	/**
	 * 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) {
	  var aOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { loadFromCache: true,
	    policy: Ci.nsIContentPolicy.TYPE_OTHER,
	    window: null,
	    charset: null };
	
	  // Create a channel.
	  var url = aURL.split(" -> ").pop();
	  var channel = void 0;
	  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;
	  }
	
	  var deferred = promise.defer();
	  var 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.
	      var available = stream.available();
	      var 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.
	      var charset = channel.contentCharset || aOptions.charset || "UTF-8";
	      var unicodeSource = NetworkHelper.convertToUnicode(source, charset);
	
	      deferred.resolve({
	        content: unicodeSource,
	        contentType: request.contentType
	      });
	    } catch (ex) {
	      var 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);
	        var result = OS.File.read(uri.file.path).then(bytes => {
	          // Convert the bytearray to a String.
	          var decoder = new TextDecoder();
	          var 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, _ref) {
	  var policy = _ref.policy;
	
	  var 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.");
	  }
	
	  var deferred = promise.defer();
	
	  values = Array.isArray(values) ? values : [].concat(_toConsumableArray(values));
	  var countdown = values.length;
	  var resolutionValues = new Array(countdown);
	  var rejectionValue = void 0;
	  var 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);
	    }
	  }
	
	  var _loop = function (i) {
	    var index = i;
	    var value = values[i];
	    var resolver = result => {
	      resolutionValues[index] = result;
	      checkForCompletion();
	    };
	    var 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);
	    }
	  };
	
	  for (var i = 0; i < values.length; i++) {
	    _loop(i);
	  }
	
	  return deferred.promise;
	};
	
	/**
	 * When the testing flag is set, various behaviors may be altered from
	 * production mode, typically to enable easier testing or enhanced debugging.
	 */
	var testing = false;
	Object.defineProperty(exports, "testing", {
	  get: function () {
	    return testing;
	  },
	  set: function (state) {
	    testing = state;
	  }
	});
	
	/**
	 * Open the file at the given path for reading.
	 *
	 * @param {String} filePath
	 *
	 * @returns Promise<nsIInputStream>
	 */
	exports.openFileStream = function (filePath) {
	  return new Promise((resolve, reject) => {
	    var 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;
	  }
	  var proto = Object.getPrototypeOf(fn);
	  if (!proto) {
	    return false;
	  }
	  var 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]";
	};

/***/ },
/* 69 */
/***/ function(module, exports) {

	/*
	 * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/FileUtils.jsm
	 */

/***/ },
/* 70 */
/***/ function(module, exports) {

	/*
	 * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/modules/AppConstants.jsm
	 */
	
	module.exports = { AppConstants: {} };

/***/ },
/* 71 */
/***/ function(module, exports) {

	/*
	 * A sham for https://dxr.mozilla.org/mozilla-central/source/netwerk/base/NetUtil.jsm
	 */

/***/ },
/* 72 */
/***/ function(module, exports) {

	/*
	 * A sham for https://dxr.mozilla.org/mozilla-central/source/toolkit/components/osfile/osfile.jsm
	 */

/***/ },
/* 73 */
/***/ 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";
	
	var _require = __webpack_require__(61);
	
	var components = _require.components;
	var Cc = _require.Cc;
	var Ci = _require.Ci;
	var Cu = _require.Cu;
	
	var _require2 = __webpack_require__(71);
	
	var NetUtil = _require2.NetUtil;
	
	var DevToolsUtils = __webpack_require__(68);
	
	// The cache used in the `nsIURL` function.
	var 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) {
	    var 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) {
	    var 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) {
	      var iStream = aRequest.uploadStream;
	
	      var isSeekableStream = false;
	      if (iStream instanceof Ci.nsISeekableStream) {
	        isSeekableStream = true;
	      }
	
	      var prevOffset = void 0;
	      if (isSeekableStream) {
	        prevOffset = iStream.tell();
	        iStream.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
	      }
	
	      // Read data from the stream.
	      var 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) {
	    var 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) {
	      var 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) {
	      var 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) {
	    var 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.
	      var aChannel = aRequest.QueryInterface(Ci.nsIChannel);
	      var 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) {
	    var cookies = aHeader.split(";");
	    var result = [];
	
	    cookies.forEach(function (aCookie) {
	      var equal = aCookie.indexOf("=");
	      var name = aCookie.substr(0, equal);
	      var 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) {
	    var rawCookies = aHeader.split(/\r\n|\n|\r/);
	    var cookies = [];
	
	    rawCookies.forEach(function (aCookie) {
	      var equal = aCookie.indexOf("=");
	      var name = unescape(aCookie.substr(0, equal).trim());
	      var parts = aCookie.substr(equal + 1).split(";");
	      var value = unescape(parts.shift().trim());
	
	      var cookie = { name: name, value: value };
	
	      parts.forEach(function (aPart) {
	        var part = aPart.trim();
	        if (part.toLowerCase() == "secure") {
	          cookie.secure = true;
	        } else if (part.toLowerCase() == "httponly") {
	          cookie.httpOnly = true;
	        } else if (part.indexOf("=") > -1) {
	          var 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;
	    }
	
	    var 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) {
	    var 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);
	
	    var wpl = Ci.nsIWebProgressListener;
	    var NSSErrorsService = Cc['@mozilla.org/nss_errors_service;1'].getService(Ci.nsINSSErrorsService);
	    var SSLStatus = securityInfo.SSLStatus;
	    if (!NSSErrorsService.isNSSErrorCode(securityInfo.errorCode)) {
	      var state = securityInfo.securityState;
	
	      var 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) {
	        var 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.
	        var flags = httpActivity.private ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0;
	
	        var 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) {
	    var 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) {
	    var 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
	    var reasons = [];
	
	    if (state & wpl.STATE_IS_BROKEN) {
	      var 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.
	    var paramsArray = aQueryString.replace(/^[?&]/, "").split("&").map(e => {
	      var 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) {
	    var aStore = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : gNSURLStore;
	
	    if (aStore.has(aUrl)) {
	      return aStore.get(aUrl);
	    }
	
	    var uri = Services.io.newURI(aUrl, null, null).QueryInterface(Ci.nsIURL);
	    aStore.set(aUrl, uri);
	    return uri;
	  }
	};
	
	for (var prop of Object.getOwnPropertyNames(NetworkHelper)) {
	  exports[prop] = NetworkHelper[prop];
	}

/***/ },
/* 74 */
/***/ 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/. */
	
	var _require = __webpack_require__(61);
	
	var Ci = _require.Ci;
	var Cc = _require.Cc;
	var Cr = _require.Cr;
	var CC = _require.CC;
	
	var _require2 = __webpack_require__(30);
	
	var Services = _require2.Services;
	
	var _require3 = __webpack_require__(68);
	
	var dumpv = _require3.dumpv;
	
	var EventEmitter = __webpack_require__(60);
	var promise = __webpack_require__(66);
	
	var IOUtil = Cc("@mozilla.org/io-util;1").getService(Ci.nsIIOUtil);
	
	var ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", "nsIScriptableInputStream", "init");
	
	var 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) {
	  var 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 () {
	    var bytesAvailable = this.input.available();
	    var amountToCopy = Math.min(bytesAvailable, this._amountLeft);
	    this._debug("Trying to copy: " + amountToCopy);
	
	    var bytesCopied = void 0;
	    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");
	
	  var scriptableStream = void 0;
	  if (stream.readBytes) {
	    scriptableStream = stream;
	  } else {
	    scriptableStream = new ScriptableInputStream(stream);
	  }
	
	  var data = "";
	
	  // Don't exceed what's available on the stream
	  count = Math.min(count, stream.available());
	
	  if (count <= 0) {
	    return data;
	  }
	
	  var char = void 0;
	  while (char !== delimiter && count > 0) {
	    char = scriptableStream.readBytes(1);
	    count--;
	    data += char;
	  }
	
	  return data;
	}
	
	module.exports = {
	  copyStream: copyStream,
	  delimitedRead: delimitedRead
	};

/***/ },
/* 75 */
/***/ 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
	 */
	
	var _require = __webpack_require__(61);
	
	var Cc = _require.Cc;
	var Ci = _require.Ci;
	var Cu = _require.Cu;
	
	var DevToolsUtils = __webpack_require__(68);
	var dumpn = DevToolsUtils.dumpn;
	var dumpv = DevToolsUtils.dumpv;
	
	var StreamUtils = __webpack_require__(74);
	var promise = __webpack_require__(66);
	
	/*DevToolsUtils.defineLazyGetter(this, "unicodeConverter", () => {
	  const unicodeConverter = Cc("@mozilla.org/intl/scriptableunicodeconverter")
	                           .createInstance(Ci.nsIScriptableUnicodeConverter);
	  unicodeConverter.charset = "UTF-8";
	  return unicodeConverter;
	});*/
	var utf8 = __webpack_require__(76);
	
	// 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.
	var 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) {
	  var match = this.HEADER_PATTERN.exec(header);
	
	  if (!match) {
	    return null;
	  }
	
	  dumpv("Header matches JSON packet");
	  var 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;
	    var 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;
	  }
	
	  var json = this._data;
	  try {
	    json = utf8.decode(json);
	    this._object = JSON.parse(json);
	  } catch (e) {
	    var 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());
	  }
	  var 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;
	  }
	
	  var 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) {
	  var match = this.HEADER_PATTERN.exec(header);
	
	  if (!match) {
	    return null;
	  }
	
	  dumpv("Header matches bulk packet");
	  var 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();
	
	  var deferred = promise.defer();
	
	  this._transport._onBulkReadReady({
	    actor: this.actor,
	    type: this.type,
	    length: this.length,
	    copyTo: output => {
	      dumpv("CT length: " + this.length);
	      var 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");
	    var 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();
	
	  var deferred = promise.defer();
	
	  this._readyForWriting.resolve({
	    copyFrom: input => {
	      dumpv("CF length: " + this.length);
	      var 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) {
	  var 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;

/***/ },
/* 76 */
/***/ 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__(77)(module), (function() { return this; }())))

/***/ },
/* 77 */
/***/ 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;
	}


/***/ },
/* 78 */
/***/ 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__(77)(module), (function() { return this; }())))

/***/ },
/* 79 */
/***/ function(module, exports, __webpack_require__) {

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	/* -*- 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/. */
	
	var _require = __webpack_require__(61);
	
	var Ci = _require.Ci;
	var Cu = _require.Cu;
	var components = _require.components;
	
	var _require2 = __webpack_require__(30);
	
	var Services = _require2.Services;
	
	var DevToolsUtils = __webpack_require__(68);
	
	// WARNING I swapped the sync one for the async one here
	// const promise = require("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise;
	var promise = __webpack_require__(66);
	
	var events = __webpack_require__(80);
	
	var _require3 = __webpack_require__(82);
	
	var WebConsoleClient = _require3.WebConsoleClient;
	/* const { DebuggerSocket } = require("../shared/security/socket");*/
	/* const Authentication = require("../shared/security/auth");*/
	
	var 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) {
	    var _this = this;
	
	    var l = function () {
	      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	        args[_key] = arguments[_key];
	      }
	
	      _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;
	    }
	
	    var name = arguments[0];
	    var listeners = this._getListeners(name).slice(0);
	
	    for (var 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.
	 */
	var ThreadStateTypes = {
	  "paused": "paused",
	  "resumed": "attached",
	  "detached": "detached"
	};
	
	/**
	 * Set of protocol messages that are sent by the server without a prior request
	 * by the client.
	 */
	var 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.
	 */
	var 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.
	 */
	var 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) {
	  var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	  var telemetry = config.telemetry;
	  var before = config.before;
	  var after = config.after;
	
	  return DevToolsUtils.makeInfallible(function () {
	    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
	      args[_key2] = arguments[_key2];
	    }
	
	    var histogram = void 0,
	        startTime = void 0;
	    if (telemetry) {
	      var transportType = this._transport.onOutputStreamReady === undefined ? "LOCAL_" : "REMOTE_";
	      var histogramId = "DEVTOOLS_DEBUGGER_RDP_" + transportType + telemetry + "_MS";
	      histogram = Services.telemetry.getHistogramById(histogramId);
	      startTime = +new Date();
	    }
	    var outgoingPacket = {
	      to: aPacketSkeleton.to || this.actor
	    };
	
	    var maxPosition = -1;
	    for (var k of Object.keys(aPacketSkeleton)) {
	      if (aPacketSkeleton[k] instanceof DebuggerClient.Argument) {
	        var position = aPacketSkeleton[k].position;
	
	        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) {
	        var _aResponse = aResponse;
	        var from = _aResponse.from;
	
	        aResponse = after.call(this, aResponse);
	        if (!aResponse.from) {
	          aResponse.from = from;
	        }
	      }
	
	      // The callback is always the last parameter.
	      var 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;
	
	    var 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.
	    var clients = [].concat(_toConsumableArray(this._clients.values()));
	    this._clients.clear();
	    var detachClients = () => {
	      var 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) {
	    var _this2 = this;
	
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    if (this._clients.has(aTabActor)) {
	      var _ret = function () {
	        var cachedTab = _this2._clients.get(aTabActor);
	        var cachedResponse = {
	          cacheDisabled: cachedTab.cacheDisabled,
	          javascriptEnabled: cachedTab.javascriptEnabled,
	          traits: cachedTab.traits
	        };
	        DevToolsUtils.executeSoon(() => aOnResponse(cachedResponse, cachedTab));
	        return {
	          v: promise.resolve([cachedResponse, cachedTab])
	        };
	      }();
	
	      if (typeof _ret === "object") return _ret.v;
	    }
	
	    var packet = {
	      to: aTabActor,
	      type: "attach"
	    };
	    return this.request(packet).then(aResponse => {
	      var tabClient = void 0;
	      if (!aResponse.error) {
	        tabClient = new TabClient(this, aResponse);
	        this.registerClient(tabClient);
	      }
	      aOnResponse(aResponse, tabClient);
	      return [aResponse, tabClient];
	    });
	  },
	
	  attachWorker: function DC_attachWorker(aWorkerActor) {
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    var workerClient = this._clients.get(aWorkerActor);
	    if (workerClient !== undefined) {
	      var _ret2 = function () {
	        var response = {
	          from: workerClient.actor,
	          type: "attached",
	          url: workerClient.url
	        };
	        DevToolsUtils.executeSoon(() => aOnResponse(response, workerClient));
	        return {
	          v: promise.resolve([response, workerClient])
	        };
	      }();
	
	      if (typeof _ret2 === "object") return _ret2.v;
	    }
	
	    return this.request({ to: aWorkerActor, type: "attach" }).then(aResponse => {
	      if (aResponse.error) {
	        aOnResponse(aResponse, null);
	        return [aResponse, null];
	      }
	
	      var 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) {
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    var packet = {
	      to: aAddonActor,
	      type: "attach"
	    };
	    return this.request(packet).then(aResponse => {
	      var addonClient = void 0;
	      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) {
	    var aOnResponse = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
	
	    var packet = {
	      to: aConsoleActor,
	      type: "startListeners",
	      listeners: aListeners
	    };
	
	    return this.request(packet).then(aResponse => {
	      var consoleClient = void 0;
	      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) {
	    var _this3 = this;
	
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	    var aOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
	
	    if (this._clients.has(aThreadActor)) {
	      var _ret3 = function () {
	        var client = _this3._clients.get(aThreadActor);
	        DevToolsUtils.executeSoon(() => aOnResponse({}, client));
	        return {
	          v: promise.resolve([{}, client])
	        };
	      }();
	
	      if (typeof _ret3 === "object") return _ret3.v;
	    }
	
	    var 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) {
	    var _this4 = this;
	
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    if (this._clients.has(aTraceActor)) {
	      var _ret4 = function () {
	        var client = _this4._clients.get(aTraceActor);
	        DevToolsUtils.executeSoon(() => aOnResponse({}, client));
	        return {
	          v: promise.resolve([{}, client])
	        };
	      }();
	
	      if (typeof _ret4 === "object") return _ret4.v;
	    }
	
	    var 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) {
	    var 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.");
	    }
	    var type = aRequest.type || "";
	    if (!aRequest.to) {
	      throw Error("'" + type + "' request packet has no destination.");
	    }
	    if (this._closed) {
	      var msg = "'" + type + "' request packet to " + "'" + aRequest.to + "' " + "can't be sent as the connection is closed.";
	      var resp = { error: "connectionClosed", message: msg };
	      if (aOnResponse) {
	        aOnResponse(resp);
	      }
	      return promise.reject(resp);
	    }
	
	    var 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
	    var 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) {
	    var 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) {
	    var actor = request.actor;
	    this.expectReply(actor, request);
	
	    if (request.format === "json") {
	      this._transport.send(request.request);
	      return false;
	    }
	
	    this._transport.startBulkSend(request.request).then(function () {
	      for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
	        args[_key3] = arguments[_key3];
	      }
	
	      request.emit.apply(request, ["bulk-send-ready"].concat(args));
	    });
	  },
	
	  /**
	   * Queue a request to be sent later.  Queues are only drained when an in
	   * flight request to a given actor completes.
	   */
	  _queueRequest(request) {
	    var actor = request.actor;
	    var 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;
	    }
	    var queue = this._pendingRequests.get(actor);
	    if (!queue) {
	      return;
	    }
	    var 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") {
	      var 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.
	    var front = this.getActor(aPacket.from);
	    if (front) {
	      front.onPacket(aPacket);
	      return;
	    }
	
	    if (this._clients.has(aPacket.from) && aPacket.type) {
	      var client = this._clients.get(aPacket.from);
	      var 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;
	      }
	    }
	
	    var activeRequest = void 0;
	    // 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) {
	        var thread = this._clients.get(aPacket.from).thread;
	        var 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) {
	      var 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) {
	    var actor = packet.actor;
	    var type = packet.type;
	    var length = packet.length;
	
	
	    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;
	    }
	
	    var 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
	    var 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.
	      var msg = void 0;
	      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.";
	      }
	      var packet = { error: "connectionClosed", message: msg };
	      request.emit("json-reply", packet);
	    };
	
	    var pendingRequests = new Map(this._pendingRequests);
	    this._pendingRequests.clear();
	    pendingRequests.forEach((list, actor) => {
	      list.forEach(request => reject("pending", request, actor));
	    });
	    var 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 (var pool of this._pools) {
	      pool.cleanup();
	    }
	  },
	
	  registerClient: function (client) {
	    var 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) {
	    var 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) {
	    var pool = this.poolFor(actorID);
	    return pool ? pool.get(actorID) : null;
	  },
	
	  poolFor: function (actorID) {
	    for (var 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) {
	    for (var _len4 = arguments.length, args = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
	      args[_key4 - 1] = arguments[_key4];
	    }
	
	    events.emit.apply(events, [this, type].concat(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 () {
	    var aOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    if (this.thread) {
	      DevToolsUtils.executeSoon(() => aOnResponse({}, this.thread));
	      return promise.resolve([{}, this.thread]);
	    }
	
	    var 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 () {
	    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { 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 () {
	    var _this5 = this;
	
	    var aOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    if (this.thread) {
	      var _ret5 = function () {
	        var response = [{
	          type: "connected",
	          threadActor: _this5.thread._actor,
	          consoleActor: _this5.consoleActor
	        }, _this5.thread];
	        DevToolsUtils.executeSoon(() => aOnResponse(response));
	        return {
	          v: response
	        };
	      }();
	
	      if (typeof _ret5 === "object") return _ret5.v;
	    }
	
	    // 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) {
	    var 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) {
	        var browser = aFilter.tab.linkedBrowser;
	        if (browser.frameLoader.tabParent) {
	          // Tabs in child process
	          packet.tabId = browser.frameLoader.tabParent.tabId;
	        } else {
	          // Tabs in parent process
	          var 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) {
	    var aOnResponse = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 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) {
	    var onResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 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) {
	    var aCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    this._assertPaused("fillFrames");
	    if (this._frameCache.length >= aTotal) {
	      return false;
	    }
	
	    var numFrames = this._frameCache.length;
	
	    this.getFrames(numFrames, aTotal - numFrames, aResponse => {
	      if (aResponse.error) {
	        aCallback(aResponse);
	        return;
	      }
	
	      var threadGrips = DevToolsUtils.values(this._threadGrips);
	
	      for (var i in aResponse.frames) {
	        var frame = aResponse.frames[i];
	        if (!frame.where.source) {
	          // Older servers use urls instead, so we need to resolve
	          // them to source actors
	          for (var 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];
	    }
	
	    var 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];
	    }
	
	    var 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 (var 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:[<parameterName>, ...] }
	   *        where each <parameterName> 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 () {
	    var cb = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
	
	    var 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 () {
	    var aCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
	
	    var 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) {
	    var aCallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    var 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 () {
	    var aCallback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : noop;
	
	    var 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;
	    }
	
	    var contentType = aResponse.contentType;
	    var source = aResponse.source;
	
	    var longString = this._activeThread.threadLongString(source);
	    return longString.substring(0, longString.length).then(function (aResponse) {
	      if (aResponse.error) {
	        aCallback(aResponse);
	        return aReponse;
	      }
	
	      var 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 (_ref) {
	    var line = _ref.line;
	    var column = _ref.column;
	    var condition = _ref.condition;
	    var noSliding = _ref.noSliding;
	    var aOnResponse = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noop;
	
	    // A helper function that sets the breakpoint.
	    var doSetBreakpoint = aCallback => {
	      var root = this._client.mainRoot;
	      var location = {
	        line: line,
	        column: column
	      };
	
	      var 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.
	        var bpClient = void 0;
	        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;
	      }
	
	      var type = aResponse.type;
	      var why = aResponse.why;
	
	      var 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 () {
	    var 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 () {
	    var 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) {
	    var _this6 = this;
	
	    var root = this._client.mainRoot;
	    var deferred = promise.defer();
	
	    if (root.traits.conditionalBreakpoints) {
	      (function () {
	        var info = {
	          line: _this6.location.line,
	          column: _this6.location.column,
	          condition: aCondition,
	          noSliding
	        };
	
	        // Remove the current breakpoint and add a new one with the
	        // condition.
	        _this6.remove(aResponse => {
	          if (aResponse && aResponse.error) {
	            deferred.reject(aResponse);
	            return;
	          }
	
	          _this6.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);

/***/ },
/* 80 */
/***/ 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"
	};
	
	var UNCAUGHT_ERROR = 'An error event was emitted for which there was no listener.';
	var BAD_LISTENER = 'The event listener must be a function.';
	
	var _require = __webpack_require__(81);
	
	var ns = _require.ns;
	
	
	var event = ns();
	
	var 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.
	var observers = function observers(target, type) {
	  if (!target) throw TypeError("Event target must be an object");
	  var 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);
	
	  var 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) {
	  var replacement = function observer() {
	    off(target, type, observer);
	    onceWeakMap.delete(listener);
	
	    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	      args[_key] = arguments[_key];
	    }
	
	    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) {
	  for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
	    args[_key2 - 2] = arguments[_key2];
	  }
	
	  emitOnObject.apply(undefined, [target, type, target].concat(args));
	}
	exports.emit = emit;
	
	/**
	 * A variant of emit that allows setting the this property for event listeners
	 */
	function emitOnObject(target, type, thisArg) {
	  var all = observers(target, '*').length;
	  var state = observers(target, type);
	  var listeners = state.slice();
	  var count = listeners.length;
	  var index = 0;
	
	  // If error event and there are no handlers (explicit or catch-all)
	  // then print error message to the console.
	
	  for (var _len3 = arguments.length, args = Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {
	    args[_key3 - 3] = arguments[_key3];
	  }
	
	  if (count === 0 && type === 'error' && all === 0) console.exception(args[0]);
	  while (index < count) {
	    try {
	      var 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.apply(undefined, [target, '*', type].concat(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) {
	  var length = arguments.length;
	  if (length === 3) {
	    if (onceWeakMap.has(listener)) {
	      listener = onceWeakMap.get(listener);
	      onceWeakMap.delete(listener);
	    }
	
	    var listeners = observers(target, type);
	    var index = listeners.indexOf(listener);
	    if (~index) listeners.splice(index, 1);
	  } else if (length === 2) {
	    observers(target, type).splice(0);
	  } else if (length === 1) {
	    (function () {
	      var 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 => {
	    var match = EVENT_TYPE_PATTERN.exec(key);
	    var type = match && match[1].toLowerCase();
	    if (!type) return;
	
	    var listener = listeners[key];
	    if (typeof listener === 'function') on(target, type, listener);
	  });
	}
	exports.setListeners = setListeners;
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(77)(module)))

/***/ },
/* 81 */
/***/ 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"
	};
	
	var create = Object.create;
	var 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() {
	  var 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__(77)(module)))

/***/ },
/* 82 */
/***/ 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";
	
	var _require = __webpack_require__(61);
	
	var Cc = _require.Cc;
	var Ci = _require.Ci;
	var Cu = _require.Cu;
	
	var DevToolsUtils = __webpack_require__(68);
	var EventEmitter = __webpack_require__(60);
	var promise = __webpack_require__(66);
	
	var _require2 = __webpack_require__(79);
	
	var LongStringClient = _require2.LongStringClient;
	
	/**
	 * 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) {
	      var actor = packet.eventActor;
	      var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var aOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
	
	    var 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) {
	    var aOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
	
	    // Pre-37 servers don't support async evaluation.
	    if (!this.traits.evaluateJSAsync) {
	      this.evaluateJS(aString, aOnResponse, aOptions);
	      return;
	    }
	
	    var 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.
	    var 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) {
	    var 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() {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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) {
	    var 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];
	    }
	
	    var 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;
	    }
	
	    var deferred = stringGrip._fullText = promise.defer();
	    var actor = stringGrip.actor;
	    var initial = stringGrip.initial;
	    var length = stringGrip.length;
	
	    var 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;
	  }
	};

/***/ },
/* 83 */
/***/ 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__(30);
	const EventEmitter = __webpack_require__(60);
	
	/**
	 * 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;


/***/ },
/* 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/. */
	
	var promise = __webpack_require__(66);
	var EventEmitter = __webpack_require__(60);
	
	/* const { DebuggerServer } = require("../../server/main");*/
	
	var _require = __webpack_require__(79);
	
	var DebuggerClient = _require.DebuggerClient;
	
	
	var targets = new WeakMap();
	var 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) {
	    var 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) {
	    var targetPromise = promiseTargets.get(options);
	    if (targetPromise == null) {
	      (function () {
	        var target = new TabTarget(options);
	        targetPromise = target.makeRemote().then(() => target);
	        promiseTargets.set(options, targetPromise);
	      })();
	    }
	    return targetPromise;
	  },
	
	  forWorker: function (workerClient) {
	    var 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.");
	    }
	
	    var 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();
	
	    var 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();
	      });
	    };
	
	    var onConsoleAttached = (response, consoleClient) => {
	      if (!consoleClient) {
	        this._remote.reject("Unable to attach to the console");
	        return;
	      }
	      this.activeConsole = consoleClient;
	      this._remote.resolve(null);
	    };
	
	    var 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) => {
	      var 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();
	    }
	
	    var 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 () {
	    var 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();
	  }
	};

/***/ },
/* 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";
	
	var EventEmitter = __webpack_require__(60);
	
	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(_ref) {
	    var data = _ref.data;
	
	    if (typeof data !== "string") {
	      throw new Error("Binary messages are not supported by WebSocket transport");
	    }
	
	    var object = JSON.parse(data);
	    this.emit("packet", object);
	    if (this.hooks) {
	      this.hooks.onPacket(object);
	    }
	  }
	};
	
	module.exports = WebSocketDebuggerTransport;

/***/ },
/* 86 */
/***/ 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";
	
	var EventEmitter = __webpack_require__(60);
	
	/**
	 * 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() {
	  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	
	  var _ref$id = _ref.id;
	  var id = _ref$id === undefined ? null : _ref$id;
	
	  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) {
	  var doc = toolbox.doc;
	  var 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.
	  var 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) {
	  var doc = parent.ownerDocument;
	  this.menuitems.forEach(item => {
	    if (!item.visible) {
	      return;
	    }
	
	    if (item.submenu) {
	      var menupopup = doc.createElement("menupopup");
	      item.submenu._createMenuItems(menupopup);
	
	      var 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") {
	      var menusep = doc.createElement("menuseparator");
	      parent.appendChild(menusep);
	    } else {
	      var 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;

/***/ },
/* 87 */
/***/ 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() {
	  var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	
	  var _ref$accesskey = _ref.accesskey;
	  var accesskey = _ref$accesskey === undefined ? null : _ref$accesskey;
	  var _ref$checked = _ref.checked;
	  var checked = _ref$checked === undefined ? false : _ref$checked;
	  var _ref$click = _ref.click;
	  var click = _ref$click === undefined ? () => {} : _ref$click;
	  var _ref$disabled = _ref.disabled;
	  var disabled = _ref$disabled === undefined ? false : _ref$disabled;
	  var _ref$label = _ref.label;
	  var label = _ref$label === undefined ? "" : _ref$label;
	  var _ref$id = _ref.id;
	  var id = _ref$id === undefined ? null : _ref$id;
	  var _ref$submenu = _ref.submenu;
	  var submenu = _ref$submenu === undefined ? null : _ref$submenu;
	  var _ref$type = _ref.type;
	  var type = _ref$type === undefined ? "normal" : _ref$type;
	  var _ref$visible = _ref.visible;
	  var visible = _ref$visible === undefined ? true : _ref$visible;
	
	  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;

/***/ },
/* 88 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(89);
	
	var isDevelopment = _require.isDevelopment;
	var isTesting = _require.isTesting;
	
	
	function debugGlobal(field, value) {
	  if (isDevelopment() || isTesting()) {
	    window[field] = value;
	  }
	}
	
	function injectGlobals(_ref) {
	  var store = _ref.store;
	
	  debugGlobal("store", store);
	  debugGlobal("injectDebuggee", __webpack_require__(140));
	  debugGlobal("serializeStore", () => {
	    return JSON.parse(JSON.stringify(store.getState()));
	  });
	}
	
	module.exports = {
	  debugGlobal,
	  injectGlobals
	};

/***/ },
/* 89 */
/***/ function(module, exports, __webpack_require__) {

	var feature = __webpack_require__(90);
	
	module.exports = feature;

/***/ },
/* 90 */
/***/ function(module, exports, __webpack_require__) {

	var pick = __webpack_require__(91);
	var config = void 0;
	
	var flag = __webpack_require__(139);
	
	/**
	 * 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[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 isFirefox() {
	  return (/firefox/i.test(navigator.userAgent)
	  );
	}
	
	function setConfig(value) {
	  config = value;
	}
	
	function getConfig() {
	  return config;
	}
	
	module.exports = {
	  isEnabled,
	  getValue,
	  isDevelopment,
	  isTesting,
	  isFirefoxPanel,
	  isFirefox,
	  getConfig,
	  setConfig
	};

/***/ },
/* 91 */
/***/ function(module, exports, __webpack_require__) {

	var baseGet = __webpack_require__(92);
	
	/**
	 * 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;


/***/ },
/* 92 */
/***/ function(module, exports, __webpack_require__) {

	var castPath = __webpack_require__(93),
	    isKey = __webpack_require__(137),
	    toKey = __webpack_require__(138);
	
	/**
	 * 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 = isKey(path, object) ? [path] : castPath(path);
	
	  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;


/***/ },
/* 93 */
/***/ function(module, exports, __webpack_require__) {

	var isArray = __webpack_require__(94),
	    stringToPath = __webpack_require__(95);
	
	/**
	 * Casts `value` to a path array if it's not one.
	 *
	 * @private
	 * @param {*} value The value to inspect.
	 * @returns {Array} Returns the cast property path array.
	 */
	function castPath(value) {
	  return isArray(value) ? value : stringToPath(value);
	}
	
	module.exports = castPath;


/***/ },
/* 94 */
/***/ 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;


/***/ },
/* 95 */
/***/ function(module, exports, __webpack_require__) {

	var memoizeCapped = __webpack_require__(96),
	    toString = __webpack_require__(132);
	
	/** 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) {
	  string = toString(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;


/***/ },
/* 96 */
/***/ function(module, exports, __webpack_require__) {

	var memoize = __webpack_require__(97);
	
	/** 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;


/***/ },
/* 97 */
/***/ function(module, exports, __webpack_require__) {

	var MapCache = __webpack_require__(98);
	
	/** 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 `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 && 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;


/***/ },
/* 98 */
/***/ function(module, exports, __webpack_require__) {

	var mapCacheClear = __webpack_require__(99),
	    mapCacheDelete = __webpack_require__(126),
	    mapCacheGet = __webpack_require__(129),
	    mapCacheHas = __webpack_require__(130),
	    mapCacheSet = __webpack_require__(131);
	
	/**
	 * 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 ? entries.length : 0;
	
	  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;


/***/ },
/* 99 */
/***/ function(module, exports, __webpack_require__) {

	var Hash = __webpack_require__(100),
	    ListCache = __webpack_require__(117),
	    Map = __webpack_require__(125);
	
	/**
	 * 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;


/***/ },
/* 100 */
/***/ function(module, exports, __webpack_require__) {

	var hashClear = __webpack_require__(101),
	    hashDelete = __webpack_require__(113),
	    hashGet = __webpack_require__(114),
	    hashHas = __webpack_require__(115),
	    hashSet = __webpack_require__(116);
	
	/**
	 * Creates a hash object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function Hash(entries) {
	  var index = -1,
	      length = entries ? entries.length : 0;
	
	  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;


/***/ },
/* 101 */
/***/ function(module, exports, __webpack_require__) {

	var nativeCreate = __webpack_require__(102);
	
	/**
	 * 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;


/***/ },
/* 102 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103);
	
	/* Built-in method references that are verified to be native. */
	var nativeCreate = getNative(Object, 'create');
	
	module.exports = nativeCreate;


/***/ },
/* 103 */
/***/ function(module, exports, __webpack_require__) {

	var baseIsNative = __webpack_require__(104),
	    getValue = __webpack_require__(112);
	
	/**
	 * 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;


/***/ },
/* 104 */
/***/ function(module, exports, __webpack_require__) {

	var isFunction = __webpack_require__(105),
	    isMasked = __webpack_require__(107),
	    isObject = __webpack_require__(106),
	    toSource = __webpack_require__(111);
	
	/**
	 * 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;


/***/ },
/* 105 */
/***/ function(module, exports, __webpack_require__) {

	var isObject = __webpack_require__(106);
	
	/** `Object#toString` result references. */
	var funcTag = '[object Function]',
	    genTag = '[object GeneratorFunction]',
	    proxyTag = '[object Proxy]';
	
	/** 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 objectToString = objectProto.toString;
	
	/**
	 * 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) {
	  // The use of `Object#toString` avoids issues with the `typeof` operator
	  // in Safari 9 which returns 'object' for typed array and other constructors.
	  var tag = isObject(value) ? objectToString.call(value) : '';
	  return tag == funcTag || tag == genTag || tag == proxyTag;
	}
	
	module.exports = isFunction;


/***/ },
/* 106 */
/***/ 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;


/***/ },
/* 107 */
/***/ function(module, exports, __webpack_require__) {

	var coreJsData = __webpack_require__(108);
	
	/** 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;


/***/ },
/* 108 */
/***/ function(module, exports, __webpack_require__) {

	var root = __webpack_require__(109);
	
	/** Used to detect overreaching core-js shims. */
	var coreJsData = root['__core-js_shared__'];
	
	module.exports = coreJsData;


/***/ },
/* 109 */
/***/ function(module, exports, __webpack_require__) {

	var freeGlobal = __webpack_require__(110);
	
	/** 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;


/***/ },
/* 110 */
/***/ 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; }())))

/***/ },
/* 111 */
/***/ 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 process.
	 * @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;


/***/ },
/* 112 */
/***/ 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;


/***/ },
/* 113 */
/***/ 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;


/***/ },
/* 114 */
/***/ function(module, exports, __webpack_require__) {

	var nativeCreate = __webpack_require__(102);
	
	/** 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;


/***/ },
/* 115 */
/***/ function(module, exports, __webpack_require__) {

	var nativeCreate = __webpack_require__(102);
	
	/** 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;


/***/ },
/* 116 */
/***/ function(module, exports, __webpack_require__) {

	var nativeCreate = __webpack_require__(102);
	
	/** 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;


/***/ },
/* 117 */
/***/ function(module, exports, __webpack_require__) {

	var listCacheClear = __webpack_require__(118),
	    listCacheDelete = __webpack_require__(119),
	    listCacheGet = __webpack_require__(122),
	    listCacheHas = __webpack_require__(123),
	    listCacheSet = __webpack_require__(124);
	
	/**
	 * Creates an list cache object.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function ListCache(entries) {
	  var index = -1,
	      length = entries ? entries.length : 0;
	
	  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;


/***/ },
/* 118 */
/***/ 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;


/***/ },
/* 119 */
/***/ function(module, exports, __webpack_require__) {

	var assocIndexOf = __webpack_require__(120);
	
	/** 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;


/***/ },
/* 120 */
/***/ function(module, exports, __webpack_require__) {

	var eq = __webpack_require__(121);
	
	/**
	 * 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;


/***/ },
/* 121 */
/***/ 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;


/***/ },
/* 122 */
/***/ function(module, exports, __webpack_require__) {

	var assocIndexOf = __webpack_require__(120);
	
	/**
	 * 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;


/***/ },
/* 123 */
/***/ function(module, exports, __webpack_require__) {

	var assocIndexOf = __webpack_require__(120);
	
	/**
	 * 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;


/***/ },
/* 124 */
/***/ function(module, exports, __webpack_require__) {

	var assocIndexOf = __webpack_require__(120);
	
	/**
	 * 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;


/***/ },
/* 125 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103),
	    root = __webpack_require__(109);
	
	/* Built-in method references that are verified to be native. */
	var Map = getNative(root, 'Map');
	
	module.exports = Map;


/***/ },
/* 126 */
/***/ function(module, exports, __webpack_require__) {

	var getMapData = __webpack_require__(127);
	
	/**
	 * 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;


/***/ },
/* 127 */
/***/ function(module, exports, __webpack_require__) {

	var isKeyable = __webpack_require__(128);
	
	/**
	 * 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;


/***/ },
/* 128 */
/***/ 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;


/***/ },
/* 129 */
/***/ function(module, exports, __webpack_require__) {

	var getMapData = __webpack_require__(127);
	
	/**
	 * 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;


/***/ },
/* 130 */
/***/ function(module, exports, __webpack_require__) {

	var getMapData = __webpack_require__(127);
	
	/**
	 * 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;


/***/ },
/* 131 */
/***/ function(module, exports, __webpack_require__) {

	var getMapData = __webpack_require__(127);
	
	/**
	 * 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;


/***/ },
/* 132 */
/***/ function(module, exports, __webpack_require__) {

	var baseToString = __webpack_require__(133);
	
	/**
	 * 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;


/***/ },
/* 133 */
/***/ function(module, exports, __webpack_require__) {

	var Symbol = __webpack_require__(134),
	    arrayMap = __webpack_require__(135),
	    isArray = __webpack_require__(94),
	    isSymbol = __webpack_require__(136);
	
	/** 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;


/***/ },
/* 134 */
/***/ function(module, exports, __webpack_require__) {

	var root = __webpack_require__(109);
	
	/** Built-in value references. */
	var Symbol = root.Symbol;
	
	module.exports = Symbol;


/***/ },
/* 135 */
/***/ 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 ? array.length : 0,
	      result = Array(length);
	
	  while (++index < length) {
	    result[index] = iteratee(array[index], index, array);
	  }
	  return result;
	}
	
	module.exports = arrayMap;


/***/ },
/* 136 */
/***/ function(module, exports, __webpack_require__) {

	var isObjectLike = __webpack_require__(8);
	
	/** `Object#toString` result references. */
	var symbolTag = '[object Symbol]';
	
	/** 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 objectToString = objectProto.toString;
	
	/**
	 * 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) && objectToString.call(value) == symbolTag);
	}
	
	module.exports = isSymbol;


/***/ },
/* 137 */
/***/ function(module, exports, __webpack_require__) {

	var isArray = __webpack_require__(94),
	    isSymbol = __webpack_require__(136);
	
	/** 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;


/***/ },
/* 138 */
/***/ function(module, exports, __webpack_require__) {

	var isSymbol = __webpack_require__(136);
	
	/** 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;


/***/ },
/* 139 */
/***/ function(module, exports) {

	module.exports = devtoolsRequire("devtools/shared/flags");

/***/ },
/* 140 */
/***/ function(module, exports) {

	function Debuggee() {
	  function $(selector) {
	    var element = document.querySelector(selector);
	    console.log("$", selector, element);
	
	    if (!element) {
	      throw new Error("Element not found, try changing the selector");
	    }
	    return element;
	  }
	
	  function mouseEvent(eventType) {
	    return new MouseEvent(eventType, {
	      "view": window,
	      "bubbles": true,
	      "cancelable": true
	    });
	  }
	
	  var specialKeysMap = {
	    "{enter}": 13
	  };
	
	  // Special character examples {enter}, {esc}, {leftarrow} ..
	  function isSpecialCharacter(text) {
	    return text.match(/^\{.*\}$/);
	  }
	
	  function keyInfo(key, eventType) {
	    var charCodeAt = void 0;
	
	    if (key.length > 1) {
	      charCodeAt = specialKeysMap[key];
	    } else {
	      charCodeAt = key.toUpperCase().charCodeAt(0);
	    }
	
	    return {
	      charCode: eventType == "keypress" ? 0 : charCodeAt,
	      keyCode: charCodeAt,
	      which: charCodeAt
	    };
	  }
	
	  function keyEvent(eventType, key) {
	    var event = new Event(eventType, {
	      bubbles: true,
	      cancelable: false,
	      view: window
	    });
	
	    var _keyInfo = keyInfo(key, eventType);
	
	    var charCode = _keyInfo.charCode;
	    var keyCode = _keyInfo.keyCode;
	    var which = _keyInfo.which;
	
	
	    return Object.assign(event, {
	      charCode: charCode,
	      keyCode: keyCode,
	      which: which,
	      detail: 0,
	      layerX: 0,
	      layerY: 0,
	      pageX: 0,
	      pageY: 0
	    });
	  }
	
	  function sendKey(element, key) {
	    element.dispatchEvent(keyEvent("keydown", key));
	    element.dispatchEvent(keyEvent("keypress", key));
	    if (key.length == 1) {
	      element.value += key;
	    }
	    element.dispatchEvent(keyEvent("keyup", key));
	  }
	
	  function click(selector) {
	    var element = $(selector);
	    console.log("click", selector);
	    element.dispatchEvent(mouseEvent("click"));
	  }
	
	  function dblclick(selector) {
	    var element = $(selector);
	    console.log("dblclick", selector);
	    element.dispatchEvent(mouseEvent("dblclick"));
	  }
	
	  function type(selector, text) {
	    var element = $(selector);
	    console.log("type", selector, text);
	    element.select();
	
	    if (isSpecialCharacter(text)) {
	      sendKey(element, text);
	    } else {
	      var chars = text.split("");
	      chars.forEach(char => sendKey(element, char));
	    }
	  }
	
	  return {
	    click,
	    dblclick,
	    type
	  };
	}
	
	var debuggeeStatement = `window.dbg = (${ Debuggee })()`;
	var injectedDebuggee = void 0;
	
	function injectDebuggee() {
	  if (injectedDebuggee) {
	    return Promise.resolve(injectedDebuggee);
	  }
	
	  return window.client.debuggeeCommand(debuggeeStatement).then(result => {
	    injectedDebuggee = result;
	  });
	}
	
	module.exports = injectDebuggee;

/***/ },
/* 141 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(142);
	
	var Task = _require.Task;
	
	var firefox = __webpack_require__(143);
	var chrome = __webpack_require__(205);
	
	var _require2 = __webpack_require__(88);
	
	var debugGlobal = _require2.debugGlobal;
	
	
	var clientType = void 0;
	function getClient() {
	  if (clientType === "chrome") {
	    return chrome.clientCommands;
	  }
	
	  return firefox.clientCommands;
	}
	
	function startDebugging(connTarget, actions) {
	  if (connTarget.type === "node") {
	    return startDebuggingNode(connTarget.param, actions);
	  }
	
	  var target = connTarget.type === "chrome" ? chrome : firefox;
	  return startDebuggingTab(target, connTarget.param, actions);
	}
	
	function startDebuggingNode(url, actions) {
	  clientType = "chrome";
	  return chrome.connectNode(`ws://${ url }`).then(() => {
	    chrome.initPage(actions);
	  });
	}
	
	function startDebuggingTab(targetEnv, tabId, actions) {
	  return Task.spawn(function* () {
	    var tabs = yield targetEnv.connectClient();
	    var tab = tabs.find(t => t.id.indexOf(tabId) !== -1);
	    yield targetEnv.connectTab(tab.tab);
	    targetEnv.initPage(actions);
	
	    clientType = targetEnv === firefox ? "firefox" : "chrome";
	    debugGlobal("client", targetEnv.clientCommands);
	
	    return tabs;
	  });
	}
	
	function connectClients(onConnect) {
	  firefox.connectClient().then(onConnect);
	  chrome.connectClient().then(onConnect);
	}
	
	module.exports = {
	  getClient,
	  connectClients,
	  startDebugging,
	  firefox,
	  chrome
	};

/***/ },
/* 142 */
/***/ function(module, exports) {

	/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
	/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	/**
	 * This object provides the public module functions.
	 */
	var Task = {
	  // XXX: Not sure if this works in all cases...
	  async: function (task) {
	    return function () {
	      return Task.spawn(task, this, arguments);
	    };
	  },
	
	  /**
	   * Creates and starts a new task.
	   * @param task A generator function
	   * @return A promise, resolved when the task terminates
	   */
	  spawn: function (task, scope, args) {
	    return new Promise(function (resolve, reject) {
	      var iterator = task.apply(scope, args);
	
	      var callNext = lastValue => {
	        var iteration = iterator.next(lastValue);
	        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 };

/***/ },
/* 143 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(28);
	
	var DebuggerClient = _require.DebuggerClient;
	var DebuggerTransport = _require.DebuggerTransport;
	var TargetFactory = _require.TargetFactory;
	var WebsocketTransport = _require.WebsocketTransport;
	
	var defer = __webpack_require__(144);
	
	var _require2 = __webpack_require__(89);
	
	var getValue = _require2.getValue;
	
	var _require3 = __webpack_require__(145);
	
	var Tab = _require3.Tab;
	
	var _require4 = __webpack_require__(202);
	
	var setupCommands = _require4.setupCommands;
	var clientCommands = _require4.clientCommands;
	
	var _require5 = __webpack_require__(203);
	
	var setupEvents = _require5.setupEvents;
	var clientEvents = _require5.clientEvents;
	
	var _require6 = __webpack_require__(204);
	
	var createSource = _require6.createSource;
	
	
	var debuggerClient = null;
	var threadClient = null;
	var tabTarget = null;
	
	function getThreadClient() {
	  return threadClient;
	}
	
	function setThreadClient(client) {
	  threadClient = client;
	}
	
	function getTabTarget() {
	  return tabTarget;
	}
	
	function setTabTarget(target) {
	  tabTarget = target;
	}
	
	function lookupTabTarget(tab) {
	  var options = { client: debuggerClient, form: tab, chrome: false };
	  return TargetFactory.forRemoteTab(options);
	}
	
	function createTabs(tabs) {
	  return tabs.map(tab => {
	    return Tab({
	      title: tab.title,
	      url: tab.url,
	      id: tab.actor,
	      tab,
	      browser: "firefox"
	    });
	  });
	}
	
	function connectClient() {
	  var deferred = defer();
	  var useProxy = !getValue("firefox.webSocketConnection");
	  var portPref = useProxy ? "firefox.proxyPort" : "firefox.webSocketPort";
	  var webSocketPort = getValue(portPref);
	
	  var socket = new WebSocket(`ws://${ document.location.hostname }:${ webSocketPort }`);
	  var 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 });
	
	  tabTarget.on("will-navigate", actions.willNavigate);
	  tabTarget.on("navigate", actions.navigated);
	
	  // Listen to all the requested events.
	  setupEvents({ threadClient, actions });
	  Object.keys(clientEvents).forEach(eventName => {
	    threadClient.addListener(eventName, clientEvents[eventName]);
	  });
	
	  // In Firefox, we need to initially request all of the sources. This
	  // usually fires off individual `newSource` notifications as the
	  // debugger finds them, but there may be existing sources already in
	  // the debugger (if it's paused already, or if loading the page from
	  // bfcache) so explicity fire `newSource` events for all returned
	  // sources.
	  return threadClient.getSources().then((_ref) => {
	    var sources = _ref.sources;
	
	    actions.newSources(sources.map(createSource));
	
	    // If the threadClient is already paused, make sure to show a
	    // paused state.
	    var pausedPacket = threadClient.getLastPausePacket();
	    if (pausedPacket) {
	      clientEvents.paused(null, pausedPacket);
	    }
	  });
	}
	
	module.exports = {
	  connectClient,
	  connectTab,
	  clientCommands,
	  getThreadClient,
	  setThreadClient,
	  getTabTarget,
	  setTabTarget,
	  initPage
	};

/***/ },
/* 144 */
/***/ function(module, exports) {

	module.exports = function defer() {
	  var resolve = void 0,
	      reject = void 0;
	  var promise = new Promise(function () {
	    resolve = arguments[0];
	    reject = arguments[1];
	  });
	  return {
	    resolve: resolve,
	    reject: reject,
	    promise: promise
	  };
	};

/***/ },
/* 145 */
/***/ function(module, exports, __webpack_require__) {

	var t = __webpack_require__(146);
	
	var Tab = t.struct({
	  title: t.String,
	  url: t.String,
	  id: t.String,
	  tab: t.Object,
	  browser: t.enums.of(["chrome", "firefox"])
	}, "Tab");
	
	var SourceText = t.struct({
	  text: t.String,
	  contentType: t.String
	});
	
	var Source = t.struct({
	  id: t.String,
	  url: t.union([t.String, t.Nil]),
	  isPrettyPrinted: t.Boolean,
	  sourceMapURL: t.union([t.String, t.Nil])
	}, "Source");
	
	var Location = t.struct({
	  sourceId: t.String,
	  line: t.Number,
	  column: t.union([t.Number, t.Nil])
	}, "Location");
	
	var Breakpoint = t.struct({
	  id: t.String,
	  loading: t.Boolean,
	  disabled: t.Boolean,
	  text: t.String,
	  condition: t.union([t.String, t.Nil])
	});
	
	var BreakpointResult = t.struct({
	  id: t.String,
	  actualLocation: Location
	});
	
	var 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])
	}, "Frame");
	
	module.exports = {
	  Tab,
	  Source,
	  SourceText,
	  Location,
	  Breakpoint,
	  BreakpointResult,
	  Frame
	};

/***/ },
/* 146 */
/***/ 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__(147);
	
	// types
	t.Any = __webpack_require__(153);
	t.Array = __webpack_require__(161);
	t.Boolean = __webpack_require__(162);
	t.Date = __webpack_require__(164);
	t.Error = __webpack_require__(165);
	t.Function = __webpack_require__(166);
	t.Nil = __webpack_require__(167);
	t.Number = __webpack_require__(168);
	t.Integer = __webpack_require__(170);
	t.IntegerT = t.Integer;
	t.Object = __webpack_require__(176);
	t.RegExp = __webpack_require__(177);
	t.String = __webpack_require__(178);
	t.Type = __webpack_require__(179);
	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__(180);
	t.declare = __webpack_require__(181);
	t.enums = __webpack_require__(184);
	t.irreducible = __webpack_require__(154);
	t.list = __webpack_require__(185);
	t.maybe = __webpack_require__(186);
	t.refinement = __webpack_require__(171);
	t.struct = __webpack_require__(188);
	t.tuple = __webpack_require__(194);
	t.union = __webpack_require__(195);
	t.func = __webpack_require__(196);
	t.intersection = __webpack_require__(197);
	t.subtype = t.refinement;
	t.inter = __webpack_require__(198); // IE8 alias
	t['interface'] = t.inter;
	
	// functions
	t.assert = t;
	t.update = __webpack_require__(200);
	t.mixin = __webpack_require__(182);
	t.isType = __webpack_require__(158);
	t.is = __webpack_require__(175);
	t.getTypeName = __webpack_require__(157);
	t.match = __webpack_require__(201);
	
	module.exports = t;


/***/ },
/* 147 */
/***/ function(module, exports, __webpack_require__) {

	var isFunction = __webpack_require__(148);
	var isNil = __webpack_require__(149);
	var fail = __webpack_require__(150);
	var stringify = __webpack_require__(151);
	
	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;

/***/ },
/* 148 */
/***/ function(module, exports) {

	module.exports = function isFunction(x) {
	  return typeof x === 'function';
	};

/***/ },
/* 149 */
/***/ function(module, exports) {

	module.exports = function isNil(x) {
	  return x === null || x === void 0;
	};

/***/ },
/* 150 */
/***/ function(module, exports) {

	module.exports = function fail(message) {
	  throw new TypeError('[tcomb] ' + message);
	};

/***/ },
/* 151 */
/***/ function(module, exports, __webpack_require__) {

	var getFunctionName = __webpack_require__(152);
	
	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);
	  }
	};

/***/ },
/* 152 */
/***/ function(module, exports) {

	module.exports = function getFunctionName(f) {
	  return f.displayName || f.name || '<function' + f.length + '>';
	};

/***/ },
/* 153 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	
	module.exports = irreducible('Any', function () { return true; });


/***/ },
/* 154 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isString = __webpack_require__(155);
	var isFunction = __webpack_require__(148);
	var forbidNewOperator = __webpack_require__(156);
	
	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;
	};


/***/ },
/* 155 */
/***/ function(module, exports) {

	module.exports = function isString(x) {
	  return typeof x === 'string';
	};

/***/ },
/* 156 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var getTypeName = __webpack_require__(157);
	
	module.exports = function forbidNewOperator(x, type) {
	  assert(!(x instanceof type), function () { return 'Cannot use the new operator to instantiate the type ' + getTypeName(type); });
	};

/***/ },
/* 157 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	var getFunctionName = __webpack_require__(152);
	
	module.exports = function getTypeName(ctor) {
	  if (isType(ctor)) {
	    return ctor.displayName;
	  }
	  return getFunctionName(ctor);
	};

/***/ },
/* 158 */
/***/ function(module, exports, __webpack_require__) {

	var isFunction = __webpack_require__(148);
	var isObject = __webpack_require__(159);
	
	module.exports = function isType(x) {
	  return isFunction(x) && isObject(x.meta);
	};

/***/ },
/* 159 */
/***/ function(module, exports, __webpack_require__) {

	var isNil = __webpack_require__(149);
	var isArray = __webpack_require__(160);
	
	module.exports = function isObject(x) {
	  return !isNil(x) && typeof x === 'object' && !isArray(x);
	};

/***/ },
/* 160 */
/***/ function(module, exports) {

	module.exports = function isArray(x) {
	  return Array.isArray ? Array.isArray(x) : x instanceof Array;
	};

/***/ },
/* 161 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isArray = __webpack_require__(160);
	
	module.exports = irreducible('Array', isArray);


/***/ },
/* 162 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isBoolean = __webpack_require__(163);
	
	module.exports = irreducible('Boolean', isBoolean);


/***/ },
/* 163 */
/***/ function(module, exports) {

	module.exports = function isBoolean(x) {
	  return x === true || x === false;
	};

/***/ },
/* 164 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	
	module.exports = irreducible('Date', function (x) { return x instanceof Date; });


/***/ },
/* 165 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	
	module.exports = irreducible('Error', function (x) { return x instanceof Error; });


/***/ },
/* 166 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isFunction = __webpack_require__(148);
	
	module.exports = irreducible('Function', isFunction);


/***/ },
/* 167 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isNil = __webpack_require__(149);
	
	module.exports = irreducible('Nil', isNil);


/***/ },
/* 168 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isNumber = __webpack_require__(169);
	
	module.exports = irreducible('Number', isNumber);


/***/ },
/* 169 */
/***/ function(module, exports) {

	module.exports = function isNumber(x) {
	  return typeof x === 'number' && isFinite(x) && !isNaN(x);
	};

/***/ },
/* 170 */
/***/ function(module, exports, __webpack_require__) {

	var refinement = __webpack_require__(171);
	var Number = __webpack_require__(168);
	
	module.exports = refinement(Number, function (x) { return x % 1 === 0; }, 'Integer');


/***/ },
/* 171 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var forbidNewOperator = __webpack_require__(156);
	var isIdentity = __webpack_require__(173);
	var create = __webpack_require__(174);
	var is = __webpack_require__(175);
	var getTypeName = __webpack_require__(157);
	var getFunctionName = __webpack_require__(152);
	
	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;


/***/ },
/* 172 */
/***/ function(module, exports, __webpack_require__) {

	var isNil = __webpack_require__(149);
	var isString = __webpack_require__(155);
	
	module.exports = function isTypeName(name) {
	  return isNil(name) || isString(name);
	};

/***/ },
/* 173 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var Boolean = __webpack_require__(162);
	var isType = __webpack_require__(158);
	var getTypeName = __webpack_require__(157);
	
	// 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;
	};

/***/ },
/* 174 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	var getFunctionName = __webpack_require__(152);
	var assert = __webpack_require__(147);
	var stringify = __webpack_require__(151);
	
	// 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;
	};

/***/ },
/* 175 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	// 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
	};


/***/ },
/* 176 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isObject = __webpack_require__(159);
	
	module.exports = irreducible('Object', isObject);


/***/ },
/* 177 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	
	module.exports = irreducible('RegExp', function (x) { return x instanceof RegExp; });


/***/ },
/* 178 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isString = __webpack_require__(155);
	
	module.exports = irreducible('String', isString);


/***/ },
/* 179 */
/***/ function(module, exports, __webpack_require__) {

	var irreducible = __webpack_require__(154);
	var isType = __webpack_require__(158);
	
	module.exports = irreducible('Type', isType);

/***/ },
/* 180 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var getTypeName = __webpack_require__(157);
	var isIdentity = __webpack_require__(173);
	var isObject = __webpack_require__(159);
	var create = __webpack_require__(174);
	var is = __webpack_require__(175);
	
	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;


/***/ },
/* 181 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isType = __webpack_require__(158);
	var isNil = __webpack_require__(149);
	var mixin = __webpack_require__(182);
	var getTypeName = __webpack_require__(157);
	var isUnion = __webpack_require__(183);
	
	// 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;
	};


/***/ },
/* 182 */
/***/ function(module, exports, __webpack_require__) {

	var isNil = __webpack_require__(149);
	var assert = __webpack_require__(147);
	
	// 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;
	};

/***/ },
/* 183 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	module.exports = function isUnion(x) {
	  return isType(x) && ( x.meta.kind === 'union' );
	};

/***/ },
/* 184 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var forbidNewOperator = __webpack_require__(156);
	var isString = __webpack_require__(155);
	var isObject = __webpack_require__(159);
	
	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;
	


/***/ },
/* 185 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var getTypeName = __webpack_require__(157);
	var isIdentity = __webpack_require__(173);
	var create = __webpack_require__(174);
	var is = __webpack_require__(175);
	var isArray = __webpack_require__(160);
	
	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;


/***/ },
/* 186 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var isMaybe = __webpack_require__(187);
	var isIdentity = __webpack_require__(173);
	var Any = __webpack_require__(153);
	var create = __webpack_require__(174);
	var Nil = __webpack_require__(167);
	var forbidNewOperator = __webpack_require__(156);
	var is = __webpack_require__(175);
	var getTypeName = __webpack_require__(157);
	
	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;


/***/ },
/* 187 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	module.exports = function isMaybe(x) {
	  return isType(x) && ( x.meta.kind === 'maybe' );
	};

/***/ },
/* 188 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var String = __webpack_require__(178);
	var Function = __webpack_require__(166);
	var isBoolean = __webpack_require__(163);
	var isObject = __webpack_require__(159);
	var isNil = __webpack_require__(149);
	var create = __webpack_require__(174);
	var getTypeName = __webpack_require__(157);
	var dict = __webpack_require__(180);
	var getDefaultInterfaceName = __webpack_require__(189);
	var extend = __webpack_require__(190);
	
	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;


/***/ },
/* 189 */
/***/ function(module, exports, __webpack_require__) {

	var getTypeName = __webpack_require__(157);
	
	function getDefaultInterfaceName(props) {
	  return '{' + Object.keys(props).map(function (prop) {
	    return prop + ': ' + getTypeName(props[prop]);
	  }).join(', ') + '}';
	}
	
	module.exports = getDefaultInterfaceName;


/***/ },
/* 190 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isFunction = __webpack_require__(148);
	var isArray = __webpack_require__(160);
	var mixin = __webpack_require__(182);
	var isStruct = __webpack_require__(191);
	var isInterface = __webpack_require__(192);
	var isObject = __webpack_require__(159);
	var refinement = __webpack_require__(171);
	var decompose = __webpack_require__(193);
	
	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;

/***/ },
/* 191 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	module.exports = function isStruct(x) {
	  return isType(x) && ( x.meta.kind === 'struct' );
	};

/***/ },
/* 192 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	module.exports = function isInterface(x) {
	  return isType(x) && ( x.meta.kind === 'interface' );
	};

/***/ },
/* 193 */
/***/ function(module, exports, __webpack_require__) {

	var isType = __webpack_require__(158);
	
	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;

/***/ },
/* 194 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var getTypeName = __webpack_require__(157);
	var isIdentity = __webpack_require__(173);
	var isArray = __webpack_require__(160);
	var create = __webpack_require__(174);
	var is = __webpack_require__(175);
	
	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;

/***/ },
/* 195 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var getTypeName = __webpack_require__(157);
	var isIdentity = __webpack_require__(173);
	var isArray = __webpack_require__(160);
	var create = __webpack_require__(174);
	var is = __webpack_require__(175);
	var forbidNewOperator = __webpack_require__(156);
	var isUnion = __webpack_require__(183);
	var isNil = __webpack_require__(149);
	
	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;
	


/***/ },
/* 196 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var FunctionType = __webpack_require__(166);
	var isArray = __webpack_require__(160);
	var list = __webpack_require__(185);
	var isObject = __webpack_require__(159);
	var create = __webpack_require__(174);
	var isNil = __webpack_require__(149);
	var isBoolean = __webpack_require__(163);
	var tuple = __webpack_require__(194);
	var getFunctionName = __webpack_require__(152);
	var getTypeName = __webpack_require__(157);
	var isType = __webpack_require__(158);
	
	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;


/***/ },
/* 197 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var isFunction = __webpack_require__(148);
	var isArray = __webpack_require__(160);
	var forbidNewOperator = __webpack_require__(173);
	var is = __webpack_require__(175);
	var getTypeName = __webpack_require__(157);
	var isIdentity = __webpack_require__(173);
	
	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;
	


/***/ },
/* 198 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isTypeName = __webpack_require__(172);
	var String = __webpack_require__(178);
	var Function = __webpack_require__(166);
	var isBoolean = __webpack_require__(163);
	var isObject = __webpack_require__(159);
	var isNil = __webpack_require__(149);
	var create = __webpack_require__(174);
	var getTypeName = __webpack_require__(157);
	var dict = __webpack_require__(180);
	var getDefaultInterfaceName = __webpack_require__(189);
	var isIdentity = __webpack_require__(173);
	var is = __webpack_require__(175);
	var extend = __webpack_require__(190);
	var assign = __webpack_require__(199);
	
	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;


/***/ },
/* 199 */
/***/ function(module, exports) {

	function assign(x, y) {
	  for (var k in y) {
	    x[k] = y[k];
	  }
	  return x;
	}
	
	module.exports = assign;

/***/ },
/* 200 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isObject = __webpack_require__(159);
	var isFunction = __webpack_require__(148);
	var isArray = __webpack_require__(160);
	var isNumber = __webpack_require__(169);
	var assign = __webpack_require__(199);
	
	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;


/***/ },
/* 201 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(147);
	var isFunction = __webpack_require__(148);
	var isType = __webpack_require__(158);
	var Any = __webpack_require__(153);
	
	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');
	};


/***/ },
/* 202 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(145);
	
	var BreakpointResult = _require.BreakpointResult;
	var Location = _require.Location;
	
	var defer = __webpack_require__(144);
	
	var bpClients = void 0;
	var threadClient = void 0;
	var tabTarget = void 0;
	var debuggerClient = void 0;
	
	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) {
	  var sourceClient = threadClient.source({ actor: sourceId });
	  return sourceClient.source();
	}
	
	function setBreakpoint(location, condition, noSliding) {
	  var 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) {
	  var bpClient = res[1];
	  var 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) {
	  var bpClient = bpClients[breakpointId];
	  bpClients[breakpointId] = null;
	  return bpClient.remove();
	}
	
	function setBreakpointCondition(breakpointId, location, condition, noSliding) {
	  var bpClient = bpClients[breakpointId];
	  bpClients[breakpointId] = null;
	
	  return bpClient.setCondition(threadClient, condition, noSliding).then(_bpClient => onNewBreakpoint(location, [{}, _bpClient]));
	}
	
	function evaluate(script, _ref) {
	  var frameId = _ref.frameId;
	
	  var deferred = defer();
	  tabTarget.activeConsole.evaluateJS(script, result => {
	    deferred.resolve(result);
	  }, { frameActor: frameId });
	
	  return deferred.promise;
	}
	
	function debuggeeCommand(script) {
	  tabTarget.activeConsole.evaluateJS(script, () => {});
	
	  var consoleActor = tabTarget.form.consoleActor;
	  var 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) {
	  var objClient = threadClient.pauseGrip(grip);
	  return objClient.getPrototypeAndProperties();
	}
	
	function pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
	  return threadClient.pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions);
	}
	
	function prettyPrint(sourceId, indentSize) {
	  var sourceClient = threadClient.source({ actor: sourceId });
	  return sourceClient.prettyPrint(indentSize);
	}
	
	function disablePrettyPrint(sourceId) {
	  var sourceClient = threadClient.source({ actor: sourceId });
	  return sourceClient.disablePrettyPrint();
	}
	
	var clientCommands = {
	  resume,
	  stepIn,
	  stepOut,
	  stepOver,
	  breakOnNext,
	  sourceContents,
	  setBreakpoint,
	  removeBreakpoint,
	  setBreakpointCondition,
	  evaluate,
	  debuggeeCommand,
	  navigate,
	  reload,
	  getProperties,
	  pauseOnExceptions,
	  prettyPrint,
	  disablePrettyPrint
	};
	
	module.exports = {
	  setupCommands,
	  clientCommands
	};

/***/ },
/* 203 */
/***/ function(module, exports, __webpack_require__) {

	var 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
	    var response = yield threadClient.getFrames(0, CALL_STACK_PAGE_SIZE);
	    var frames = response.frames.map(createFrame);
	
	    var 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"); }); }; }
	
	var _require = __webpack_require__(204);
	
	var createFrame = _require.createFrame;
	var createSource = _require.createSource;
	
	
	var CALL_STACK_PAGE_SIZE = 1000;
	
	var threadClient = void 0;
	var actions = void 0;
	
	function setupEvents(dependencies) {
	  threadClient = dependencies.threadClient;
	  actions = dependencies.actions;
	}
	
	function resumed(_, packet) {
	  actions.resumed(packet);
	}
	
	function newSource(_, _ref2) {
	  var source = _ref2.source;
	
	  actions.newSource(createSource(source));
	}
	
	var clientEvents = {
	  paused,
	  resumed,
	  newSource
	};
	
	module.exports = {
	  setupEvents,
	  clientEvents
	};

/***/ },
/* 204 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(145);
	
	var Source = _require.Source;
	var Frame = _require.Frame;
	var Location = _require.Location;
	
	
	function createFrame(frame) {
	  var title = void 0;
	  if (frame.type == "call") {
	    var 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 };

/***/ },
/* 205 */
/***/ function(module, exports, __webpack_require__) {

	/* eslint-disable */
	
	var _require = __webpack_require__(206);
	
	var connect = _require.connect;
	
	var defer = __webpack_require__(144);
	
	var _require2 = __webpack_require__(145);
	
	var Tab = _require2.Tab;
	
	var _require3 = __webpack_require__(89);
	
	var isEnabled = _require3.isEnabled;
	var getValue = _require3.getValue;
	
	var networkRequest = __webpack_require__(207);
	
	var _require4 = __webpack_require__(208);
	
	var setupCommands = _require4.setupCommands;
	var clientCommands = _require4.clientCommands;
	
	var _require5 = __webpack_require__(209);
	
	var setupEvents = _require5.setupEvents;
	var clientEvents = _require5.clientEvents;
	var pageEvents = _require5.pageEvents;
	
	// TODO: figure out a way to avoid patching native prototypes.
	// Unfortunately the Chrome client requires it to work.
	
	Array.prototype.peekLast = function () {
	  return this[this.length - 1];
	};
	
	var connection = void 0;
	
	function createTabs(tabs) {
	
	  return tabs.filter(tab => {
	    var isPage = tab.type == "page";
	    return isPage;
	  }).map(tab => {
	    return Tab({
	      title: tab.title,
	      url: tab.url,
	      id: tab.id,
	      tab,
	      browser: "chrome"
	    });
	  });
	}
	
	function connectClient() {
	  var deferred = defer();
	
	  if (!getValue("chrome.debug")) {
	    return deferred.resolve(createTabs([]));
	  }
	
	  var webSocketPort = getValue("chrome.webSocketPort");
	  var url = `http://localhost:${ webSocketPort }/json/list`;
	  networkRequest(url).then(res => {
	    deferred.resolve(createTabs(JSON.parse(res.content)));
	  }).catch(err => {
	    console.log(err);
	    deferred.reject();
	  });
	
	  return deferred.promise;
	}
	
	function connectTab(tab) {
	  return connect(tab.webSocketDebuggerUrl).then(conn => {
	    connection = conn;
	  });
	}
	
	function connectNode(url) {
	  return connect(url).then(conn => {
	    connection = conn;
	  });
	}
	
	function initPage(actions) {
	  var agents = connection._agents;
	
	  setupCommands({ agents: agents });
	  setupEvents({ actions, agents });
	
	  agents.Debugger.enable();
	  agents.Debugger.setPauseOnExceptions("none");
	  agents.Debugger.setAsyncCallStackDepth(0);
	
	  agents.Runtime.enable();
	  agents.Runtime.run();
	
	  agents.Page.enable();
	
	  connection.registerDispatcher("Debugger", clientEvents);
	  connection.registerDispatcher("Page", pageEvents);
	}
	
	module.exports = {
	  connectClient,
	  clientCommands,
	  connectNode,
	  connectTab,
	  initPage
	};

/***/ },
/* 206 */
/***/ function(module, exports) {

	module.exports = {};

/***/ },
/* 207 */
/***/ function(module, exports) {

	function networkRequest(url, opts) {
	  return new Promise((resolve, reject) => {
	    var req = new XMLHttpRequest();
	
	    req.addEventListener("readystatechange", () => {
	      if (req.readyState === XMLHttpRequest.DONE) {
	        if (req.status === 200) {
	          resolve({ content: req.responseText });
	        } else {
	          resolve(req.statusText);
	        }
	      }
	    });
	
	    // Not working yet.
	    // if (!opts.loadFromCache) {
	    //   req.channel.loadFlags = (
	    //     Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE |
	    //       Components.interfaces.nsIRequest.INHIBIT_CACHING |
	    //       Components.interfaces.nsIRequest.LOAD_ANONYMOUS
	    //   );
	    // }
	
	    req.open("GET", url);
	    req.send();
	  });
	}
	
	module.exports = networkRequest;

/***/ },
/* 208 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(145);
	
	var BreakpointResult = _require.BreakpointResult;
	var Location = _require.Location;
	
	
	var debuggerAgent = void 0;
	var runtimeAgent = void 0;
	var pageAgent = void 0;
	
	function setupCommands(_ref) {
	  var agents = _ref.agents;
	
	  debuggerAgent = agents.Debugger;
	  runtimeAgent = agents.Runtime;
	  pageAgent = agents.Page;
	}
	
	function resume() {
	  return debuggerAgent.resume();
	}
	
	function stepIn() {
	  return debuggerAgent.stepInto();
	}
	
	function stepOver() {
	  return debuggerAgent.stepOver();
	}
	
	function stepOut() {
	  return debuggerAgent.stepOut();
	}
	
	function pauseOnExceptions(toggle) {
	  var state = toggle ? "uncaught" : "none";
	  return debuggerAgent.setPauseOnExceptions(state);
	}
	
	function breakOnNext() {
	  return debuggerAgent.pause();
	}
	
	function sourceContents(sourceId) {
	  return debuggerAgent.getScriptSource(sourceId, (err, contents) => ({
	    source: contents,
	    contentType: null
	  }));
	}
	
	function setBreakpoint(location, condition) {
	  return new Promise((resolve, reject) => {
	    return debuggerAgent.setBreakpoint({
	      scriptId: location.sourceId,
	      lineNumber: location.line - 1,
	      columnNumber: location.column
	    }, (err, breakpointId, actualLocation) => {
	      if (err) {
	        reject(err);
	        return;
	      }
	
	      actualLocation = actualLocation ? {
	        sourceId: actualLocation.scriptId,
	        line: actualLocation.lineNumber + 1,
	        column: actualLocation.columnNumber
	      } : location;
	
	      resolve(BreakpointResult({
	        id: breakpointId,
	        actualLocation: Location(actualLocation)
	      }));
	    });
	  });
	}
	
	function removeBreakpoint(breakpointId) {
	  // TODO: resolve promise when request is completed.
	  return new Promise((resolve, reject) => {
	    resolve(debuggerAgent.removeBreakpoint(breakpointId));
	  });
	}
	
	function evaluate(script) {
	  return runtimeAgent.evaluate(script, (_, result) => {
	    return result;
	  });
	}
	
	function debuggeeCommand(script) {
	  evaluate(script);
	  return Promise.resolve();
	}
	
	function navigate(url) {
	  return pageAgent.navigate(url, (_, result) => {
	    return result;
	  });
	}
	
	var clientCommands = {
	  resume,
	  stepIn,
	  stepOut,
	  stepOver,
	  pauseOnExceptions,
	  breakOnNext,
	  sourceContents,
	  setBreakpoint,
	  removeBreakpoint,
	  evaluate,
	  debuggeeCommand,
	  navigate
	};
	
	module.exports = {
	  setupCommands,
	  clientCommands
	};

/***/ },
/* 209 */
/***/ function(module, exports, __webpack_require__) {

	var paused = (() => {
	  var _ref = _asyncToGenerator(function* (callFrames, reason, data, hitBreakpoints, asyncStackTrace) {
	    var frames = callFrames.map(function (frame) {
	      return Frame({
	        id: frame.callFrameId,
	        displayName: frame.functionName,
	        location: Location({
	          sourceId: frame.location.scriptId,
	          line: frame.location.lineNumber + 1,
	          column: frame.location.columnNumber
	        })
	      });
	    });
	
	    var frame = frames[0];
	    var why = Object.assign({}, {
	      type: reason
	    }, data);
	
	    pageAgent.setOverlayMessage("Paused in debugger.html");
	
	    yield actions.paused({ frame, why, frames });
	  });
	
	  return function paused(_x, _x2, _x3, _x4, _x5) {
	    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"); }); }; }
	
	var _require = __webpack_require__(145);
	
	var Source = _require.Source;
	var Location = _require.Location;
	var Frame = _require.Frame;
	
	
	var actions = void 0;
	var pageAgent = void 0;
	
	function setupEvents(dependencies) {
	  actions = dependencies.actions;
	  pageAgent = dependencies.agents.Page;
	}
	
	// Debugger Events
	function scriptParsed(scriptId, url, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed) {
	  if (isContentScript) {
	    return;
	  }
	
	  actions.newSource(Source({
	    id: scriptId,
	    url,
	    sourceMapURL,
	    isPrettyPrinted: false
	  }));
	}
	
	function scriptFailedToParse() {}
	
	function resumed() {
	  pageAgent.setOverlayMessage(undefined);
	  actions.resumed();
	}
	
	function globalObjectCleared() {}
	
	// Page Events
	function frameNavigated(frame) {
	  actions.navigate();
	}
	
	function frameStartedLoading() {
	  actions.willNavigate();
	}
	
	function domContentEventFired() {}
	
	function loadEventFired() {}
	
	function frameStoppedLoading() {}
	
	var clientEvents = {
	  scriptParsed,
	  scriptFailedToParse,
	  paused,
	  resumed,
	  globalObjectCleared
	};
	
	var pageEvents = {
	  frameNavigated,
	  frameStartedLoading,
	  domContentEventFired,
	  loadEventFired,
	  frameStoppedLoading
	};
	
	module.exports = {
	  setupEvents,
	  pageEvents,
	  clientEvents
	};

/***/ },
/* 210 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	
	var classnames = __webpack_require__(211);
	
	var _require = __webpack_require__(89);
	
	var getValue = _require.getValue;
	var isDevelopment = _require.isDevelopment;
	
	
	__webpack_require__(212);
	
	function themeClass() {
	  var theme = getValue("theme");
	  return `theme-${ theme }`;
	}
	
	module.exports = function (component) {
	  return dom.div({
	    className: classnames("theme-body", { [themeClass()]: isDevelopment() }),
	    style: { flex: 1 }
	  }, React.createElement(component));
	};

/***/ },
/* 211 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
	  Copyright (c) 2016 Jed Watson.
	  Licensed under the MIT License (MIT), see
	  http://jedwatson.github.io/classnames
	*/
	/* global define */
	
	(function () {
		'use strict';
	
		var hasOwn = {}.hasOwnProperty;
	
		function classNames () {
			var classes = [];
	
			for (var i = 0; i < arguments.length; i++) {
				var arg = arguments[i];
				if (!arg) continue;
	
				var argType = typeof arg;
	
				if (argType === 'string' || argType === 'number') {
					classes.push(arg);
				} else if (Array.isArray(arg)) {
					classes.push(classNames.apply(null, arg));
				} else if (argType === 'object') {
					for (var key in arg) {
						if (hasOwn.call(arg, key) && arg[key]) {
							classes.push(key);
						}
					}
				}
			}
	
			return classes.join(' ');
		}
	
		if (typeof module !== 'undefined' && module.exports) {
			module.exports = classNames;
		} else if (true) {
			// register as 'classnames', consistent with npm package name
			!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function () {
				return classNames;
			}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else {
			window.classNames = classNames;
		}
	}());


/***/ },
/* 212 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 213 */,
/* 214 */,
/* 215 */,
/* 216 */
/***/ 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/. */
	/* global window */
	
	var _require = __webpack_require__(3);
	
	var createStore = _require.createStore;
	var applyMiddleware = _require.applyMiddleware;
	
	var _require2 = __webpack_require__(217);
	
	var waitUntilService = _require2.waitUntilService;
	
	var _require3 = __webpack_require__(218);
	
	var log = _require3.log;
	
	var _require4 = __webpack_require__(219);
	
	var history = _require4.history;
	
	var _require5 = __webpack_require__(220);
	
	var promise = _require5.promise;
	
	var _require6 = __webpack_require__(225);
	
	var thunk = _require6.thunk;
	
	
	/**
	 * This creates a dispatcher with all the standard middleware in place
	 * that all code requires. It can also be optionally configured in
	 * various ways, such as logging and recording.
	 *
	 * @param {object} opts:
	 *        - log: log all dispatched actions to console
	 *        - history: an array to store every action in. Should only be
	 *                   used in tests.
	 *        - middleware: array of middleware to be included in the redux store
	 */
	var configureStore = function () {
	  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	
	  var middleware = [thunk(opts.makeThunkArgs), promise,
	
	  // Order is important: services must go last as they always
	  // operate on "already transformed" actions. Actions going through
	  // them shouldn't have any special fields like promises, they
	  // should just be normal JSON objects.
	  waitUntilService];
	
	  if (opts.history) {
	    middleware.push(history(opts.history));
	  }
	
	  if (opts.middleware) {
	    opts.middleware.forEach(fn => middleware.push(fn));
	  }
	
	  if (opts.log) {
	    middleware.push(log);
	  }
	
	  // Hook in the redux devtools browser extension if it exists
	  var devtoolsExt = typeof window === "object" && window.devToolsExtension ? window.devToolsExtension() : f => f;
	
	  return applyMiddleware.apply(undefined, middleware)(devtoolsExt(createStore));
	};
	
	module.exports = configureStore;

/***/ },
/* 217 */
/***/ 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";
	
	/**
	 * A middleware which acts like a service, because it is stateful
	 * and "long-running" in the background. It provides the ability
	 * for actions to install a function to be run once when a specific
	 * condition is met by an action coming through the system. Think of
	 * it as a thunk that blocks until the condition is met. Example:
	 *
	 * ```js
	 * const services = { WAIT_UNTIL: require('wait-service').NAME };
	 *
	 * { type: services.WAIT_UNTIL,
	 *   predicate: action => action.type === constants.ADD_ITEM,
	 *   run: (dispatch, getState, action) => {
	 *     // Do anything here. You only need to accept the arguments
	 *     // if you need them. `action` is the action that satisfied
	 *     // the predicate.
	 *   }
	 * }
	 * ```
	 */
	
	var NAME = exports.NAME = "@@service/waitUntil";
	
	function waitUntilService(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  var pending = [];
	
	  function checkPending(action) {
	    var readyRequests = [];
	    var stillPending = [];
	
	    // Find the pending requests whose predicates are satisfied with
	    // this action. Wait to run the requests until after we update the
	    // pending queue because the request handler may synchronously
	    // dispatch again and run this service (that use case is
	    // completely valid).
	    for (var request of pending) {
	      if (request.predicate(action)) {
	        readyRequests.push(request);
	      } else {
	        stillPending.push(request);
	      }
	    }
	
	    pending = stillPending;
	    for (var _request of readyRequests) {
	      _request.run(dispatch, getState, action);
	    }
	  }
	
	  return next => action => {
	    if (action.type === NAME) {
	      pending.push(action);
	      return null;
	    }
	    var result = next(action);
	    checkPending(action);
	    return result;
	  };
	}
	exports.waitUntilService = waitUntilService;

/***/ },
/* 218 */
/***/ function(module, exports) {

	/**
	 * A middleware that logs all actions coming through the system
	 * to the console.
	 */
	function log(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  return next => action => {
	    var actionText = JSON.stringify(action, null, 2);
	    var truncatedActionText = actionText.slice(0, 1000) + "...";
	    console.log(`[DISPATCH ${ action.type }]`, action, truncatedActionText);
	    next(action);
	  };
	}
	
	exports.log = log;

/***/ },
/* 219 */
/***/ 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/. */
	
	var _require = __webpack_require__(89);
	
	var isDevelopment = _require.isDevelopment;
	
	/**
	 * A middleware that stores every action coming through the store in the passed
	 * in logging object. Should only be used for tests, as it collects all
	 * action information, which will cause memory bloat.
	 */
	
	exports.history = function () {
	  var log = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var getState = _ref.getState;
	
	    if (isDevelopment()) {
	      console.warn("Using history middleware stores all actions in state for " + "testing and devtools is not currently running in test " + "mode. Be sure this is intentional.");
	    }
	    return next => action => {
	      log.push(action);
	      next(action);
	    };
	  };
	};

/***/ },
/* 220 */
/***/ 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/. */
	
	var defer = __webpack_require__(144);
	
	var _require = __webpack_require__(221);
	
	var entries = _require.entries;
	var toObject = _require.toObject;
	
	var _require2 = __webpack_require__(223);
	
	var executeSoon = _require2.executeSoon;
	
	
	var PROMISE = exports.PROMISE = "@@dispatch/promise";
	var seqIdVal = 1;
	
	function seqIdGen() {
	  return seqIdVal++;
	}
	
	function promiseMiddleware(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  return next => action => {
	    if (!(PROMISE in action)) {
	      return next(action);
	    }
	
	    var promiseInst = action[PROMISE];
	    var seqId = seqIdGen().toString();
	
	    // Create a new action that doesn't have the promise field and has
	    // the `seqId` field that represents the sequence id
	    action = Object.assign(toObject(entries(action).filter(pair => pair[0] !== PROMISE)), { seqId });
	
	    dispatch(Object.assign({}, action, { status: "start" }));
	
	    // Return the promise so action creators can still compose if they
	    // want to.
	    var deferred = defer();
	    promiseInst.then(value => {
	      executeSoon(() => {
	        dispatch(Object.assign({}, action, {
	          status: "done",
	          value: value
	        }));
	        deferred.resolve(value);
	      });
	    }, error => {
	      executeSoon(() => {
	        dispatch(Object.assign({}, action, {
	          status: "error",
	          error: error.message || error
	        }));
	        deferred.reject(error);
	      });
	    });
	    return deferred.promise;
	  };
	}
	
	exports.promise = promiseMiddleware;

/***/ },
/* 221 */
/***/ function(module, exports, __webpack_require__) {

	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	/* -*- 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/. */
	
	var co = __webpack_require__(222);
	
	function asPaused(client, func) {
	  if (client.state != "paused") {
	    return co(function* () {
	      yield client.interrupt();
	      var result = void 0;
	
	      try {
	        result = yield func();
	      } catch (e) {
	        // Try to put the debugger back in a working state by resuming
	        // it
	        yield client.resume();
	        throw e;
	      }
	
	      yield client.resume();
	      return result;
	    });
	  }
	  return func();
	}
	
	function handleError(err) {
	  console.log("ERROR: ", err);
	}
	
	function promisify(context, method) {
	  for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
	    args[_key - 2] = arguments[_key];
	  }
	
	  return new Promise((resolve, reject) => {
	    args.push(response => {
	      if (response.error) {
	        reject(response);
	      } else {
	        resolve(response);
	      }
	    });
	    method.apply(context, args);
	  });
	}
	
	function truncateStr(str, size) {
	  if (str.length > size) {
	    return str.slice(0, size) + "...";
	  }
	  return str;
	}
	
	function endTruncateStr(str, size) {
	  if (str.length > size) {
	    return "..." + str.slice(str.length - size);
	  }
	  return str;
	}
	
	var msgId = 1;
	function workerTask(worker, method) {
	  return function () {
	    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
	      args[_key2] = arguments[_key2];
	    }
	
	    return new Promise((resolve, reject) => {
	      var id = msgId++;
	      worker.postMessage({ id, method, args });
	
	      var listener = (_ref) => {
	        var result = _ref.data;
	
	        if (result.id !== id) {
	          return;
	        }
	
	        worker.removeEventListener("message", listener);
	        if (result.error) {
	          reject(result.error);
	        } else {
	          resolve(result.response);
	        }
	      };
	
	      worker.addEventListener("message", listener);
	    });
	  };
	}
	
	/**
	 * Interleaves two arrays element by element, returning the combined array, like
	 * a zip. In the case of arrays with different sizes, undefined values will be
	 * interleaved at the end along with the extra values of the larger array.
	 *
	 * @param Array a
	 * @param Array b
	 * @returns Array
	 *          The combined array, in the form [a1, b1, a2, b2, ...]
	 */
	function zip(a, b) {
	  if (!b) {
	    return a;
	  }
	  if (!a) {
	    return b;
	  }
	  var pairs = [];
	  for (var i = 0, aLength = a.length, bLength = b.length; i < aLength || i < bLength; i++) {
	    pairs.push([a[i], b[i]]);
	  }
	  return pairs;
	}
	
	/**
	 * Converts an object into an array with 2-element arrays as key/value
	 * pairs of the object. `{ foo: 1, bar: 2}` would become
	 * `[[foo, 1], [bar 2]]` (order not guaranteed);
	 *
	 * @param object obj
	 * @returns array
	 */
	function entries(obj) {
	  return Object.keys(obj).map(k => [k, obj[k]]);
	}
	
	function mapObject(obj, iteratee) {
	  return toObject(entries(obj).map((_ref2) => {
	    var _ref3 = _slicedToArray(_ref2, 2);
	
	    var key = _ref3[0];
	    var value = _ref3[1];
	
	    return [key, iteratee(key, value)];
	  }));
	}
	
	/**
	 * Takes an array of 2-element arrays as key/values pairs and
	 * constructs an object using them.
	 */
	function toObject(arr) {
	  var obj = {};
	  for (var pair of arr) {
	    obj[pair[0]] = pair[1];
	  }
	  return obj;
	}
	
	/**
	 * Composes the given functions into a single function, which will
	 * apply the results of each function right-to-left, starting with
	 * applying the given arguments to the right-most function.
	 * `compose(foo, bar, baz)` === `args => foo(bar(baz(args)`
	 *
	 * @param ...function funcs
	 * @returns function
	 */
	function compose() {
	  for (var _len3 = arguments.length, funcs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
	    funcs[_key3] = arguments[_key3];
	  }
	
	  return function () {
	    for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
	      args[_key4] = arguments[_key4];
	    }
	
	    var initialValue = funcs[funcs.length - 1].apply(null, args);
	    var leftFuncs = funcs.slice(0, -1);
	    return leftFuncs.reduceRight((composed, f) => f(composed), initialValue);
	  };
	}
	
	function updateObj(obj, fields) {
	  return Object.assign({}, obj, fields);
	}
	
	function throttle(func, ms) {
	  var timeout = void 0,
	      _this = void 0;
	  return function () {
	    for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
	      args[_key5] = arguments[_key5];
	    }
	
	    _this = this;
	    if (!timeout) {
	      timeout = setTimeout(() => {
	        func.apply.apply(func, [_this].concat(_toConsumableArray(args)));
	        timeout = null;
	      }, ms);
	    }
	  };
	}
	
	module.exports = {
	  asPaused,
	  handleError,
	  promisify,
	  truncateStr,
	  endTruncateStr,
	  workerTask,
	  zip,
	  entries,
	  toObject,
	  mapObject,
	  compose,
	  updateObj,
	  throttle
	};

/***/ },
/* 222 */
/***/ function(module, exports) {

	
	/**
	 * slice() reference.
	 */
	
	var slice = Array.prototype.slice;
	
	/**
	 * Expose `co`.
	 */
	
	module.exports = co['default'] = co.co = co;
	
	/**
	 * Wrap the given generator `fn` into a
	 * function that returns a promise.
	 * This is a separate function so that
	 * every `co()` call doesn't create a new,
	 * unnecessary closure.
	 *
	 * @param {GeneratorFunction} fn
	 * @return {Function}
	 * @api public
	 */
	
	co.wrap = function (fn) {
	  createPromise.__generatorFunction__ = fn;
	  return createPromise;
	  function createPromise() {
	    return co.call(this, fn.apply(this, arguments));
	  }
	};
	
	/**
	 * Execute the generator function or a generator
	 * and return a promise.
	 *
	 * @param {Function} fn
	 * @return {Promise}
	 * @api public
	 */
	
	function co(gen) {
	  var ctx = this;
	  var args = slice.call(arguments, 1)
	
	  // we wrap everything in a promise to avoid promise chaining,
	  // which leads to memory leak errors.
	  // see https://github.com/tj/co/issues/180
	  return new Promise(function(resolve, reject) {
	    if (typeof gen === 'function') gen = gen.apply(ctx, args);
	    if (!gen || typeof gen.next !== 'function') return resolve(gen);
	
	    onFulfilled();
	
	    /**
	     * @param {Mixed} res
	     * @return {Promise}
	     * @api private
	     */
	
	    function onFulfilled(res) {
	      var ret;
	      try {
	        ret = gen.next(res);
	      } catch (e) {
	        return reject(e);
	      }
	      next(ret);
	    }
	
	    /**
	     * @param {Error} err
	     * @return {Promise}
	     * @api private
	     */
	
	    function onRejected(err) {
	      var ret;
	      try {
	        ret = gen.throw(err);
	      } catch (e) {
	        return reject(e);
	      }
	      next(ret);
	    }
	
	    /**
	     * Get the next value in the generator,
	     * return a promise.
	     *
	     * @param {Object} ret
	     * @return {Promise}
	     * @api private
	     */
	
	    function next(ret) {
	      if (ret.done) return resolve(ret.value);
	      var value = toPromise.call(ctx, ret.value);
	      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
	      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
	        + 'but the following object was passed: "' + String(ret.value) + '"'));
	    }
	  });
	}
	
	/**
	 * Convert a `yield`ed value into a promise.
	 *
	 * @param {Mixed} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function toPromise(obj) {
	  if (!obj) return obj;
	  if (isPromise(obj)) return obj;
	  if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);
	  if ('function' == typeof obj) return thunkToPromise.call(this, obj);
	  if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
	  if (isObject(obj)) return objectToPromise.call(this, obj);
	  return obj;
	}
	
	/**
	 * Convert a thunk to a promise.
	 *
	 * @param {Function}
	 * @return {Promise}
	 * @api private
	 */
	
	function thunkToPromise(fn) {
	  var ctx = this;
	  return new Promise(function (resolve, reject) {
	    fn.call(ctx, function (err, res) {
	      if (err) return reject(err);
	      if (arguments.length > 2) res = slice.call(arguments, 1);
	      resolve(res);
	    });
	  });
	}
	
	/**
	 * Convert an array of "yieldables" to a promise.
	 * Uses `Promise.all()` internally.
	 *
	 * @param {Array} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function arrayToPromise(obj) {
	  return Promise.all(obj.map(toPromise, this));
	}
	
	/**
	 * Convert an object of "yieldables" to a promise.
	 * Uses `Promise.all()` internally.
	 *
	 * @param {Object} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function objectToPromise(obj){
	  var results = new obj.constructor();
	  var keys = Object.keys(obj);
	  var promises = [];
	  for (var i = 0; i < keys.length; i++) {
	    var key = keys[i];
	    var promise = toPromise.call(this, obj[key]);
	    if (promise && isPromise(promise)) defer(promise, key);
	    else results[key] = obj[key];
	  }
	  return Promise.all(promises).then(function () {
	    return results;
	  });
	
	  function defer(promise, key) {
	    // predefine the key in the result
	    results[key] = undefined;
	    promises.push(promise.then(function (res) {
	      results[key] = res;
	    }));
	  }
	}
	
	/**
	 * Check if `obj` is a promise.
	 *
	 * @param {Object} obj
	 * @return {Boolean}
	 * @api private
	 */
	
	function isPromise(obj) {
	  return 'function' == typeof obj.then;
	}
	
	/**
	 * Check if `obj` is a generator.
	 *
	 * @param {Mixed} obj
	 * @return {Boolean}
	 * @api private
	 */
	
	function isGenerator(obj) {
	  return 'function' == typeof obj.next && 'function' == typeof obj.throw;
	}
	
	/**
	 * Check if `obj` is a generator function.
	 *
	 * @param {Mixed} obj
	 * @return {Boolean}
	 * @api private
	 */
	function isGeneratorFunction(obj) {
	  var constructor = obj.constructor;
	  if (!constructor) return false;
	  if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true;
	  return isGenerator(constructor.prototype);
	}
	
	/**
	 * Check for plain object.
	 *
	 * @param {Mixed} val
	 * @return {Boolean}
	 * @api private
	 */
	
	function isObject(val) {
	  return Object == val.constructor;
	}


/***/ },
/* 223 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(224);
	
	function reportException(who, exception) {
	  var msg = who + " threw an exception: ";
	  console.error(msg, exception);
	}
	
	function executeSoon(fn) {
	  setTimeout(fn, 0);
	}
	
	module.exports = {
	  reportException,
	  executeSoon,
	  assert
	};

/***/ },
/* 224 */
/***/ function(module, exports) {

	function assert(condition, message) {
	  if (!condition) {
	    throw new Error("Assertion failure: " + message);
	  }
	}
	
	module.exports = assert;

/***/ },
/* 225 */
/***/ function(module, exports) {

	
	/**
	 * A middleware that allows thunks (functions) to be dispatched. If
	 * it's a thunk, it is called with an argument that contains
	 * `dispatch`, `getState`, and any additional args passed in via the
	 * middleware constructure. This allows the action to create multiple
	 * actions (most likely asynchronously).
	 */
	function thunk(makeArgs) {
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var getState = _ref.getState;
	
	    var args = { dispatch, getState };
	
	    return next => action => {
	      return typeof action === "function" ? action(makeArgs ? makeArgs(args, getState()) : args) : next(action);
	    };
	  };
	}
	exports.thunk = thunk;

/***/ },
/* 226 */
/***/ function(module, exports, __webpack_require__) {

	var tabs = __webpack_require__(227);
	
	module.exports = {
	  tabs
	};

/***/ },
/* 227 */
/***/ 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/. */
	
	var constants = __webpack_require__(228);
	var Immutable = __webpack_require__(229);
	var fromJS = __webpack_require__(230);
	
	var initialState = fromJS({
	  tabs: {},
	  selectedTab: null
	});
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
	  var action = arguments[1];
	
	  switch (action.type) {
	    case constants.ADD_TABS:
	      var tabs = action.value;
	      if (!tabs) {
	        return state;
	      }
	
	      return state.mergeIn(["tabs"], Immutable.Map(tabs.map(tab => {
	        tab = Object.assign({}, tab, { id: getTabId(tab) });
	        return [tab.id, Immutable.Map(tab)];
	      })));
	    case constants.SELECT_TAB:
	      var tab = state.getIn(["tabs", action.id]);
	      return state.setIn(["selectedTab"], tab);
	  }
	
	  return state;
	}
	
	function getTabId(tab) {
	  var id = tab.id;
	  var isFirefox = tab.browser == "firefox";
	
	  // NOTE: we're getting the last part of the actor because
	  // we want to ignore the connection id
	  if (isFirefox) {
	    id = tab.id.split(".").pop();
	  }
	
	  return id;
	}
	
	module.exports = update;

/***/ },
/* 228 */
/***/ 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/. */
	
	exports.ADD_TABS = "ADD_TABS";
	exports.SELECT_TAB = "SELECT_TAB";

/***/ },
/* 229 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 *  Copyright (c) 2014-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.
	 */
	
	(function (global, factory) {
	   true ? module.exports = factory() :
	  typeof define === 'function' && define.amd ? define(factory) :
	  (global.Immutable = factory());
	}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice;
	
	  function createClass(ctor, superClass) {
	    if (superClass) {
	      ctor.prototype = Object.create(superClass.prototype);
	    }
	    ctor.prototype.constructor = ctor;
	  }
	
	  function Iterable(value) {
	      return isIterable(value) ? value : Seq(value);
	    }
	
	
	  createClass(KeyedIterable, Iterable);
	    function KeyedIterable(value) {
	      return isKeyed(value) ? value : KeyedSeq(value);
	    }
	
	
	  createClass(IndexedIterable, Iterable);
	    function IndexedIterable(value) {
	      return isIndexed(value) ? value : IndexedSeq(value);
	    }
	
	
	  createClass(SetIterable, Iterable);
	    function SetIterable(value) {
	      return isIterable(value) && !isAssociative(value) ? value : SetSeq(value);
	    }
	
	
	
	  function isIterable(maybeIterable) {
	    return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]);
	  }
	
	  function isKeyed(maybeKeyed) {
	    return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]);
	  }
	
	  function isIndexed(maybeIndexed) {
	    return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]);
	  }
	
	  function isAssociative(maybeAssociative) {
	    return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);
	  }
	
	  function isOrdered(maybeOrdered) {
	    return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]);
	  }
	
	  Iterable.isIterable = isIterable;
	  Iterable.isKeyed = isKeyed;
	  Iterable.isIndexed = isIndexed;
	  Iterable.isAssociative = isAssociative;
	  Iterable.isOrdered = isOrdered;
	
	  Iterable.Keyed = KeyedIterable;
	  Iterable.Indexed = IndexedIterable;
	  Iterable.Set = SetIterable;
	
	
	  var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
	  var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
	  var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
	  var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
	
	  // Used for setting prototype methods that IE8 chokes on.
	  var DELETE = 'delete';
	
	  // Constants describing the size of trie nodes.
	  var SHIFT = 5; // Resulted in best performance after ______?
	  var SIZE = 1 << SHIFT;
	  var MASK = SIZE - 1;
	
	  // A consistent shared value representing "not set" which equals nothing other
	  // than itself, and nothing that could be provided externally.
	  var NOT_SET = {};
	
	  // Boolean references, Rough equivalent of `bool &`.
	  var CHANGE_LENGTH = { value: false };
	  var DID_ALTER = { value: false };
	
	  function MakeRef(ref) {
	    ref.value = false;
	    return ref;
	  }
	
	  function SetRef(ref) {
	    ref && (ref.value = true);
	  }
	
	  // A function which returns a value representing an "owner" for transient writes
	  // to tries. The return value will only ever equal itself, and will not equal
	  // the return of any subsequent call of this function.
	  function OwnerID() {}
	
	  // http://jsperf.com/copy-array-inline
	  function arrCopy(arr, offset) {
	    offset = offset || 0;
	    var len = Math.max(0, arr.length - offset);
	    var newArr = new Array(len);
	    for (var ii = 0; ii < len; ii++) {
	      newArr[ii] = arr[ii + offset];
	    }
	    return newArr;
	  }
	
	  function ensureSize(iter) {
	    if (iter.size === undefined) {
	      iter.size = iter.__iterate(returnTrue);
	    }
	    return iter.size;
	  }
	
	  function wrapIndex(iter, index) {
	    // This implements "is array index" which the ECMAString spec defines as:
	    //
	    //     A String property name P is an array index if and only if
	    //     ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
	    //     to 2^32−1.
	    //
	    // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects
	    if (typeof index !== 'number') {
	      var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32
	      if ('' + uint32Index !== index || uint32Index === 4294967295) {
	        return NaN;
	      }
	      index = uint32Index;
	    }
	    return index < 0 ? ensureSize(iter) + index : index;
	  }
	
	  function returnTrue() {
	    return true;
	  }
	
	  function wholeSlice(begin, end, size) {
	    return (begin === 0 || (size !== undefined && begin <= -size)) &&
	      (end === undefined || (size !== undefined && end >= size));
	  }
	
	  function resolveBegin(begin, size) {
	    return resolveIndex(begin, size, 0);
	  }
	
	  function resolveEnd(end, size) {
	    return resolveIndex(end, size, size);
	  }
	
	  function resolveIndex(index, size, defaultIndex) {
	    return index === undefined ?
	      defaultIndex :
	      index < 0 ?
	        Math.max(0, size + index) :
	        size === undefined ?
	          index :
	          Math.min(size, index);
	  }
	
	  /* global Symbol */
	
	  var ITERATE_KEYS = 0;
	  var ITERATE_VALUES = 1;
	  var ITERATE_ENTRIES = 2;
	
	  var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
	  var FAUX_ITERATOR_SYMBOL = '@@iterator';
	
	  var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;
	
	
	  function Iterator(next) {
	      this.next = next;
	    }
	
	    Iterator.prototype.toString = function() {
	      return '[Iterator]';
	    };
	
	
	  Iterator.KEYS = ITERATE_KEYS;
	  Iterator.VALUES = ITERATE_VALUES;
	  Iterator.ENTRIES = ITERATE_ENTRIES;
	
	  Iterator.prototype.inspect =
	  Iterator.prototype.toSource = function () { return this.toString(); }
	  Iterator.prototype[ITERATOR_SYMBOL] = function () {
	    return this;
	  };
	
	
	  function iteratorValue(type, k, v, iteratorResult) {
	    var value = type === 0 ? k : type === 1 ? v : [k, v];
	    iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {
	      value: value, done: false
	    });
	    return iteratorResult;
	  }
	
	  function iteratorDone() {
	    return { value: undefined, done: true };
	  }
	
	  function hasIterator(maybeIterable) {
	    return !!getIteratorFn(maybeIterable);
	  }
	
	  function isIterator(maybeIterator) {
	    return maybeIterator && typeof maybeIterator.next === 'function';
	  }
	
	  function getIterator(iterable) {
	    var iteratorFn = getIteratorFn(iterable);
	    return iteratorFn && iteratorFn.call(iterable);
	  }
	
	  function getIteratorFn(iterable) {
	    var iteratorFn = iterable && (
	      (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||
	      iterable[FAUX_ITERATOR_SYMBOL]
	    );
	    if (typeof iteratorFn === 'function') {
	      return iteratorFn;
	    }
	  }
	
	  function isArrayLike(value) {
	    return value && typeof value.length === 'number';
	  }
	
	  createClass(Seq, Iterable);
	    function Seq(value) {
	      return value === null || value === undefined ? emptySequence() :
	        isIterable(value) ? value.toSeq() : seqFromValue(value);
	    }
	
	    Seq.of = function(/*...values*/) {
	      return Seq(arguments);
	    };
	
	    Seq.prototype.toSeq = function() {
	      return this;
	    };
	
	    Seq.prototype.toString = function() {
	      return this.__toString('Seq {', '}');
	    };
	
	    Seq.prototype.cacheResult = function() {
	      if (!this._cache && this.__iterateUncached) {
	        this._cache = this.entrySeq().toArray();
	        this.size = this._cache.length;
	      }
	      return this;
	    };
	
	    // abstract __iterateUncached(fn, reverse)
	
	    Seq.prototype.__iterate = function(fn, reverse) {
	      return seqIterate(this, fn, reverse, true);
	    };
	
	    // abstract __iteratorUncached(type, reverse)
	
	    Seq.prototype.__iterator = function(type, reverse) {
	      return seqIterator(this, type, reverse, true);
	    };
	
	
	
	  createClass(KeyedSeq, Seq);
	    function KeyedSeq(value) {
	      return value === null || value === undefined ?
	        emptySequence().toKeyedSeq() :
	        isIterable(value) ?
	          (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :
	          keyedSeqFromValue(value);
	    }
	
	    KeyedSeq.prototype.toKeyedSeq = function() {
	      return this;
	    };
	
	
	
	  createClass(IndexedSeq, Seq);
	    function IndexedSeq(value) {
	      return value === null || value === undefined ? emptySequence() :
	        !isIterable(value) ? indexedSeqFromValue(value) :
	        isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();
	    }
	
	    IndexedSeq.of = function(/*...values*/) {
	      return IndexedSeq(arguments);
	    };
	
	    IndexedSeq.prototype.toIndexedSeq = function() {
	      return this;
	    };
	
	    IndexedSeq.prototype.toString = function() {
	      return this.__toString('Seq [', ']');
	    };
	
	    IndexedSeq.prototype.__iterate = function(fn, reverse) {
	      return seqIterate(this, fn, reverse, false);
	    };
	
	    IndexedSeq.prototype.__iterator = function(type, reverse) {
	      return seqIterator(this, type, reverse, false);
	    };
	
	
	
	  createClass(SetSeq, Seq);
	    function SetSeq(value) {
	      return (
	        value === null || value === undefined ? emptySequence() :
	        !isIterable(value) ? indexedSeqFromValue(value) :
	        isKeyed(value) ? value.entrySeq() : value
	      ).toSetSeq();
	    }
	
	    SetSeq.of = function(/*...values*/) {
	      return SetSeq(arguments);
	    };
	
	    SetSeq.prototype.toSetSeq = function() {
	      return this;
	    };
	
	
	
	  Seq.isSeq = isSeq;
	  Seq.Keyed = KeyedSeq;
	  Seq.Set = SetSeq;
	  Seq.Indexed = IndexedSeq;
	
	  var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';
	
	  Seq.prototype[IS_SEQ_SENTINEL] = true;
	
	
	
	  createClass(ArraySeq, IndexedSeq);
	    function ArraySeq(array) {
	      this._array = array;
	      this.size = array.length;
	    }
	
	    ArraySeq.prototype.get = function(index, notSetValue) {
	      return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;
	    };
	
	    ArraySeq.prototype.__iterate = function(fn, reverse) {
	      var array = this._array;
	      var maxIndex = array.length - 1;
	      for (var ii = 0; ii <= maxIndex; ii++) {
	        if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {
	          return ii + 1;
	        }
	      }
	      return ii;
	    };
	
	    ArraySeq.prototype.__iterator = function(type, reverse) {
	      var array = this._array;
	      var maxIndex = array.length - 1;
	      var ii = 0;
	      return new Iterator(function() 
	        {return ii > maxIndex ?
	          iteratorDone() :
	          iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}
	      );
	    };
	
	
	
	  createClass(ObjectSeq, KeyedSeq);
	    function ObjectSeq(object) {
	      var keys = Object.keys(object);
	      this._object = object;
	      this._keys = keys;
	      this.size = keys.length;
	    }
	
	    ObjectSeq.prototype.get = function(key, notSetValue) {
	      if (notSetValue !== undefined && !this.has(key)) {
	        return notSetValue;
	      }
	      return this._object[key];
	    };
	
	    ObjectSeq.prototype.has = function(key) {
	      return this._object.hasOwnProperty(key);
	    };
	
	    ObjectSeq.prototype.__iterate = function(fn, reverse) {
	      var object = this._object;
	      var keys = this._keys;
	      var maxIndex = keys.length - 1;
	      for (var ii = 0; ii <= maxIndex; ii++) {
	        var key = keys[reverse ? maxIndex - ii : ii];
	        if (fn(object[key], key, this) === false) {
	          return ii + 1;
	        }
	      }
	      return ii;
	    };
	
	    ObjectSeq.prototype.__iterator = function(type, reverse) {
	      var object = this._object;
	      var keys = this._keys;
	      var maxIndex = keys.length - 1;
	      var ii = 0;
	      return new Iterator(function()  {
	        var key = keys[reverse ? maxIndex - ii : ii];
	        return ii++ > maxIndex ?
	          iteratorDone() :
	          iteratorValue(type, key, object[key]);
	      });
	    };
	
	  ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;
	
	
	  createClass(IterableSeq, IndexedSeq);
	    function IterableSeq(iterable) {
	      this._iterable = iterable;
	      this.size = iterable.length || iterable.size;
	    }
	
	    IterableSeq.prototype.__iterateUncached = function(fn, reverse) {
	      if (reverse) {
	        return this.cacheResult().__iterate(fn, reverse);
	      }
	      var iterable = this._iterable;
	      var iterator = getIterator(iterable);
	      var iterations = 0;
	      if (isIterator(iterator)) {
	        var step;
	        while (!(step = iterator.next()).done) {
	          if (fn(step.value, iterations++, this) === false) {
	            break;
	          }
	        }
	      }
	      return iterations;
	    };
	
	    IterableSeq.prototype.__iteratorUncached = function(type, reverse) {
	      if (reverse) {
	        return this.cacheResult().__iterator(type, reverse);
	      }
	      var iterable = this._iterable;
	      var iterator = getIterator(iterable);
	      if (!isIterator(iterator)) {
	        return new Iterator(iteratorDone);
	      }
	      var iterations = 0;
	      return new Iterator(function()  {
	        var step = iterator.next();
	        return step.done ? step : iteratorValue(type, iterations++, step.value);
	      });
	    };
	
	
	
	  createClass(IteratorSeq, IndexedSeq);
	    function IteratorSeq(iterator) {
	      this._iterator = iterator;
	      this._iteratorCache = [];
	    }
	
	    IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {
	      if (reverse) {
	        return this.cacheResult().__iterate(fn, reverse);
	      }
	      var iterator = this._iterator;
	      var cache = this._iteratorCache;
	      var iterations = 0;
	      while (iterations < cache.length) {
	        if (fn(cache[iterations], iterations++, this) === false) {
	          return iterations;
	        }
	      }
	      var step;
	      while (!(step = iterator.next()).done) {
	        var val = step.value;
	        cache[iterations] = val;
	        if (fn(val, iterations++, this) === false) {
	          break;
	        }
	      }
	      return iterations;
	    };
	
	    IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {
	      if (reverse) {
	        return this.cacheResult().__iterator(type, reverse);
	      }
	      var iterator = this._iterator;
	      var cache = this._iteratorCache;
	      var iterations = 0;
	      return new Iterator(function()  {
	        if (iterations >= cache.length) {
	          var step = iterator.next();
	          if (step.done) {
	            return step;
	          }
	          cache[iterations] = step.value;
	        }
	        return iteratorValue(type, iterations, cache[iterations++]);
	      });
	    };
	
	
	
	
	  // # pragma Helper functions
	
	  function isSeq(maybeSeq) {
	    return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);
	  }
	
	  var EMPTY_SEQ;
	
	  function emptySequence() {
	    return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));
	  }
	
	  function keyedSeqFromValue(value) {
	    var seq =
	      Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :
	      isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :
	      hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :
	      typeof value === 'object' ? new ObjectSeq(value) :
	      undefined;
	    if (!seq) {
	      throw new TypeError(
	        'Expected Array or iterable object of [k, v] entries, '+
	        'or keyed object: ' + value
	      );
	    }
	    return seq;
	  }
	
	  function indexedSeqFromValue(value) {
	    var seq = maybeIndexedSeqFromValue(value);
	    if (!seq) {
	      throw new TypeError(
	        'Expected Array or iterable object of values: ' + value
	      );
	    }
	    return seq;
	  }
	
	  function seqFromValue(value) {
	    var seq = maybeIndexedSeqFromValue(value) ||
	      (typeof value === 'object' && new ObjectSeq(value));
	    if (!seq) {
	      throw new TypeError(
	        'Expected Array or iterable object of values, or keyed object: ' + value
	      );
	    }
	    return seq;
	  }
	
	  function maybeIndexedSeqFromValue(value) {
	    return (
	      isArrayLike(value) ? new ArraySeq(value) :
	      isIterator(value) ? new IteratorSeq(value) :
	      hasIterator(value) ? new IterableSeq(value) :
	      undefined
	    );
	  }
	
	  function seqIterate(seq, fn, reverse, useKeys) {
	    var cache = seq._cache;
	    if (cache) {
	      var maxIndex = cache.length - 1;
	      for (var ii = 0; ii <= maxIndex; ii++) {
	        var entry = cache[reverse ? maxIndex - ii : ii];
	        if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {
	          return ii + 1;
	        }
	      }
	      return ii;
	    }
	    return seq.__iterateUncached(fn, reverse);
	  }
	
	  function seqIterator(seq, type, reverse, useKeys) {
	    var cache = seq._cache;
	    if (cache) {
	      var maxIndex = cache.length - 1;
	      var ii = 0;
	      return new Iterator(function()  {
	        var entry = cache[reverse ? maxIndex - ii : ii];
	        return ii++ > maxIndex ?
	          iteratorDone() :
	          iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);
	      });
	    }
	    return seq.__iteratorUncached(type, reverse);
	  }
	
	  function fromJS(json, converter) {
	    return converter ?
	      fromJSWith(converter, json, '', {'': json}) :
	      fromJSDefault(json);
	  }
	
	  function fromJSWith(converter, json, key, parentJSON) {
	    if (Array.isArray(json)) {
	      return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k)  {return fromJSWith(converter, v, k, json)}));
	    }
	    if (isPlainObj(json)) {
	      return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k)  {return fromJSWith(converter, v, k, json)}));
	    }
	    return json;
	  }
	
	  function fromJSDefault(json) {
	    if (Array.isArray(json)) {
	      return IndexedSeq(json).map(fromJSDefault).toList();
	    }
	    if (isPlainObj(json)) {
	      return KeyedSeq(json).map(fromJSDefault).toMap();
	    }
	    return json;
	  }
	
	  function isPlainObj(value) {
	    return value && (value.constructor === Object || value.constructor === undefined);
	  }
	
	  /**
	   * An extension of the "same-value" algorithm as [described for use by ES6 Map
	   * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)
	   *
	   * NaN is considered the same as NaN, however -0 and 0 are considered the same
	   * value, which is different from the algorithm described by
	   * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
	   *
	   * This is extended further to allow Objects to describe the values they
	   * represent, by way of `valueOf` or `equals` (and `hashCode`).
	   *
	   * Note: because of this extension, the key equality of Immutable.Map and the
	   * value equality of Immutable.Set will differ from ES6 Map and Set.
	   *
	   * ### Defining custom values
	   *
	   * The easiest way to describe the value an object represents is by implementing
	   * `valueOf`. For example, `Date` represents a value by returning a unix
	   * timestamp for `valueOf`:
	   *
	   *     var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...
	   *     var date2 = new Date(1234567890000);
	   *     date1.valueOf(); // 1234567890000
	   *     assert( date1 !== date2 );
	   *     assert( Immutable.is( date1, date2 ) );
	   *
	   * Note: overriding `valueOf` may have other implications if you use this object
	   * where JavaScript expects a primitive, such as implicit string coercion.
	   *
	   * For more complex types, especially collections, implementing `valueOf` may
	   * not be performant. An alternative is to implement `equals` and `hashCode`.
	   *
	   * `equals` takes another object, presumably of similar type, and returns true
	   * if the it is equal. Equality is symmetrical, so the same result should be
	   * returned if this and the argument are flipped.
	   *
	   *     assert( a.equals(b) === b.equals(a) );
	   *
	   * `hashCode` returns a 32bit integer number representing the object which will
	   * be used to determine how to store the value object in a Map or Set. You must
	   * provide both or neither methods, one must not exist without the other.
	   *
	   * Also, an important relationship between these methods must be upheld: if two
	   * values are equal, they *must* return the same hashCode. If the values are not
	   * equal, they might have the same hashCode; this is called a hash collision,
	   * and while undesirable for performance reasons, it is acceptable.
	   *
	   *     if (a.equals(b)) {
	   *       assert( a.hashCode() === b.hashCode() );
	   *     }
	   *
	   * All Immutable collections implement `equals` and `hashCode`.
	   *
	   */
	  function is(valueA, valueB) {
	    if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
	      return true;
	    }
	    if (!valueA || !valueB) {
	      return false;
	    }
	    if (typeof valueA.valueOf === 'function' &&
	        typeof valueB.valueOf === 'function') {
	      valueA = valueA.valueOf();
	      valueB = valueB.valueOf();
	      if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
	        return true;
	      }
	      if (!valueA || !valueB) {
	        return false;
	      }
	    }
	    if (typeof valueA.equals === 'function' &&
	        typeof valueB.equals === 'function' &&
	        valueA.equals(valueB)) {
	      return true;
	    }
	    return false;
	  }
	
	  function deepEqual(a, b) {
	    if (a === b) {
	      return true;
	    }
	
	    if (
	      !isIterable(b) ||
	      a.size !== undefined && b.size !== undefined && a.size !== b.size ||
	      a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||
	      isKeyed(a) !== isKeyed(b) ||
	      isIndexed(a) !== isIndexed(b) ||
	      isOrdered(a) !== isOrdered(b)
	    ) {
	      return false;
	    }
	
	    if (a.size === 0 && b.size === 0) {
	      return true;
	    }
	
	    var notAssociative = !isAssociative(a);
	
	    if (isOrdered(a)) {
	      var entries = a.entries();
	      return b.every(function(v, k)  {
	        var entry = entries.next().value;
	        return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));
	      }) && entries.next().done;
	    }
	
	    var flipped = false;
	
	    if (a.size === undefined) {
	      if (b.size === undefined) {
	        if (typeof a.cacheResult === 'function') {
	          a.cacheResult();
	        }
	      } else {
	        flipped = true;
	        var _ = a;
	        a = b;
	        b = _;
	      }
	    }
	
	    var allEqual = true;
	    var bSize = b.__iterate(function(v, k)  {
	      if (notAssociative ? !a.has(v) :
	          flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {
	        allEqual = false;
	        return false;
	      }
	    });
	
	    return allEqual && a.size === bSize;
	  }
	
	  createClass(Repeat, IndexedSeq);
	
	    function Repeat(value, times) {
	      if (!(this instanceof Repeat)) {
	        return new Repeat(value, times);
	      }
	      this._value = value;
	      this.size = times === undefined ? Infinity : Math.max(0, times);
	      if (this.size === 0) {
	        if (EMPTY_REPEAT) {
	          return EMPTY_REPEAT;
	        }
	        EMPTY_REPEAT = this;
	      }
	    }
	
	    Repeat.prototype.toString = function() {
	      if (this.size === 0) {
	        return 'Repeat []';
	      }
	      return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';
	    };
	
	    Repeat.prototype.get = function(index, notSetValue) {
	      return this.has(index) ? this._value : notSetValue;
	    };
	
	    Repeat.prototype.includes = function(searchValue) {
	      return is(this._value, searchValue);
	    };
	
	    Repeat.prototype.slice = function(begin, end) {
	      var size = this.size;
	      return wholeSlice(begin, end, size) ? this :
	        new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
	    };
	
	    Repeat.prototype.reverse = function() {
	      return this;
	    };
	
	    Repeat.prototype.indexOf = function(searchValue) {
	      if (is(this._value, searchValue)) {
	        return 0;
	      }
	      return -1;
	    };
	
	    Repeat.prototype.lastIndexOf = function(searchValue) {
	      if (is(this._value, searchValue)) {
	        return this.size;
	      }
	      return -1;
	    };
	
	    Repeat.prototype.__iterate = function(fn, reverse) {
	      for (var ii = 0; ii < this.size; ii++) {
	        if (fn(this._value, ii, this) === false) {
	          return ii + 1;
	        }
	      }
	      return ii;
	    };
	
	    Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;
	      var ii = 0;
	      return new Iterator(function() 
	        {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}
	      );
	    };
	
	    Repeat.prototype.equals = function(other) {
	      return other instanceof Repeat ?
	        is(this._value, other._value) :
	        deepEqual(other);
	    };
	
	
	  var EMPTY_REPEAT;
	
	  function invariant(condition, error) {
	    if (!condition) throw new Error(error);
	  }
	
	  createClass(Range, IndexedSeq);
	
	    function Range(start, end, step) {
	      if (!(this instanceof Range)) {
	        return new Range(start, end, step);
	      }
	      invariant(step !== 0, 'Cannot step a Range by 0');
	      start = start || 0;
	      if (end === undefined) {
	        end = Infinity;
	      }
	      step = step === undefined ? 1 : Math.abs(step);
	      if (end < start) {
	        step = -step;
	      }
	      this._start = start;
	      this._end = end;
	      this._step = step;
	      this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
	      if (this.size === 0) {
	        if (EMPTY_RANGE) {
	          return EMPTY_RANGE;
	        }
	        EMPTY_RANGE = this;
	      }
	    }
	
	    Range.prototype.toString = function() {
	      if (this.size === 0) {
	        return 'Range []';
	      }
	      return 'Range [ ' +
	        this._start + '...' + this._end +
	        (this._step !== 1 ? ' by ' + this._step : '') +
	      ' ]';
	    };
	
	    Range.prototype.get = function(index, notSetValue) {
	      return this.has(index) ?
	        this._start + wrapIndex(this, index) * this._step :
	        notSetValue;
	    };
	
	    Range.prototype.includes = function(searchValue) {
	      var possibleIndex = (searchValue - this._start) / this._step;
	      return possibleIndex >= 0 &&
	        possibleIndex < this.size &&
	        possibleIndex === Math.floor(possibleIndex);
	    };
	
	    Range.prototype.slice = function(begin, end) {
	      if (wholeSlice(begin, end, this.size)) {
	        return this;
	      }
	      begin = resolveBegin(begin, this.size);
	      end = resolveEnd(end, this.size);
	      if (end <= begin) {
	        return new Range(0, 0);
	      }
	      return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);
	    };
	
	    Range.prototype.indexOf = function(searchValue) {
	      var offsetValue = searchValue - this._start;
	      if (offsetValue % this._step === 0) {
	        var index = offsetValue / this._step;
	        if (index >= 0 && index < this.size) {
	          return index
	        }
	      }
	      return -1;
	    };
	
	    Range.prototype.lastIndexOf = function(searchValue) {
	      return this.indexOf(searchValue);
	    };
	
	    Range.prototype.__iterate = function(fn, reverse) {
	      var maxIndex = this.size - 1;
	      var step = this._step;
	      var value = reverse ? this._start + maxIndex * step : this._start;
	      for (var ii = 0; ii <= maxIndex; ii++) {
	        if (fn(value, ii, this) === false) {
	          return ii + 1;
	        }
	        value += reverse ? -step : step;
	      }
	      return ii;
	    };
	
	    Range.prototype.__iterator = function(type, reverse) {
	      var maxIndex = this.size - 1;
	      var step = this._step;
	      var value = reverse ? this._start + maxIndex * step : this._start;
	      var ii = 0;
	      return new Iterator(function()  {
	        var v = value;
	        value += reverse ? -step : step;
	        return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);
	      });
	    };
	
	    Range.prototype.equals = function(other) {
	      return other instanceof Range ?
	        this._start === other._start &&
	        this._end === other._end &&
	        this._step === other._step :
	        deepEqual(this, other);
	    };
	
	
	  var EMPTY_RANGE;
	
	  createClass(Collection, Iterable);
	    function Collection() {
	      throw TypeError('Abstract');
	    }
	
	
	  createClass(KeyedCollection, Collection);function KeyedCollection() {}
	
	  createClass(IndexedCollection, Collection);function IndexedCollection() {}
	
	  createClass(SetCollection, Collection);function SetCollection() {}
	
	
	  Collection.Keyed = KeyedCollection;
	  Collection.Indexed = IndexedCollection;
	  Collection.Set = SetCollection;
	
	  var imul =
	    typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?
	    Math.imul :
	    function imul(a, b) {
	      a = a | 0; // int
	      b = b | 0; // int
	      var c = a & 0xffff;
	      var d = b & 0xffff;
	      // Shift by 0 fixes the sign on the high part.
	      return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int
	    };
	
	  // v8 has an optimization for storing 31-bit signed numbers.
	  // Values which have either 00 or 11 as the high order bits qualify.
	  // This function drops the highest order bit in a signed number, maintaining
	  // the sign bit.
	  function smi(i32) {
	    return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);
	  }
	
	  function hash(o) {
	    if (o === false || o === null || o === undefined) {
	      return 0;
	    }
	    if (typeof o.valueOf === 'function') {
	      o = o.valueOf();
	      if (o === false || o === null || o === undefined) {
	        return 0;
	      }
	    }
	    if (o === true) {
	      return 1;
	    }
	    var type = typeof o;
	    if (type === 'number') {
	      if (o !== o || o === Infinity) {
	        return 0;
	      }
	      var h = o | 0;
	      if (h !== o) {
	        h ^= o * 0xFFFFFFFF;
	      }
	      while (o > 0xFFFFFFFF) {
	        o /= 0xFFFFFFFF;
	        h ^= o;
	      }
	      return smi(h);
	    }
	    if (type === 'string') {
	      return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);
	    }
	    if (typeof o.hashCode === 'function') {
	      return o.hashCode();
	    }
	    if (type === 'object') {
	      return hashJSObj(o);
	    }
	    if (typeof o.toString === 'function') {
	      return hashString(o.toString());
	    }
	    throw new Error('Value type ' + type + ' cannot be hashed.');
	  }
	
	  function cachedHashString(string) {
	    var hash = stringHashCache[string];
	    if (hash === undefined) {
	      hash = hashString(string);
	      if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {
	        STRING_HASH_CACHE_SIZE = 0;
	        stringHashCache = {};
	      }
	      STRING_HASH_CACHE_SIZE++;
	      stringHashCache[string] = hash;
	    }
	    return hash;
	  }
	
	  // http://jsperf.com/hashing-strings
	  function hashString(string) {
	    // This is the hash from JVM
	    // The hash code for a string is computed as
	    // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
	    // where s[i] is the ith character of the string and n is the length of
	    // the string. We "mod" the result to make it between 0 (inclusive) and 2^31
	    // (exclusive) by dropping high bits.
	    var hash = 0;
	    for (var ii = 0; ii < string.length; ii++) {
	      hash = 31 * hash + string.charCodeAt(ii) | 0;
	    }
	    return smi(hash);
	  }
	
	  function hashJSObj(obj) {
	    var hash;
	    if (usingWeakMap) {
	      hash = weakMap.get(obj);
	      if (hash !== undefined) {
	        return hash;
	      }
	    }
	
	    hash = obj[UID_HASH_KEY];
	    if (hash !== undefined) {
	      return hash;
	    }
	
	    if (!canDefineProperty) {
	      hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];
	      if (hash !== undefined) {
	        return hash;
	      }
	
	      hash = getIENodeHash(obj);
	      if (hash !== undefined) {
	        return hash;
	      }
	    }
	
	    hash = ++objHashUID;
	    if (objHashUID & 0x40000000) {
	      objHashUID = 0;
	    }
	
	    if (usingWeakMap) {
	      weakMap.set(obj, hash);
	    } else if (isExtensible !== undefined && isExtensible(obj) === false) {
	      throw new Error('Non-extensible objects are not allowed as keys.');
	    } else if (canDefineProperty) {
	      Object.defineProperty(obj, UID_HASH_KEY, {
	        'enumerable': false,
	        'configurable': false,
	        'writable': false,
	        'value': hash
	      });
	    } else if (obj.propertyIsEnumerable !== undefined &&
	               obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {
	      // Since we can't define a non-enumerable property on the object
	      // we'll hijack one of the less-used non-enumerable properties to
	      // save our hash on it. Since this is a function it will not show up in
	      // `JSON.stringify` which is what we want.
	      obj.propertyIsEnumerable = function() {
	        return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);
	      };
	      obj.propertyIsEnumerable[UID_HASH_KEY] = hash;
	    } else if (obj.nodeType !== undefined) {
	      // At this point we couldn't get the IE `uniqueID` to use as a hash
	      // and we couldn't use a non-enumerable property to exploit the
	      // dontEnum bug so we simply add the `UID_HASH_KEY` on the node
	      // itself.
	      obj[UID_HASH_KEY] = hash;
	    } else {
	      throw new Error('Unable to set a non-enumerable property on object.');
	    }
	
	    return hash;
	  }
	
	  // Get references to ES5 object methods.
	  var isExtensible = Object.isExtensible;
	
	  // True if Object.defineProperty works as expected. IE8 fails this test.
	  var canDefineProperty = (function() {
	    try {
	      Object.defineProperty({}, '@', {});
	      return true;
	    } catch (e) {
	      return false;
	    }
	  }());
	
	  // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it
	  // and avoid memory leaks from the IE cloneNode bug.
	  function getIENodeHash(node) {
	    if (node && node.nodeType > 0) {
	      switch (node.nodeType) {
	        case 1: // Element
	          return node.uniqueID;
	        case 9: // Document
	          return node.documentElement && node.documentElement.uniqueID;
	      }
	    }
	  }
	
	  // If possible, use a WeakMap.
	  var usingWeakMap = typeof WeakMap === 'function';
	  var weakMap;
	  if (usingWeakMap) {
	    weakMap = new WeakMap();
	  }
	
	  var objHashUID = 0;
	
	  var UID_HASH_KEY = '__immutablehash__';
	  if (typeof Symbol === 'function') {
	    UID_HASH_KEY = Symbol(UID_HASH_KEY);
	  }
	
	  var STRING_HASH_CACHE_MIN_STRLEN = 16;
	  var STRING_HASH_CACHE_MAX_SIZE = 255;
	  var STRING_HASH_CACHE_SIZE = 0;
	  var stringHashCache = {};
	
	  function assertNotInfinite(size) {
	    invariant(
	      size !== Infinity,
	      'Cannot perform this action with an infinite size.'
	    );
	  }
	
	  createClass(Map, KeyedCollection);
	
	    // @pragma Construction
	
	    function Map(value) {
	      return value === null || value === undefined ? emptyMap() :
	        isMap(value) && !isOrdered(value) ? value :
	        emptyMap().withMutations(function(map ) {
	          var iter = KeyedIterable(value);
	          assertNotInfinite(iter.size);
	          iter.forEach(function(v, k)  {return map.set(k, v)});
	        });
	    }
	
	    Map.of = function() {var keyValues = SLICE$0.call(arguments, 0);
	      return emptyMap().withMutations(function(map ) {
	        for (var i = 0; i < keyValues.length; i += 2) {
	          if (i + 1 >= keyValues.length) {
	            throw new Error('Missing value for key: ' + keyValues[i]);
	          }
	          map.set(keyValues[i], keyValues[i + 1]);
	        }
	      });
	    };
	
	    Map.prototype.toString = function() {
	      return this.__toString('Map {', '}');
	    };
	
	    // @pragma Access
	
	    Map.prototype.get = function(k, notSetValue) {
	      return this._root ?
	        this._root.get(0, undefined, k, notSetValue) :
	        notSetValue;
	    };
	
	    // @pragma Modification
	
	    Map.prototype.set = function(k, v) {
	      return updateMap(this, k, v);
	    };
	
	    Map.prototype.setIn = function(keyPath, v) {
	      return this.updateIn(keyPath, NOT_SET, function()  {return v});
	    };
	
	    Map.prototype.remove = function(k) {
	      return updateMap(this, k, NOT_SET);
	    };
	
	    Map.prototype.deleteIn = function(keyPath) {
	      return this.updateIn(keyPath, function()  {return NOT_SET});
	    };
	
	    Map.prototype.update = function(k, notSetValue, updater) {
	      return arguments.length === 1 ?
	        k(this) :
	        this.updateIn([k], notSetValue, updater);
	    };
	
	    Map.prototype.updateIn = function(keyPath, notSetValue, updater) {
	      if (!updater) {
	        updater = notSetValue;
	        notSetValue = undefined;
	      }
	      var updatedValue = updateInDeepMap(
	        this,
	        forceIterator(keyPath),
	        notSetValue,
	        updater
	      );
	      return updatedValue === NOT_SET ? undefined : updatedValue;
	    };
	
	    Map.prototype.clear = function() {
	      if (this.size === 0) {
	        return this;
	      }
	      if (this.__ownerID) {
	        this.size = 0;
	        this._root = null;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return emptyMap();
	    };
	
	    // @pragma Composition
	
	    Map.prototype.merge = function(/*...iters*/) {
	      return mergeIntoMapWith(this, undefined, arguments);
	    };
	
	    Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
	      return mergeIntoMapWith(this, merger, iters);
	    };
	
	    Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
	      return this.updateIn(
	        keyPath,
	        emptyMap(),
	        function(m ) {return typeof m.merge === 'function' ?
	          m.merge.apply(m, iters) :
	          iters[iters.length - 1]}
	      );
	    };
	
	    Map.prototype.mergeDeep = function(/*...iters*/) {
	      return mergeIntoMapWith(this, deepMerger, arguments);
	    };
	
	    Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
	      return mergeIntoMapWith(this, deepMergerWith(merger), iters);
	    };
	
	    Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
	      return this.updateIn(
	        keyPath,
	        emptyMap(),
	        function(m ) {return typeof m.mergeDeep === 'function' ?
	          m.mergeDeep.apply(m, iters) :
	          iters[iters.length - 1]}
	      );
	    };
	
	    Map.prototype.sort = function(comparator) {
	      // Late binding
	      return OrderedMap(sortFactory(this, comparator));
	    };
	
	    Map.prototype.sortBy = function(mapper, comparator) {
	      // Late binding
	      return OrderedMap(sortFactory(this, comparator, mapper));
	    };
	
	    // @pragma Mutability
	
	    Map.prototype.withMutations = function(fn) {
	      var mutable = this.asMutable();
	      fn(mutable);
	      return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;
	    };
	
	    Map.prototype.asMutable = function() {
	      return this.__ownerID ? this : this.__ensureOwner(new OwnerID());
	    };
	
	    Map.prototype.asImmutable = function() {
	      return this.__ensureOwner();
	    };
	
	    Map.prototype.wasAltered = function() {
	      return this.__altered;
	    };
	
	    Map.prototype.__iterator = function(type, reverse) {
	      return new MapIterator(this, type, reverse);
	    };
	
	    Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      var iterations = 0;
	      this._root && this._root.iterate(function(entry ) {
	        iterations++;
	        return fn(entry[1], entry[0], this$0);
	      }, reverse);
	      return iterations;
	    };
	
	    Map.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        this.__altered = false;
	        return this;
	      }
	      return makeMap(this.size, this._root, ownerID, this.__hash);
	    };
	
	
	  function isMap(maybeMap) {
	    return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);
	  }
	
	  Map.isMap = isMap;
	
	  var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';
	
	  var MapPrototype = Map.prototype;
	  MapPrototype[IS_MAP_SENTINEL] = true;
	  MapPrototype[DELETE] = MapPrototype.remove;
	  MapPrototype.removeIn = MapPrototype.deleteIn;
	
	
	  // #pragma Trie Nodes
	
	
	
	    function ArrayMapNode(ownerID, entries) {
	      this.ownerID = ownerID;
	      this.entries = entries;
	    }
	
	    ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
	      var entries = this.entries;
	      for (var ii = 0, len = entries.length; ii < len; ii++) {
	        if (is(key, entries[ii][0])) {
	          return entries[ii][1];
	        }
	      }
	      return notSetValue;
	    };
	
	    ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	      var removed = value === NOT_SET;
	
	      var entries = this.entries;
	      var idx = 0;
	      for (var len = entries.length; idx < len; idx++) {
	        if (is(key, entries[idx][0])) {
	          break;
	        }
	      }
	      var exists = idx < len;
	
	      if (exists ? entries[idx][1] === value : removed) {
	        return this;
	      }
	
	      SetRef(didAlter);
	      (removed || !exists) && SetRef(didChangeSize);
	
	      if (removed && entries.length === 1) {
	        return; // undefined
	      }
	
	      if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {
	        return createNodes(ownerID, entries, key, value);
	      }
	
	      var isEditable = ownerID && ownerID === this.ownerID;
	      var newEntries = isEditable ? entries : arrCopy(entries);
	
	      if (exists) {
	        if (removed) {
	          idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
	        } else {
	          newEntries[idx] = [key, value];
	        }
	      } else {
	        newEntries.push([key, value]);
	      }
	
	      if (isEditable) {
	        this.entries = newEntries;
	        return this;
	      }
	
	      return new ArrayMapNode(ownerID, newEntries);
	    };
	
	
	
	
	    function BitmapIndexedNode(ownerID, bitmap, nodes) {
	      this.ownerID = ownerID;
	      this.bitmap = bitmap;
	      this.nodes = nodes;
	    }
	
	    BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {
	      if (keyHash === undefined) {
	        keyHash = hash(key);
	      }
	      var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));
	      var bitmap = this.bitmap;
	      return (bitmap & bit) === 0 ? notSetValue :
	        this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);
	    };
	
	    BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	      if (keyHash === undefined) {
	        keyHash = hash(key);
	      }
	      var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
	      var bit = 1 << keyHashFrag;
	      var bitmap = this.bitmap;
	      var exists = (bitmap & bit) !== 0;
	
	      if (!exists && value === NOT_SET) {
	        return this;
	      }
	
	      var idx = popCount(bitmap & (bit - 1));
	      var nodes = this.nodes;
	      var node = exists ? nodes[idx] : undefined;
	      var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
	
	      if (newNode === node) {
	        return this;
	      }
	
	      if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {
	        return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);
	      }
	
	      if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {
	        return nodes[idx ^ 1];
	      }
	
	      if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {
	        return newNode;
	      }
	
	      var isEditable = ownerID && ownerID === this.ownerID;
	      var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;
	      var newNodes = exists ? newNode ?
	        setIn(nodes, idx, newNode, isEditable) :
	        spliceOut(nodes, idx, isEditable) :
	        spliceIn(nodes, idx, newNode, isEditable);
	
	      if (isEditable) {
	        this.bitmap = newBitmap;
	        this.nodes = newNodes;
	        return this;
	      }
	
	      return new BitmapIndexedNode(ownerID, newBitmap, newNodes);
	    };
	
	
	
	
	    function HashArrayMapNode(ownerID, count, nodes) {
	      this.ownerID = ownerID;
	      this.count = count;
	      this.nodes = nodes;
	    }
	
	    HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
	      if (keyHash === undefined) {
	        keyHash = hash(key);
	      }
	      var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
	      var node = this.nodes[idx];
	      return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;
	    };
	
	    HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	      if (keyHash === undefined) {
	        keyHash = hash(key);
	      }
	      var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
	      var removed = value === NOT_SET;
	      var nodes = this.nodes;
	      var node = nodes[idx];
	
	      if (removed && !node) {
	        return this;
	      }
	
	      var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
	      if (newNode === node) {
	        return this;
	      }
	
	      var newCount = this.count;
	      if (!node) {
	        newCount++;
	      } else if (!newNode) {
	        newCount--;
	        if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {
	          return packNodes(ownerID, nodes, newCount, idx);
	        }
	      }
	
	      var isEditable = ownerID && ownerID === this.ownerID;
	      var newNodes = setIn(nodes, idx, newNode, isEditable);
	
	      if (isEditable) {
	        this.count = newCount;
	        this.nodes = newNodes;
	        return this;
	      }
	
	      return new HashArrayMapNode(ownerID, newCount, newNodes);
	    };
	
	
	
	
	    function HashCollisionNode(ownerID, keyHash, entries) {
	      this.ownerID = ownerID;
	      this.keyHash = keyHash;
	      this.entries = entries;
	    }
	
	    HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {
	      var entries = this.entries;
	      for (var ii = 0, len = entries.length; ii < len; ii++) {
	        if (is(key, entries[ii][0])) {
	          return entries[ii][1];
	        }
	      }
	      return notSetValue;
	    };
	
	    HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	      if (keyHash === undefined) {
	        keyHash = hash(key);
	      }
	
	      var removed = value === NOT_SET;
	
	      if (keyHash !== this.keyHash) {
	        if (removed) {
	          return this;
	        }
	        SetRef(didAlter);
	        SetRef(didChangeSize);
	        return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);
	      }
	
	      var entries = this.entries;
	      var idx = 0;
	      for (var len = entries.length; idx < len; idx++) {
	        if (is(key, entries[idx][0])) {
	          break;
	        }
	      }
	      var exists = idx < len;
	
	      if (exists ? entries[idx][1] === value : removed) {
	        return this;
	      }
	
	      SetRef(didAlter);
	      (removed || !exists) && SetRef(didChangeSize);
	
	      if (removed && len === 2) {
	        return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);
	      }
	
	      var isEditable = ownerID && ownerID === this.ownerID;
	      var newEntries = isEditable ? entries : arrCopy(entries);
	
	      if (exists) {
	        if (removed) {
	          idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
	        } else {
	          newEntries[idx] = [key, value];
	        }
	      } else {
	        newEntries.push([key, value]);
	      }
	
	      if (isEditable) {
	        this.entries = newEntries;
	        return this;
	      }
	
	      return new HashCollisionNode(ownerID, this.keyHash, newEntries);
	    };
	
	
	
	
	    function ValueNode(ownerID, keyHash, entry) {
	      this.ownerID = ownerID;
	      this.keyHash = keyHash;
	      this.entry = entry;
	    }
	
	    ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {
	      return is(key, this.entry[0]) ? this.entry[1] : notSetValue;
	    };
	
	    ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	      var removed = value === NOT_SET;
	      var keyMatch = is(key, this.entry[0]);
	      if (keyMatch ? value === this.entry[1] : removed) {
	        return this;
	      }
	
	      SetRef(didAlter);
	
	      if (removed) {
	        SetRef(didChangeSize);
	        return; // undefined
	      }
	
	      if (keyMatch) {
	        if (ownerID && ownerID === this.ownerID) {
	          this.entry[1] = value;
	          return this;
	        }
	        return new ValueNode(ownerID, this.keyHash, [key, value]);
	      }
	
	      SetRef(didChangeSize);
	      return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);
	    };
	
	
	
	  // #pragma Iterators
	
	  ArrayMapNode.prototype.iterate =
	  HashCollisionNode.prototype.iterate = function (fn, reverse) {
	    var entries = this.entries;
	    for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {
	      if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {
	        return false;
	      }
	    }
	  }
	
	  BitmapIndexedNode.prototype.iterate =
	  HashArrayMapNode.prototype.iterate = function (fn, reverse) {
	    var nodes = this.nodes;
	    for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {
	      var node = nodes[reverse ? maxIndex - ii : ii];
	      if (node && node.iterate(fn, reverse) === false) {
	        return false;
	      }
	    }
	  }
	
	  ValueNode.prototype.iterate = function (fn, reverse) {
	    return fn(this.entry);
	  }
	
	  createClass(MapIterator, Iterator);
	
	    function MapIterator(map, type, reverse) {
	      this._type = type;
	      this._reverse = reverse;
	      this._stack = map._root && mapIteratorFrame(map._root);
	    }
	
	    MapIterator.prototype.next = function() {
	      var type = this._type;
	      var stack = this._stack;
	      while (stack) {
	        var node = stack.node;
	        var index = stack.index++;
	        var maxIndex;
	        if (node.entry) {
	          if (index === 0) {
	            return mapIteratorValue(type, node.entry);
	          }
	        } else if (node.entries) {
	          maxIndex = node.entries.length - 1;
	          if (index <= maxIndex) {
	            return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);
	          }
	        } else {
	          maxIndex = node.nodes.length - 1;
	          if (index <= maxIndex) {
	            var subNode = node.nodes[this._reverse ? maxIndex - index : index];
	            if (subNode) {
	              if (subNode.entry) {
	                return mapIteratorValue(type, subNode.entry);
	              }
	              stack = this._stack = mapIteratorFrame(subNode, stack);
	            }
	            continue;
	          }
	        }
	        stack = this._stack = this._stack.__prev;
	      }
	      return iteratorDone();
	    };
	
	
	  function mapIteratorValue(type, entry) {
	    return iteratorValue(type, entry[0], entry[1]);
	  }
	
	  function mapIteratorFrame(node, prev) {
	    return {
	      node: node,
	      index: 0,
	      __prev: prev
	    };
	  }
	
	  function makeMap(size, root, ownerID, hash) {
	    var map = Object.create(MapPrototype);
	    map.size = size;
	    map._root = root;
	    map.__ownerID = ownerID;
	    map.__hash = hash;
	    map.__altered = false;
	    return map;
	  }
	
	  var EMPTY_MAP;
	  function emptyMap() {
	    return EMPTY_MAP || (EMPTY_MAP = makeMap(0));
	  }
	
	  function updateMap(map, k, v) {
	    var newRoot;
	    var newSize;
	    if (!map._root) {
	      if (v === NOT_SET) {
	        return map;
	      }
	      newSize = 1;
	      newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);
	    } else {
	      var didChangeSize = MakeRef(CHANGE_LENGTH);
	      var didAlter = MakeRef(DID_ALTER);
	      newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);
	      if (!didAlter.value) {
	        return map;
	      }
	      newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);
	    }
	    if (map.__ownerID) {
	      map.size = newSize;
	      map._root = newRoot;
	      map.__hash = undefined;
	      map.__altered = true;
	      return map;
	    }
	    return newRoot ? makeMap(newSize, newRoot) : emptyMap();
	  }
	
	  function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
	    if (!node) {
	      if (value === NOT_SET) {
	        return node;
	      }
	      SetRef(didAlter);
	      SetRef(didChangeSize);
	      return new ValueNode(ownerID, keyHash, [key, value]);
	    }
	    return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);
	  }
	
	  function isLeafNode(node) {
	    return node.constructor === ValueNode || node.constructor === HashCollisionNode;
	  }
	
	  function mergeIntoNode(node, ownerID, shift, keyHash, entry) {
	    if (node.keyHash === keyHash) {
	      return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);
	    }
	
	    var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;
	    var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
	
	    var newNode;
	    var nodes = idx1 === idx2 ?
	      [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :
	      ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);
	
	    return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);
	  }
	
	  function createNodes(ownerID, entries, key, value) {
	    if (!ownerID) {
	      ownerID = new OwnerID();
	    }
	    var node = new ValueNode(ownerID, hash(key), [key, value]);
	    for (var ii = 0; ii < entries.length; ii++) {
	      var entry = entries[ii];
	      node = node.update(ownerID, 0, undefined, entry[0], entry[1]);
	    }
	    return node;
	  }
	
	  function packNodes(ownerID, nodes, count, excluding) {
	    var bitmap = 0;
	    var packedII = 0;
	    var packedNodes = new Array(count);
	    for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {
	      var node = nodes[ii];
	      if (node !== undefined && ii !== excluding) {
	        bitmap |= bit;
	        packedNodes[packedII++] = node;
	      }
	    }
	    return new BitmapIndexedNode(ownerID, bitmap, packedNodes);
	  }
	
	  function expandNodes(ownerID, nodes, bitmap, including, node) {
	    var count = 0;
	    var expandedNodes = new Array(SIZE);
	    for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {
	      expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;
	    }
	    expandedNodes[including] = node;
	    return new HashArrayMapNode(ownerID, count + 1, expandedNodes);
	  }
	
	  function mergeIntoMapWith(map, merger, iterables) {
	    var iters = [];
	    for (var ii = 0; ii < iterables.length; ii++) {
	      var value = iterables[ii];
	      var iter = KeyedIterable(value);
	      if (!isIterable(value)) {
	        iter = iter.map(function(v ) {return fromJS(v)});
	      }
	      iters.push(iter);
	    }
	    return mergeIntoCollectionWith(map, merger, iters);
	  }
	
	  function deepMerger(existing, value, key) {
	    return existing && existing.mergeDeep && isIterable(value) ?
	      existing.mergeDeep(value) :
	      is(existing, value) ? existing : value;
	  }
	
	  function deepMergerWith(merger) {
	    return function(existing, value, key)  {
	      if (existing && existing.mergeDeepWith && isIterable(value)) {
	        return existing.mergeDeepWith(merger, value);
	      }
	      var nextValue = merger(existing, value, key);
	      return is(existing, nextValue) ? existing : nextValue;
	    };
	  }
	
	  function mergeIntoCollectionWith(collection, merger, iters) {
	    iters = iters.filter(function(x ) {return x.size !== 0});
	    if (iters.length === 0) {
	      return collection;
	    }
	    if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {
	      return collection.constructor(iters[0]);
	    }
	    return collection.withMutations(function(collection ) {
	      var mergeIntoMap = merger ?
	        function(value, key)  {
	          collection.update(key, NOT_SET, function(existing )
	            {return existing === NOT_SET ? value : merger(existing, value, key)}
	          );
	        } :
	        function(value, key)  {
	          collection.set(key, value);
	        }
	      for (var ii = 0; ii < iters.length; ii++) {
	        iters[ii].forEach(mergeIntoMap);
	      }
	    });
	  }
	
	  function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {
	    var isNotSet = existing === NOT_SET;
	    var step = keyPathIter.next();
	    if (step.done) {
	      var existingValue = isNotSet ? notSetValue : existing;
	      var newValue = updater(existingValue);
	      return newValue === existingValue ? existing : newValue;
	    }
	    invariant(
	      isNotSet || (existing && existing.set),
	      'invalid keyPath'
	    );
	    var key = step.value;
	    var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);
	    var nextUpdated = updateInDeepMap(
	      nextExisting,
	      keyPathIter,
	      notSetValue,
	      updater
	    );
	    return nextUpdated === nextExisting ? existing :
	      nextUpdated === NOT_SET ? existing.remove(key) :
	      (isNotSet ? emptyMap() : existing).set(key, nextUpdated);
	  }
	
	  function popCount(x) {
	    x = x - ((x >> 1) & 0x55555555);
	    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
	    x = (x + (x >> 4)) & 0x0f0f0f0f;
	    x = x + (x >> 8);
	    x = x + (x >> 16);
	    return x & 0x7f;
	  }
	
	  function setIn(array, idx, val, canEdit) {
	    var newArray = canEdit ? array : arrCopy(array);
	    newArray[idx] = val;
	    return newArray;
	  }
	
	  function spliceIn(array, idx, val, canEdit) {
	    var newLen = array.length + 1;
	    if (canEdit && idx + 1 === newLen) {
	      array[idx] = val;
	      return array;
	    }
	    var newArray = new Array(newLen);
	    var after = 0;
	    for (var ii = 0; ii < newLen; ii++) {
	      if (ii === idx) {
	        newArray[ii] = val;
	        after = -1;
	      } else {
	        newArray[ii] = array[ii + after];
	      }
	    }
	    return newArray;
	  }
	
	  function spliceOut(array, idx, canEdit) {
	    var newLen = array.length - 1;
	    if (canEdit && idx === newLen) {
	      array.pop();
	      return array;
	    }
	    var newArray = new Array(newLen);
	    var after = 0;
	    for (var ii = 0; ii < newLen; ii++) {
	      if (ii === idx) {
	        after = 1;
	      }
	      newArray[ii] = array[ii + after];
	    }
	    return newArray;
	  }
	
	  var MAX_ARRAY_MAP_SIZE = SIZE / 4;
	  var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;
	  var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;
	
	  createClass(List, IndexedCollection);
	
	    // @pragma Construction
	
	    function List(value) {
	      var empty = emptyList();
	      if (value === null || value === undefined) {
	        return empty;
	      }
	      if (isList(value)) {
	        return value;
	      }
	      var iter = IndexedIterable(value);
	      var size = iter.size;
	      if (size === 0) {
	        return empty;
	      }
	      assertNotInfinite(size);
	      if (size > 0 && size < SIZE) {
	        return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
	      }
	      return empty.withMutations(function(list ) {
	        list.setSize(size);
	        iter.forEach(function(v, i)  {return list.set(i, v)});
	      });
	    }
	
	    List.of = function(/*...values*/) {
	      return this(arguments);
	    };
	
	    List.prototype.toString = function() {
	      return this.__toString('List [', ']');
	    };
	
	    // @pragma Access
	
	    List.prototype.get = function(index, notSetValue) {
	      index = wrapIndex(this, index);
	      if (index >= 0 && index < this.size) {
	        index += this._origin;
	        var node = listNodeFor(this, index);
	        return node && node.array[index & MASK];
	      }
	      return notSetValue;
	    };
	
	    // @pragma Modification
	
	    List.prototype.set = function(index, value) {
	      return updateList(this, index, value);
	    };
	
	    List.prototype.remove = function(index) {
	      return !this.has(index) ? this :
	        index === 0 ? this.shift() :
	        index === this.size - 1 ? this.pop() :
	        this.splice(index, 1);
	    };
	
	    List.prototype.insert = function(index, value) {
	      return this.splice(index, 0, value);
	    };
	
	    List.prototype.clear = function() {
	      if (this.size === 0) {
	        return this;
	      }
	      if (this.__ownerID) {
	        this.size = this._origin = this._capacity = 0;
	        this._level = SHIFT;
	        this._root = this._tail = null;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return emptyList();
	    };
	
	    List.prototype.push = function(/*...values*/) {
	      var values = arguments;
	      var oldSize = this.size;
	      return this.withMutations(function(list ) {
	        setListBounds(list, 0, oldSize + values.length);
	        for (var ii = 0; ii < values.length; ii++) {
	          list.set(oldSize + ii, values[ii]);
	        }
	      });
	    };
	
	    List.prototype.pop = function() {
	      return setListBounds(this, 0, -1);
	    };
	
	    List.prototype.unshift = function(/*...values*/) {
	      var values = arguments;
	      return this.withMutations(function(list ) {
	        setListBounds(list, -values.length);
	        for (var ii = 0; ii < values.length; ii++) {
	          list.set(ii, values[ii]);
	        }
	      });
	    };
	
	    List.prototype.shift = function() {
	      return setListBounds(this, 1);
	    };
	
	    // @pragma Composition
	
	    List.prototype.merge = function(/*...iters*/) {
	      return mergeIntoListWith(this, undefined, arguments);
	    };
	
	    List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
	      return mergeIntoListWith(this, merger, iters);
	    };
	
	    List.prototype.mergeDeep = function(/*...iters*/) {
	      return mergeIntoListWith(this, deepMerger, arguments);
	    };
	
	    List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
	      return mergeIntoListWith(this, deepMergerWith(merger), iters);
	    };
	
	    List.prototype.setSize = function(size) {
	      return setListBounds(this, 0, size);
	    };
	
	    // @pragma Iteration
	
	    List.prototype.slice = function(begin, end) {
	      var size = this.size;
	      if (wholeSlice(begin, end, size)) {
	        return this;
	      }
	      return setListBounds(
	        this,
	        resolveBegin(begin, size),
	        resolveEnd(end, size)
	      );
	    };
	
	    List.prototype.__iterator = function(type, reverse) {
	      var index = 0;
	      var values = iterateList(this, reverse);
	      return new Iterator(function()  {
	        var value = values();
	        return value === DONE ?
	          iteratorDone() :
	          iteratorValue(type, index++, value);
	      });
	    };
	
	    List.prototype.__iterate = function(fn, reverse) {
	      var index = 0;
	      var values = iterateList(this, reverse);
	      var value;
	      while ((value = values()) !== DONE) {
	        if (fn(value, index++, this) === false) {
	          break;
	        }
	      }
	      return index;
	    };
	
	    List.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        return this;
	      }
	      return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);
	    };
	
	
	  function isList(maybeList) {
	    return !!(maybeList && maybeList[IS_LIST_SENTINEL]);
	  }
	
	  List.isList = isList;
	
	  var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';
	
	  var ListPrototype = List.prototype;
	  ListPrototype[IS_LIST_SENTINEL] = true;
	  ListPrototype[DELETE] = ListPrototype.remove;
	  ListPrototype.setIn = MapPrototype.setIn;
	  ListPrototype.deleteIn =
	  ListPrototype.removeIn = MapPrototype.removeIn;
	  ListPrototype.update = MapPrototype.update;
	  ListPrototype.updateIn = MapPrototype.updateIn;
	  ListPrototype.mergeIn = MapPrototype.mergeIn;
	  ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
	  ListPrototype.withMutations = MapPrototype.withMutations;
	  ListPrototype.asMutable = MapPrototype.asMutable;
	  ListPrototype.asImmutable = MapPrototype.asImmutable;
	  ListPrototype.wasAltered = MapPrototype.wasAltered;
	
	
	
	    function VNode(array, ownerID) {
	      this.array = array;
	      this.ownerID = ownerID;
	    }
	
	    // TODO: seems like these methods are very similar
	
	    VNode.prototype.removeBefore = function(ownerID, level, index) {
	      if (index === level ? 1 << level : 0 || this.array.length === 0) {
	        return this;
	      }
	      var originIndex = (index >>> level) & MASK;
	      if (originIndex >= this.array.length) {
	        return new VNode([], ownerID);
	      }
	      var removingFirst = originIndex === 0;
	      var newChild;
	      if (level > 0) {
	        var oldChild = this.array[originIndex];
	        newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);
	        if (newChild === oldChild && removingFirst) {
	          return this;
	        }
	      }
	      if (removingFirst && !newChild) {
	        return this;
	      }
	      var editable = editableVNode(this, ownerID);
	      if (!removingFirst) {
	        for (var ii = 0; ii < originIndex; ii++) {
	          editable.array[ii] = undefined;
	        }
	      }
	      if (newChild) {
	        editable.array[originIndex] = newChild;
	      }
	      return editable;
	    };
	
	    VNode.prototype.removeAfter = function(ownerID, level, index) {
	      if (index === (level ? 1 << level : 0) || this.array.length === 0) {
	        return this;
	      }
	      var sizeIndex = ((index - 1) >>> level) & MASK;
	      if (sizeIndex >= this.array.length) {
	        return this;
	      }
	
	      var newChild;
	      if (level > 0) {
	        var oldChild = this.array[sizeIndex];
	        newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
	        if (newChild === oldChild && sizeIndex === this.array.length - 1) {
	          return this;
	        }
	      }
	
	      var editable = editableVNode(this, ownerID);
	      editable.array.splice(sizeIndex + 1);
	      if (newChild) {
	        editable.array[sizeIndex] = newChild;
	      }
	      return editable;
	    };
	
	
	
	  var DONE = {};
	
	  function iterateList(list, reverse) {
	    var left = list._origin;
	    var right = list._capacity;
	    var tailPos = getTailOffset(right);
	    var tail = list._tail;
	
	    return iterateNodeOrLeaf(list._root, list._level, 0);
	
	    function iterateNodeOrLeaf(node, level, offset) {
	      return level === 0 ?
	        iterateLeaf(node, offset) :
	        iterateNode(node, level, offset);
	    }
	
	    function iterateLeaf(node, offset) {
	      var array = offset === tailPos ? tail && tail.array : node && node.array;
	      var from = offset > left ? 0 : left - offset;
	      var to = right - offset;
	      if (to > SIZE) {
	        to = SIZE;
	      }
	      return function()  {
	        if (from === to) {
	          return DONE;
	        }
	        var idx = reverse ? --to : from++;
	        return array && array[idx];
	      };
	    }
	
	    function iterateNode(node, level, offset) {
	      var values;
	      var array = node && node.array;
	      var from = offset > left ? 0 : (left - offset) >> level;
	      var to = ((right - offset) >> level) + 1;
	      if (to > SIZE) {
	        to = SIZE;
	      }
	      return function()  {
	        do {
	          if (values) {
	            var value = values();
	            if (value !== DONE) {
	              return value;
	            }
	            values = null;
	          }
	          if (from === to) {
	            return DONE;
	          }
	          var idx = reverse ? --to : from++;
	          values = iterateNodeOrLeaf(
	            array && array[idx], level - SHIFT, offset + (idx << level)
	          );
	        } while (true);
	      };
	    }
	  }
	
	  function makeList(origin, capacity, level, root, tail, ownerID, hash) {
	    var list = Object.create(ListPrototype);
	    list.size = capacity - origin;
	    list._origin = origin;
	    list._capacity = capacity;
	    list._level = level;
	    list._root = root;
	    list._tail = tail;
	    list.__ownerID = ownerID;
	    list.__hash = hash;
	    list.__altered = false;
	    return list;
	  }
	
	  var EMPTY_LIST;
	  function emptyList() {
	    return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));
	  }
	
	  function updateList(list, index, value) {
	    index = wrapIndex(list, index);
	
	    if (index !== index) {
	      return list;
	    }
	
	    if (index >= list.size || index < 0) {
	      return list.withMutations(function(list ) {
	        index < 0 ?
	          setListBounds(list, index).set(0, value) :
	          setListBounds(list, 0, index + 1).set(index, value)
	      });
	    }
	
	    index += list._origin;
	
	    var newTail = list._tail;
	    var newRoot = list._root;
	    var didAlter = MakeRef(DID_ALTER);
	    if (index >= getTailOffset(list._capacity)) {
	      newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);
	    } else {
	      newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);
	    }
	
	    if (!didAlter.value) {
	      return list;
	    }
	
	    if (list.__ownerID) {
	      list._root = newRoot;
	      list._tail = newTail;
	      list.__hash = undefined;
	      list.__altered = true;
	      return list;
	    }
	    return makeList(list._origin, list._capacity, list._level, newRoot, newTail);
	  }
	
	  function updateVNode(node, ownerID, level, index, value, didAlter) {
	    var idx = (index >>> level) & MASK;
	    var nodeHas = node && idx < node.array.length;
	    if (!nodeHas && value === undefined) {
	      return node;
	    }
	
	    var newNode;
	
	    if (level > 0) {
	      var lowerNode = node && node.array[idx];
	      var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);
	      if (newLowerNode === lowerNode) {
	        return node;
	      }
	      newNode = editableVNode(node, ownerID);
	      newNode.array[idx] = newLowerNode;
	      return newNode;
	    }
	
	    if (nodeHas && node.array[idx] === value) {
	      return node;
	    }
	
	    SetRef(didAlter);
	
	    newNode = editableVNode(node, ownerID);
	    if (value === undefined && idx === newNode.array.length - 1) {
	      newNode.array.pop();
	    } else {
	      newNode.array[idx] = value;
	    }
	    return newNode;
	  }
	
	  function editableVNode(node, ownerID) {
	    if (ownerID && node && ownerID === node.ownerID) {
	      return node;
	    }
	    return new VNode(node ? node.array.slice() : [], ownerID);
	  }
	
	  function listNodeFor(list, rawIndex) {
	    if (rawIndex >= getTailOffset(list._capacity)) {
	      return list._tail;
	    }
	    if (rawIndex < 1 << (list._level + SHIFT)) {
	      var node = list._root;
	      var level = list._level;
	      while (node && level > 0) {
	        node = node.array[(rawIndex >>> level) & MASK];
	        level -= SHIFT;
	      }
	      return node;
	    }
	  }
	
	  function setListBounds(list, begin, end) {
	    // Sanitize begin & end using this shorthand for ToInt32(argument)
	    // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
	    if (begin !== undefined) {
	      begin = begin | 0;
	    }
	    if (end !== undefined) {
	      end = end | 0;
	    }
	    var owner = list.__ownerID || new OwnerID();
	    var oldOrigin = list._origin;
	    var oldCapacity = list._capacity;
	    var newOrigin = oldOrigin + begin;
	    var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;
	    if (newOrigin === oldOrigin && newCapacity === oldCapacity) {
	      return list;
	    }
	
	    // If it's going to end after it starts, it's empty.
	    if (newOrigin >= newCapacity) {
	      return list.clear();
	    }
	
	    var newLevel = list._level;
	    var newRoot = list._root;
	
	    // New origin might need creating a higher root.
	    var offsetShift = 0;
	    while (newOrigin + offsetShift < 0) {
	      newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);
	      newLevel += SHIFT;
	      offsetShift += 1 << newLevel;
	    }
	    if (offsetShift) {
	      newOrigin += offsetShift;
	      oldOrigin += offsetShift;
	      newCapacity += offsetShift;
	      oldCapacity += offsetShift;
	    }
	
	    var oldTailOffset = getTailOffset(oldCapacity);
	    var newTailOffset = getTailOffset(newCapacity);
	
	    // New size might need creating a higher root.
	    while (newTailOffset >= 1 << (newLevel + SHIFT)) {
	      newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);
	      newLevel += SHIFT;
	    }
	
	    // Locate or create the new tail.
	    var oldTail = list._tail;
	    var newTail = newTailOffset < oldTailOffset ?
	      listNodeFor(list, newCapacity - 1) :
	      newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
	
	    // Merge Tail into tree.
	    if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
	      newRoot = editableVNode(newRoot, owner);
	      var node = newRoot;
	      for (var level = newLevel; level > SHIFT; level -= SHIFT) {
	        var idx = (oldTailOffset >>> level) & MASK;
	        node = node.array[idx] = editableVNode(node.array[idx], owner);
	      }
	      node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;
	    }
	
	    // If the size has been reduced, there's a chance the tail needs to be trimmed.
	    if (newCapacity < oldCapacity) {
	      newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);
	    }
	
	    // If the new origin is within the tail, then we do not need a root.
	    if (newOrigin >= newTailOffset) {
	      newOrigin -= newTailOffset;
	      newCapacity -= newTailOffset;
	      newLevel = SHIFT;
	      newRoot = null;
	      newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);
	
	    // Otherwise, if the root has been trimmed, garbage collect.
	    } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {
	      offsetShift = 0;
	
	      // Identify the new top root node of the subtree of the old root.
	      while (newRoot) {
	        var beginIndex = (newOrigin >>> newLevel) & MASK;
	        if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {
	          break;
	        }
	        if (beginIndex) {
	          offsetShift += (1 << newLevel) * beginIndex;
	        }
	        newLevel -= SHIFT;
	        newRoot = newRoot.array[beginIndex];
	      }
	
	      // Trim the new sides of the new root.
	      if (newRoot && newOrigin > oldOrigin) {
	        newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);
	      }
	      if (newRoot && newTailOffset < oldTailOffset) {
	        newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);
	      }
	      if (offsetShift) {
	        newOrigin -= offsetShift;
	        newCapacity -= offsetShift;
	      }
	    }
	
	    if (list.__ownerID) {
	      list.size = newCapacity - newOrigin;
	      list._origin = newOrigin;
	      list._capacity = newCapacity;
	      list._level = newLevel;
	      list._root = newRoot;
	      list._tail = newTail;
	      list.__hash = undefined;
	      list.__altered = true;
	      return list;
	    }
	    return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);
	  }
	
	  function mergeIntoListWith(list, merger, iterables) {
	    var iters = [];
	    var maxSize = 0;
	    for (var ii = 0; ii < iterables.length; ii++) {
	      var value = iterables[ii];
	      var iter = IndexedIterable(value);
	      if (iter.size > maxSize) {
	        maxSize = iter.size;
	      }
	      if (!isIterable(value)) {
	        iter = iter.map(function(v ) {return fromJS(v)});
	      }
	      iters.push(iter);
	    }
	    if (maxSize > list.size) {
	      list = list.setSize(maxSize);
	    }
	    return mergeIntoCollectionWith(list, merger, iters);
	  }
	
	  function getTailOffset(size) {
	    return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);
	  }
	
	  createClass(OrderedMap, Map);
	
	    // @pragma Construction
	
	    function OrderedMap(value) {
	      return value === null || value === undefined ? emptyOrderedMap() :
	        isOrderedMap(value) ? value :
	        emptyOrderedMap().withMutations(function(map ) {
	          var iter = KeyedIterable(value);
	          assertNotInfinite(iter.size);
	          iter.forEach(function(v, k)  {return map.set(k, v)});
	        });
	    }
	
	    OrderedMap.of = function(/*...values*/) {
	      return this(arguments);
	    };
	
	    OrderedMap.prototype.toString = function() {
	      return this.__toString('OrderedMap {', '}');
	    };
	
	    // @pragma Access
	
	    OrderedMap.prototype.get = function(k, notSetValue) {
	      var index = this._map.get(k);
	      return index !== undefined ? this._list.get(index)[1] : notSetValue;
	    };
	
	    // @pragma Modification
	
	    OrderedMap.prototype.clear = function() {
	      if (this.size === 0) {
	        return this;
	      }
	      if (this.__ownerID) {
	        this.size = 0;
	        this._map.clear();
	        this._list.clear();
	        return this;
	      }
	      return emptyOrderedMap();
	    };
	
	    OrderedMap.prototype.set = function(k, v) {
	      return updateOrderedMap(this, k, v);
	    };
	
	    OrderedMap.prototype.remove = function(k) {
	      return updateOrderedMap(this, k, NOT_SET);
	    };
	
	    OrderedMap.prototype.wasAltered = function() {
	      return this._map.wasAltered() || this._list.wasAltered();
	    };
	
	    OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      return this._list.__iterate(
	        function(entry ) {return entry && fn(entry[1], entry[0], this$0)},
	        reverse
	      );
	    };
	
	    OrderedMap.prototype.__iterator = function(type, reverse) {
	      return this._list.fromEntrySeq().__iterator(type, reverse);
	    };
	
	    OrderedMap.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      var newMap = this._map.__ensureOwner(ownerID);
	      var newList = this._list.__ensureOwner(ownerID);
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        this._map = newMap;
	        this._list = newList;
	        return this;
	      }
	      return makeOrderedMap(newMap, newList, ownerID, this.__hash);
	    };
	
	
	  function isOrderedMap(maybeOrderedMap) {
	    return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);
	  }
	
	  OrderedMap.isOrderedMap = isOrderedMap;
	
	  OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;
	  OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;
	
	
	
	  function makeOrderedMap(map, list, ownerID, hash) {
	    var omap = Object.create(OrderedMap.prototype);
	    omap.size = map ? map.size : 0;
	    omap._map = map;
	    omap._list = list;
	    omap.__ownerID = ownerID;
	    omap.__hash = hash;
	    return omap;
	  }
	
	  var EMPTY_ORDERED_MAP;
	  function emptyOrderedMap() {
	    return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));
	  }
	
	  function updateOrderedMap(omap, k, v) {
	    var map = omap._map;
	    var list = omap._list;
	    var i = map.get(k);
	    var has = i !== undefined;
	    var newMap;
	    var newList;
	    if (v === NOT_SET) { // removed
	      if (!has) {
	        return omap;
	      }
	      if (list.size >= SIZE && list.size >= map.size * 2) {
	        newList = list.filter(function(entry, idx)  {return entry !== undefined && i !== idx});
	        newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();
	        if (omap.__ownerID) {
	          newMap.__ownerID = newList.__ownerID = omap.__ownerID;
	        }
	      } else {
	        newMap = map.remove(k);
	        newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);
	      }
	    } else {
	      if (has) {
	        if (v === list.get(i)[1]) {
	          return omap;
	        }
	        newMap = map;
	        newList = list.set(i, [k, v]);
	      } else {
	        newMap = map.set(k, list.size);
	        newList = list.set(list.size, [k, v]);
	      }
	    }
	    if (omap.__ownerID) {
	      omap.size = newMap.size;
	      omap._map = newMap;
	      omap._list = newList;
	      omap.__hash = undefined;
	      return omap;
	    }
	    return makeOrderedMap(newMap, newList);
	  }
	
	  createClass(ToKeyedSequence, KeyedSeq);
	    function ToKeyedSequence(indexed, useKeys) {
	      this._iter = indexed;
	      this._useKeys = useKeys;
	      this.size = indexed.size;
	    }
	
	    ToKeyedSequence.prototype.get = function(key, notSetValue) {
	      return this._iter.get(key, notSetValue);
	    };
	
	    ToKeyedSequence.prototype.has = function(key) {
	      return this._iter.has(key);
	    };
	
	    ToKeyedSequence.prototype.valueSeq = function() {
	      return this._iter.valueSeq();
	    };
	
	    ToKeyedSequence.prototype.reverse = function() {var this$0 = this;
	      var reversedSequence = reverseFactory(this, true);
	      if (!this._useKeys) {
	        reversedSequence.valueSeq = function()  {return this$0._iter.toSeq().reverse()};
	      }
	      return reversedSequence;
	    };
	
	    ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;
	      var mappedSequence = mapFactory(this, mapper, context);
	      if (!this._useKeys) {
	        mappedSequence.valueSeq = function()  {return this$0._iter.toSeq().map(mapper, context)};
	      }
	      return mappedSequence;
	    };
	
	    ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      var ii;
	      return this._iter.__iterate(
	        this._useKeys ?
	          function(v, k)  {return fn(v, k, this$0)} :
	          ((ii = reverse ? resolveSize(this) : 0),
	            function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),
	        reverse
	      );
	    };
	
	    ToKeyedSequence.prototype.__iterator = function(type, reverse) {
	      if (this._useKeys) {
	        return this._iter.__iterator(type, reverse);
	      }
	      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
	      var ii = reverse ? resolveSize(this) : 0;
	      return new Iterator(function()  {
	        var step = iterator.next();
	        return step.done ? step :
	          iteratorValue(type, reverse ? --ii : ii++, step.value, step);
	      });
	    };
	
	  ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;
	
	
	  createClass(ToIndexedSequence, IndexedSeq);
	    function ToIndexedSequence(iter) {
	      this._iter = iter;
	      this.size = iter.size;
	    }
	
	    ToIndexedSequence.prototype.includes = function(value) {
	      return this._iter.includes(value);
	    };
	
	    ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      var iterations = 0;
	      return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);
	    };
	
	    ToIndexedSequence.prototype.__iterator = function(type, reverse) {
	      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
	      var iterations = 0;
	      return new Iterator(function()  {
	        var step = iterator.next();
	        return step.done ? step :
	          iteratorValue(type, iterations++, step.value, step)
	      });
	    };
	
	
	
	  createClass(ToSetSequence, SetSeq);
	    function ToSetSequence(iter) {
	      this._iter = iter;
	      this.size = iter.size;
	    }
	
	    ToSetSequence.prototype.has = function(key) {
	      return this._iter.includes(key);
	    };
	
	    ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);
	    };
	
	    ToSetSequence.prototype.__iterator = function(type, reverse) {
	      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
	      return new Iterator(function()  {
	        var step = iterator.next();
	        return step.done ? step :
	          iteratorValue(type, step.value, step.value, step);
	      });
	    };
	
	
	
	  createClass(FromEntriesSequence, KeyedSeq);
	    function FromEntriesSequence(entries) {
	      this._iter = entries;
	      this.size = entries.size;
	    }
	
	    FromEntriesSequence.prototype.entrySeq = function() {
	      return this._iter.toSeq();
	    };
	
	    FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      return this._iter.__iterate(function(entry ) {
	        // Check if entry exists first so array access doesn't throw for holes
	        // in the parent iteration.
	        if (entry) {
	          validateEntry(entry);
	          var indexedIterable = isIterable(entry);
	          return fn(
	            indexedIterable ? entry.get(1) : entry[1],
	            indexedIterable ? entry.get(0) : entry[0],
	            this$0
	          );
	        }
	      }, reverse);
	    };
	
	    FromEntriesSequence.prototype.__iterator = function(type, reverse) {
	      var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
	      return new Iterator(function()  {
	        while (true) {
	          var step = iterator.next();
	          if (step.done) {
	            return step;
	          }
	          var entry = step.value;
	          // Check if entry exists first so array access doesn't throw for holes
	          // in the parent iteration.
	          if (entry) {
	            validateEntry(entry);
	            var indexedIterable = isIterable(entry);
	            return iteratorValue(
	              type,
	              indexedIterable ? entry.get(0) : entry[0],
	              indexedIterable ? entry.get(1) : entry[1],
	              step
	            );
	          }
	        }
	      });
	    };
	
	
	  ToIndexedSequence.prototype.cacheResult =
	  ToKeyedSequence.prototype.cacheResult =
	  ToSetSequence.prototype.cacheResult =
	  FromEntriesSequence.prototype.cacheResult =
	    cacheResultThrough;
	
	
	  function flipFactory(iterable) {
	    var flipSequence = makeSequence(iterable);
	    flipSequence._iter = iterable;
	    flipSequence.size = iterable.size;
	    flipSequence.flip = function()  {return iterable};
	    flipSequence.reverse = function () {
	      var reversedSequence = iterable.reverse.apply(this); // super.reverse()
	      reversedSequence.flip = function()  {return iterable.reverse()};
	      return reversedSequence;
	    };
	    flipSequence.has = function(key ) {return iterable.includes(key)};
	    flipSequence.includes = function(key ) {return iterable.has(key)};
	    flipSequence.cacheResult = cacheResultThrough;
	    flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
	      return iterable.__iterate(function(v, k)  {return fn(k, v, this$0) !== false}, reverse);
	    }
	    flipSequence.__iteratorUncached = function(type, reverse) {
	      if (type === ITERATE_ENTRIES) {
	        var iterator = iterable.__iterator(type, reverse);
	        return new Iterator(function()  {
	          var step = iterator.next();
	          if (!step.done) {
	            var k = step.value[0];
	            step.value[0] = step.value[1];
	            step.value[1] = k;
	          }
	          return step;
	        });
	      }
	      return iterable.__iterator(
	        type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,
	        reverse
	      );
	    }
	    return flipSequence;
	  }
	
	
	  function mapFactory(iterable, mapper, context) {
	    var mappedSequence = makeSequence(iterable);
	    mappedSequence.size = iterable.size;
	    mappedSequence.has = function(key ) {return iterable.has(key)};
	    mappedSequence.get = function(key, notSetValue)  {
	      var v = iterable.get(key, NOT_SET);
	      return v === NOT_SET ?
	        notSetValue :
	        mapper.call(context, v, key, iterable);
	    };
	    mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
	      return iterable.__iterate(
	        function(v, k, c)  {return fn(mapper.call(context, v, k, c), k, this$0) !== false},
	        reverse
	      );
	    }
	    mappedSequence.__iteratorUncached = function (type, reverse) {
	      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
	      return new Iterator(function()  {
	        var step = iterator.next();
	        if (step.done) {
	          return step;
	        }
	        var entry = step.value;
	        var key = entry[0];
	        return iteratorValue(
	          type,
	          key,
	          mapper.call(context, entry[1], key, iterable),
	          step
	        );
	      });
	    }
	    return mappedSequence;
	  }
	
	
	  function reverseFactory(iterable, useKeys) {
	    var reversedSequence = makeSequence(iterable);
	    reversedSequence._iter = iterable;
	    reversedSequence.size = iterable.size;
	    reversedSequence.reverse = function()  {return iterable};
	    if (iterable.flip) {
	      reversedSequence.flip = function () {
	        var flipSequence = flipFactory(iterable);
	        flipSequence.reverse = function()  {return iterable.flip()};
	        return flipSequence;
	      };
	    }
	    reversedSequence.get = function(key, notSetValue) 
	      {return iterable.get(useKeys ? key : -1 - key, notSetValue)};
	    reversedSequence.has = function(key )
	      {return iterable.has(useKeys ? key : -1 - key)};
	    reversedSequence.includes = function(value ) {return iterable.includes(value)};
	    reversedSequence.cacheResult = cacheResultThrough;
	    reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;
	      return iterable.__iterate(function(v, k)  {return fn(v, k, this$0)}, !reverse);
	    };
	    reversedSequence.__iterator =
	      function(type, reverse)  {return iterable.__iterator(type, !reverse)};
	    return reversedSequence;
	  }
	
	
	  function filterFactory(iterable, predicate, context, useKeys) {
	    var filterSequence = makeSequence(iterable);
	    if (useKeys) {
	      filterSequence.has = function(key ) {
	        var v = iterable.get(key, NOT_SET);
	        return v !== NOT_SET && !!predicate.call(context, v, key, iterable);
	      };
	      filterSequence.get = function(key, notSetValue)  {
	        var v = iterable.get(key, NOT_SET);
	        return v !== NOT_SET && predicate.call(context, v, key, iterable) ?
	          v : notSetValue;
	      };
	    }
	    filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
	      var iterations = 0;
	      iterable.__iterate(function(v, k, c)  {
	        if (predicate.call(context, v, k, c)) {
	          iterations++;
	          return fn(v, useKeys ? k : iterations - 1, this$0);
	        }
	      }, reverse);
	      return iterations;
	    };
	    filterSequence.__iteratorUncached = function (type, reverse) {
	      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
	      var iterations = 0;
	      return new Iterator(function()  {
	        while (true) {
	          var step = iterator.next();
	          if (step.done) {
	            return step;
	          }
	          var entry = step.value;
	          var key = entry[0];
	          var value = entry[1];
	          if (predicate.call(context, value, key, iterable)) {
	            return iteratorValue(type, useKeys ? key : iterations++, value, step);
	          }
	        }
	      });
	    }
	    return filterSequence;
	  }
	
	
	  function countByFactory(iterable, grouper, context) {
	    var groups = Map().asMutable();
	    iterable.__iterate(function(v, k)  {
	      groups.update(
	        grouper.call(context, v, k, iterable),
	        0,
	        function(a ) {return a + 1}
	      );
	    });
	    return groups.asImmutable();
	  }
	
	
	  function groupByFactory(iterable, grouper, context) {
	    var isKeyedIter = isKeyed(iterable);
	    var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable();
	    iterable.__iterate(function(v, k)  {
	      groups.update(
	        grouper.call(context, v, k, iterable),
	        function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}
	      );
	    });
	    var coerce = iterableClass(iterable);
	    return groups.map(function(arr ) {return reify(iterable, coerce(arr))});
	  }
	
	
	  function sliceFactory(iterable, begin, end, useKeys) {
	    var originalSize = iterable.size;
	
	    // Sanitize begin & end using this shorthand for ToInt32(argument)
	    // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
	    if (begin !== undefined) {
	      begin = begin | 0;
	    }
	    if (end !== undefined) {
	      if (end === Infinity) {
	        end = originalSize;
	      } else {
	        end = end | 0;
	      }
	    }
	
	    if (wholeSlice(begin, end, originalSize)) {
	      return iterable;
	    }
	
	    var resolvedBegin = resolveBegin(begin, originalSize);
	    var resolvedEnd = resolveEnd(end, originalSize);
	
	    // begin or end will be NaN if they were provided as negative numbers and
	    // this iterable's size is unknown. In that case, cache first so there is
	    // a known size and these do not resolve to NaN.
	    if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {
	      return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);
	    }
	
	    // Note: resolvedEnd is undefined when the original sequence's length is
	    // unknown and this slice did not supply an end and should contain all
	    // elements after resolvedBegin.
	    // In that case, resolvedSize will be NaN and sliceSize will remain undefined.
	    var resolvedSize = resolvedEnd - resolvedBegin;
	    var sliceSize;
	    if (resolvedSize === resolvedSize) {
	      sliceSize = resolvedSize < 0 ? 0 : resolvedSize;
	    }
	
	    var sliceSeq = makeSequence(iterable);
	
	    // If iterable.size is undefined, the size of the realized sliceSeq is
	    // unknown at this point unless the number of items to slice is 0
	    sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined;
	
	    if (!useKeys && isSeq(iterable) && sliceSize >= 0) {
	      sliceSeq.get = function (index, notSetValue) {
	        index = wrapIndex(this, index);
	        return index >= 0 && index < sliceSize ?
	          iterable.get(index + resolvedBegin, notSetValue) :
	          notSetValue;
	      }
	    }
	
	    sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;
	      if (sliceSize === 0) {
	        return 0;
	      }
	      if (reverse) {
	        return this.cacheResult().__iterate(fn, reverse);
	      }
	      var skipped = 0;
	      var isSkipping = true;
	      var iterations = 0;
	      iterable.__iterate(function(v, k)  {
	        if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {
	          iterations++;
	          return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&
	                 iterations !== sliceSize;
	        }
	      });
	      return iterations;
	    };
	
	    sliceSeq.__iteratorUncached = function(type, reverse) {
	      if (sliceSize !== 0 && reverse) {
	        return this.cacheResult().__iterator(type, reverse);
	      }
	      // Don't bother instantiating parent iterator if taking 0.
	      var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);
	      var skipped = 0;
	      var iterations = 0;
	      return new Iterator(function()  {
	        while (skipped++ < resolvedBegin) {
	          iterator.next();
	        }
	        if (++iterations > sliceSize) {
	          return iteratorDone();
	        }
	        var step = iterator.next();
	        if (useKeys || type === ITERATE_VALUES) {
	          return step;
	        } else if (type === ITERATE_KEYS) {
	          return iteratorValue(type, iterations - 1, undefined, step);
	        } else {
	          return iteratorValue(type, iterations - 1, step.value[1], step);
	        }
	      });
	    }
	
	    return sliceSeq;
	  }
	
	
	  function takeWhileFactory(iterable, predicate, context) {
	    var takeSequence = makeSequence(iterable);
	    takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
	      if (reverse) {
	        return this.cacheResult().__iterate(fn, reverse);
	      }
	      var iterations = 0;
	      iterable.__iterate(function(v, k, c) 
	        {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}
	      );
	      return iterations;
	    };
	    takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
	      if (reverse) {
	        return this.cacheResult().__iterator(type, reverse);
	      }
	      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
	      var iterating = true;
	      return new Iterator(function()  {
	        if (!iterating) {
	          return iteratorDone();
	        }
	        var step = iterator.next();
	        if (step.done) {
	          return step;
	        }
	        var entry = step.value;
	        var k = entry[0];
	        var v = entry[1];
	        if (!predicate.call(context, v, k, this$0)) {
	          iterating = false;
	          return iteratorDone();
	        }
	        return type === ITERATE_ENTRIES ? step :
	          iteratorValue(type, k, v, step);
	      });
	    };
	    return takeSequence;
	  }
	
	
	  function skipWhileFactory(iterable, predicate, context, useKeys) {
	    var skipSequence = makeSequence(iterable);
	    skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
	      if (reverse) {
	        return this.cacheResult().__iterate(fn, reverse);
	      }
	      var isSkipping = true;
	      var iterations = 0;
	      iterable.__iterate(function(v, k, c)  {
	        if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {
	          iterations++;
	          return fn(v, useKeys ? k : iterations - 1, this$0);
	        }
	      });
	      return iterations;
	    };
	    skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
	      if (reverse) {
	        return this.cacheResult().__iterator(type, reverse);
	      }
	      var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
	      var skipping = true;
	      var iterations = 0;
	      return new Iterator(function()  {
	        var step, k, v;
	        do {
	          step = iterator.next();
	          if (step.done) {
	            if (useKeys || type === ITERATE_VALUES) {
	              return step;
	            } else if (type === ITERATE_KEYS) {
	              return iteratorValue(type, iterations++, undefined, step);
	            } else {
	              return iteratorValue(type, iterations++, step.value[1], step);
	            }
	          }
	          var entry = step.value;
	          k = entry[0];
	          v = entry[1];
	          skipping && (skipping = predicate.call(context, v, k, this$0));
	        } while (skipping);
	        return type === ITERATE_ENTRIES ? step :
	          iteratorValue(type, k, v, step);
	      });
	    };
	    return skipSequence;
	  }
	
	
	  function concatFactory(iterable, values) {
	    var isKeyedIterable = isKeyed(iterable);
	    var iters = [iterable].concat(values).map(function(v ) {
	      if (!isIterable(v)) {
	        v = isKeyedIterable ?
	          keyedSeqFromValue(v) :
	          indexedSeqFromValue(Array.isArray(v) ? v : [v]);
	      } else if (isKeyedIterable) {
	        v = KeyedIterable(v);
	      }
	      return v;
	    }).filter(function(v ) {return v.size !== 0});
	
	    if (iters.length === 0) {
	      return iterable;
	    }
	
	    if (iters.length === 1) {
	      var singleton = iters[0];
	      if (singleton === iterable ||
	          isKeyedIterable && isKeyed(singleton) ||
	          isIndexed(iterable) && isIndexed(singleton)) {
	        return singleton;
	      }
	    }
	
	    var concatSeq = new ArraySeq(iters);
	    if (isKeyedIterable) {
	      concatSeq = concatSeq.toKeyedSeq();
	    } else if (!isIndexed(iterable)) {
	      concatSeq = concatSeq.toSetSeq();
	    }
	    concatSeq = concatSeq.flatten(true);
	    concatSeq.size = iters.reduce(
	      function(sum, seq)  {
	        if (sum !== undefined) {
	          var size = seq.size;
	          if (size !== undefined) {
	            return sum + size;
	          }
	        }
	      },
	      0
	    );
	    return concatSeq;
	  }
	
	
	  function flattenFactory(iterable, depth, useKeys) {
	    var flatSequence = makeSequence(iterable);
	    flatSequence.__iterateUncached = function(fn, reverse) {
	      var iterations = 0;
	      var stopped = false;
	      function flatDeep(iter, currentDepth) {var this$0 = this;
	        iter.__iterate(function(v, k)  {
	          if ((!depth || currentDepth < depth) && isIterable(v)) {
	            flatDeep(v, currentDepth + 1);
	          } else if (fn(v, useKeys ? k : iterations++, this$0) === false) {
	            stopped = true;
	          }
	          return !stopped;
	        }, reverse);
	      }
	      flatDeep(iterable, 0);
	      return iterations;
	    }
	    flatSequence.__iteratorUncached = function(type, reverse) {
	      var iterator = iterable.__iterator(type, reverse);
	      var stack = [];
	      var iterations = 0;
	      return new Iterator(function()  {
	        while (iterator) {
	          var step = iterator.next();
	          if (step.done !== false) {
	            iterator = stack.pop();
	            continue;
	          }
	          var v = step.value;
	          if (type === ITERATE_ENTRIES) {
	            v = v[1];
	          }
	          if ((!depth || stack.length < depth) && isIterable(v)) {
	            stack.push(iterator);
	            iterator = v.__iterator(type, reverse);
	          } else {
	            return useKeys ? step : iteratorValue(type, iterations++, v, step);
	          }
	        }
	        return iteratorDone();
	      });
	    }
	    return flatSequence;
	  }
	
	
	  function flatMapFactory(iterable, mapper, context) {
	    var coerce = iterableClass(iterable);
	    return iterable.toSeq().map(
	      function(v, k)  {return coerce(mapper.call(context, v, k, iterable))}
	    ).flatten(true);
	  }
	
	
	  function interposeFactory(iterable, separator) {
	    var interposedSequence = makeSequence(iterable);
	    interposedSequence.size = iterable.size && iterable.size * 2 -1;
	    interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
	      var iterations = 0;
	      iterable.__iterate(function(v, k) 
	        {return (!iterations || fn(separator, iterations++, this$0) !== false) &&
	        fn(v, iterations++, this$0) !== false},
	        reverse
	      );
	      return iterations;
	    };
	    interposedSequence.__iteratorUncached = function(type, reverse) {
	      var iterator = iterable.__iterator(ITERATE_VALUES, reverse);
	      var iterations = 0;
	      var step;
	      return new Iterator(function()  {
	        if (!step || iterations % 2) {
	          step = iterator.next();
	          if (step.done) {
	            return step;
	          }
	        }
	        return iterations % 2 ?
	          iteratorValue(type, iterations++, separator) :
	          iteratorValue(type, iterations++, step.value, step);
	      });
	    };
	    return interposedSequence;
	  }
	
	
	  function sortFactory(iterable, comparator, mapper) {
	    if (!comparator) {
	      comparator = defaultComparator;
	    }
	    var isKeyedIterable = isKeyed(iterable);
	    var index = 0;
	    var entries = iterable.toSeq().map(
	      function(v, k)  {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}
	    ).toArray();
	    entries.sort(function(a, b)  {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(
	      isKeyedIterable ?
	      function(v, i)  { entries[i].length = 2; } :
	      function(v, i)  { entries[i] = v[1]; }
	    );
	    return isKeyedIterable ? KeyedSeq(entries) :
	      isIndexed(iterable) ? IndexedSeq(entries) :
	      SetSeq(entries);
	  }
	
	
	  function maxFactory(iterable, comparator, mapper) {
	    if (!comparator) {
	      comparator = defaultComparator;
	    }
	    if (mapper) {
	      var entry = iterable.toSeq()
	        .map(function(v, k)  {return [v, mapper(v, k, iterable)]})
	        .reduce(function(a, b)  {return maxCompare(comparator, a[1], b[1]) ? b : a});
	      return entry && entry[0];
	    } else {
	      return iterable.reduce(function(a, b)  {return maxCompare(comparator, a, b) ? b : a});
	    }
	  }
	
	  function maxCompare(comparator, a, b) {
	    var comp = comparator(b, a);
	    // b is considered the new max if the comparator declares them equal, but
	    // they are not equal and b is in fact a nullish value.
	    return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;
	  }
	
	
	  function zipWithFactory(keyIter, zipper, iters) {
	    var zipSequence = makeSequence(keyIter);
	    zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();
	    // Note: this a generic base implementation of __iterate in terms of
	    // __iterator which may be more generically useful in the future.
	    zipSequence.__iterate = function(fn, reverse) {
	      /* generic:
	      var iterator = this.__iterator(ITERATE_ENTRIES, reverse);
	      var step;
	      var iterations = 0;
	      while (!(step = iterator.next()).done) {
	        iterations++;
	        if (fn(step.value[1], step.value[0], this) === false) {
	          break;
	        }
	      }
	      return iterations;
	      */
	      // indexed:
	      var iterator = this.__iterator(ITERATE_VALUES, reverse);
	      var step;
	      var iterations = 0;
	      while (!(step = iterator.next()).done) {
	        if (fn(step.value, iterations++, this) === false) {
	          break;
	        }
	      }
	      return iterations;
	    };
	    zipSequence.__iteratorUncached = function(type, reverse) {
	      var iterators = iters.map(function(i )
	        {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}
	      );
	      var iterations = 0;
	      var isDone = false;
	      return new Iterator(function()  {
	        var steps;
	        if (!isDone) {
	          steps = iterators.map(function(i ) {return i.next()});
	          isDone = steps.some(function(s ) {return s.done});
	        }
	        if (isDone) {
	          return iteratorDone();
	        }
	        return iteratorValue(
	          type,
	          iterations++,
	          zipper.apply(null, steps.map(function(s ) {return s.value}))
	        );
	      });
	    };
	    return zipSequence
	  }
	
	
	  // #pragma Helper Functions
	
	  function reify(iter, seq) {
	    return isSeq(iter) ? seq : iter.constructor(seq);
	  }
	
	  function validateEntry(entry) {
	    if (entry !== Object(entry)) {
	      throw new TypeError('Expected [K, V] tuple: ' + entry);
	    }
	  }
	
	  function resolveSize(iter) {
	    assertNotInfinite(iter.size);
	    return ensureSize(iter);
	  }
	
	  function iterableClass(iterable) {
	    return isKeyed(iterable) ? KeyedIterable :
	      isIndexed(iterable) ? IndexedIterable :
	      SetIterable;
	  }
	
	  function makeSequence(iterable) {
	    return Object.create(
	      (
	        isKeyed(iterable) ? KeyedSeq :
	        isIndexed(iterable) ? IndexedSeq :
	        SetSeq
	      ).prototype
	    );
	  }
	
	  function cacheResultThrough() {
	    if (this._iter.cacheResult) {
	      this._iter.cacheResult();
	      this.size = this._iter.size;
	      return this;
	    } else {
	      return Seq.prototype.cacheResult.call(this);
	    }
	  }
	
	  function defaultComparator(a, b) {
	    return a > b ? 1 : a < b ? -1 : 0;
	  }
	
	  function forceIterator(keyPath) {
	    var iter = getIterator(keyPath);
	    if (!iter) {
	      // Array might not be iterable in this environment, so we need a fallback
	      // to our wrapped type.
	      if (!isArrayLike(keyPath)) {
	        throw new TypeError('Expected iterable or array-like: ' + keyPath);
	      }
	      iter = getIterator(Iterable(keyPath));
	    }
	    return iter;
	  }
	
	  createClass(Record, KeyedCollection);
	
	    function Record(defaultValues, name) {
	      var hasInitialized;
	
	      var RecordType = function Record(values) {
	        if (values instanceof RecordType) {
	          return values;
	        }
	        if (!(this instanceof RecordType)) {
	          return new RecordType(values);
	        }
	        if (!hasInitialized) {
	          hasInitialized = true;
	          var keys = Object.keys(defaultValues);
	          setProps(RecordTypePrototype, keys);
	          RecordTypePrototype.size = keys.length;
	          RecordTypePrototype._name = name;
	          RecordTypePrototype._keys = keys;
	          RecordTypePrototype._defaultValues = defaultValues;
	        }
	        this._map = Map(values);
	      };
	
	      var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
	      RecordTypePrototype.constructor = RecordType;
	
	      return RecordType;
	    }
	
	    Record.prototype.toString = function() {
	      return this.__toString(recordName(this) + ' {', '}');
	    };
	
	    // @pragma Access
	
	    Record.prototype.has = function(k) {
	      return this._defaultValues.hasOwnProperty(k);
	    };
	
	    Record.prototype.get = function(k, notSetValue) {
	      if (!this.has(k)) {
	        return notSetValue;
	      }
	      var defaultVal = this._defaultValues[k];
	      return this._map ? this._map.get(k, defaultVal) : defaultVal;
	    };
	
	    // @pragma Modification
	
	    Record.prototype.clear = function() {
	      if (this.__ownerID) {
	        this._map && this._map.clear();
	        return this;
	      }
	      var RecordType = this.constructor;
	      return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));
	    };
	
	    Record.prototype.set = function(k, v) {
	      if (!this.has(k)) {
	        throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this));
	      }
	      if (this._map && !this._map.has(k)) {
	        var defaultVal = this._defaultValues[k];
	        if (v === defaultVal) {
	          return this;
	        }
	      }
	      var newMap = this._map && this._map.set(k, v);
	      if (this.__ownerID || newMap === this._map) {
	        return this;
	      }
	      return makeRecord(this, newMap);
	    };
	
	    Record.prototype.remove = function(k) {
	      if (!this.has(k)) {
	        return this;
	      }
	      var newMap = this._map && this._map.remove(k);
	      if (this.__ownerID || newMap === this._map) {
	        return this;
	      }
	      return makeRecord(this, newMap);
	    };
	
	    Record.prototype.wasAltered = function() {
	      return this._map.wasAltered();
	    };
	
	    Record.prototype.__iterator = function(type, reverse) {var this$0 = this;
	      return KeyedIterable(this._defaultValues).map(function(_, k)  {return this$0.get(k)}).__iterator(type, reverse);
	    };
	
	    Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      return KeyedIterable(this._defaultValues).map(function(_, k)  {return this$0.get(k)}).__iterate(fn, reverse);
	    };
	
	    Record.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      var newMap = this._map && this._map.__ensureOwner(ownerID);
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        this._map = newMap;
	        return this;
	      }
	      return makeRecord(this, newMap, ownerID);
	    };
	
	
	  var RecordPrototype = Record.prototype;
	  RecordPrototype[DELETE] = RecordPrototype.remove;
	  RecordPrototype.deleteIn =
	  RecordPrototype.removeIn = MapPrototype.removeIn;
	  RecordPrototype.merge = MapPrototype.merge;
	  RecordPrototype.mergeWith = MapPrototype.mergeWith;
	  RecordPrototype.mergeIn = MapPrototype.mergeIn;
	  RecordPrototype.mergeDeep = MapPrototype.mergeDeep;
	  RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;
	  RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
	  RecordPrototype.setIn = MapPrototype.setIn;
	  RecordPrototype.update = MapPrototype.update;
	  RecordPrototype.updateIn = MapPrototype.updateIn;
	  RecordPrototype.withMutations = MapPrototype.withMutations;
	  RecordPrototype.asMutable = MapPrototype.asMutable;
	  RecordPrototype.asImmutable = MapPrototype.asImmutable;
	
	
	  function makeRecord(likeRecord, map, ownerID) {
	    var record = Object.create(Object.getPrototypeOf(likeRecord));
	    record._map = map;
	    record.__ownerID = ownerID;
	    return record;
	  }
	
	  function recordName(record) {
	    return record._name || record.constructor.name || 'Record';
	  }
	
	  function setProps(prototype, names) {
	    try {
	      names.forEach(setProp.bind(undefined, prototype));
	    } catch (error) {
	      // Object.defineProperty failed. Probably IE8.
	    }
	  }
	
	  function setProp(prototype, name) {
	    Object.defineProperty(prototype, name, {
	      get: function() {
	        return this.get(name);
	      },
	      set: function(value) {
	        invariant(this.__ownerID, 'Cannot set on an immutable record.');
	        this.set(name, value);
	      }
	    });
	  }
	
	  createClass(Set, SetCollection);
	
	    // @pragma Construction
	
	    function Set(value) {
	      return value === null || value === undefined ? emptySet() :
	        isSet(value) && !isOrdered(value) ? value :
	        emptySet().withMutations(function(set ) {
	          var iter = SetIterable(value);
	          assertNotInfinite(iter.size);
	          iter.forEach(function(v ) {return set.add(v)});
	        });
	    }
	
	    Set.of = function(/*...values*/) {
	      return this(arguments);
	    };
	
	    Set.fromKeys = function(value) {
	      return this(KeyedIterable(value).keySeq());
	    };
	
	    Set.prototype.toString = function() {
	      return this.__toString('Set {', '}');
	    };
	
	    // @pragma Access
	
	    Set.prototype.has = function(value) {
	      return this._map.has(value);
	    };
	
	    // @pragma Modification
	
	    Set.prototype.add = function(value) {
	      return updateSet(this, this._map.set(value, true));
	    };
	
	    Set.prototype.remove = function(value) {
	      return updateSet(this, this._map.remove(value));
	    };
	
	    Set.prototype.clear = function() {
	      return updateSet(this, this._map.clear());
	    };
	
	    // @pragma Composition
	
	    Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);
	      iters = iters.filter(function(x ) {return x.size !== 0});
	      if (iters.length === 0) {
	        return this;
	      }
	      if (this.size === 0 && !this.__ownerID && iters.length === 1) {
	        return this.constructor(iters[0]);
	      }
	      return this.withMutations(function(set ) {
	        for (var ii = 0; ii < iters.length; ii++) {
	          SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});
	        }
	      });
	    };
	
	    Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);
	      if (iters.length === 0) {
	        return this;
	      }
	      iters = iters.map(function(iter ) {return SetIterable(iter)});
	      var originalSet = this;
	      return this.withMutations(function(set ) {
	        originalSet.forEach(function(value ) {
	          if (!iters.every(function(iter ) {return iter.includes(value)})) {
	            set.remove(value);
	          }
	        });
	      });
	    };
	
	    Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);
	      if (iters.length === 0) {
	        return this;
	      }
	      iters = iters.map(function(iter ) {return SetIterable(iter)});
	      var originalSet = this;
	      return this.withMutations(function(set ) {
	        originalSet.forEach(function(value ) {
	          if (iters.some(function(iter ) {return iter.includes(value)})) {
	            set.remove(value);
	          }
	        });
	      });
	    };
	
	    Set.prototype.merge = function() {
	      return this.union.apply(this, arguments);
	    };
	
	    Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
	      return this.union.apply(this, iters);
	    };
	
	    Set.prototype.sort = function(comparator) {
	      // Late binding
	      return OrderedSet(sortFactory(this, comparator));
	    };
	
	    Set.prototype.sortBy = function(mapper, comparator) {
	      // Late binding
	      return OrderedSet(sortFactory(this, comparator, mapper));
	    };
	
	    Set.prototype.wasAltered = function() {
	      return this._map.wasAltered();
	    };
	
	    Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;
	      return this._map.__iterate(function(_, k)  {return fn(k, k, this$0)}, reverse);
	    };
	
	    Set.prototype.__iterator = function(type, reverse) {
	      return this._map.map(function(_, k)  {return k}).__iterator(type, reverse);
	    };
	
	    Set.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      var newMap = this._map.__ensureOwner(ownerID);
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        this._map = newMap;
	        return this;
	      }
	      return this.__make(newMap, ownerID);
	    };
	
	
	  function isSet(maybeSet) {
	    return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);
	  }
	
	  Set.isSet = isSet;
	
	  var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';
	
	  var SetPrototype = Set.prototype;
	  SetPrototype[IS_SET_SENTINEL] = true;
	  SetPrototype[DELETE] = SetPrototype.remove;
	  SetPrototype.mergeDeep = SetPrototype.merge;
	  SetPrototype.mergeDeepWith = SetPrototype.mergeWith;
	  SetPrototype.withMutations = MapPrototype.withMutations;
	  SetPrototype.asMutable = MapPrototype.asMutable;
	  SetPrototype.asImmutable = MapPrototype.asImmutable;
	
	  SetPrototype.__empty = emptySet;
	  SetPrototype.__make = makeSet;
	
	  function updateSet(set, newMap) {
	    if (set.__ownerID) {
	      set.size = newMap.size;
	      set._map = newMap;
	      return set;
	    }
	    return newMap === set._map ? set :
	      newMap.size === 0 ? set.__empty() :
	      set.__make(newMap);
	  }
	
	  function makeSet(map, ownerID) {
	    var set = Object.create(SetPrototype);
	    set.size = map ? map.size : 0;
	    set._map = map;
	    set.__ownerID = ownerID;
	    return set;
	  }
	
	  var EMPTY_SET;
	  function emptySet() {
	    return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
	  }
	
	  createClass(OrderedSet, Set);
	
	    // @pragma Construction
	
	    function OrderedSet(value) {
	      return value === null || value === undefined ? emptyOrderedSet() :
	        isOrderedSet(value) ? value :
	        emptyOrderedSet().withMutations(function(set ) {
	          var iter = SetIterable(value);
	          assertNotInfinite(iter.size);
	          iter.forEach(function(v ) {return set.add(v)});
	        });
	    }
	
	    OrderedSet.of = function(/*...values*/) {
	      return this(arguments);
	    };
	
	    OrderedSet.fromKeys = function(value) {
	      return this(KeyedIterable(value).keySeq());
	    };
	
	    OrderedSet.prototype.toString = function() {
	      return this.__toString('OrderedSet {', '}');
	    };
	
	
	  function isOrderedSet(maybeOrderedSet) {
	    return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);
	  }
	
	  OrderedSet.isOrderedSet = isOrderedSet;
	
	  var OrderedSetPrototype = OrderedSet.prototype;
	  OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;
	
	  OrderedSetPrototype.__empty = emptyOrderedSet;
	  OrderedSetPrototype.__make = makeOrderedSet;
	
	  function makeOrderedSet(map, ownerID) {
	    var set = Object.create(OrderedSetPrototype);
	    set.size = map ? map.size : 0;
	    set._map = map;
	    set.__ownerID = ownerID;
	    return set;
	  }
	
	  var EMPTY_ORDERED_SET;
	  function emptyOrderedSet() {
	    return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));
	  }
	
	  createClass(Stack, IndexedCollection);
	
	    // @pragma Construction
	
	    function Stack(value) {
	      return value === null || value === undefined ? emptyStack() :
	        isStack(value) ? value :
	        emptyStack().unshiftAll(value);
	    }
	
	    Stack.of = function(/*...values*/) {
	      return this(arguments);
	    };
	
	    Stack.prototype.toString = function() {
	      return this.__toString('Stack [', ']');
	    };
	
	    // @pragma Access
	
	    Stack.prototype.get = function(index, notSetValue) {
	      var head = this._head;
	      index = wrapIndex(this, index);
	      while (head && index--) {
	        head = head.next;
	      }
	      return head ? head.value : notSetValue;
	    };
	
	    Stack.prototype.peek = function() {
	      return this._head && this._head.value;
	    };
	
	    // @pragma Modification
	
	    Stack.prototype.push = function(/*...values*/) {
	      if (arguments.length === 0) {
	        return this;
	      }
	      var newSize = this.size + arguments.length;
	      var head = this._head;
	      for (var ii = arguments.length - 1; ii >= 0; ii--) {
	        head = {
	          value: arguments[ii],
	          next: head
	        };
	      }
	      if (this.__ownerID) {
	        this.size = newSize;
	        this._head = head;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return makeStack(newSize, head);
	    };
	
	    Stack.prototype.pushAll = function(iter) {
	      iter = IndexedIterable(iter);
	      if (iter.size === 0) {
	        return this;
	      }
	      assertNotInfinite(iter.size);
	      var newSize = this.size;
	      var head = this._head;
	      iter.reverse().forEach(function(value ) {
	        newSize++;
	        head = {
	          value: value,
	          next: head
	        };
	      });
	      if (this.__ownerID) {
	        this.size = newSize;
	        this._head = head;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return makeStack(newSize, head);
	    };
	
	    Stack.prototype.pop = function() {
	      return this.slice(1);
	    };
	
	    Stack.prototype.unshift = function(/*...values*/) {
	      return this.push.apply(this, arguments);
	    };
	
	    Stack.prototype.unshiftAll = function(iter) {
	      return this.pushAll(iter);
	    };
	
	    Stack.prototype.shift = function() {
	      return this.pop.apply(this, arguments);
	    };
	
	    Stack.prototype.clear = function() {
	      if (this.size === 0) {
	        return this;
	      }
	      if (this.__ownerID) {
	        this.size = 0;
	        this._head = undefined;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return emptyStack();
	    };
	
	    Stack.prototype.slice = function(begin, end) {
	      if (wholeSlice(begin, end, this.size)) {
	        return this;
	      }
	      var resolvedBegin = resolveBegin(begin, this.size);
	      var resolvedEnd = resolveEnd(end, this.size);
	      if (resolvedEnd !== this.size) {
	        // super.slice(begin, end);
	        return IndexedCollection.prototype.slice.call(this, begin, end);
	      }
	      var newSize = this.size - resolvedBegin;
	      var head = this._head;
	      while (resolvedBegin--) {
	        head = head.next;
	      }
	      if (this.__ownerID) {
	        this.size = newSize;
	        this._head = head;
	        this.__hash = undefined;
	        this.__altered = true;
	        return this;
	      }
	      return makeStack(newSize, head);
	    };
	
	    // @pragma Mutability
	
	    Stack.prototype.__ensureOwner = function(ownerID) {
	      if (ownerID === this.__ownerID) {
	        return this;
	      }
	      if (!ownerID) {
	        this.__ownerID = ownerID;
	        this.__altered = false;
	        return this;
	      }
	      return makeStack(this.size, this._head, ownerID, this.__hash);
	    };
	
	    // @pragma Iteration
	
	    Stack.prototype.__iterate = function(fn, reverse) {
	      if (reverse) {
	        return this.reverse().__iterate(fn);
	      }
	      var iterations = 0;
	      var node = this._head;
	      while (node) {
	        if (fn(node.value, iterations++, this) === false) {
	          break;
	        }
	        node = node.next;
	      }
	      return iterations;
	    };
	
	    Stack.prototype.__iterator = function(type, reverse) {
	      if (reverse) {
	        return this.reverse().__iterator(type);
	      }
	      var iterations = 0;
	      var node = this._head;
	      return new Iterator(function()  {
	        if (node) {
	          var value = node.value;
	          node = node.next;
	          return iteratorValue(type, iterations++, value);
	        }
	        return iteratorDone();
	      });
	    };
	
	
	  function isStack(maybeStack) {
	    return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);
	  }
	
	  Stack.isStack = isStack;
	
	  var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';
	
	  var StackPrototype = Stack.prototype;
	  StackPrototype[IS_STACK_SENTINEL] = true;
	  StackPrototype.withMutations = MapPrototype.withMutations;
	  StackPrototype.asMutable = MapPrototype.asMutable;
	  StackPrototype.asImmutable = MapPrototype.asImmutable;
	  StackPrototype.wasAltered = MapPrototype.wasAltered;
	
	
	  function makeStack(size, head, ownerID, hash) {
	    var map = Object.create(StackPrototype);
	    map.size = size;
	    map._head = head;
	    map.__ownerID = ownerID;
	    map.__hash = hash;
	    map.__altered = false;
	    return map;
	  }
	
	  var EMPTY_STACK;
	  function emptyStack() {
	    return EMPTY_STACK || (EMPTY_STACK = makeStack(0));
	  }
	
	  /**
	   * Contributes additional methods to a constructor
	   */
	  function mixin(ctor, methods) {
	    var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };
	    Object.keys(methods).forEach(keyCopier);
	    Object.getOwnPropertySymbols &&
	      Object.getOwnPropertySymbols(methods).forEach(keyCopier);
	    return ctor;
	  }
	
	  Iterable.Iterator = Iterator;
	
	  mixin(Iterable, {
	
	    // ### Conversion to other types
	
	    toArray: function() {
	      assertNotInfinite(this.size);
	      var array = new Array(this.size || 0);
	      this.valueSeq().__iterate(function(v, i)  { array[i] = v; });
	      return array;
	    },
	
	    toIndexedSeq: function() {
	      return new ToIndexedSequence(this);
	    },
	
	    toJS: function() {
	      return this.toSeq().map(
	        function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}
	      ).__toJS();
	    },
	
	    toJSON: function() {
	      return this.toSeq().map(
	        function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}
	      ).__toJS();
	    },
	
	    toKeyedSeq: function() {
	      return new ToKeyedSequence(this, true);
	    },
	
	    toMap: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return Map(this.toKeyedSeq());
	    },
	
	    toObject: function() {
	      assertNotInfinite(this.size);
	      var object = {};
	      this.__iterate(function(v, k)  { object[k] = v; });
	      return object;
	    },
	
	    toOrderedMap: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return OrderedMap(this.toKeyedSeq());
	    },
	
	    toOrderedSet: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return OrderedSet(isKeyed(this) ? this.valueSeq() : this);
	    },
	
	    toSet: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return Set(isKeyed(this) ? this.valueSeq() : this);
	    },
	
	    toSetSeq: function() {
	      return new ToSetSequence(this);
	    },
	
	    toSeq: function() {
	      return isIndexed(this) ? this.toIndexedSeq() :
	        isKeyed(this) ? this.toKeyedSeq() :
	        this.toSetSeq();
	    },
	
	    toStack: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return Stack(isKeyed(this) ? this.valueSeq() : this);
	    },
	
	    toList: function() {
	      // Use Late Binding here to solve the circular dependency.
	      return List(isKeyed(this) ? this.valueSeq() : this);
	    },
	
	
	    // ### Common JavaScript methods and properties
	
	    toString: function() {
	      return '[Iterable]';
	    },
	
	    __toString: function(head, tail) {
	      if (this.size === 0) {
	        return head + tail;
	      }
	      return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;
	    },
	
	
	    // ### ES6 Collection methods (ES6 Array and Map)
	
	    concat: function() {var values = SLICE$0.call(arguments, 0);
	      return reify(this, concatFactory(this, values));
	    },
	
	    includes: function(searchValue) {
	      return this.some(function(value ) {return is(value, searchValue)});
	    },
	
	    entries: function() {
	      return this.__iterator(ITERATE_ENTRIES);
	    },
	
	    every: function(predicate, context) {
	      assertNotInfinite(this.size);
	      var returnValue = true;
	      this.__iterate(function(v, k, c)  {
	        if (!predicate.call(context, v, k, c)) {
	          returnValue = false;
	          return false;
	        }
	      });
	      return returnValue;
	    },
	
	    filter: function(predicate, context) {
	      return reify(this, filterFactory(this, predicate, context, true));
	    },
	
	    find: function(predicate, context, notSetValue) {
	      var entry = this.findEntry(predicate, context);
	      return entry ? entry[1] : notSetValue;
	    },
	
	    forEach: function(sideEffect, context) {
	      assertNotInfinite(this.size);
	      return this.__iterate(context ? sideEffect.bind(context) : sideEffect);
	    },
	
	    join: function(separator) {
	      assertNotInfinite(this.size);
	      separator = separator !== undefined ? '' + separator : ',';
	      var joined = '';
	      var isFirst = true;
	      this.__iterate(function(v ) {
	        isFirst ? (isFirst = false) : (joined += separator);
	        joined += v !== null && v !== undefined ? v.toString() : '';
	      });
	      return joined;
	    },
	
	    keys: function() {
	      return this.__iterator(ITERATE_KEYS);
	    },
	
	    map: function(mapper, context) {
	      return reify(this, mapFactory(this, mapper, context));
	    },
	
	    reduce: function(reducer, initialReduction, context) {
	      assertNotInfinite(this.size);
	      var reduction;
	      var useFirst;
	      if (arguments.length < 2) {
	        useFirst = true;
	      } else {
	        reduction = initialReduction;
	      }
	      this.__iterate(function(v, k, c)  {
	        if (useFirst) {
	          useFirst = false;
	          reduction = v;
	        } else {
	          reduction = reducer.call(context, reduction, v, k, c);
	        }
	      });
	      return reduction;
	    },
	
	    reduceRight: function(reducer, initialReduction, context) {
	      var reversed = this.toKeyedSeq().reverse();
	      return reversed.reduce.apply(reversed, arguments);
	    },
	
	    reverse: function() {
	      return reify(this, reverseFactory(this, true));
	    },
	
	    slice: function(begin, end) {
	      return reify(this, sliceFactory(this, begin, end, true));
	    },
	
	    some: function(predicate, context) {
	      return !this.every(not(predicate), context);
	    },
	
	    sort: function(comparator) {
	      return reify(this, sortFactory(this, comparator));
	    },
	
	    values: function() {
	      return this.__iterator(ITERATE_VALUES);
	    },
	
	
	    // ### More sequential methods
	
	    butLast: function() {
	      return this.slice(0, -1);
	    },
	
	    isEmpty: function() {
	      return this.size !== undefined ? this.size === 0 : !this.some(function()  {return true});
	    },
	
	    count: function(predicate, context) {
	      return ensureSize(
	        predicate ? this.toSeq().filter(predicate, context) : this
	      );
	    },
	
	    countBy: function(grouper, context) {
	      return countByFactory(this, grouper, context);
	    },
	
	    equals: function(other) {
	      return deepEqual(this, other);
	    },
	
	    entrySeq: function() {
	      var iterable = this;
	      if (iterable._cache) {
	        // We cache as an entries array, so we can just return the cache!
	        return new ArraySeq(iterable._cache);
	      }
	      var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();
	      entriesSequence.fromEntrySeq = function()  {return iterable.toSeq()};
	      return entriesSequence;
	    },
	
	    filterNot: function(predicate, context) {
	      return this.filter(not(predicate), context);
	    },
	
	    findEntry: function(predicate, context, notSetValue) {
	      var found = notSetValue;
	      this.__iterate(function(v, k, c)  {
	        if (predicate.call(context, v, k, c)) {
	          found = [k, v];
	          return false;
	        }
	      });
	      return found;
	    },
	
	    findKey: function(predicate, context) {
	      var entry = this.findEntry(predicate, context);
	      return entry && entry[0];
	    },
	
	    findLast: function(predicate, context, notSetValue) {
	      return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);
	    },
	
	    findLastEntry: function(predicate, context, notSetValue) {
	      return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue);
	    },
	
	    findLastKey: function(predicate, context) {
	      return this.toKeyedSeq().reverse().findKey(predicate, context);
	    },
	
	    first: function() {
	      return this.find(returnTrue);
	    },
	
	    flatMap: function(mapper, context) {
	      return reify(this, flatMapFactory(this, mapper, context));
	    },
	
	    flatten: function(depth) {
	      return reify(this, flattenFactory(this, depth, true));
	    },
	
	    fromEntrySeq: function() {
	      return new FromEntriesSequence(this);
	    },
	
	    get: function(searchKey, notSetValue) {
	      return this.find(function(_, key)  {return is(key, searchKey)}, undefined, notSetValue);
	    },
	
	    getIn: function(searchKeyPath, notSetValue) {
	      var nested = this;
	      // Note: in an ES6 environment, we would prefer:
	      // for (var key of searchKeyPath) {
	      var iter = forceIterator(searchKeyPath);
	      var step;
	      while (!(step = iter.next()).done) {
	        var key = step.value;
	        nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;
	        if (nested === NOT_SET) {
	          return notSetValue;
	        }
	      }
	      return nested;
	    },
	
	    groupBy: function(grouper, context) {
	      return groupByFactory(this, grouper, context);
	    },
	
	    has: function(searchKey) {
	      return this.get(searchKey, NOT_SET) !== NOT_SET;
	    },
	
	    hasIn: function(searchKeyPath) {
	      return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;
	    },
	
	    isSubset: function(iter) {
	      iter = typeof iter.includes === 'function' ? iter : Iterable(iter);
	      return this.every(function(value ) {return iter.includes(value)});
	    },
	
	    isSuperset: function(iter) {
	      iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);
	      return iter.isSubset(this);
	    },
	
	    keyOf: function(searchValue) {
	      return this.findKey(function(value ) {return is(value, searchValue)});
	    },
	
	    keySeq: function() {
	      return this.toSeq().map(keyMapper).toIndexedSeq();
	    },
	
	    last: function() {
	      return this.toSeq().reverse().first();
	    },
	
	    lastKeyOf: function(searchValue) {
	      return this.toKeyedSeq().reverse().keyOf(searchValue);
	    },
	
	    max: function(comparator) {
	      return maxFactory(this, comparator);
	    },
	
	    maxBy: function(mapper, comparator) {
	      return maxFactory(this, comparator, mapper);
	    },
	
	    min: function(comparator) {
	      return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);
	    },
	
	    minBy: function(mapper, comparator) {
	      return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);
	    },
	
	    rest: function() {
	      return this.slice(1);
	    },
	
	    skip: function(amount) {
	      return this.slice(Math.max(0, amount));
	    },
	
	    skipLast: function(amount) {
	      return reify(this, this.toSeq().reverse().skip(amount).reverse());
	    },
	
	    skipWhile: function(predicate, context) {
	      return reify(this, skipWhileFactory(this, predicate, context, true));
	    },
	
	    skipUntil: function(predicate, context) {
	      return this.skipWhile(not(predicate), context);
	    },
	
	    sortBy: function(mapper, comparator) {
	      return reify(this, sortFactory(this, comparator, mapper));
	    },
	
	    take: function(amount) {
	      return this.slice(0, Math.max(0, amount));
	    },
	
	    takeLast: function(amount) {
	      return reify(this, this.toSeq().reverse().take(amount).reverse());
	    },
	
	    takeWhile: function(predicate, context) {
	      return reify(this, takeWhileFactory(this, predicate, context));
	    },
	
	    takeUntil: function(predicate, context) {
	      return this.takeWhile(not(predicate), context);
	    },
	
	    valueSeq: function() {
	      return this.toIndexedSeq();
	    },
	
	
	    // ### Hashable Object
	
	    hashCode: function() {
	      return this.__hash || (this.__hash = hashIterable(this));
	    }
	
	
	    // ### Internal
	
	    // abstract __iterate(fn, reverse)
	
	    // abstract __iterator(type, reverse)
	  });
	
	  // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
	  // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
	  // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
	  // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
	
	  var IterablePrototype = Iterable.prototype;
	  IterablePrototype[IS_ITERABLE_SENTINEL] = true;
	  IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;
	  IterablePrototype.__toJS = IterablePrototype.toArray;
	  IterablePrototype.__toStringMapper = quoteString;
	  IterablePrototype.inspect =
	  IterablePrototype.toSource = function() { return this.toString(); };
	  IterablePrototype.chain = IterablePrototype.flatMap;
	  IterablePrototype.contains = IterablePrototype.includes;
	
	  mixin(KeyedIterable, {
	
	    // ### More sequential methods
	
	    flip: function() {
	      return reify(this, flipFactory(this));
	    },
	
	    mapEntries: function(mapper, context) {var this$0 = this;
	      var iterations = 0;
	      return reify(this,
	        this.toSeq().map(
	          function(v, k)  {return mapper.call(context, [k, v], iterations++, this$0)}
	        ).fromEntrySeq()
	      );
	    },
	
	    mapKeys: function(mapper, context) {var this$0 = this;
	      return reify(this,
	        this.toSeq().flip().map(
	          function(k, v)  {return mapper.call(context, k, v, this$0)}
	        ).flip()
	      );
	    }
	
	  });
	
	  var KeyedIterablePrototype = KeyedIterable.prototype;
	  KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;
	  KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;
	  KeyedIterablePrototype.__toJS = IterablePrototype.toObject;
	  KeyedIterablePrototype.__toStringMapper = function(v, k)  {return JSON.stringify(k) + ': ' + quoteString(v)};
	
	
	
	  mixin(IndexedIterable, {
	
	    // ### Conversion to other types
	
	    toKeyedSeq: function() {
	      return new ToKeyedSequence(this, false);
	    },
	
	
	    // ### ES6 Collection methods (ES6 Array and Map)
	
	    filter: function(predicate, context) {
	      return reify(this, filterFactory(this, predicate, context, false));
	    },
	
	    findIndex: function(predicate, context) {
	      var entry = this.findEntry(predicate, context);
	      return entry ? entry[0] : -1;
	    },
	
	    indexOf: function(searchValue) {
	      var key = this.keyOf(searchValue);
	      return key === undefined ? -1 : key;
	    },
	
	    lastIndexOf: function(searchValue) {
	      var key = this.lastKeyOf(searchValue);
	      return key === undefined ? -1 : key;
	    },
	
	    reverse: function() {
	      return reify(this, reverseFactory(this, false));
	    },
	
	    slice: function(begin, end) {
	      return reify(this, sliceFactory(this, begin, end, false));
	    },
	
	    splice: function(index, removeNum /*, ...values*/) {
	      var numArgs = arguments.length;
	      removeNum = Math.max(removeNum | 0, 0);
	      if (numArgs === 0 || (numArgs === 2 && !removeNum)) {
	        return this;
	      }
	      // If index is negative, it should resolve relative to the size of the
	      // collection. However size may be expensive to compute if not cached, so
	      // only call count() if the number is in fact negative.
	      index = resolveBegin(index, index < 0 ? this.count() : this.size);
	      var spliced = this.slice(0, index);
	      return reify(
	        this,
	        numArgs === 1 ?
	          spliced :
	          spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))
	      );
	    },
	
	
	    // ### More collection methods
	
	    findLastIndex: function(predicate, context) {
	      var entry = this.findLastEntry(predicate, context);
	      return entry ? entry[0] : -1;
	    },
	
	    first: function() {
	      return this.get(0);
	    },
	
	    flatten: function(depth) {
	      return reify(this, flattenFactory(this, depth, false));
	    },
	
	    get: function(index, notSetValue) {
	      index = wrapIndex(this, index);
	      return (index < 0 || (this.size === Infinity ||
	          (this.size !== undefined && index > this.size))) ?
	        notSetValue :
	        this.find(function(_, key)  {return key === index}, undefined, notSetValue);
	    },
	
	    has: function(index) {
	      index = wrapIndex(this, index);
	      return index >= 0 && (this.size !== undefined ?
	        this.size === Infinity || index < this.size :
	        this.indexOf(index) !== -1
	      );
	    },
	
	    interpose: function(separator) {
	      return reify(this, interposeFactory(this, separator));
	    },
	
	    interleave: function(/*...iterables*/) {
	      var iterables = [this].concat(arrCopy(arguments));
	      var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);
	      var interleaved = zipped.flatten(true);
	      if (zipped.size) {
	        interleaved.size = zipped.size * iterables.length;
	      }
	      return reify(this, interleaved);
	    },
	
	    keySeq: function() {
	      return Range(0, this.size);
	    },
	
	    last: function() {
	      return this.get(-1);
	    },
	
	    skipWhile: function(predicate, context) {
	      return reify(this, skipWhileFactory(this, predicate, context, false));
	    },
	
	    zip: function(/*, ...iterables */) {
	      var iterables = [this].concat(arrCopy(arguments));
	      return reify(this, zipWithFactory(this, defaultZipper, iterables));
	    },
	
	    zipWith: function(zipper/*, ...iterables */) {
	      var iterables = arrCopy(arguments);
	      iterables[0] = this;
	      return reify(this, zipWithFactory(this, zipper, iterables));
	    }
	
	  });
	
	  IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;
	  IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;
	
	
	
	  mixin(SetIterable, {
	
	    // ### ES6 Collection methods (ES6 Array and Map)
	
	    get: function(value, notSetValue) {
	      return this.has(value) ? value : notSetValue;
	    },
	
	    includes: function(value) {
	      return this.has(value);
	    },
	
	
	    // ### More sequential methods
	
	    keySeq: function() {
	      return this.valueSeq();
	    }
	
	  });
	
	  SetIterable.prototype.has = IterablePrototype.includes;
	  SetIterable.prototype.contains = SetIterable.prototype.includes;
	
	
	  // Mixin subclasses
	
	  mixin(KeyedSeq, KeyedIterable.prototype);
	  mixin(IndexedSeq, IndexedIterable.prototype);
	  mixin(SetSeq, SetIterable.prototype);
	
	  mixin(KeyedCollection, KeyedIterable.prototype);
	  mixin(IndexedCollection, IndexedIterable.prototype);
	  mixin(SetCollection, SetIterable.prototype);
	
	
	  // #pragma Helper functions
	
	  function keyMapper(v, k) {
	    return k;
	  }
	
	  function entryMapper(v, k) {
	    return [k, v];
	  }
	
	  function not(predicate) {
	    return function() {
	      return !predicate.apply(this, arguments);
	    }
	  }
	
	  function neg(predicate) {
	    return function() {
	      return -predicate.apply(this, arguments);
	    }
	  }
	
	  function quoteString(value) {
	    return typeof value === 'string' ? JSON.stringify(value) : String(value);
	  }
	
	  function defaultZipper() {
	    return arrCopy(arguments);
	  }
	
	  function defaultNegComparator(a, b) {
	    return a < b ? 1 : a > b ? -1 : 0;
	  }
	
	  function hashIterable(iterable) {
	    if (iterable.size === Infinity) {
	      return 0;
	    }
	    var ordered = isOrdered(iterable);
	    var keyed = isKeyed(iterable);
	    var h = ordered ? 1 : 0;
	    var size = iterable.__iterate(
	      keyed ?
	        ordered ?
	          function(v, k)  { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :
	          function(v, k)  { h = h + hashMerge(hash(v), hash(k)) | 0; } :
	        ordered ?
	          function(v ) { h = 31 * h + hash(v) | 0; } :
	          function(v ) { h = h + hash(v) | 0; }
	    );
	    return murmurHashOfSize(size, h);
	  }
	
	  function murmurHashOfSize(size, h) {
	    h = imul(h, 0xCC9E2D51);
	    h = imul(h << 15 | h >>> -15, 0x1B873593);
	    h = imul(h << 13 | h >>> -13, 5);
	    h = (h + 0xE6546B64 | 0) ^ size;
	    h = imul(h ^ h >>> 16, 0x85EBCA6B);
	    h = imul(h ^ h >>> 13, 0xC2B2AE35);
	    h = smi(h ^ h >>> 16);
	    return h;
	  }
	
	  function hashMerge(a, b) {
	    return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int
	  }
	
	  var Immutable = {
	
	    Iterable: Iterable,
	
	    Seq: Seq,
	    Collection: Collection,
	    Map: Map,
	    OrderedMap: OrderedMap,
	    List: List,
	    Stack: Stack,
	    Set: Set,
	    OrderedSet: OrderedSet,
	
	    Record: Record,
	    Range: Range,
	    Repeat: Repeat,
	
	    is: is,
	    fromJS: fromJS
	
	  };
	
	  return Immutable;
	
	}));

/***/ },
/* 230 */
/***/ function(module, exports, __webpack_require__) {

	var Immutable = __webpack_require__(229);
	
	// When our app state is fully types, we should be able to get rid of
	// this function. This is only temporarily necessary to support
	// converting typed objects to immutable.js, which usually happens in
	// reducers.
	function fromJS(value) {
	  if (Array.isArray(value)) {
	    return Immutable.Seq(value).map(fromJS).toList();
	  }
	  if (value && value.constructor.meta) {
	    // This adds support for tcomb objects which are native JS objects
	    // but are not "plain", so the above checks fail. Since they
	    // behave the same we can use the same constructors, but we need
	    // special checks for them.
	    var kind = value.constructor.meta.kind;
	    if (kind === "struct") {
	      return Immutable.Seq(value).map(fromJS).toMap();
	    } else if (kind === "list") {
	      return Immutable.Seq(value).map(fromJS).toList();
	    }
	  }
	
	  // If it's a primitive type, just return the value. Note `==` check
	  // for null, which is intentionally used to match either `null` or
	  // `undefined`.
	  if (value == null || typeof value !== "object") {
	    return value;
	  }
	
	  // Otherwise, treat it like an object. We can't reliably detect if
	  // it's a plain object because we might be objects from other JS
	  // contexts so `Object !== Object`.
	  return Immutable.Seq(value).map(fromJS).toMap();
	}
	
	module.exports = fromJS;

/***/ },
/* 231 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var classnames = __webpack_require__(211);
	
	var _require2 = __webpack_require__(232);
	
	var getTabs = _require2.getTabs;
	
	
	__webpack_require__(233);
	var dom = React.DOM;
	
	var ImPropTypes = __webpack_require__(235);
	
	var githubUrl = "https://github.com/devtools-html/debugger.html/blob/master";
	
	function getTabsByBrowser(tabs, browser) {
	  return tabs.valueSeq().filter(tab => tab.get("browser") == browser);
	}
	
	function firstTimeMessage(title, urlPart) {
	  return dom.div({ className: "footer-note" }, `First time connecting to ${ title }? Checkout out the `, dom.a({ href: `${ githubUrl }/CONTRIBUTING.md#${ urlPart }` }, "docs"), ".");
	}
	
	var LandingPage = React.createClass({
	  propTypes: {
	    tabs: ImPropTypes.map.isRequired
	  },
	
	  displayName: "LandingPage",
	
	  getInitialState() {
	    return {
	      selectedPane: "Firefox"
	    };
	  },
	
	  renderTabs(tabTitle, tabs, paramName) {
	    if (!tabs || tabs.count() == 0) {
	      return dom.div({}, "");
	    }
	
	    return dom.div({ className: "tab-group" }, dom.ul({ className: "tab-list" }, tabs.valueSeq().map(tab => dom.li({ "className": "tab",
	      "key": tab.get("id"),
	      "onClick": () => {
	        window.location = "/?" + paramName + "=" + tab.get("id");
	      } }, dom.div({ className: "tab-title" }, tab.get("title")), dom.div({ className: "tab-url" }, tab.get("url"))))));
	  },
	
	  renderFirefoxPanel() {
	    var targets = getTabsByBrowser(this.props.tabs, "firefox");
	    return dom.div({ className: "center" }, this.renderTabs("", targets, "firefox-tab"), firstTimeMessage("Firefox", "firefox"));
	  },
	
	  renderChromePanel() {
	    var targets = getTabsByBrowser(this.props.tabs, "chrome");
	    return dom.div({ className: "center" }, this.renderTabs("", targets, "chrome-tab"), firstTimeMessage("Chrome", "chrome"));
	  },
	
	  renderNodePanel() {
	    return dom.div({ className: "center" }, dom.div({ className: "center-message" }, dom.a({
	      href: `/?ws=${ document.location.hostname }:9229/node`
	    }, "Connect to Node")), firstTimeMessage("Node", "nodejs"));
	  },
	
	  renderPanel() {
	    var panels = {
	      Firefox: this.renderFirefoxPanel,
	      Chrome: this.renderChromePanel,
	      Node: this.renderNodePanel
	    };
	
	    return dom.div({
	      className: "panel"
	    }, dom.div({ className: "title" }, dom.h2({}, this.state.selectedPane)), panels[this.state.selectedPane]());
	  },
	
	  renderSidebar() {
	    return dom.div({
	      className: "sidebar"
	    }, dom.h1({}, "Debugger"), dom.ul({}, ["Firefox", "Chrome", "Node"].map(title => dom.li({
	      className: classnames({
	        selected: title == this.state.selectedPane
	      }),
	      key: title,
	
	      onClick: () => this.setState({ selectedPane: title })
	    }, dom.a({}, title)))));
	  },
	
	  render() {
	    return dom.div({
	      className: "landing-page"
	    }, this.renderSidebar(), this.renderPanel());
	  }
	});
	
	module.exports = connect(state => ({ tabs: getTabs(state) }))(LandingPage);

/***/ },
/* 232 */
/***/ function(module, exports) {

	function getTabs(state) {
	  return state.tabs.get("tabs");
	}
	
	function getSelectedTab(state) {
	  return state.tabs.get("selectedTab");
	}
	
	module.exports = {
	  getTabs,
	  getSelectedTab
	};

/***/ },
/* 233 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 234 */,
/* 235 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * This is a straight rip-off of the React.js ReactPropTypes.js proptype validators,
	 * modified to make it possible to validate Immutable.js data.
	 *     ImmutableTypes.listOf is patterned after React.PropTypes.arrayOf, but for Immutable.List
	 *     ImmutableTypes.shape  is based on React.PropTypes.shape, but for any Immutable.Iterable
	 */
	"use strict";
	
	var Immutable = __webpack_require__(229);
	
	var ANONYMOUS = "<<anonymous>>";
	
	var ImmutablePropTypes = {
	  listOf: createListOfTypeChecker,
	  mapOf: createMapOfTypeChecker,
	  orderedMapOf: createOrderedMapOfTypeChecker,
	  setOf: createSetOfTypeChecker,
	  orderedSetOf: createOrderedSetOfTypeChecker,
	  stackOf: createStackOfTypeChecker,
	  iterableOf: createIterableOfTypeChecker,
	  recordOf: createRecordOfTypeChecker,
	  shape: createShapeChecker,
	  contains: createShapeChecker,
	  mapContains: createMapContainsChecker,
	  // Primitive Types
	  list: createImmutableTypeChecker("List", Immutable.List.isList),
	  map: createImmutableTypeChecker("Map", Immutable.Map.isMap),
	  orderedMap: createImmutableTypeChecker("OrderedMap", Immutable.OrderedMap.isOrderedMap),
	  set: createImmutableTypeChecker("Set", Immutable.Set.isSet),
	  orderedSet: createImmutableTypeChecker("OrderedSet", Immutable.OrderedSet.isOrderedSet),
	  stack: createImmutableTypeChecker("Stack", Immutable.Stack.isStack),
	  seq: createImmutableTypeChecker("Seq", Immutable.Seq.isSeq),
	  record: createImmutableTypeChecker("Record", function (isRecord) {
	    return isRecord instanceof Immutable.Record;
	  }),
	  iterable: createImmutableTypeChecker("Iterable", Immutable.Iterable.isIterable)
	};
	
	function getPropType(propValue) {
	  var propType = typeof propValue;
	  if (Array.isArray(propValue)) {
	    return "array";
	  }
	  if (propValue instanceof RegExp) {
	    // Old webkits (at least until Android 4.0) return 'function' rather than
	    // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
	    // passes PropTypes.object.
	    return "object";
	  }
	  if (propValue instanceof Immutable.Iterable) {
	    return "Immutable." + propValue.toSource().split(" ")[0];
	  }
	  return propType;
	}
	
	function createChainableTypeChecker(validate) {
	  function checkType(isRequired, props, propName, componentName, location, propFullName) {
	    propFullName = propFullName || propName;
	    componentName = componentName || ANONYMOUS;
	    if (props[propName] == null) {
	      var locationName = location;
	      if (isRequired) {
	        return new Error("Required " + locationName + " `" + propFullName + "` was not specified in " + ("`" + componentName + "`."));
	      }
	    } else {
	      return validate(props, propName, componentName, location, propFullName);
	    }
	  }
	
	  var chainedCheckType = checkType.bind(null, false);
	  chainedCheckType.isRequired = checkType.bind(null, true);
	
	  return chainedCheckType;
	}
	
	function createImmutableTypeChecker(immutableClassName, immutableClassTypeValidator) {
	  function validate(props, propName, componentName, location, propFullName) {
	    var propValue = props[propName];
	    if (!immutableClassTypeValidator(propValue)) {
	      var propType = getPropType(propValue);
	      return new Error("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` " + ("supplied to `" + componentName + "`, expected `" + immutableClassName + "`."));
	    }
	    return null;
	  }
	  return createChainableTypeChecker(validate);
	}
	
	function createIterableTypeChecker(typeChecker, immutableClassName, immutableClassTypeValidator) {
	
	  function validate(props, propName, componentName, location, propFullName) {
	    var propValue = props[propName];
	    if (!immutableClassTypeValidator(propValue)) {
	      var locationName = location;
	      var propType = getPropType(propValue);
	      return new Error("Invalid " + locationName + " `" + propFullName + "` of type " + ("`" + propType + "` supplied to `" + componentName + "`, expected an Immutable.js " + immutableClassName + "."));
	    }
	
	    if (typeof typeChecker !== "function") {
	      return new Error("Invalid typeChecker supplied to `" + componentName + "` " + ("for propType `" + propFullName + "`, expected a function."));
	    }
	
	    var propValues = propValue.toArray();
	    for (var i = 0, len = propValues.length; i < len; i++) {
	      var error = typeChecker(propValues, i, componentName, location, "" + propFullName + "[" + i + "]");
	      if (error instanceof Error) {
	        return error;
	      }
	    }
	  }
	  return createChainableTypeChecker(validate);
	}
	
	function createListOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "List", Immutable.List.isList);
	}
	
	function createMapOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "Map", Immutable.Map.isMap);
	}
	
	function createOrderedMapOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "OrderedMap", Immutable.OrderedMap.isOrderedMap);
	}
	
	function createSetOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "Set", Immutable.Set.isSet);
	}
	
	function createOrderedSetOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "OrderedSet", Immutable.OrderedSet.isOrderedSet);
	}
	
	function createStackOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "Stack", Immutable.Stack.isStack);
	}
	
	function createIterableOfTypeChecker(typeChecker) {
	  return createIterableTypeChecker(typeChecker, "Iterable", Immutable.Iterable.isIterable);
	}
	
	function createRecordOfTypeChecker(recordKeys) {
	  function validate(props, propName, componentName, location, propFullName) {
	    var propValue = props[propName];
	    if (!(propValue instanceof Immutable.Record)) {
	      var propType = getPropType(propValue);
	      var locationName = location;
	      return new Error("Invalid " + locationName + " `" + propFullName + "` of type `" + propType + "` " + ("supplied to `" + componentName + "`, expected an Immutable.js Record."));
	    }
	    for (var key in recordKeys) {
	      var checker = recordKeys[key];
	      if (!checker) {
	        continue;
	      }
	      var mutablePropValue = propValue.toObject();
	      var error = checker(mutablePropValue, key, componentName, location, "" + propFullName + "." + key);
	      if (error) {
	        return error;
	      }
	    }
	  }
	  return createChainableTypeChecker(validate);
	}
	
	// there is some irony in the fact that shapeTypes is a standard hash and not an immutable collection
	function createShapeTypeChecker(shapeTypes) {
	  var immutableClassName = arguments[1] === undefined ? "Iterable" : arguments[1];
	  var immutableClassTypeValidator = arguments[2] === undefined ? Immutable.Iterable.isIterable : arguments[2];
	
	  function validate(props, propName, componentName, location, propFullName) {
	    var propValue = props[propName];
	    if (!immutableClassTypeValidator(propValue)) {
	      var propType = getPropType(propValue);
	      var locationName = location;
	      return new Error("Invalid " + locationName + " `" + propFullName + "` of type `" + propType + "` " + ("supplied to `" + componentName + "`, expected an Immutable.js " + immutableClassName + "."));
	    }
	    var mutablePropValue = propValue.toObject();
	    for (var key in shapeTypes) {
	      var checker = shapeTypes[key];
	      if (!checker) {
	        continue;
	      }
	      var error = checker(mutablePropValue, key, componentName, location, "" + propFullName + "." + key);
	      if (error) {
	        return error;
	      }
	    }
	  }
	  return createChainableTypeChecker(validate);
	}
	
	function createShapeChecker(shapeTypes) {
	  return createShapeTypeChecker(shapeTypes);
	}
	
	function createMapContainsChecker(shapeTypes) {
	  return createShapeTypeChecker(shapeTypes, "Map", Immutable.Map.isMap);
	}
	
	module.exports = ImmutablePropTypes;

/***/ },
/* 236 */
/***/ function(module, exports, __webpack_require__) {

	
	var tabs = __webpack_require__(237);
	
	module.exports = Object.assign({}, tabs);

/***/ },
/* 237 */
/***/ 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/. */
	/* global window */
	
	/**
	 * Redux actions for the pause state
	 * @module actions/tabs
	 */
	
	var constants = __webpack_require__(228);
	
	/**
	 * @typedef {Object} TabAction
	 * @memberof actions/tabs
	 * @static
	 * @property {number} type The type of Action
	 * @property {number} value The payload of the Action
	 */
	
	/**
	 * @memberof actions/tabs
	 * @static
	 * @param {Array} tabs
	 * @returns {TabAction} with type constants.ADD_TABS and tabs as value
	 */
	function newTabs(tabs) {
	  return {
	    type: constants.ADD_TABS,
	    value: tabs
	  };
	}
	
	/**
	 * @memberof actions/tabs
	 * @static
	 * @param {String} $0.id Unique ID of the tab to select
	 * @returns {TabAction}
	 */
	function selectTab(_ref) {
	  var id = _ref.id;
	
	  return {
	    type: constants.SELECT_TAB,
	    id: id
	  };
	}
	
	module.exports = {
	  newTabs,
	  selectTab
	};

/***/ },
/* 238 */
/***/ 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/. */
	/* global window */
	
	/**
	 * Redux store utils
	 * @module utils/create-store
	 */
	
	var _require = __webpack_require__(3);
	
	var createStore = _require.createStore;
	var applyMiddleware = _require.applyMiddleware;
	
	var _require2 = __webpack_require__(239);
	
	var waitUntilService = _require2.waitUntilService;
	
	var _require3 = __webpack_require__(240);
	
	var log = _require3.log;
	
	var _require4 = __webpack_require__(241);
	
	var history = _require4.history;
	
	var _require5 = __webpack_require__(242);
	
	var promise = _require5.promise;
	
	var _require6 = __webpack_require__(248);
	
	var thunk = _require6.thunk;
	
	/**
	 * @memberof utils/create-store
	 * @static
	 */
	
	/**
	 * This creates a dispatcher with all the standard middleware in place
	 * that all code requires. It can also be optionally configured in
	 * various ways, such as logging and recording.
	 *
	 * @param {object} opts:
	 *        - log: log all dispatched actions to console
	 *        - history: an array to store every action in. Should only be
	 *                   used in tests.
	 *        - middleware: array of middleware to be included in the redux store
	 * @memberof utils/create-store
	 * @static
	 */
	var configureStore = function () {
	  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
	
	  var middleware = [thunk(opts.makeThunkArgs), promise,
	
	  // Order is important: services must go last as they always
	  // operate on "already transformed" actions. Actions going through
	  // them shouldn't have any special fields like promises, they
	  // should just be normal JSON objects.
	  waitUntilService];
	
	  if (opts.history) {
	    middleware.push(history(opts.history));
	  }
	
	  if (opts.middleware) {
	    opts.middleware.forEach(fn => middleware.push(fn));
	  }
	
	  if (opts.log) {
	    middleware.push(log);
	  }
	
	  // Hook in the redux devtools browser extension if it exists
	  var devtoolsExt = typeof window === "object" && window.devToolsExtension ? window.devToolsExtension() : f => f;
	
	  return applyMiddleware.apply(undefined, middleware)(devtoolsExt(createStore));
	};
	
	module.exports = configureStore;

/***/ },
/* 239 */
/***/ 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/. */
	
	/**
	 * A middleware which acts like a service, because it is stateful
	 * and "long-running" in the background. It provides the ability
	 * for actions to install a function to be run once when a specific
	 * condition is met by an action coming through the system. Think of
	 * it as a thunk that blocks until the condition is met. Example:
	 *
	 * ```js
	 * const services = { WAIT_UNTIL: require('wait-service').NAME };
	 *
	 * { type: services.WAIT_UNTIL,
	 *   predicate: action => action.type === constants.ADD_ITEM,
	 *   run: (dispatch, getState, action) => {
	 *     // Do anything here. You only need to accept the arguments
	 *     // if you need them. `action` is the action that satisfied
	 *     // the predicate.
	 *   }
	 * }
	 * ```
	 */
	var NAME = exports.NAME = "@@service/waitUntil";
	
	function waitUntilService(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  var pending = [];
	
	  function checkPending(action) {
	    var readyRequests = [];
	    var stillPending = [];
	
	    // Find the pending requests whose predicates are satisfied with
	    // this action. Wait to run the requests until after we update the
	    // pending queue because the request handler may synchronously
	    // dispatch again and run this service (that use case is
	    // completely valid).
	    for (var request of pending) {
	      if (request.predicate(action)) {
	        readyRequests.push(request);
	      } else {
	        stillPending.push(request);
	      }
	    }
	
	    pending = stillPending;
	    for (var _request of readyRequests) {
	      _request.run(dispatch, getState, action);
	    }
	  }
	
	  return next => action => {
	    if (action.type === NAME) {
	      pending.push(action);
	      return null;
	    }
	    var result = next(action);
	    checkPending(action);
	    return result;
	  };
	}
	exports.waitUntilService = waitUntilService;

/***/ },
/* 240 */
/***/ function(module, exports) {

	/**
	 * A middleware that logs all actions coming through the system
	 * to the console.
	 */
	function log(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  return next => action => {
	    var actionText = JSON.stringify(action, null, 2);
	    var truncatedActionText = actionText.slice(0, 1000) + "...";
	    console.log(`[DISPATCH ${ action.type }]`, action, truncatedActionText);
	    next(action);
	  };
	}
	
	exports.log = log;

/***/ },
/* 241 */
/***/ 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/. */
	
	var _require = __webpack_require__(89);
	
	var isDevelopment = _require.isDevelopment;
	
	/**
	 * A middleware that stores every action coming through the store in the passed
	 * in logging object. Should only be used for tests, as it collects all
	 * action information, which will cause memory bloat.
	 */
	
	exports.history = function () {
	  var log = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var getState = _ref.getState;
	
	    if (isDevelopment()) {
	      console.warn("Using history middleware stores all actions in state for " + "testing and devtools is not currently running in test " + "mode. Be sure this is intentional.");
	    }
	    return next => action => {
	      log.push(action);
	      next(action);
	    };
	  };
	};

/***/ },
/* 242 */
/***/ 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/. */
	
	var defer = __webpack_require__(243);
	
	var _require = __webpack_require__(244);
	
	var entries = _require.entries;
	var toObject = _require.toObject;
	
	var _require2 = __webpack_require__(246);
	
	var executeSoon = _require2.executeSoon;
	
	
	var PROMISE = exports.PROMISE = "@@dispatch/promise";
	var seqIdVal = 1;
	
	function seqIdGen() {
	  return seqIdVal++;
	}
	
	function promiseMiddleware(_ref) {
	  var dispatch = _ref.dispatch;
	  var getState = _ref.getState;
	
	  return next => action => {
	    if (!(PROMISE in action)) {
	      return next(action);
	    }
	
	    var promiseInst = action[PROMISE];
	    var seqId = seqIdGen().toString();
	
	    // Create a new action that doesn't have the promise field and has
	    // the `seqId` field that represents the sequence id
	    action = Object.assign(toObject(entries(action).filter(pair => pair[0] !== PROMISE)), { seqId });
	
	    dispatch(Object.assign({}, action, { status: "start" }));
	
	    // Return the promise so action creators can still compose if they
	    // want to.
	    var deferred = defer();
	    promiseInst.then(value => {
	      executeSoon(() => {
	        dispatch(Object.assign({}, action, {
	          status: "done",
	          value: value
	        }));
	        deferred.resolve(value);
	      });
	    }, error => {
	      executeSoon(() => {
	        dispatch(Object.assign({}, action, {
	          status: "error",
	          error: error.message || error
	        }));
	        deferred.reject(error);
	      });
	    });
	    return deferred.promise;
	  };
	}
	
	exports.promise = promiseMiddleware;

/***/ },
/* 243 */
/***/ function(module, exports) {

	
	
	function defer() {
	  var resolve = void 0;
	  var reject = void 0;
	  var promise = new Promise(function (innerResolve, innerReject) {
	    resolve = innerResolve;
	    reject = innerReject;
	  });
	  return {
	    resolve: resolve,
	    reject: reject,
	    promise: promise
	  };
	} /* flow */
	
	module.exports = defer;

/***/ },
/* 244 */
/***/ function(module, exports, __webpack_require__) {

	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	/* -*- 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/. */
	
	/**
	 * Utils for utils, by utils
	 * @module utils/utils
	 */
	
	var co = __webpack_require__(245);
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function asPaused(client, func) {
	  if (client.state != "paused") {
	    return co(function* () {
	      yield client.interrupt();
	      var result = void 0;
	
	      try {
	        result = yield func();
	      } catch (e) {
	        // Try to put the debugger back in a working state by resuming
	        // it
	        yield client.resume();
	        throw e;
	      }
	
	      yield client.resume();
	      return result;
	    });
	  }
	  return func();
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function handleError(err) {
	  console.log("ERROR: ", err);
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function promisify(context, method) {
	  for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
	    args[_key - 2] = arguments[_key];
	  }
	
	  return new Promise((resolve, reject) => {
	    args.push(response => {
	      if (response.error) {
	        reject(response);
	      } else {
	        resolve(response);
	      }
	    });
	    method.apply(context, args);
	  });
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function truncateStr(str, size) {
	  if (str.length > size) {
	    return str.slice(0, size) + "...";
	  }
	  return str;
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function endTruncateStr(str, size) {
	  if (str.length > size) {
	    return "..." + str.slice(str.length - size);
	  }
	  return str;
	}
	
	var msgId = 1;
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function workerTask(worker, method) {
	  return function () {
	    for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
	      args[_key2] = arguments[_key2];
	    }
	
	    return new Promise((resolve, reject) => {
	      var id = msgId++;
	      worker.postMessage({ id, method, args });
	
	      var listener = (_ref) => {
	        var result = _ref.data;
	
	        if (result.id !== id) {
	          return;
	        }
	
	        worker.removeEventListener("message", listener);
	        if (result.error) {
	          reject(result.error);
	        } else {
	          resolve(result.response);
	        }
	      };
	
	      worker.addEventListener("message", listener);
	    });
	  };
	}
	
	/**
	 * Interleaves two arrays element by element, returning the combined array, like
	 * a zip. In the case of arrays with different sizes, undefined values will be
	 * interleaved at the end along with the extra values of the larger array.
	 *
	 * @param Array a
	 * @param Array b
	 * @returns Array
	 *          The combined array, in the form [a1, b1, a2, b2, ...]
	 * @memberof utils/utils
	 * @static
	 */
	function zip(a, b) {
	  if (!b) {
	    return a;
	  }
	  if (!a) {
	    return b;
	  }
	  var pairs = [];
	  for (var i = 0, aLength = a.length, bLength = b.length; i < aLength || i < bLength; i++) {
	    pairs.push([a[i], b[i]]);
	  }
	  return pairs;
	}
	
	/**
	 * Converts an object into an array with 2-element arrays as key/value
	 * pairs of the object. `{ foo: 1, bar: 2}` would become
	 * `[[foo, 1], [bar 2]]` (order not guaranteed);
	 *
	 * @returns array
	 * @memberof utils/utils
	 * @static
	 */
	function entries(obj) {
	  return Object.keys(obj).map(k => [k, obj[k]]);
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function mapObject(obj, iteratee) {
	  return toObject(entries(obj).map((_ref2) => {
	    var _ref3 = _slicedToArray(_ref2, 2);
	
	    var key = _ref3[0];
	    var value = _ref3[1];
	
	    return [key, iteratee(key, value)];
	  }));
	}
	
	/**
	 * Takes an array of 2-element arrays as key/values pairs and
	 * constructs an object using them.
	 * @memberof utils/utils
	 * @static
	 */
	function toObject(arr) {
	  var obj = {};
	  for (var pair of arr) {
	    obj[pair[0]] = pair[1];
	  }
	  return obj;
	}
	
	/**
	 * Composes the given functions into a single function, which will
	 * apply the results of each function right-to-left, starting with
	 * applying the given arguments to the right-most function.
	 * `compose(foo, bar, baz)` === `args => foo(bar(baz(args)`
	 *
	 * @param ...function funcs
	 * @returns function
	 * @memberof utils/utils
	 * @static
	 */
	function compose() {
	  for (var _len3 = arguments.length, funcs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
	    funcs[_key3] = arguments[_key3];
	  }
	
	  return function () {
	    for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
	      args[_key4] = arguments[_key4];
	    }
	
	    var initialValue = funcs[funcs.length - 1].apply(null, args);
	    var leftFuncs = funcs.slice(0, -1);
	    return leftFuncs.reduceRight((composed, f) => f(composed), initialValue);
	  };
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function updateObj(obj, fields) {
	  return Object.assign({}, obj, fields);
	}
	
	/**
	 * @memberof utils/utils
	 * @static
	 */
	function throttle(func, ms) {
	  var timeout = void 0,
	      _this = void 0;
	  return function () {
	    for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
	      args[_key5] = arguments[_key5];
	    }
	
	    _this = this;
	    if (!timeout) {
	      timeout = setTimeout(() => {
	        func.apply.apply(func, [_this].concat(_toConsumableArray(args)));
	        timeout = null;
	      }, ms);
	    }
	  };
	}
	
	module.exports = {
	  asPaused,
	  handleError,
	  promisify,
	  truncateStr,
	  endTruncateStr,
	  workerTask,
	  zip,
	  entries,
	  toObject,
	  mapObject,
	  compose,
	  updateObj,
	  throttle
	};

/***/ },
/* 245 */
/***/ function(module, exports) {

	
	/**
	 * slice() reference.
	 */
	
	var slice = Array.prototype.slice;
	
	/**
	 * Expose `co`.
	 */
	
	module.exports = co['default'] = co.co = co;
	
	/**
	 * Wrap the given generator `fn` into a
	 * function that returns a promise.
	 * This is a separate function so that
	 * every `co()` call doesn't create a new,
	 * unnecessary closure.
	 *
	 * @param {GeneratorFunction} fn
	 * @return {Function}
	 * @api public
	 */
	
	co.wrap = function (fn) {
	  createPromise.__generatorFunction__ = fn;
	  return createPromise;
	  function createPromise() {
	    return co.call(this, fn.apply(this, arguments));
	  }
	};
	
	/**
	 * Execute the generator function or a generator
	 * and return a promise.
	 *
	 * @param {Function} fn
	 * @return {Promise}
	 * @api public
	 */
	
	function co(gen) {
	  var ctx = this;
	  var args = slice.call(arguments, 1)
	
	  // we wrap everything in a promise to avoid promise chaining,
	  // which leads to memory leak errors.
	  // see https://github.com/tj/co/issues/180
	  return new Promise(function(resolve, reject) {
	    if (typeof gen === 'function') gen = gen.apply(ctx, args);
	    if (!gen || typeof gen.next !== 'function') return resolve(gen);
	
	    onFulfilled();
	
	    /**
	     * @param {Mixed} res
	     * @return {Promise}
	     * @api private
	     */
	
	    function onFulfilled(res) {
	      var ret;
	      try {
	        ret = gen.next(res);
	      } catch (e) {
	        return reject(e);
	      }
	      next(ret);
	    }
	
	    /**
	     * @param {Error} err
	     * @return {Promise}
	     * @api private
	     */
	
	    function onRejected(err) {
	      var ret;
	      try {
	        ret = gen.throw(err);
	      } catch (e) {
	        return reject(e);
	      }
	      next(ret);
	    }
	
	    /**
	     * Get the next value in the generator,
	     * return a promise.
	     *
	     * @param {Object} ret
	     * @return {Promise}
	     * @api private
	     */
	
	    function next(ret) {
	      if (ret.done) return resolve(ret.value);
	      var value = toPromise.call(ctx, ret.value);
	      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
	      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
	        + 'but the following object was passed: "' + String(ret.value) + '"'));
	    }
	  });
	}
	
	/**
	 * Convert a `yield`ed value into a promise.
	 *
	 * @param {Mixed} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function toPromise(obj) {
	  if (!obj) return obj;
	  if (isPromise(obj)) return obj;
	  if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj);
	  if ('function' == typeof obj) return thunkToPromise.call(this, obj);
	  if (Array.isArray(obj)) return arrayToPromise.call(this, obj);
	  if (isObject(obj)) return objectToPromise.call(this, obj);
	  return obj;
	}
	
	/**
	 * Convert a thunk to a promise.
	 *
	 * @param {Function}
	 * @return {Promise}
	 * @api private
	 */
	
	function thunkToPromise(fn) {
	  var ctx = this;
	  return new Promise(function (resolve, reject) {
	    fn.call(ctx, function (err, res) {
	      if (err) return reject(err);
	      if (arguments.length > 2) res = slice.call(arguments, 1);
	      resolve(res);
	    });
	  });
	}
	
	/**
	 * Convert an array of "yieldables" to a promise.
	 * Uses `Promise.all()` internally.
	 *
	 * @param {Array} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function arrayToPromise(obj) {
	  return Promise.all(obj.map(toPromise, this));
	}
	
	/**
	 * Convert an object of "yieldables" to a promise.
	 * Uses `Promise.all()` internally.
	 *
	 * @param {Object} obj
	 * @return {Promise}
	 * @api private
	 */
	
	function objectToPromise(obj){
	  var results = new obj.constructor();
	  var keys = Object.keys(obj);
	  var promises = [];
	  for (var i = 0; i < keys.length; i++) {
	    var key = keys[i];
	    var promise = toPromise.call(this, obj[key]);
	    if (promise && isPromise(promise)) defer(promise, key);
	    else results[key] = obj[key];
	  }
	  return Promise.all(promises).then(function () {
	    return results;
	  });
	
	  function defer(promise, key) {
	    // predefine the key in the result
	    results[key] = undefined;
	    promises.push(promise.then(function (res) {
	      results[key] = res;
	    }));
	  }
	}
	
	/**
	 * Check if `obj` is a promise.
	 *
	 * @param {Object} obj
	 * @return {Boolean}
	 * @api private
	 */
	
	function isPromise(obj) {
	  return 'function' == typeof obj.then;
	}
	
	/**
	 * Check if `obj` is a generator.
	 *
	 * @param {Mixed} obj
	 * @return {Boolean}
	 * @api private
	 */
	
	function isGenerator(obj) {
	  return 'function' == typeof obj.next && 'function' == typeof obj.throw;
	}
	
	/**
	 * Check if `obj` is a generator function.
	 *
	 * @param {Mixed} obj
	 * @return {Boolean}
	 * @api private
	 */
	function isGeneratorFunction(obj) {
	  var constructor = obj.constructor;
	  if (!constructor) return false;
	  if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true;
	  return isGenerator(constructor.prototype);
	}
	
	/**
	 * Check for plain object.
	 *
	 * @param {Mixed} val
	 * @return {Boolean}
	 * @api private
	 */
	
	function isObject(val) {
	  return Object == val.constructor;
	}


/***/ },
/* 246 */
/***/ function(module, exports, __webpack_require__) {

	var assert = __webpack_require__(247);
	
	function reportException(who, exception) {
	  var msg = who + " threw an exception: ";
	  console.error(msg, exception);
	}
	
	function executeSoon(fn) {
	  setTimeout(fn, 0);
	}
	
	module.exports = {
	  reportException,
	  executeSoon,
	  assert
	};

/***/ },
/* 247 */
/***/ function(module, exports) {

	function assert(condition, message) {
	  if (!condition) {
	    throw new Error("Assertion failure: " + message);
	  }
	}
	
	module.exports = assert;

/***/ },
/* 248 */
/***/ function(module, exports) {

	
	/**
	 * A middleware that allows thunks (functions) to be dispatched. If
	 * it's a thunk, it is called with an argument that contains
	 * `dispatch`, `getState`, and any additional args passed in via the
	 * middleware constructure. This allows the action to create multiple
	 * actions (most likely asynchronously).
	 */
	function thunk(makeArgs) {
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var getState = _ref.getState;
	
	    var args = { dispatch, getState };
	
	    return next => action => {
	      return typeof action === "function" ? action(makeArgs ? makeArgs(args, getState()) : args) : next(action);
	    };
	  };
	}
	exports.thunk = thunk;

/***/ },
/* 249 */
/***/ 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/. */
	
	var eventListeners = __webpack_require__(250);
	var sources = __webpack_require__(252);
	var breakpoints = __webpack_require__(255);
	var asyncRequests = __webpack_require__(256);
	var pause = __webpack_require__(257);
	var ui = __webpack_require__(258);
	
	module.exports = {
	  eventListeners,
	  sources: sources.update,
	  breakpoints: breakpoints.update,
	  pause: pause.update,
	  asyncRequests,
	  ui: ui.update
	};

/***/ },
/* 250 */
/***/ 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/. */
	
	var constants = __webpack_require__(251);
	
	var initialState = {
	  activeEventNames: [],
	  listeners: [],
	  fetchingListeners: false
	};
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
	  var action = arguments[1];
	  var emit = arguments[2];
	
	  switch (action.type) {
	    case constants.UPDATE_EVENT_BREAKPOINTS:
	      state.activeEventNames = action.eventNames;
	      emit("activeEventNames", state.activeEventNames);
	      break;
	    case constants.FETCH_EVENT_LISTENERS:
	      if (action.status === "begin") {
	        state.fetchingListeners = true;
	      } else if (action.status === "done") {
	        state.fetchingListeners = false;
	        state.listeners = action.listeners;
	        emit("event-listeners", state.listeners);
	      }
	      break;
	    case constants.NAVIGATE:
	      return initialState;
	  }
	
	  return state;
	}
	
	module.exports = update;

/***/ },
/* 251 */
/***/ 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/. */
	
	exports.UPDATE_EVENT_BREAKPOINTS = "UPDATE_EVENT_BREAKPOINTS";
	exports.FETCH_EVENT_LISTENERS = "FETCH_EVENT_LISTENERS";
	
	exports.TOGGLE_PRETTY_PRINT = "TOGGLE_PRETTY_PRINT";
	exports.BLACKBOX = "BLACKBOX";
	
	exports.ADD_BREAKPOINT = "ADD_BREAKPOINT";
	exports.REMOVE_BREAKPOINT = "REMOVE_BREAKPOINT";
	exports.ENABLE_BREAKPOINT = "ENABLE_BREAKPOINT";
	exports.DISABLE_BREAKPOINT = "DISABLE_BREAKPOINT";
	exports.SET_BREAKPOINT_CONDITION = "SET_BREAKPOINT_CONDITION";
	exports.TOGGLE_BREAKPOINTS = "TOGGLE_BREAKPOINTS";
	
	exports.ADD_SOURCE = "ADD_SOURCE";
	exports.ADD_SOURCES = "ADD_SOURCES";
	exports.LOAD_SOURCE_TEXT = "LOAD_SOURCE_TEXT";
	exports.SELECT_SOURCE = "SELECT_SOURCE";
	exports.SELECT_SOURCE_URL = "SELECT_SOURCE_URL";
	exports.CLOSE_TAB = "CLOSE_TAB";
	exports.NAVIGATE = "NAVIGATE";
	exports.RELOAD = "RELOAD";
	
	exports.ADD_TABS = "ADD_TABS";
	exports.SELECT_TAB = "SELECT_TAB";
	
	exports.BREAK_ON_NEXT = "BREAK_ON_NEXT";
	exports.RESUME = "RESUME";
	exports.PAUSED = "PAUSED";
	exports.PAUSE_ON_EXCEPTIONS = "PAUSE_ON_EXCEPTIONS";
	exports.COMMAND = "COMMAND";
	exports.SELECT_FRAME = "SELECT_FRAME";
	exports.LOAD_OBJECT_PROPERTIES = "LOAD_OBJECT_PROPERTIES";
	exports.ADD_EXPRESSION = "ADD_EXPRESSION";
	exports.EVALUATE_EXPRESSION = "EVALUATE_EXPRESSION";
	exports.UPDATE_EXPRESSION = "UPDATE_EXPRESSION";
	exports.DELETE_EXPRESSION = "DELETE_EXPRESSION";
	
	exports.TOGGLE_FILE_SEARCH = "TOGGLE_FILE_SEARCH";

/***/ },
/* 252 */
/***/ 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/. */
	
	/**
	 * Sources reducer
	 * @module reducers/sources
	 */
	
	var fromJS = __webpack_require__(253);
	var I = __webpack_require__(229);
	var makeRecord = __webpack_require__(254);
	
	var State = makeRecord({
	  sources: I.Map(),
	  selectedLocation: undefined,
	  pendingSelectedLocation: undefined,
	  sourcesText: I.Map(),
	  tabs: I.List([])
	});
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : State();
	  var action = arguments[1];
	
	  switch (action.type) {
	    case "ADD_SOURCE":
	      {
	        var _source = action.source;
	        return state.mergeIn(["sources", action.source.id], _source);
	      }
	
	    case "SELECT_SOURCE":
	      return state.set("selectedLocation", {
	        sourceId: action.source.id,
	        line: action.line
	      }).set("pendingSelectedLocation", null).merge({
	        tabs: updateTabList(state, fromJS(action.source), action.tabIndex)
	      });
	
	    case "SELECT_SOURCE_URL":
	      return state.set("pendingSelectedLocation", {
	        url: action.url,
	        line: action.line
	      });
	
	    case "CLOSE_TAB":
	      return state.merge({ tabs: removeSourceFromTabList(state, action.id) }).set("selectedLocation", {
	        sourceId: getNewSelectedSourceId(state, action.id)
	      });
	
	    case "LOAD_SOURCE_TEXT":
	      return _updateText(state, action);
	
	    case "BLACKBOX":
	      if (action.status === "done") {
	        return state.setIn(["sources", action.source.id, "isBlackBoxed"], action.value.isBlackBoxed);
	      }
	      break;
	
	    case "TOGGLE_PRETTY_PRINT":
	      return _updateText(state, action);
	
	    case "NAVIGATE":
	      var source = getSelectedSource({ sources: state });
	      var _url = source && source.get("url");
	      return State().set("pendingSelectedLocation", { url: _url });
	  }
	
	  return state;
	}
	
	// TODO: Action is coerced to `any` unfortunately because how we type
	// asynchronous actions is wrong. The `value` may be null for the
	// "start" and "error" states but we don't type it like that. We need
	// to rethink how we type async actions.
	function _updateText(state, action) {
	  var source = action.source;
	  var sourceText = action.value;
	
	  if (action.status === "start") {
	    // Merge this in, don't set it. That way the previous value is
	    // still stored here, and we can retrieve it if whatever we're
	    // doing fails.
	    return state.mergeIn(["sourcesText", source.id], {
	      loading: true
	    });
	  }
	
	  if (action.status === "error") {
	    return state.setIn(["sourcesText", source.id], I.Map({
	      error: action.error
	    }));
	  }
	
	  return state.setIn(["sourcesText", source.id], I.Map({
	    text: sourceText.text,
	    contentType: sourceText.contentType
	  }));
	}
	
	function removeSourceFromTabList(state, id) {
	  return state.tabs.filter(tab => tab.get("id") != id);
	}
	
	/**
	 * Adds the new source to the tab list if it is not already there
	 * @memberof reducers/sources
	 * @static
	 */
	function updateTabList(state, source, tabIndex) {
	  var tabs = state.get("tabs");
	  var sourceIndex = tabs.indexOf(source);
	  var includesSource = !!tabs.find(t => t.get("id") == source.get("id"));
	
	  if (includesSource) {
	    if (tabIndex != undefined) {
	      return tabs.delete(sourceIndex).insert(tabIndex, source);
	    }
	
	    return tabs;
	  }
	
	  return tabs.insert(0, source);
	}
	
	/**
	 * Gets the next tab to select when a tab closes.
	 * @memberof reducers/sources
	 * @static
	 */
	function getNewSelectedSourceId(state, id) {
	  var tabs = state.get("tabs");
	  var selectedSource = getSelectedSource({ sources: state });
	
	  if (!selectedSource) {
	    return undefined;
	  } else if (selectedSource.get("id") != id) {
	    // If we're not closing the selected tab return the selected tab
	    return selectedSource.get("id");
	  }
	
	  var tabIndex = tabs.findIndex(tab => tab.get("id") == id);
	  var numTabs = tabs.count();
	
	  if (numTabs == 1) {
	    return undefined;
	  }
	
	  // if we're closing the last tab, select the penultimate tab
	  if (tabIndex + 1 == numTabs) {
	    return tabs.get(tabIndex - 1).get("id");
	  }
	
	  // return the next tab
	  return tabs.get(tabIndex + 1).get("id");
	}
	
	// Selectors
	
	// Unfortunately, it's really hard to make these functions accept just
	// the state that we care about and still type it with Flow. The
	// problem is that we want to re-export all selectors from a single
	// module for the UI, and all of those selectors should take the
	// top-level app state, so we'd have to "wrap" them to automatically
	// pick off the piece of state we're interested in. It's impossible
	// (right now) to type those wrapped functions.
	
	
	function getSource(state, id) {
	  return state.sources.sources.get(id);
	}
	
	function getSourceByURL(state, url) {
	  return state.sources.sources.find(source => source.get("url") == url);
	}
	
	function getSourceById(state, id) {
	  return state.sources.sources.find(source => source.get("id") == id);
	}
	
	function getSources(state) {
	  return state.sources.sources;
	}
	
	function getSourceText(state, id) {
	  return state.sources.sourcesText.get(id);
	}
	
	function getSourceTabs(state) {
	  return state.sources.tabs;
	}
	
	function getSelectedSource(state) {
	  if (state.sources.selectedLocation) {
	    return getSource(state, state.sources.selectedLocation.sourceId);
	  }
	  return undefined;
	}
	
	function getSelectedLocation(state) {
	  return state.sources.selectedLocation;
	}
	
	function getPendingSelectedLocation(state) {
	  return state.sources.pendingSelectedLocation;
	}
	
	function getPrettySource(state, id) {
	  var source = getSource(state, id);
	  if (!source) {
	    return;
	  }
	
	  return getSourceByURL(state, source.get("url") + ":formatted");
	}
	
	module.exports = {
	  State,
	  update,
	  getSource,
	  getSourceByURL,
	  getSourceById,
	  getSources,
	  getSourceText,
	  getSourceTabs,
	  getSelectedSource,
	  getSelectedLocation,
	  getPendingSelectedLocation,
	  getPrettySource
	};

/***/ },
/* 253 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * Immutable JS conversion utils
	 * @deprecated
	 * @module utils/fromJS
	 */
	
	var Immutable = __webpack_require__(229);
	
	/**
	 * When our app state is fully typed, we should be able to get rid of
	 * this function. This is only temporarily necessary to support
	 * converting typed objects to immutable.js, which usually happens in
	 * reducers.
	 *
	 * @memberof utils/fromJS
	 * @static
	 */
	function fromJS(value) {
	  if (Array.isArray(value)) {
	    return Immutable.Seq(value).map(fromJS).toList();
	  }
	  if (value && value.constructor.meta) {
	    // This adds support for tcomb objects which are native JS objects
	    // but are not "plain", so the above checks fail. Since they
	    // behave the same we can use the same constructors, but we need
	    // special checks for them.
	    var kind = value.constructor.meta.kind;
	    if (kind === "struct") {
	      return Immutable.Seq(value).map(fromJS).toMap();
	    } else if (kind === "list") {
	      return Immutable.Seq(value).map(fromJS).toList();
	    }
	  }
	
	  // If it's a primitive type, just return the value. Note `==` check
	  // for null, which is intentionally used to match either `null` or
	  // `undefined`.
	  if (value == null || typeof value !== "object") {
	    return value;
	  }
	
	  // Otherwise, treat it like an object. We can't reliably detect if
	  // it's a plain object because we might be objects from other JS
	  // contexts so `Object !== Object`.
	  return Immutable.Seq(value).map(fromJS).toMap();
	}
	
	module.exports = fromJS;

/***/ },
/* 254 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * When Flow 0.29 is released (very soon), we can use this Record type
	 * instead of the builtin immutable.js Record type. This is better
	 * because all the fields are actually typed, unlike the builtin one.
	 * This depends on a performance fix that will go out in 0.29 though;
	 * @module utils/makeRecord
	 */
	
	var I = __webpack_require__(229);
	
	/**
	 * @memberof utils/makeRecord
	 * @static
	 */
	
	
	/**
	 * Make an immutable record type
	 *
	 * @param spec - the keys and their default values
	 * @return a state record factory function
	 * @memberof utils/makeRecord
	 * @static
	 */
	function makeRecord(spec) {
	  return I.Record(spec);
	}
	
	module.exports = makeRecord;

/***/ },
/* 255 */
/***/ 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/. */
	
	/**
	 * Breakpoints reducer
	 * @module reducers/breakpoints
	 */
	
	var fromJS = __webpack_require__(253);
	
	var _require = __webpack_require__(244);
	
	var updateObj = _require.updateObj;
	
	var I = __webpack_require__(229);
	var makeRecord = __webpack_require__(254);
	
	var State = makeRecord({
	  breakpoints: I.Map(),
	  breakpointsDisabled: false
	});
	
	// Return the first argument that is a string, or null if nothing is a
	// string.
	function firstString() {
	  for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	    args[_key] = arguments[_key];
	  }
	
	  for (var arg of args) {
	    if (typeof arg === "string") {
	      return arg;
	    }
	  }
	  return null;
	}
	
	function locationMoved(location, newLocation) {
	  return location.line !== newLocation.line || location.column != null && location.column !== newLocation.column;
	}
	
	function makeLocationId(location) {
	  return location.sourceId + ":" + location.line.toString();
	}
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : State();
	  var action = arguments[1];
	
	  switch (action.type) {
	    case "ADD_BREAKPOINT":
	      {
	        var id = makeLocationId(action.breakpoint.location);
	
	        if (action.status === "start") {
	          var bp = state.breakpoints.get(id) || action.breakpoint;
	
	          return state.setIn(["breakpoints", id], updateObj(bp, {
	            disabled: false,
	            loading: true,
	            // We want to do an OR here, but we can't because we need
	            // empty strings to be truthy, i.e. an empty string is a valid
	            // condition.
	            condition: firstString(action.condition, bp.condition)
	          }));
	        } else if (action.status === "done") {
	          var _action$value = action.value;
	          var breakpointId = _action$value.id;
	          var text = _action$value.text;
	
	          var location = action.breakpoint.location;
	          var actualLocation = action.value.actualLocation;
	
	          // If the breakpoint moved, update the map
	
	          if (locationMoved(location, actualLocation)) {
	            state = state.deleteIn(["breakpoints", id]);
	
	            var movedId = makeLocationId(actualLocation);
	            var currentBp = state.breakpoints.get(movedId) || fromJS(action.breakpoint);
	            var newBp = updateObj(currentBp, { location: actualLocation });
	            state = state.setIn(["breakpoints", movedId], newBp);
	            location = actualLocation;
	          }
	
	          var locationId = makeLocationId(location);
	          var _bp = state.breakpoints.get(locationId);
	          return state.setIn(["breakpoints", locationId], updateObj(_bp, {
	            id: breakpointId,
	            disabled: false,
	            loading: false,
	            text: text
	          }));
	        } else if (action.status === "error") {
	          // Remove the optimistic update
	          return state.deleteIn(["breakpoints", id]);
	        }
	        break;
	      }
	
	    case "REMOVE_BREAKPOINT":
	      {
	        if (action.status === "done") {
	          var _id = makeLocationId(action.breakpoint.location);
	
	          if (action.disabled) {
	            var _bp2 = state.breakpoints.get(_id);
	            return state.setIn(["breakpoints", _id], updateObj(_bp2, {
	              loading: false, disabled: true
	            }));
	          }
	
	          return state.deleteIn(["breakpoints", _id]);
	        }
	        break;
	      }
	
	    case "TOGGLE_BREAKPOINTS":
	      {
	        if (action.status === "start") {
	          return state.set("breakpointsDisabled", action.shouldDisableBreakpoints);
	        }
	        break;
	      }
	
	    case "SET_BREAKPOINT_CONDITION":
	      {
	        var _id2 = makeLocationId(action.breakpoint.location);
	
	        if (action.status === "start") {
	          var _bp3 = state.breakpoints.get(_id2);
	          return state.setIn(["breakpoints", _id2], updateObj(_bp3, {
	            loading: true,
	            condition: action.condition
	          }));
	        } else if (action.status === "done") {
	          var _bp4 = state.breakpoints.get(_id2);
	          return state.setIn(["breakpoints", _id2], updateObj(_bp4, {
	            id: action.value.id,
	            loading: false
	          }));
	        } else if (action.status === "error") {
	          return state.deleteIn(["breakpoints", _id2]);
	        }
	
	        break;
	      }}
	
	  return state;
	}
	
	// Selectors
	
	function getBreakpoint(state, location) {
	  return state.breakpoints.breakpoints.get(makeLocationId(location));
	}
	
	function getBreakpoints(state) {
	  return state.breakpoints.breakpoints;
	}
	
	function getBreakpointsForSource(state, sourceId) {
	  return state.breakpoints.breakpoints.filter(bp => {
	    return bp.location.sourceId === sourceId;
	  });
	}
	
	function getBreakpointsDisabled(state) {
	  return state.breakpoints.get("breakpointsDisabled");
	}
	
	function getBreakpointsLoading(state) {
	  var breakpoints = getBreakpoints(state);
	  var isLoading = !!breakpoints.valueSeq().filter(bp => bp.loading).first();
	
	  return breakpoints.size > 0 && isLoading;
	}
	
	module.exports = {
	  State,
	  update,
	  makeLocationId,
	  getBreakpoint,
	  getBreakpoints,
	  getBreakpointsForSource,
	  getBreakpointsDisabled,
	  getBreakpointsLoading
	};

/***/ },
/* 256 */
/***/ function(module, exports, __webpack_require__) {

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this
	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	var constants = __webpack_require__(251);
	var initialState = [];
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
	  var action = arguments[1];
	  var seqId = action.seqId;
	
	
	  if (action.type === constants.NAVIGATE) {
	    return initialState;
	  } else if (seqId) {
	    var newState = void 0;
	    if (action.status === "start") {
	      newState = [].concat(_toConsumableArray(state), [seqId]);
	    } else if (action.status === "error" || action.status === "done") {
	      newState = state.filter(id => id !== seqId);
	    }
	
	    return newState;
	  }
	
	  return state;
	}
	
	module.exports = update;

/***/ },
/* 257 */
/***/ 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/. */
	
	var constants = __webpack_require__(251);
	var fromJS = __webpack_require__(253);
	
	var initialState = fromJS({
	  pause: null,
	  isWaitingOnBreak: false,
	  frames: null,
	  selectedFrameId: null,
	  loadedObjects: {},
	  shouldPauseOnExceptions: false,
	  shouldIgnoreCaughtExceptions: false,
	  expressions: []
	});
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
	  var action = arguments[1];
	  var emit = arguments[2];
	
	  switch (action.type) {
	    case constants.PAUSED:
	      {
	        var selectedFrameId = action.selectedFrameId;
	        var frames = action.frames;
	        var pauseInfo = action.pauseInfo;
	
	        pauseInfo.isInterrupted = pauseInfo.why.type === "interrupted";
	
	        return state.merge({
	          isWaitingOnBreak: false,
	          pause: fromJS(pauseInfo),
	          selectedFrameId,
	          frames
	        });
	      }
	
	    case constants.RESUME:
	      return state.merge({
	        pause: null,
	        frames: null,
	        selectedFrameId: null,
	        loadedObjects: {}
	      });
	
	    case constants.TOGGLE_PRETTY_PRINT:
	      if (action.status == "done") {
	        var _frames = action.value.frames;
	        var pause = state.get("pause");
	        if (pause) {
	          pause = pause.set("frame", fromJS(_frames[0]));
	        }
	
	        return state.merge({ pause, frames: _frames });
	      }
	
	      break;
	    case constants.BREAK_ON_NEXT:
	      return state.set("isWaitingOnBreak", true);
	
	    case constants.LOADED_FRAMES:
	      if (action.status == "done") {
	        return state.set("frames", action.value.frames);
	      }
	
	      break;
	    case constants.SELECT_FRAME:
	      return state.set("selectedFrameId", action.frame.id);
	
	    case constants.LOAD_OBJECT_PROPERTIES:
	      if (action.status === "done") {
	        var ownProperties = action.value.ownProperties;
	        var prototype = action.value.prototype;
	
	        return state.setIn(["loadedObjects", action.objectId], { ownProperties, prototype });
	      }
	      break;
	
	    case constants.NAVIGATE:
	      return initialState;
	
	    case constants.PAUSE_ON_EXCEPTIONS:
	      var shouldPauseOnExceptions = action.shouldPauseOnExceptions;
	      var shouldIgnoreCaughtExceptions = action.shouldIgnoreCaughtExceptions;
	
	      return state.merge({
	        shouldPauseOnExceptions,
	        shouldIgnoreCaughtExceptions
	      });
	
	    case constants.ADD_EXPRESSION:
	      return state.setIn(["expressions", action.id], { id: action.id,
	        input: action.input,
	        value: action.value,
	        updating: false });
	
	    case constants.EVALUATE_EXPRESSION:
	      if (action.status === "done") {
	        return state.mergeIn(["expressions", action.id], { id: action.id,
	          input: action.input,
	          value: action.value,
	          updating: false });
	      }
	      break;
	
	    case constants.UPDATE_EXPRESSION:
	      return state.mergeIn(["expressions", action.id], { id: action.id,
	        input: action.input,
	        updating: true });
	
	    case constants.DELETE_EXPRESSION:
	      return state.deleteIn(["expressions", action.id]);
	  }
	
	  return state;
	}
	
	function getPause(state) {
	  return state.pause.get("pause");
	}
	
	function getLoadedObjects(state) {
	  return state.pause.get("loadedObjects");
	}
	
	function getExpressions(state) {
	  return state.pause.get("expressions");
	}
	
	function getIsWaitingOnBreak(state) {
	  return state.pause.get("isWaitingOnBreak");
	}
	
	function getShouldPauseOnExceptions(state) {
	  return state.pause.get("shouldPauseOnExceptions");
	}
	
	function getShouldIgnoreCaughtExceptions(state) {
	  return state.pause.get("shouldIgnoreCaughtExceptions");
	}
	
	function getFrames(state) {
	  return state.pause.get("frames");
	}
	
	function getSelectedFrame(state) {
	  var selectedFrameId = state.pause.get("selectedFrameId");
	  var frames = state.pause.get("frames");
	  return frames && frames.find(frame => frame.id == selectedFrameId);
	}
	
	module.exports = {
	  initialState,
	  update,
	  getPause,
	  getLoadedObjects,
	  getExpressions,
	  getIsWaitingOnBreak,
	  getShouldPauseOnExceptions,
	  getShouldIgnoreCaughtExceptions,
	  getFrames,
	  getSelectedFrame
	};

/***/ },
/* 258 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * UI reducer
	 * @module reducers/ui
	 */
	
	var constants = __webpack_require__(251);
	var makeRecord = __webpack_require__(254);
	
	var State = makeRecord({
	  searchOn: false
	});
	
	function update() {
	  var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : State();
	  var action = arguments[1];
	
	  switch (action.type) {
	    case constants.TOGGLE_FILE_SEARCH:
	      {
	        return state.set("searchOn", action.searchOn);
	      }
	    default:
	      {
	        return state;
	      }
	  }
	}
	
	// NOTE: we'd like to have the app state fully typed
	// https://github.com/devtools-html/debugger.html/blob/master/public/js/reducers/sources.js#L179-L185
	
	
	function getFileSearchState(state) {
	  return state.ui.get("searchOn");
	}
	
	module.exports = {
	  State,
	  update,
	  getFileSearchState
	};

/***/ },
/* 259 */
/***/ function(module, exports, __webpack_require__) {

	var sources = __webpack_require__(252);
	var pause = __webpack_require__(257);
	var breakpoints = __webpack_require__(255);
	var ui = __webpack_require__(258);
	
	/**
	 * @param object - location
	 */
	
	module.exports = {
	  getSource: sources.getSource,
	  getSourceByURL: sources.getSourceByURL,
	  getSourceById: sources.getSourceById,
	  getSources: sources.getSources,
	  getSourceText: sources.getSourceText,
	  getSourceTabs: sources.getSourceTabs,
	  getSelectedSource: sources.getSelectedSource,
	  getSelectedLocation: sources.getSelectedLocation,
	  getPendingSelectedLocation: sources.getPendingSelectedLocation,
	  getPrettySource: sources.getPrettySource,
	
	  getBreakpoint: breakpoints.getBreakpoint,
	  getBreakpoints: breakpoints.getBreakpoints,
	  getBreakpointsForSource: breakpoints.getBreakpointsForSource,
	  getBreakpointsDisabled: breakpoints.getBreakpointsDisabled,
	  getBreakpointsLoading: breakpoints.getBreakpointsLoading,
	
	  getPause: pause.getPause,
	  getLoadedObjects: pause.getLoadedObjects,
	  getExpressions: pause.getExpressions,
	  getExpressionInputVisibility: pause.getExpressionInputVisibility,
	  getIsWaitingOnBreak: pause.getIsWaitingOnBreak,
	  getShouldPauseOnExceptions: pause.getShouldPauseOnExceptions,
	  getShouldIgnoreCaughtExceptions: pause.getShouldIgnoreCaughtExceptions,
	  getFrames: pause.getFrames,
	  getSelectedFrame: pause.getSelectedFrame,
	
	  getFileSearchState: ui.getFileSearchState
	};

/***/ },
/* 260 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	var createFactory = React.createFactory;
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var _require3 = __webpack_require__(261);
	
	var cmdString = _require3.cmdString;
	
	var actions = __webpack_require__(262);
	
	var _require4 = __webpack_require__(259);
	
	var getSources = _require4.getSources;
	var getSelectedSource = _require4.getSelectedSource;
	
	var _require5 = __webpack_require__(28);
	
	var KeyShortcuts = _require5.KeyShortcuts;
	
	var shortcuts = new KeyShortcuts({ window });
	
	__webpack_require__(283);
	__webpack_require__(286);
	__webpack_require__(288);
	__webpack_require__(290);
	
	var _require6 = __webpack_require__(30);
	
	var SplitBox = _require6.SplitBox;
	
	SplitBox = createFactory(SplitBox);
	
	var SourceSearch = createFactory(__webpack_require__(292));
	var Sources = createFactory(__webpack_require__(339));
	var Editor = createFactory(__webpack_require__(400));
	var RightSidebar = createFactory(__webpack_require__(416));
	var SourceTabs = createFactory(__webpack_require__(452));
	
	var App = React.createClass({
	  propTypes: {
	    sources: PropTypes.object,
	    selectSource: PropTypes.func,
	    selectedSource: PropTypes.object
	  },
	
	  displayName: "App",
	
	  getChildContext() {
	    return { shortcuts };
	  },
	
	  renderWelcomeBox() {
	    return dom.div({ className: "welcomebox" }, L10N.getFormatStr("welcome.search", cmdString() + "+P"));
	  },
	
	  renderCenterPane() {
	    return dom.div({ className: "center-pane" }, dom.div({ className: "editor-container" }, SourceTabs(), Editor(), !this.props.selectedSource ? this.renderWelcomeBox() : null, SourceSearch()));
	  },
	
	  render: function () {
	    return dom.div({ className: "debugger" }, SplitBox({
	      style: { width: "100vw" },
	      initialSize: "300px",
	      minSize: 10,
	      maxSize: "50%",
	      splitterSize: 1,
	      startPanel: Sources({ sources: this.props.sources }),
	      endPanel: SplitBox({
	        initialSize: "300px",
	        minSize: 10,
	        maxSize: "80%",
	        splitterSize: 1,
	        endPanelControl: true,
	        startPanel: this.renderCenterPane(this.props),
	        endPanel: RightSidebar()
	      })
	    }));
	  }
	});
	
	App.childContextTypes = {
	  shortcuts: PropTypes.object
	};
	
	module.exports = connect(state => ({ sources: getSources(state),
	  selectedSource: getSelectedSource(state)
	}), dispatch => bindActionCreators(actions, dispatch))(App);

/***/ },
/* 261 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * Utils for keyboard command strings
	 * @module utils/text
	 */
	
	var _require = __webpack_require__(30);
	
	var appinfo = _require.Services.appinfo;
	
	/**
	 * @memberof utils/text
	 * @static
	 */
	
	function cmdString() {
	  return appinfo.OS === "Darwin" ? "⌘" : "Ctrl";
	}
	
	module.exports = {
	  cmdString
	};

/***/ },
/* 262 */
/***/ function(module, exports, __webpack_require__) {

	var breakpoints = __webpack_require__(263);
	var eventListeners = __webpack_require__(271);
	var sources = __webpack_require__(273);
	var pause = __webpack_require__(280);
	var navigation = __webpack_require__(281);
	var ui = __webpack_require__(282);
	
	module.exports = Object.assign(navigation, breakpoints, eventListeners, sources, pause, ui);

/***/ },
/* 263 */
/***/ function(module, exports, __webpack_require__) {

	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
	
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this
	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	/**
	 * Redux actions for breakpoints
	 * @module actions/breakpoints
	 */
	
	var constants = __webpack_require__(251);
	
	var _require = __webpack_require__(242);
	
	var PROMISE = _require.PROMISE;
	
	var _require2 = __webpack_require__(259);
	
	var getBreakpoint = _require2.getBreakpoint;
	var getBreakpoints = _require2.getBreakpoints;
	var getSource = _require2.getSource;
	
	var _require3 = __webpack_require__(264);
	
	var getOriginalLocation = _require3.getOriginalLocation;
	var getGeneratedLocation = _require3.getGeneratedLocation;
	var isOriginalId = _require3.isOriginalId;
	
	
	function _breakpointExists(state, location) {
	  var currentBp = getBreakpoint(state, location);
	  return currentBp && !currentBp.disabled;
	}
	
	function _getOrCreateBreakpoint(state, location, condition) {
	  return getBreakpoint(state, location) || { location, condition, text: "" };
	}
	
	/**
	 * Enabling a breakpoint calls {@link addBreakpoint}
	 * which will reuse the existing breakpoint information that is stored.
	 *
	 * @memberof actions/breakpoints
	 * @static
	 */
	function enableBreakpoint(location) {
	  return addBreakpoint(location);
	}
	
	/**
	 * Add a new or enable an existing breakpoint
	 *
	 * @memberof actions/breakpoints
	 * @static
	 * @param {String} $1.condition Conditional breakpoint condition value
	 * @param {Function} $1.getTextForLine Get the text to represent the line
	 */
	function addBreakpoint(location) {
	  var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	
	  var condition = _ref.condition;
	  var getTextForLine = _ref.getTextForLine;
	
	  return (_ref2) => {
	    var dispatch = _ref2.dispatch;
	    var getState = _ref2.getState;
	    var client = _ref2.client;
	
	    if (_breakpointExists(getState(), location)) {
	      return Promise.resolve();
	    }
	
	    var bp = _getOrCreateBreakpoint(getState(), location, condition);
	
	    return dispatch({
	      type: constants.ADD_BREAKPOINT,
	      breakpoint: bp,
	      condition: condition,
	      [PROMISE]: _asyncToGenerator(function* () {
	        if (isOriginalId(bp.location.sourceId)) {
	          var source = getSource(getState(), bp.location.sourceId);
	          location = yield getGeneratedLocation(bp.location, source.toJS());
	        }
	
	        var _ref4 = yield client.setBreakpoint(location, bp.condition, isOriginalId(bp.location.sourceId));
	
	        var id = _ref4.id;
	        var actualLocation = _ref4.actualLocation;
	
	
	        actualLocation = yield getOriginalLocation(actualLocation);
	
	        // If this breakpoint is being re-enabled, it already has a
	        // text snippet.
	        var text = bp.text;
	        if (!text) {
	          text = getTextForLine ? getTextForLine(actualLocation.line) : "";
	        }
	
	        return { id, actualLocation, text };
	      })()
	    });
	  };
	}
	
	/**
	 * Disable a single breakpoint
	 *
	 * @memberof actions/breakpoints
	 * @static
	 */
	function disableBreakpoint(location) {
	  return _removeOrDisableBreakpoint(location, true);
	}
	
	/**
	 * Remove a single breakpoint
	 *
	 * @memberof actions/breakpoints
	 * @static
	 */
	function removeBreakpoint(location) {
	  return _removeOrDisableBreakpoint(location);
	}
	
	function _removeOrDisableBreakpoint(location, isDisabled) {
	  return (_ref5) => {
	    var dispatch = _ref5.dispatch;
	    var getState = _ref5.getState;
	    var client = _ref5.client;
	
	    var bp = getBreakpoint(getState(), location);
	    if (!bp) {
	      throw new Error("attempt to remove breakpoint that does not exist");
	    }
	    if (bp.loading) {
	      // TODO(jwl): make this wait until the breakpoint is saved if it
	      // is still loading
	      throw new Error("attempt to remove unsaved breakpoint");
	    }
	
	    var action = {
	      type: constants.REMOVE_BREAKPOINT,
	      breakpoint: bp,
	      disabled: isDisabled
	    };
	
	    // If the breakpoint is already disabled, we don't need to remove
	    // it from the server. We just need to dispatch an action
	    // simulating a successful server request to remove it, and it
	    // will be removed completely from the state.
	    if (!bp.disabled) {
	      return dispatch(Object.assign({}, action, {
	        [PROMISE]: client.removeBreakpoint(bp.id)
	      }));
	    }
	    return dispatch(Object.assign({}, action, { status: "done" }));
	  };
	}
	
	/**
	 * Toggle All Breakpoints
	 *
	 * @memberof actions/breakpoints
	 * @static
	 */
	function toggleAllBreakpoints(shouldDisableBreakpoints) {
	  return (_ref6) => {
	    var dispatch = _ref6.dispatch;
	    var getState = _ref6.getState;
	
	    var breakpoints = getBreakpoints(getState());
	    return dispatch({
	      type: constants.TOGGLE_BREAKPOINTS,
	      shouldDisableBreakpoints,
	      [PROMISE]: _asyncToGenerator(function* () {
	        for (var _ref8 of breakpoints) {
	          var _ref9 = _slicedToArray(_ref8, 2);
	
	          var breakpoint = _ref9[1];
	
	          if (shouldDisableBreakpoints) {
	            yield dispatch(disableBreakpoint(breakpoint.location));
	          } else {
	            yield dispatch(enableBreakpoint(breakpoint.location));
	          }
	        }
	      })()
	    });
	  };
	}
	
	/**
	 * Update the condition of a breakpoint.
	 *
	 * @throws {Error} "not implemented"
	 * @memberof actions/breakpoints
	 * @static
	 * @param {Location} location
	 *        @see DebuggerController.Breakpoints.addBreakpoint
	 * @param {string} condition
	 *        The condition to set on the breakpoint
	 */
	function setBreakpointCondition(location) {
	  var _ref10 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	
	  var condition = _ref10.condition;
	  var getTextForLine = _ref10.getTextForLine;
	
	  // location: Location, condition: string, { getTextForLine }) {
	  return (_ref11) => {
	    var dispatch = _ref11.dispatch;
	    var getState = _ref11.getState;
	    var client = _ref11.client;
	
	    var bp = getBreakpoint(getState(), location);
	    if (!bp) {
	      return dispatch(addBreakpoint(location, { condition, getTextForLine }));
	    }
	
	    if (bp.loading) {
	      // TODO(jwl): when this function is called, make sure the action
	      // creator waits for the breakpoint to exist
	      throw new Error("breakpoint must be saved");
	    }
	
	    return dispatch({
	      type: constants.SET_BREAKPOINT_CONDITION,
	      breakpoint: bp,
	      condition: condition,
	      [PROMISE]: client.setBreakpointCondition(bp.id, location, condition, isOriginalId(bp.location.sourceId))
	    });
	  };
	}
	
	module.exports = {
	  enableBreakpoint,
	  addBreakpoint,
	  disableBreakpoint,
	  removeBreakpoint,
	  toggleAllBreakpoints,
	  setBreakpointCondition
	};

/***/ },
/* 264 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(89);
	
	var getValue = _require.getValue;
	var isEnabled = _require.isEnabled;
	
	var _require2 = __webpack_require__(244);
	
	var workerTask = _require2.workerTask;
	
	var _require3 = __webpack_require__(265);
	
	var originalToGeneratedId = _require3.originalToGeneratedId;
	var generatedToOriginalId = _require3.generatedToOriginalId;
	var isGeneratedId = _require3.isGeneratedId;
	var isOriginalId = _require3.isOriginalId;
	
	var _require4 = __webpack_require__(270);
	
	var prefs = _require4.prefs;
	
	
	var sourceMapWorker = void 0;
	function restartWorker() {
	  if (sourceMapWorker) {
	    sourceMapWorker.terminate();
	  }
	  sourceMapWorker = new Worker(getValue("baseWorkerURL") + "source-map-worker.js");
	
	  if (isEnabled("sourceMaps")) {
	    sourceMapWorker.postMessage({ id: 0, method: "enableSourceMaps" });
	  }
	}
	restartWorker();
	
	function destroyWorker() {
	  if (sourceMapWorker) {
	    sourceMapWorker.terminate();
	    sourceMapWorker = null;
	  }
	}
	
	function shouldSourceMap() {
	  return isEnabled("sourceMaps") && prefs.clientSourceMapsEnabled;
	}
	
	var getOriginalURLs = workerTask(sourceMapWorker, "getOriginalURLs");
	var getGeneratedLocation = workerTask(sourceMapWorker, "getGeneratedLocation");
	var getOriginalLocation = workerTask(sourceMapWorker, "getOriginalLocation");
	var getOriginalSourceText = workerTask(sourceMapWorker, "getOriginalSourceText");
	var applySourceMap = workerTask(sourceMapWorker, "applySourceMap");
	var clearSourceMaps = workerTask(sourceMapWorker, "clearSourceMaps");
	
	module.exports = {
	  originalToGeneratedId,
	  generatedToOriginalId,
	  isGeneratedId,
	  isOriginalId,
	
	  getOriginalURLs,
	  getGeneratedLocation,
	  getOriginalLocation,
	  getOriginalSourceText,
	  applySourceMap,
	  clearSourceMaps,
	  destroyWorker,
	  shouldSourceMap
	};

/***/ },
/* 265 */
/***/ function(module, exports, __webpack_require__) {

	var md5 = __webpack_require__(266);
	
	function originalToGeneratedId(originalId) {
	  var match = originalId.match(/(.*)\/originalSource/);
	  return match ? match[1] : "";
	}
	
	function generatedToOriginalId(generatedId, url) {
	  return generatedId + "/originalSource-" + md5(url);
	}
	
	function isOriginalId(id) {
	  return !!id.match(/\/originalSource/);
	}
	
	function isGeneratedId(id) {
	  return !isOriginalId(id);
	}
	
	module.exports = {
	  originalToGeneratedId, generatedToOriginalId, isOriginalId, isGeneratedId
	};

/***/ },
/* 266 */
/***/ function(module, exports, __webpack_require__) {

	(function(){
	  var crypt = __webpack_require__(267),
	      utf8 = __webpack_require__(268).utf8,
	      isBuffer = __webpack_require__(269),
	      bin = __webpack_require__(268).bin,
	
	  // The core
	  md5 = function (message, options) {
	    // Convert to byte array
	    if (message.constructor == String)
	      if (options && options.encoding === 'binary')
	        message = bin.stringToBytes(message);
	      else
	        message = utf8.stringToBytes(message);
	    else if (isBuffer(message))
	      message = Array.prototype.slice.call(message, 0);
	    else if (!Array.isArray(message))
	      message = message.toString();
	    // else, assume byte array already
	
	    var m = crypt.bytesToWords(message),
	        l = message.length * 8,
	        a =  1732584193,
	        b = -271733879,
	        c = -1732584194,
	        d =  271733878;
	
	    // Swap endian
	    for (var i = 0; i < m.length; i++) {
	      m[i] = ((m[i] <<  8) | (m[i] >>> 24)) & 0x00FF00FF |
	             ((m[i] << 24) | (m[i] >>>  8)) & 0xFF00FF00;
	    }
	
	    // Padding
	    m[l >>> 5] |= 0x80 << (l % 32);
	    m[(((l + 64) >>> 9) << 4) + 14] = l;
	
	    // Method shortcuts
	    var FF = md5._ff,
	        GG = md5._gg,
	        HH = md5._hh,
	        II = md5._ii;
	
	    for (var i = 0; i < m.length; i += 16) {
	
	      var aa = a,
	          bb = b,
	          cc = c,
	          dd = d;
	
	      a = FF(a, b, c, d, m[i+ 0],  7, -680876936);
	      d = FF(d, a, b, c, m[i+ 1], 12, -389564586);
	      c = FF(c, d, a, b, m[i+ 2], 17,  606105819);
	      b = FF(b, c, d, a, m[i+ 3], 22, -1044525330);
	      a = FF(a, b, c, d, m[i+ 4],  7, -176418897);
	      d = FF(d, a, b, c, m[i+ 5], 12,  1200080426);
	      c = FF(c, d, a, b, m[i+ 6], 17, -1473231341);
	      b = FF(b, c, d, a, m[i+ 7], 22, -45705983);
	      a = FF(a, b, c, d, m[i+ 8],  7,  1770035416);
	      d = FF(d, a, b, c, m[i+ 9], 12, -1958414417);
	      c = FF(c, d, a, b, m[i+10], 17, -42063);
	      b = FF(b, c, d, a, m[i+11], 22, -1990404162);
	      a = FF(a, b, c, d, m[i+12],  7,  1804603682);
	      d = FF(d, a, b, c, m[i+13], 12, -40341101);
	      c = FF(c, d, a, b, m[i+14], 17, -1502002290);
	      b = FF(b, c, d, a, m[i+15], 22,  1236535329);
	
	      a = GG(a, b, c, d, m[i+ 1],  5, -165796510);
	      d = GG(d, a, b, c, m[i+ 6],  9, -1069501632);
	      c = GG(c, d, a, b, m[i+11], 14,  643717713);
	      b = GG(b, c, d, a, m[i+ 0], 20, -373897302);
	      a = GG(a, b, c, d, m[i+ 5],  5, -701558691);
	      d = GG(d, a, b, c, m[i+10],  9,  38016083);
	      c = GG(c, d, a, b, m[i+15], 14, -660478335);
	      b = GG(b, c, d, a, m[i+ 4], 20, -405537848);
	      a = GG(a, b, c, d, m[i+ 9],  5,  568446438);
	      d = GG(d, a, b, c, m[i+14],  9, -1019803690);
	      c = GG(c, d, a, b, m[i+ 3], 14, -187363961);
	      b = GG(b, c, d, a, m[i+ 8], 20,  1163531501);
	      a = GG(a, b, c, d, m[i+13],  5, -1444681467);
	      d = GG(d, a, b, c, m[i+ 2],  9, -51403784);
	      c = GG(c, d, a, b, m[i+ 7], 14,  1735328473);
	      b = GG(b, c, d, a, m[i+12], 20, -1926607734);
	
	      a = HH(a, b, c, d, m[i+ 5],  4, -378558);
	      d = HH(d, a, b, c, m[i+ 8], 11, -2022574463);
	      c = HH(c, d, a, b, m[i+11], 16,  1839030562);
	      b = HH(b, c, d, a, m[i+14], 23, -35309556);
	      a = HH(a, b, c, d, m[i+ 1],  4, -1530992060);
	      d = HH(d, a, b, c, m[i+ 4], 11,  1272893353);
	      c = HH(c, d, a, b, m[i+ 7], 16, -155497632);
	      b = HH(b, c, d, a, m[i+10], 23, -1094730640);
	      a = HH(a, b, c, d, m[i+13],  4,  681279174);
	      d = HH(d, a, b, c, m[i+ 0], 11, -358537222);
	      c = HH(c, d, a, b, m[i+ 3], 16, -722521979);
	      b = HH(b, c, d, a, m[i+ 6], 23,  76029189);
	      a = HH(a, b, c, d, m[i+ 9],  4, -640364487);
	      d = HH(d, a, b, c, m[i+12], 11, -421815835);
	      c = HH(c, d, a, b, m[i+15], 16,  530742520);
	      b = HH(b, c, d, a, m[i+ 2], 23, -995338651);
	
	      a = II(a, b, c, d, m[i+ 0],  6, -198630844);
	      d = II(d, a, b, c, m[i+ 7], 10,  1126891415);
	      c = II(c, d, a, b, m[i+14], 15, -1416354905);
	      b = II(b, c, d, a, m[i+ 5], 21, -57434055);
	      a = II(a, b, c, d, m[i+12],  6,  1700485571);
	      d = II(d, a, b, c, m[i+ 3], 10, -1894986606);
	      c = II(c, d, a, b, m[i+10], 15, -1051523);
	      b = II(b, c, d, a, m[i+ 1], 21, -2054922799);
	      a = II(a, b, c, d, m[i+ 8],  6,  1873313359);
	      d = II(d, a, b, c, m[i+15], 10, -30611744);
	      c = II(c, d, a, b, m[i+ 6], 15, -1560198380);
	      b = II(b, c, d, a, m[i+13], 21,  1309151649);
	      a = II(a, b, c, d, m[i+ 4],  6, -145523070);
	      d = II(d, a, b, c, m[i+11], 10, -1120210379);
	      c = II(c, d, a, b, m[i+ 2], 15,  718787259);
	      b = II(b, c, d, a, m[i+ 9], 21, -343485551);
	
	      a = (a + aa) >>> 0;
	      b = (b + bb) >>> 0;
	      c = (c + cc) >>> 0;
	      d = (d + dd) >>> 0;
	    }
	
	    return crypt.endian([a, b, c, d]);
	  };
	
	  // Auxiliary functions
	  md5._ff  = function (a, b, c, d, x, s, t) {
	    var n = a + (b & c | ~b & d) + (x >>> 0) + t;
	    return ((n << s) | (n >>> (32 - s))) + b;
	  };
	  md5._gg  = function (a, b, c, d, x, s, t) {
	    var n = a + (b & d | c & ~d) + (x >>> 0) + t;
	    return ((n << s) | (n >>> (32 - s))) + b;
	  };
	  md5._hh  = function (a, b, c, d, x, s, t) {
	    var n = a + (b ^ c ^ d) + (x >>> 0) + t;
	    return ((n << s) | (n >>> (32 - s))) + b;
	  };
	  md5._ii  = function (a, b, c, d, x, s, t) {
	    var n = a + (c ^ (b | ~d)) + (x >>> 0) + t;
	    return ((n << s) | (n >>> (32 - s))) + b;
	  };
	
	  // Package private blocksize
	  md5._blocksize = 16;
	  md5._digestsize = 16;
	
	  module.exports = function (message, options) {
	    if (message === undefined || message === null)
	      throw new Error('Illegal argument ' + message);
	
	    var digestbytes = crypt.wordsToBytes(md5(message, options));
	    return options && options.asBytes ? digestbytes :
	        options && options.asString ? bin.bytesToString(digestbytes) :
	        crypt.bytesToHex(digestbytes);
	  };
	
	})();


/***/ },
/* 267 */
/***/ function(module, exports) {

	(function() {
	  var base64map
	      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
	
	  crypt = {
	    // Bit-wise rotation left
	    rotl: function(n, b) {
	      return (n << b) | (n >>> (32 - b));
	    },
	
	    // Bit-wise rotation right
	    rotr: function(n, b) {
	      return (n << (32 - b)) | (n >>> b);
	    },
	
	    // Swap big-endian to little-endian and vice versa
	    endian: function(n) {
	      // If number given, swap endian
	      if (n.constructor == Number) {
	        return crypt.rotl(n, 8) & 0x00FF00FF | crypt.rotl(n, 24) & 0xFF00FF00;
	      }
	
	      // Else, assume array and swap all items
	      for (var i = 0; i < n.length; i++)
	        n[i] = crypt.endian(n[i]);
	      return n;
	    },
	
	    // Generate an array of any length of random bytes
	    randomBytes: function(n) {
	      for (var bytes = []; n > 0; n--)
	        bytes.push(Math.floor(Math.random() * 256));
	      return bytes;
	    },
	
	    // Convert a byte array to big-endian 32-bit words
	    bytesToWords: function(bytes) {
	      for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
	        words[b >>> 5] |= bytes[i] << (24 - b % 32);
	      return words;
	    },
	
	    // Convert big-endian 32-bit words to a byte array
	    wordsToBytes: function(words) {
	      for (var bytes = [], b = 0; b < words.length * 32; b += 8)
	        bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
	      return bytes;
	    },
	
	    // Convert a byte array to a hex string
	    bytesToHex: function(bytes) {
	      for (var hex = [], i = 0; i < bytes.length; i++) {
	        hex.push((bytes[i] >>> 4).toString(16));
	        hex.push((bytes[i] & 0xF).toString(16));
	      }
	      return hex.join('');
	    },
	
	    // Convert a hex string to a byte array
	    hexToBytes: function(hex) {
	      for (var bytes = [], c = 0; c < hex.length; c += 2)
	        bytes.push(parseInt(hex.substr(c, 2), 16));
	      return bytes;
	    },
	
	    // Convert a byte array to a base-64 string
	    bytesToBase64: function(bytes) {
	      for (var base64 = [], i = 0; i < bytes.length; i += 3) {
	        var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
	        for (var j = 0; j < 4; j++)
	          if (i * 8 + j * 6 <= bytes.length * 8)
	            base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
	          else
	            base64.push('=');
	      }
	      return base64.join('');
	    },
	
	    // Convert a base-64 string to a byte array
	    base64ToBytes: function(base64) {
	      // Remove non-base-64 characters
	      base64 = base64.replace(/[^A-Z0-9+\/]/ig, '');
	
	      for (var bytes = [], i = 0, imod4 = 0; i < base64.length;
	          imod4 = ++i % 4) {
	        if (imod4 == 0) continue;
	        bytes.push(((base64map.indexOf(base64.charAt(i - 1))
	            & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2))
	            | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
	      }
	      return bytes;
	    }
	  };
	
	  module.exports = crypt;
	})();


/***/ },
/* 268 */
/***/ function(module, exports) {

	var charenc = {
	  // UTF-8 encoding
	  utf8: {
	    // Convert a string to a byte array
	    stringToBytes: function(str) {
	      return charenc.bin.stringToBytes(unescape(encodeURIComponent(str)));
	    },
	
	    // Convert a byte array to a string
	    bytesToString: function(bytes) {
	      return decodeURIComponent(escape(charenc.bin.bytesToString(bytes)));
	    }
	  },
	
	  // Binary encoding
	  bin: {
	    // Convert a string to a byte array
	    stringToBytes: function(str) {
	      for (var bytes = [], i = 0; i < str.length; i++)
	        bytes.push(str.charCodeAt(i) & 0xFF);
	      return bytes;
	    },
	
	    // Convert a byte array to a string
	    bytesToString: function(bytes) {
	      for (var str = [], i = 0; i < bytes.length; i++)
	        str.push(String.fromCharCode(bytes[i]));
	      return str.join('');
	    }
	  }
	};
	
	module.exports = charenc;


/***/ },
/* 269 */
/***/ function(module, exports) {

	/*!
	 * Determine if an object is a Buffer
	 *
	 * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
	 * @license  MIT
	 */
	
	// The _isBuffer check is for Safari 5-7 support, because it's missing
	// Object.prototype.constructor. Remove this eventually
	module.exports = function (obj) {
	  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
	}
	
	function isBuffer (obj) {
	  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
	}
	
	// For Node v0.10 support. Remove this eventually.
	function isSlowBuffer (obj) {
	  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
	}


/***/ },
/* 270 */
/***/ function(module, exports, __webpack_require__) {

	var { PrefsHelper } = __webpack_require__(28);
	const { Services: { pref }} = __webpack_require__(30);
	const { isDevelopment } = __webpack_require__(89);
	
	if (isDevelopment()) {
	  pref("devtools.debugger.client-source-maps-enabled", true);
	}
	
	const prefs = new PrefsHelper("devtools", {
	  clientSourceMapsEnabled: ["Bool", "debugger.client-source-maps-enabled"],
	});
	
	module.exports = { prefs };


/***/ },
/* 271 */
/***/ 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/. */
	/* global window gThreadClient setNamedTimeout services EVENTS */
	/* eslint no-shadow: 0  */
	
	/**
	 * Redux actions for the event listeners state
	 * @module actions/event-listeners
	 */
	
	var constants = __webpack_require__(251);
	
	var _require = __webpack_require__(244);
	
	var asPaused = _require.asPaused;
	
	var _require2 = __webpack_require__(246);
	
	var reportException = _require2.reportException;
	
	var _require3 = __webpack_require__(272);
	
	var Task = _require3.Task;
	
	// delay is in ms
	
	var FETCH_EVENT_LISTENERS_DELAY = 200;
	
	/**
	 * @memberof actions/event-listeners
	 * @static
	 */
	function fetchEventListeners() {
	  return (dispatch, getState) => {
	    // Make sure we"re not sending a batch of closely repeated requests.
	    // This can easily happen whenever new sources are fetched.
	    setNamedTimeout("event-listeners-fetch", FETCH_EVENT_LISTENERS_DELAY, () => {
	      // In case there is still a request of listeners going on (it
	      // takes several RDP round trips right now), make sure we wait
	      // on a currently running request
	      if (getState().eventListeners.fetchingListeners) {
	        dispatch({
	          type: services.WAIT_UNTIL,
	          predicate: action => action.type === constants.FETCH_EVENT_LISTENERS && action.status === "done",
	          run: dispatch => dispatch(fetchEventListeners())
	        });
	        return;
	      }
	
	      dispatch({
	        type: constants.FETCH_EVENT_LISTENERS,
	        status: "begin"
	      });
	
	      asPaused(gThreadClient, _getListeners).then(listeners => {
	        // Notify that event listeners were fetched and shown in the view,
	        // and callback to resume the active thread if necessary.
	        window.emit(EVENTS.EVENT_LISTENERS_FETCHED);
	
	        dispatch({
	          type: constants.FETCH_EVENT_LISTENERS,
	          status: "done",
	          listeners: listeners
	        });
	      });
	    });
	  };
	}
	
	var _getListeners = Task.async(function* () {
	  var response = yield gThreadClient.eventListeners();
	
	  // Make sure all the listeners are sorted by the event type, since
	  // they"re not guaranteed to be clustered together.
	  response.listeners.sort((a, b) => a.type > b.type ? 1 : -1);
	
	  // Add all the listeners in the debugger view event linsteners container.
	  var fetchedDefinitions = new Map();
	  var listeners = [];
	  for (var listener of response.listeners) {
	    var definitionSite = void 0;
	    if (fetchedDefinitions.has(listener.function.actor)) {
	      definitionSite = fetchedDefinitions.get(listener.function.actor);
	    } else if (listener.function.class == "Function") {
	      definitionSite = yield _getDefinitionSite(listener.function);
	      if (!definitionSite) {
	        // We don"t know where this listener comes from so don"t show it in
	        // the UI as breaking on it doesn"t work (bug 942899).
	        continue;
	      }
	
	      fetchedDefinitions.set(listener.function.actor, definitionSite);
	    }
	    listener.function.url = definitionSite;
	    listeners.push(listener);
	  }
	  fetchedDefinitions.clear();
	
	  return listeners;
	});
	
	var _getDefinitionSite = Task.async(function* (func) {
	  var grip = gThreadClient.pauseGrip(func);
	  var response = void 0;
	
	  try {
	    response = yield grip.getDefinitionSite();
	  } catch (e) {
	    // Don't make this error fatal, it would break the entire events pane.
	    reportException("_getDefinitionSite", e);
	    return null;
	  }
	
	  return response.source.url;
	});
	
	/**
	 * @memberof actions/event-listeners
	 * @static
	 * @param {string} eventNames
	 */
	function updateEventBreakpoints(eventNames) {
	  return dispatch => {
	    setNamedTimeout("event-breakpoints-update", 0, () => {
	      gThreadClient.pauseOnDOMEvents(eventNames, function () {
	        // Notify that event breakpoints were added/removed on the server.
	        window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED);
	
	        dispatch({
	          type: constants.UPDATE_EVENT_BREAKPOINTS,
	          eventNames: eventNames
	        });
	      });
	    });
	  };
	}
	
	module.exports = { updateEventBreakpoints, fetchEventListeners };

/***/ },
/* 272 */
/***/ function(module, exports) {

	/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
	/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
	 * You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	/**
	 * This object provides the public module functions.
	 */
	var Task = {
	  // XXX: Not sure if this works in all cases...
	  async: function (task) {
	    return function () {
	      return Task.spawn(task, this, arguments);
	    };
	  },
	
	  /**
	   * Creates and starts a new task.
	   * @param task A generator function
	   * @return A promise, resolved when the task terminates
	   */
	  spawn: function (task, scope, args) {
	    return new Promise(function (resolve, reject) {
	      var iterator = task.apply(scope, args);
	
	      var callNext = lastValue => {
	        var iteration = iterator.next(lastValue);
	        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 };

/***/ },
/* 273 */
/***/ function(module, exports, __webpack_require__) {

	var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
	
	function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
	
	/* This Source Code Form is subject to the terms of the Mozilla Public
	 * License, v. 2.0. If a copy of the MPL was not distributed with this
	 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
	
	/**
	 * Redux actions for the sources state
	 * @module actions/sources
	 */
	
	var defer = __webpack_require__(243);
	
	var _require = __webpack_require__(242);
	
	var PROMISE = _require.PROMISE;
	
	var assert = __webpack_require__(247);
	
	var _require2 = __webpack_require__(274);
	
	var updateFrameLocations = _require2.updateFrameLocations;
	
	var _require3 = __webpack_require__(264);
	
	var getOriginalURLs = _require3.getOriginalURLs;
	var getOriginalSourceText = _require3.getOriginalSourceText;
	var generatedToOriginalId = _require3.generatedToOriginalId;
	var isOriginalId = _require3.isOriginalId;
	var isGeneratedId = _require3.isGeneratedId;
	var applySourceMap = _require3.applySourceMap;
	var shouldSourceMap = _require3.shouldSourceMap;
	
	var _require4 = __webpack_require__(276);
	
	var prettyPrint = _require4.prettyPrint;
	
	
	var constants = __webpack_require__(251);
	
	var _require5 = __webpack_require__(89);
	
	var isEnabled = _require5.isEnabled;
	
	var _require6 = __webpack_require__(279);
	
	var removeDocument = _require6.removeDocument;
	
	var _require7 = __webpack_require__(259);
	
	var getSource = _require7.getSource;
	var getSourceByURL = _require7.getSourceByURL;
	var getSourceText = _require7.getSourceText;
	var getPendingSelectedLocation = _require7.getPendingSelectedLocation;
	var getFrames = _require7.getFrames;
	
	
	/**
	 * Handler for the debugger client's unsolicited newSource notification.
	 * @memberof actions/sources
	 * @static
	 */
	function newSource(source) {
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var getState = _ref.getState;
	
	    if (shouldSourceMap()) {
	      dispatch(loadSourceMap(source));
	    }
	
	    dispatch({
	      type: constants.ADD_SOURCE,
	      source
	    });
	
	    // If a request has been made to show this source, go ahead and
	    // select it.
	    var pendingLocation = getPendingSelectedLocation(getState());
	    if (pendingLocation && pendingLocation.url === source.url) {
	      dispatch(selectSource(source.id, { line: pendingLocation.line }));
	    }
	  };
	}
	
	function newSources(sources) {
	  return (_ref2) => {
	    var dispatch = _ref2.dispatch;
	    var getState = _ref2.getState;
	
	    sources.filter(source => !getSource(getState(), source.id)).forEach(source => dispatch(newSource(source)));
	  };
	}
	
	/**
	 * @memberof actions/sources
	 * @static
	 */
	function loadSourceMap(generatedSource) {
	  return (() => {
	    var _ref3 = _asyncToGenerator(function* (_ref4) {
	      var dispatch = _ref4.dispatch;
	      var getState = _ref4.getState;
	
	      var urls = yield getOriginalURLs(generatedSource);
	      if (!urls) {
	        // If this source doesn't have a sourcemap, do nothing.
	        return;
	      }
	
	      var originalSources = urls.map(function (originalUrl) {
	        return {
	          url: originalUrl,
	          id: generatedToOriginalId(generatedSource.id, originalUrl),
	          isPrettyPrinted: false
	        };
	      });
	
	      originalSources.forEach(function (s) {
	        return dispatch(newSource(s));
	      });
	    });
	
	    return function (_x) {
	      return _ref3.apply(this, arguments);
	    };
	  })();
	}
	
	/**
	 * Deterministically select a source that has a given URL. This will
	 * work regardless of the connection status or if the source exists
	 * yet. This exists mostly for external things to interact with the
	 * debugger.
	 *
	 * @memberof actions/sources
	 * @static
	 */
	function selectSourceURL(url) {
	  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	
	  return (_ref5) => {
	    var dispatch = _ref5.dispatch;
	    var getState = _ref5.getState;
	
	    var source = getSourceByURL(getState(), url);
	    if (source) {
	      dispatch(selectSource(source.get("id"), options));
	    } else {
	      dispatch({
	        type: constants.SELECT_SOURCE_URL,
	        url: url,
	        tabIndex: options.tabIndex,
	        line: options.line
	      });
	    }
	  };
	}
	
	/**
	 * @memberof actions/sources
	 * @static
	 */
	function selectSource(id) {
	  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
	
	  return (_ref6) => {
	    var dispatch = _ref6.dispatch;
	    var getState = _ref6.getState;
	    var client = _ref6.client;
	
	    if (!client) {
	      // No connection, do nothing. This happens when the debugger is
	      // shut down too fast and it tries to display a default source.
	      return;
	    }
	
	    var source = getSource(getState(), id).toJS();
	
	    // Make sure to start a request to load the source text.
	    dispatch(loadSourceText(source));
	
	    dispatch({ type: constants.TOGGLE_FILE_SEARCH, searchOn: false });
	
	    dispatch({
	      type: constants.SELECT_SOURCE,
	      source: source,
	      tabIndex: options.tabIndex,
	      line: options.line
	    });
	  };
	}
	
	/**
	 * @memberof actions/sources
	 * @static
	 */
	function closeTab(id) {
	  removeDocument(id);
	  return {
	    type: constants.CLOSE_TAB,
	    id: id
	  };
	}
	
	/**
	 * Toggle the pretty printing of a source's text. All subsequent calls to
	 * |getText| will return the pretty-toggled text. Nothing will happen for
	 * non-javascript files.
	 *
	 * @memberof actions/sources
	 * @static
	 * @param string id The source form from the RDP.
	 * @returns Promise
	 *          A promise that resolves to [aSource, prettyText] or rejects to
	 *          [aSource, error].
	 */
	function togglePrettyPrint(sourceId) {
	  return (_ref7) => {
	    var dispatch = _ref7.dispatch;
	    var getState = _ref7.getState;
	    var client = _ref7.client;
	
	    var source = getSource(getState(), sourceId).toJS();
	    var sourceText = getSourceText(getState(), sourceId).toJS();
	
	    if (!isEnabled("prettyPrint") || sourceText.loading) {
	      return {};
	    }
	
	    assert(isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
	
	    var url = source.url + ":formatted";
	    var id = generatedToOriginalId(source.id, url);
	    var originalSource = { url, id, isPrettyPrinted: false };
	    dispatch({
	      type: constants.ADD_SOURCE,
	      source: originalSource
	    });
	
	    return dispatch({
	      type: constants.TOGGLE_PRETTY_PRINT,
	      source: originalSource,
	      [PROMISE]: _asyncToGenerator(function* () {
	        var _ref9 = yield prettyPrint({
	          source, sourceText, url
	        });
	
	        var code = _ref9.code;
	        var mappings = _ref9.mappings;
	
	        yield applySourceMap(source.id, url, code, mappings);
	
	        var frames = yield updateFrameLocations(getFrames(getState()));
	        dispatch(selectSource(originalSource.id));
	
	        return {
	          text: code,
	          contentType: "text/javascript",
	          frames
	        };
	      })()
	    });
	  };
	}
	
	/**
	 * @memberof actions/sources
	 * @static
	 */
	function loadSourceText(source) {
	  return (_ref10) => {
	    var dispatch = _ref10.dispatch;
	    var getState = _ref10.getState;
	    var client = _ref10.client;
	
	    // Fetch the source text only once.
	    var textInfo = getSourceText(getState(), source.id);
	    if (textInfo) {
	      // It's already loaded or is loading
	      return Promise.resolve(textInfo);
	    }
	
	    return dispatch({
	      type: constants.LOAD_SOURCE_TEXT,
	      source: source,
	      [PROMISE]: _asyncToGenerator(function* () {
	        if (isOriginalId(source.id)) {
	          return yield getOriginalSourceText(source);
	        }
	
	        var response = yield client.sourceContents(source.id);
	        return {
	          text: response.source,
	          contentType: response.contentType || "text/javascript"
	        };
	
	        // Automatically pretty print if enabled and the test is
	        // detected to be "minified"
	        // if (Prefs.autoPrettyPrint &&
	        //     !source.isPrettyPrinted &&
	        //     SourceUtils.isMinified(source.id, response.source)) {
	        //   dispatch(togglePrettyPrint(source));
	        // }
	      })()
	    });
	  };
	}
	
	// delay is in ms
	var FETCH_SOURCE_RESPONSE_DELAY = 200;
	
	/**
	 * Starts fetching all the sources, silently.
	 *
	 * @memberof actions/sources
	 * @static
	 * @param array actors
	 *        The urls for the sources to fetch. If fetching a source's text
	 *        takes too long, it will be discarded.
	 * @returns {Promise}
	 *         A promise that is resolved after source texts have been fetched.
	 */
	function getTextForSources(actors) {
	  return (_ref12) => {
	    var dispatch = _ref12.dispatch;
	    var getState = _ref12.getState;
	
	    var deferred = defer();
	    var pending = new Set(actors);
	
	    var fetched = [];
	
	    // Can't use promise.all, because if one fetch operation is rejected, then
	    // everything is considered rejected, thus no other subsequent source will
	    // be getting fetched. We don't want that. Something like Q's allSettled
	    // would work like a charm here.
	
	    // Try to fetch as many sources as possible.
	
	    var _loop = function (actor) {
	      var source = getSource(getState(), actor);
	      dispatch(loadSourceText(source)).then((_ref21) => {
	        var text = _ref21.text;
	        var contentType = _ref21.contentType;
	
	        onFetch([source, text, contentType]);
	      }, err => {
	        onError(source, err);
	      });
	    };
	
	    for (var actor of actors) {
	      _loop(actor);
	    }
	
	    setTimeout(onTimeout, FETCH_SOURCE_RESPONSE_DELAY);
	
	    /* Called if fetching a source takes too long. */
	    function onTimeout() {
	      pending = new Set();
	      maybeFinish();
	    }
	
	    /* Called if fetching a source finishes successfully. */
	    function onFetch(_ref13) {
	      var _ref14 = _slicedToArray(_ref13, 3);
	
	      var aSource = _ref14[0];
	      var aText = _ref14[1];
	      var aContentType = _ref14[2];
	
	      // If fetching the source has previously timed out, discard it this time.
	      if (!pending.has(aSource.actor)) {
	        return;
	      }
	      pending.delete(aSource.actor);
	      fetched.push([aSource.actor, aText, aContentType]);
	      maybeFinish();
	    }
	
	    /* Called if fetching a source failed because of an error. */
	    function onError(_ref15) {
	      var _ref16 = _slicedToArray(_ref15, 2);
	
	      var aSource = _ref16[0];
	      var aError = _ref16[1];
	
	      pending.delete(aSource.actor);
	      maybeFinish();
	    }
	
	    /* Called every time something interesting
	     *  happens while fetching sources.
	     */
	    function maybeFinish() {
	      if (pending.size == 0) {
	        // Sort the fetched sources alphabetically by their url.
	        if (deferred) {
	          deferred.resolve(fetched.sort((_ref17, _ref18) => {
	            var _ref20 = _slicedToArray(_ref17, 1);
	
	            var aFirst = _ref20[0];
	
	            var _ref19 = _slicedToArray(_ref18, 1);
	
	            var aSecond = _ref19[0];
	            return aFirst > aSecond ? -1 : 1;
	          }));
	        }
	      }
	    }
	
	    return deferred.promise;
	  };
	}
	
	module.exports = {
	  newSource,
	  newSources,
	  selectSource,
	  selectSourceURL,
	  closeTab,
	  togglePrettyPrint,
	  loadSourceText,
	  getTextForSources
	};

/***/ },
/* 274 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(275);
	
	var Frame = _require.Frame;
	
	var _require2 = __webpack_require__(264);
	
	var getOriginalLocation = _require2.getOriginalLocation;
	
	
	function updateFrameLocations(frames) {
	  if (!frames) {
	    return Promise.resolve(frames);
	  }
	  return Promise.all(frames.map(frame => {
	    return getOriginalLocation(frame.location).then(loc => {
	      return Frame.update(frame, {
	        $merge: { location: loc }
	      });
	    });
	  }));
	}
	
	module.exports = {
	  updateFrameLocations
	};

/***/ },
/* 275 */
/***/ function(module, exports, __webpack_require__) {

	var t = __webpack_require__(146);
	
	var Location = t.struct({
	  sourceId: t.String,
	  line: t.Number,
	  column: t.union([t.Number, t.Nil])
	}, "Location");
	
	var 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])
	}, "Frame");
	
	module.exports = {
	  Frame
	};

/***/ },
/* 276 */
/***/ function(module, exports, __webpack_require__) {

	var prettyPrint = (() => {
	  var _ref = _asyncToGenerator(function* (_ref2) {
	    var source = _ref2.source;
	    var sourceText = _ref2.sourceText;
	    var url = _ref2.url;
	
	    var contentType = sourceText ? sourceText.contentType : null;
	    var indent = 2;
	
	    assert(isJavaScript(source.url, contentType), "Can't prettify non-javascript files.");
	
	    return yield _prettyPrint({
	      url,
	      indent,
	      source: sourceText.text
	    });
	  });
	
	  return function prettyPrint(_x) {
	    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"); }); }; }
	
	var _require = __webpack_require__(89);
	
	var getValue = _require.getValue;
	
	var _require2 = __webpack_require__(244);
	
	var workerTask = _require2.workerTask;
	
	var _require3 = __webpack_require__(277);
	
	var isJavaScript = _require3.isJavaScript;
	
	var assert = __webpack_require__(247);
	
	var prettyPrintWorker = new Worker(getValue("baseWorkerURL") + "pretty-print-worker.js");
	
	function destroyWorker() {
	  prettyPrintWorker.terminate();
	  prettyPrintWorker = null;
	}
	
	var _prettyPrint = workerTask(prettyPrintWorker, "prettyPrint");
	
	module.exports = {
	  prettyPrint,
	  destroyWorker
	};

/***/ },
/* 277 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * Utils for working with Source URLs
	 * @module utils/source
	 */
	
	var _require = __webpack_require__(244);
	
	var endTruncateStr = _require.endTruncateStr;
	
	var _require2 = __webpack_require__(278);
	
	var basename = _require2.basename;
	
	
	/**
	 * Trims the query part or reference identifier of a url string, if necessary.
	 *
	 * @memberof utils/source
	 * @static
	 */
	function trimUrlQuery(url) {
	  var length = url.length;
	  var q1 = url.indexOf("?");
	  var q2 = url.indexOf("&");
	  var q3 = url.indexOf("#");
	  var q = Math.min(q1 != -1 ? q1 : length, q2 != -1 ? q2 : length, q3 != -1 ? q3 : length);
	
	  return url.slice(0, q);
	}
	
	/**
	 * Returns true if the specified url and/or content type are specific to
	 * javascript files.
	 *
	 * @return boolean
	 *         True if the source is likely javascript.
	 *
	 * @memberof utils/source
	 * @static
	 */
	function isJavaScript(url) {
	  var contentType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
	
	  return url && /\.(jsm|js)?$/.test(trimUrlQuery(url)) || contentType.includes("javascript");
	}
	
	/**
	 * @memberof utils/source
	 * @static
	 */
	function isPretty(source) {
	  return source.url ? /formatted$/.test(source.url) : false;
	}
	
	/**
	 * Show a source url's filename.
	 * If the source does not have a url, use the source id.
	 *
	 * @memberof utils/source
	 * @static
	 */
	function getFilename(source) {
	  var url = source.url;
	  var id = source.id;
	
	  if (!url) {
	    var sourceId = id.split("/")[1];
	    return `SOURCE${ sourceId }`;
	  }
	
	  var name = basename(source.url || "") || "(index)";
	  return endTruncateStr(name, 50);
	}
	
	module.exports = {
	  isJavaScript,
	  isPretty,
	  getFilename
	};

/***/ },
/* 278 */
/***/ function(module, exports) {

	function basename(path) {
	  return path.split("/").pop();
	}
	
	function dirname(path) {
	  var idx = path.lastIndexOf("/");
	  return path.slice(0, idx);
	}
	
	function isURL(str) {
	  return str.indexOf("://") !== -1;
	}
	
	function isAbsolute(str) {
	  return str[0] === "/";
	}
	
	function join(base, dir) {
	  return base + "/" + dir;
	}
	
	module.exports = {
	  basename, dirname, isURL, isAbsolute, join
	};

/***/ },
/* 279 */
/***/ function(module, exports) {

	var sourceDocs = {};
	
	function getDocument(key) {
	  return sourceDocs[key];
	}
	
	function setDocument(key, doc) {
	  sourceDocs[key] = doc;
	}
	
	function removeDocument(key) {
	  delete sourceDocs[key];
	}
	
	function clearDocuments() {
	  sourceDocs = {};
	}
	
	module.exports = {
	  getDocument,
	  setDocument,
	  removeDocument,
	  clearDocuments
	};

/***/ },
/* 280 */
/***/ function(module, exports, __webpack_require__) {

	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"); }); }; }
	
	var constants = __webpack_require__(251);
	
	var _require = __webpack_require__(273);
	
	var selectSource = _require.selectSource;
	
	var _require2 = __webpack_require__(242);
	
	var PROMISE = _require2.PROMISE;
	
	var _require3 = __webpack_require__(259);
	
	var getExpressions = _require3.getExpressions;
	var getSelectedFrame = _require3.getSelectedFrame;
	
	var _require4 = __webpack_require__(274);
	
	var updateFrameLocations = _require4.updateFrameLocations;
	
	/**
	 * Redux actions for the pause state
	 * @module actions/pause
	 */
	
	/**
	 * Debugger has just resumed
	 *
	 * @memberof actions/pause
	 * @static
	 */
	
	function resumed() {
	  return (_ref) => {
	    var dispatch = _ref.dispatch;
	    var client = _ref.client;
	
	    return dispatch({
	      type: constants.RESUME,
	      value: undefined
	    });
	  };
	}
	
	/**
	 * Debugger has just paused
	 *
	 * @param {object} pauseInfo
	 * @memberof actions/pause
	 * @static
	 */
	function paused(pauseInfo) {
	  return (() => {
	    var _ref2 = _asyncToGenerator(function* (_ref3) {
	      var dispatch = _ref3.dispatch;
	      var getState = _ref3.getState;
	      var client = _ref3.client;
	      var frames = pauseInfo.frames;
	      var why = pauseInfo.why;
	
	      frames = yield updateFrameLocations(frames);
	      var frame = frames[0];
	
	      dispatch({
	        type: constants.PAUSED,
	        pauseInfo: { why, frame },
	        frames: frames,
	        selectedFrameId: frame.id
	      });
	
	      dispatch(evaluateExpressions());
	
	      dispatch(selectSource(frame.location.sourceId, { line: frame.location.line }));
	    });
	
	    return function (_x) {
	      return _ref2.apply(this, arguments);
	    };
	  })();
	}
	
	/**
	 *
	 * @memberof actions/pause
	 * @static
	 */
	function pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions) {
	  return (_ref4) => {
	    var dispatch = _ref4.dispatch;
	    var client = _ref4.client;
	
	    dispatch({
	      type: constants.PAUSE_ON_EXCEPTIONS,
	      shouldPauseOnExceptions,
	      shouldIgnoreCaughtExceptions,
	      [PROMISE]: client.pauseOnExceptions(shouldPauseOnExceptions, shouldIgnoreCaughtExceptions)
	    });
	  };
	}
	
	/**
	 * Debugger commands like stepOver, stepIn, stepUp
	 *
	 * @param string $0.type
	 * @memberof actions/pause
	 * @static
	 */
	function command(_ref5) {
	  var type = _ref5.type;
	
	  return (_ref6) => {
	    var dispatch = _ref6.dispatch;
	    var client = _ref6.client;
	
	    // execute debugger thread command e.g. stepIn, stepOver
	    client[type]();
	
	    return dispatch({
	      type: constants.COMMAND,
	      value: undefined
	    });
	  };
	}
	
	/**
	 * StepIn
	 * @memberof actions/pause
	 * @static
	 * @returns {Function} {@link command}
	 */
	function stepIn() {
	  return command({ type: "stepIn" });
	}
	
	/**
	 * stepOver
	 * @memberof actions/pause
	 * @static
	 * @returns {Function} {@link command}
	 */
	function stepOver() {
	  return command({ type: "stepOver" });
	}
	
	/**
	 * stepOut
	 * @memberof actions/pause
	 * @static
	 * @returns {Function} {@link command}
	 */
	function stepOut() {
	  return command({ type: "stepOut" });
	}
	
	/**
	 * resume
	 * @memberof actions/pause
	 * @static
	 * @returns {Function} {@link command}
	 */
	function resume() {
	  return command({ type: "resume" });
	}
	
	/**
	 * Debugger breakOnNext command.
	 * It's different from the comand action because we also want to
	 * highlight the pause icon.
	 *
	 * @memberof actions/pause
	 * @static
	 */
	function breakOnNext() {
	  return (_ref7) => {
	    var dispatch = _ref7.dispatch;
	    var client = _ref7.client;
	
	    client.breakOnNext();
	
	    return dispatch({
	      type: constants.BREAK_ON_NEXT,
	      value: true
	    });
	  };
	}
	
	/**
	 * Select a frame
	 *
	 * @param frame
	 * @memberof actions/pause
	 * @static
	 */
	function selectFrame(frame) {
	  return (_ref8) => {
	    var dispatch = _ref8.dispatch;
	
	    dispatch(selectSource(frame.location.sourceId, { line: frame.location.line }));
	    dispatch({
	      type: constants.SELECT_FRAME,
	      frame
	    });
	  };
	}
	
	/**
	 * Load an object.
	 *
	 * @param grip
	 * TODO: Right now this if Firefox specific and is not implemented
	 * for Chrome, which is why it takes a grip.
	 * @memberof actions/pause
	 * @static
	 */
	function loadObjectProperties(grip) {
	  return (_ref9) => {
	    var dispatch = _ref9.dispatch;
	    var client = _ref9.client;
	
	    dispatch({
	      type: constants.LOAD_OBJECT_PROPERTIES,
	      objectId: grip.actor,
	      [PROMISE]: client.getProperties(grip)
	    });
	  };
	}
	
	/**
	 * Add expression for debugger to watch
	 *
	 * @param {object} expression
	 * @param {number} expression.id
	 * @memberof actions/pause
	 * @static
	 */
	function addExpression(expression) {
	  return (_ref10) => {
	    var dispatch = _ref10.dispatch;
	    var getState = _ref10.getState;
	
	    var id = expression.id !== undefined ? parseInt(expression.id, 10) : getExpressions(getState()).toSeq().size++;
	    dispatch({
	      type: constants.ADD_EXPRESSION,
	      id: id,
	      input: expression.input
	    });
	    dispatch(evaluateExpressions());
	  };
	}
	
	/**
	 *
	 * @param {object} expression
	 * @param {number} expression.id
	 * @memberof actions/pause
	 * @static
	 */
	function updateExpression(expression) {
	  return (_ref11) => {
	    var dispatch = _ref11.dispatch;
	
	    dispatch({
	      type: constants.UPDATE_EXPRESSION,
	      id: expression.id,
	      input: expression.input
	    });
	  };
	}
	
	/**
	 *
	 * @param {object} expression
	 * @param {number} expression.id
	 * @memberof actions/pause
	 * @static
	 */
	function deleteExpression(expression) {
	  return (_ref12) => {
	    var dispatch = _ref12.dispatch;
	
	    dispatch({
	      type: constants.DELETE_EXPRESSION,
	      id: expression.id
	    });
	  };
	}
	
	/**
	 *
	 * @memberof actions/pause
	 * @static
	 */
	function evaluateExpressions() {
	  return (() => {
	    var _ref13 = _asyncToGenerator(function* (_ref14) {
	      var dispatch = _ref14.dispatch;
	      var getState = _ref14.getState;
	      var client = _ref14.client;
	
	      var selectedFrame = getSelectedFrame(getState());
	      if (!selectedFrame) {
	        return;
	      }
	
	      var frameId = selectedFrame.id;
	
	      for (var expression of getExpressions(getState())) {
	        yield dispatch({
	          type: constants.EVALUATE_EXPRESSION,
	          id: expression.id,
	          input: expression.input,
	          [PROMISE]: client.evaluate(expression.input, { frameId })
	        });
	      }
	    });
	
	    return function (_x2) {
	      return _ref13.apply(this, arguments);
	    };
	  })();
	}
	
	module.exports = {
	  addExpression,
	  updateExpression,
	  deleteExpression,
	  evaluateExpressions,
	  resumed,
	  paused,
	  pauseOnExceptions,
	  command,
	  stepIn,
	  stepOut,
	  stepOver,
	  resume,
	  breakOnNext,
	  selectFrame,
	  loadObjectProperties
	};

/***/ },
/* 281 */
/***/ function(module, exports, __webpack_require__) {

	var constants = __webpack_require__(251);
	
	var _require = __webpack_require__(264);
	
	var clearSourceMaps = _require.clearSourceMaps;
	
	var _require2 = __webpack_require__(279);
	
	var clearDocuments = _require2.clearDocuments;
	
	/**
	 * Redux actions for the navigation state
	 * @module actions/navigation
	 */
	
	/**
	 * @memberof actions/navigation
	 * @static
	 */
	
	function willNavigate() {
	  clearSourceMaps();
	  clearDocuments();
	
	  return { type: constants.NAVIGATE };
	}
	
	/**
	 * @memberof actions/navigation
	 * @static
	 */
	function navigated() {
	  return (_ref) => {
	    // We need to load all the sources again because they might have
	    // come from bfcache, so we won't get a `newSource` notification.
	    //
	    // TODO: This seems to be buggy on the debugger server side. When
	    // the page is loaded from bfcache, we still get sources from the
	    // *previous* page as well. For now, emulate the current debugger
	    // behavior by not showing sources loaded by bfcache.
	    // return dispatch(sources.loadSources());
	
	    var dispatch = _ref.dispatch;
	  };
	}
	
	module.exports = {
	  willNavigate,
	  navigated
	};

/***/ },
/* 282 */
/***/ function(module, exports, __webpack_require__) {

	var constants = __webpack_require__(251);
	
	function toggleFileSearch(searchOn) {
	  return {
	    type: constants.TOGGLE_FILE_SEARCH,
	    searchOn
	  };
	}
	
	module.exports = {
	  toggleFileSearch
	};

/***/ },
/* 283 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 284 */,
/* 285 */,
/* 286 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 287 */,
/* 288 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 289 */,
/* 290 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 291 */,
/* 292 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	var createFactory = React.createFactory;
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(259);
	
	var getSources = _require3.getSources;
	var getSelectedSource = _require3.getSelectedSource;
	var getFileSearchState = _require3.getFileSearchState;
	
	var _require4 = __webpack_require__(244);
	
	var endTruncateStr = _require4.endTruncateStr;
	
	var _require5 = __webpack_require__(293);
	
	var parseURL = _require5.parse;
	
	var _require6 = __webpack_require__(277);
	
	var isPretty = _require6.isPretty;
	
	
	__webpack_require__(298);
	
	var Autocomplete = createFactory(__webpack_require__(300));
	
	function searchResults(sources) {
	  function getSourcePath(source) {
	    var _parseURL = parseURL(source.get("url"));
	
	    var path = _parseURL.path;
	    var href = _parseURL.href;
	    // for URLs like "about:home" the path is null so we pass the full href
	
	    return endTruncateStr(path || href, 50);
	  }
	
	  return sources.valueSeq().filter(source => !isPretty(source.toJS()) && source.get("url")).map(source => ({
	    value: getSourcePath(source),
	    title: getSourcePath(source).split("/").pop(),
	    subtitle: getSourcePath(source),
	    id: source.get("id")
	  })).toJS();
	}
	
	var Search = React.createClass({
	  propTypes: {
	    sources: PropTypes.object,
	    selectSource: PropTypes.func,
	    selectedSource: PropTypes.object,
	    toggleFileSearch: PropTypes.func,
	    searchOn: PropTypes.bool
	  },
	
	  contextTypes: {
	    shortcuts: PropTypes.object
	  },
	
	  displayName: "Search",
	
	  getInitialState() {
	    return {
	      inputValue: ""
	    };
	  },
	
	  componentWillUnmount() {
	    var shortcuts = this.context.shortcuts;
	    shortcuts.off("CmdOrCtrl+P", this.toggle);
	    shortcuts.off("Escape", this.onEscape);
	  },
	
	  componentDidMount() {
	    var shortcuts = this.context.shortcuts;
	    shortcuts.on("CmdOrCtrl+P", this.toggle);
	    shortcuts.on("Escape", this.onEscape);
	  },
	
	  toggle(key, e) {
	    e.preventDefault();
	    this.props.toggleFileSearch(!this.props.searchOn);
	  },
	
	  onEscape(shortcut, e) {
	    if (this.props.searchOn) {
	      e.preventDefault();
	      this.setState({ inputValue: "" });
	      this.props.toggleFileSearch(false);
	    }
	  },
	
	  close() {
	    var inputValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
	
	    this.setState({ inputValue });
	    this.props.toggleFileSearch(false);
	  },
	
	  render() {
	    return this.props.searchOn ? dom.div({ className: "search-container" }, Autocomplete({
	      selectItem: result => {
	        this.props.selectSource(result.id);
	        this.setState({ inputValue: "" });
	        this.props.toggleFileSearch(false);
	      },
	      handleClose: this.close,
	      items: searchResults(this.props.sources),
	      inputValue: this.state.inputValue
	    })) : null;
	  }
	
	});
	
	module.exports = connect(state => ({
	  sources: getSources(state),
	  selectedSource: getSelectedSource(state),
	  searchOn: getFileSearchState(state)
	}), dispatch => bindActionCreators(actions, dispatch))(Search);

/***/ },
/* 293 */
/***/ function(module, exports, __webpack_require__) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	var punycode = __webpack_require__(294);
	
	exports.parse = urlParse;
	exports.resolve = urlResolve;
	exports.resolveObject = urlResolveObject;
	exports.format = urlFormat;
	
	exports.Url = Url;
	
	function Url() {
	  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;
	}
	
	// Reference: RFC 3986, RFC 1808, RFC 2396
	
	// define these here so at least they only have to be
	// compiled once on the first module load.
	var protocolPattern = /^([a-z0-9.+-]+:)/i,
	    portPattern = /:[0-9]*$/,
	
	    // RFC 2396: characters reserved for delimiting URLs.
	    // We actually just auto-escape these.
	    delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
	
	    // RFC 2396: characters not allowed for various reasons.
	    unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
	
	    // Allowed by RFCs, but cause of XSS attacks.  Always escape these.
	    autoEscape = ['\''].concat(unwise),
	    // Characters that are never ever allowed in a hostname.
	    // Note that any invalid chars are also handled, but these
	    // are the ones that are *expected* to be seen, so we fast-path
	    // them.
	    nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
	    hostEndingChars = ['/', '?', '#'],
	    hostnameMaxLen = 255,
	    hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/,
	    hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/,
	    // protocols that can allow "unsafe" and "unwise" chars.
	    unsafeProtocol = {
	      'javascript': true,
	      'javascript:': true
	    },
	    // protocols that never have a hostname.
	    hostlessProtocol = {
	      'javascript': true,
	      'javascript:': true
	    },
	    // protocols that always contain a // bit.
	    slashedProtocol = {
	      'http': true,
	      'https': true,
	      'ftp': true,
	      'gopher': true,
	      'file': true,
	      'http:': true,
	      'https:': true,
	      'ftp:': true,
	      'gopher:': true,
	      'file:': true
	    },
	    querystring = __webpack_require__(295);
	
	function urlParse(url, parseQueryString, slashesDenoteHost) {
	  if (url && isObject(url) && url instanceof Url) return url;
	
	  var u = new Url;
	  u.parse(url, parseQueryString, slashesDenoteHost);
	  return u;
	}
	
	Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
	  if (!isString(url)) {
	    throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
	  }
	
	  var rest = url;
	
	  // trim before proceeding.
	  // This is to support parse stuff like "  http://foo.com  \n"
	  rest = rest.trim();
	
	  var proto = protocolPattern.exec(rest);
	  if (proto) {
	    proto = proto[0];
	    var lowerProto = proto.toLowerCase();
	    this.protocol = lowerProto;
	    rest = rest.substr(proto.length);
	  }
	
	  // figure out if it's got a host
	  // user@server is *always* interpreted as a hostname, and url
	  // resolution will treat //foo/bar as host=foo,path=bar because that's
	  // how the browser resolves relative URLs.
	  if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
	    var slashes = rest.substr(0, 2) === '//';
	    if (slashes && !(proto && hostlessProtocol[proto])) {
	      rest = rest.substr(2);
	      this.slashes = true;
	    }
	  }
	
	  if (!hostlessProtocol[proto] &&
	      (slashes || (proto && !slashedProtocol[proto]))) {
	
	    // there's a hostname.
	    // the first instance of /, ?, ;, or # ends the host.
	    //
	    // If there is an @ in the hostname, then non-host chars *are* allowed
	    // to the left of the last @ sign, unless some host-ending character
	    // comes *before* the @-sign.
	    // URLs are obnoxious.
	    //
	    // ex:
	    // http://a@b@c/ => user:a@b host:c
	    // http://a@b?@c => user:a host:c path:/?@c
	
	    // v0.12 TODO(isaacs): This is not quite how Chrome does things.
	    // Review our test case against browsers more comprehensively.
	
	    // find the first instance of any hostEndingChars
	    var hostEnd = -1;
	    for (var i = 0; i < hostEndingChars.length; i++) {
	      var hec = rest.indexOf(hostEndingChars[i]);
	      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
	        hostEnd = hec;
	    }
	
	    // at this point, either we have an explicit point where the
	    // auth portion cannot go past, or the last @ char is the decider.
	    var auth, atSign;
	    if (hostEnd === -1) {
	      // atSign can be anywhere.
	      atSign = rest.lastIndexOf('@');
	    } else {
	      // atSign must be in auth portion.
	      // http://a@b/c@d => host:b auth:a path:/c@d
	      atSign = rest.lastIndexOf('@', hostEnd);
	    }
	
	    // Now we have a portion which is definitely the auth.
	    // Pull that off.
	    if (atSign !== -1) {
	      auth = rest.slice(0, atSign);
	      rest = rest.slice(atSign + 1);
	      this.auth = decodeURIComponent(auth);
	    }
	
	    // the host is the remaining to the left of the first non-host char
	    hostEnd = -1;
	    for (var i = 0; i < nonHostChars.length; i++) {
	      var hec = rest.indexOf(nonHostChars[i]);
	      if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
	        hostEnd = hec;
	    }
	    // if we still have not hit it, then the entire thing is a host.
	    if (hostEnd === -1)
	      hostEnd = rest.length;
	
	    this.host = rest.slice(0, hostEnd);
	    rest = rest.slice(hostEnd);
	
	    // pull out port.
	    this.parseHost();
	
	    // we've indicated that there is a hostname,
	    // so even if it's empty, it has to be present.
	    this.hostname = this.hostname || '';
	
	    // if hostname begins with [ and ends with ]
	    // assume that it's an IPv6 address.
	    var ipv6Hostname = this.hostname[0] === '[' &&
	        this.hostname[this.hostname.length - 1] === ']';
	
	    // validate a little.
	    if (!ipv6Hostname) {
	      var hostparts = this.hostname.split(/\./);
	      for (var i = 0, l = hostparts.length; i < l; i++) {
	        var part = hostparts[i];
	        if (!part) continue;
	        if (!part.match(hostnamePartPattern)) {
	          var newpart = '';
	          for (var j = 0, k = part.length; j < k; j++) {
	            if (part.charCodeAt(j) > 127) {
	              // we replace non-ASCII char with a temporary placeholder
	              // we need this to make sure size of hostname is not
	              // broken by replacing non-ASCII by nothing
	              newpart += 'x';
	            } else {
	              newpart += part[j];
	            }
	          }
	          // we test again with ASCII char only
	          if (!newpart.match(hostnamePartPattern)) {
	            var validParts = hostparts.slice(0, i);
	            var notHost = hostparts.slice(i + 1);
	            var bit = part.match(hostnamePartStart);
	            if (bit) {
	              validParts.push(bit[1]);
	              notHost.unshift(bit[2]);
	            }
	            if (notHost.length) {
	              rest = '/' + notHost.join('.') + rest;
	            }
	            this.hostname = validParts.join('.');
	            break;
	          }
	        }
	      }
	    }
	
	    if (this.hostname.length > hostnameMaxLen) {
	      this.hostname = '';
	    } else {
	      // hostnames are always lower case.
	      this.hostname = this.hostname.toLowerCase();
	    }
	
	    if (!ipv6Hostname) {
	      // IDNA Support: Returns a puny coded representation of "domain".
	      // It only converts the part of the domain name that
	      // has non ASCII characters. I.e. it dosent matter if
	      // you call it with a domain that already is in ASCII.
	      var domainArray = this.hostname.split('.');
	      var newOut = [];
	      for (var i = 0; i < domainArray.length; ++i) {
	        var s = domainArray[i];
	        newOut.push(s.match(/[^A-Za-z0-9_-]/) ?
	            'xn--' + punycode.encode(s) : s);
	      }
	      this.hostname = newOut.join('.');
	    }
	
	    var p = this.port ? ':' + this.port : '';
	    var h = this.hostname || '';
	    this.host = h + p;
	    this.href += this.host;
	
	    // strip [ and ] from the hostname
	    // the host field still retains them, though
	    if (ipv6Hostname) {
	      this.hostname = this.hostname.substr(1, this.hostname.length - 2);
	      if (rest[0] !== '/') {
	        rest = '/' + rest;
	      }
	    }
	  }
	
	  // now rest is set to the post-host stuff.
	  // chop off any delim chars.
	  if (!unsafeProtocol[lowerProto]) {
	
	    // First, make 100% sure that any "autoEscape" chars get
	    // escaped, even if encodeURIComponent doesn't think they
	    // need to be.
	    for (var i = 0, l = autoEscape.length; i < l; i++) {
	      var ae = autoEscape[i];
	      var esc = encodeURIComponent(ae);
	      if (esc === ae) {
	        esc = escape(ae);
	      }
	      rest = rest.split(ae).join(esc);
	    }
	  }
	
	
	  // chop off from the tail first.
	  var hash = rest.indexOf('#');
	  if (hash !== -1) {
	    // got a fragment string.
	    this.hash = rest.substr(hash);
	    rest = rest.slice(0, hash);
	  }
	  var qm = rest.indexOf('?');
	  if (qm !== -1) {
	    this.search = rest.substr(qm);
	    this.query = rest.substr(qm + 1);
	    if (parseQueryString) {
	      this.query = querystring.parse(this.query);
	    }
	    rest = rest.slice(0, qm);
	  } else if (parseQueryString) {
	    // no query string, but parseQueryString still requested
	    this.search = '';
	    this.query = {};
	  }
	  if (rest) this.pathname = rest;
	  if (slashedProtocol[lowerProto] &&
	      this.hostname && !this.pathname) {
	    this.pathname = '/';
	  }
	
	  //to support http.request
	  if (this.pathname || this.search) {
	    var p = this.pathname || '';
	    var s = this.search || '';
	    this.path = p + s;
	  }
	
	  // finally, reconstruct the href based on what has been validated.
	  this.href = this.format();
	  return this;
	};
	
	// format a parsed object into a url string
	function urlFormat(obj) {
	  // ensure it's an object, and not a string url.
	  // If it's an obj, this is a no-op.
	  // this way, you can call url_format() on strings
	  // to clean up potentially wonky urls.
	  if (isString(obj)) obj = urlParse(obj);
	  if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
	  return obj.format();
	}
	
	Url.prototype.format = function() {
	  var auth = this.auth || '';
	  if (auth) {
	    auth = encodeURIComponent(auth);
	    auth = auth.replace(/%3A/i, ':');
	    auth += '@';
	  }
	
	  var protocol = this.protocol || '',
	      pathname = this.pathname || '',
	      hash = this.hash || '',
	      host = false,
	      query = '';
	
	  if (this.host) {
	    host = auth + this.host;
	  } else if (this.hostname) {
	    host = auth + (this.hostname.indexOf(':') === -1 ?
	        this.hostname :
	        '[' + this.hostname + ']');
	    if (this.port) {
	      host += ':' + this.port;
	    }
	  }
	
	  if (this.query &&
	      isObject(this.query) &&
	      Object.keys(this.query).length) {
	    query = querystring.stringify(this.query);
	  }
	
	  var search = this.search || (query && ('?' + query)) || '';
	
	  if (protocol && protocol.substr(-1) !== ':') protocol += ':';
	
	  // only the slashedProtocols get the //.  Not mailto:, xmpp:, etc.
	  // unless they had them to begin with.
	  if (this.slashes ||
	      (!protocol || slashedProtocol[protocol]) && host !== false) {
	    host = '//' + (host || '');
	    if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
	  } else if (!host) {
	    host = '';
	  }
	
	  if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
	  if (search && search.charAt(0) !== '?') search = '?' + search;
	
	  pathname = pathname.replace(/[?#]/g, function(match) {
	    return encodeURIComponent(match);
	  });
	  search = search.replace('#', '%23');
	
	  return protocol + host + pathname + search + hash;
	};
	
	function urlResolve(source, relative) {
	  return urlParse(source, false, true).resolve(relative);
	}
	
	Url.prototype.resolve = function(relative) {
	  return this.resolveObject(urlParse(relative, false, true)).format();
	};
	
	function urlResolveObject(source, relative) {
	  if (!source) return relative;
	  return urlParse(source, false, true).resolveObject(relative);
	}
	
	Url.prototype.resolveObject = function(relative) {
	  if (isString(relative)) {
	    var rel = new Url();
	    rel.parse(relative, false, true);
	    relative = rel;
	  }
	
	  var result = new Url();
	  Object.keys(this).forEach(function(k) {
	    result[k] = this[k];
	  }, this);
	
	  // hash is always overridden, no matter what.
	  // even href="" will remove it.
	  result.hash = relative.hash;
	
	  // if the relative url is empty, then there's nothing left to do here.
	  if (relative.href === '') {
	    result.href = result.format();
	    return result;
	  }
	
	  // hrefs like //foo/bar always cut to the protocol.
	  if (relative.slashes && !relative.protocol) {
	    // take everything except the protocol from relative
	    Object.keys(relative).forEach(function(k) {
	      if (k !== 'protocol')
	        result[k] = relative[k];
	    });
	
	    //urlParse appends trailing / to urls like http://www.example.com
	    if (slashedProtocol[result.protocol] &&
	        result.hostname && !result.pathname) {
	      result.path = result.pathname = '/';
	    }
	
	    result.href = result.format();
	    return result;
	  }
	
	  if (relative.protocol && relative.protocol !== result.protocol) {
	    // if it's a known url protocol, then changing
	    // the protocol does weird things
	    // first, if it's not file:, then we MUST have a host,
	    // and if there was a path
	    // to begin with, then we MUST have a path.
	    // if it is file:, then the host is dropped,
	    // because that's known to be hostless.
	    // anything else is assumed to be absolute.
	    if (!slashedProtocol[relative.protocol]) {
	      Object.keys(relative).forEach(function(k) {
	        result[k] = relative[k];
	      });
	      result.href = result.format();
	      return result;
	    }
	
	    result.protocol = relative.protocol;
	    if (!relative.host && !hostlessProtocol[relative.protocol]) {
	      var relPath = (relative.pathname || '').split('/');
	      while (relPath.length && !(relative.host = relPath.shift()));
	      if (!relative.host) relative.host = '';
	      if (!relative.hostname) relative.hostname = '';
	      if (relPath[0] !== '') relPath.unshift('');
	      if (relPath.length < 2) relPath.unshift('');
	      result.pathname = relPath.join('/');
	    } else {
	      result.pathname = relative.pathname;
	    }
	    result.search = relative.search;
	    result.query = relative.query;
	    result.host = relative.host || '';
	    result.auth = relative.auth;
	    result.hostname = relative.hostname || relative.host;
	    result.port = relative.port;
	    // to support http.request
	    if (result.pathname || result.search) {
	      var p = result.pathname || '';
	      var s = result.search || '';
	      result.path = p + s;
	    }
	    result.slashes = result.slashes || relative.slashes;
	    result.href = result.format();
	    return result;
	  }
	
	  var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
	      isRelAbs = (
	          relative.host ||
	          relative.pathname && relative.pathname.charAt(0) === '/'
	      ),
	      mustEndAbs = (isRelAbs || isSourceAbs ||
	                    (result.host && relative.pathname)),
	      removeAllDots = mustEndAbs,
	      srcPath = result.pathname && result.pathname.split('/') || [],
	      relPath = relative.pathname && relative.pathname.split('/') || [],
	      psychotic = result.protocol && !slashedProtocol[result.protocol];
	
	  // if the url is a non-slashed url, then relative
	  // links like ../.. should be able
	  // to crawl up to the hostname, as well.  This is strange.
	  // result.protocol has already been set by now.
	  // Later on, put the first path part into the host field.
	  if (psychotic) {
	    result.hostname = '';
	    result.port = null;
	    if (result.host) {
	      if (srcPath[0] === '') srcPath[0] = result.host;
	      else srcPath.unshift(result.host);
	    }
	    result.host = '';
	    if (relative.protocol) {
	      relative.hostname = null;
	      relative.port = null;
	      if (relative.host) {
	        if (relPath[0] === '') relPath[0] = relative.host;
	        else relPath.unshift(relative.host);
	      }
	      relative.host = null;
	    }
	    mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
	  }
	
	  if (isRelAbs) {
	    // it's absolute.
	    result.host = (relative.host || relative.host === '') ?
	                  relative.host : result.host;
	    result.hostname = (relative.hostname || relative.hostname === '') ?
	                      relative.hostname : result.hostname;
	    result.search = relative.search;
	    result.query = relative.query;
	    srcPath = relPath;
	    // fall through to the dot-handling below.
	  } else if (relPath.length) {
	    // it's relative
	    // throw away the existing file, and take the new path instead.
	    if (!srcPath) srcPath = [];
	    srcPath.pop();
	    srcPath = srcPath.concat(relPath);
	    result.search = relative.search;
	    result.query = relative.query;
	  } else if (!isNullOrUndefined(relative.search)) {
	    // just pull out the search.
	    // like href='?foo'.
	    // Put this after the other two cases because it simplifies the booleans
	    if (psychotic) {
	      result.hostname = result.host = srcPath.shift();
	      //occationaly the auth can get stuck only in host
	      //this especialy happens in cases like
	      //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
	      var authInHost = result.host && result.host.indexOf('@') > 0 ?
	                       result.host.split('@') : false;
	      if (authInHost) {
	        result.auth = authInHost.shift();
	        result.host = result.hostname = authInHost.shift();
	      }
	    }
	    result.search = relative.search;
	    result.query = relative.query;
	    //to support http.request
	    if (!isNull(result.pathname) || !isNull(result.search)) {
	      result.path = (result.pathname ? result.pathname : '') +
	                    (result.search ? result.search : '');
	    }
	    result.href = result.format();
	    return result;
	  }
	
	  if (!srcPath.length) {
	    // no path at all.  easy.
	    // we've already handled the other stuff above.
	    result.pathname = null;
	    //to support http.request
	    if (result.search) {
	      result.path = '/' + result.search;
	    } else {
	      result.path = null;
	    }
	    result.href = result.format();
	    return result;
	  }
	
	  // if a url ENDs in . or .., then it must get a trailing slash.
	  // however, if it ends in anything else non-slashy,
	  // then it must NOT get a trailing slash.
	  var last = srcPath.slice(-1)[0];
	  var hasTrailingSlash = (
	      (result.host || relative.host) && (last === '.' || last === '..') ||
	      last === '');
	
	  // strip single dots, resolve double dots to parent dir
	  // if the path tries to go above the root, `up` ends up > 0
	  var up = 0;
	  for (var i = srcPath.length; i >= 0; i--) {
	    last = srcPath[i];
	    if (last == '.') {
	      srcPath.splice(i, 1);
	    } else if (last === '..') {
	      srcPath.splice(i, 1);
	      up++;
	    } else if (up) {
	      srcPath.splice(i, 1);
	      up--;
	    }
	  }
	
	  // if the path is allowed to go above the root, restore leading ..s
	  if (!mustEndAbs && !removeAllDots) {
	    for (; up--; up) {
	      srcPath.unshift('..');
	    }
	  }
	
	  if (mustEndAbs && srcPath[0] !== '' &&
	      (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
	    srcPath.unshift('');
	  }
	
	  if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
	    srcPath.push('');
	  }
	
	  var isAbsolute = srcPath[0] === '' ||
	      (srcPath[0] && srcPath[0].charAt(0) === '/');
	
	  // put the host back
	  if (psychotic) {
	    result.hostname = result.host = isAbsolute ? '' :
	                                    srcPath.length ? srcPath.shift() : '';
	    //occationaly the auth can get stuck only in host
	    //this especialy happens in cases like
	    //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
	    var authInHost = result.host && result.host.indexOf('@') > 0 ?
	                     result.host.split('@') : false;
	    if (authInHost) {
	      result.auth = authInHost.shift();
	      result.host = result.hostname = authInHost.shift();
	    }
	  }
	
	  mustEndAbs = mustEndAbs || (result.host && srcPath.length);
	
	  if (mustEndAbs && !isAbsolute) {
	    srcPath.unshift('');
	  }
	
	  if (!srcPath.length) {
	    result.pathname = null;
	    result.path = null;
	  } else {
	    result.pathname = srcPath.join('/');
	  }
	
	  //to support request.http
	  if (!isNull(result.pathname) || !isNull(result.search)) {
	    result.path = (result.pathname ? result.pathname : '') +
	                  (result.search ? result.search : '');
	  }
	  result.auth = relative.auth || result.auth;
	  result.slashes = result.slashes || relative.slashes;
	  result.href = result.format();
	  return result;
	};
	
	Url.prototype.parseHost = function() {
	  var host = this.host;
	  var port = portPattern.exec(host);
	  if (port) {
	    port = port[0];
	    if (port !== ':') {
	      this.port = port.substr(1);
	    }
	    host = host.substr(0, host.length - port.length);
	  }
	  if (host) this.hostname = host;
	};
	
	function isString(arg) {
	  return typeof arg === "string";
	}
	
	function isObject(arg) {
	  return typeof arg === 'object' && arg !== null;
	}
	
	function isNull(arg) {
	  return arg === null;
	}
	function isNullOrUndefined(arg) {
	  return  arg == null;
	}


/***/ },
/* 294 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/*! https://mths.be/punycode v1.3.2 by @mathias */
	;(function(root) {
	
		/** Detect free variables */
		var freeExports = typeof exports == 'object' && exports &&
			!exports.nodeType && exports;
		var freeModule = typeof module == 'object' && module &&
			!module.nodeType && module;
		var freeGlobal = typeof global == 'object' && global;
		if (
			freeGlobal.global === freeGlobal ||
			freeGlobal.window === freeGlobal ||
			freeGlobal.self === freeGlobal
		) {
			root = freeGlobal;
		}
	
		/**
		 * The `punycode` object.
		 * @name punycode
		 * @type Object
		 */
		var punycode,
	
		/** Highest positive signed 32-bit float value */
		maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
	
		/** Bootstring parameters */
		base = 36,
		tMin = 1,
		tMax = 26,
		skew = 38,
		damp = 700,
		initialBias = 72,
		initialN = 128, // 0x80
		delimiter = '-', // '\x2D'
	
		/** Regular expressions */
		regexPunycode = /^xn--/,
		regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
		regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
	
		/** Error messages */
		errors = {
			'overflow': 'Overflow: input needs wider integers to process',
			'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
			'invalid-input': 'Invalid input'
		},
	
		/** Convenience shortcuts */
		baseMinusTMin = base - tMin,
		floor = Math.floor,
		stringFromCharCode = String.fromCharCode,
	
		/** Temporary variable */
		key;
	
		/*--------------------------------------------------------------------------*/
	
		/**
		 * A generic error utility function.
		 * @private
		 * @param {String} type The error type.
		 * @returns {Error} Throws a `RangeError` with the applicable error message.
		 */
		function error(type) {
			throw RangeError(errors[type]);
		}
	
		/**
		 * A generic `Array#map` utility function.
		 * @private
		 * @param {Array} array The array to iterate over.
		 * @param {Function} callback The function that gets called for every array
		 * item.
		 * @returns {Array} A new array of values returned by the callback function.
		 */
		function map(array, fn) {
			var length = array.length;
			var result = [];
			while (length--) {
				result[length] = fn(array[length]);
			}
			return result;
		}
	
		/**
		 * A simple `Array#map`-like wrapper to work with domain name strings or email
		 * addresses.
		 * @private
		 * @param {String} domain The domain name or email address.
		 * @param {Function} callback The function that gets called for every
		 * character.
		 * @returns {Array} A new string of characters returned by the callback
		 * function.
		 */
		function mapDomain(string, fn) {
			var parts = string.split('@');
			var result = '';
			if (parts.length > 1) {
				// In email addresses, only the domain name should be punycoded. Leave
				// the local part (i.e. everything up to `@`) intact.
				result = parts[0] + '@';
				string = parts[1];
			}
			// Avoid `split(regex)` for IE8 compatibility. See #17.
			string = string.replace(regexSeparators, '\x2E');
			var labels = string.split('.');
			var encoded = map(labels, fn).join('.');
			return result + encoded;
		}
	
		/**
		 * Creates an array containing the numeric code points of each Unicode
		 * character in the string. While JavaScript uses UCS-2 internally,
		 * this function will convert a pair of surrogate halves (each of which
		 * UCS-2 exposes as separate characters) into a single code point,
		 * matching UTF-16.
		 * @see `punycode.ucs2.encode`
		 * @see <https://mathiasbynens.be/notes/javascript-encoding>
		 * @memberOf punycode.ucs2
		 * @name decode
		 * @param {String} string The Unicode input string (UCS-2).
		 * @returns {Array} The new array of code points.
		 */
		function ucs2decode(string) {
			var output = [],
			    counter = 0,
			    length = string.length,
			    value,
			    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;
		}
	
		/**
		 * Creates a string based on an array of numeric code points.
		 * @see `punycode.ucs2.decode`
		 * @memberOf punycode.ucs2
		 * @name encode
		 * @param {Array} codePoints The array of numeric code points.
		 * @returns {String} The new Unicode string (UCS-2).
		 */
		function ucs2encode(array) {
			return map(array, function(value) {
				var output = '';
				if (value > 0xFFFF) {
					value -= 0x10000;
					output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
					value = 0xDC00 | value & 0x3FF;
				}
				output += stringFromCharCode(value);
				return output;
			}).join('');
		}
	
		/**
		 * Converts a basic code point into a digit/integer.
		 * @see `digitToBasic()`
		 * @private
		 * @param {Number} codePoint The basic numeric code point value.
		 * @returns {Number} The numeric value of a basic code point (for use in
		 * representing integers) in the range `0` to `base - 1`, or `base` if
		 * the code point does not represent a value.
		 */
		function basicToDigit(codePoint) {
			if (codePoint - 48 < 10) {
				return codePoint - 22;
			}
			if (codePoint - 65 < 26) {
				return codePoint - 65;
			}
			if (codePoint - 97 < 26) {
				return codePoint - 97;
			}
			return base;
		}
	
		/**
		 * Converts a digit/integer into a basic code point.
		 * @see `basicToDigit()`
		 * @private
		 * @param {Number} digit The numeric value of a basic code point.
		 * @returns {Number} The basic code point whose value (when used for
		 * representing integers) is `digit`, which needs to be in the range
		 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
		 * used; else, the lowercase form is used. The behavior is undefined
		 * if `flag` is non-zero and `digit` has no uppercase form.
		 */
		function digitToBasic(digit, flag) {
			//  0..25 map to ASCII a..z or A..Z
			// 26..35 map to ASCII 0..9
			return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
		}
	
		/**
		 * Bias adaptation function as per section 3.4 of RFC 3492.
		 * http://tools.ietf.org/html/rfc3492#section-3.4
		 * @private
		 */
		function adapt(delta, numPoints, firstTime) {
			var k = 0;
			delta = firstTime ? floor(delta / damp) : delta >> 1;
			delta += floor(delta / numPoints);
			for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
				delta = floor(delta / baseMinusTMin);
			}
			return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
		}
	
		/**
		 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
		 * symbols.
		 * @memberOf punycode
		 * @param {String} input The Punycode string of ASCII-only symbols.
		 * @returns {String} The resulting string of Unicode symbols.
		 */
		function decode(input) {
			// Don't use UCS-2
			var output = [],
			    inputLength = input.length,
			    out,
			    i = 0,
			    n = initialN,
			    bias = initialBias,
			    basic,
			    j,
			    index,
			    oldi,
			    w,
			    k,
			    digit,
			    t,
			    /** Cached calculation results */
			    baseMinusT;
	
			// Handle the basic code points: let `basic` be the number of input code
			// points before the last delimiter, or `0` if there is none, then copy
			// the first basic code points to the output.
	
			basic = input.lastIndexOf(delimiter);
			if (basic < 0) {
				basic = 0;
			}
	
			for (j = 0; j < basic; ++j) {
				// if it's not a basic code point
				if (input.charCodeAt(j) >= 0x80) {
					error('not-basic');
				}
				output.push(input.charCodeAt(j));
			}
	
			// Main decoding loop: start just after the last delimiter if any basic code
			// points were copied; start at the beginning otherwise.
	
			for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
	
				// `index` is the index of the next character to be consumed.
				// Decode a generalized variable-length integer into `delta`,
				// which gets added to `i`. The overflow checking is easier
				// if we increase `i` as we go, then subtract off its starting
				// value at the end to obtain `delta`.
				for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
	
					if (index >= inputLength) {
						error('invalid-input');
					}
	
					digit = basicToDigit(input.charCodeAt(index++));
	
					if (digit >= base || digit > floor((maxInt - i) / w)) {
						error('overflow');
					}
	
					i += digit * w;
					t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
	
					if (digit < t) {
						break;
					}
	
					baseMinusT = base - t;
					if (w > floor(maxInt / baseMinusT)) {
						error('overflow');
					}
	
					w *= baseMinusT;
	
				}
	
				out = output.length + 1;
				bias = adapt(i - oldi, out, oldi == 0);
	
				// `i` was supposed to wrap around from `out` to `0`,
				// incrementing `n` each time, so we'll fix that now:
				if (floor(i / out) > maxInt - n) {
					error('overflow');
				}
	
				n += floor(i / out);
				i %= out;
	
				// Insert `n` at position `i` of the output
				output.splice(i++, 0, n);
	
			}
	
			return ucs2encode(output);
		}
	
		/**
		 * Converts a string of Unicode symbols (e.g. a domain name label) to a
		 * Punycode string of ASCII-only symbols.
		 * @memberOf punycode
		 * @param {String} input The string of Unicode symbols.
		 * @returns {String} The resulting Punycode string of ASCII-only symbols.
		 */
		function encode(input) {
			var n,
			    delta,
			    handledCPCount,
			    basicLength,
			    bias,
			    j,
			    m,
			    q,
			    k,
			    t,
			    currentValue,
			    output = [],
			    /** `inputLength` will hold the number of code points in `input`. */
			    inputLength,
			    /** Cached calculation results */
			    handledCPCountPlusOne,
			    baseMinusT,
			    qMinusT;
	
			// Convert the input in UCS-2 to Unicode
			input = ucs2decode(input);
	
			// Cache the length
			inputLength = input.length;
	
			// Initialize the state
			n = initialN;
			delta = 0;
			bias = initialBias;
	
			// Handle the basic code points
			for (j = 0; j < inputLength; ++j) {
				currentValue = input[j];
				if (currentValue < 0x80) {
					output.push(stringFromCharCode(currentValue));
				}
			}
	
			handledCPCount = basicLength = output.length;
	
			// `handledCPCount` is the number of code points that have been handled;
			// `basicLength` is the number of basic code points.
	
			// Finish the basic string - if it is not empty - with a delimiter
			if (basicLength) {
				output.push(delimiter);
			}
	
			// Main encoding loop:
			while (handledCPCount < inputLength) {
	
				// All non-basic code points < n have been handled already. Find the next
				// larger one:
				for (m = maxInt, j = 0; j < inputLength; ++j) {
					currentValue = input[j];
					if (currentValue >= n && currentValue < m) {
						m = currentValue;
					}
				}
	
				// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
				// but guard against overflow
				handledCPCountPlusOne = handledCPCount + 1;
				if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
					error('overflow');
				}
	
				delta += (m - n) * handledCPCountPlusOne;
				n = m;
	
				for (j = 0; j < inputLength; ++j) {
					currentValue = input[j];
	
					if (currentValue < n && ++delta > maxInt) {
						error('overflow');
					}
	
					if (currentValue == n) {
						// Represent delta as a generalized variable-length integer
						for (q = delta, k = base; /* no condition */; k += base) {
							t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
							if (q < t) {
								break;
							}
							qMinusT = q - t;
							baseMinusT = base - t;
							output.push(
								stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
							);
							q = floor(qMinusT / baseMinusT);
						}
	
						output.push(stringFromCharCode(digitToBasic(q, 0)));
						bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
						delta = 0;
						++handledCPCount;
					}
				}
	
				++delta;
				++n;
	
			}
			return output.join('');
		}
	
		/**
		 * Converts a Punycode string representing a domain name or an email address
		 * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
		 * it doesn't matter if you call it on a string that has already been
		 * converted to Unicode.
		 * @memberOf punycode
		 * @param {String} input The Punycoded domain name or email address to
		 * convert to Unicode.
		 * @returns {String} The Unicode representation of the given Punycode
		 * string.
		 */
		function toUnicode(input) {
			return mapDomain(input, function(string) {
				return regexPunycode.test(string)
					? decode(string.slice(4).toLowerCase())
					: string;
			});
		}
	
		/**
		 * Converts a Unicode string representing a domain name or an email address to
		 * Punycode. Only the non-ASCII parts of the domain name will be converted,
		 * i.e. it doesn't matter if you call it with a domain that's already in
		 * ASCII.
		 * @memberOf punycode
		 * @param {String} input The domain name or email address to convert, as a
		 * Unicode string.
		 * @returns {String} The Punycode representation of the given domain name or
		 * email address.
		 */
		function toASCII(input) {
			return mapDomain(input, function(string) {
				return regexNonASCII.test(string)
					? 'xn--' + encode(string)
					: string;
			});
		}
	
		/*--------------------------------------------------------------------------*/
	
		/** Define the public API */
		punycode = {
			/**
			 * A string representing the current Punycode.js version number.
			 * @memberOf punycode
			 * @type String
			 */
			'version': '1.3.2',
			/**
			 * An object of methods to convert from JavaScript's internal character
			 * representation (UCS-2) to Unicode code points, and back.
			 * @see <https://mathiasbynens.be/notes/javascript-encoding>
			 * @memberOf punycode
			 * @type Object
			 */
			'ucs2': {
				'decode': ucs2decode,
				'encode': ucs2encode
			},
			'decode': decode,
			'encode': encode,
			'toASCII': toASCII,
			'toUnicode': toUnicode
		};
	
		/** Expose `punycode` */
		// Some AMD build optimizers, like r.js, check for specific condition patterns
		// like the following:
		if (
			true
		) {
			!(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
				return punycode;
			}.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
		} else if (freeExports && freeModule) {
			if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
				freeModule.exports = punycode;
			} else { // in Narwhal or RingoJS v0.7.0-
				for (key in punycode) {
					punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
				}
			}
		} else { // in Rhino or a web browser
			root.punycode = punycode;
		}
	
	}(this));
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(77)(module), (function() { return this; }())))

/***/ },
/* 295 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	exports.decode = exports.parse = __webpack_require__(296);
	exports.encode = exports.stringify = __webpack_require__(297);


/***/ },
/* 296 */
/***/ function(module, exports) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	'use strict';
	
	// If obj.hasOwnProperty has been overridden, then calling
	// obj.hasOwnProperty(prop) will break.
	// See: https://github.com/joyent/node/issues/1707
	function hasOwnProperty(obj, prop) {
	  return Object.prototype.hasOwnProperty.call(obj, prop);
	}
	
	module.exports = function(qs, sep, eq, options) {
	  sep = sep || '&';
	  eq = eq || '=';
	  var obj = {};
	
	  if (typeof qs !== 'string' || qs.length === 0) {
	    return obj;
	  }
	
	  var regexp = /\+/g;
	  qs = qs.split(sep);
	
	  var maxKeys = 1000;
	  if (options && typeof options.maxKeys === 'number') {
	    maxKeys = options.maxKeys;
	  }
	
	  var len = qs.length;
	  // maxKeys <= 0 means that we should not limit keys count
	  if (maxKeys > 0 && len > maxKeys) {
	    len = maxKeys;
	  }
	
	  for (var i = 0; i < len; ++i) {
	    var x = qs[i].replace(regexp, '%20'),
	        idx = x.indexOf(eq),
	        kstr, vstr, k, v;
	
	    if (idx >= 0) {
	      kstr = x.substr(0, idx);
	      vstr = x.substr(idx + 1);
	    } else {
	      kstr = x;
	      vstr = '';
	    }
	
	    k = decodeURIComponent(kstr);
	    v = decodeURIComponent(vstr);
	
	    if (!hasOwnProperty(obj, k)) {
	      obj[k] = v;
	    } else if (Array.isArray(obj[k])) {
	      obj[k].push(v);
	    } else {
	      obj[k] = [obj[k], v];
	    }
	  }
	
	  return obj;
	};


/***/ },
/* 297 */
/***/ function(module, exports) {

	// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	'use strict';
	
	var stringifyPrimitive = function(v) {
	  switch (typeof v) {
	    case 'string':
	      return v;
	
	    case 'boolean':
	      return v ? 'true' : 'false';
	
	    case 'number':
	      return isFinite(v) ? v : '';
	
	    default:
	      return '';
	  }
	};
	
	module.exports = function(obj, sep, eq, name) {
	  sep = sep || '&';
	  eq = eq || '=';
	  if (obj === null) {
	    obj = undefined;
	  }
	
	  if (typeof obj === 'object') {
	    return Object.keys(obj).map(function(k) {
	      var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
	      if (Array.isArray(obj[k])) {
	        return obj[k].map(function(v) {
	          return ks + encodeURIComponent(stringifyPrimitive(v));
	        }).join(sep);
	      } else {
	        return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
	      }
	    }).join(sep);
	
	  }
	
	  if (!name) return '';
	  return encodeURIComponent(stringifyPrimitive(name)) + eq +
	         encodeURIComponent(stringifyPrimitive(obj));
	};


/***/ },
/* 298 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 299 */,
/* 300 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var _require = __webpack_require__(301);
	
	var filter = _require.filter;
	
	var classnames = __webpack_require__(211);
	__webpack_require__(308);
	var Svg = __webpack_require__(310);
	var CloseButton = __webpack_require__(336);
	
	var INITIAL_SELECTED_INDEX = 0;
	
	var Autocomplete = React.createClass({
	  propTypes: {
	    selectItem: PropTypes.func,
	    items: PropTypes.array,
	    handleClose: PropTypes.func,
	    inputValue: PropTypes.string
	  },
	
	  displayName: "Autocomplete",
	
	  getInitialState() {
	    return {
	      inputValue: this.props.inputValue,
	      selectedIndex: INITIAL_SELECTED_INDEX
	    };
	  },
	
	  componentDidMount() {
	    var endOfInput = this.state.inputValue.length;
	    this.refs.searchInput.focus();
	    this.refs.searchInput.setSelectionRange(endOfInput, endOfInput);
	  },
	
	  componentDidUpdate() {
	    this.scrollList();
	  },
	
	  scrollList() {
	    var resultsEl = this.refs.results;
	    if (!resultsEl || resultsEl.children.length === 0) {
	      return;
	    }
	
	    var resultsHeight = resultsEl.clientHeight;
	    var itemHeight = resultsEl.children[0].clientHeight;
	    var numVisible = resultsHeight / itemHeight;
	    var positionsToScroll = this.state.selectedIndex - numVisible + 1;
	    var itemOffset = resultsHeight % itemHeight;
	    var scroll = positionsToScroll * (itemHeight + 2) + itemOffset;
	
	    resultsEl.scrollTop = Math.max(0, scroll);
	  },
	
	  getSearchResults() {
	    var inputValue = this.state.inputValue;
	
	    if (inputValue == "") {
	      return [];
	    }
	    return filter(this.props.items, this.state.inputValue, {
	      key: "value"
	    });
	  },
	
	  onKeyDown(e) {
	    var searchResults = this.getSearchResults(),
	        resultCount = searchResults.length;
	
	    if (e.key === "ArrowUp") {
	      this.setState({
	        selectedIndex: Math.max(0, this.state.selectedIndex - 1)
	      });
	      e.preventDefault();
	    } else if (e.key === "ArrowDown") {
	      this.setState({
	        selectedIndex: Math.min(resultCount - 1, this.state.selectedIndex + 1)
	      });
	      e.preventDefault();
	    } else if (e.key === "Enter") {
	      if (searchResults.length) {
	        this.props.selectItem(searchResults[this.state.selectedIndex]);
	      } else {
	        this.props.handleClose(this.state.inputValue);
	      }
	      e.preventDefault();
	    } else if (e.key === "Tab") {
	      this.props.handleClose(this.state.inputValue);
	      e.preventDefault();
	    }
	  },
	
	  renderSearchItem(result, index) {
	    return dom.li({
	      onClick: () => this.props.selectItem(result),
	      key: result.value,
	      className: classnames({
	        selected: index === this.state.selectedIndex
	      })
	    }, dom.div({ className: "title" }, result.title), dom.div({ className: "subtitle" }, result.subtitle));
	  },
	
	  renderInput() {
	    return dom.input({
	      ref: "searchInput",
	      value: this.state.inputValue,
	      onChange: e => this.setState({
	        inputValue: e.target.value,
	        selectedIndex: INITIAL_SELECTED_INDEX
	      }),
	      onFocus: e => this.setState({ focused: true }),
	      onBlur: e => this.setState({ focused: false }),
	      onKeyDown: this.onKeyDown,
	      placeholder: L10N.getStr("sourceSearch.search")
	    });
	  },
	
	  renderResults(results) {
	    if (results.length) {
	      return dom.ul({ className: "results", ref: "results" }, results.map(this.renderSearchItem));
	    } else if (this.state.inputValue && !results.length) {
	      return dom.div({ className: "no-result-msg" }, Svg("sad-face"), L10N.getFormatStr("sourceSearch.noResults", this.state.inputValue));
	    }
	  },
	
	  renderSummary(searchResults) {
	    if (searchResults && searchResults.length === 0) {
	      return;
	    }
	
	    var resultCountSummary = "";
	    if (this.state.inputValue) {
	      resultCountSummary = L10N.getFormatStr("sourceSearch.resultsSummary", searchResults.length, this.state.inputValue);
	    }
	    return dom.div({ className: "results-summary" }, resultCountSummary);
	  },
	
	  render() {
	    var searchResults = this.getSearchResults();
	    return dom.div({ className: classnames({
	        autocomplete: true,
	        focused: this.state.focused
	      })
	    }, dom.div({ className: "searchinput-container" }, Svg("magnifying-glass"), this.renderInput(), CloseButton({
	      buttonClass: "big",
	      handleClick: this.props.handleClose
	    })), this.renderSummary(searchResults), this.renderResults(searchResults));
	  }
	});
	
	module.exports = Autocomplete;

/***/ },
/* 301 */
/***/ function(module, exports, __webpack_require__) {

	(function() {
	  var PathSeparator, filter, legacy_scorer, matcher, prepQueryCache, scorer;
	
	  scorer = __webpack_require__(302);
	
	  legacy_scorer = __webpack_require__(305);
	
	  filter = __webpack_require__(306);
	
	  matcher = __webpack_require__(307);
	
	  PathSeparator = __webpack_require__(303).sep;
	
	  prepQueryCache = null;
	
	  module.exports = {
	    filter: function(candidates, query, options) {
	      if (!((query != null ? query.length : void 0) && (candidates != null ? candidates.length : void 0))) {
	        return [];
	      }
	      return filter(candidates, query, options);
	    },
	    prepQuery: function(query) {
	      return scorer.prepQuery(query);
	    },
	    score: function(string, query, prepQuery, _arg) {
	      var allowErrors, coreQuery, legacy, queryHasSlashes, score, _ref;
	      _ref = _arg != null ? _arg : {}, allowErrors = _ref.allowErrors, legacy = _ref.legacy;
	      if (!((string != null ? string.length : void 0) && (query != null ? query.length : void 0))) {
	        return 0;
	      }
	      if (prepQuery == null) {
	        prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query));
	      }
	      if (!legacy) {
	        score = scorer.score(string, query, prepQuery, !!allowErrors);
	      } else {
	        queryHasSlashes = prepQuery.depth > 0;
	        coreQuery = prepQuery.core;
	        score = legacy_scorer.score(string, coreQuery, queryHasSlashes);
	        if (!queryHasSlashes) {
	          score = legacy_scorer.basenameScore(string, coreQuery, score);
	        }
	      }
	      return score;
	    },
	    match: function(string, query, prepQuery, _arg) {
	      var allowErrors, baseMatches, matches, query_lw, string_lw, _i, _ref, _results;
	      allowErrors = (_arg != null ? _arg : {}).allowErrors;
	      if (!string) {
	        return [];
	      }
	      if (!query) {
	        return [];
	      }
	      if (string === query) {
	        return (function() {
	          _results = [];
	          for (var _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }
	          return _results;
	        }).apply(this);
	      }
	      if (prepQuery == null) {
	        prepQuery = prepQueryCache && prepQueryCache.query === query ? prepQueryCache : (prepQueryCache = scorer.prepQuery(query));
	      }
	      if (!(allowErrors || scorer.isMatch(string, prepQuery.core_lw, prepQuery.core_up))) {
	        return [];
	      }
	      string_lw = string.toLowerCase();
	      query_lw = prepQuery.query_lw;
	      matches = matcher.match(string, string_lw, prepQuery);
	      if (matches.length === 0) {
	        return matches;
	      }
	      if (string.indexOf(PathSeparator) > -1) {
	        baseMatches = matcher.basenameMatch(string, string_lw, prepQuery);
	        matches = matcher.mergeMatches(matches, baseMatches);
	      }
	      return matches;
	    }
	  };
	
	}).call(this);


/***/ },
/* 302 */
/***/ function(module, exports, __webpack_require__) {

	(function() {
	  var AcronymResult, PathSeparator, Query, basenameScore, coreChars, countDir, doScore, emptyAcronymResult, file_coeff, isMatch, isSeparator, isWordEnd, isWordStart, miss_coeff, opt_char_re, pos_bonus, scoreAcronyms, scoreCharacter, scoreConsecutives, scoreExact, scoreExactMatch, scorePattern, scorePosition, scoreSize, tau_depth, tau_size, truncatedUpperCase, wm;
	
	  PathSeparator = __webpack_require__(303).sep;
	
	  wm = 150;
	
	  pos_bonus = 20;
	
	  tau_depth = 13;
	
	  tau_size = 85;
	
	  file_coeff = 1.2;
	
	  miss_coeff = 0.75;
	
	  opt_char_re = /[ _\-:\/\\]/g;
	
	  exports.coreChars = coreChars = function(query) {
	    return query.replace(opt_char_re, '');
	  };
	
	  exports.score = function(string, query, prepQuery, allowErrors) {
	    var score, string_lw;
	    if (prepQuery == null) {
	      prepQuery = new Query(query);
	    }
	    if (allowErrors == null) {
	      allowErrors = false;
	    }
	    if (!(allowErrors || isMatch(string, prepQuery.core_lw, prepQuery.core_up))) {
	      return 0;
	    }
	    string_lw = string.toLowerCase();
	    score = doScore(string, string_lw, prepQuery);
	    return Math.ceil(basenameScore(string, string_lw, prepQuery, score));
	  };
	
	  Query = (function() {
	    function Query(query) {
	      if (!(query != null ? query.length : void 0)) {
	        return null;
	      }
	      this.query = query;
	      this.query_lw = query.toLowerCase();
	      this.core = coreChars(query);
	      this.core_lw = this.core.toLowerCase();
	      this.core_up = truncatedUpperCase(this.core);
	      this.depth = countDir(query, query.length);
	    }
	
	    return Query;
	
	  })();
	
	  exports.prepQuery = function(query) {
	    return new Query(query);
	  };
	
	  exports.isMatch = isMatch = function(subject, query_lw, query_up) {
	    var i, j, m, n, qj_lw, qj_up, si;
	    m = subject.length;
	    n = query_lw.length;
	    if (!m || n > m) {
	      return false;
	    }
	    i = -1;
	    j = -1;
	    while (++j < n) {
	      qj_lw = query_lw[j];
	      qj_up = query_up[j];
	      while (++i < m) {
	        si = subject[i];
	        if (si === qj_lw || si === qj_up) {
	          break;
	        }
	      }
	      if (i === m) {
	        return false;
	      }
	    }
	    return true;
	  };
	
	  doScore = function(subject, subject_lw, prepQuery) {
	    var acro, acro_score, align, csc_diag, csc_row, csc_score, i, j, m, miss_budget, miss_left, mm, n, pos, query, query_lw, record_miss, score, score_diag, score_row, score_up, si_lw, start, sz;
	    query = prepQuery.query;
	    query_lw = prepQuery.query_lw;
	    m = subject.length;
	    n = query.length;
	    acro = scoreAcronyms(subject, subject_lw, query, query_lw);
	    acro_score = acro.score;
	    if (acro.count === n) {
	      return scoreExact(n, m, acro_score, acro.pos);
	    }
	    pos = subject_lw.indexOf(query_lw);
	    if (pos > -1) {
	      return scoreExactMatch(subject, subject_lw, query, query_lw, pos, n, m);
	    }
	    score_row = new Array(n);
	    csc_row = new Array(n);
	    sz = scoreSize(n, m);
	    miss_budget = Math.ceil(miss_coeff * n) + 5;
	    miss_left = miss_budget;
	    j = -1;
	    while (++j < n) {
	      score_row[j] = 0;
	      csc_row[j] = 0;
	    }
	    i = subject_lw.indexOf(query_lw[0]);
	    if (i > -1) {
	      i--;
	    }
	    mm = subject_lw.lastIndexOf(query_lw[n - 1], m);
	    if (mm > i) {
	      m = mm + 1;
	    }
	    while (++i < m) {
	      score = 0;
	      score_diag = 0;
	      csc_diag = 0;
	      si_lw = subject_lw[i];
	      record_miss = true;
	      j = -1;
	      while (++j < n) {
	        score_up = score_row[j];
	        if (score_up > score) {
	          score = score_up;
	        }
	        csc_score = 0;
	        if (query_lw[j] === si_lw) {
	          start = isWordStart(i, subject, subject_lw);
	          csc_score = csc_diag > 0 ? csc_diag : scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);
	          align = score_diag + scoreCharacter(i, j, start, acro_score, csc_score);
	          if (align > score) {
	            score = align;
	            miss_left = miss_budget;
	          } else {
	            if (record_miss && --miss_left <= 0) {
	              return score_row[n - 1] * sz;
	            }
	            record_miss = false;
	          }
	        }
	        score_diag = score_up;
	        csc_diag = csc_row[j];
	        csc_row[j] = csc_score;
	        score_row[j] = score;
	      }
	    }
	    return score * sz;
	  };
	
	  exports.isWordStart = isWordStart = function(pos, subject, subject_lw) {
	    var curr_s, prev_s;
	    if (pos === 0) {
	      return true;
	    }
	    curr_s = subject[pos];
	    prev_s = subject[pos - 1];
	    return isSeparator(curr_s) || isSeparator(prev_s) || (curr_s !== subject_lw[pos] && prev_s === subject_lw[pos - 1]);
	  };
	
	  exports.isWordEnd = isWordEnd = function(pos, subject, subject_lw, len) {
	    var curr_s, next_s;
	    if (pos === len - 1) {
	      return true;
	    }
	    curr_s = subject[pos];
	    next_s = subject[pos + 1];
	    return isSeparator(curr_s) || isSeparator(next_s) || (curr_s === subject_lw[pos] && next_s !== subject_lw[pos + 1]);
	  };
	
	  isSeparator = function(c) {
	    return c === ' ' || c === '.' || c === '-' || c === '_' || c === '/' || c === '\\';
	  };
	
	  scorePosition = function(pos) {
	    var sc;
	    if (pos < pos_bonus) {
	      sc = pos_bonus - pos;
	      return 100 + sc * sc;
	    } else {
	      return Math.max(100 + pos_bonus - pos, 0);
	    }
	  };
	
	  scoreSize = function(n, m) {
	    return tau_size / (tau_size + Math.abs(m - n));
	  };
	
	  scoreExact = function(n, m, quality, pos) {
	    return 2 * n * (wm * quality + scorePosition(pos)) * scoreSize(n, m);
	  };
	
	  exports.scorePattern = scorePattern = function(count, len, sameCase, start, end) {
	    var bonus, sz;
	    sz = count;
	    bonus = 6;
	    if (sameCase === count) {
	      bonus += 2;
	    }
	    if (start) {
	      bonus += 3;
	    }
	    if (end) {
	      bonus += 1;
	    }
	    if (count === len) {
	      if (start) {
	        if (sameCase === len) {
	          sz += 2;
	        } else {
	          sz += 1;
	        }
	      }
	      if (end) {
	        bonus += 1;
	      }
	    }
	    return sameCase + sz * (sz + bonus);
	  };
	
	  exports.scoreCharacter = scoreCharacter = function(i, j, start, acro_score, csc_score) {
	    var posBonus;
	    posBonus = scorePosition(i);
	    if (start) {
	      return posBonus + wm * ((acro_score > csc_score ? acro_score : csc_score) + 10);
	    }
	    return posBonus + wm * csc_score;
	  };
	
	  exports.scoreConsecutives = scoreConsecutives = function(subject, subject_lw, query, query_lw, i, j, start) {
	    var k, m, mi, n, nj, sameCase, startPos, sz;
	    m = subject.length;
	    n = query.length;
	    mi = m - i;
	    nj = n - j;
	    k = mi < nj ? mi : nj;
	    startPos = i;
	    sameCase = 0;
	    sz = 0;
	    if (query[j] === subject[i]) {
	      sameCase++;
	    }
	    while (++sz < k && query_lw[++j] === subject_lw[++i]) {
	      if (query[j] === subject[i]) {
	        sameCase++;
	      }
	    }
	    if (sz === 1) {
	      return 1 + 2 * sameCase;
	    }
	    return scorePattern(sz, n, sameCase, start, isWordEnd(i, subject, subject_lw, m));
	  };
	
	  exports.scoreExactMatch = scoreExactMatch = function(subject, subject_lw, query, query_lw, pos, n, m) {
	    var end, i, pos2, sameCase, start;
	    start = isWordStart(pos, subject, subject_lw);
	    if (!start) {
	      pos2 = subject_lw.indexOf(query_lw, pos + 1);
	      if (pos2 > -1) {
	        start = isWordStart(pos2, subject, subject_lw);
	        if (start) {
	          pos = pos2;
	        }
	      }
	    }
	    i = -1;
	    sameCase = 0;
	    while (++i < n) {
	      if (query[pos + i] === subject[i]) {
	        sameCase++;
	      }
	    }
	    end = isWordEnd(pos + n - 1, subject, subject_lw, m);
	    return scoreExact(n, m, scorePattern(n, n, sameCase, start, end), pos);
	  };
	
	  AcronymResult = (function() {
	    function AcronymResult(score, pos, count) {
	      this.score = score;
	      this.pos = pos;
	      this.count = count;
	    }
	
	    return AcronymResult;
	
	  })();
	
	  emptyAcronymResult = new AcronymResult(0, 0.1, 0);
	
	  exports.scoreAcronyms = scoreAcronyms = function(subject, subject_lw, query, query_lw) {
	    var count, i, j, m, n, pos, qj_lw, sameCase, score;
	    m = subject.length;
	    n = query.length;
	    if (!(m > 1 && n > 1)) {
	      return emptyAcronymResult;
	    }
	    count = 0;
	    pos = 0;
	    sameCase = 0;
	    i = -1;
	    j = -1;
	    while (++j < n) {
	      qj_lw = query_lw[j];
	      while (++i < m) {
	        if (qj_lw === subject_lw[i] && isWordStart(i, subject, subject_lw)) {
	          if (query[j] === subject[i]) {
	            sameCase++;
	          }
	          pos += i;
	          count++;
	          break;
	        }
	      }
	      if (i === m) {
	        break;
	      }
	    }
	    if (count < 2) {
	      return emptyAcronymResult;
	    }
	    score = scorePattern(count, n, sameCase, true, false);
	    return new AcronymResult(score, pos / count, count);
	  };
	
	  basenameScore = function(subject, subject_lw, prepQuery, fullPathScore) {
	    var alpha, basePathScore, basePos, depth, end;
	    if (fullPathScore === 0) {
	      return 0;
	    }
	    end = subject.length - 1;
	    while (subject[end] === PathSeparator) {
	      end--;
	    }
	    basePos = subject.lastIndexOf(PathSeparator, end);
	    if (basePos === -1) {
	      return fullPathScore;
	    }
	    depth = prepQuery.depth;
	    while (depth-- > 0) {
	      basePos = subject.lastIndexOf(PathSeparator, basePos - 1);
	      if (basePos === -1) {
	        return fullPathScore;
	      }
	    }
	    basePos++;
	    end++;
	    basePathScore = doScore(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery);
	    alpha = 0.5 * tau_depth / (tau_depth + countDir(subject, end + 1));
	    return alpha * basePathScore + (1 - alpha) * fullPathScore * scoreSize(0, file_coeff * (end - basePos));
	  };
	
	  exports.countDir = countDir = function(path, end) {
	    var count, i;
	    if (end < 1) {
	      return 0;
	    }
	    count = 0;
	    i = -1;
	    while (++i < end && path[i] === PathSeparator) {
	      continue;
	    }
	    while (++i < end) {
	      if (path[i] === PathSeparator) {
	        count++;
	        while (++i < end && path[i] === PathSeparator) {
	          continue;
	        }
	      }
	    }
	    return count;
	  };
	
	  truncatedUpperCase = function(str) {
	    var char, upper, _i, _len;
	    upper = "";
	    for (_i = 0, _len = str.length; _i < _len; _i++) {
	      char = str[_i];
	      upper += char.toUpperCase()[0];
	    }
	    return upper;
	  };
	
	}).call(this);


/***/ },
/* 303 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors.
	//
	// Permission is hereby granted, free of charge, to any person obtaining a
	// copy of this software and associated documentation files (the
	// "Software"), to deal in the Software without restriction, including
	// without limitation the rights to use, copy, modify, merge, publish,
	// distribute, sublicense, and/or sell copies of the Software, and to permit
	// persons to whom the Software is furnished to do so, subject to the
	// following conditions:
	//
	// The above copyright notice and this permission notice shall be included
	// in all copies or substantial portions of the Software.
	//
	// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
	// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
	// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
	// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
	// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
	// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
	// USE OR OTHER DEALINGS IN THE SOFTWARE.
	
	// resolves . and .. elements in a path array with directory names there
	// must be no slashes, empty elements, or device names (c:\) in the array
	// (so also no leading and trailing slashes - it does not distinguish
	// relative and absolute paths)
	function normalizeArray(parts, allowAboveRoot) {
	  // if the path tries to go above the root, `up` ends up > 0
	  var up = 0;
	  for (var i = parts.length - 1; i >= 0; i--) {
	    var last = parts[i];
	    if (last === '.') {
	      parts.splice(i, 1);
	    } else if (last === '..') {
	      parts.splice(i, 1);
	      up++;
	    } else if (up) {
	      parts.splice(i, 1);
	      up--;
	    }
	  }
	
	  // if the path is allowed to go above the root, restore leading ..s
	  if (allowAboveRoot) {
	    for (; up--; up) {
	      parts.unshift('..');
	    }
	  }
	
	  return parts;
	}
	
	// Split a filename into [root, dir, basename, ext], unix version
	// 'root' is just a slash, or nothing.
	var splitPathRe =
	    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
	var splitPath = function(filename) {
	  return splitPathRe.exec(filename).slice(1);
	};
	
	// path.resolve([from ...], to)
	// posix version
	exports.resolve = function() {
	  var resolvedPath = '',
	      resolvedAbsolute = false;
	
	  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
	    var path = (i >= 0) ? arguments[i] : process.cwd();
	
	    // Skip empty and invalid entries
	    if (typeof path !== 'string') {
	      throw new TypeError('Arguments to path.resolve must be strings');
	    } else if (!path) {
	      continue;
	    }
	
	    resolvedPath = path + '/' + resolvedPath;
	    resolvedAbsolute = path.charAt(0) === '/';
	  }
	
	  // At this point the path should be resolved to a full absolute path, but
	  // handle relative paths to be safe (might happen when process.cwd() fails)
	
	  // Normalize the path
	  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
	    return !!p;
	  }), !resolvedAbsolute).join('/');
	
	  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
	};
	
	// path.normalize(path)
	// posix version
	exports.normalize = function(path) {
	  var isAbsolute = exports.isAbsolute(path),
	      trailingSlash = substr(path, -1) === '/';
	
	  // Normalize the path
	  path = normalizeArray(filter(path.split('/'), function(p) {
	    return !!p;
	  }), !isAbsolute).join('/');
	
	  if (!path && !isAbsolute) {
	    path = '.';
	  }
	  if (path && trailingSlash) {
	    path += '/';
	  }
	
	  return (isAbsolute ? '/' : '') + path;
	};
	
	// posix version
	exports.isAbsolute = function(path) {
	  return path.charAt(0) === '/';
	};
	
	// posix version
	exports.join = function() {
	  var paths = Array.prototype.slice.call(arguments, 0);
	  return exports.normalize(filter(paths, function(p, index) {
	    if (typeof p !== 'string') {
	      throw new TypeError('Arguments to path.join must be strings');
	    }
	    return p;
	  }).join('/'));
	};
	
	
	// path.relative(from, to)
	// posix version
	exports.relative = function(from, to) {
	  from = exports.resolve(from).substr(1);
	  to = exports.resolve(to).substr(1);
	
	  function trim(arr) {
	    var start = 0;
	    for (; start < arr.length; start++) {
	      if (arr[start] !== '') break;
	    }
	
	    var end = arr.length - 1;
	    for (; end >= 0; end--) {
	      if (arr[end] !== '') break;
	    }
	
	    if (start > end) return [];
	    return arr.slice(start, end - start + 1);
	  }
	
	  var fromParts = trim(from.split('/'));
	  var toParts = trim(to.split('/'));
	
	  var length = Math.min(fromParts.length, toParts.length);
	  var samePartsLength = length;
	  for (var i = 0; i < length; i++) {
	    if (fromParts[i] !== toParts[i]) {
	      samePartsLength = i;
	      break;
	    }
	  }
	
	  var outputParts = [];
	  for (var i = samePartsLength; i < fromParts.length; i++) {
	    outputParts.push('..');
	  }
	
	  outputParts = outputParts.concat(toParts.slice(samePartsLength));
	
	  return outputParts.join('/');
	};
	
	exports.sep = '/';
	exports.delimiter = ':';
	
	exports.dirname = function(path) {
	  var result = splitPath(path),
	      root = result[0],
	      dir = result[1];
	
	  if (!root && !dir) {
	    // No dirname whatsoever
	    return '.';
	  }
	
	  if (dir) {
	    // It has a dirname, strip trailing slash
	    dir = dir.substr(0, dir.length - 1);
	  }
	
	  return root + dir;
	};
	
	
	exports.basename = function(path, ext) {
	  var f = splitPath(path)[2];
	  // TODO: make this comparison case-insensitive on windows?
	  if (ext && f.substr(-1 * ext.length) === ext) {
	    f = f.substr(0, f.length - ext.length);
	  }
	  return f;
	};
	
	
	exports.extname = function(path) {
	  return splitPath(path)[3];
	};
	
	function filter (xs, f) {
	    if (xs.filter) return xs.filter(f);
	    var res = [];
	    for (var i = 0; i < xs.length; i++) {
	        if (f(xs[i], i, xs)) res.push(xs[i]);
	    }
	    return res;
	}
	
	// String.prototype.substr - negative index don't work in IE8
	var substr = 'ab'.substr(-1) === 'b'
	    ? function (str, start, len) { return str.substr(start, len) }
	    : function (str, start, len) {
	        if (start < 0) start = str.length + start;
	        return str.substr(start, len);
	    }
	;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(304)))

/***/ },
/* 304 */
/***/ function(module, exports) {

	// shim for using process in browser
	var process = module.exports = {};
	
	// cached from whatever global is present so that test runners that stub it
	// don't break things.  But we need to wrap it in a try catch in case it is
	// wrapped in strict mode code which doesn't define any globals.  It's inside a
	// function because try/catches deoptimize in certain engines.
	
	var cachedSetTimeout;
	var cachedClearTimeout;
	
	function defaultSetTimout() {
	    throw new Error('setTimeout has not been defined');
	}
	function defaultClearTimeout () {
	    throw new Error('clearTimeout has not been defined');
	}
	(function () {
	    try {
	        if (typeof setTimeout === 'function') {
	            cachedSetTimeout = setTimeout;
	        } else {
	            cachedSetTimeout = defaultSetTimout;
	        }
	    } catch (e) {
	        cachedSetTimeout = defaultSetTimout;
	    }
	    try {
	        if (typeof clearTimeout === 'function') {
	            cachedClearTimeout = clearTimeout;
	        } else {
	            cachedClearTimeout = defaultClearTimeout;
	        }
	    } catch (e) {
	        cachedClearTimeout = defaultClearTimeout;
	    }
	} ())
	function runTimeout(fun) {
	    if (cachedSetTimeout === setTimeout) {
	        //normal enviroments in sane situations
	        return setTimeout(fun, 0);
	    }
	    // if setTimeout wasn't available but was latter defined
	    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
	        cachedSetTimeout = setTimeout;
	        return setTimeout(fun, 0);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedSetTimeout(fun, 0);
	    } catch(e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
	            return cachedSetTimeout.call(null, fun, 0);
	        } catch(e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
	            return cachedSetTimeout.call(this, fun, 0);
	        }
	    }
	
	
	}
	function runClearTimeout(marker) {
	    if (cachedClearTimeout === clearTimeout) {
	        //normal enviroments in sane situations
	        return clearTimeout(marker);
	    }
	    // if clearTimeout wasn't available but was latter defined
	    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
	        cachedClearTimeout = clearTimeout;
	        return clearTimeout(marker);
	    }
	    try {
	        // when when somebody has screwed with setTimeout but no I.E. maddness
	        return cachedClearTimeout(marker);
	    } catch (e){
	        try {
	            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
	            return cachedClearTimeout.call(null, marker);
	        } catch (e){
	            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
	            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
	            return cachedClearTimeout.call(this, marker);
	        }
	    }
	
	
	
	}
	var queue = [];
	var draining = false;
	var currentQueue;
	var queueIndex = -1;
	
	function cleanUpNextTick() {
	    if (!draining || !currentQueue) {
	        return;
	    }
	    draining = false;
	    if (currentQueue.length) {
	        queue = currentQueue.concat(queue);
	    } else {
	        queueIndex = -1;
	    }
	    if (queue.length) {
	        drainQueue();
	    }
	}
	
	function drainQueue() {
	    if (draining) {
	        return;
	    }
	    var timeout = runTimeout(cleanUpNextTick);
	    draining = true;
	
	    var len = queue.length;
	    while(len) {
	        currentQueue = queue;
	        queue = [];
	        while (++queueIndex < len) {
	            if (currentQueue) {
	                currentQueue[queueIndex].run();
	            }
	        }
	        queueIndex = -1;
	        len = queue.length;
	    }
	    currentQueue = null;
	    draining = false;
	    runClearTimeout(timeout);
	}
	
	process.nextTick = function (fun) {
	    var args = new Array(arguments.length - 1);
	    if (arguments.length > 1) {
	        for (var i = 1; i < arguments.length; i++) {
	            args[i - 1] = arguments[i];
	        }
	    }
	    queue.push(new Item(fun, args));
	    if (queue.length === 1 && !draining) {
	        runTimeout(drainQueue);
	    }
	};
	
	// v8 likes predictible objects
	function Item(fun, array) {
	    this.fun = fun;
	    this.array = array;
	}
	Item.prototype.run = function () {
	    this.fun.apply(null, this.array);
	};
	process.title = 'browser';
	process.browser = true;
	process.env = {};
	process.argv = [];
	process.version = ''; // empty string to avoid regexp issues
	process.versions = {};
	
	function noop() {}
	
	process.on = noop;
	process.addListener = noop;
	process.once = noop;
	process.off = noop;
	process.removeListener = noop;
	process.removeAllListeners = noop;
	process.emit = noop;
	
	process.binding = function (name) {
	    throw new Error('process.binding is not supported');
	};
	
	process.cwd = function () { return '/' };
	process.chdir = function (dir) {
	    throw new Error('process.chdir is not supported');
	};
	process.umask = function() { return 0; };


/***/ },
/* 305 */
/***/ function(module, exports, __webpack_require__) {

	(function() {
	  var PathSeparator, queryIsLastPathSegment;
	
	  PathSeparator = __webpack_require__(303).sep;
	
	  exports.basenameScore = function(string, query, score) {
	    var base, depth, index, lastCharacter, segmentCount, slashCount;
	    index = string.length - 1;
	    while (string[index] === PathSeparator) {
	      index--;
	    }
	    slashCount = 0;
	    lastCharacter = index;
	    base = null;
	    while (index >= 0) {
	      if (string[index] === PathSeparator) {
	        slashCount++;
	        if (base == null) {
	          base = string.substring(index + 1, lastCharacter + 1);
	        }
	      } else if (index === 0) {
	        if (lastCharacter < string.length - 1) {
	          if (base == null) {
	            base = string.substring(0, lastCharacter + 1);
	          }
	        } else {
	          if (base == null) {
	            base = string;
	          }
	        }
	      }
	      index--;
	    }
	    if (base === string) {
	      score *= 2;
	    } else if (base) {
	      score += exports.score(base, query);
	    }
	    segmentCount = slashCount + 1;
	    depth = Math.max(1, 10 - segmentCount);
	    score *= depth * 0.01;
	    return score;
	  };
	
	  exports.score = function(string, query) {
	    var character, characterScore, indexInQuery, indexInString, lowerCaseIndex, minIndex, queryLength, queryScore, stringLength, totalCharacterScore, upperCaseIndex, _ref;
	    if (string === query) {
	      return 1;
	    }
	    if (queryIsLastPathSegment(string, query)) {
	      return 1;
	    }
	    totalCharacterScore = 0;
	    queryLength = query.length;
	    stringLength = string.length;
	    indexInQuery = 0;
	    indexInString = 0;
	    while (indexInQuery < queryLength) {
	      character = query[indexInQuery++];
	      lowerCaseIndex = string.indexOf(character.toLowerCase());
	      upperCaseIndex = string.indexOf(character.toUpperCase());
	      minIndex = Math.min(lowerCaseIndex, upperCaseIndex);
	      if (minIndex === -1) {
	        minIndex = Math.max(lowerCaseIndex, upperCaseIndex);
	      }
	      indexInString = minIndex;
	      if (indexInString === -1) {
	        return 0;
	      }
	      characterScore = 0.1;
	      if (string[indexInString] === character) {
	        characterScore += 0.1;
	      }
	      if (indexInString === 0 || string[indexInString - 1] === PathSeparator) {
	        characterScore += 0.8;
	      } else if ((_ref = string[indexInString - 1]) === '-' || _ref === '_' || _ref === ' ') {
	        characterScore += 0.7;
	      }
	      string = string.substring(indexInString + 1, stringLength);
	      totalCharacterScore += characterScore;
	    }
	    queryScore = totalCharacterScore / queryLength;
	    return ((queryScore * (queryLength / stringLength)) + queryScore) / 2;
	  };
	
	  queryIsLastPathSegment = function(string, query) {
	    if (string[string.length - query.length - 1] === PathSeparator) {
	      return string.lastIndexOf(query) === string.length - query.length;
	    }
	  };
	
	  exports.match = function(string, query, stringOffset) {
	    var character, indexInQuery, indexInString, lowerCaseIndex, matches, minIndex, queryLength, stringLength, upperCaseIndex, _i, _ref, _results;
	    if (stringOffset == null) {
	      stringOffset = 0;
	    }
	    if (string === query) {
	      return (function() {
	        _results = [];
	        for (var _i = stringOffset, _ref = stringOffset + string.length; stringOffset <= _ref ? _i < _ref : _i > _ref; stringOffset <= _ref ? _i++ : _i--){ _results.push(_i); }
	        return _results;
	      }).apply(this);
	    }
	    queryLength = query.length;
	    stringLength = string.length;
	    indexInQuery = 0;
	    indexInString = 0;
	    matches = [];
	    while (indexInQuery < queryLength) {
	      character = query[indexInQuery++];
	      lowerCaseIndex = string.indexOf(character.toLowerCase());
	      upperCaseIndex = string.indexOf(character.toUpperCase());
	      minIndex = Math.min(lowerCaseIndex, upperCaseIndex);
	      if (minIndex === -1) {
	        minIndex = Math.max(lowerCaseIndex, upperCaseIndex);
	      }
	      indexInString = minIndex;
	      if (indexInString === -1) {
	        return [];
	      }
	      matches.push(stringOffset + indexInString);
	      stringOffset += indexInString + 1;
	      string = string.substring(indexInString + 1, stringLength);
	    }
	    return matches;
	  };
	
	}).call(this);


/***/ },
/* 306 */
/***/ function(module, exports, __webpack_require__) {

	(function() {
	  var PathSeparator, legacy_scorer, pluckCandidates, scorer, sortCandidates;
	
	  scorer = __webpack_require__(302);
	
	  legacy_scorer = __webpack_require__(305);
	
	  pluckCandidates = function(a) {
	    return a.candidate;
	  };
	
	  sortCandidates = function(a, b) {
	    return b.score - a.score;
	  };
	
	  PathSeparator = __webpack_require__(303).sep;
	
	  module.exports = function(candidates, query, _arg) {
	    var allowErrors, bAllowErrors, bKey, candidate, coreQuery, key, legacy, maxInners, maxResults, prepQuery, queryHasSlashes, score, scoredCandidates, spotLeft, string, _i, _j, _len, _len1, _ref;
	    _ref = _arg != null ? _arg : {}, key = _ref.key, maxResults = _ref.maxResults, maxInners = _ref.maxInners, allowErrors = _ref.allowErrors, legacy = _ref.legacy;
	    scoredCandidates = [];
	    spotLeft = (maxInners != null) && maxInners > 0 ? maxInners : candidates.length;
	    bAllowErrors = !!allowErrors;
	    bKey = key != null;
	    prepQuery = scorer.prepQuery(query);
	    if (!legacy) {
	      for (_i = 0, _len = candidates.length; _i < _len; _i++) {
	        candidate = candidates[_i];
	        string = bKey ? candidate[key] : candidate;
	        if (!string) {
	          continue;
	        }
	        score = scorer.score(string, query, prepQuery, bAllowErrors);
	        if (score > 0) {
	          scoredCandidates.push({
	            candidate: candidate,
	            score: score
	          });
	          if (!--spotLeft) {
	            break;
	          }
	        }
	      }
	    } else {
	      queryHasSlashes = prepQuery.depth > 0;
	      coreQuery = prepQuery.core;
	      for (_j = 0, _len1 = candidates.length; _j < _len1; _j++) {
	        candidate = candidates[_j];
	        string = key != null ? candidate[key] : candidate;
	        if (!string) {
	          continue;
	        }
	        score = legacy_scorer.score(string, coreQuery, queryHasSlashes);
	        if (!queryHasSlashes) {
	          score = legacy_scorer.basenameScore(string, coreQuery, score);
	        }
	        if (score > 0) {
	          scoredCandidates.push({
	            candidate: candidate,
	            score: score
	          });
	        }
	      }
	    }
	    scoredCandidates.sort(sortCandidates);
	    candidates = scoredCandidates.map(pluckCandidates);
	    if (maxResults != null) {
	      candidates = candidates.slice(0, maxResults);
	    }
	    return candidates;
	  };
	
	}).call(this);


/***/ },
/* 307 */
/***/ function(module, exports, __webpack_require__) {

	(function() {
	  var PathSeparator, scorer;
	
	  PathSeparator = __webpack_require__(303).sep;
	
	  scorer = __webpack_require__(302);
	
	  exports.basenameMatch = function(subject, subject_lw, prepQuery) {
	    var basePos, depth, end;
	    end = subject.length - 1;
	    while (subject[end] === PathSeparator) {
	      end--;
	    }
	    basePos = subject.lastIndexOf(PathSeparator, end);
	    if (basePos === -1) {
	      return [];
	    }
	    depth = prepQuery.depth;
	    while (depth-- > 0) {
	      basePos = subject.lastIndexOf(PathSeparator, basePos - 1);
	      if (basePos === -1) {
	        return [];
	      }
	    }
	    basePos++;
	    end++;
	    return exports.match(subject.slice(basePos, end), subject_lw.slice(basePos, end), prepQuery, basePos);
	  };
	
	  exports.mergeMatches = function(a, b) {
	    var ai, bj, i, j, m, n, out;
	    m = a.length;
	    n = b.length;
	    if (n === 0) {
	      return a.slice();
	    }
	    if (m === 0) {
	      return b.slice();
	    }
	    i = -1;
	    j = 0;
	    bj = b[j];
	    out = [];
	    while (++i < m) {
	      ai = a[i];
	      while (bj <= ai && ++j < n) {
	        if (bj < ai) {
	          out.push(bj);
	        }
	        bj = b[j];
	      }
	      out.push(ai);
	    }
	    while (j < n) {
	      out.push(b[j++]);
	    }
	    return out;
	  };
	
	  exports.match = function(subject, subject_lw, prepQuery, offset) {
	    var DIAGONAL, LEFT, STOP, UP, acro_score, align, backtrack, csc_diag, csc_row, csc_score, i, j, m, matches, move, n, pos, query, query_lw, score, score_diag, score_row, score_up, si_lw, start, trace;
	    if (offset == null) {
	      offset = 0;
	    }
	    query = prepQuery.query;
	    query_lw = prepQuery.query_lw;
	    m = subject.length;
	    n = query.length;
	    acro_score = scorer.scoreAcronyms(subject, subject_lw, query, query_lw).score;
	    score_row = new Array(n);
	    csc_row = new Array(n);
	    STOP = 0;
	    UP = 1;
	    LEFT = 2;
	    DIAGONAL = 3;
	    trace = new Array(m * n);
	    pos = -1;
	    j = -1;
	    while (++j < n) {
	      score_row[j] = 0;
	      csc_row[j] = 0;
	    }
	    i = -1;
	    while (++i < m) {
	      score = 0;
	      score_up = 0;
	      csc_diag = 0;
	      si_lw = subject_lw[i];
	      j = -1;
	      while (++j < n) {
	        csc_score = 0;
	        align = 0;
	        score_diag = score_up;
	        if (query_lw[j] === si_lw) {
	          start = scorer.isWordStart(i, subject, subject_lw);
	          csc_score = csc_diag > 0 ? csc_diag : scorer.scoreConsecutives(subject, subject_lw, query, query_lw, i, j, start);
	          align = score_diag + scorer.scoreCharacter(i, j, start, acro_score, csc_score);
	        }
	        score_up = score_row[j];
	        csc_diag = csc_row[j];
	        if (score > score_up) {
	          move = LEFT;
	        } else {
	          score = score_up;
	          move = UP;
	        }
	        if (align > score) {
	          score = align;
	          move = DIAGONAL;
	        } else {
	          csc_score = 0;
	        }
	        score_row[j] = score;
	        csc_row[j] = csc_score;
	        trace[++pos] = score > 0 ? move : STOP;
	      }
	    }
	    i = m - 1;
	    j = n - 1;
	    pos = i * n + j;
	    backtrack = true;
	    matches = [];
	    while (backtrack && i >= 0 && j >= 0) {
	      switch (trace[pos]) {
	        case UP:
	          i--;
	          pos -= n;
	          break;
	        case LEFT:
	          j--;
	          pos--;
	          break;
	        case DIAGONAL:
	          matches.push(i + offset);
	          j--;
	          i--;
	          pos -= n + 1;
	          break;
	        default:
	          backtrack = false;
	      }
	    }
	    matches.reverse();
	    return matches;
	  };
	
	}).call(this);


/***/ },
/* 308 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 309 */,
/* 310 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * This file maps the SVG React Components in the public/images directory.
	 */
	var Svg = __webpack_require__(311);
	module.exports = Svg;

/***/ },
/* 311 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var InlineSVG = __webpack_require__(312);
	
	var svg = {
	  "angle-brackets": __webpack_require__(313),
	  "arrow": __webpack_require__(314),
	  "blackBox": __webpack_require__(315),
	  "breakpoint": __webpack_require__(316),
	  "close": __webpack_require__(317),
	  "domain": __webpack_require__(318),
	  "file": __webpack_require__(319),
	  "folder": __webpack_require__(320),
	  "globe": __webpack_require__(321),
	  "magnifying-glass": __webpack_require__(322),
	  "pause": __webpack_require__(323),
	  "pause-exceptions": __webpack_require__(324),
	  "plus": __webpack_require__(325),
	  "prettyPrint": __webpack_require__(326),
	  "resume": __webpack_require__(327),
	  "settings": __webpack_require__(328),
	  "stepIn": __webpack_require__(329),
	  "stepOut": __webpack_require__(330),
	  "stepOver": __webpack_require__(331),
	  "subSettings": __webpack_require__(332),
	  "toggleBreakpoints": __webpack_require__(333),
	  "worker": __webpack_require__(334),
	  "sad-face": __webpack_require__(335)
	};
	
	module.exports = function (name, props) {
	  // eslint-disable-line
	  if (!svg[name]) {
	    throw new Error("Unknown SVG: " + name);
	  }
	  var className = name;
	  if (props && props.className) {
	    className = `${ name } ${ props.className }`;
	  }
	  if (name === "subSettings") {
	    className = "";
	  }
	  props = Object.assign({}, props, { className, src: svg[name] });
	  return React.createElement(InlineSVG, props);
	};

/***/ },
/* 312 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';
	
	Object.defineProperty(exports, '__esModule', {
	    value: true
	});
	
	var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
	
	var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
	
	var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
	
	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
	
	function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
	
	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
	
	function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
	
	var _react = __webpack_require__(2);
	
	var _react2 = _interopRequireDefault(_react);
	
	var DOMParser = typeof window !== 'undefined' && window.DOMParser;
	var process = process || {};
	process.env = process.env || {};
	var parserAvailable = typeof DOMParser !== 'undefined' && DOMParser.prototype != null && DOMParser.prototype.parseFromString != null;
	
	if ("production" !== process.env.NODE_ENV && !parserAvailable) {
	    console.info('<InlineSVG />: `raw` prop works only when `window.DOMParser` exists.');
	}
	
	function isParsable(src) {
	    // kinda naive but meh, ain't gonna use full-blown parser for this
	    return parserAvailable && typeof src === 'string' && src.trim().substr(0, 4) === '<svg';
	}
	
	// parse SVG string using `DOMParser`
	function parseFromSVGString(src) {
	    var parser = new DOMParser();
	    return parser.parseFromString(src, "image/svg+xml");
	}
	
	// Transform DOM prop/attr names applicable to `<svg>` element but react-limited
	function switchSVGAttrToReactProp(propName) {
	    switch (propName) {
	        case 'class':
	            return 'className';
	        default:
	            return propName;
	    }
	}
	
	var InlineSVG = (function (_React$Component) {
	    _inherits(InlineSVG, _React$Component);
	
	    _createClass(InlineSVG, null, [{
	        key: 'defaultProps',
	        value: {
	            element: 'i',
	            raw: false,
	            src: ''
	        },
	        enumerable: true
	    }, {
	        key: 'propTypes',
	        value: {
	            src: _react2['default'].PropTypes.string.isRequired,
	            element: _react2['default'].PropTypes.string,
	            raw: _react2['default'].PropTypes.bool
	        },
	        enumerable: true
	    }]);
	
	    function InlineSVG(props) {
	        _classCallCheck(this, InlineSVG);
	
	        _get(Object.getPrototypeOf(InlineSVG.prototype), 'constructor', this).call(this, props);
	        this._extractSVGProps = this._extractSVGProps.bind(this);
	    }
	
	    // Serialize `Attr` objects in `NamedNodeMap`
	
	    _createClass(InlineSVG, [{
	        key: '_serializeAttrs',
	        value: function _serializeAttrs(map) {
	            var ret = {};
	            var prop = undefined;
	            for (var i = 0; i < map.length; i++) {
	                prop = switchSVGAttrToReactProp(map[i].name);
	                ret[prop] = map[i].value;
	            }
	            return ret;
	        }
	
	        // get <svg /> element props
	    }, {
	        key: '_extractSVGProps',
	        value: function _extractSVGProps(src) {
	            var map = parseFromSVGString(src).documentElement.attributes;
	            return map.length > 0 ? this._serializeAttrs(map) : null;
	        }
	
	        // get content inside <svg> element.
	    }, {
	        key: '_stripSVG',
	        value: function _stripSVG(src) {
	            return parseFromSVGString(src).documentElement.innerHTML;
	        }
	    }, {
	        key: 'componentWillReceiveProps',
	        value: function componentWillReceiveProps(_ref) {
	            var children = _ref.children;
	
	            if ("production" !== process.env.NODE_ENV && children != null) {
	                console.info('<InlineSVG />: `children` prop will be ignored.');
	            }
	        }
	    }, {
	        key: 'render',
	        value: function render() {
	            var Element = undefined,
	                __html = undefined,
	                svgProps = undefined;
	            var _props = this.props;
	            var element = _props.element;
	            var raw = _props.raw;
	            var src = _props.src;
	
	            var otherProps = _objectWithoutProperties(_props, ['element', 'raw', 'src']);
	
	            if (raw === true && isParsable(src)) {
	                Element = 'svg';
	                svgProps = this._extractSVGProps(src);
	                __html = this._stripSVG(src);
	            }
	            __html = __html || src;
	            Element = Element || element;
	            svgProps = svgProps || {};
	
	            return _react2['default'].createElement(Element, _extends({}, svgProps, otherProps, { src: null, children: null,
	                dangerouslySetInnerHTML: { __html: __html } }));
	        }
	    }]);
	
	    return InlineSVG;
	})(_react2['default'].Component);
	
	exports['default'] = InlineSVG;
	module.exports = exports['default'];

/***/ },
/* 313 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"-1 73 16 11\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"Shape-Copy-3-+-Shape-Copy-4\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(0.000000, 74.000000)\"><path d=\"M0.749321284,4.16081709 L4.43130681,0.242526751 C4.66815444,-0.00952143591 5.06030999,-0.0211407611 5.30721074,0.216574262 C5.55411149,0.454289284 5.56226116,0.851320812 5.32541353,1.103369 L1.95384971,4.69131519 L5.48809879,8.09407556 C5.73499955,8.33179058 5.74314922,8.72882211 5.50630159,8.9808703 C5.26945396,9.23291849 4.87729841,9.24453781 4.63039766,9.00682279 L0.827097345,5.34502101 C0.749816996,5.31670099 0.677016974,5.27216098 0.613753508,5.21125118 C0.427367989,5.03179997 0.377040713,4.7615583 0.465458792,4.53143559 C0.492371834,4.43667624 0.541703274,4.34676528 0.613628034,4.27022448 C0.654709457,4.22650651 0.70046335,4.19002189 0.749321284,4.16081709 Z\" id=\"Shape-Copy-3\" stroke=\"#FFFFFF\" stroke-width=\"0.05\" fill=\"#DDE1E4\"></path><path d=\"M13.7119065,5.44453032 L9.77062746,9.09174784 C9.51677479,9.3266604 9.12476399,9.31089603 8.89504684,9.05653714 C8.66532968,8.80217826 8.68489539,8.40554539 8.93874806,8.17063283 L12.5546008,4.82456128 L9.26827469,1.18571135 C9.03855754,0.931352463 9.05812324,0.534719593 9.31197591,0.299807038 C9.56582858,0.0648944831 9.95783938,0.0806588502 10.1875565,0.335017737 L13.72891,4.25625178 C13.8013755,4.28980469 13.8684335,4.3382578 13.9254821,4.40142604 C14.0883019,4.58171146 14.1258883,4.83347168 14.0435812,5.04846202 C14.0126705,5.15680232 13.9526426,5.2583679 13.8641331,5.34027361 C13.8174417,5.38348136 13.7660763,5.41820853 13.7119065,5.44453032 Z\" id=\"Shape-Copy-4\" stroke=\"#FFFFFF\" stroke-width=\"0.05\" fill=\"#DDE1E4\"></path></g></svg>"

/***/ },
/* 314 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 16 16\"><path d=\"M8 13.4c-.5 0-.9-.2-1.2-.6L.4 5.2C0 4.7-.1 4.3.2 3.7S1 3 1.6 3h12.8c.6 0 1.2.1 1.4.7.3.6.2 1.1-.2 1.6l-6.4 7.6c-.3.4-.7.5-1.2.5z\"></path></svg>"

/***/ },
/* 315 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><circle cx=\"8\" cy=\"8.5\" r=\"1.5\"></circle><path d=\"M15.498 8.28l-.001-.03v-.002-.004l-.002-.018-.004-.031c0-.002 0-.002 0 0l-.004-.035.006.082c-.037-.296-.133-.501-.28-.661-.4-.522-.915-1.042-1.562-1.604-1.36-1.182-2.74-1.975-4.178-2.309a6.544 6.544 0 0 0-2.755-.042c-.78.153-1.565.462-2.369.91C3.252 5.147 2.207 6 1.252 7.035c-.216.233-.36.398-.499.577-.338.437-.338 1 0 1.437.428.552.941 1.072 1.59 1.635 1.359 1.181 2.739 1.975 4.177 2.308.907.21 1.829.223 2.756.043.78-.153 1.564-.462 2.369-.91 1.097-.612 2.141-1.464 3.097-2.499.217-.235.36-.398.498-.578.12-.128.216-.334.248-.554 0 .01 0 .01-.008.04l.013-.079-.001.011.003-.031.001-.017v.005l.001-.02v.008l.002-.03.001-.05-.001-.044v-.004-.004zm-.954.045v.007l.001.004V8.33v.012l-.001.01v-.005-.005l.002-.015-.001.008c-.002.014-.002.014 0 0l-.007.084c.003-.057-.004-.041-.014-.031-.143.182-.27.327-.468.543-.89.963-1.856 1.752-2.86 2.311-.724.404-1.419.677-2.095.81a5.63 5.63 0 0 1-2.374-.036c-1.273-.295-2.523-1.014-3.774-2.101-.604-.525-1.075-1.001-1.457-1.496-.054-.07-.054-.107 0-.177.117-.152.244-.298.442-.512.89-.963 1.856-1.752 2.86-2.311.724-.404 1.419-.678 2.095-.81a5.631 5.631 0 0 1 2.374.036c1.272.295 2.523 1.014 3.774 2.101.603.524 1.074 1 1.457 1.496.035.041.043.057.046.076 0 .01 0 .01.008.043l-.009-.047.003.02-.002-.013v-.008.016c0-.004 0-.004 0 0v-.004z\"></path></g></svg>"

/***/ },
/* 316 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 60 12\"><path id=\"base-path\" d=\"M53.9,0H1C0.4,0,0,0.4,0,1v10c0,0.6,0.4,1,1,1h52.9c0.6,0,1.2-0.3,1.5-0.7L60,6l-4.4-5.3C55,0.3,54.5,0,53.9,0z\"></path></svg>"

/***/ },
/* 317 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 6 6\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><path d=\"M1.35191454,5.27895256 L5.31214367,1.35518468 C5.50830675,1.16082764 5.50977084,0.844248536 5.3154138,0.648085456 C5.12105677,0.451922377 4.80447766,0.450458288 4.60831458,0.644815324 L0.648085456,4.56858321 C0.451922377,4.76294025 0.450458288,5.07951935 0.644815324,5.27568243 C0.83917236,5.47184551 1.15575146,5.4733096 1.35191454,5.27895256 L1.35191454,5.27895256 Z\" id=\"Line\" stroke=\"none\" fill=\"#696969\" fill-rule=\"evenodd\"></path><path d=\"M5.31214367,4.56858321 L1.35191454,0.644815324 C1.15575146,0.450458288 0.83917236,0.451922377 0.644815324,0.648085456 C0.450458288,0.844248536 0.451922377,1.16082764 0.648085456,1.35518468 L4.60831458,5.27895256 C4.80447766,5.4733096 5.12105677,5.47184551 5.3154138,5.27568243 C5.50977084,5.07951935 5.50830675,4.76294025 5.31214367,4.56858321 L5.31214367,4.56858321 Z\" id=\"Line-Copy-2\" stroke=\"none\" fill=\"#696969\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 318 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.05 4.634l-2.144.003-.116.116v1.445l.92.965.492.034.116-.116v-.617L9.13 5.7l.035-.95M12.482 10.38l-1.505-1.462H9.362l-.564.516-.034 1.108.72.768 1.323.034-.117-.116v1.2l.972 1.02.315.034.116-.116v-1.154l.422-.374.034-.927-.117.117h.26l.408-.36V10.5l-.125-.124-.575-.033\"></path><path d=\"M8.47 15.073c-3.088 0-5.6-2.513-5.6-5.602V9.4v-.003c0-.018 0-.018.002-.034l.182-.088.724.587.49.033.497.543-.034.9.317.383h.47l.114.096-.032 1.9.524.553h.105l.025-.338 1.004-.95.054-.474.53-.462v-.888l-.588-.038-1.118-1.155H4.48l-.154-.09V9.01l.155-.1h1.164v-.273l.12-.115.7.033.494-.443.034-.746-.624-.655h-.724v.28l-.11.07H4.64l-.114-.09.025-.64.48-.43v-.244h-.382c-.102 0-.152-.128-.08-.2 1.04-1.01 2.428-1.59 3.903-1.59 1.374 0 2.672.5 3.688 1.39.08.068.03.198-.075.198l-1.144-.034-.81.803.52.523v.16l-.382.388h-.158l-.176-.177v-.16l.076-.074-.252-.252-.37.362.53.53c.072.072.005.194-.096.194l-.752-.005v.844h.783L9.885 8l.16-.143h.16l.62.61v.267l.58.027.003.002V8.76l.18-.03 1.234 1.24.753-.708h.382l.116.108c0 .02.003.016.003.036v.065c0 3.09-2.515 5.603-5.605 5.603M8.47 3C4.904 3 2 5.903 2 9.47c0 3.57 2.903 6.472 6.47 6.472 3.57 0 6.472-2.903 6.472-6.47C14.942 5.9 12.04 3 8.472 3\"></path></svg>"

/***/ },
/* 319 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4 2v12h9V4.775L9.888 2H4zm0-1h5.888c.246 0 .483.09.666.254l3.112 2.774c.212.19.334.462.334.747V14c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V2c0-.552.448-1 1-1z\"></path><path d=\"M9 1.5v4c0 .325.306.564.62.485l4-1c.27-.067.432-.338.365-.606-.067-.27-.338-.432-.606-.365l-4 1L10 5.5v-4c0-.276-.224-.5-.5-.5s-.5.224-.5.5z\"></path></svg>"

/***/ },
/* 320 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2 5.193v7.652c0 .003-.002 0 .007 0H14v-7.69c0-.003.002 0-.007 0h-7.53v-2.15c0-.002-.004-.005-.01-.005H2.01C2 3 2 3 2 3.005V5.193zm-1 0V3.005C1 2.45 1.444 2 2.01 2h4.442c.558 0 1.01.45 1.01 1.005v1.15h6.53c.557 0 1.008.44 1.008 1v7.69c0 .553-.45 1-1.007 1H2.007c-.556 0-1.007-.44-1.007-1V5.193zM6.08 4.15H2v1h4.46v-1h-.38z\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 321 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"14 6 13 12\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><g id=\"world\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(14.000000, 6.000000)\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6.35076107,0.354 C3.25095418,0.354 0.729,2.87582735 0.729,5.9758879 C0.729,9.07544113 3.25082735,11.5972685 6.35076107,11.5972685 C9.45044113,11.5972685 11.9723953,9.07544113 11.9723953,5.97576107 C11.9723953,2.87582735 9.45044113,0.354 6.35076107,0.354 L6.35076107,0.354 Z M6.35076107,10.8289121 C3.67445071,10.8289121 1.49722956,8.65181776 1.49722956,5.97576107 C1.49722956,5.9443064 1.49900522,5.91335907 1.49976622,5.88215806 L2.20090094,6.4213266 L2.56313696,6.4213266 L2.97268183,6.8306178 L2.97268183,7.68217686 L3.32324919,8.03287105 L3.73926255,8.03287105 L3.73926255,9.79940584 L4.27386509,10.3361645 L4.4591686,10.3361645 L4.4591686,10.000183 L5.37655417,9.08343163 L5.37655417,8.73400577 L5.85585737,8.25203907 L5.85585737,7.37206934 L5.32518666,7.37206934 L4.28439226,6.33140176 L2.82225748,6.33140176 L2.82225748,5.56938704 L3.96286973,5.56938704 L3.96286973,5.23949352 L4.65068695,5.23949352 L5.11477015,4.77667865 L5.11477015,4.03001076 L4.49087694,3.40662489 L3.75359472,3.40662489 L3.75359472,3.78725175 L2.96228149,3.78725175 L2.96228149,3.28385021 L3.42217919,2.82319151 L3.42217919,2.49786399 L2.97001833,2.49786399 C3.84466106,1.64744643 5.03714814,1.12222956 6.35063424,1.12222956 C7.57292716,1.12222956 8.69020207,1.57730759 9.54442463,2.32587797 L8.46164839,2.32587797 L7.680355,3.10666403 L8.21508437,3.64088607 L7.87238068,3.98257509 L7.7165025,3.82669692 L7.85297518,3.68946324 L7.78930484,3.62566607 L7.78943167,3.62566607 L7.56011699,3.39559038 L7.55986332,3.39571722 L7.49758815,3.33318838 L7.01904595,3.78585658 L7.55910232,4.32654712 L6.8069806,4.32198112 L6.8069806,5.25864535 L7.66716433,5.25864535 L7.6723645,4.72112565 L7.81289584,4.57996014 L8.31819988,5.08653251 L8.31819988,5.41921636 L9.00703176,5.41921636 L9.03366676,5.39321553 L9.03430093,5.39194719 L10.195587,6.55259911 L10.8637451,5.88520206 L11.2018828,5.88520206 C11.2023901,5.9153884 11.2041658,5.94532107 11.2041658,5.97563424 C11.2040389,8.65181776 9.0269446,10.8289121 6.35076107,10.8289121 L6.35076107,10.8289121 Z\" id=\"Shape\" stroke=\"#DDE1E5\" stroke-width=\"0.25\" fill=\"#DDE1E5\"></path><polygon id=\"Shape\" stroke=\"#DDE1E5\" stroke-width=\"0.25\" fill=\"#DDE1E5\" points=\"6.50676608 1.61523076 4.52892694 1.61789426 4.52892694 2.95192735 5.34560683 3.76733891 5.72496536 3.76733891 5.72496536 3.1967157 6.50676608 2.41592965\"></polygon><polygon id=\"Shape\" stroke=\"#DDE1E5\" stroke-width=\"0.25\" fill=\"#DDE1E5\" points=\"9.59959714 6.88718547 8.28623788 5.57268471 8.28623788 5.57002121 6.79607294 5.57002121 6.35101474 6.01469891 6.35101474 6.96201714 6.98429362 7.59466185 8.12909136 7.59466185 8.12909136 8.70343893 8.99434843 9.56882283 9.20971144 9.56882283 9.20971144 8.50329592 9.63029081 8.08271655 9.63029081 7.3026915 9.87025949 7.3026915 10.1711082 7.00082814 10.0558167 6.88718547\"></polygon></g></svg>"

/***/ },
/* 322 */
/***/ function(module, exports) {

	module.exports = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path class=\"st0\" d=\"M9 9.3l3.6 3.6\"></path><ellipse fill=\"transparent\" cx=\"5.9\" cy=\"6.2\" rx=\"4.5\" ry=\"4.5\"></ellipse></svg>"

/***/ },
/* 323 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M6.5 12.003l.052-9a.5.5 0 1 0-1-.006l-.052 9a.5.5 0 1 0 1 .006zM13 11.997l-.05-9a.488.488 0 0 0-.477-.497.488.488 0 0 0-.473.503l.05 9a.488.488 0 0 0 .477.497.488.488 0 0 0 .473-.503z\"></path></g></svg>"

/***/ },
/* 324 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.483 13.995H5.517l-3.512-3.512V5.516l3.512-3.512h4.966l3.512 3.512v4.967l-3.512 3.512zm4.37-9.042l-3.807-3.805A.503.503 0 0 0 10.691 1H5.309a.503.503 0 0 0-.356.148L1.147 4.953A.502.502 0 0 0 1 5.308v5.383c0 .134.053.262.147.356l3.806 3.806a.503.503 0 0 0 .356.147h5.382a.503.503 0 0 0 .355-.147l3.806-3.806A.502.502 0 0 0 15 10.69V5.308a.502.502 0 0 0-.147-.355z\"></path><path d=\"M10 10.5a.5.5 0 1 0 1 0v-5a.5.5 0 1 0-1 0v5zM5 10.5a.5.5 0 1 0 1 0v-5a.5.5 0 0 0-1 0v5z\"></path></svg>"

/***/ },
/* 325 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M8.5 8.5V14a.5.5 0 1 1-1 0V8.5H2a.5.5 0 0 1 0-1h5.5V2a.5.5 0 0 1 1 0v5.5H14a.5.5 0 1 1 0 1H8.5z\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 326 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.525 13.21h-.472c-.574 0-.987-.154-1.24-.463-.253-.31-.38-.882-.38-1.719v-.573c0-.746-.097-1.265-.292-1.557-.196-.293-.51-.44-.945-.44v-.974c.435 0 .75-.146.945-.44.195-.292.293-.811.293-1.556v-.58c0-.833.126-1.404.379-1.712.253-.31.666-.464 1.24-.464h.472v.783h-.179c-.37 0-.628.08-.774.24-.145.159-.218.54-.218 1.141v.383c0 .824-.096 1.432-.287 1.823-.191.39-.516.679-.974.866.458.191.783.482.974.873.191.39.287.998.287 1.823v.382c0 .602.073.982.218 1.142.146.16.404.239.774.239h.18v.783zm9.502-4.752c-.43 0-.744.147-.942.44-.197.292-.296.811-.296 1.557v.573c0 .837-.125 1.41-.376 1.719-.251.309-.664.463-1.237.463h-.478v-.783h.185c.37 0 .628-.08.774-.24.145-.159.218-.539.218-1.14v-.383c0-.825.096-1.433.287-1.823.191-.39.516-.682.974-.873-.458-.187-.783-.476-.974-.866-.191-.391-.287-.999-.287-1.823v-.383c0-.602-.073-.982-.218-1.142-.146-.159-.404-.239-.774-.239h-.185v-.783h.478c.573 0 .986.155 1.237.464.25.308.376.88.376 1.712v.58c0 .673.088 1.174.263 1.503.176.329.5.493.975.493v.974z\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 327 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.925 12.5l7.4-5-7.4-5v10zM6 12.5v-10c0-.785.8-1.264 1.415-.848l7.4 5c.58.392.58 1.304 0 1.696l-7.4 5C6.8 13.764 6 13.285 6 12.5z\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 328 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 33 12\"><path id=\"base-path\" d=\"M27.1,0H1C0.4,0,0,0.4,0,1v10c0,0.6,0.4,1,1,1h26.1 c0.6,0,1.2-0.3,1.5-0.7L33,6l-4.4-5.3C28.2,0.3,27.7,0,27.1,0z\"></path></svg>"

/***/ },
/* 329 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M1.5 14.042h4.095a.5.5 0 0 0 0-1H1.5a.5.5 0 1 0 0 1zM7.983 2a.5.5 0 0 1 .517.5v7.483l3.136-3.326a.5.5 0 1 1 .728.686l-4 4.243a.499.499 0 0 1-.73-.004L3.635 7.343a.5.5 0 0 1 .728-.686L7.5 9.983V3H1.536C1.24 3 1 2.776 1 2.5s.24-.5.536-.5h6.447zM10.5 14.042h4.095a.5.5 0 0 0 0-1H10.5a.5.5 0 1 0 0 1z\"></path></g></svg>"

/***/ },
/* 330 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M5 13.5H1a.5.5 0 1 0 0 1h4a.5.5 0 1 0 0-1zM12 13.5H8a.5.5 0 1 0 0 1h4a.5.5 0 1 0 0-1zM6.11 5.012A.427.427 0 0 1 6.21 5h7.083L9.646 1.354a.5.5 0 1 1 .708-.708l4.5 4.5a.498.498 0 0 1 0 .708l-4.5 4.5a.5.5 0 0 1-.708-.708L13.293 6H6.5v5.5a.5.5 0 1 1-1 0v-6a.5.5 0 0 1 .61-.488z\"></path></g></svg>"

/***/ },
/* 331 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M13.297 6.912C12.595 4.39 10.167 2.5 7.398 2.5A5.898 5.898 0 0 0 1.5 8.398a.5.5 0 0 0 1 0A4.898 4.898 0 0 1 7.398 3.5c2.75 0 5.102 2.236 5.102 4.898v.004L8.669 7.029a.5.5 0 0 0-.338.942l4.462 1.598a.5.5 0 0 0 .651-.34.506.506 0 0 0 .02-.043l2-5a.5.5 0 1 0-.928-.372l-1.24 3.098z\"></path><circle cx=\"7\" cy=\"12\" r=\"1\"></circle></g></svg>"

/***/ },
/* 332 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.219 7c.345 0 .635.117.869.352.234.234.351.524.351.869 0 .351-.118.652-.356.903-.238.25-.526.376-.864.376-.332 0-.615-.125-.85-.376a1.276 1.276 0 0 1-.351-.903A1.185 1.185 0 0 1 12.218 7zM8.234 7c.345 0 .635.117.87.352.234.234.351.524.351.869 0 .351-.119.652-.356.903-.238.25-.526.376-.865.376-.332 0-.613-.125-.844-.376a1.286 1.286 0 0 1-.347-.903c0-.352.114-.643.342-.874.228-.231.51-.347.85-.347zM4.201 7c.339 0 .627.117.864.352.238.234.357.524.357.869 0 .351-.119.652-.357.903-.237.25-.525.376-.864.376-.338 0-.623-.125-.854-.376A1.286 1.286 0 0 1 3 8.221 1.185 1.185 0 0 1 4.201 7z\" fill-rule=\"evenodd\"></path></svg>"

/***/ },
/* 333 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><g fill-rule=\"evenodd\"><path d=\"M3.233 11.25l-.417 1H1.712C.763 12.25 0 11.574 0 10.747V6.503C0 5.675.755 5 1.712 5h4.127l-.417 1H1.597C1.257 6 1 6.225 1 6.503v4.244c0 .277.267.503.597.503h1.636zM7.405 11.27L7 12.306c.865.01 2.212-.024 2.315-.04.112-.016.112-.016.185-.035.075-.02.156-.046.251-.082.152-.056.349-.138.592-.244.415-.182.962-.435 1.612-.744l.138-.066a179.35 179.35 0 0 0 2.255-1.094c1.191-.546 1.191-2.074-.025-2.632l-.737-.34a3547.554 3547.554 0 0 0-3.854-1.78c-.029.11-.065.222-.11.336l-.232.596c.894.408 4.56 2.107 4.56 2.107.458.21.458.596 0 .806L9.197 11.27H7.405zM4.462 14.692l5-12a.5.5 0 1 0-.924-.384l-5 12a.5.5 0 1 0 .924.384z\"></path></g></svg>"

/***/ },
/* 334 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" d=\"M8.5 8.793L5.854 6.146l-.04-.035L7.5 4.426c.2-.2.3-.4.3-.6 0-.2-.1-.4-.2-.6l-1-1c-.4-.3-.9-.3-1.2 0l-4.1 4.1c-.2.2-.3.4-.3.6 0 .2.1.4.2.6l1 1c.3.3.9.3 1.2 0l1.71-1.71.036.04L7.793 9.5l-3.647 3.646c-.195.196-.195.512 0 .708.196.195.512.195.708 0L8.5 10.207l3.646 3.647c.196.195.512.195.708 0 .195-.196.195-.512 0-.708L9.207 9.5l2.565-2.565L13.3 8.5c.1.1 2.3 1.1 2.7.7.4-.4-.3-2.7-.5-2.9l-1.1-1.1c.1-.1.2-.4.2-.6 0-.2-.1-.4-.2-.6l-.4-.4c-.3-.3-.8-.3-1.1 0l-1.5-1.4c-.2-.2-.3-.2-.5-.2s-.3.1-.5.2L9.2 3.4c-.2.1-.2.2-.2.4s.1.4.2.5l1.874 1.92L8.5 8.792z\"></path></svg>"

/***/ },
/* 335 */
/***/ function(module, exports) {

	module.exports = "<!-- This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --><svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" fill=\"#D92215\"><path d=\"M8 14.5c-3.6 0-6.5-2.9-6.5-6.5S4.4 1.5 8 1.5s6.5 2.9 6.5 6.5-2.9 6.5-6.5 6.5zm0-12C5 2.5 2.5 5 2.5 8S5 13.5 8 13.5 13.5 11 13.5 8 11 2.5 8 2.5z\"></path><circle cx=\"5\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><circle cx=\"9\" cy=\"6\" r=\"1\" transform=\"translate(1 1)\"></circle><path d=\"M5.5 11c-.1 0-.2 0-.3-.1-.2-.1-.3-.4-.1-.7C6 9 7 8.5 8.1 8.5c1.7.1 2.8 1.7 2.8 1.8.2.2.1.5-.1.7-.2.1-.6 0-.7-.2 0 0-.9-1.3-2-1.3-.7 0-1.4.4-2.1 1.3-.2.2-.4.2-.5.2z\"></path></svg>"

/***/ },
/* 336 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var Svg = __webpack_require__(310);
	
	__webpack_require__(337);
	
	function CloseButton(_ref) {
	  var handleClick = _ref.handleClick;
	  var buttonClass = _ref.buttonClass;
	
	  return dom.div({
	    className: buttonClass ? "close-btn-" + buttonClass : "close-btn",
	    onClick: handleClick
	  }, Svg("close"));
	}
	
	CloseButton.propTypes = {
	  handleClick: PropTypes.func.isRequired
	};
	
	module.exports = CloseButton;

/***/ },
/* 337 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 338 */,
/* 339 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var ImPropTypes = __webpack_require__(235);
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	
	var _require2 = __webpack_require__(19);
	
	var connect = _require2.connect;
	
	var _require3 = __webpack_require__(261);
	
	var cmdString = _require3.cmdString;
	
	var SourcesTree = React.createFactory(__webpack_require__(340));
	var actions = __webpack_require__(262);
	
	var _require4 = __webpack_require__(259);
	
	var getSelectedSource = _require4.getSelectedSource;
	var getSources = _require4.getSources;
	
	
	__webpack_require__(398);
	
	var Sources = React.createClass({
	  propTypes: {
	    sources: ImPropTypes.map.isRequired,
	    selectSource: PropTypes.func.isRequired
	  },
	
	  displayName: "Sources",
	
	  render() {
	    var _props = this.props;
	    var sources = _props.sources;
	    var selectSource = _props.selectSource;
	
	
	    return dom.div({ className: "sources-panel" }, dom.div({ className: "sources-header" }, L10N.getStr("sources.header"), dom.span({ className: "sources-header-info" }, L10N.getFormatStr("sources.search", cmdString() + "+P"))), SourcesTree({ sources, selectSource }));
	  }
	});
	
	module.exports = connect(state => ({ selectedSource: getSelectedSource(state),
	  sources: getSources(state) }), dispatch => bindActionCreators(actions, dispatch))(Sources);

/***/ },
/* 340 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var classnames = __webpack_require__(211);
	var ImPropTypes = __webpack_require__(235);
	
	var _require = __webpack_require__(229);
	
	var Set = _require.Set;
	
	var _require2 = __webpack_require__(341);
	
	var nodeHasChildren = _require2.nodeHasChildren;
	var createParentMap = _require2.createParentMap;
	var addToTree = _require2.addToTree;
	var collapseTree = _require2.collapseTree;
	var createTree = _require2.createTree;
	
	var ManagedTree = React.createFactory(__webpack_require__(394));
	var Svg = __webpack_require__(310);
	
	var _require3 = __webpack_require__(244);
	
	var throttle = _require3.throttle;
	
	
	var SourcesTree = React.createClass({
	  propTypes: {
	    sources: ImPropTypes.map.isRequired,
	    selectSource: PropTypes.func.isRequired
	  },
	
	  displayName: "SourcesTree",
	
	  getInitialState() {
	    return createTree(this.props.sources);
	  },
	
	  queueUpdate: throttle(function () {
	    if (!this.isMounted()) {
	      return;
	    }
	
	    this.forceUpdate();
	  }, 50),
	
	  shouldComponentUpdate() {
	    this.queueUpdate();
	    return false;
	  },
	
	  componentWillReceiveProps(nextProps) {
	    if (nextProps.sources === this.props.sources) {
	      return;
	    }
	
	    if (nextProps.sources.size === 0) {
	      this.setState(createTree(nextProps.sources));
	      return;
	    }
	
	    var next = Set(nextProps.sources.valueSeq());
	    var prev = Set(this.props.sources.valueSeq());
	    var newSet = next.subtract(prev);
	
	    var uncollapsedTree = this.state.uncollapsedTree;
	    for (var source of newSet) {
	      addToTree(uncollapsedTree, source);
	    }
	
	    // TODO: recreating the tree every time messes with the expanded
	    // state of ManagedTree, because it depends on item instances
	    // being the same. The result is that if a source is added at a
	    // later time, all expanded state is lost.
	    var sourceTree = newSet.size > 0 ? collapseTree(uncollapsedTree) : this.state.sourceTree;
	
	    this.setState({ uncollapsedTree,
	      sourceTree,
	      parentMap: createParentMap(sourceTree) });
	  },
	
	  focusItem(item) {
	    this.setState({ focusedItem: item });
	  },
	
	  selectItem(item) {
	    if (!nodeHasChildren(item)) {
	      this.props.selectSource(item.contents.get("id"));
	    }
	  },
	
	  getIcon(item, depth) {
	    if (depth === 0) {
	      return Svg("domain");
	    }
	
	    if (!nodeHasChildren(item)) {
	      return Svg("file");
	    }
	
	    return Svg("folder");
	  },
	
	  renderItem(item, depth, focused, _, expanded, _ref) {
	    var setExpanded = _ref.setExpanded;
	
	    var arrow = Svg("arrow", {
	      className: classnames({ expanded: expanded,
	        hidden: !nodeHasChildren(item) }),
	      onClick: e => {
	        e.stopPropagation();
	        setExpanded(item, !expanded);
	      }
	    });
	
	    var icon = this.getIcon(item, depth);
	
	    return dom.div({
	      className: classnames("node", { focused }),
	      style: { paddingLeft: depth * 15 + "px" },
	      key: item.path,
	      onClick: () => this.selectItem(item),
	      onDoubleClick: e => setExpanded(item, !expanded)
	    }, dom.div(null, arrow, icon, item.name));
	  },
	
	  render: function () {
	    var _state = this.state;
	    var focusedItem = _state.focusedItem;
	    var sourceTree = _state.sourceTree;
	    var parentMap = _state.parentMap;
	
        const isEmpty = sourceTree.contents.length === 0;
	
	    var tree = ManagedTree({
          key: isEmpty ? "empty" : "full",
	      getParent: item => {
	        return parentMap.get(item);
	      },
	      getChildren: item => {
	        if (nodeHasChildren(item)) {
	          return item.contents;
	        }
	        return [];
	      },
	      getRoots: () => sourceTree.contents,
	      getKey: (item, i) => item.path,
	      itemHeight: 30,
	      autoExpandDepth: 1,
	      onFocus: this.focusItem,
	      renderItem: this.renderItem
	    });
	
	    return dom.div({
	      className: "sources-list",
	      onKeyDown: e => {
	        if (e.keyCode === 13 && focusedItem) {
	          this.selectItem(focusedItem);
	        }
	      }
	    }, tree);
	  }
	});
	
	module.exports = SourcesTree;

/***/ },
/* 341 */
/***/ function(module, exports, __webpack_require__) {

	
	
	/**
	 * Utils for Sources Tree Component
	 * @module utils/sources-tree
	 */
	
	var _require = __webpack_require__(293);
	
	var parse = _require.parse;
	
	var _require2 = __webpack_require__(246);
	
	var assert = _require2.assert;
	
	var _require3 = __webpack_require__(277);
	
	var isPretty = _require3.isPretty;
	
	var merge = __webpack_require__(342);
	
	var IGNORED_URLS = ["debugger eval code", "XStringBundle"];
	
	/**
	 * Temporary Source type to be used only within this module
	 * TODO: Replace with real Source type definition when refactoring types
	 * @memberof utils/sources-tree
	 * @static
	 */
	
	
	/**
	 * TODO: createNode is exported so this type could be useful to other modules
	 * @memberof utils/sources-tree
	 * @static
	 */
	
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function nodeHasChildren(item) {
	  return Array.isArray(item.contents);
	}
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function createNode(name, path, contents) {
	  return {
	    name,
	    path,
	    contents: contents || null
	  };
	}
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function createParentMap(tree) {
	  var map = new WeakMap();
	
	  function _traverse(subtree) {
	    if (nodeHasChildren(subtree)) {
	      for (var child of subtree.contents) {
	        map.set(child, subtree);
	        _traverse(child);
	      }
	    }
	  }
	
	  // Don't link each top-level path to the "root" node because the
	  // user never sees the root
	  tree.contents.forEach(_traverse);
	  return map;
	}
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function getURL(source) {
	  var url = source.get("url");
	  var def = { path: "", group: "" };
	  if (!url) {
	    return def;
	  }
	
	  var _parse = parse(url);
	
	  var pathname = _parse.pathname;
	  var protocol = _parse.protocol;
	  var host = _parse.host;
	  var path = _parse.path;
	
	
	  switch (protocol) {
	    case "javascript:":
	      // Ignore `javascript:` URLs for now
	      return def;
	
	    case "about:":
	      // An about page is a special case
	      return merge(def, {
	        path: "/",
	        group: url
	      });
	
	    case null:
	      if (pathname && pathname.startsWith("/")) {
	        // If it's just a URL like "/foo/bar.js", resolve it to the file
	        // protocol
	        return merge(def, {
	          path: path,
	          group: "file://"
	        });
	      } else if (host === null) {
	        // We don't know what group to put this under, and it's a script
	        // with a weird URL. Just group them all under an anonymous group.
	        return merge(def, {
	          path: url,
	          group: "(no domain)"
	        });
	      }
	      break;
	
	    case "http:":
	    case "https:":
	      return merge(def, {
	        path: pathname,
	        group: host
	      });
	  }
	
	  return merge(def, {
	    path: path,
	    group: protocol ? protocol + "//" : ""
	  });
	}
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function addToTree(tree, source) {
	  var url = getURL(source);
	
	  if (IGNORED_URLS.indexOf(url) != -1 || !source.get("url") || isPretty(source.toJS())) {
	    return;
	  }
	
	  url.path = decodeURIComponent(url.path);
	
	  var parts = url.path.split("/").filter(p => p !== "");
	  var isDir = parts.length === 0 || parts[parts.length - 1].indexOf(".") === -1;
	  parts.unshift(url.group);
	
	  var path = "";
	  var subtree = tree;
	
	  for (var i = 0; i < parts.length; i++) {
	    var part = parts[i];
	    var isLastPart = i === parts.length - 1;
	
	    // Currently we assume that we are descending into a node with
	    // children. This will fail if a path has a directory named the
	    // same as another file, like `foo/bar.js/file.js`.
	    //
	    // TODO: Be smarter about this, which we'll probably do when we
	    // are smarter about folders and collapsing empty ones.
	    assert(nodeHasChildren(subtree), `${ subtree.name } should have children`);
	    var children = subtree.contents;
	
	    var index = determineFileSortOrder(children, part, isLastPart);
	
	    if (index >= 0 && children[index].name === part) {
	      // A node with the same name already exists, simply traverse
	      // into it.
	      subtree = children[index];
	    } else {
	      // No node with this name exists, so insert a new one in the
	      // place that is alphabetically sorted.
	      var node = createNode(part, path + "/" + part, []);
	      var where = index === -1 ? children.length : index;
	      children.splice(where, 0, node);
	      subtree = children[where];
	    }
	
	    // Keep track of the children so we can tag each node with them.
	    path = path + "/" + part;
	  }
	
	  // Overwrite the contents of the final node to store the source
	  // there.
	  if (isDir) {
	    subtree.contents.unshift(createNode("(index)", source.get("url"), source));
	  } else {
	    subtree.contents = source;
	  }
	}
	
	/**
	 * Look at the nodes in the source tree, and determine the index of where to
	 * insert a new node. The ordering is index -> folder -> file.
	 * @memberof utils/sources-tree
	 * @static
	 */
	function determineFileSortOrder(nodes, pathPart, isLastPart) {
	  var partIsDir = !isLastPart || pathPart.indexOf(".") === -1;
	
	  return nodes.findIndex(node => {
	    var nodeIsDir = nodeHasChildren(node);
	
	    // The index will always be the first thing, so this pathPart will be
	    // after it.
	    if (node.name === "(index)") {
	      return false;
	    }
	
	    // If both the pathPart and node are the same type, then compare them
	    // alphabetically.
	    if (partIsDir === nodeIsDir) {
	      return node.name.localeCompare(pathPart) >= 0;
	    }
	
	    // If the pathPart and node differ, then stop here if the pathPart is a
	    // directory. Keep on searching if the part is a file, as it needs to be
	    // placed after the directories.
	    return partIsDir;
	  });
	}
	
	/**
	 * Take an existing source tree, and return a new one with collapsed nodes.
	 * @memberof utils/sources-tree
	 * @static
	 */
	function collapseTree(node) {
	  var depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
	
	  // Node is a folder.
	  if (nodeHasChildren(node)) {
	    // Node is not a root/domain node, and only contains 1 item.
	    if (depth > 1 && node.contents.length === 1) {
	      var next = node.contents[0];
	      // Do not collapse if the next node is a leaf node.
	      if (nodeHasChildren(next)) {
	        return collapseTree(createNode(`${ node.name }/${ next.name }`, next.path, next.contents), depth + 1);
	      }
	    }
	    // Map the contents.
	    return createNode(node.name, node.path, node.contents.map(next => collapseTree(next, depth + 1)));
	  }
	  // Node is a leaf, not a folder, do not modify it.
	  return node;
	}
	
	/**
	 * @memberof utils/sources-tree
	 * @static
	 */
	function createTree(sources) {
	  var uncollapsedTree = createNode("root", "", []);
	  for (var source of sources.valueSeq()) {
	    addToTree(uncollapsedTree, source);
	  }
	  var sourceTree = collapseTree(uncollapsedTree);
	
	  return { uncollapsedTree,
	    sourceTree,
	    parentMap: createParentMap(sourceTree),
	    focusedItem: null };
	}
	
	module.exports = {
	  createNode,
	  nodeHasChildren,
	  createParentMap,
	  addToTree,
	  collapseTree,
	  createTree
	};

/***/ },
/* 342 */
/***/ function(module, exports, __webpack_require__) {

	var baseMerge = __webpack_require__(343),
	    createAssigner = __webpack_require__(384);
	
	/**
	 * This method is like `_.assign` except that it recursively merges own and
	 * inherited enumerable string keyed properties of source objects into the
	 * destination object. Source properties that resolve to `undefined` are
	 * skipped if a destination value exists. Array and plain object properties
	 * are merged recursively. Other objects and value types are overridden by
	 * assignment. Source objects are applied from left to right. Subsequent
	 * sources overwrite property assignments of previous sources.
	 *
	 * **Note:** This method mutates `object`.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.5.0
	 * @category Object
	 * @param {Object} object The destination object.
	 * @param {...Object} [sources] The source objects.
	 * @returns {Object} Returns `object`.
	 * @example
	 *
	 * var object = {
	 *   'a': [{ 'b': 2 }, { 'd': 4 }]
	 * };
	 *
	 * var other = {
	 *   'a': [{ 'c': 3 }, { 'e': 5 }]
	 * };
	 *
	 * _.merge(object, other);
	 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
	 */
	var merge = createAssigner(function(object, source, srcIndex) {
	  baseMerge(object, source, srcIndex);
	});
	
	module.exports = merge;


/***/ },
/* 343 */
/***/ function(module, exports, __webpack_require__) {

	var Stack = __webpack_require__(344),
	    assignMergeValue = __webpack_require__(350),
	    baseFor = __webpack_require__(353),
	    baseMergeDeep = __webpack_require__(355),
	    isObject = __webpack_require__(106),
	    keysIn = __webpack_require__(378);
	
	/**
	 * The base implementation of `_.merge` without support for multiple sources.
	 *
	 * @private
	 * @param {Object} object The destination object.
	 * @param {Object} source The source object.
	 * @param {number} srcIndex The index of `source`.
	 * @param {Function} [customizer] The function to customize merged values.
	 * @param {Object} [stack] Tracks traversed source values and their merged
	 *  counterparts.
	 */
	function baseMerge(object, source, srcIndex, customizer, stack) {
	  if (object === source) {
	    return;
	  }
	  baseFor(source, function(srcValue, key) {
	    if (isObject(srcValue)) {
	      stack || (stack = new Stack);
	      baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
	    }
	    else {
	      var newValue = customizer
	        ? customizer(object[key], srcValue, (key + ''), object, source, stack)
	        : undefined;
	
	      if (newValue === undefined) {
	        newValue = srcValue;
	      }
	      assignMergeValue(object, key, newValue);
	    }
	  }, keysIn);
	}
	
	module.exports = baseMerge;


/***/ },
/* 344 */
/***/ function(module, exports, __webpack_require__) {

	var ListCache = __webpack_require__(117),
	    stackClear = __webpack_require__(345),
	    stackDelete = __webpack_require__(346),
	    stackGet = __webpack_require__(347),
	    stackHas = __webpack_require__(348),
	    stackSet = __webpack_require__(349);
	
	/**
	 * Creates a stack cache object to store key-value pairs.
	 *
	 * @private
	 * @constructor
	 * @param {Array} [entries] The key-value pairs to cache.
	 */
	function Stack(entries) {
	  var data = this.__data__ = new ListCache(entries);
	  this.size = data.size;
	}
	
	// Add methods to `Stack`.
	Stack.prototype.clear = stackClear;
	Stack.prototype['delete'] = stackDelete;
	Stack.prototype.get = stackGet;
	Stack.prototype.has = stackHas;
	Stack.prototype.set = stackSet;
	
	module.exports = Stack;


/***/ },
/* 345 */
/***/ function(module, exports, __webpack_require__) {

	var ListCache = __webpack_require__(117);
	
	/**
	 * Removes all key-value entries from the stack.
	 *
	 * @private
	 * @name clear
	 * @memberOf Stack
	 */
	function stackClear() {
	  this.__data__ = new ListCache;
	  this.size = 0;
	}
	
	module.exports = stackClear;


/***/ },
/* 346 */
/***/ function(module, exports) {

	/**
	 * Removes `key` and its value from the stack.
	 *
	 * @private
	 * @name delete
	 * @memberOf Stack
	 * @param {string} key The key of the value to remove.
	 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	 */
	function stackDelete(key) {
	  var data = this.__data__,
	      result = data['delete'](key);
	
	  this.size = data.size;
	  return result;
	}
	
	module.exports = stackDelete;


/***/ },
/* 347 */
/***/ function(module, exports) {

	/**
	 * Gets the stack value for `key`.
	 *
	 * @private
	 * @name get
	 * @memberOf Stack
	 * @param {string} key The key of the value to get.
	 * @returns {*} Returns the entry value.
	 */
	function stackGet(key) {
	  return this.__data__.get(key);
	}
	
	module.exports = stackGet;


/***/ },
/* 348 */
/***/ function(module, exports) {

	/**
	 * Checks if a stack value for `key` exists.
	 *
	 * @private
	 * @name has
	 * @memberOf Stack
	 * @param {string} key The key of the entry to check.
	 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	 */
	function stackHas(key) {
	  return this.__data__.has(key);
	}
	
	module.exports = stackHas;


/***/ },
/* 349 */
/***/ function(module, exports, __webpack_require__) {

	var ListCache = __webpack_require__(117),
	    Map = __webpack_require__(125),
	    MapCache = __webpack_require__(98);
	
	/** Used as the size to enable large array optimizations. */
	var LARGE_ARRAY_SIZE = 200;
	
	/**
	 * Sets the stack `key` to `value`.
	 *
	 * @private
	 * @name set
	 * @memberOf Stack
	 * @param {string} key The key of the value to set.
	 * @param {*} value The value to set.
	 * @returns {Object} Returns the stack cache instance.
	 */
	function stackSet(key, value) {
	  var data = this.__data__;
	  if (data instanceof ListCache) {
	    var pairs = data.__data__;
	    if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
	      pairs.push([key, value]);
	      this.size = ++data.size;
	      return this;
	    }
	    data = this.__data__ = new MapCache(pairs);
	  }
	  data.set(key, value);
	  this.size = data.size;
	  return this;
	}
	
	module.exports = stackSet;


/***/ },
/* 350 */
/***/ function(module, exports, __webpack_require__) {

	var baseAssignValue = __webpack_require__(351),
	    eq = __webpack_require__(121);
	
	/**
	 * This function is like `assignValue` except that it doesn't assign
	 * `undefined` values.
	 *
	 * @private
	 * @param {Object} object The object to modify.
	 * @param {string} key The key of the property to assign.
	 * @param {*} value The value to assign.
	 */
	function assignMergeValue(object, key, value) {
	  if ((value !== undefined && !eq(object[key], value)) ||
	      (value === undefined && !(key in object))) {
	    baseAssignValue(object, key, value);
	  }
	}
	
	module.exports = assignMergeValue;


/***/ },
/* 351 */
/***/ function(module, exports, __webpack_require__) {

	var defineProperty = __webpack_require__(352);
	
	/**
	 * The base implementation of `assignValue` and `assignMergeValue` without
	 * value checks.
	 *
	 * @private
	 * @param {Object} object The object to modify.
	 * @param {string} key The key of the property to assign.
	 * @param {*} value The value to assign.
	 */
	function baseAssignValue(object, key, value) {
	  if (key == '__proto__' && defineProperty) {
	    defineProperty(object, key, {
	      'configurable': true,
	      'enumerable': true,
	      'value': value,
	      'writable': true
	    });
	  } else {
	    object[key] = value;
	  }
	}
	
	module.exports = baseAssignValue;


/***/ },
/* 352 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103);
	
	var defineProperty = (function() {
	  try {
	    var func = getNative(Object, 'defineProperty');
	    func({}, '', {});
	    return func;
	  } catch (e) {}
	}());
	
	module.exports = defineProperty;


/***/ },
/* 353 */
/***/ function(module, exports, __webpack_require__) {

	var createBaseFor = __webpack_require__(354);
	
	/**
	 * The base implementation of `baseForOwn` which iterates over `object`
	 * properties returned by `keysFunc` and invokes `iteratee` for each property.
	 * Iteratee functions may exit iteration early by explicitly returning `false`.
	 *
	 * @private
	 * @param {Object} object The object to iterate over.
	 * @param {Function} iteratee The function invoked per iteration.
	 * @param {Function} keysFunc The function to get the keys of `object`.
	 * @returns {Object} Returns `object`.
	 */
	var baseFor = createBaseFor();
	
	module.exports = baseFor;


/***/ },
/* 354 */
/***/ function(module, exports) {

	/**
	 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
	 *
	 * @private
	 * @param {boolean} [fromRight] Specify iterating from right to left.
	 * @returns {Function} Returns the new base function.
	 */
	function createBaseFor(fromRight) {
	  return function(object, iteratee, keysFunc) {
	    var index = -1,
	        iterable = Object(object),
	        props = keysFunc(object),
	        length = props.length;
	
	    while (length--) {
	      var key = props[fromRight ? length : ++index];
	      if (iteratee(iterable[key], key, iterable) === false) {
	        break;
	      }
	    }
	    return object;
	  };
	}
	
	module.exports = createBaseFor;


/***/ },
/* 355 */
/***/ function(module, exports, __webpack_require__) {

	var assignMergeValue = __webpack_require__(350),
	    cloneBuffer = __webpack_require__(356),
	    cloneTypedArray = __webpack_require__(357),
	    copyArray = __webpack_require__(360),
	    initCloneObject = __webpack_require__(361),
	    isArguments = __webpack_require__(364),
	    isArray = __webpack_require__(94),
	    isArrayLikeObject = __webpack_require__(366),
	    isBuffer = __webpack_require__(369),
	    isFunction = __webpack_require__(105),
	    isObject = __webpack_require__(106),
	    isPlainObject = __webpack_require__(5),
	    isTypedArray = __webpack_require__(371),
	    toPlainObject = __webpack_require__(375);
	
	/**
	 * A specialized version of `baseMerge` for arrays and objects which performs
	 * deep merges and tracks traversed objects enabling objects with circular
	 * references to be merged.
	 *
	 * @private
	 * @param {Object} object The destination object.
	 * @param {Object} source The source object.
	 * @param {string} key The key of the value to merge.
	 * @param {number} srcIndex The index of `source`.
	 * @param {Function} mergeFunc The function to merge values.
	 * @param {Function} [customizer] The function to customize assigned values.
	 * @param {Object} [stack] Tracks traversed source values and their merged
	 *  counterparts.
	 */
	function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
	  var objValue = object[key],
	      srcValue = source[key],
	      stacked = stack.get(srcValue);
	
	  if (stacked) {
	    assignMergeValue(object, key, stacked);
	    return;
	  }
	  var newValue = customizer
	    ? customizer(objValue, srcValue, (key + ''), object, source, stack)
	    : undefined;
	
	  var isCommon = newValue === undefined;
	
	  if (isCommon) {
	    var isArr = isArray(srcValue),
	        isBuff = !isArr && isBuffer(srcValue),
	        isTyped = !isArr && !isBuff && isTypedArray(srcValue);
	
	    newValue = srcValue;
	    if (isArr || isBuff || isTyped) {
	      if (isArray(objValue)) {
	        newValue = objValue;
	      }
	      else if (isArrayLikeObject(objValue)) {
	        newValue = copyArray(objValue);
	      }
	      else if (isBuff) {
	        isCommon = false;
	        newValue = cloneBuffer(srcValue, true);
	      }
	      else if (isTyped) {
	        isCommon = false;
	        newValue = cloneTypedArray(srcValue, true);
	      }
	      else {
	        newValue = [];
	      }
	    }
	    else if (isPlainObject(srcValue) || isArguments(srcValue)) {
	      newValue = objValue;
	      if (isArguments(objValue)) {
	        newValue = toPlainObject(objValue);
	      }
	      else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
	        newValue = initCloneObject(srcValue);
	      }
	    }
	    else {
	      isCommon = false;
	    }
	  }
	  if (isCommon) {
	    // Recursively merge objects and arrays (susceptible to call stack limits).
	    stack.set(srcValue, newValue);
	    mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
	    stack['delete'](srcValue);
	  }
	  assignMergeValue(object, key, newValue);
	}
	
	module.exports = baseMergeDeep;


/***/ },
/* 356 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(109);
	
	/** Detect free variable `exports`. */
	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	/** Detect free variable `module`. */
	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	/** Detect the popular CommonJS extension `module.exports`. */
	var moduleExports = freeModule && freeModule.exports === freeExports;
	
	/** Built-in value references. */
	var Buffer = moduleExports ? root.Buffer : undefined,
	    allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
	
	/**
	 * Creates a clone of  `buffer`.
	 *
	 * @private
	 * @param {Buffer} buffer The buffer to clone.
	 * @param {boolean} [isDeep] Specify a deep clone.
	 * @returns {Buffer} Returns the cloned buffer.
	 */
	function cloneBuffer(buffer, isDeep) {
	  if (isDeep) {
	    return buffer.slice();
	  }
	  var length = buffer.length,
	      result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
	
	  buffer.copy(result);
	  return result;
	}
	
	module.exports = cloneBuffer;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(77)(module)))

/***/ },
/* 357 */
/***/ function(module, exports, __webpack_require__) {

	var cloneArrayBuffer = __webpack_require__(358);
	
	/**
	 * Creates a clone of `typedArray`.
	 *
	 * @private
	 * @param {Object} typedArray The typed array to clone.
	 * @param {boolean} [isDeep] Specify a deep clone.
	 * @returns {Object} Returns the cloned typed array.
	 */
	function cloneTypedArray(typedArray, isDeep) {
	  var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
	  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
	}
	
	module.exports = cloneTypedArray;


/***/ },
/* 358 */
/***/ function(module, exports, __webpack_require__) {

	var Uint8Array = __webpack_require__(359);
	
	/**
	 * Creates a clone of `arrayBuffer`.
	 *
	 * @private
	 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
	 * @returns {ArrayBuffer} Returns the cloned array buffer.
	 */
	function cloneArrayBuffer(arrayBuffer) {
	  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
	  new Uint8Array(result).set(new Uint8Array(arrayBuffer));
	  return result;
	}
	
	module.exports = cloneArrayBuffer;


/***/ },
/* 359 */
/***/ function(module, exports, __webpack_require__) {

	var root = __webpack_require__(109);
	
	/** Built-in value references. */
	var Uint8Array = root.Uint8Array;
	
	module.exports = Uint8Array;


/***/ },
/* 360 */
/***/ function(module, exports) {

	/**
	 * Copies the values of `source` to `array`.
	 *
	 * @private
	 * @param {Array} source The array to copy values from.
	 * @param {Array} [array=[]] The array to copy values to.
	 * @returns {Array} Returns `array`.
	 */
	function copyArray(source, array) {
	  var index = -1,
	      length = source.length;
	
	  array || (array = Array(length));
	  while (++index < length) {
	    array[index] = source[index];
	  }
	  return array;
	}
	
	module.exports = copyArray;


/***/ },
/* 361 */
/***/ function(module, exports, __webpack_require__) {

	var baseCreate = __webpack_require__(362),
	    getPrototype = __webpack_require__(6),
	    isPrototype = __webpack_require__(363);
	
	/**
	 * Initializes an object clone.
	 *
	 * @private
	 * @param {Object} object The object to clone.
	 * @returns {Object} Returns the initialized clone.
	 */
	function initCloneObject(object) {
	  return (typeof object.constructor == 'function' && !isPrototype(object))
	    ? baseCreate(getPrototype(object))
	    : {};
	}
	
	module.exports = initCloneObject;


/***/ },
/* 362 */
/***/ function(module, exports, __webpack_require__) {

	var isObject = __webpack_require__(106);
	
	/** Built-in value references. */
	var objectCreate = Object.create;
	
	/**
	 * The base implementation of `_.create` without support for assigning
	 * properties to the created object.
	 *
	 * @private
	 * @param {Object} proto The object to inherit from.
	 * @returns {Object} Returns the new object.
	 */
	var baseCreate = (function() {
	  function object() {}
	  return function(proto) {
	    if (!isObject(proto)) {
	      return {};
	    }
	    if (objectCreate) {
	      return objectCreate(proto);
	    }
	    object.prototype = proto;
	    var result = new object;
	    object.prototype = undefined;
	    return result;
	  };
	}());
	
	module.exports = baseCreate;


/***/ },
/* 363 */
/***/ function(module, exports) {

	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/**
	 * Checks if `value` is likely a prototype object.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
	 */
	function isPrototype(value) {
	  var Ctor = value && value.constructor,
	      proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
	
	  return value === proto;
	}
	
	module.exports = isPrototype;


/***/ },
/* 364 */
/***/ function(module, exports, __webpack_require__) {

	var baseIsArguments = __webpack_require__(365),
	    isObjectLike = __webpack_require__(8);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/** Built-in value references. */
	var propertyIsEnumerable = objectProto.propertyIsEnumerable;
	
	/**
	 * Checks if `value` is likely an `arguments` object.
	 *
	 * @static
	 * @memberOf _
	 * @since 0.1.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 *  else `false`.
	 * @example
	 *
	 * _.isArguments(function() { return arguments; }());
	 * // => true
	 *
	 * _.isArguments([1, 2, 3]);
	 * // => false
	 */
	var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
	  return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
	    !propertyIsEnumerable.call(value, 'callee');
	};
	
	module.exports = isArguments;


/***/ },
/* 365 */
/***/ function(module, exports, __webpack_require__) {

	var isObjectLike = __webpack_require__(8);
	
	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]';
	
	/** 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 objectToString = objectProto.toString;
	
	/**
	 * The base implementation of `_.isArguments`.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	 */
	function baseIsArguments(value) {
	  return isObjectLike(value) && objectToString.call(value) == argsTag;
	}
	
	module.exports = baseIsArguments;


/***/ },
/* 366 */
/***/ function(module, exports, __webpack_require__) {

	var isArrayLike = __webpack_require__(367),
	    isObjectLike = __webpack_require__(8);
	
	/**
	 * This method is like `_.isArrayLike` except that it also checks if `value`
	 * is an object.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is an array-like object,
	 *  else `false`.
	 * @example
	 *
	 * _.isArrayLikeObject([1, 2, 3]);
	 * // => true
	 *
	 * _.isArrayLikeObject(document.body.children);
	 * // => true
	 *
	 * _.isArrayLikeObject('abc');
	 * // => false
	 *
	 * _.isArrayLikeObject(_.noop);
	 * // => false
	 */
	function isArrayLikeObject(value) {
	  return isObjectLike(value) && isArrayLike(value);
	}
	
	module.exports = isArrayLikeObject;


/***/ },
/* 367 */
/***/ function(module, exports, __webpack_require__) {

	var isFunction = __webpack_require__(105),
	    isLength = __webpack_require__(368);
	
	/**
	 * Checks if `value` is array-like. A value is considered array-like if it's
	 * not a function and has a `value.length` that's an integer greater than or
	 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
	 * @example
	 *
	 * _.isArrayLike([1, 2, 3]);
	 * // => true
	 *
	 * _.isArrayLike(document.body.children);
	 * // => true
	 *
	 * _.isArrayLike('abc');
	 * // => true
	 *
	 * _.isArrayLike(_.noop);
	 * // => false
	 */
	function isArrayLike(value) {
	  return value != null && isLength(value.length) && !isFunction(value);
	}
	
	module.exports = isArrayLike;


/***/ },
/* 368 */
/***/ function(module, exports) {

	/** Used as references for various `Number` constants. */
	var MAX_SAFE_INTEGER = 9007199254740991;
	
	/**
	 * Checks if `value` is a valid array-like length.
	 *
	 * **Note:** This method is loosely based on
	 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	 * @example
	 *
	 * _.isLength(3);
	 * // => true
	 *
	 * _.isLength(Number.MIN_VALUE);
	 * // => false
	 *
	 * _.isLength(Infinity);
	 * // => false
	 *
	 * _.isLength('3');
	 * // => false
	 */
	function isLength(value) {
	  return typeof value == 'number' &&
	    value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	}
	
	module.exports = isLength;


/***/ },
/* 369 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(module) {var root = __webpack_require__(109),
	    stubFalse = __webpack_require__(370);
	
	/** Detect free variable `exports`. */
	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	/** Detect free variable `module`. */
	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	/** Detect the popular CommonJS extension `module.exports`. */
	var moduleExports = freeModule && freeModule.exports === freeExports;
	
	/** Built-in value references. */
	var Buffer = moduleExports ? root.Buffer : undefined;
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
	
	/**
	 * Checks if `value` is a buffer.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.3.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
	 * @example
	 *
	 * _.isBuffer(new Buffer(2));
	 * // => true
	 *
	 * _.isBuffer(new Uint8Array(2));
	 * // => false
	 */
	var isBuffer = nativeIsBuffer || stubFalse;
	
	module.exports = isBuffer;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(77)(module)))

/***/ },
/* 370 */
/***/ function(module, exports) {

	/**
	 * This method returns `false`.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.13.0
	 * @category Util
	 * @returns {boolean} Returns `false`.
	 * @example
	 *
	 * _.times(2, _.stubFalse);
	 * // => [false, false]
	 */
	function stubFalse() {
	  return false;
	}
	
	module.exports = stubFalse;


/***/ },
/* 371 */
/***/ function(module, exports, __webpack_require__) {

	var baseIsTypedArray = __webpack_require__(372),
	    baseUnary = __webpack_require__(373),
	    nodeUtil = __webpack_require__(374);
	
	/* Node.js helper references. */
	var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
	
	/**
	 * Checks if `value` is classified as a typed array.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Lang
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 * @example
	 *
	 * _.isTypedArray(new Uint8Array);
	 * // => true
	 *
	 * _.isTypedArray([]);
	 * // => false
	 */
	var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
	
	module.exports = isTypedArray;


/***/ },
/* 372 */
/***/ function(module, exports, __webpack_require__) {

	var isLength = __webpack_require__(368),
	    isObjectLike = __webpack_require__(8);
	
	/** `Object#toString` result references. */
	var argsTag = '[object Arguments]',
	    arrayTag = '[object Array]',
	    boolTag = '[object Boolean]',
	    dateTag = '[object Date]',
	    errorTag = '[object Error]',
	    funcTag = '[object Function]',
	    mapTag = '[object Map]',
	    numberTag = '[object Number]',
	    objectTag = '[object Object]',
	    regexpTag = '[object RegExp]',
	    setTag = '[object Set]',
	    stringTag = '[object String]',
	    weakMapTag = '[object WeakMap]';
	
	var arrayBufferTag = '[object ArrayBuffer]',
	    dataViewTag = '[object DataView]',
	    float32Tag = '[object Float32Array]',
	    float64Tag = '[object Float64Array]',
	    int8Tag = '[object Int8Array]',
	    int16Tag = '[object Int16Array]',
	    int32Tag = '[object Int32Array]',
	    uint8Tag = '[object Uint8Array]',
	    uint8ClampedTag = '[object Uint8ClampedArray]',
	    uint16Tag = '[object Uint16Array]',
	    uint32Tag = '[object Uint32Array]';
	
	/** Used to identify `toStringTag` values of typed arrays. */
	var typedArrayTags = {};
	typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
	typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
	typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
	typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
	typedArrayTags[uint32Tag] = true;
	typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
	typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
	typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
	typedArrayTags[errorTag] = typedArrayTags[funcTag] =
	typedArrayTags[mapTag] = typedArrayTags[numberTag] =
	typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
	typedArrayTags[setTag] = typedArrayTags[stringTag] =
	typedArrayTags[weakMapTag] = false;
	
	/** 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 objectToString = objectProto.toString;
	
	/**
	 * The base implementation of `_.isTypedArray` without Node.js optimizations.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	 */
	function baseIsTypedArray(value) {
	  return isObjectLike(value) &&
	    isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
	}
	
	module.exports = baseIsTypedArray;


/***/ },
/* 373 */
/***/ function(module, exports) {

	/**
	 * The base implementation of `_.unary` without support for storing metadata.
	 *
	 * @private
	 * @param {Function} func The function to cap arguments for.
	 * @returns {Function} Returns the new capped function.
	 */
	function baseUnary(func) {
	  return function(value) {
	    return func(value);
	  };
	}
	
	module.exports = baseUnary;


/***/ },
/* 374 */
/***/ function(module, exports, __webpack_require__) {

	/* WEBPACK VAR INJECTION */(function(module) {var freeGlobal = __webpack_require__(110);
	
	/** Detect free variable `exports`. */
	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	/** Detect free variable `module`. */
	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	/** Detect the popular CommonJS extension `module.exports`. */
	var moduleExports = freeModule && freeModule.exports === freeExports;
	
	/** Detect free variable `process` from Node.js. */
	var freeProcess = moduleExports && freeGlobal.process;
	
	/** Used to access faster Node.js helpers. */
	var nodeUtil = (function() {
	  try {
	    return freeProcess && freeProcess.binding('util');
	  } catch (e) {}
	}());
	
	module.exports = nodeUtil;
	
	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(77)(module)))

/***/ },
/* 375 */
/***/ function(module, exports, __webpack_require__) {

	var copyObject = __webpack_require__(376),
	    keysIn = __webpack_require__(378);
	
	/**
	 * Converts `value` to a plain object flattening inherited enumerable string
	 * keyed properties of `value` to own properties of the plain object.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Lang
	 * @param {*} value The value to convert.
	 * @returns {Object} Returns the converted plain object.
	 * @example
	 *
	 * function Foo() {
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.assign({ 'a': 1 }, new Foo);
	 * // => { 'a': 1, 'b': 2 }
	 *
	 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
	 * // => { 'a': 1, 'b': 2, 'c': 3 }
	 */
	function toPlainObject(value) {
	  return copyObject(value, keysIn(value));
	}
	
	module.exports = toPlainObject;


/***/ },
/* 376 */
/***/ function(module, exports, __webpack_require__) {

	var assignValue = __webpack_require__(377),
	    baseAssignValue = __webpack_require__(351);
	
	/**
	 * Copies properties of `source` to `object`.
	 *
	 * @private
	 * @param {Object} source The object to copy properties from.
	 * @param {Array} props The property identifiers to copy.
	 * @param {Object} [object={}] The object to copy properties to.
	 * @param {Function} [customizer] The function to customize copied values.
	 * @returns {Object} Returns `object`.
	 */
	function copyObject(source, props, object, customizer) {
	  var isNew = !object;
	  object || (object = {});
	
	  var index = -1,
	      length = props.length;
	
	  while (++index < length) {
	    var key = props[index];
	
	    var newValue = customizer
	      ? customizer(object[key], source[key], key, object, source)
	      : undefined;
	
	    if (newValue === undefined) {
	      newValue = source[key];
	    }
	    if (isNew) {
	      baseAssignValue(object, key, newValue);
	    } else {
	      assignValue(object, key, newValue);
	    }
	  }
	  return object;
	}
	
	module.exports = copyObject;


/***/ },
/* 377 */
/***/ function(module, exports, __webpack_require__) {

	var baseAssignValue = __webpack_require__(351),
	    eq = __webpack_require__(121);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Assigns `value` to `key` of `object` if the existing value is not equivalent
	 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	 * for equality comparisons.
	 *
	 * @private
	 * @param {Object} object The object to modify.
	 * @param {string} key The key of the property to assign.
	 * @param {*} value The value to assign.
	 */
	function assignValue(object, key, value) {
	  var objValue = object[key];
	  if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
	      (value === undefined && !(key in object))) {
	    baseAssignValue(object, key, value);
	  }
	}
	
	module.exports = assignValue;


/***/ },
/* 378 */
/***/ function(module, exports, __webpack_require__) {

	var arrayLikeKeys = __webpack_require__(379),
	    baseKeysIn = __webpack_require__(382),
	    isArrayLike = __webpack_require__(367);
	
	/**
	 * Creates an array of the own and inherited enumerable property names of `object`.
	 *
	 * **Note:** Non-object values are coerced to objects.
	 *
	 * @static
	 * @memberOf _
	 * @since 3.0.0
	 * @category Object
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.keysIn(new Foo);
	 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
	 */
	function keysIn(object) {
	  return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
	}
	
	module.exports = keysIn;


/***/ },
/* 379 */
/***/ function(module, exports, __webpack_require__) {

	var baseTimes = __webpack_require__(380),
	    isArguments = __webpack_require__(364),
	    isArray = __webpack_require__(94),
	    isBuffer = __webpack_require__(369),
	    isIndex = __webpack_require__(381),
	    isTypedArray = __webpack_require__(371);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * Creates an array of the enumerable property names of the array-like `value`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @param {boolean} inherited Specify returning inherited property names.
	 * @returns {Array} Returns the array of property names.
	 */
	function arrayLikeKeys(value, inherited) {
	  var isArr = isArray(value),
	      isArg = !isArr && isArguments(value),
	      isBuff = !isArr && !isArg && isBuffer(value),
	      isType = !isArr && !isArg && !isBuff && isTypedArray(value),
	      skipIndexes = isArr || isArg || isBuff || isType,
	      result = skipIndexes ? baseTimes(value.length, String) : [],
	      length = result.length;
	
	  for (var key in value) {
	    if ((inherited || hasOwnProperty.call(value, key)) &&
	        !(skipIndexes && (
	           // Safari 9 has enumerable `arguments.length` in strict mode.
	           key == 'length' ||
	           // Node.js 0.10 has enumerable non-index properties on buffers.
	           (isBuff && (key == 'offset' || key == 'parent')) ||
	           // PhantomJS 2 has enumerable non-index properties on typed arrays.
	           (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
	           // Skip index properties.
	           isIndex(key, length)
	        ))) {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = arrayLikeKeys;


/***/ },
/* 380 */
/***/ function(module, exports) {

	/**
	 * The base implementation of `_.times` without support for iteratee shorthands
	 * or max array length checks.
	 *
	 * @private
	 * @param {number} n The number of times to invoke `iteratee`.
	 * @param {Function} iteratee The function invoked per iteration.
	 * @returns {Array} Returns the array of results.
	 */
	function baseTimes(n, iteratee) {
	  var index = -1,
	      result = Array(n);
	
	  while (++index < n) {
	    result[index] = iteratee(index);
	  }
	  return result;
	}
	
	module.exports = baseTimes;


/***/ },
/* 381 */
/***/ function(module, exports) {

	/** Used as references for various `Number` constants. */
	var MAX_SAFE_INTEGER = 9007199254740991;
	
	/** Used to detect unsigned integer values. */
	var reIsUint = /^(?:0|[1-9]\d*)$/;
	
	/**
	 * Checks if `value` is a valid array-like index.
	 *
	 * @private
	 * @param {*} value The value to check.
	 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
	 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
	 */
	function isIndex(value, length) {
	  length = length == null ? MAX_SAFE_INTEGER : length;
	  return !!length &&
	    (typeof value == 'number' || reIsUint.test(value)) &&
	    (value > -1 && value % 1 == 0 && value < length);
	}
	
	module.exports = isIndex;


/***/ },
/* 382 */
/***/ function(module, exports, __webpack_require__) {

	var isObject = __webpack_require__(106),
	    isPrototype = __webpack_require__(363),
	    nativeKeysIn = __webpack_require__(383);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 */
	function baseKeysIn(object) {
	  if (!isObject(object)) {
	    return nativeKeysIn(object);
	  }
	  var isProto = isPrototype(object),
	      result = [];
	
	  for (var key in object) {
	    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = baseKeysIn;


/***/ },
/* 383 */
/***/ function(module, exports) {

	/**
	 * This function is like
	 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	 * except that it includes inherited enumerable properties.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 */
	function nativeKeysIn(object) {
	  var result = [];
	  if (object != null) {
	    for (var key in Object(object)) {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = nativeKeysIn;


/***/ },
/* 384 */
/***/ function(module, exports, __webpack_require__) {

	var baseRest = __webpack_require__(385),
	    isIterateeCall = __webpack_require__(393);
	
	/**
	 * Creates a function like `_.assign`.
	 *
	 * @private
	 * @param {Function} assigner The function to assign values.
	 * @returns {Function} Returns the new assigner function.
	 */
	function createAssigner(assigner) {
	  return baseRest(function(object, sources) {
	    var index = -1,
	        length = sources.length,
	        customizer = length > 1 ? sources[length - 1] : undefined,
	        guard = length > 2 ? sources[2] : undefined;
	
	    customizer = (assigner.length > 3 && typeof customizer == 'function')
	      ? (length--, customizer)
	      : undefined;
	
	    if (guard && isIterateeCall(sources[0], sources[1], guard)) {
	      customizer = length < 3 ? undefined : customizer;
	      length = 1;
	    }
	    object = Object(object);
	    while (++index < length) {
	      var source = sources[index];
	      if (source) {
	        assigner(object, source, index, customizer);
	      }
	    }
	    return object;
	  });
	}
	
	module.exports = createAssigner;


/***/ },
/* 385 */
/***/ function(module, exports, __webpack_require__) {

	var identity = __webpack_require__(386),
	    overRest = __webpack_require__(387),
	    setToString = __webpack_require__(389);
	
	/**
	 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
	 *
	 * @private
	 * @param {Function} func The function to apply a rest parameter to.
	 * @param {number} [start=func.length-1] The start position of the rest parameter.
	 * @returns {Function} Returns the new function.
	 */
	function baseRest(func, start) {
	  return setToString(overRest(func, start, identity), func + '');
	}
	
	module.exports = baseRest;


/***/ },
/* 386 */
/***/ function(module, exports) {

	/**
	 * This method returns the first argument it receives.
	 *
	 * @static
	 * @since 0.1.0
	 * @memberOf _
	 * @category Util
	 * @param {*} value Any value.
	 * @returns {*} Returns `value`.
	 * @example
	 *
	 * var object = { 'a': 1 };
	 *
	 * console.log(_.identity(object) === object);
	 * // => true
	 */
	function identity(value) {
	  return value;
	}
	
	module.exports = identity;


/***/ },
/* 387 */
/***/ function(module, exports, __webpack_require__) {

	var apply = __webpack_require__(388);
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeMax = Math.max;
	
	/**
	 * A specialized version of `baseRest` which transforms the rest array.
	 *
	 * @private
	 * @param {Function} func The function to apply a rest parameter to.
	 * @param {number} [start=func.length-1] The start position of the rest parameter.
	 * @param {Function} transform The rest array transform.
	 * @returns {Function} Returns the new function.
	 */
	function overRest(func, start, transform) {
	  start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
	  return function() {
	    var args = arguments,
	        index = -1,
	        length = nativeMax(args.length - start, 0),
	        array = Array(length);
	
	    while (++index < length) {
	      array[index] = args[start + index];
	    }
	    index = -1;
	    var otherArgs = Array(start + 1);
	    while (++index < start) {
	      otherArgs[index] = args[index];
	    }
	    otherArgs[start] = transform(array);
	    return apply(func, this, otherArgs);
	  };
	}
	
	module.exports = overRest;


/***/ },
/* 388 */
/***/ function(module, exports) {

	/**
	 * A faster alternative to `Function#apply`, this function invokes `func`
	 * with the `this` binding of `thisArg` and the arguments of `args`.
	 *
	 * @private
	 * @param {Function} func The function to invoke.
	 * @param {*} thisArg The `this` binding of `func`.
	 * @param {Array} args The arguments to invoke `func` with.
	 * @returns {*} Returns the result of `func`.
	 */
	function apply(func, thisArg, args) {
	  switch (args.length) {
	    case 0: return func.call(thisArg);
	    case 1: return func.call(thisArg, args[0]);
	    case 2: return func.call(thisArg, args[0], args[1]);
	    case 3: return func.call(thisArg, args[0], args[1], args[2]);
	  }
	  return func.apply(thisArg, args);
	}
	
	module.exports = apply;


/***/ },
/* 389 */
/***/ function(module, exports, __webpack_require__) {

	var baseSetToString = __webpack_require__(390),
	    shortOut = __webpack_require__(392);
	
	/**
	 * Sets the `toString` method of `func` to return `string`.
	 *
	 * @private
	 * @param {Function} func The function to modify.
	 * @param {Function} string The `toString` result.
	 * @returns {Function} Returns `func`.
	 */
	var setToString = shortOut(baseSetToString);
	
	module.exports = setToString;


/***/ },
/* 390 */
/***/ function(module, exports, __webpack_require__) {

	var constant = __webpack_require__(391),
	    defineProperty = __webpack_require__(352),
	    identity = __webpack_require__(386);
	
	/**
	 * The base implementation of `setToString` without support for hot loop shorting.
	 *
	 * @private
	 * @param {Function} func The function to modify.
	 * @param {Function} string The `toString` result.
	 * @returns {Function} Returns `func`.
	 */
	var baseSetToString = !defineProperty ? identity : function(func, string) {
	  return defineProperty(func, 'toString', {
	    'configurable': true,
	    'enumerable': false,
	    'value': constant(string),
	    'writable': true
	  });
	};
	
	module.exports = baseSetToString;


/***/ },
/* 391 */
/***/ function(module, exports) {

	/**
	 * Creates a function that returns `value`.
	 *
	 * @static
	 * @memberOf _
	 * @since 2.4.0
	 * @category Util
	 * @param {*} value The value to return from the new function.
	 * @returns {Function} Returns the new constant function.
	 * @example
	 *
	 * var objects = _.times(2, _.constant({ 'a': 1 }));
	 *
	 * console.log(objects);
	 * // => [{ 'a': 1 }, { 'a': 1 }]
	 *
	 * console.log(objects[0] === objects[1]);
	 * // => true
	 */
	function constant(value) {
	  return function() {
	    return value;
	  };
	}
	
	module.exports = constant;


/***/ },
/* 392 */
/***/ function(module, exports) {

	/** Used to detect hot functions by number of calls within a span of milliseconds. */
	var HOT_COUNT = 500,
	    HOT_SPAN = 16;
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeNow = Date.now;
	
	/**
	 * Creates a function that'll short out and invoke `identity` instead
	 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
	 * milliseconds.
	 *
	 * @private
	 * @param {Function} func The function to restrict.
	 * @returns {Function} Returns the new shortable function.
	 */
	function shortOut(func) {
	  var count = 0,
	      lastCalled = 0;
	
	  return function() {
	    var stamp = nativeNow(),
	        remaining = HOT_SPAN - (stamp - lastCalled);
	
	    lastCalled = stamp;
	    if (remaining > 0) {
	      if (++count >= HOT_COUNT) {
	        return arguments[0];
	      }
	    } else {
	      count = 0;
	    }
	    return func.apply(undefined, arguments);
	  };
	}
	
	module.exports = shortOut;


/***/ },
/* 393 */
/***/ function(module, exports, __webpack_require__) {

	var eq = __webpack_require__(121),
	    isArrayLike = __webpack_require__(367),
	    isIndex = __webpack_require__(381),
	    isObject = __webpack_require__(106);
	
	/**
	 * Checks if the given arguments are from an iteratee call.
	 *
	 * @private
	 * @param {*} value The potential iteratee value argument.
	 * @param {*} index The potential iteratee index or key argument.
	 * @param {*} object The potential iteratee object argument.
	 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
	 *  else `false`.
	 */
	function isIterateeCall(value, index, object) {
	  if (!isObject(object)) {
	    return false;
	  }
	  var type = typeof index;
	  if (type == 'number'
	        ? (isArrayLike(object) && isIndex(index, object.length))
	        : (type == 'string' && index in object)
	      ) {
	    return eq(object[index], value);
	  }
	  return false;
	}
	
	module.exports = isIterateeCall;


/***/ },
/* 394 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var Tree = React.createFactory(__webpack_require__(395));
	__webpack_require__(396);
	
	var ManagedTree = React.createClass({
	  propTypes: Tree.propTypes,
	
	  displayName: "ManagedTree",
	
	  getInitialState() {
	    return {
          expanded: new Set(),
	      focusedItem: null
        };
	  },
	
	  setExpanded(item, isExpanded) {
	    var expanded = this.state.expanded;
	    var key = this.props.getKey(item);
	    if (isExpanded) {
	      expanded.add(key);
	    } else {
	      expanded.delete(key);
	    }
	    this.setState({ expanded });
	
	    if (isExpanded && this.props.onExpand) {
	      this.props.onExpand(item);
	    } else if (!expanded && this.props.onCollapse) {
	      this.props.onCollapse(item);
	    }
	  },
	
	  focusItem(item) {
	    if (!this.props.disabledFocus && this.state.focusedItem !== item) {
	      this.setState({ focusedItem: item });
	
	      if (this.props.onFocus) {
	        this.props.onFocus(item);
	      }
	    }
	  },
	
	  render() {
	    var _this = this;
	
	    var _state = this.state;
	    var expanded = _state.expanded;
	    var focusedItem = _state.focusedItem;
	
	
	    var props = Object.assign({}, this.props, {
	      isExpanded: item => expanded.has(this.props.getKey(item)),
	      focused: focusedItem,
	
	      onExpand: item => this.setExpanded(item, true),
	      onCollapse: item => this.setExpanded(item, false),
	      onFocus: this.focusItem,
	
	      renderItem: function () {
	        var _props;
	
	        for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
	          args[_key] = arguments[_key];
	        }
	
	        return (_props = _this.props).renderItem.apply(_props, args.concat([{
	          setExpanded: _this.setExpanded
	        }]));
	      }
	    });
	
	    return Tree(props);
	  }
	});
	
	module.exports = ManagedTree;

/***/ },
/* 395 */
/***/ 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__(2);
	// 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,
	    // Optional event handlers for when items are expanded or collapsed.
	    onExpand: PropTypes.func,
	    onCollapse: PropTypes.func,
	  },
	
	  getDefaultProps() {
	    return {
	      autoExpandDepth: AUTO_EXPAND_DEPTH,
	    };
	  },
	
	  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;
	    for (let i = 0; i < length; i++) {
	      autoExpand(roots[i], 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);
	  }),
	});


/***/ },
/* 396 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 397 */,
/* 398 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 399 */,
/* 400 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	var createFactory = React.createFactory;
	
	
	var ReactDOM = __webpack_require__(16);
	var ImPropTypes = __webpack_require__(235);
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	
	var _require2 = __webpack_require__(19);
	
	var connect = _require2.connect;
	
	var SourceEditor = __webpack_require__(401);
	var SourceFooter = createFactory(__webpack_require__(402));
	var EditorSearchBar = createFactory(__webpack_require__(406));
	
	var _require3 = __webpack_require__(411);
	
	var renderConditionalPanel = _require3.renderConditionalPanel;
	
	var _require4 = __webpack_require__(18);
	
	var debugGlobal = _require4.debugGlobal;
	
	var _require5 = __webpack_require__(259);
	
	var getSourceText = _require5.getSourceText;
	var getBreakpointsForSource = _require5.getBreakpointsForSource;
	var getSelectedLocation = _require5.getSelectedLocation;
	var getSelectedFrame = _require5.getSelectedFrame;
	var getSelectedSource = _require5.getSelectedSource;
	
	var _require6 = __webpack_require__(255);
	
	var makeLocationId = _require6.makeLocationId;
	
	var actions = __webpack_require__(262);
	var Breakpoint = React.createFactory(__webpack_require__(412));
	
	var _require7 = __webpack_require__(279);
	
	var getDocument = _require7.getDocument;
	var setDocument = _require7.setDocument;
	
	var _require8 = __webpack_require__(403);
	
	var shouldShowFooter = _require8.shouldShowFooter;
	
	var _require9 = __webpack_require__(89);
	
	var isFirefox = _require9.isFirefox;
	
	var _require10 = __webpack_require__(413);
	
	var showMenu = _require10.showMenu;
	
	var _require11 = __webpack_require__(89);
	
	var isEnabled = _require11.isEnabled;
	
	
	__webpack_require__(414);
	
	function isTextForSource(sourceText) {
	  return !sourceText.get("loading") && !sourceText.get("error");
	}
	
	function breakpointAtLine(breakpoints, line) {
	  return breakpoints.find(b => {
	    return b.location.line === line + 1;
	  });
	}
	
	function getTextForLine(codeMirror, line) {
	  return codeMirror.getLine(line - 1).trim();
	}
	
	/**
	 * Forces the breakpoint gutter to be the same size as the line
	 * numbers gutter. Editor CSS will absolutely position the gutter
	 * beneath the line numbers. This makes it easy to be flexible with
	 * how we overlay breakpoints.
	 */
	function resizeBreakpointGutter(editor) {
	  var gutters = editor.display.gutters;
	  var lineNumbers = gutters.querySelector(".CodeMirror-linenumbers");
	  var breakpoints = gutters.querySelector(".breakpoints");
	  breakpoints.style.width = lineNumbers.clientWidth + "px";
	}
	
	var Editor = React.createClass({
	  propTypes: {
	    breakpoints: ImPropTypes.map.isRequired,
	    selectedLocation: PropTypes.object,
	    selectedSource: ImPropTypes.map,
	    sourceText: PropTypes.object,
	    addBreakpoint: PropTypes.func,
	    removeBreakpoint: PropTypes.func,
	    setBreakpointCondition: PropTypes.func,
	    selectedFrame: PropTypes.object
	  },
	
	  displayName: "Editor",
	
	  onGutterClick(cm, line, gutter, ev) {
	    // ignore right clicks in the gutter
	    if (ev.which === 3) {
	      return;
	    }
	
	    if (this.isCbPanelOpen()) {
	      return this.closeConditionalPanel(line);
	    }
	
	    this.toggleBreakpoint(line);
	  },
	
	  onGutterContextMenu(event) {
	    event.preventDefault();
	    var line = this.editor.codeMirror.lineAtHeight(event.clientY);
	    var bp = breakpointAtLine(this.props.breakpoints, line);
	    this.showGutterMenu(event, line, bp);
	  },
	
	  showConditionalPanel(line) {
	    if (this.isCbPanelOpen()) {
	      return;
	    }
	
	    var _props = this.props;
	    var sourceId = _props.selectedLocation.sourceId;
	    var setBreakpointCondition = _props.setBreakpointCondition;
	    var breakpoints = _props.breakpoints;
	
	
	    var bp = breakpointAtLine(breakpoints, line);
	    var location = { sourceId, line: line + 1 };
	    var condition = bp ? bp.condition : "";
	
	    var setBreakpoint = value => {
	      setBreakpointCondition(location, {
	        condition: value,
	        getTextForLine: l => getTextForLine(this.editor.codeMirror, l)
	      });
	    };
	
	    var panel = renderConditionalPanel({
	      condition,
	      setBreakpoint,
	      closePanel: this.closeConditionalPanel
	    });
	
	    this.cbPanel = this.editor.codeMirror.addLineWidget(line, panel);
	    this.cbPanel.node.querySelector("input").focus();
	  },
	
	  closeConditionalPanel() {
	    this.cbPanel.clear();
	    this.cbPanel = null;
	  },
	
	  isCbPanelOpen() {
	    return !!this.cbPanel;
	  },
	
	  toggleBreakpoint(line) {
	    var bp = breakpointAtLine(this.props.breakpoints, line);
	
	    if (bp && bp.loading) {
	      return;
	    }
	
	    if (bp) {
	      this.props.removeBreakpoint({
	        sourceId: this.props.selectedLocation.sourceId,
	        line: line + 1
	      });
	    } else {
	      this.props.addBreakpoint({ sourceId: this.props.selectedLocation.sourceId,
	        line: line + 1 },
	      // Pass in a function to get line text because the breakpoint
	      // may slide and it needs to compute the value at the new
	      // line.
	      { getTextForLine: l => getTextForLine(this.editor.codeMirror, l) });
	    }
	  },
	
	  clearDebugLine(selectedFrame) {
	    if (selectedFrame) {
	      var line = selectedFrame.location.line;
	      this.editor.codeMirror.removeLineClass(line - 1, "line", "debug-line");
	    }
	  },
	
	  setDebugLine(selectedFrame, selectedLocation) {
	    if (selectedFrame && selectedLocation && selectedFrame.location.sourceId === selectedLocation.sourceId) {
	      var line = selectedFrame.location.line;
	      this.editor.codeMirror.addLineClass(line - 1, "line", "debug-line");
	    }
	  },
	
	  highlightLine() {
	    if (!this.pendingJumpLine) {
	      return;
	    }
	
	    // If the location has changed and a specific line is requested,
	    // move to that line and flash it.
	    var codeMirror = this.editor.codeMirror;
	
	    // Make sure to clean up after ourselves. Not only does this
	    // cancel any existing animation, but it avoids it from
	    // happening ever again (in case CodeMirror re-applies the
	    // class, etc).
	    if (this.lastJumpLine) {
	      codeMirror.removeLineClass(this.lastJumpLine - 1, "line", "highlight-line");
	    }
	
	    var line = this.pendingJumpLine;
	    this.editor.alignLine(line);
	
	    // We only want to do the flashing animation if it's not a debug
	    // line, which has it's own styling.
	    if (!this.props.selectedFrame || this.props.selectedFrame.location.line !== line) {
	      this.editor.codeMirror.addLineClass(line - 1, "line", "highlight-line");
	    }
	
	    this.lastJumpLine = line;
	    this.pendingJumpLine = null;
	  },
	
	  setText(text) {
	    if (!text || !this.editor) {
	      return;
	    }
	
	    this.editor.setText(text);
	  },
	
	  setMode(sourceText) {
	    var contentType = sourceText.get("contentType");
	
	    if (contentType.includes("javascript")) {
	      this.editor.setMode({ name: "javascript" });
	    } else if (contentType === "text/wasm") {
	      this.editor.setMode({ name: "text" });
	    } else if (sourceText.get("text").match(/^\s*</)) {
	      // Use HTML mode for files in which the first non whitespace
	      // character is `<` regardless of extension.
	      this.editor.setMode({ name: "htmlmixed" });
	    } else {
	      this.editor.setMode({ name: "text" });
	    }
	  },
	
	  showGutterMenu(e, line, bp) {
	    var bpLabel = void 0;
	    var cbLabel = void 0;
	    if (!bp) {
	      bpLabel = L10N.getStr("editor.addBreakpoint");
	      cbLabel = L10N.getStr("editor.addConditionalBreakpoint");
	    } else {
	      bpLabel = L10N.getStr("editor.removeBreakpoint");
	      cbLabel = L10N.getStr("editor.editBreakpoint");
	    }
	
	    var toggleBreakpoint = {
	      id: "node-menu-breakpoint",
	      label: bpLabel,
	      accesskey: "B",
	      disabled: false,
	      click: () => {
	        this.toggleBreakpoint(line);
	        if (this.isCbPanelOpen()) {
	          this.closeConditionalPanel();
	        }
	      }
	    };
	
	    var conditionalBreakpoint = {
	      id: "node-menu-conditional-breakpoint",
	      label: cbLabel,
	      accesskey: "C",
	      disabled: false,
	      click: () => this.showConditionalPanel(line)
	    };
	
	    showMenu(e, [toggleBreakpoint, conditionalBreakpoint]);
	  },
	
	  componentDidMount() {
	    this.cbPanel = null;
	
	    this.editor = new SourceEditor({
	      mode: "javascript",
	      readOnly: true,
	      lineNumbers: true,
	      theme: "mozilla",
	      lineWrapping: false,
	      matchBrackets: true,
	      showAnnotationRuler: true,
	      enableCodeFolding: false,
	      gutters: ["breakpoints"],
	      value: " ",
	      extraKeys: {}
	    });
	
	    // disables the default search shortcuts
	    if (isEnabled("editorSearch")) {
	      this.editor._initShortcuts = () => {};
	    }
	
	    this.editor.appendToLocalElement(ReactDOM.findDOMNode(this).querySelector(".editor-mount"));
	
	    this.editor.codeMirror.on("gutterClick", this.onGutterClick);
	
	    if (!isFirefox()) {
	      this.editor.codeMirror.on("gutterContextMenu", (cm, line, eventName, event) => this.onGutterContextMenu(event));
	    } else {
	      this.editor.codeMirror.getWrapperElement().addEventListener("contextmenu", event => this.onGutterContextMenu(event), false);
	    }
	
	    resizeBreakpointGutter(this.editor.codeMirror);
	    debugGlobal("cm", this.editor.codeMirror);
	
	    if (this.props.sourceText) {
	      this.setText(this.props.sourceText.get("text"));
	    }
	  },
	
	  componentWillUnmount() {
	    this.editor.destroy();
	    this.editor = null;
	  },
	
	  componentWillReceiveProps(nextProps) {
	    // This lifecycle method is responsible for updating the editor
	    // text.
	    var sourceText = nextProps.sourceText;
	    var selectedLocation = nextProps.selectedLocation;
	
	    this.clearDebugLine(this.props.selectedFrame);
	
	    if (!sourceText) {
	      this.showMessage("");
	    } else if (!isTextForSource(sourceText)) {
	      this.showMessage(sourceText.get("error") || "Loading...");
	    } else if (this.props.sourceText !== sourceText) {
	      this.showSourceText(sourceText, selectedLocation);
	    }
	
	    this.setDebugLine(nextProps.selectedFrame, selectedLocation);
	    resizeBreakpointGutter(this.editor.codeMirror);
	  },
	
	  showMessage(msg) {
	    this.editor.replaceDocument(this.editor.createDocument());
	    this.setText(msg);
	    this.editor.setMode({ name: "text" });
	  },
	
	  /**
	   * Handle getting the source document or creating a new
	   * document with the correct mode and text.
	   *
	   */
	  showSourceText(sourceText, selectedLocation) {
	    var doc = getDocument(selectedLocation.sourceId);
	    if (doc) {
	      this.editor.replaceDocument(doc);
	      return doc;
	    }
	
	    doc = this.editor.createDocument();
	    setDocument(selectedLocation.sourceId, doc);
	    this.editor.replaceDocument(doc);
	
	    this.setText(sourceText.get("text"));
	    this.setMode(sourceText);
	  },
	
	  componentDidUpdate(prevProps) {
	    // This is in `componentDidUpdate` so helper functions can expect
	    // `this.props` to be the current props. This lifecycle method is
	    // responsible for updating the editor annotations.
	    var selectedLocation = this.props.selectedLocation;
	
	    // If the location is different and a new line is requested,
	    // update the pending jump line. Note that if jumping to a line in
	    // a source where the text hasn't been loaded yet, we will set the
	    // line here but not jump until rendering the actual source.
	
	    if (prevProps.selectedLocation !== selectedLocation) {
	      if (selectedLocation && selectedLocation.line != undefined) {
	        this.pendingJumpLine = selectedLocation.line;
	      } else {
	        this.pendingJumpLine = null;
	      }
	    }
	
	    // Only update and jump around in real source texts. This will
	    // keep the jump state around until the real source text is
	    // loaded.
	    if (this.props.sourceText && isTextForSource(this.props.sourceText)) {
	      this.highlightLine();
	    }
	  },
	
	  renderBreakpoints() {
	    var _props2 = this.props;
	    var breakpoints = _props2.breakpoints;
	    var sourceText = _props2.sourceText;
	
	    var isLoading = sourceText && sourceText.get("loading");
	
	    if (isLoading) {
	      return;
	    }
	
	    return breakpoints.valueSeq().map(bp => {
	      return Breakpoint({
	        key: makeLocationId(bp.location),
	        breakpoint: bp,
	        editor: this.editor && this.editor.codeMirror
	      });
	    });
	  },
	
	  editorHeight() {
	    var selectedSource = this.props.selectedSource;
	
	
	    if (!selectedSource || !shouldShowFooter(selectedSource.toJS())) {
	      return "100%";
	    }
	
	    return "";
	  },
	
	  render() {
	    var sourceText = this.props.sourceText;
	
	
	    return dom.div({ className: "editor-wrapper devtools-monospace" }, EditorSearchBar({
	      editor: this.editor,
	      sourceText
	    }), dom.div({
	      className: "editor-mount",
	      style: { height: this.editorHeight() }
	    }), this.renderBreakpoints(), SourceFooter({ editor: this.editor }));
	  }
	});
	
	module.exports = connect(state => {
	  var selectedLocation = getSelectedLocation(state);
	  var sourceId = selectedLocation && selectedLocation.sourceId;
	  var selectedSource = getSelectedSource(state);
	
	  return {
	    selectedLocation,
	    selectedSource,
	    sourceText: getSourceText(state, sourceId),
	    breakpoints: getBreakpointsForSource(state, sourceId),
	    selectedFrame: getSelectedFrame(state)
	  };
	}, dispatch => bindActionCreators(actions, dispatch))(Editor);

/***/ },
/* 401 */
/***/ function(module, exports) {

	module.exports = devtoolsRequire("devtools/client/sourceeditor/editor");

/***/ },
/* 402 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(259);
	
	var getSelectedSource = _require3.getSelectedSource;
	var getSourceText = _require3.getSourceText;
	var getPrettySource = _require3.getPrettySource;
	
	var Svg = __webpack_require__(310);
	var ImPropTypes = __webpack_require__(235);
	var classnames = __webpack_require__(211);
	
	var _require4 = __webpack_require__(277);
	
	var isPretty = _require4.isPretty;
	
	var _require5 = __webpack_require__(403);
	
	var shouldShowFooter = _require5.shouldShowFooter;
	var shouldShowPrettyPrint = _require5.shouldShowPrettyPrint;
	
	
	__webpack_require__(404);
	
	function debugBtn(onClick, type) {
	  var className = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "active";
	  var tooltip = arguments[3];
	
	  className = `${ type } ${ className }`;
	  return dom.span({ onClick, className, key: type }, Svg(type, { title: tooltip }));
	}
	
	var SourceFooter = React.createClass({
	  propTypes: {
	    selectedSource: ImPropTypes.map,
	    togglePrettyPrint: PropTypes.func,
	    sourceText: ImPropTypes.map,
	    selectSource: PropTypes.func,
	    prettySource: ImPropTypes.map,
	    editor: PropTypes.object
	  },
	
	  displayName: "SourceFooter",
	
	  onClickPrettyPrint() {
	    this.props.togglePrettyPrint(this.props.selectedSource.get("id"));
	  },
	
	  prettyPrintButton() {
	    var _props = this.props;
	    var selectedSource = _props.selectedSource;
	    var sourceText = _props.sourceText;
	
	    var sourceLoaded = selectedSource && !sourceText.get("loading");
	
	    if (!shouldShowPrettyPrint(selectedSource.toJS())) {
	      return;
	    }
	
	    return debugBtn(this.onClickPrettyPrint, "prettyPrint", classnames({
	      active: sourceLoaded,
	      pretty: isPretty(selectedSource.toJS())
	    }), "Prettify Source");
	  },
	
	  render() {
	    var selectedSource = this.props.selectedSource;
	
	
	    if (!selectedSource || !shouldShowFooter(selectedSource.toJS())) {
	      return null;
	    }
	
	    return dom.div({ className: "source-footer" }, dom.div({ className: "command-bar" }, this.prettyPrintButton()));
	  }
	});
	
	module.exports = connect(state => {
	  var selectedSource = getSelectedSource(state);
	  var selectedId = selectedSource && selectedSource.get("id");
	  return {
	    selectedSource,
	    sourceText: getSourceText(state, selectedId),
	    prettySource: getPrettySource(state, selectedId)
	  };
	}, dispatch => bindActionCreators(actions, dispatch))(SourceFooter);

/***/ },
/* 403 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(277);
	
	var isPretty = _require.isPretty;
	
	var _require2 = __webpack_require__(89);
	
	var isEnabled = _require2.isEnabled;
	
	var _require3 = __webpack_require__(264);
	
	var isOriginalId = _require3.isOriginalId;
	
	
	function shouldShowPrettyPrint(selectedSource) {
	  if (!isEnabled("prettyPrint")) {
	    return false;
	  }
	
	  var _isPretty = isPretty(selectedSource);
	  var isOriginal = isOriginalId(selectedSource.id);
	  var hasSourceMap = selectedSource.sourceMapURL;
	
	  if (_isPretty || isOriginal || hasSourceMap) {
	    return false;
	  }
	
	  return true;
	}
	
	function shouldShowFooter(selectedSource) {
	  return shouldShowPrettyPrint(selectedSource);
	}
	
	module.exports = {
	  shouldShowPrettyPrint,
	  shouldShowFooter
	};

/***/ },
/* 404 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 405 */,
/* 406 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var _require = __webpack_require__(16);
	
	var findDOMNode = _require.findDOMNode;
	
	var Svg = __webpack_require__(310);
	
	var _require2 = __webpack_require__(407);
	
	var find = _require2.find;
	var findNext = _require2.findNext;
	var findPrev = _require2.findPrev;
	
	var classnames = __webpack_require__(211);
	
	var _require3 = __webpack_require__(408);
	
	var debounce = _require3.debounce;
	var escapeRegExp = _require3.escapeRegExp;
	
	var CloseButton = __webpack_require__(336);
	
	var _require4 = __webpack_require__(89);
	
	var isEnabled = _require4.isEnabled;
	
	
	__webpack_require__(409);
	
	function countMatches(query, text) {
	  var re = new RegExp(escapeRegExp(query), "g");
	  var match = text.match(re);
	  return match ? match.length : 0;
	}
	
	var EditorSearchBar = React.createClass({
	
	  propTypes: {
	    editor: PropTypes.object,
	    sourceText: PropTypes.object
	  },
	
	  displayName: "EditorSearchBar",
	
	  getInitialState() {
	    return {
	      enabled: false,
	      query: "",
	      count: 0,
	      index: 0
	    };
	  },
	
	  contextTypes: {
	    shortcuts: PropTypes.object
	  },
	
	  componentWillUnmount() {
	    var shortcuts = this.context.shortcuts;
	    if (isEnabled("editorSearch")) {
	      shortcuts.off("CmdOrCtrl+F", this.toggleSearch);
	      shortcuts.off("Escape", this.onEscape);
	    }
	  },
	
	  componentDidMount() {
	    var shortcuts = this.context.shortcuts;
	    if (isEnabled("editorSearch")) {
	      shortcuts.on("CmdOrCtrl+F", this.toggleSearch);
	      shortcuts.on("Escape", this.onEscape);
	    }
	  },
	
	  componentWillReceiveProps() {
	    var shortcuts = this.context.shortcuts;
	    shortcuts.on("CmdOrCtrl+Shift+G", (_, e) => this.traverseResultsPrev(e));
	    shortcuts.on("CmdOrCtrl+G", (_, e) => this.traverseResultsNext(e));
	  },
	
	  componentDidUpdate() {
	    if (this.searchInput()) {
	      this.searchInput().focus();
	    }
	  },
	
	  onEscape(shortcut, e) {
	    this.closeSearch(e);
	  },
	
	  closeSearch(e) {
	    if (this.state.enabled) {
	      this.setState({ enabled: false });
	      e.stopPropagation();
	      e.preventDefault();
	    }
	  },
	
	  toggleSearch(shortcut, e) {
	    e.stopPropagation();
	    e.preventDefault();
	
	    this.setState({ enabled: !this.state.enabled });
	
	    if (this.state.enabled) {
	      var node = this.searchInput();
	      if (node) {
	        node.setSelectionRange(0, node.value.length);
	      }
	    }
	  },
	
	  searchInput() {
	    return findDOMNode(this).querySelector("input");
	  },
	
	  onChange(e) {
	    var query = e.target.value;
	
	    var count = countMatches(query, this.props.sourceText.get("text"));
	    this.setState({ query, count, index: 0 });
	
	    this.search(query);
	  },
	
	  traverseResultsPrev(e) {
	    e.stopPropagation();
	    e.preventDefault();
	
	    var ed = this.props.editor;
	    var ctx = { ed, cm: ed.codeMirror };
	    var _state = this.state;
	    var query = _state.query;
	    var index = _state.index;
	    var count = _state.count;
	
	
	    findPrev(ctx, query);
	    var nextIndex = index == 0 ? count - 1 : index - 1;
	    this.setState({ index: nextIndex });
	  },
	
	  traverseResultsNext(e) {
	    e.stopPropagation();
	    e.preventDefault();
	
	    var ed = this.props.editor;
	    var ctx = { ed, cm: ed.codeMirror };
	    var _state2 = this.state;
	    var query = _state2.query;
	    var index = _state2.index;
	    var count = _state2.count;
	
	
	    findNext(ctx, query);
	    var nextIndex = index == count - 1 ? 0 : index + 1;
	    this.setState({ index: nextIndex });
	  },
	
	  onKeyUp(e) {
	    if (e.key != "Enter") {
	      return;
	    }
	
	    if (e.shiftKey) {
	      this.traverseResultsPrev(e);
	    } else {
	      this.traverseResultsNext(e);
	    }
	  },
	
	  search: debounce(function (query) {
	    var ed = this.props.editor;
	    var ctx = { ed, cm: ed.codeMirror };
	
	    find(ctx, query);
	  }, 100),
	
	  renderSummary() {
	    var _state3 = this.state;
	    var count = _state3.count;
	    var index = _state3.index;
	    var query = _state3.query;
	
	
	    if (query.trim() == "") {
	      return dom.div({});
	    } else if (count == 0) {
	      return dom.div({ className: "summary" }, L10N.getStr("editor.noResults"));
	    }
	
	    return dom.div({ className: "summary" }, L10N.getFormatStr("editor.searchResults", index + 1, count));
	  },
	
	  renderSvg() {
	    var _state4 = this.state;
	    var count = _state4.count;
	    var query = _state4.query;
	
	
	    if (count == 0 && query.trim() != "") {
	      return Svg("sad-face");
	    }
	
	    return Svg("magnifying-glass");
	  },
	
	  render() {
	    if (!this.state.enabled) {
	      return dom.div();
	    }
	
	    var _state5 = this.state;
	    var count = _state5.count;
	    var query = _state5.query;
	
	
	    return dom.div({ className: "search-bar" }, this.renderSvg(), dom.input({
	      className: classnames({
	        empty: count == 0 && query.trim() != ""
	      }),
	      onChange: this.onChange,
	      onKeyUp: this.onKeyUp,
	      placeholder: "Search in file...",
	      value: this.state.query,
	      spellCheck: false
	    }), this.renderSummary(), CloseButton({
	      handleClick: this.closeSearch,
	      buttonClass: "big"
	    }));
	  }
	});
	
	module.exports = EditorSearchBar;

/***/ },
/* 407 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(408);
	
	var escapeRegExp = _require.escapeRegExp;
	/**
	 * These functions implement search within the debugger. Since
	 * search in the debugger is different from other components,
	 * we can't use search.js CodeMirror addon. This is a slightly
	 * modified version of that addon. Depends on searchcursor.js.
	 * @module utils/source-search
	 */
	
	/**
	 * @memberof utils/source-search
	 * @static
	 */
	
	function SearchState() {
	  this.posFrom = this.posTo = this.query = null;
	  this.overlay = null;
	}
	
	/**
	 * @memberof utils/source-search
	 * @static
	 */
	function getSearchState(cm) {
	  return cm.state.search || (cm.state.search = new SearchState());
	}
	
	/**
	 * @memberof utils/source-search
	 * @static
	 */
	function getSearchCursor(cm, query, pos) {
	  // If the query string is all lowercase, do a case insensitive search.
	  return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
	}
	
	/**
	 * Ignore doing outline matches for less than 3 whitespaces
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function ignoreWhiteSpace(str) {
	  return (/^\s{0,2}$/.test(str) ? "(?!\s*.*)" : str
	  );
	}
	
	/**
	 * This returns a mode object used by CoeMirror's addOverlay function
	 * to parse and style tokens in the file.
	 * The mode object contains a tokenizer function (token) which takes
	 * a character stream as input, advances it past a token, and returns
	 * a style for that token. For more details see
	 * https://codemirror.net/doc/manual.html#modeapi
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function searchOverlay(query) {
	  query = new RegExp(escapeRegExp(ignoreWhiteSpace(query)), "g");
	  return {
	    token: function (stream) {
	      query.lastIndex = stream.pos;
	      var match = query.exec(stream.string);
	      if (match && match.index == stream.pos) {
	        stream.pos += match[0].length || 1;
	        return "selecting";
	      } else if (match) {
	        stream.pos = match.index;
	      } else {
	        stream.skipToEnd();
	      }
	    }
	  };
	}
	
	/**
	 * @memberof utils/source-search
	 * @static
	 */
	function startSearch(cm, state, query) {
	  cm.removeOverlay(state.overlay);
	  state.overlay = searchOverlay(query);
	  cm.addOverlay(state.overlay, { opaque: true });
	}
	
	/**
	 * If there's a saved search, selects the next results.
	 * Otherwise, creates a new search and selects the first
	 * result.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function doSearch(ctx, rev, query) {
	  var cm = ctx.cm;
	
	  var state = getSearchState(cm);
	
	  if (state.query) {
	    searchNext(ctx, rev);
	    return;
	  }
	
	  cm.operation(function () {
	    if (state.query) {
	      return;
	    }
	    startSearch(cm, state, query);
	    state.query = query;
	    state.posFrom = state.posTo = { line: 0, ch: 0 };
	    searchNext(ctx, rev);
	  });
	}
	
	/**
	 * Selects the next result of a saved search.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function searchNext(ctx, rev) {
	  var cm = ctx.cm;
	  var ed = ctx.ed;
	
	  cm.operation(function () {
	    var state = getSearchState(cm);
	    var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
	
	    if (!cursor.find(rev)) {
	      cursor = getSearchCursor(cm, state.query, rev ? { line: cm.lastLine(), ch: null } : { line: cm.firstLine(), ch: 0 });
	      if (!cursor.find(rev)) {
	        return;
	      }
	    }
	
	    ed.alignLine(cursor.from().line, "center");
	    cm.setSelection(cursor.from(), cursor.to());
	    state.posFrom = cursor.from();
	    state.posTo = cursor.to();
	  });
	}
	
	/**
	 * Clears the currently saved search.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function clearSearch(cm) {
	  var state = getSearchState(cm);
	
	  if (!state.query) {
	    return;
	  }
	  cm.removeOverlay(state.overlay);
	  state.query = null;
	}
	
	/**
	 * Starts a new search.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function find(ctx, query) {
	  clearSearch(ctx.cm);
	  doSearch(ctx, false, query);
	}
	
	/**
	 * Finds the next item based on the currently saved search.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function findNext(ctx, query) {
	  doSearch(ctx, false, query);
	}
	
	/**
	 * Finds the previous item based on the currently saved search.
	 *
	 * @memberof utils/source-search
	 * @static
	 */
	function findPrev(ctx, query) {
	  doSearch(ctx, true, query);
	}
	
	module.exports = { find, findNext, findPrev };

/***/ },
/* 408 */
/***/ function(module, exports, __webpack_require__) {

	var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(global, module) {/**
	 * @license
	 * lodash <https://lodash.com/>
	 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
	 * Released under MIT license <https://lodash.com/license>
	 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
	 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
	 */
	;(function() {
	
	  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
	  var undefined;
	
	  /** Used as the semantic version number. */
	  var VERSION = '4.16.4';
	
	  /** Used as the size to enable large array optimizations. */
	  var LARGE_ARRAY_SIZE = 200;
	
	  /** Error message constants. */
	  var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://github.com/es-shims.',
	      FUNC_ERROR_TEXT = 'Expected a function';
	
	  /** Used to stand-in for `undefined` hash values. */
	  var HASH_UNDEFINED = '__lodash_hash_undefined__';
	
	  /** Used as the maximum memoize cache size. */
	  var MAX_MEMOIZE_SIZE = 500;
	
	  /** Used as the internal argument placeholder. */
	  var PLACEHOLDER = '__lodash_placeholder__';
	
	  /** Used to compose bitmasks for function metadata. */
	  var BIND_FLAG = 1,
	      BIND_KEY_FLAG = 2,
	      CURRY_BOUND_FLAG = 4,
	      CURRY_FLAG = 8,
	      CURRY_RIGHT_FLAG = 16,
	      PARTIAL_FLAG = 32,
	      PARTIAL_RIGHT_FLAG = 64,
	      ARY_FLAG = 128,
	      REARG_FLAG = 256,
	      FLIP_FLAG = 512;
	
	  /** Used to compose bitmasks for comparison styles. */
	  var UNORDERED_COMPARE_FLAG = 1,
	      PARTIAL_COMPARE_FLAG = 2;
	
	  /** Used as default options for `_.truncate`. */
	  var DEFAULT_TRUNC_LENGTH = 30,
	      DEFAULT_TRUNC_OMISSION = '...';
	
	  /** Used to detect hot functions by number of calls within a span of milliseconds. */
	  var HOT_COUNT = 500,
	      HOT_SPAN = 16;
	
	  /** Used to indicate the type of lazy iteratees. */
	  var LAZY_FILTER_FLAG = 1,
	      LAZY_MAP_FLAG = 2,
	      LAZY_WHILE_FLAG = 3;
	
	  /** Used as references for various `Number` constants. */
	  var INFINITY = 1 / 0,
	      MAX_SAFE_INTEGER = 9007199254740991,
	      MAX_INTEGER = 1.7976931348623157e+308,
	      NAN = 0 / 0;
	
	  /** Used as references for the maximum length and index of an array. */
	  var MAX_ARRAY_LENGTH = 4294967295,
	      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1,
	      HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1;
	
	  /** Used to associate wrap methods with their bit flags. */
	  var wrapFlags = [
	    ['ary', ARY_FLAG],
	    ['bind', BIND_FLAG],
	    ['bindKey', BIND_KEY_FLAG],
	    ['curry', CURRY_FLAG],
	    ['curryRight', CURRY_RIGHT_FLAG],
	    ['flip', FLIP_FLAG],
	    ['partial', PARTIAL_FLAG],
	    ['partialRight', PARTIAL_RIGHT_FLAG],
	    ['rearg', REARG_FLAG]
	  ];
	
	  /** `Object#toString` result references. */
	  var argsTag = '[object Arguments]',
	      arrayTag = '[object Array]',
	      boolTag = '[object Boolean]',
	      dateTag = '[object Date]',
	      errorTag = '[object Error]',
	      funcTag = '[object Function]',
	      genTag = '[object GeneratorFunction]',
	      mapTag = '[object Map]',
	      numberTag = '[object Number]',
	      objectTag = '[object Object]',
	      promiseTag = '[object Promise]',
	      proxyTag = '[object Proxy]',
	      regexpTag = '[object RegExp]',
	      setTag = '[object Set]',
	      stringTag = '[object String]',
	      symbolTag = '[object Symbol]',
	      weakMapTag = '[object WeakMap]',
	      weakSetTag = '[object WeakSet]';
	
	  var arrayBufferTag = '[object ArrayBuffer]',
	      dataViewTag = '[object DataView]',
	      float32Tag = '[object Float32Array]',
	      float64Tag = '[object Float64Array]',
	      int8Tag = '[object Int8Array]',
	      int16Tag = '[object Int16Array]',
	      int32Tag = '[object Int32Array]',
	      uint8Tag = '[object Uint8Array]',
	      uint8ClampedTag = '[object Uint8ClampedArray]',
	      uint16Tag = '[object Uint16Array]',
	      uint32Tag = '[object Uint32Array]';
	
	  /** Used to match empty string literals in compiled template source. */
	  var reEmptyStringLeading = /\b__p \+= '';/g,
	      reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
	      reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
	
	  /** Used to match HTML entities and HTML characters. */
	  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
	      reUnescapedHtml = /[&<>"']/g,
	      reHasEscapedHtml = RegExp(reEscapedHtml.source),
	      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
	
	  /** Used to match template delimiters. */
	  var reEscape = /<%-([\s\S]+?)%>/g,
	      reEvaluate = /<%([\s\S]+?)%>/g,
	      reInterpolate = /<%=([\s\S]+?)%>/g;
	
	  /** Used to match property names within property paths. */
	  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
	      reIsPlainProp = /^\w*$/,
	      reLeadingDot = /^\./,
	      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
	
	  /**
	   * Used to match `RegExp`
	   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
	   */
	  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
	      reHasRegExpChar = RegExp(reRegExpChar.source);
	
	  /** Used to match leading and trailing whitespace. */
	  var reTrim = /^\s+|\s+$/g,
	      reTrimStart = /^\s+/,
	      reTrimEnd = /\s+$/;
	
	  /** Used to match wrap detail comments. */
	  var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,
	      reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/,
	      reSplitDetails = /,? & /;
	
	  /** Used to match words composed of alphanumeric characters. */
	  var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
	
	  /** Used to match backslashes in property paths. */
	  var reEscapeChar = /\\(\\)?/g;
	
	  /**
	   * Used to match
	   * [ES template delimiters](http://ecma-international.org/ecma-262/7.0/#sec-template-literal-lexical-components).
	   */
	  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
	
	  /** Used to match `RegExp` flags from their coerced string values. */
	  var reFlags = /\w*$/;
	
	  /** Used to detect bad signed hexadecimal string values. */
	  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
	
	  /** Used to detect binary string values. */
	  var reIsBinary = /^0b[01]+$/i;
	
	  /** Used to detect host constructors (Safari). */
	  var reIsHostCtor = /^\[object .+?Constructor\]$/;
	
	  /** Used to detect octal string values. */
	  var reIsOctal = /^0o[0-7]+$/i;
	
	  /** Used to detect unsigned integer values. */
	  var reIsUint = /^(?:0|[1-9]\d*)$/;
	
	  /** Used to match Latin Unicode letters (excluding mathematical operators). */
	  var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
	
	  /** Used to ensure capturing order of template delimiters. */
	  var reNoMatch = /($^)/;
	
	  /** Used to match unescaped characters in compiled string literals. */
	  var reUnescapedString = /['\n\r\u2028\u2029\\]/g;
	
	  /** Used to compose unicode character classes. */
	  var rsAstralRange = '\\ud800-\\udfff',
	      rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
	      rsComboSymbolsRange = '\\u20d0-\\u20f0',
	      rsDingbatRange = '\\u2700-\\u27bf',
	      rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
	      rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
	      rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
	      rsPunctuationRange = '\\u2000-\\u206f',
	      rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
	      rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
	      rsVarRange = '\\ufe0e\\ufe0f',
	      rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
	
	  /** Used to compose unicode capture groups. */
	  var rsApos = "['\u2019]",
	      rsAstral = '[' + rsAstralRange + ']',
	      rsBreak = '[' + rsBreakRange + ']',
	      rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
	      rsDigits = '\\d+',
	      rsDingbat = '[' + rsDingbatRange + ']',
	      rsLower = '[' + rsLowerRange + ']',
	      rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
	      rsFitz = '\\ud83c[\\udffb-\\udfff]',
	      rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
	      rsNonAstral = '[^' + rsAstralRange + ']',
	      rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
	      rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
	      rsUpper = '[' + rsUpperRange + ']',
	      rsZWJ = '\\u200d';
	
	  /** Used to compose unicode regexes. */
	  var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
	      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
	      rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
	      rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
	      reOptMod = rsModifier + '?',
	      rsOptVar = '[' + rsVarRange + ']?',
	      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
	      rsSeq = rsOptVar + reOptMod + rsOptJoin,
	      rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq,
	      rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')';
	
	  /** Used to match apostrophes. */
	  var reApos = RegExp(rsApos, 'g');
	
	  /**
	   * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
	   * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
	   */
	  var reComboMark = RegExp(rsCombo, 'g');
	
	  /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */
	  var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
	
	  /** Used to match complex or compound words. */
	  var reUnicodeWord = RegExp([
	    rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
	    rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
	    rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
	    rsUpper + '+' + rsOptUpperContr,
	    rsDigits,
	    rsEmoji
	  ].join('|'), 'g');
	
	  /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */
	  var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
	
	  /** Used to detect strings that need a more robust regexp to match words. */
	  var reHasUnicodeWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
	
	  /** Used to assign default `context` object properties. */
	  var contextProps = [
	    'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array',
	    'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object',
	    'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', 'Uint8Array',
	    'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap',
	    '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout'
	  ];
	
	  /** Used to make template sourceURLs easier to identify. */
	  var templateCounter = -1;
	
	  /** Used to identify `toStringTag` values of typed arrays. */
	  var typedArrayTags = {};
	  typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
	  typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
	  typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
	  typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
	  typedArrayTags[uint32Tag] = true;
	  typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
	  typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
	  typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
	  typedArrayTags[errorTag] = typedArrayTags[funcTag] =
	  typedArrayTags[mapTag] = typedArrayTags[numberTag] =
	  typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
	  typedArrayTags[setTag] = typedArrayTags[stringTag] =
	  typedArrayTags[weakMapTag] = false;
	
	  /** Used to identify `toStringTag` values supported by `_.clone`. */
	  var cloneableTags = {};
	  cloneableTags[argsTag] = cloneableTags[arrayTag] =
	  cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =
	  cloneableTags[boolTag] = cloneableTags[dateTag] =
	  cloneableTags[float32Tag] = cloneableTags[float64Tag] =
	  cloneableTags[int8Tag] = cloneableTags[int16Tag] =
	  cloneableTags[int32Tag] = cloneableTags[mapTag] =
	  cloneableTags[numberTag] = cloneableTags[objectTag] =
	  cloneableTags[regexpTag] = cloneableTags[setTag] =
	  cloneableTags[stringTag] = cloneableTags[symbolTag] =
	  cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
	  cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
	  cloneableTags[errorTag] = cloneableTags[funcTag] =
	  cloneableTags[weakMapTag] = false;
	
	  /** Used to map Latin Unicode letters to basic Latin letters. */
	  var deburredLetters = {
	    // Latin-1 Supplement block.
	    '\xc0': 'A',  '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
	    '\xe0': 'a',  '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
	    '\xc7': 'C',  '\xe7': 'c',
	    '\xd0': 'D',  '\xf0': 'd',
	    '\xc8': 'E',  '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
	    '\xe8': 'e',  '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
	    '\xcc': 'I',  '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
	    '\xec': 'i',  '\xed': 'i', '\xee': 'i', '\xef': 'i',
	    '\xd1': 'N',  '\xf1': 'n',
	    '\xd2': 'O',  '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
	    '\xf2': 'o',  '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
	    '\xd9': 'U',  '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
	    '\xf9': 'u',  '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
	    '\xdd': 'Y',  '\xfd': 'y', '\xff': 'y',
	    '\xc6': 'Ae', '\xe6': 'ae',
	    '\xde': 'Th', '\xfe': 'th',
	    '\xdf': 'ss',
	    // Latin Extended-A block.
	    '\u0100': 'A',  '\u0102': 'A', '\u0104': 'A',
	    '\u0101': 'a',  '\u0103': 'a', '\u0105': 'a',
	    '\u0106': 'C',  '\u0108': 'C', '\u010a': 'C', '\u010c': 'C',
	    '\u0107': 'c',  '\u0109': 'c', '\u010b': 'c', '\u010d': 'c',
	    '\u010e': 'D',  '\u0110': 'D', '\u010f': 'd', '\u0111': 'd',
	    '\u0112': 'E',  '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E',
	    '\u0113': 'e',  '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e',
	    '\u011c': 'G',  '\u011e': 'G', '\u0120': 'G', '\u0122': 'G',
	    '\u011d': 'g',  '\u011f': 'g', '\u0121': 'g', '\u0123': 'g',
	    '\u0124': 'H',  '\u0126': 'H', '\u0125': 'h', '\u0127': 'h',
	    '\u0128': 'I',  '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I',
	    '\u0129': 'i',  '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i',
	    '\u0134': 'J',  '\u0135': 'j',
	    '\u0136': 'K',  '\u0137': 'k', '\u0138': 'k',
	    '\u0139': 'L',  '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L',
	    '\u013a': 'l',  '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l',
	    '\u0143': 'N',  '\u0145': 'N', '\u0147': 'N', '\u014a': 'N',
	    '\u0144': 'n',  '\u0146': 'n', '\u0148': 'n', '\u014b': 'n',
	    '\u014c': 'O',  '\u014e': 'O', '\u0150': 'O',
	    '\u014d': 'o',  '\u014f': 'o', '\u0151': 'o',
	    '\u0154': 'R',  '\u0156': 'R', '\u0158': 'R',
	    '\u0155': 'r',  '\u0157': 'r', '\u0159': 'r',
	    '\u015a': 'S',  '\u015c': 'S', '\u015e': 'S', '\u0160': 'S',
	    '\u015b': 's',  '\u015d': 's', '\u015f': 's', '\u0161': 's',
	    '\u0162': 'T',  '\u0164': 'T', '\u0166': 'T',
	    '\u0163': 't',  '\u0165': 't', '\u0167': 't',
	    '\u0168': 'U',  '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U',
	    '\u0169': 'u',  '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u',
	    '\u0174': 'W',  '\u0175': 'w',
	    '\u0176': 'Y',  '\u0177': 'y', '\u0178': 'Y',
	    '\u0179': 'Z',  '\u017b': 'Z', '\u017d': 'Z',
	    '\u017a': 'z',  '\u017c': 'z', '\u017e': 'z',
	    '\u0132': 'IJ', '\u0133': 'ij',
	    '\u0152': 'Oe', '\u0153': 'oe',
	    '\u0149': "'n", '\u017f': 's'
	  };
	
	  /** Used to map characters to HTML entities. */
	  var htmlEscapes = {
	    '&': '&amp;',
	    '<': '&lt;',
	    '>': '&gt;',
	    '"': '&quot;',
	    "'": '&#39;'
	  };
	
	  /** Used to map HTML entities to characters. */
	  var htmlUnescapes = {
	    '&amp;': '&',
	    '&lt;': '<',
	    '&gt;': '>',
	    '&quot;': '"',
	    '&#39;': "'"
	  };
	
	  /** Used to escape characters for inclusion in compiled string literals. */
	  var stringEscapes = {
	    '\\': '\\',
	    "'": "'",
	    '\n': 'n',
	    '\r': 'r',
	    '\u2028': 'u2028',
	    '\u2029': 'u2029'
	  };
	
	  /** Built-in method references without a dependency on `root`. */
	  var freeParseFloat = parseFloat,
	      freeParseInt = parseInt;
	
	  /** Detect free variable `global` from Node.js. */
	  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
	
	  /** 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')();
	
	  /** Detect free variable `exports`. */
	  var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
	
	  /** Detect free variable `module`. */
	  var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
	
	  /** Detect the popular CommonJS extension `module.exports`. */
	  var moduleExports = freeModule && freeModule.exports === freeExports;
	
	  /** Detect free variable `process` from Node.js. */
	  var freeProcess = moduleExports && freeGlobal.process;
	
	  /** Used to access faster Node.js helpers. */
	  var nodeUtil = (function() {
	    try {
	      return freeProcess && freeProcess.binding('util');
	    } catch (e) {}
	  }());
	
	  /* Node.js helper references. */
	  var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer,
	      nodeIsDate = nodeUtil && nodeUtil.isDate,
	      nodeIsMap = nodeUtil && nodeUtil.isMap,
	      nodeIsRegExp = nodeUtil && nodeUtil.isRegExp,
	      nodeIsSet = nodeUtil && nodeUtil.isSet,
	      nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
	
	  /*--------------------------------------------------------------------------*/
	
	  /**
	   * Adds the key-value `pair` to `map`.
	   *
	   * @private
	   * @param {Object} map The map to modify.
	   * @param {Array} pair The key-value pair to add.
	   * @returns {Object} Returns `map`.
	   */
	  function addMapEntry(map, pair) {
	    // Don't return `map.set` because it's not chainable in IE 11.
	    map.set(pair[0], pair[1]);
	    return map;
	  }
	
	  /**
	   * Adds `value` to `set`.
	   *
	   * @private
	   * @param {Object} set The set to modify.
	   * @param {*} value The value to add.
	   * @returns {Object} Returns `set`.
	   */
	  function addSetEntry(set, value) {
	    // Don't return `set.add` because it's not chainable in IE 11.
	    set.add(value);
	    return set;
	  }
	
	  /**
	   * A faster alternative to `Function#apply`, this function invokes `func`
	   * with the `this` binding of `thisArg` and the arguments of `args`.
	   *
	   * @private
	   * @param {Function} func The function to invoke.
	   * @param {*} thisArg The `this` binding of `func`.
	   * @param {Array} args The arguments to invoke `func` with.
	   * @returns {*} Returns the result of `func`.
	   */
	  function apply(func, thisArg, args) {
	    switch (args.length) {
	      case 0: return func.call(thisArg);
	      case 1: return func.call(thisArg, args[0]);
	      case 2: return func.call(thisArg, args[0], args[1]);
	      case 3: return func.call(thisArg, args[0], args[1], args[2]);
	    }
	    return func.apply(thisArg, args);
	  }
	
	  /**
	   * A specialized version of `baseAggregator` for arrays.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} setter The function to set `accumulator` values.
	   * @param {Function} iteratee The iteratee to transform keys.
	   * @param {Object} accumulator The initial aggregated object.
	   * @returns {Function} Returns `accumulator`.
	   */
	  function arrayAggregator(array, setter, iteratee, accumulator) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    while (++index < length) {
	      var value = array[index];
	      setter(accumulator, value, iteratee(value), array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.forEach` 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 `array`.
	   */
	  function arrayEach(array, iteratee) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    while (++index < length) {
	      if (iteratee(array[index], index, array) === false) {
	        break;
	      }
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.forEachRight` 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 `array`.
	   */
	  function arrayEachRight(array, iteratee) {
	    var length = array ? array.length : 0;
	
	    while (length--) {
	      if (iteratee(array[length], length, array) === false) {
	        break;
	      }
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.every` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} predicate The function invoked per iteration.
	   * @returns {boolean} Returns `true` if all elements pass the predicate check,
	   *  else `false`.
	   */
	  function arrayEvery(array, predicate) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    while (++index < length) {
	      if (!predicate(array[index], index, array)) {
	        return false;
	      }
	    }
	    return true;
	  }
	
	  /**
	   * A specialized version of `_.filter` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} predicate The function invoked per iteration.
	   * @returns {Array} Returns the new filtered array.
	   */
	  function arrayFilter(array, predicate) {
	    var index = -1,
	        length = array ? array.length : 0,
	        resIndex = 0,
	        result = [];
	
	    while (++index < length) {
	      var value = array[index];
	      if (predicate(value, index, array)) {
	        result[resIndex++] = value;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * A specialized version of `_.includes` for arrays without support for
	   * specifying an index to search from.
	   *
	   * @private
	   * @param {Array} [array] The array to inspect.
	   * @param {*} target The value to search for.
	   * @returns {boolean} Returns `true` if `target` is found, else `false`.
	   */
	  function arrayIncludes(array, value) {
	    var length = array ? array.length : 0;
	    return !!length && baseIndexOf(array, value, 0) > -1;
	  }
	
	  /**
	   * This function is like `arrayIncludes` except that it accepts a comparator.
	   *
	   * @private
	   * @param {Array} [array] The array to inspect.
	   * @param {*} target The value to search for.
	   * @param {Function} comparator The comparator invoked per element.
	   * @returns {boolean} Returns `true` if `target` is found, else `false`.
	   */
	  function arrayIncludesWith(array, value, comparator) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    while (++index < length) {
	      if (comparator(value, array[index])) {
	        return true;
	      }
	    }
	    return false;
	  }
	
	  /**
	   * 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 ? array.length : 0,
	        result = Array(length);
	
	    while (++index < length) {
	      result[index] = iteratee(array[index], index, array);
	    }
	    return result;
	  }
	
	  /**
	   * Appends the elements of `values` to `array`.
	   *
	   * @private
	   * @param {Array} array The array to modify.
	   * @param {Array} values The values to append.
	   * @returns {Array} Returns `array`.
	   */
	  function arrayPush(array, values) {
	    var index = -1,
	        length = values.length,
	        offset = array.length;
	
	    while (++index < length) {
	      array[offset + index] = values[index];
	    }
	    return array;
	  }
	
	  /**
	   * A specialized version of `_.reduce` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} [accumulator] The initial value.
	   * @param {boolean} [initAccum] Specify using the first element of `array` as
	   *  the initial value.
	   * @returns {*} Returns the accumulated value.
	   */
	  function arrayReduce(array, iteratee, accumulator, initAccum) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    if (initAccum && length) {
	      accumulator = array[++index];
	    }
	    while (++index < length) {
	      accumulator = iteratee(accumulator, array[index], index, array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.reduceRight` for arrays without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} [accumulator] The initial value.
	   * @param {boolean} [initAccum] Specify using the last element of `array` as
	   *  the initial value.
	   * @returns {*} Returns the accumulated value.
	   */
	  function arrayReduceRight(array, iteratee, accumulator, initAccum) {
	    var length = array ? array.length : 0;
	    if (initAccum && length) {
	      accumulator = array[--length];
	    }
	    while (length--) {
	      accumulator = iteratee(accumulator, array[length], length, array);
	    }
	    return accumulator;
	  }
	
	  /**
	   * A specialized version of `_.some` for arrays without support for iteratee
	   * shorthands.
	   *
	   * @private
	   * @param {Array} [array] The array to iterate over.
	   * @param {Function} predicate The function invoked per iteration.
	   * @returns {boolean} Returns `true` if any element passes the predicate check,
	   *  else `false`.
	   */
	  function arraySome(array, predicate) {
	    var index = -1,
	        length = array ? array.length : 0;
	
	    while (++index < length) {
	      if (predicate(array[index], index, array)) {
	        return true;
	      }
	    }
	    return false;
	  }
	
	  /**
	   * Gets the size of an ASCII `string`.
	   *
	   * @private
	   * @param {string} string The string inspect.
	   * @returns {number} Returns the string size.
	   */
	  var asciiSize = baseProperty('length');
	
	  /**
	   * Converts an ASCII `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function asciiToArray(string) {
	    return string.split('');
	  }
	
	  /**
	   * Splits an ASCII `string` into an array of its words.
	   *
	   * @private
	   * @param {string} The string to inspect.
	   * @returns {Array} Returns the words of `string`.
	   */
	  function asciiWords(string) {
	    return string.match(reAsciiWord) || [];
	  }
	
	  /**
	   * The base implementation of methods like `_.findKey` and `_.findLastKey`,
	   * without support for iteratee shorthands, which iterates over `collection`
	   * using `eachFunc`.
	   *
	   * @private
	   * @param {Array|Object} collection The collection to inspect.
	   * @param {Function} predicate The function invoked per iteration.
	   * @param {Function} eachFunc The function to iterate over `collection`.
	   * @returns {*} Returns the found element or its key, else `undefined`.
	   */
	  function baseFindKey(collection, predicate, eachFunc) {
	    var result;
	    eachFunc(collection, function(value, key, collection) {
	      if (predicate(value, key, collection)) {
	        result = key;
	        return false;
	      }
	    });
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.findIndex` and `_.findLastIndex` without
	   * support for iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {Function} predicate The function invoked per iteration.
	   * @param {number} fromIndex The index to search from.
	   * @param {boolean} [fromRight] Specify iterating from right to left.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseFindIndex(array, predicate, fromIndex, fromRight) {
	    var length = array.length,
	        index = fromIndex + (fromRight ? 1 : -1);
	
	    while ((fromRight ? index-- : ++index < length)) {
	      if (predicate(array[index], index, array)) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseIndexOf(array, value, fromIndex) {
	    return value === value
	      ? strictIndexOf(array, value, fromIndex)
	      : baseFindIndex(array, baseIsNaN, fromIndex);
	  }
	
	  /**
	   * This function is like `baseIndexOf` except that it accepts a comparator.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @param {Function} comparator The comparator invoked per element.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function baseIndexOfWith(array, value, fromIndex, comparator) {
	    var index = fromIndex - 1,
	        length = array.length;
	
	    while (++index < length) {
	      if (comparator(array[index], value)) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * The base implementation of `_.isNaN` without support for number objects.
	   *
	   * @private
	   * @param {*} value The value to check.
	   * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
	   */
	  function baseIsNaN(value) {
	    return value !== value;
	  }
	
	  /**
	   * The base implementation of `_.mean` and `_.meanBy` without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {number} Returns the mean.
	   */
	  function baseMean(array, iteratee) {
	    var length = array ? array.length : 0;
	    return length ? (baseSum(array, iteratee) / length) : NAN;
	  }
	
	  /**
	   * The base implementation of `_.property` without support for deep paths.
	   *
	   * @private
	   * @param {string} key The key of the property to get.
	   * @returns {Function} Returns the new accessor function.
	   */
	  function baseProperty(key) {
	    return function(object) {
	      return object == null ? undefined : object[key];
	    };
	  }
	
	  /**
	   * The base implementation of `_.propertyOf` without support for deep paths.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @returns {Function} Returns the new accessor function.
	   */
	  function basePropertyOf(object) {
	    return function(key) {
	      return object == null ? undefined : object[key];
	    };
	  }
	
	  /**
	   * The base implementation of `_.reduce` and `_.reduceRight`, without support
	   * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
	   *
	   * @private
	   * @param {Array|Object} collection The collection to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @param {*} accumulator The initial value.
	   * @param {boolean} initAccum Specify using the first or last element of
	   *  `collection` as the initial value.
	   * @param {Function} eachFunc The function to iterate over `collection`.
	   * @returns {*} Returns the accumulated value.
	   */
	  function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
	    eachFunc(collection, function(value, index, collection) {
	      accumulator = initAccum
	        ? (initAccum = false, value)
	        : iteratee(accumulator, value, index, collection);
	    });
	    return accumulator;
	  }
	
	  /**
	   * The base implementation of `_.sortBy` which uses `comparer` to define the
	   * sort order of `array` and replaces criteria objects with their corresponding
	   * values.
	   *
	   * @private
	   * @param {Array} array The array to sort.
	   * @param {Function} comparer The function to define sort order.
	   * @returns {Array} Returns `array`.
	   */
	  function baseSortBy(array, comparer) {
	    var length = array.length;
	
	    array.sort(comparer);
	    while (length--) {
	      array[length] = array[length].value;
	    }
	    return array;
	  }
	
	  /**
	   * The base implementation of `_.sum` and `_.sumBy` without support for
	   * iteratee shorthands.
	   *
	   * @private
	   * @param {Array} array The array to iterate over.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {number} Returns the sum.
	   */
	  function baseSum(array, iteratee) {
	    var result,
	        index = -1,
	        length = array.length;
	
	    while (++index < length) {
	      var current = iteratee(array[index]);
	      if (current !== undefined) {
	        result = result === undefined ? current : (result + current);
	      }
	    }
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.times` without support for iteratee shorthands
	   * or max array length checks.
	   *
	   * @private
	   * @param {number} n The number of times to invoke `iteratee`.
	   * @param {Function} iteratee The function invoked per iteration.
	   * @returns {Array} Returns the array of results.
	   */
	  function baseTimes(n, iteratee) {
	    var index = -1,
	        result = Array(n);
	
	    while (++index < n) {
	      result[index] = iteratee(index);
	    }
	    return result;
	  }
	
	  /**
	   * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
	   * of key-value pairs for `object` corresponding to the property names of `props`.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @param {Array} props The property names to get values for.
	   * @returns {Object} Returns the key-value pairs.
	   */
	  function baseToPairs(object, props) {
	    return arrayMap(props, function(key) {
	      return [key, object[key]];
	    });
	  }
	
	  /**
	   * The base implementation of `_.unary` without support for storing metadata.
	   *
	   * @private
	   * @param {Function} func The function to cap arguments for.
	   * @returns {Function} Returns the new capped function.
	   */
	  function baseUnary(func) {
	    return function(value) {
	      return func(value);
	    };
	  }
	
	  /**
	   * The base implementation of `_.values` and `_.valuesIn` which creates an
	   * array of `object` property values corresponding to the property names
	   * of `props`.
	   *
	   * @private
	   * @param {Object} object The object to query.
	   * @param {Array} props The property names to get values for.
	   * @returns {Object} Returns the array of property values.
	   */
	  function baseValues(object, props) {
	    return arrayMap(props, function(key) {
	      return object[key];
	    });
	  }
	
	  /**
	   * Checks if a `cache` value for `key` exists.
	   *
	   * @private
	   * @param {Object} cache The cache to query.
	   * @param {string} key The key of the entry to check.
	   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	   */
	  function cacheHas(cache, key) {
	    return cache.has(key);
	  }
	
	  /**
	   * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol
	   * that is not found in the character symbols.
	   *
	   * @private
	   * @param {Array} strSymbols The string symbols to inspect.
	   * @param {Array} chrSymbols The character symbols to find.
	   * @returns {number} Returns the index of the first unmatched string symbol.
	   */
	  function charsStartIndex(strSymbols, chrSymbols) {
	    var index = -1,
	        length = strSymbols.length;
	
	    while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
	    return index;
	  }
	
	  /**
	   * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol
	   * that is not found in the character symbols.
	   *
	   * @private
	   * @param {Array} strSymbols The string symbols to inspect.
	   * @param {Array} chrSymbols The character symbols to find.
	   * @returns {number} Returns the index of the last unmatched string symbol.
	   */
	  function charsEndIndex(strSymbols, chrSymbols) {
	    var index = strSymbols.length;
	
	    while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {}
	    return index;
	  }
	
	  /**
	   * Gets the number of `placeholder` occurrences in `array`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} placeholder The placeholder to search for.
	   * @returns {number} Returns the placeholder count.
	   */
	  function countHolders(array, placeholder) {
	    var length = array.length,
	        result = 0;
	
	    while (length--) {
	      if (array[length] === placeholder) {
	        ++result;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * Used by `_.deburr` to convert Latin-1 Supplement and Latin Extended-A
	   * letters to basic Latin letters.
	   *
	   * @private
	   * @param {string} letter The matched letter to deburr.
	   * @returns {string} Returns the deburred letter.
	   */
	  var deburrLetter = basePropertyOf(deburredLetters);
	
	  /**
	   * Used by `_.escape` to convert characters to HTML entities.
	   *
	   * @private
	   * @param {string} chr The matched character to escape.
	   * @returns {string} Returns the escaped character.
	   */
	  var escapeHtmlChar = basePropertyOf(htmlEscapes);
	
	  /**
	   * Used by `_.template` to escape characters for inclusion in compiled string literals.
	   *
	   * @private
	   * @param {string} chr The matched character to escape.
	   * @returns {string} Returns the escaped character.
	   */
	  function escapeStringChar(chr) {
	    return '\\' + stringEscapes[chr];
	  }
	
	  /**
	   * 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];
	  }
	
	  /**
	   * Checks if `string` contains Unicode symbols.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {boolean} Returns `true` if a symbol is found, else `false`.
	   */
	  function hasUnicode(string) {
	    return reHasUnicode.test(string);
	  }
	
	  /**
	   * Checks if `string` contains a word composed of Unicode symbols.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {boolean} Returns `true` if a word is found, else `false`.
	   */
	  function hasUnicodeWord(string) {
	    return reHasUnicodeWord.test(string);
	  }
	
	  /**
	   * Converts `iterator` to an array.
	   *
	   * @private
	   * @param {Object} iterator The iterator to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function iteratorToArray(iterator) {
	    var data,
	        result = [];
	
	    while (!(data = iterator.next()).done) {
	      result.push(data.value);
	    }
	    return result;
	  }
	
	  /**
	   * Converts `map` to its key-value pairs.
	   *
	   * @private
	   * @param {Object} map The map to convert.
	   * @returns {Array} Returns the key-value pairs.
	   */
	  function mapToArray(map) {
	    var index = -1,
	        result = Array(map.size);
	
	    map.forEach(function(value, key) {
	      result[++index] = [key, value];
	    });
	    return result;
	  }
	
	  /**
	   * 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));
	    };
	  }
	
	  /**
	   * Replaces all `placeholder` elements in `array` with an internal placeholder
	   * and returns an array of their indexes.
	   *
	   * @private
	   * @param {Array} array The array to modify.
	   * @param {*} placeholder The placeholder to replace.
	   * @returns {Array} Returns the new array of placeholder indexes.
	   */
	  function replaceHolders(array, placeholder) {
	    var index = -1,
	        length = array.length,
	        resIndex = 0,
	        result = [];
	
	    while (++index < length) {
	      var value = array[index];
	      if (value === placeholder || value === PLACEHOLDER) {
	        array[index] = PLACEHOLDER;
	        result[resIndex++] = index;
	      }
	    }
	    return result;
	  }
	
	  /**
	   * Converts `set` to an array of its values.
	   *
	   * @private
	   * @param {Object} set The set to convert.
	   * @returns {Array} Returns the values.
	   */
	  function setToArray(set) {
	    var index = -1,
	        result = Array(set.size);
	
	    set.forEach(function(value) {
	      result[++index] = value;
	    });
	    return result;
	  }
	
	  /**
	   * Converts `set` to its value-value pairs.
	   *
	   * @private
	   * @param {Object} set The set to convert.
	   * @returns {Array} Returns the value-value pairs.
	   */
	  function setToPairs(set) {
	    var index = -1,
	        result = Array(set.size);
	
	    set.forEach(function(value) {
	      result[++index] = [value, value];
	    });
	    return result;
	  }
	
	  /**
	   * A specialized version of `_.indexOf` which performs strict equality
	   * comparisons of values, i.e. `===`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function strictIndexOf(array, value, fromIndex) {
	    var index = fromIndex - 1,
	        length = array.length;
	
	    while (++index < length) {
	      if (array[index] === value) {
	        return index;
	      }
	    }
	    return -1;
	  }
	
	  /**
	   * A specialized version of `_.lastIndexOf` which performs strict equality
	   * comparisons of values, i.e. `===`.
	   *
	   * @private
	   * @param {Array} array The array to inspect.
	   * @param {*} value The value to search for.
	   * @param {number} fromIndex The index to search from.
	   * @returns {number} Returns the index of the matched value, else `-1`.
	   */
	  function strictLastIndexOf(array, value, fromIndex) {
	    var index = fromIndex + 1;
	    while (index--) {
	      if (array[index] === value) {
	        return index;
	      }
	    }
	    return index;
	  }
	
	  /**
	   * Gets the number of symbols in `string`.
	   *
	   * @private
	   * @param {string} string The string to inspect.
	   * @returns {number} Returns the string size.
	   */
	  function stringSize(string) {
	    return hasUnicode(string)
	      ? unicodeSize(string)
	      : asciiSize(string);
	  }
	
	  /**
	   * Converts `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function stringToArray(string) {
	    return hasUnicode(string)
	      ? unicodeToArray(string)
	      : asciiToArray(string);
	  }
	
	  /**
	   * Used by `_.unescape` to convert HTML entities to characters.
	   *
	   * @private
	   * @param {string} chr The matched character to unescape.
	   * @returns {string} Returns the unescaped character.
	   */
	  var unescapeHtmlChar = basePropertyOf(htmlUnescapes);
	
	  /**
	   * Gets the size of a Unicode `string`.
	   *
	   * @private
	   * @param {string} string The string inspect.
	   * @returns {number} Returns the string size.
	   */
	  function unicodeSize(string) {
	    var result = reUnicode.lastIndex = 0;
	    while (reUnicode.test(string)) {
	      ++result;
	    }
	    return result;
	  }
	
	  /**
	   * Converts a Unicode `string` to an array.
	   *
	   * @private
	   * @param {string} string The string to convert.
	   * @returns {Array} Returns the converted array.
	   */
	  function unicodeToArray(string) {
	    return string.match(reUnicode) || [];
	  }
	
	  /**
	   * Splits a Unicode `string` into an array of its words.
	   *
	   * @private
	   * @param {string} The string to inspect.
	   * @returns {Array} Returns the words of `string`.
	   */
	  function unicodeWords(string) {
	    return string.match(reUnicodeWord) || [];
	  }
	
	  /*--------------------------------------------------------------------------*/
	
	  /**
	   * Create a new pristine `lodash` function using the `context` object.
	   *
	   * @static
	   * @memberOf _
	   * @since 1.1.0
	   * @category Util
	   * @param {Object} [context=root] The context object.
	   * @returns {Function} Returns a new `lodash` function.
	   * @example
	   *
	   * _.mixin({ 'foo': _.constant('foo') });
	   *
	   * var lodash = _.runInContext();
	   * lodash.mixin({ 'bar': lodash.constant('bar') });
	   *
	   * _.isFunction(_.foo);
	   * // => true
	   * _.isFunction(_.bar);
	   * // => false
	   *
	   * lodash.isFunction(lodash.foo);
	   * // => false
	   * lodash.isFunction(lodash.bar);
	   * // => true
	   *
	   * // Create a suped-up `defer` in Node.js.
	   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
	   */
	  var runInContext = (function runInContext(context) {
	    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
	
	    /** Built-in constructor references. */
	    var Array = context.Array,
	        Date = context.Date,
	        Error = context.Error,
	        Function = context.Function,
	        Math = context.Math,
	        Object = context.Object,
	        RegExp = context.RegExp,
	        String = context.String,
	        TypeError = context.TypeError;
	
	    /** Used for built-in method references. */
	    var arrayProto = Array.prototype,
	        funcProto = Function.prototype,
	        objectProto = Object.prototype;
	
	    /** Used to detect overreaching core-js shims. */
	    var coreJsData = context['__core-js_shared__'];
	
	    /** 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) : '';
	    }());
	
	    /** 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 generate unique IDs. */
	    var idCounter = 0;
	
	    /** Used to infer the `Object` constructor. */
	    var objectCtorString = funcToString.call(Object);
	
	    /**
	     * Used to resolve the
	     * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
	     * of values.
	     */
	    var objectToString = objectProto.toString;
	
	    /** Used to restore the original `_` reference in `_.noConflict`. */
	    var oldDash = root._;
	
	    /** Used to detect if a method is native. */
	    var reIsNative = RegExp('^' +
	      funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
	      .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
	    );
	
	    /** Built-in value references. */
	    var Buffer = moduleExports ? context.Buffer : undefined,
	        Symbol = context.Symbol,
	        Uint8Array = context.Uint8Array,
	        allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined,
	        getPrototype = overArg(Object.getPrototypeOf, Object),
	        iteratorSymbol = Symbol ? Symbol.iterator : undefined,
	        objectCreate = Object.create,
	        propertyIsEnumerable = objectProto.propertyIsEnumerable,
	        splice = arrayProto.splice,
	        spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
	
	    var defineProperty = (function() {
	      try {
	        var func = getNative(Object, 'defineProperty');
	        func({}, '', {});
	        return func;
	      } catch (e) {}
	    }());
	
	    /** Mocked built-ins. */
	    var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout,
	        ctxNow = Date && Date.now !== root.Date.now && Date.now,
	        ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
	
	    /* Built-in method references for those with the same name as other `lodash` methods. */
	    var nativeCeil = Math.ceil,
	        nativeFloor = Math.floor,
	        nativeGetSymbols = Object.getOwnPropertySymbols,
	        nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
	        nativeIsFinite = context.isFinite,
	        nativeJoin = arrayProto.join,
	        nativeKeys = overArg(Object.keys, Object),
	        nativeMax = Math.max,
	        nativeMin = Math.min,
	        nativeNow = Date.now,
	        nativeParseInt = context.parseInt,
	        nativeRandom = Math.random,
	        nativeReverse = arrayProto.reverse;
	
	    /* Built-in method references that are verified to be native. */
	    var DataView = getNative(context, 'DataView'),
	        Map = getNative(context, 'Map'),
	        Promise = getNative(context, 'Promise'),
	        Set = getNative(context, 'Set'),
	        WeakMap = getNative(context, 'WeakMap'),
	        nativeCreate = getNative(Object, 'create');
	
	    /** Used to store function metadata. */
	    var metaMap = WeakMap && new WeakMap;
	
	    /** Used to lookup unminified function names. */
	    var realNames = {};
	
	    /** Used to detect maps, sets, and weakmaps. */
	    var dataViewCtorString = toSource(DataView),
	        mapCtorString = toSource(Map),
	        promiseCtorString = toSource(Promise),
	        setCtorString = toSource(Set),
	        weakMapCtorString = toSource(WeakMap);
	
	    /** Used to convert symbols to primitives and strings. */
	    var symbolProto = Symbol ? Symbol.prototype : undefined,
	        symbolValueOf = symbolProto ? symbolProto.valueOf : undefined,
	        symbolToString = symbolProto ? symbolProto.toString : undefined;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a `lodash` object which wraps `value` to enable implicit method
	     * chain sequences. Methods that operate on and return arrays, collections,
	     * and functions can be chained together. Methods that retrieve a single value
	     * or may return a primitive value will automatically end the chain sequence
	     * and return the unwrapped value. Otherwise, the value must be unwrapped
	     * with `_#value`.
	     *
	     * Explicit chain sequences, which must be unwrapped with `_#value`, may be
	     * enabled using `_.chain`.
	     *
	     * The execution of chained methods is lazy, that is, it's deferred until
	     * `_#value` is implicitly or explicitly called.
	     *
	     * Lazy evaluation allows several methods to support shortcut fusion.
	     * Shortcut fusion is an optimization to merge iteratee calls; this avoids
	     * the creation of intermediate arrays and can greatly reduce the number of
	     * iteratee executions. Sections of a chain sequence qualify for shortcut
	     * fusion if the section is applied to an array of at least `200` elements
	     * and any iteratees accept only one argument. The heuristic for whether a
	     * section qualifies for shortcut fusion is subject to change.
	     *
	     * Chaining is supported in custom builds as long as the `_#value` method is
	     * directly or indirectly included in the build.
	     *
	     * In addition to lodash methods, wrappers have `Array` and `String` methods.
	     *
	     * The wrapper `Array` methods are:
	     * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
	     *
	     * The wrapper `String` methods are:
	     * `replace` and `split`
	     *
	     * The wrapper methods that support shortcut fusion are:
	     * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
	     * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
	     * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
	     *
	     * The chainable wrapper methods are:
	     * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
	     * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
	     * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
	     * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
	     * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
	     * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
	     * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
	     * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
	     * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
	     * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
	     * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
	     * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
	     * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
	     * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
	     * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
	     * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
	     * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
	     * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
	     * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
	     * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
	     * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
	     * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
	     * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
	     * `zipObject`, `zipObjectDeep`, and `zipWith`
	     *
	     * The wrapper methods that are **not** chainable by default are:
	     * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
	     * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
	     * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
	     * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
	     * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
	     * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
	     * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
	     * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
	     * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
	     * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
	     * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
	     * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
	     * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
	     * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
	     * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
	     * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
	     * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
	     * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
	     * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
	     * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
	     * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
	     * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
	     * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
	     * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
	     * `upperFirst`, `value`, and `words`
	     *
	     * @name _
	     * @constructor
	     * @category Seq
	     * @param {*} value The value to wrap in a `lodash` instance.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var wrapped = _([1, 2, 3]);
	     *
	     * // Returns an unwrapped value.
	     * wrapped.reduce(_.add);
	     * // => 6
	     *
	     * // Returns a wrapped value.
	     * var squares = wrapped.map(square);
	     *
	     * _.isArray(squares);
	     * // => false
	     *
	     * _.isArray(squares.value());
	     * // => true
	     */
	    function lodash(value) {
	      if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
	        if (value instanceof LodashWrapper) {
	          return value;
	        }
	        if (hasOwnProperty.call(value, '__wrapped__')) {
	          return wrapperClone(value);
	        }
	      }
	      return new LodashWrapper(value);
	    }
	
	    /**
	     * The base implementation of `_.create` without support for assigning
	     * properties to the created object.
	     *
	     * @private
	     * @param {Object} proto The object to inherit from.
	     * @returns {Object} Returns the new object.
	     */
	    var baseCreate = (function() {
	      function object() {}
	      return function(proto) {
	        if (!isObject(proto)) {
	          return {};
	        }
	        if (objectCreate) {
	          return objectCreate(proto);
	        }
	        object.prototype = proto;
	        var result = new object;
	        object.prototype = undefined;
	        return result;
	      };
	    }());
	
	    /**
	     * The function whose prototype chain sequence wrappers inherit from.
	     *
	     * @private
	     */
	    function baseLodash() {
	      // No operation performed.
	    }
	
	    /**
	     * The base constructor for creating `lodash` wrapper objects.
	     *
	     * @private
	     * @param {*} value The value to wrap.
	     * @param {boolean} [chainAll] Enable explicit method chain sequences.
	     */
	    function LodashWrapper(value, chainAll) {
	      this.__wrapped__ = value;
	      this.__actions__ = [];
	      this.__chain__ = !!chainAll;
	      this.__index__ = 0;
	      this.__values__ = undefined;
	    }
	
	    /**
	     * By default, the template delimiters used by lodash are like those in
	     * embedded Ruby (ERB). Change the following template settings to use
	     * alternative delimiters.
	     *
	     * @static
	     * @memberOf _
	     * @type {Object}
	     */
	    lodash.templateSettings = {
	
	      /**
	       * Used to detect `data` property values to be HTML-escaped.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'escape': reEscape,
	
	      /**
	       * Used to detect code to be evaluated.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'evaluate': reEvaluate,
	
	      /**
	       * Used to detect `data` property values to inject.
	       *
	       * @memberOf _.templateSettings
	       * @type {RegExp}
	       */
	      'interpolate': reInterpolate,
	
	      /**
	       * Used to reference the data object in the template text.
	       *
	       * @memberOf _.templateSettings
	       * @type {string}
	       */
	      'variable': '',
	
	      /**
	       * Used to import variables into the compiled template.
	       *
	       * @memberOf _.templateSettings
	       * @type {Object}
	       */
	      'imports': {
	
	        /**
	         * A reference to the `lodash` function.
	         *
	         * @memberOf _.templateSettings.imports
	         * @type {Function}
	         */
	        '_': lodash
	      }
	    };
	
	    // Ensure wrappers are instances of `baseLodash`.
	    lodash.prototype = baseLodash.prototype;
	    lodash.prototype.constructor = lodash;
	
	    LodashWrapper.prototype = baseCreate(baseLodash.prototype);
	    LodashWrapper.prototype.constructor = LodashWrapper;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
	     *
	     * @private
	     * @constructor
	     * @param {*} value The value to wrap.
	     */
	    function LazyWrapper(value) {
	      this.__wrapped__ = value;
	      this.__actions__ = [];
	      this.__dir__ = 1;
	      this.__filtered__ = false;
	      this.__iteratees__ = [];
	      this.__takeCount__ = MAX_ARRAY_LENGTH;
	      this.__views__ = [];
	    }
	
	    /**
	     * Creates a clone of the lazy wrapper object.
	     *
	     * @private
	     * @name clone
	     * @memberOf LazyWrapper
	     * @returns {Object} Returns the cloned `LazyWrapper` object.
	     */
	    function lazyClone() {
	      var result = new LazyWrapper(this.__wrapped__);
	      result.__actions__ = copyArray(this.__actions__);
	      result.__dir__ = this.__dir__;
	      result.__filtered__ = this.__filtered__;
	      result.__iteratees__ = copyArray(this.__iteratees__);
	      result.__takeCount__ = this.__takeCount__;
	      result.__views__ = copyArray(this.__views__);
	      return result;
	    }
	
	    /**
	     * Reverses the direction of lazy iteration.
	     *
	     * @private
	     * @name reverse
	     * @memberOf LazyWrapper
	     * @returns {Object} Returns the new reversed `LazyWrapper` object.
	     */
	    function lazyReverse() {
	      if (this.__filtered__) {
	        var result = new LazyWrapper(this);
	        result.__dir__ = -1;
	        result.__filtered__ = true;
	      } else {
	        result = this.clone();
	        result.__dir__ *= -1;
	      }
	      return result;
	    }
	
	    /**
	     * Extracts the unwrapped value from its lazy wrapper.
	     *
	     * @private
	     * @name value
	     * @memberOf LazyWrapper
	     * @returns {*} Returns the unwrapped value.
	     */
	    function lazyValue() {
	      var array = this.__wrapped__.value(),
	          dir = this.__dir__,
	          isArr = isArray(array),
	          isRight = dir < 0,
	          arrLength = isArr ? array.length : 0,
	          view = getView(0, arrLength, this.__views__),
	          start = view.start,
	          end = view.end,
	          length = end - start,
	          index = isRight ? end : (start - 1),
	          iteratees = this.__iteratees__,
	          iterLength = iteratees.length,
	          resIndex = 0,
	          takeCount = nativeMin(length, this.__takeCount__);
	
	      if (!isArr || arrLength < LARGE_ARRAY_SIZE ||
	          (arrLength == length && takeCount == length)) {
	        return baseWrapperValue(array, this.__actions__);
	      }
	      var result = [];
	
	      outer:
	      while (length-- && resIndex < takeCount) {
	        index += dir;
	
	        var iterIndex = -1,
	            value = array[index];
	
	        while (++iterIndex < iterLength) {
	          var data = iteratees[iterIndex],
	              iteratee = data.iteratee,
	              type = data.type,
	              computed = iteratee(value);
	
	          if (type == LAZY_MAP_FLAG) {
	            value = computed;
	          } else if (!computed) {
	            if (type == LAZY_FILTER_FLAG) {
	              continue outer;
	            } else {
	              break outer;
	            }
	          }
	        }
	        result[resIndex++] = value;
	      }
	      return result;
	    }
	
	    // Ensure `LazyWrapper` is an instance of `baseLodash`.
	    LazyWrapper.prototype = baseCreate(baseLodash.prototype);
	    LazyWrapper.prototype.constructor = LazyWrapper;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a hash object.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function Hash(entries) {
	      var index = -1,
	          length = entries ? entries.length : 0;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * Removes all key-value entries from the hash.
	     *
	     * @private
	     * @name clear
	     * @memberOf Hash
	     */
	    function hashClear() {
	      this.__data__ = nativeCreate ? nativeCreate(null) : {};
	      this.size = 0;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * 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;
	    }
	
	    // Add methods to `Hash`.
	    Hash.prototype.clear = hashClear;
	    Hash.prototype['delete'] = hashDelete;
	    Hash.prototype.get = hashGet;
	    Hash.prototype.has = hashHas;
	    Hash.prototype.set = hashSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an list cache object.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function ListCache(entries) {
	      var index = -1,
	          length = entries ? entries.length : 0;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * Removes all key-value entries from the list cache.
	     *
	     * @private
	     * @name clear
	     * @memberOf ListCache
	     */
	    function listCacheClear() {
	      this.__data__ = [];
	      this.size = 0;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * 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];
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * 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;
	    }
	
	    // Add methods to `ListCache`.
	    ListCache.prototype.clear = listCacheClear;
	    ListCache.prototype['delete'] = listCacheDelete;
	    ListCache.prototype.get = listCacheGet;
	    ListCache.prototype.has = listCacheHas;
	    ListCache.prototype.set = listCacheSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * 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 ? entries.length : 0;
	
	      this.clear();
	      while (++index < length) {
	        var entry = entries[index];
	        this.set(entry[0], entry[1]);
	      }
	    }
	
	    /**
	     * 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
	      };
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * 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;
	    }
	
	    // Add methods to `MapCache`.
	    MapCache.prototype.clear = mapCacheClear;
	    MapCache.prototype['delete'] = mapCacheDelete;
	    MapCache.prototype.get = mapCacheGet;
	    MapCache.prototype.has = mapCacheHas;
	    MapCache.prototype.set = mapCacheSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     *
	     * Creates an array cache object to store unique values.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [values] The values to cache.
	     */
	    function SetCache(values) {
	      var index = -1,
	          length = values ? values.length : 0;
	
	      this.__data__ = new MapCache;
	      while (++index < length) {
	        this.add(values[index]);
	      }
	    }
	
	    /**
	     * Adds `value` to the array cache.
	     *
	     * @private
	     * @name add
	     * @memberOf SetCache
	     * @alias push
	     * @param {*} value The value to cache.
	     * @returns {Object} Returns the cache instance.
	     */
	    function setCacheAdd(value) {
	      this.__data__.set(value, HASH_UNDEFINED);
	      return this;
	    }
	
	    /**
	     * Checks if `value` is in the array cache.
	     *
	     * @private
	     * @name has
	     * @memberOf SetCache
	     * @param {*} value The value to search for.
	     * @returns {number} Returns `true` if `value` is found, else `false`.
	     */
	    function setCacheHas(value) {
	      return this.__data__.has(value);
	    }
	
	    // Add methods to `SetCache`.
	    SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
	    SetCache.prototype.has = setCacheHas;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a stack cache object to store key-value pairs.
	     *
	     * @private
	     * @constructor
	     * @param {Array} [entries] The key-value pairs to cache.
	     */
	    function Stack(entries) {
	      var data = this.__data__ = new ListCache(entries);
	      this.size = data.size;
	    }
	
	    /**
	     * Removes all key-value entries from the stack.
	     *
	     * @private
	     * @name clear
	     * @memberOf Stack
	     */
	    function stackClear() {
	      this.__data__ = new ListCache;
	      this.size = 0;
	    }
	
	    /**
	     * Removes `key` and its value from the stack.
	     *
	     * @private
	     * @name delete
	     * @memberOf Stack
	     * @param {string} key The key of the value to remove.
	     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
	     */
	    function stackDelete(key) {
	      var data = this.__data__,
	          result = data['delete'](key);
	
	      this.size = data.size;
	      return result;
	    }
	
	    /**
	     * Gets the stack value for `key`.
	     *
	     * @private
	     * @name get
	     * @memberOf Stack
	     * @param {string} key The key of the value to get.
	     * @returns {*} Returns the entry value.
	     */
	    function stackGet(key) {
	      return this.__data__.get(key);
	    }
	
	    /**
	     * Checks if a stack value for `key` exists.
	     *
	     * @private
	     * @name has
	     * @memberOf Stack
	     * @param {string} key The key of the entry to check.
	     * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
	     */
	    function stackHas(key) {
	      return this.__data__.has(key);
	    }
	
	    /**
	     * Sets the stack `key` to `value`.
	     *
	     * @private
	     * @name set
	     * @memberOf Stack
	     * @param {string} key The key of the value to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns the stack cache instance.
	     */
	    function stackSet(key, value) {
	      var data = this.__data__;
	      if (data instanceof ListCache) {
	        var pairs = data.__data__;
	        if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
	          pairs.push([key, value]);
	          this.size = ++data.size;
	          return this;
	        }
	        data = this.__data__ = new MapCache(pairs);
	      }
	      data.set(key, value);
	      this.size = data.size;
	      return this;
	    }
	
	    // Add methods to `Stack`.
	    Stack.prototype.clear = stackClear;
	    Stack.prototype['delete'] = stackDelete;
	    Stack.prototype.get = stackGet;
	    Stack.prototype.has = stackHas;
	    Stack.prototype.set = stackSet;
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an array of the enumerable property names of the array-like `value`.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @param {boolean} inherited Specify returning inherited property names.
	     * @returns {Array} Returns the array of property names.
	     */
	    function arrayLikeKeys(value, inherited) {
	      var isArr = isArray(value),
	          isArg = !isArr && isArguments(value),
	          isBuff = !isArr && !isArg && isBuffer(value),
	          isType = !isArr && !isArg && !isBuff && isTypedArray(value),
	          skipIndexes = isArr || isArg || isBuff || isType,
	          result = skipIndexes ? baseTimes(value.length, String) : [],
	          length = result.length;
	
	      for (var key in value) {
	        if ((inherited || hasOwnProperty.call(value, key)) &&
	            !(skipIndexes && (
	               // Safari 9 has enumerable `arguments.length` in strict mode.
	               key == 'length' ||
	               // Node.js 0.10 has enumerable non-index properties on buffers.
	               (isBuff && (key == 'offset' || key == 'parent')) ||
	               // PhantomJS 2 has enumerable non-index properties on typed arrays.
	               (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
	               // Skip index properties.
	               isIndex(key, length)
	            ))) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * A specialized version of `_.sample` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to sample.
	     * @returns {*} Returns the random element.
	     */
	    function arraySample(array) {
	      var length = array.length;
	      return length ? array[baseRandom(0, length - 1)] : undefined;
	    }
	
	    /**
	     * A specialized version of `_.sampleSize` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to sample.
	     * @param {number} n The number of elements to sample.
	     * @returns {Array} Returns the random elements.
	     */
	    function arraySampleSize(array, n) {
	      return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length));
	    }
	
	    /**
	     * A specialized version of `_.shuffle` for arrays.
	     *
	     * @private
	     * @param {Array} array The array to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     */
	    function arrayShuffle(array) {
	      return shuffleSelf(copyArray(array));
	    }
	
	    /**
	     * Used by `_.defaults` to customize its `_.assignIn` use.
	     *
	     * @private
	     * @param {*} objValue The destination value.
	     * @param {*} srcValue The source value.
	     * @param {string} key The key of the property to assign.
	     * @param {Object} object The parent object of `objValue`.
	     * @returns {*} Returns the value to assign.
	     */
	    function assignInDefaults(objValue, srcValue, key, object) {
	      if (objValue === undefined ||
	          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
	        return srcValue;
	      }
	      return objValue;
	    }
	
	    /**
	     * This function is like `assignValue` except that it doesn't assign
	     * `undefined` values.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function assignMergeValue(object, key, value) {
	      if ((value !== undefined && !eq(object[key], value)) ||
	          (value === undefined && !(key in object))) {
	        baseAssignValue(object, key, value);
	      }
	    }
	
	    /**
	     * Assigns `value` to `key` of `object` if the existing value is not equivalent
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function assignValue(object, key, value) {
	      var objValue = object[key];
	      if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
	          (value === undefined && !(key in object))) {
	        baseAssignValue(object, key, value);
	      }
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Aggregates elements of `collection` on `accumulator` with keys transformed
	     * by `iteratee` and values set by `setter`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} setter The function to set `accumulator` values.
	     * @param {Function} iteratee The iteratee to transform keys.
	     * @param {Object} accumulator The initial aggregated object.
	     * @returns {Function} Returns `accumulator`.
	     */
	    function baseAggregator(collection, setter, iteratee, accumulator) {
	      baseEach(collection, function(value, key, collection) {
	        setter(accumulator, value, iteratee(value), collection);
	      });
	      return accumulator;
	    }
	
	    /**
	     * The base implementation of `_.assign` without support for multiple sources
	     * or `customizer` functions.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @returns {Object} Returns `object`.
	     */
	    function baseAssign(object, source) {
	      return object && copyObject(source, keys(source), object);
	    }
	
	    /**
	     * The base implementation of `assignValue` and `assignMergeValue` without
	     * value checks.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {string} key The key of the property to assign.
	     * @param {*} value The value to assign.
	     */
	    function baseAssignValue(object, key, value) {
	      if (key == '__proto__' && defineProperty) {
	        defineProperty(object, key, {
	          'configurable': true,
	          'enumerable': true,
	          'value': value,
	          'writable': true
	        });
	      } else {
	        object[key] = value;
	      }
	    }
	
	    /**
	     * The base implementation of `_.at` without support for individual paths.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {string[]} paths The property paths of elements to pick.
	     * @returns {Array} Returns the picked elements.
	     */
	    function baseAt(object, paths) {
	      var index = -1,
	          isNil = object == null,
	          length = paths.length,
	          result = Array(length);
	
	      while (++index < length) {
	        result[index] = isNil ? undefined : get(object, paths[index]);
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.clamp` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {number} number The number to clamp.
	     * @param {number} [lower] The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the clamped number.
	     */
	    function baseClamp(number, lower, upper) {
	      if (number === number) {
	        if (upper !== undefined) {
	          number = number <= upper ? number : upper;
	        }
	        if (lower !== undefined) {
	          number = number >= lower ? number : lower;
	        }
	      }
	      return number;
	    }
	
	    /**
	     * The base implementation of `_.clone` and `_.cloneDeep` which tracks
	     * traversed objects.
	     *
	     * @private
	     * @param {*} value The value to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @param {boolean} [isFull] Specify a clone including symbols.
	     * @param {Function} [customizer] The function to customize cloning.
	     * @param {string} [key] The key of `value`.
	     * @param {Object} [object] The parent object of `value`.
	     * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
	     * @returns {*} Returns the cloned value.
	     */
	    function baseClone(value, isDeep, isFull, customizer, key, object, stack) {
	      var result;
	      if (customizer) {
	        result = object ? customizer(value, key, object, stack) : customizer(value);
	      }
	      if (result !== undefined) {
	        return result;
	      }
	      if (!isObject(value)) {
	        return value;
	      }
	      var isArr = isArray(value);
	      if (isArr) {
	        result = initCloneArray(value);
	        if (!isDeep) {
	          return copyArray(value, result);
	        }
	      } else {
	        var tag = getTag(value),
	            isFunc = tag == funcTag || tag == genTag;
	
	        if (isBuffer(value)) {
	          return cloneBuffer(value, isDeep);
	        }
	        if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
	          result = initCloneObject(isFunc ? {} : value);
	          if (!isDeep) {
	            return copySymbols(value, baseAssign(result, value));
	          }
	        } else {
	          if (!cloneableTags[tag]) {
	            return object ? value : {};
	          }
	          result = initCloneByTag(value, tag, baseClone, isDeep);
	        }
	      }
	      // Check for circular references and return its corresponding clone.
	      stack || (stack = new Stack);
	      var stacked = stack.get(value);
	      if (stacked) {
	        return stacked;
	      }
	      stack.set(value, result);
	
	      var props = isArr ? undefined : (isFull ? getAllKeys : keys)(value);
	      arrayEach(props || value, function(subValue, key) {
	        if (props) {
	          key = subValue;
	          subValue = value[key];
	        }
	        // Recursively populate clone (susceptible to call stack limits).
	        assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.conforms` which doesn't clone `source`.
	     *
	     * @private
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseConforms(source) {
	      var props = keys(source);
	      return function(object) {
	        return baseConformsTo(object, source, props);
	      };
	    }
	
	    /**
	     * The base implementation of `_.conformsTo` which accepts `props` to check.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
	     */
	    function baseConformsTo(object, source, props) {
	      var length = props.length;
	      if (object == null) {
	        return !length;
	      }
	      object = Object(object);
	      while (length--) {
	        var key = props[length],
	            predicate = source[key],
	            value = object[key];
	
	        if ((value === undefined && !(key in object)) || !predicate(value)) {
	          return false;
	        }
	      }
	      return true;
	    }
	
	    /**
	     * The base implementation of `_.delay` and `_.defer` which accepts `args`
	     * to provide to `func`.
	     *
	     * @private
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @param {Array} args The arguments to provide to `func`.
	     * @returns {number|Object} Returns the timer id or timeout object.
	     */
	    function baseDelay(func, wait, args) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      return setTimeout(function() { func.apply(undefined, args); }, wait);
	    }
	
	    /**
	     * The base implementation of methods like `_.difference` without support
	     * for excluding multiple arrays or iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Array} values The values to exclude.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     */
	    function baseDifference(array, values, iteratee, comparator) {
	      var index = -1,
	          includes = arrayIncludes,
	          isCommon = true,
	          length = array.length,
	          result = [],
	          valuesLength = values.length;
	
	      if (!length) {
	        return result;
	      }
	      if (iteratee) {
	        values = arrayMap(values, baseUnary(iteratee));
	      }
	      if (comparator) {
	        includes = arrayIncludesWith;
	        isCommon = false;
	      }
	      else if (values.length >= LARGE_ARRAY_SIZE) {
	        includes = cacheHas;
	        isCommon = false;
	        values = new SetCache(values);
	      }
	      outer:
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (isCommon && computed === computed) {
	          var valuesIndex = valuesLength;
	          while (valuesIndex--) {
	            if (values[valuesIndex] === computed) {
	              continue outer;
	            }
	          }
	          result.push(value);
	        }
	        else if (!includes(values, computed, comparator)) {
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.forEach` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     */
	    var baseEach = createBaseEach(baseForOwn);
	
	    /**
	     * The base implementation of `_.forEachRight` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     */
	    var baseEachRight = createBaseEach(baseForOwnRight, true);
	
	    /**
	     * The base implementation of `_.every` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {boolean} Returns `true` if all elements pass the predicate check,
	     *  else `false`
	     */
	    function baseEvery(collection, predicate) {
	      var result = true;
	      baseEach(collection, function(value, index, collection) {
	        result = !!predicate(value, index, collection);
	        return result;
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of methods like `_.max` and `_.min` which accepts a
	     * `comparator` to determine the extremum value.
	     *
	     * @private
	     * @param {Array} array The array to iterate over.
	     * @param {Function} iteratee The iteratee invoked per iteration.
	     * @param {Function} comparator The comparator used to compare values.
	     * @returns {*} Returns the extremum value.
	     */
	    function baseExtremum(array, iteratee, comparator) {
	      var index = -1,
	          length = array.length;
	
	      while (++index < length) {
	        var value = array[index],
	            current = iteratee(value);
	
	        if (current != null && (computed === undefined
	              ? (current === current && !isSymbol(current))
	              : comparator(current, computed)
	            )) {
	          var computed = current,
	              result = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.fill` without an iteratee call guard.
	     *
	     * @private
	     * @param {Array} array The array to fill.
	     * @param {*} value The value to fill `array` with.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns `array`.
	     */
	    function baseFill(array, value, start, end) {
	      var length = array.length;
	
	      start = toInteger(start);
	      if (start < 0) {
	        start = -start > length ? 0 : (length + start);
	      }
	      end = (end === undefined || end > length) ? length : toInteger(end);
	      if (end < 0) {
	        end += length;
	      }
	      end = start > end ? 0 : toLength(end);
	      while (start < end) {
	        array[start++] = value;
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.filter` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     */
	    function baseFilter(collection, predicate) {
	      var result = [];
	      baseEach(collection, function(value, index, collection) {
	        if (predicate(value, index, collection)) {
	          result.push(value);
	        }
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.flatten` with support for restricting flattening.
	     *
	     * @private
	     * @param {Array} array The array to flatten.
	     * @param {number} depth The maximum recursion depth.
	     * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
	     * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
	     * @param {Array} [result=[]] The initial result value.
	     * @returns {Array} Returns the new flattened array.
	     */
	    function baseFlatten(array, depth, predicate, isStrict, result) {
	      var index = -1,
	          length = array.length;
	
	      predicate || (predicate = isFlattenable);
	      result || (result = []);
	
	      while (++index < length) {
	        var value = array[index];
	        if (depth > 0 && predicate(value)) {
	          if (depth > 1) {
	            // Recursively flatten arrays (susceptible to call stack limits).
	            baseFlatten(value, depth - 1, predicate, isStrict, result);
	          } else {
	            arrayPush(result, value);
	          }
	        } else if (!isStrict) {
	          result[result.length] = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `baseForOwn` which iterates over `object`
	     * properties returned by `keysFunc` and invokes `iteratee` for each property.
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @returns {Object} Returns `object`.
	     */
	    var baseFor = createBaseFor();
	
	    /**
	     * This function is like `baseFor` except that it iterates over properties
	     * in the opposite order.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @returns {Object} Returns `object`.
	     */
	    var baseForRight = createBaseFor(true);
	
	    /**
	     * The base implementation of `_.forOwn` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     */
	    function baseForOwn(object, iteratee) {
	      return object && baseFor(object, iteratee, keys);
	    }
	
	    /**
	     * The base implementation of `_.forOwnRight` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     */
	    function baseForOwnRight(object, iteratee) {
	      return object && baseForRight(object, iteratee, keys);
	    }
	
	    /**
	     * The base implementation of `_.functions` which creates an array of
	     * `object` function property names filtered from `props`.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Array} props The property names to filter.
	     * @returns {Array} Returns the function names.
	     */
	    function baseFunctions(object, props) {
	      return arrayFilter(props, function(key) {
	        return isFunction(object[key]);
	      });
	    }
	
	    /**
	     * 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 = isKey(path, object) ? [path] : castPath(path);
	
	      var index = 0,
	          length = path.length;
	
	      while (object != null && index < length) {
	        object = object[toKey(path[index++])];
	      }
	      return (index && index == length) ? object : undefined;
	    }
	
	    /**
	     * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
	     * `keysFunc` and `symbolsFunc` to get the enumerable property names and
	     * symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Function} keysFunc The function to get the keys of `object`.
	     * @param {Function} symbolsFunc The function to get the symbols of `object`.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function baseGetAllKeys(object, keysFunc, symbolsFunc) {
	      var result = keysFunc(object);
	      return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
	    }
	
	    /**
	     * The base implementation of `getTag`.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @returns {string} Returns the `toStringTag`.
	     */
	    function baseGetTag(value) {
	      return objectToString.call(value);
	    }
	
	    /**
	     * The base implementation of `_.gt` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than `other`,
	     *  else `false`.
	     */
	    function baseGt(value, other) {
	      return value > other;
	    }
	
	    /**
	     * The base implementation of `_.has` without support for deep paths.
	     *
	     * @private
	     * @param {Object} [object] The object to query.
	     * @param {Array|string} key The key to check.
	     * @returns {boolean} Returns `true` if `key` exists, else `false`.
	     */
	    function baseHas(object, key) {
	      return object != null && hasOwnProperty.call(object, key);
	    }
	
	    /**
	     * The base implementation of `_.hasIn` without support for deep paths.
	     *
	     * @private
	     * @param {Object} [object] The object to query.
	     * @param {Array|string} key The key to check.
	     * @returns {boolean} Returns `true` if `key` exists, else `false`.
	     */
	    function baseHasIn(object, key) {
	      return object != null && key in Object(object);
	    }
	
	    /**
	     * The base implementation of `_.inRange` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {number} number The number to check.
	     * @param {number} start The start of the range.
	     * @param {number} end The end of the range.
	     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
	     */
	    function baseInRange(number, start, end) {
	      return number >= nativeMin(start, end) && number < nativeMax(start, end);
	    }
	
	    /**
	     * The base implementation of methods like `_.intersection`, without support
	     * for iteratee shorthands, that accepts an array of arrays to inspect.
	     *
	     * @private
	     * @param {Array} arrays The arrays to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of shared values.
	     */
	    function baseIntersection(arrays, iteratee, comparator) {
	      var includes = comparator ? arrayIncludesWith : arrayIncludes,
	          length = arrays[0].length,
	          othLength = arrays.length,
	          othIndex = othLength,
	          caches = Array(othLength),
	          maxLength = Infinity,
	          result = [];
	
	      while (othIndex--) {
	        var array = arrays[othIndex];
	        if (othIndex && iteratee) {
	          array = arrayMap(array, baseUnary(iteratee));
	        }
	        maxLength = nativeMin(array.length, maxLength);
	        caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
	          ? new SetCache(othIndex && array)
	          : undefined;
	      }
	      array = arrays[0];
	
	      var index = -1,
	          seen = caches[0];
	
	      outer:
	      while (++index < length && result.length < maxLength) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (!(seen
	              ? cacheHas(seen, computed)
	              : includes(result, computed, comparator)
	            )) {
	          othIndex = othLength;
	          while (--othIndex) {
	            var cache = caches[othIndex];
	            if (!(cache
	                  ? cacheHas(cache, computed)
	                  : includes(arrays[othIndex], computed, comparator))
	                ) {
	              continue outer;
	            }
	          }
	          if (seen) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.invert` and `_.invertBy` which inverts
	     * `object` with values transformed by `iteratee` and set by `setter`.
	     *
	     * @private
	     * @param {Object} object The object to iterate over.
	     * @param {Function} setter The function to set `accumulator` values.
	     * @param {Function} iteratee The iteratee to transform values.
	     * @param {Object} accumulator The initial inverted object.
	     * @returns {Function} Returns `accumulator`.
	     */
	    function baseInverter(object, setter, iteratee, accumulator) {
	      baseForOwn(object, function(value, key, object) {
	        setter(accumulator, iteratee(value), key, object);
	      });
	      return accumulator;
	    }
	
	    /**
	     * The base implementation of `_.invoke` without support for individual
	     * method arguments.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {Array} args The arguments to invoke the method with.
	     * @returns {*} Returns the result of the invoked method.
	     */
	    function baseInvoke(object, path, args) {
	      if (!isKey(path, object)) {
	        path = castPath(path);
	        object = parent(object, path);
	        path = last(path);
	      }
	      var func = object == null ? object : object[toKey(path)];
	      return func == null ? undefined : apply(func, object, args);
	    }
	
	    /**
	     * The base implementation of `_.isArguments`.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	     */
	    function baseIsArguments(value) {
	      return isObjectLike(value) && objectToString.call(value) == argsTag;
	    }
	
	    /**
	     * The base implementation of `_.isArrayBuffer` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
	     */
	    function baseIsArrayBuffer(value) {
	      return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
	    }
	
	    /**
	     * The base implementation of `_.isDate` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
	     */
	    function baseIsDate(value) {
	      return isObjectLike(value) && objectToString.call(value) == dateTag;
	    }
	
	    /**
	     * The base implementation of `_.isEqual` which supports partial comparisons
	     * and tracks traversed objects.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @param {boolean} [bitmask] The bitmask of comparison flags.
	     *  The bitmask may be composed of the following flags:
	     *     1 - Unordered comparison
	     *     2 - Partial comparison
	     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     */
	    function baseIsEqual(value, other, customizer, bitmask, stack) {
	      if (value === other) {
	        return true;
	      }
	      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
	        return value !== value && other !== other;
	      }
	      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack);
	    }
	
	    /**
	     * A specialized version of `baseIsEqual` for arrays and objects which performs
	     * deep comparisons and tracks traversed objects enabling objects with circular
	     * references to be compared.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
	     *  for more details.
	     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
	      var objIsArr = isArray(object),
	          othIsArr = isArray(other),
	          objTag = arrayTag,
	          othTag = arrayTag;
	
	      if (!objIsArr) {
	        objTag = getTag(object);
	        objTag = objTag == argsTag ? objectTag : objTag;
	      }
	      if (!othIsArr) {
	        othTag = getTag(other);
	        othTag = othTag == argsTag ? objectTag : othTag;
	      }
	      var objIsObj = objTag == objectTag,
	          othIsObj = othTag == objectTag,
	          isSameTag = objTag == othTag;
	
	      if (isSameTag && isBuffer(object)) {
	        if (!isBuffer(other)) {
	          return false;
	        }
	        objIsArr = true;
	        objIsObj = false;
	      }
	      if (isSameTag && !objIsObj) {
	        stack || (stack = new Stack);
	        return (objIsArr || isTypedArray(object))
	          ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
	          : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
	      }
	      if (!(bitmask & PARTIAL_COMPARE_FLAG)) {
	        var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
	            othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
	
	        if (objIsWrapped || othIsWrapped) {
	          var objUnwrapped = objIsWrapped ? object.value() : object,
	              othUnwrapped = othIsWrapped ? other.value() : other;
	
	          stack || (stack = new Stack);
	          return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
	        }
	      }
	      if (!isSameTag) {
	        return false;
	      }
	      stack || (stack = new Stack);
	      return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
	    }
	
	    /**
	     * The base implementation of `_.isMap` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
	     */
	    function baseIsMap(value) {
	      return isObjectLike(value) && getTag(value) == mapTag;
	    }
	
	    /**
	     * The base implementation of `_.isMatch` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @param {Array} matchData The property names, values, and compare flags to match.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     */
	    function baseIsMatch(object, source, matchData, customizer) {
	      var index = matchData.length,
	          length = index,
	          noCustomizer = !customizer;
	
	      if (object == null) {
	        return !length;
	      }
	      object = Object(object);
	      while (index--) {
	        var data = matchData[index];
	        if ((noCustomizer && data[2])
	              ? data[1] !== object[data[0]]
	              : !(data[0] in object)
	            ) {
	          return false;
	        }
	      }
	      while (++index < length) {
	        data = matchData[index];
	        var key = data[0],
	            objValue = object[key],
	            srcValue = data[1];
	
	        if (noCustomizer && data[2]) {
	          if (objValue === undefined && !(key in object)) {
	            return false;
	          }
	        } else {
	          var stack = new Stack;
	          if (customizer) {
	            var result = customizer(objValue, srcValue, key, object, source, stack);
	          }
	          if (!(result === undefined
	                ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
	                : result
	              )) {
	            return false;
	          }
	        }
	      }
	      return true;
	    }
	
	    /**
	     * 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));
	    }
	
	    /**
	     * The base implementation of `_.isRegExp` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
	     */
	    function baseIsRegExp(value) {
	      return isObject(value) && objectToString.call(value) == regexpTag;
	    }
	
	    /**
	     * The base implementation of `_.isSet` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
	     */
	    function baseIsSet(value) {
	      return isObjectLike(value) && getTag(value) == setTag;
	    }
	
	    /**
	     * The base implementation of `_.isTypedArray` without Node.js optimizations.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	     */
	    function baseIsTypedArray(value) {
	      return isObjectLike(value) &&
	        isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
	    }
	
	    /**
	     * The base implementation of `_.iteratee`.
	     *
	     * @private
	     * @param {*} [value=_.identity] The value to convert to an iteratee.
	     * @returns {Function} Returns the iteratee.
	     */
	    function baseIteratee(value) {
	      // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
	      // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
	      if (typeof value == 'function') {
	        return value;
	      }
	      if (value == null) {
	        return identity;
	      }
	      if (typeof value == 'object') {
	        return isArray(value)
	          ? baseMatchesProperty(value[0], value[1])
	          : baseMatches(value);
	      }
	      return property(value);
	    }
	
	    /**
	     * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function baseKeys(object) {
	      if (!isPrototype(object)) {
	        return nativeKeys(object);
	      }
	      var result = [];
	      for (var key in Object(object)) {
	        if (hasOwnProperty.call(object, key) && key != 'constructor') {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function baseKeysIn(object) {
	      if (!isObject(object)) {
	        return nativeKeysIn(object);
	      }
	      var isProto = isPrototype(object),
	          result = [];
	
	      for (var key in object) {
	        if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.lt` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than `other`,
	     *  else `false`.
	     */
	    function baseLt(value, other) {
	      return value < other;
	    }
	
	    /**
	     * The base implementation of `_.map` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} iteratee The function invoked per iteration.
	     * @returns {Array} Returns the new mapped array.
	     */
	    function baseMap(collection, iteratee) {
	      var index = -1,
	          result = isArrayLike(collection) ? Array(collection.length) : [];
	
	      baseEach(collection, function(value, key, collection) {
	        result[++index] = iteratee(value, key, collection);
	      });
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.matches` which doesn't clone `source`.
	     *
	     * @private
	     * @param {Object} source The object of property values to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseMatches(source) {
	      var matchData = getMatchData(source);
	      if (matchData.length == 1 && matchData[0][2]) {
	        return matchesStrictComparable(matchData[0][0], matchData[0][1]);
	      }
	      return function(object) {
	        return object === source || baseIsMatch(object, source, matchData);
	      };
	    }
	
	    /**
	     * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
	     *
	     * @private
	     * @param {string} path The path of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function baseMatchesProperty(path, srcValue) {
	      if (isKey(path) && isStrictComparable(srcValue)) {
	        return matchesStrictComparable(toKey(path), srcValue);
	      }
	      return function(object) {
	        var objValue = get(object, path);
	        return (objValue === undefined && objValue === srcValue)
	          ? hasIn(object, path)
	          : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
	      };
	    }
	
	    /**
	     * The base implementation of `_.merge` without support for multiple sources.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @param {number} srcIndex The index of `source`.
	     * @param {Function} [customizer] The function to customize merged values.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     */
	    function baseMerge(object, source, srcIndex, customizer, stack) {
	      if (object === source) {
	        return;
	      }
	      baseFor(source, function(srcValue, key) {
	        if (isObject(srcValue)) {
	          stack || (stack = new Stack);
	          baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack);
	        }
	        else {
	          var newValue = customizer
	            ? customizer(object[key], srcValue, (key + ''), object, source, stack)
	            : undefined;
	
	          if (newValue === undefined) {
	            newValue = srcValue;
	          }
	          assignMergeValue(object, key, newValue);
	        }
	      }, keysIn);
	    }
	
	    /**
	     * A specialized version of `baseMerge` for arrays and objects which performs
	     * deep merges and tracks traversed objects enabling objects with circular
	     * references to be merged.
	     *
	     * @private
	     * @param {Object} object The destination object.
	     * @param {Object} source The source object.
	     * @param {string} key The key of the value to merge.
	     * @param {number} srcIndex The index of `source`.
	     * @param {Function} mergeFunc The function to merge values.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     */
	    function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
	      var objValue = object[key],
	          srcValue = source[key],
	          stacked = stack.get(srcValue);
	
	      if (stacked) {
	        assignMergeValue(object, key, stacked);
	        return;
	      }
	      var newValue = customizer
	        ? customizer(objValue, srcValue, (key + ''), object, source, stack)
	        : undefined;
	
	      var isCommon = newValue === undefined;
	
	      if (isCommon) {
	        var isArr = isArray(srcValue),
	            isBuff = !isArr && isBuffer(srcValue),
	            isTyped = !isArr && !isBuff && isTypedArray(srcValue);
	
	        newValue = srcValue;
	        if (isArr || isBuff || isTyped) {
	          if (isArray(objValue)) {
	            newValue = objValue;
	          }
	          else if (isArrayLikeObject(objValue)) {
	            newValue = copyArray(objValue);
	          }
	          else if (isBuff) {
	            isCommon = false;
	            newValue = cloneBuffer(srcValue, true);
	          }
	          else if (isTyped) {
	            isCommon = false;
	            newValue = cloneTypedArray(srcValue, true);
	          }
	          else {
	            newValue = [];
	          }
	        }
	        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
	          newValue = objValue;
	          if (isArguments(objValue)) {
	            newValue = toPlainObject(objValue);
	          }
	          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
	            newValue = initCloneObject(srcValue);
	          }
	        }
	        else {
	          isCommon = false;
	        }
	      }
	      if (isCommon) {
	        // Recursively merge objects and arrays (susceptible to call stack limits).
	        stack.set(srcValue, newValue);
	        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
	        stack['delete'](srcValue);
	      }
	      assignMergeValue(object, key, newValue);
	    }
	
	    /**
	     * The base implementation of `_.nth` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {Array} array The array to query.
	     * @param {number} n The index of the element to return.
	     * @returns {*} Returns the nth element of `array`.
	     */
	    function baseNth(array, n) {
	      var length = array.length;
	      if (!length) {
	        return;
	      }
	      n += n < 0 ? length : 0;
	      return isIndex(n, length) ? array[n] : undefined;
	    }
	
	    /**
	     * The base implementation of `_.orderBy` without param guards.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
	     * @param {string[]} orders The sort orders of `iteratees`.
	     * @returns {Array} Returns the new sorted array.
	     */
	    function baseOrderBy(collection, iteratees, orders) {
	      var index = -1;
	      iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee()));
	
	      var result = baseMap(collection, function(value, key, collection) {
	        var criteria = arrayMap(iteratees, function(iteratee) {
	          return iteratee(value);
	        });
	        return { 'criteria': criteria, 'index': ++index, 'value': value };
	      });
	
	      return baseSortBy(result, function(object, other) {
	        return compareMultiple(object, other, orders);
	      });
	    }
	
	    /**
	     * The base implementation of `_.pick` without support for individual
	     * property identifiers.
	     *
	     * @private
	     * @param {Object} object The source object.
	     * @param {string[]} props The property identifiers to pick.
	     * @returns {Object} Returns the new object.
	     */
	    function basePick(object, props) {
	      object = Object(object);
	      return basePickBy(object, props, function(value, key) {
	        return key in object;
	      });
	    }
	
	    /**
	     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Object} object The source object.
	     * @param {string[]} props The property identifiers to pick from.
	     * @param {Function} predicate The function invoked per property.
	     * @returns {Object} Returns the new object.
	     */
	    function basePickBy(object, props, predicate) {
	      var index = -1,
	          length = props.length,
	          result = {};
	
	      while (++index < length) {
	        var key = props[index],
	            value = object[key];
	
	        if (predicate(value, key)) {
	          baseAssignValue(result, key, value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseProperty` which supports deep paths.
	     *
	     * @private
	     * @param {Array|string} path The path of the property to get.
	     * @returns {Function} Returns the new accessor function.
	     */
	    function basePropertyDeep(path) {
	      return function(object) {
	        return baseGet(object, path);
	      };
	    }
	
	    /**
	     * The base implementation of `_.pullAllBy` without support for iteratee
	     * shorthands.
	     *
	     * @private
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns `array`.
	     */
	    function basePullAll(array, values, iteratee, comparator) {
	      var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
	          index = -1,
	          length = values.length,
	          seen = array;
	
	      if (array === values) {
	        values = copyArray(values);
	      }
	      if (iteratee) {
	        seen = arrayMap(array, baseUnary(iteratee));
	      }
	      while (++index < length) {
	        var fromIndex = 0,
	            value = values[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
	          if (seen !== array) {
	            splice.call(seen, fromIndex, 1);
	          }
	          splice.call(array, fromIndex, 1);
	        }
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.pullAt` without support for individual
	     * indexes or capturing the removed elements.
	     *
	     * @private
	     * @param {Array} array The array to modify.
	     * @param {number[]} indexes The indexes of elements to remove.
	     * @returns {Array} Returns `array`.
	     */
	    function basePullAt(array, indexes) {
	      var length = array ? indexes.length : 0,
	          lastIndex = length - 1;
	
	      while (length--) {
	        var index = indexes[length];
	        if (length == lastIndex || index !== previous) {
	          var previous = index;
	          if (isIndex(index)) {
	            splice.call(array, index, 1);
	          }
	          else if (!isKey(index, array)) {
	            var path = castPath(index),
	                object = parent(array, path);
	
	            if (object != null) {
	              delete object[toKey(last(path))];
	            }
	          }
	          else {
	            delete array[toKey(index)];
	          }
	        }
	      }
	      return array;
	    }
	
	    /**
	     * The base implementation of `_.random` without support for returning
	     * floating-point numbers.
	     *
	     * @private
	     * @param {number} lower The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the random number.
	     */
	    function baseRandom(lower, upper) {
	      return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
	    }
	
	    /**
	     * The base implementation of `_.range` and `_.rangeRight` which doesn't
	     * coerce arguments.
	     *
	     * @private
	     * @param {number} start The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} step The value to increment or decrement by.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Array} Returns the range of numbers.
	     */
	    function baseRange(start, end, step, fromRight) {
	      var index = -1,
	          length = nativeMax(nativeCeil((end - start) / (step || 1)), 0),
	          result = Array(length);
	
	      while (length--) {
	        result[fromRight ? length : ++index] = start;
	        start += step;
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.repeat` which doesn't coerce arguments.
	     *
	     * @private
	     * @param {string} string The string to repeat.
	     * @param {number} n The number of times to repeat the string.
	     * @returns {string} Returns the repeated string.
	     */
	    function baseRepeat(string, n) {
	      var result = '';
	      if (!string || n < 1 || n > MAX_SAFE_INTEGER) {
	        return result;
	      }
	      // Leverage the exponentiation by squaring algorithm for a faster repeat.
	      // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details.
	      do {
	        if (n % 2) {
	          result += string;
	        }
	        n = nativeFloor(n / 2);
	        if (n) {
	          string += string;
	        }
	      } while (n);
	
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.rest` which doesn't validate or coerce arguments.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @returns {Function} Returns the new function.
	     */
	    function baseRest(func, start) {
	      return setToString(overRest(func, start, identity), func + '');
	    }
	
	    /**
	     * The base implementation of `_.sample`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to sample.
	     * @returns {*} Returns the random element.
	     */
	    function baseSample(collection) {
	      return arraySample(values(collection));
	    }
	
	    /**
	     * The base implementation of `_.sampleSize` without param guards.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to sample.
	     * @param {number} n The number of elements to sample.
	     * @returns {Array} Returns the random elements.
	     */
	    function baseSampleSize(collection, n) {
	      var array = values(collection);
	      return shuffleSelf(array, baseClamp(n, 0, array.length));
	    }
	
	    /**
	     * The base implementation of `_.set`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @param {Function} [customizer] The function to customize path creation.
	     * @returns {Object} Returns `object`.
	     */
	    function baseSet(object, path, value, customizer) {
	      if (!isObject(object)) {
	        return object;
	      }
	      path = isKey(path, object) ? [path] : castPath(path);
	
	      var index = -1,
	          length = path.length,
	          lastIndex = length - 1,
	          nested = object;
	
	      while (nested != null && ++index < length) {
	        var key = toKey(path[index]),
	            newValue = value;
	
	        if (index != lastIndex) {
	          var objValue = nested[key];
	          newValue = customizer ? customizer(objValue, key, nested) : undefined;
	          if (newValue === undefined) {
	            newValue = isObject(objValue)
	              ? objValue
	              : (isIndex(path[index + 1]) ? [] : {});
	          }
	        }
	        assignValue(nested, key, newValue);
	        nested = nested[key];
	      }
	      return object;
	    }
	
	    /**
	     * The base implementation of `setData` without support for hot loop shorting.
	     *
	     * @private
	     * @param {Function} func The function to associate metadata with.
	     * @param {*} data The metadata.
	     * @returns {Function} Returns `func`.
	     */
	    var baseSetData = !metaMap ? identity : function(func, data) {
	      metaMap.set(func, data);
	      return func;
	    };
	
	    /**
	     * The base implementation of `setToString` without support for hot loop shorting.
	     *
	     * @private
	     * @param {Function} func The function to modify.
	     * @param {Function} string The `toString` result.
	     * @returns {Function} Returns `func`.
	     */
	    var baseSetToString = !defineProperty ? identity : function(func, string) {
	      return defineProperty(func, 'toString', {
	        'configurable': true,
	        'enumerable': false,
	        'value': constant(string),
	        'writable': true
	      });
	    };
	
	    /**
	     * The base implementation of `_.shuffle`.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     */
	    function baseShuffle(collection) {
	      return shuffleSelf(values(collection));
	    }
	
	    /**
	     * The base implementation of `_.slice` without an iteratee call guard.
	     *
	     * @private
	     * @param {Array} array The array to slice.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function baseSlice(array, start, end) {
	      var index = -1,
	          length = array.length;
	
	      if (start < 0) {
	        start = -start > length ? 0 : (length + start);
	      }
	      end = end > length ? length : end;
	      if (end < 0) {
	        end += length;
	      }
	      length = start > end ? 0 : ((end - start) >>> 0);
	      start >>>= 0;
	
	      var result = Array(length);
	      while (++index < length) {
	        result[index] = array[index + start];
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.some` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} predicate The function invoked per iteration.
	     * @returns {boolean} Returns `true` if any element passes the predicate check,
	     *  else `false`.
	     */
	    function baseSome(collection, predicate) {
	      var result;
	
	      baseEach(collection, function(value, index, collection) {
	        result = predicate(value, index, collection);
	        return !result;
	      });
	      return !!result;
	    }
	
	    /**
	     * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which
	     * performs a binary search of `array` to determine the index at which `value`
	     * should be inserted into `array` in order to maintain its sort order.
	     *
	     * @private
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {boolean} [retHighest] Specify returning the highest qualified index.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     */
	    function baseSortedIndex(array, value, retHighest) {
	      var low = 0,
	          high = array ? array.length : low;
	
	      if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) {
	        while (low < high) {
	          var mid = (low + high) >>> 1,
	              computed = array[mid];
	
	          if (computed !== null && !isSymbol(computed) &&
	              (retHighest ? (computed <= value) : (computed < value))) {
	            low = mid + 1;
	          } else {
	            high = mid;
	          }
	        }
	        return high;
	      }
	      return baseSortedIndexBy(array, value, identity, retHighest);
	    }
	
	    /**
	     * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy`
	     * which invokes `iteratee` for `value` and each element of `array` to compute
	     * their sort ranking. The iteratee is invoked with one argument; (value).
	     *
	     * @private
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} iteratee The iteratee invoked per element.
	     * @param {boolean} [retHighest] Specify returning the highest qualified index.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     */
	    function baseSortedIndexBy(array, value, iteratee, retHighest) {
	      value = iteratee(value);
	
	      var low = 0,
	          high = array ? array.length : 0,
	          valIsNaN = value !== value,
	          valIsNull = value === null,
	          valIsSymbol = isSymbol(value),
	          valIsUndefined = value === undefined;
	
	      while (low < high) {
	        var mid = nativeFloor((low + high) / 2),
	            computed = iteratee(array[mid]),
	            othIsDefined = computed !== undefined,
	            othIsNull = computed === null,
	            othIsReflexive = computed === computed,
	            othIsSymbol = isSymbol(computed);
	
	        if (valIsNaN) {
	          var setLow = retHighest || othIsReflexive;
	        } else if (valIsUndefined) {
	          setLow = othIsReflexive && (retHighest || othIsDefined);
	        } else if (valIsNull) {
	          setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull);
	        } else if (valIsSymbol) {
	          setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol);
	        } else if (othIsNull || othIsSymbol) {
	          setLow = false;
	        } else {
	          setLow = retHighest ? (computed <= value) : (computed < value);
	        }
	        if (setLow) {
	          low = mid + 1;
	        } else {
	          high = mid;
	        }
	      }
	      return nativeMin(high, MAX_ARRAY_INDEX);
	    }
	
	    /**
	     * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without
	     * support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     */
	    function baseSortedUniq(array, iteratee) {
	      var index = -1,
	          length = array.length,
	          resIndex = 0,
	          result = [];
	
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        if (!index || !eq(computed, seen)) {
	          var seen = computed;
	          result[resIndex++] = value === 0 ? 0 : value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.toNumber` which doesn't ensure correct
	     * conversions of binary, hexadecimal, or octal string values.
	     *
	     * @private
	     * @param {*} value The value to process.
	     * @returns {number} Returns the number.
	     */
	    function baseToNumber(value) {
	      if (typeof value == 'number') {
	        return value;
	      }
	      if (isSymbol(value)) {
	        return NAN;
	      }
	      return +value;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * The base implementation of `_.uniqBy` without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     */
	    function baseUniq(array, iteratee, comparator) {
	      var index = -1,
	          includes = arrayIncludes,
	          length = array.length,
	          isCommon = true,
	          result = [],
	          seen = result;
	
	      if (comparator) {
	        isCommon = false;
	        includes = arrayIncludesWith;
	      }
	      else if (length >= LARGE_ARRAY_SIZE) {
	        var set = iteratee ? null : createSet(array);
	        if (set) {
	          return setToArray(set);
	        }
	        isCommon = false;
	        includes = cacheHas;
	        seen = new SetCache;
	      }
	      else {
	        seen = iteratee ? [] : result;
	      }
	      outer:
	      while (++index < length) {
	        var value = array[index],
	            computed = iteratee ? iteratee(value) : value;
	
	        value = (comparator || value !== 0) ? value : 0;
	        if (isCommon && computed === computed) {
	          var seenIndex = seen.length;
	          while (seenIndex--) {
	            if (seen[seenIndex] === computed) {
	              continue outer;
	            }
	          }
	          if (iteratee) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	        else if (!includes(seen, computed, comparator)) {
	          if (seen !== result) {
	            seen.push(computed);
	          }
	          result.push(value);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * The base implementation of `_.unset`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to unset.
	     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
	     */
	    function baseUnset(object, path) {
	      path = isKey(path, object) ? [path] : castPath(path);
	      object = parent(object, path);
	
	      var key = toKey(last(path));
	      return !(object != null && hasOwnProperty.call(object, key)) || delete object[key];
	    }
	
	    /**
	     * The base implementation of `_.update`.
	     *
	     * @private
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to update.
	     * @param {Function} updater The function to produce the updated value.
	     * @param {Function} [customizer] The function to customize path creation.
	     * @returns {Object} Returns `object`.
	     */
	    function baseUpdate(object, path, updater, customizer) {
	      return baseSet(object, path, updater(baseGet(object, path)), customizer);
	    }
	
	    /**
	     * The base implementation of methods like `_.dropWhile` and `_.takeWhile`
	     * without support for iteratee shorthands.
	     *
	     * @private
	     * @param {Array} array The array to query.
	     * @param {Function} predicate The function invoked per iteration.
	     * @param {boolean} [isDrop] Specify dropping elements instead of taking them.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function baseWhile(array, predicate, isDrop, fromRight) {
	      var length = array.length,
	          index = fromRight ? length : -1;
	
	      while ((fromRight ? index-- : ++index < length) &&
	        predicate(array[index], index, array)) {}
	
	      return isDrop
	        ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length))
	        : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index));
	    }
	
	    /**
	     * The base implementation of `wrapperValue` which returns the result of
	     * performing a sequence of actions on the unwrapped `value`, where each
	     * successive action is supplied the return value of the previous.
	     *
	     * @private
	     * @param {*} value The unwrapped value.
	     * @param {Array} actions Actions to perform to resolve the unwrapped value.
	     * @returns {*} Returns the resolved value.
	     */
	    function baseWrapperValue(value, actions) {
	      var result = value;
	      if (result instanceof LazyWrapper) {
	        result = result.value();
	      }
	      return arrayReduce(actions, function(result, action) {
	        return action.func.apply(action.thisArg, arrayPush([result], action.args));
	      }, result);
	    }
	
	    /**
	     * The base implementation of methods like `_.xor`, without support for
	     * iteratee shorthands, that accepts an array of arrays to inspect.
	     *
	     * @private
	     * @param {Array} arrays The arrays to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of values.
	     */
	    function baseXor(arrays, iteratee, comparator) {
	      var index = -1,
	          length = arrays.length;
	
	      while (++index < length) {
	        var result = result
	          ? arrayPush(
	              baseDifference(result, arrays[index], iteratee, comparator),
	              baseDifference(arrays[index], result, iteratee, comparator)
	            )
	          : arrays[index];
	      }
	      return (result && result.length) ? baseUniq(result, iteratee, comparator) : [];
	    }
	
	    /**
	     * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
	     *
	     * @private
	     * @param {Array} props The property identifiers.
	     * @param {Array} values The property values.
	     * @param {Function} assignFunc The function to assign values.
	     * @returns {Object} Returns the new object.
	     */
	    function baseZipObject(props, values, assignFunc) {
	      var index = -1,
	          length = props.length,
	          valsLength = values.length,
	          result = {};
	
	      while (++index < length) {
	        var value = index < valsLength ? values[index] : undefined;
	        assignFunc(result, props[index], value);
	      }
	      return result;
	    }
	
	    /**
	     * Casts `value` to an empty array if it's not an array like object.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {Array|Object} Returns the cast array-like object.
	     */
	    function castArrayLikeObject(value) {
	      return isArrayLikeObject(value) ? value : [];
	    }
	
	    /**
	     * Casts `value` to `identity` if it's not a function.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {Function} Returns cast function.
	     */
	    function castFunction(value) {
	      return typeof value == 'function' ? value : identity;
	    }
	
	    /**
	     * Casts `value` to a path array if it's not one.
	     *
	     * @private
	     * @param {*} value The value to inspect.
	     * @returns {Array} Returns the cast property path array.
	     */
	    function castPath(value) {
	      return isArray(value) ? value : stringToPath(value);
	    }
	
	    /**
	     * A `baseRest` alias which can be replaced with `identity` by module
	     * replacement plugins.
	     *
	     * @private
	     * @type {Function}
	     * @param {Function} func The function to apply a rest parameter to.
	     * @returns {Function} Returns the new function.
	     */
	    var castRest = baseRest;
	
	    /**
	     * Casts `array` to a slice if it's needed.
	     *
	     * @private
	     * @param {Array} array The array to inspect.
	     * @param {number} start The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the cast slice.
	     */
	    function castSlice(array, start, end) {
	      var length = array.length;
	      end = end === undefined ? length : end;
	      return (!start && end >= length) ? array : baseSlice(array, start, end);
	    }
	
	    /**
	     * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout).
	     *
	     * @private
	     * @param {number|Object} id The timer id or timeout object of the timer to clear.
	     */
	    var clearTimeout = ctxClearTimeout || function(id) {
	      return root.clearTimeout(id);
	    };
	
	    /**
	     * Creates a clone of  `buffer`.
	     *
	     * @private
	     * @param {Buffer} buffer The buffer to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Buffer} Returns the cloned buffer.
	     */
	    function cloneBuffer(buffer, isDeep) {
	      if (isDeep) {
	        return buffer.slice();
	      }
	      var length = buffer.length,
	          result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
	
	      buffer.copy(result);
	      return result;
	    }
	
	    /**
	     * Creates a clone of `arrayBuffer`.
	     *
	     * @private
	     * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
	     * @returns {ArrayBuffer} Returns the cloned array buffer.
	     */
	    function cloneArrayBuffer(arrayBuffer) {
	      var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
	      new Uint8Array(result).set(new Uint8Array(arrayBuffer));
	      return result;
	    }
	
	    /**
	     * Creates a clone of `dataView`.
	     *
	     * @private
	     * @param {Object} dataView The data view to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned data view.
	     */
	    function cloneDataView(dataView, isDeep) {
	      var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
	      return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
	    }
	
	    /**
	     * Creates a clone of `map`.
	     *
	     * @private
	     * @param {Object} map The map to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned map.
	     */
	    function cloneMap(map, isDeep, cloneFunc) {
	      var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);
	      return arrayReduce(array, addMapEntry, new map.constructor);
	    }
	
	    /**
	     * Creates a clone of `regexp`.
	     *
	     * @private
	     * @param {Object} regexp The regexp to clone.
	     * @returns {Object} Returns the cloned regexp.
	     */
	    function cloneRegExp(regexp) {
	      var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
	      result.lastIndex = regexp.lastIndex;
	      return result;
	    }
	
	    /**
	     * Creates a clone of `set`.
	     *
	     * @private
	     * @param {Object} set The set to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned set.
	     */
	    function cloneSet(set, isDeep, cloneFunc) {
	      var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);
	      return arrayReduce(array, addSetEntry, new set.constructor);
	    }
	
	    /**
	     * Creates a clone of the `symbol` object.
	     *
	     * @private
	     * @param {Object} symbol The symbol object to clone.
	     * @returns {Object} Returns the cloned symbol object.
	     */
	    function cloneSymbol(symbol) {
	      return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
	    }
	
	    /**
	     * Creates a clone of `typedArray`.
	     *
	     * @private
	     * @param {Object} typedArray The typed array to clone.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the cloned typed array.
	     */
	    function cloneTypedArray(typedArray, isDeep) {
	      var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
	      return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
	    }
	
	    /**
	     * Compares values to sort them in ascending order.
	     *
	     * @private
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {number} Returns the sort order indicator for `value`.
	     */
	    function compareAscending(value, other) {
	      if (value !== other) {
	        var valIsDefined = value !== undefined,
	            valIsNull = value === null,
	            valIsReflexive = value === value,
	            valIsSymbol = isSymbol(value);
	
	        var othIsDefined = other !== undefined,
	            othIsNull = other === null,
	            othIsReflexive = other === other,
	            othIsSymbol = isSymbol(other);
	
	        if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) ||
	            (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) ||
	            (valIsNull && othIsDefined && othIsReflexive) ||
	            (!valIsDefined && othIsReflexive) ||
	            !valIsReflexive) {
	          return 1;
	        }
	        if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) ||
	            (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) ||
	            (othIsNull && valIsDefined && valIsReflexive) ||
	            (!othIsDefined && valIsReflexive) ||
	            !othIsReflexive) {
	          return -1;
	        }
	      }
	      return 0;
	    }
	
	    /**
	     * Used by `_.orderBy` to compare multiple properties of a value to another
	     * and stable sort them.
	     *
	     * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
	     * specify an order of "desc" for descending or "asc" for ascending sort order
	     * of corresponding values.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {boolean[]|string[]} orders The order to sort by for each property.
	     * @returns {number} Returns the sort order indicator for `object`.
	     */
	    function compareMultiple(object, other, orders) {
	      var index = -1,
	          objCriteria = object.criteria,
	          othCriteria = other.criteria,
	          length = objCriteria.length,
	          ordersLength = orders.length;
	
	      while (++index < length) {
	        var result = compareAscending(objCriteria[index], othCriteria[index]);
	        if (result) {
	          if (index >= ordersLength) {
	            return result;
	          }
	          var order = orders[index];
	          return result * (order == 'desc' ? -1 : 1);
	        }
	      }
	      // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
	      // that causes it, under certain circumstances, to provide the same value for
	      // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247
	      // for more details.
	      //
	      // This also ensures a stable sort in V8 and other engines.
	      // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
	      return object.index - other.index;
	    }
	
	    /**
	     * Creates an array that is the composition of partially applied arguments,
	     * placeholders, and provided arguments into a single array of arguments.
	     *
	     * @private
	     * @param {Array} args The provided arguments.
	     * @param {Array} partials The arguments to prepend to those provided.
	     * @param {Array} holders The `partials` placeholder indexes.
	     * @params {boolean} [isCurried] Specify composing for a curried function.
	     * @returns {Array} Returns the new array of composed arguments.
	     */
	    function composeArgs(args, partials, holders, isCurried) {
	      var argsIndex = -1,
	          argsLength = args.length,
	          holdersLength = holders.length,
	          leftIndex = -1,
	          leftLength = partials.length,
	          rangeLength = nativeMax(argsLength - holdersLength, 0),
	          result = Array(leftLength + rangeLength),
	          isUncurried = !isCurried;
	
	      while (++leftIndex < leftLength) {
	        result[leftIndex] = partials[leftIndex];
	      }
	      while (++argsIndex < holdersLength) {
	        if (isUncurried || argsIndex < argsLength) {
	          result[holders[argsIndex]] = args[argsIndex];
	        }
	      }
	      while (rangeLength--) {
	        result[leftIndex++] = args[argsIndex++];
	      }
	      return result;
	    }
	
	    /**
	     * This function is like `composeArgs` except that the arguments composition
	     * is tailored for `_.partialRight`.
	     *
	     * @private
	     * @param {Array} args The provided arguments.
	     * @param {Array} partials The arguments to append to those provided.
	     * @param {Array} holders The `partials` placeholder indexes.
	     * @params {boolean} [isCurried] Specify composing for a curried function.
	     * @returns {Array} Returns the new array of composed arguments.
	     */
	    function composeArgsRight(args, partials, holders, isCurried) {
	      var argsIndex = -1,
	          argsLength = args.length,
	          holdersIndex = -1,
	          holdersLength = holders.length,
	          rightIndex = -1,
	          rightLength = partials.length,
	          rangeLength = nativeMax(argsLength - holdersLength, 0),
	          result = Array(rangeLength + rightLength),
	          isUncurried = !isCurried;
	
	      while (++argsIndex < rangeLength) {
	        result[argsIndex] = args[argsIndex];
	      }
	      var offset = argsIndex;
	      while (++rightIndex < rightLength) {
	        result[offset + rightIndex] = partials[rightIndex];
	      }
	      while (++holdersIndex < holdersLength) {
	        if (isUncurried || argsIndex < argsLength) {
	          result[offset + holders[holdersIndex]] = args[argsIndex++];
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Copies the values of `source` to `array`.
	     *
	     * @private
	     * @param {Array} source The array to copy values from.
	     * @param {Array} [array=[]] The array to copy values to.
	     * @returns {Array} Returns `array`.
	     */
	    function copyArray(source, array) {
	      var index = -1,
	          length = source.length;
	
	      array || (array = Array(length));
	      while (++index < length) {
	        array[index] = source[index];
	      }
	      return array;
	    }
	
	    /**
	     * Copies properties of `source` to `object`.
	     *
	     * @private
	     * @param {Object} source The object to copy properties from.
	     * @param {Array} props The property identifiers to copy.
	     * @param {Object} [object={}] The object to copy properties to.
	     * @param {Function} [customizer] The function to customize copied values.
	     * @returns {Object} Returns `object`.
	     */
	    function copyObject(source, props, object, customizer) {
	      var isNew = !object;
	      object || (object = {});
	
	      var index = -1,
	          length = props.length;
	
	      while (++index < length) {
	        var key = props[index];
	
	        var newValue = customizer
	          ? customizer(object[key], source[key], key, object, source)
	          : undefined;
	
	        if (newValue === undefined) {
	          newValue = source[key];
	        }
	        if (isNew) {
	          baseAssignValue(object, key, newValue);
	        } else {
	          assignValue(object, key, newValue);
	        }
	      }
	      return object;
	    }
	
	    /**
	     * Copies own symbol properties of `source` to `object`.
	     *
	     * @private
	     * @param {Object} source The object to copy symbols from.
	     * @param {Object} [object={}] The object to copy symbols to.
	     * @returns {Object} Returns `object`.
	     */
	    function copySymbols(source, object) {
	      return copyObject(source, getSymbols(source), object);
	    }
	
	    /**
	     * Creates a function like `_.groupBy`.
	     *
	     * @private
	     * @param {Function} setter The function to set accumulator values.
	     * @param {Function} [initializer] The accumulator object initializer.
	     * @returns {Function} Returns the new aggregator function.
	     */
	    function createAggregator(setter, initializer) {
	      return function(collection, iteratee) {
	        var func = isArray(collection) ? arrayAggregator : baseAggregator,
	            accumulator = initializer ? initializer() : {};
	
	        return func(collection, setter, getIteratee(iteratee, 2), accumulator);
	      };
	    }
	
	    /**
	     * Creates a function like `_.assign`.
	     *
	     * @private
	     * @param {Function} assigner The function to assign values.
	     * @returns {Function} Returns the new assigner function.
	     */
	    function createAssigner(assigner) {
	      return baseRest(function(object, sources) {
	        var index = -1,
	            length = sources.length,
	            customizer = length > 1 ? sources[length - 1] : undefined,
	            guard = length > 2 ? sources[2] : undefined;
	
	        customizer = (assigner.length > 3 && typeof customizer == 'function')
	          ? (length--, customizer)
	          : undefined;
	
	        if (guard && isIterateeCall(sources[0], sources[1], guard)) {
	          customizer = length < 3 ? undefined : customizer;
	          length = 1;
	        }
	        object = Object(object);
	        while (++index < length) {
	          var source = sources[index];
	          if (source) {
	            assigner(object, source, index, customizer);
	          }
	        }
	        return object;
	      });
	    }
	
	    /**
	     * Creates a `baseEach` or `baseEachRight` function.
	     *
	     * @private
	     * @param {Function} eachFunc The function to iterate over a collection.
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new base function.
	     */
	    function createBaseEach(eachFunc, fromRight) {
	      return function(collection, iteratee) {
	        if (collection == null) {
	          return collection;
	        }
	        if (!isArrayLike(collection)) {
	          return eachFunc(collection, iteratee);
	        }
	        var length = collection.length,
	            index = fromRight ? length : -1,
	            iterable = Object(collection);
	
	        while ((fromRight ? index-- : ++index < length)) {
	          if (iteratee(iterable[index], index, iterable) === false) {
	            break;
	          }
	        }
	        return collection;
	      };
	    }
	
	    /**
	     * Creates a base function for methods like `_.forIn` and `_.forOwn`.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new base function.
	     */
	    function createBaseFor(fromRight) {
	      return function(object, iteratee, keysFunc) {
	        var index = -1,
	            iterable = Object(object),
	            props = keysFunc(object),
	            length = props.length;
	
	        while (length--) {
	          var key = props[fromRight ? length : ++index];
	          if (iteratee(iterable[key], key, iterable) === false) {
	            break;
	          }
	        }
	        return object;
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with the optional `this`
	     * binding of `thisArg`.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createBind(func, bitmask, thisArg) {
	      var isBind = bitmask & BIND_FLAG,
	          Ctor = createCtor(func);
	
	      function wrapper() {
	        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	        return fn.apply(isBind ? thisArg : this, arguments);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a function like `_.lowerFirst`.
	     *
	     * @private
	     * @param {string} methodName The name of the `String` case method to use.
	     * @returns {Function} Returns the new case function.
	     */
	    function createCaseFirst(methodName) {
	      return function(string) {
	        string = toString(string);
	
	        var strSymbols = hasUnicode(string)
	          ? stringToArray(string)
	          : undefined;
	
	        var chr = strSymbols
	          ? strSymbols[0]
	          : string.charAt(0);
	
	        var trailing = strSymbols
	          ? castSlice(strSymbols, 1).join('')
	          : string.slice(1);
	
	        return chr[methodName]() + trailing;
	      };
	    }
	
	    /**
	     * Creates a function like `_.camelCase`.
	     *
	     * @private
	     * @param {Function} callback The function to combine each word.
	     * @returns {Function} Returns the new compounder function.
	     */
	    function createCompounder(callback) {
	      return function(string) {
	        return arrayReduce(words(deburr(string).replace(reApos, '')), callback, '');
	      };
	    }
	
	    /**
	     * Creates a function that produces an instance of `Ctor` regardless of
	     * whether it was invoked as part of a `new` expression or by `call` or `apply`.
	     *
	     * @private
	     * @param {Function} Ctor The constructor to wrap.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createCtor(Ctor) {
	      return function() {
	        // Use a `switch` statement to work with class constructors. See
	        // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
	        // for more details.
	        var args = arguments;
	        switch (args.length) {
	          case 0: return new Ctor;
	          case 1: return new Ctor(args[0]);
	          case 2: return new Ctor(args[0], args[1]);
	          case 3: return new Ctor(args[0], args[1], args[2]);
	          case 4: return new Ctor(args[0], args[1], args[2], args[3]);
	          case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
	          case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
	          case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
	        }
	        var thisBinding = baseCreate(Ctor.prototype),
	            result = Ctor.apply(thisBinding, args);
	
	        // Mimic the constructor's `return` behavior.
	        // See https://es5.github.io/#x13.2.2 for more details.
	        return isObject(result) ? result : thisBinding;
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to enable currying.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {number} arity The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createCurry(func, bitmask, arity) {
	      var Ctor = createCtor(func);
	
	      function wrapper() {
	        var length = arguments.length,
	            args = Array(length),
	            index = length,
	            placeholder = getHolder(wrapper);
	
	        while (index--) {
	          args[index] = arguments[index];
	        }
	        var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
	          ? []
	          : replaceHolders(args, placeholder);
	
	        length -= holders.length;
	        if (length < arity) {
	          return createRecurry(
	            func, bitmask, createHybrid, wrapper.placeholder, undefined,
	            args, holders, undefined, undefined, arity - length);
	        }
	        var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	        return apply(fn, this, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a `_.find` or `_.findLast` function.
	     *
	     * @private
	     * @param {Function} findIndexFunc The function to find the collection index.
	     * @returns {Function} Returns the new find function.
	     */
	    function createFind(findIndexFunc) {
	      return function(collection, predicate, fromIndex) {
	        var iterable = Object(collection);
	        if (!isArrayLike(collection)) {
	          var iteratee = getIteratee(predicate, 3);
	          collection = keys(collection);
	          predicate = function(key) { return iteratee(iterable[key], key, iterable); };
	        }
	        var index = findIndexFunc(collection, predicate, fromIndex);
	        return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
	      };
	    }
	
	    /**
	     * Creates a `_.flow` or `_.flowRight` function.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new flow function.
	     */
	    function createFlow(fromRight) {
	      return flatRest(function(funcs) {
	        var length = funcs.length,
	            index = length,
	            prereq = LodashWrapper.prototype.thru;
	
	        if (fromRight) {
	          funcs.reverse();
	        }
	        while (index--) {
	          var func = funcs[index];
	          if (typeof func != 'function') {
	            throw new TypeError(FUNC_ERROR_TEXT);
	          }
	          if (prereq && !wrapper && getFuncName(func) == 'wrapper') {
	            var wrapper = new LodashWrapper([], true);
	          }
	        }
	        index = wrapper ? index : length;
	        while (++index < length) {
	          func = funcs[index];
	
	          var funcName = getFuncName(func),
	              data = funcName == 'wrapper' ? getData(func) : undefined;
	
	          if (data && isLaziable(data[0]) &&
	                data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) &&
	                !data[4].length && data[9] == 1
	              ) {
	            wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]);
	          } else {
	            wrapper = (func.length == 1 && isLaziable(func))
	              ? wrapper[funcName]()
	              : wrapper.thru(func);
	          }
	        }
	        return function() {
	          var args = arguments,
	              value = args[0];
	
	          if (wrapper && args.length == 1 &&
	              isArray(value) && value.length >= LARGE_ARRAY_SIZE) {
	            return wrapper.plant(value).value();
	          }
	          var index = 0,
	              result = length ? funcs[index].apply(this, args) : value;
	
	          while (++index < length) {
	            result = funcs[index].call(this, result);
	          }
	          return result;
	        };
	      });
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with optional `this`
	     * binding of `thisArg`, partial application, and currying.
	     *
	     * @private
	     * @param {Function|string} func The function or method name to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to prepend to those provided to
	     *  the new function.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [partialsRight] The arguments to append to those provided
	     *  to the new function.
	     * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
	      var isAry = bitmask & ARY_FLAG,
	          isBind = bitmask & BIND_FLAG,
	          isBindKey = bitmask & BIND_KEY_FLAG,
	          isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
	          isFlip = bitmask & FLIP_FLAG,
	          Ctor = isBindKey ? undefined : createCtor(func);
	
	      function wrapper() {
	        var length = arguments.length,
	            args = Array(length),
	            index = length;
	
	        while (index--) {
	          args[index] = arguments[index];
	        }
	        if (isCurried) {
	          var placeholder = getHolder(wrapper),
	              holdersCount = countHolders(args, placeholder);
	        }
	        if (partials) {
	          args = composeArgs(args, partials, holders, isCurried);
	        }
	        if (partialsRight) {
	          args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
	        }
	        length -= holdersCount;
	        if (isCurried && length < arity) {
	          var newHolders = replaceHolders(args, placeholder);
	          return createRecurry(
	            func, bitmask, createHybrid, wrapper.placeholder, thisArg,
	            args, newHolders, argPos, ary, arity - length
	          );
	        }
	        var thisBinding = isBind ? thisArg : this,
	            fn = isBindKey ? thisBinding[func] : func;
	
	        length = args.length;
	        if (argPos) {
	          args = reorder(args, argPos);
	        } else if (isFlip && length > 1) {
	          args.reverse();
	        }
	        if (isAry && ary < length) {
	          args.length = ary;
	        }
	        if (this && this !== root && this instanceof wrapper) {
	          fn = Ctor || createCtor(fn);
	        }
	        return fn.apply(thisBinding, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a function like `_.invertBy`.
	     *
	     * @private
	     * @param {Function} setter The function to set accumulator values.
	     * @param {Function} toIteratee The function to resolve iteratees.
	     * @returns {Function} Returns the new inverter function.
	     */
	    function createInverter(setter, toIteratee) {
	      return function(object, iteratee) {
	        return baseInverter(object, setter, toIteratee(iteratee), {});
	      };
	    }
	
	    /**
	     * Creates a function that performs a mathematical operation on two values.
	     *
	     * @private
	     * @param {Function} operator The function to perform the operation.
	     * @param {number} [defaultValue] The value used for `undefined` arguments.
	     * @returns {Function} Returns the new mathematical operation function.
	     */
	    function createMathOperation(operator, defaultValue) {
	      return function(value, other) {
	        var result;
	        if (value === undefined && other === undefined) {
	          return defaultValue;
	        }
	        if (value !== undefined) {
	          result = value;
	        }
	        if (other !== undefined) {
	          if (result === undefined) {
	            return other;
	          }
	          if (typeof value == 'string' || typeof other == 'string') {
	            value = baseToString(value);
	            other = baseToString(other);
	          } else {
	            value = baseToNumber(value);
	            other = baseToNumber(other);
	          }
	          result = operator(value, other);
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Creates a function like `_.over`.
	     *
	     * @private
	     * @param {Function} arrayFunc The function to iterate over iteratees.
	     * @returns {Function} Returns the new over function.
	     */
	    function createOver(arrayFunc) {
	      return flatRest(function(iteratees) {
	        iteratees = arrayMap(iteratees, baseUnary(getIteratee()));
	        return baseRest(function(args) {
	          var thisArg = this;
	          return arrayFunc(iteratees, function(iteratee) {
	            return apply(iteratee, thisArg, args);
	          });
	        });
	      });
	    }
	
	    /**
	     * Creates the padding for `string` based on `length`. The `chars` string
	     * is truncated if the number of characters exceeds `length`.
	     *
	     * @private
	     * @param {number} length The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padding for `string`.
	     */
	    function createPadding(length, chars) {
	      chars = chars === undefined ? ' ' : baseToString(chars);
	
	      var charsLength = chars.length;
	      if (charsLength < 2) {
	        return charsLength ? baseRepeat(chars, length) : chars;
	      }
	      var result = baseRepeat(chars, nativeCeil(length / stringSize(chars)));
	      return hasUnicode(chars)
	        ? castSlice(stringToArray(result), 0, length).join('')
	        : result.slice(0, length);
	    }
	
	    /**
	     * Creates a function that wraps `func` to invoke it with the `this` binding
	     * of `thisArg` and `partials` prepended to the arguments it receives.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {*} thisArg The `this` binding of `func`.
	     * @param {Array} partials The arguments to prepend to those provided to
	     *  the new function.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createPartial(func, bitmask, thisArg, partials) {
	      var isBind = bitmask & BIND_FLAG,
	          Ctor = createCtor(func);
	
	      function wrapper() {
	        var argsIndex = -1,
	            argsLength = arguments.length,
	            leftIndex = -1,
	            leftLength = partials.length,
	            args = Array(leftLength + argsLength),
	            fn = (this && this !== root && this instanceof wrapper) ? Ctor : func;
	
	        while (++leftIndex < leftLength) {
	          args[leftIndex] = partials[leftIndex];
	        }
	        while (argsLength--) {
	          args[leftIndex++] = arguments[++argsIndex];
	        }
	        return apply(fn, isBind ? thisArg : this, args);
	      }
	      return wrapper;
	    }
	
	    /**
	     * Creates a `_.range` or `_.rangeRight` function.
	     *
	     * @private
	     * @param {boolean} [fromRight] Specify iterating from right to left.
	     * @returns {Function} Returns the new range function.
	     */
	    function createRange(fromRight) {
	      return function(start, end, step) {
	        if (step && typeof step != 'number' && isIterateeCall(start, end, step)) {
	          end = step = undefined;
	        }
	        // Ensure the sign of `-0` is preserved.
	        start = toFinite(start);
	        if (end === undefined) {
	          end = start;
	          start = 0;
	        } else {
	          end = toFinite(end);
	        }
	        step = step === undefined ? (start < end ? 1 : -1) : toFinite(step);
	        return baseRange(start, end, step, fromRight);
	      };
	    }
	
	    /**
	     * Creates a function that performs a relational operation on two values.
	     *
	     * @private
	     * @param {Function} operator The function to perform the operation.
	     * @returns {Function} Returns the new relational operation function.
	     */
	    function createRelationalOperation(operator) {
	      return function(value, other) {
	        if (!(typeof value == 'string' && typeof other == 'string')) {
	          value = toNumber(value);
	          other = toNumber(other);
	        }
	        return operator(value, other);
	      };
	    }
	
	    /**
	     * Creates a function that wraps `func` to continue currying.
	     *
	     * @private
	     * @param {Function} func The function to wrap.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @param {Function} wrapFunc The function to create the `func` wrapper.
	     * @param {*} placeholder The placeholder value.
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to prepend to those provided to
	     *  the new function.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
	      var isCurry = bitmask & CURRY_FLAG,
	          newHolders = isCurry ? holders : undefined,
	          newHoldersRight = isCurry ? undefined : holders,
	          newPartials = isCurry ? partials : undefined,
	          newPartialsRight = isCurry ? undefined : partials;
	
	      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
	      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
	
	      if (!(bitmask & CURRY_BOUND_FLAG)) {
	        bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
	      }
	      var newData = [
	        func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
	        newHoldersRight, argPos, ary, arity
	      ];
	
	      var result = wrapFunc.apply(undefined, newData);
	      if (isLaziable(func)) {
	        setData(result, newData);
	      }
	      result.placeholder = placeholder;
	      return setWrapToString(result, func, bitmask);
	    }
	
	    /**
	     * Creates a function like `_.round`.
	     *
	     * @private
	     * @param {string} methodName The name of the `Math` method to use when rounding.
	     * @returns {Function} Returns the new round function.
	     */
	    function createRound(methodName) {
	      var func = Math[methodName];
	      return function(number, precision) {
	        number = toNumber(number);
	        precision = nativeMin(toInteger(precision), 292);
	        if (precision) {
	          // Shift with exponential notation to avoid floating-point issues.
	          // See [MDN](https://mdn.io/round#Examples) for more details.
	          var pair = (toString(number) + 'e').split('e'),
	              value = func(pair[0] + 'e' + (+pair[1] + precision));
	
	          pair = (toString(value) + 'e').split('e');
	          return +(pair[0] + 'e' + (+pair[1] - precision));
	        }
	        return func(number);
	      };
	    }
	
	    /**
	     * Creates a set object of `values`.
	     *
	     * @private
	     * @param {Array} values The values to add to the set.
	     * @returns {Object} Returns the new set.
	     */
	    var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {
	      return new Set(values);
	    };
	
	    /**
	     * Creates a `_.toPairs` or `_.toPairsIn` function.
	     *
	     * @private
	     * @param {Function} keysFunc The function to get the keys of a given object.
	     * @returns {Function} Returns the new pairs function.
	     */
	    function createToPairs(keysFunc) {
	      return function(object) {
	        var tag = getTag(object);
	        if (tag == mapTag) {
	          return mapToArray(object);
	        }
	        if (tag == setTag) {
	          return setToPairs(object);
	        }
	        return baseToPairs(object, keysFunc(object));
	      };
	    }
	
	    /**
	     * Creates a function that either curries or invokes `func` with optional
	     * `this` binding and partially applied arguments.
	     *
	     * @private
	     * @param {Function|string} func The function or method name to wrap.
	     * @param {number} bitmask The bitmask flags.
	     *  The bitmask may be composed of the following flags:
	     *     1 - `_.bind`
	     *     2 - `_.bindKey`
	     *     4 - `_.curry` or `_.curryRight` of a bound function
	     *     8 - `_.curry`
	     *    16 - `_.curryRight`
	     *    32 - `_.partial`
	     *    64 - `_.partialRight`
	     *   128 - `_.rearg`
	     *   256 - `_.ary`
	     *   512 - `_.flip`
	     * @param {*} [thisArg] The `this` binding of `func`.
	     * @param {Array} [partials] The arguments to be partially applied.
	     * @param {Array} [holders] The `partials` placeholder indexes.
	     * @param {Array} [argPos] The argument positions of the new function.
	     * @param {number} [ary] The arity cap of `func`.
	     * @param {number} [arity] The arity of `func`.
	     * @returns {Function} Returns the new wrapped function.
	     */
	    function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
	      var isBindKey = bitmask & BIND_KEY_FLAG;
	      if (!isBindKey && typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      var length = partials ? partials.length : 0;
	      if (!length) {
	        bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
	        partials = holders = undefined;
	      }
	      ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0);
	      arity = arity === undefined ? arity : toInteger(arity);
	      length -= holders ? holders.length : 0;
	
	      if (bitmask & PARTIAL_RIGHT_FLAG) {
	        var partialsRight = partials,
	            holdersRight = holders;
	
	        partials = holders = undefined;
	      }
	      var data = isBindKey ? undefined : getData(func);
	
	      var newData = [
	        func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
	        argPos, ary, arity
	      ];
	
	      if (data) {
	        mergeData(newData, data);
	      }
	      func = newData[0];
	      bitmask = newData[1];
	      thisArg = newData[2];
	      partials = newData[3];
	      holders = newData[4];
	      arity = newData[9] = newData[9] == null
	        ? (isBindKey ? 0 : func.length)
	        : nativeMax(newData[9] - length, 0);
	
	      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
	        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
	      }
	      if (!bitmask || bitmask == BIND_FLAG) {
	        var result = createBind(func, bitmask, thisArg);
	      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
	        result = createCurry(func, bitmask, arity);
	      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
	        result = createPartial(func, bitmask, thisArg, partials);
	      } else {
	        result = createHybrid.apply(undefined, newData);
	      }
	      var setter = data ? baseSetData : setData;
	      return setWrapToString(setter(result, newData), func, bitmask);
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for arrays with support for
	     * partial deep comparisons.
	     *
	     * @private
	     * @param {Array} array The array to compare.
	     * @param {Array} other The other array to compare.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
	     *  for more details.
	     * @param {Object} stack Tracks traversed `array` and `other` objects.
	     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
	     */
	    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
	      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
	          arrLength = array.length,
	          othLength = other.length;
	
	      if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
	        return false;
	      }
	      // Assume cyclic values are equal.
	      var stacked = stack.get(array);
	      if (stacked && stack.get(other)) {
	        return stacked == other;
	      }
	      var index = -1,
	          result = true,
	          seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined;
	
	      stack.set(array, other);
	      stack.set(other, array);
	
	      // Ignore non-index properties.
	      while (++index < arrLength) {
	        var arrValue = array[index],
	            othValue = other[index];
	
	        if (customizer) {
	          var compared = isPartial
	            ? customizer(othValue, arrValue, index, other, array, stack)
	            : customizer(arrValue, othValue, index, array, other, stack);
	        }
	        if (compared !== undefined) {
	          if (compared) {
	            continue;
	          }
	          result = false;
	          break;
	        }
	        // Recursively compare arrays (susceptible to call stack limits).
	        if (seen) {
	          if (!arraySome(other, function(othValue, othIndex) {
	                if (!cacheHas(seen, othIndex) &&
	                    (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) {
	                  return seen.push(othIndex);
	                }
	              })) {
	            result = false;
	            break;
	          }
	        } else if (!(
	              arrValue === othValue ||
	                equalFunc(arrValue, othValue, customizer, bitmask, stack)
	            )) {
	          result = false;
	          break;
	        }
	      }
	      stack['delete'](array);
	      stack['delete'](other);
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for comparing objects of
	     * the same `toStringTag`.
	     *
	     * **Note:** This function only supports comparing values with tags of
	     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {string} tag The `toStringTag` of the objects to compare.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
	     *  for more details.
	     * @param {Object} stack Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) {
	      switch (tag) {
	        case dataViewTag:
	          if ((object.byteLength != other.byteLength) ||
	              (object.byteOffset != other.byteOffset)) {
	            return false;
	          }
	          object = object.buffer;
	          other = other.buffer;
	
	        case arrayBufferTag:
	          if ((object.byteLength != other.byteLength) ||
	              !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
	            return false;
	          }
	          return true;
	
	        case boolTag:
	        case dateTag:
	        case numberTag:
	          // Coerce booleans to `1` or `0` and dates to milliseconds.
	          // Invalid dates are coerced to `NaN`.
	          return eq(+object, +other);
	
	        case errorTag:
	          return object.name == other.name && object.message == other.message;
	
	        case regexpTag:
	        case stringTag:
	          // Coerce regexes to strings and treat strings, primitives and objects,
	          // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
	          // for more details.
	          return object == (other + '');
	
	        case mapTag:
	          var convert = mapToArray;
	
	        case setTag:
	          var isPartial = bitmask & PARTIAL_COMPARE_FLAG;
	          convert || (convert = setToArray);
	
	          if (object.size != other.size && !isPartial) {
	            return false;
	          }
	          // Assume cyclic values are equal.
	          var stacked = stack.get(object);
	          if (stacked) {
	            return stacked == other;
	          }
	          bitmask |= UNORDERED_COMPARE_FLAG;
	
	          // Recursively compare objects (susceptible to call stack limits).
	          stack.set(object, other);
	          var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
	          stack['delete'](object);
	          return result;
	
	        case symbolTag:
	          if (symbolValueOf) {
	            return symbolValueOf.call(object) == symbolValueOf.call(other);
	          }
	      }
	      return false;
	    }
	
	    /**
	     * A specialized version of `baseIsEqualDeep` for objects with support for
	     * partial deep comparisons.
	     *
	     * @private
	     * @param {Object} object The object to compare.
	     * @param {Object} other The other object to compare.
	     * @param {Function} equalFunc The function to determine equivalents of values.
	     * @param {Function} customizer The function to customize comparisons.
	     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
	     *  for more details.
	     * @param {Object} stack Tracks traversed `object` and `other` objects.
	     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
	     */
	    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
	      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
	          objProps = keys(object),
	          objLength = objProps.length,
	          othProps = keys(other),
	          othLength = othProps.length;
	
	      if (objLength != othLength && !isPartial) {
	        return false;
	      }
	      var index = objLength;
	      while (index--) {
	        var key = objProps[index];
	        if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
	          return false;
	        }
	      }
	      // Assume cyclic values are equal.
	      var stacked = stack.get(object);
	      if (stacked && stack.get(other)) {
	        return stacked == other;
	      }
	      var result = true;
	      stack.set(object, other);
	      stack.set(other, object);
	
	      var skipCtor = isPartial;
	      while (++index < objLength) {
	        key = objProps[index];
	        var objValue = object[key],
	            othValue = other[key];
	
	        if (customizer) {
	          var compared = isPartial
	            ? customizer(othValue, objValue, key, other, object, stack)
	            : customizer(objValue, othValue, key, object, other, stack);
	        }
	        // Recursively compare objects (susceptible to call stack limits).
	        if (!(compared === undefined
	              ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack))
	              : compared
	            )) {
	          result = false;
	          break;
	        }
	        skipCtor || (skipCtor = key == 'constructor');
	      }
	      if (result && !skipCtor) {
	        var objCtor = object.constructor,
	            othCtor = other.constructor;
	
	        // Non `Object` object instances with different constructors are not equal.
	        if (objCtor != othCtor &&
	            ('constructor' in object && 'constructor' in other) &&
	            !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
	              typeof othCtor == 'function' && othCtor instanceof othCtor)) {
	          result = false;
	        }
	      }
	      stack['delete'](object);
	      stack['delete'](other);
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseRest` which flattens the rest array.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @returns {Function} Returns the new function.
	     */
	    function flatRest(func) {
	      return setToString(overRest(func, undefined, flatten), func + '');
	    }
	
	    /**
	     * Creates an array of own enumerable property names and symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function getAllKeys(object) {
	      return baseGetAllKeys(object, keys, getSymbols);
	    }
	
	    /**
	     * Creates an array of own and inherited enumerable property names and
	     * symbols of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names and symbols.
	     */
	    function getAllKeysIn(object) {
	      return baseGetAllKeys(object, keysIn, getSymbolsIn);
	    }
	
	    /**
	     * Gets metadata for `func`.
	     *
	     * @private
	     * @param {Function} func The function to query.
	     * @returns {*} Returns the metadata for `func`.
	     */
	    var getData = !metaMap ? noop : function(func) {
	      return metaMap.get(func);
	    };
	
	    /**
	     * Gets the name of `func`.
	     *
	     * @private
	     * @param {Function} func The function to query.
	     * @returns {string} Returns the function name.
	     */
	    function getFuncName(func) {
	      var result = (func.name + ''),
	          array = realNames[result],
	          length = hasOwnProperty.call(realNames, result) ? array.length : 0;
	
	      while (length--) {
	        var data = array[length],
	            otherFunc = data.func;
	        if (otherFunc == null || otherFunc == func) {
	          return data.name;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Gets the argument placeholder value for `func`.
	     *
	     * @private
	     * @param {Function} func The function to inspect.
	     * @returns {*} Returns the placeholder value.
	     */
	    function getHolder(func) {
	      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
	      return object.placeholder;
	    }
	
	    /**
	     * Gets the appropriate "iteratee" function. If `_.iteratee` is customized,
	     * this function returns the custom method, otherwise it returns `baseIteratee`.
	     * If arguments are provided, the chosen function is invoked with them and
	     * its result is returned.
	     *
	     * @private
	     * @param {*} [value] The value to convert to an iteratee.
	     * @param {number} [arity] The arity of the created iteratee.
	     * @returns {Function} Returns the chosen function or its result.
	     */
	    function getIteratee() {
	      var result = lodash.iteratee || iteratee;
	      result = result === iteratee ? baseIteratee : result;
	      return arguments.length ? result(arguments[0], arguments[1]) : result;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Gets the property names, values, and compare flags of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the match data of `object`.
	     */
	    function getMatchData(object) {
	      var result = keys(object),
	          length = result.length;
	
	      while (length--) {
	        var key = result[length],
	            value = object[key];
	
	        result[length] = [key, value, isStrictComparable(value)];
	      }
	      return result;
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Creates an array of the own enumerable symbol properties of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of symbols.
	     */
	    var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;
	
	    /**
	     * Creates an array of the own and inherited enumerable symbol properties
	     * of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of symbols.
	     */
	    var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {
	      var result = [];
	      while (object) {
	        arrayPush(result, getSymbols(object));
	        object = getPrototype(object);
	      }
	      return result;
	    };
	
	    /**
	     * Gets the `toStringTag` of `value`.
	     *
	     * @private
	     * @param {*} value The value to query.
	     * @returns {string} Returns the `toStringTag`.
	     */
	    var getTag = baseGetTag;
	
	    // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
	    if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
	        (Map && getTag(new Map) != mapTag) ||
	        (Promise && getTag(Promise.resolve()) != promiseTag) ||
	        (Set && getTag(new Set) != setTag) ||
	        (WeakMap && getTag(new WeakMap) != weakMapTag)) {
	      getTag = function(value) {
	        var result = objectToString.call(value),
	            Ctor = result == objectTag ? value.constructor : undefined,
	            ctorString = Ctor ? toSource(Ctor) : undefined;
	
	        if (ctorString) {
	          switch (ctorString) {
	            case dataViewCtorString: return dataViewTag;
	            case mapCtorString: return mapTag;
	            case promiseCtorString: return promiseTag;
	            case setCtorString: return setTag;
	            case weakMapCtorString: return weakMapTag;
	          }
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Gets the view, applying any `transforms` to the `start` and `end` positions.
	     *
	     * @private
	     * @param {number} start The start of the view.
	     * @param {number} end The end of the view.
	     * @param {Array} transforms The transformations to apply to the view.
	     * @returns {Object} Returns an object containing the `start` and `end`
	     *  positions of the view.
	     */
	    function getView(start, end, transforms) {
	      var index = -1,
	          length = transforms.length;
	
	      while (++index < length) {
	        var data = transforms[index],
	            size = data.size;
	
	        switch (data.type) {
	          case 'drop':      start += size; break;
	          case 'dropRight': end -= size; break;
	          case 'take':      end = nativeMin(end, start + size); break;
	          case 'takeRight': start = nativeMax(start, end - size); break;
	        }
	      }
	      return { 'start': start, 'end': end };
	    }
	
	    /**
	     * Extracts wrapper details from the `source` body comment.
	     *
	     * @private
	     * @param {string} source The source to inspect.
	     * @returns {Array} Returns the wrapper details.
	     */
	    function getWrapDetails(source) {
	      var match = source.match(reWrapDetails);
	      return match ? match[1].split(reSplitDetails) : [];
	    }
	
	    /**
	     * Checks if `path` exists on `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @param {Function} hasFunc The function to check properties.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     */
	    function hasPath(object, path, hasFunc) {
	      path = isKey(path, object) ? [path] : castPath(path);
	
	      var index = -1,
	          length = path.length,
	          result = false;
	
	      while (++index < length) {
	        var key = toKey(path[index]);
	        if (!(result = object != null && hasFunc(object, key))) {
	          break;
	        }
	        object = object[key];
	      }
	      if (result || ++index != length) {
	        return result;
	      }
	      length = object ? object.length : 0;
	      return !!length && isLength(length) && isIndex(key, length) &&
	        (isArray(object) || isArguments(object));
	    }
	
	    /**
	     * Initializes an array clone.
	     *
	     * @private
	     * @param {Array} array The array to clone.
	     * @returns {Array} Returns the initialized clone.
	     */
	    function initCloneArray(array) {
	      var length = array.length,
	          result = array.constructor(length);
	
	      // Add properties assigned by `RegExp#exec`.
	      if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
	        result.index = array.index;
	        result.input = array.input;
	      }
	      return result;
	    }
	
	    /**
	     * Initializes an object clone.
	     *
	     * @private
	     * @param {Object} object The object to clone.
	     * @returns {Object} Returns the initialized clone.
	     */
	    function initCloneObject(object) {
	      return (typeof object.constructor == 'function' && !isPrototype(object))
	        ? baseCreate(getPrototype(object))
	        : {};
	    }
	
	    /**
	     * Initializes an object clone based on its `toStringTag`.
	     *
	     * **Note:** This function only supports cloning values with tags of
	     * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
	     *
	     * @private
	     * @param {Object} object The object to clone.
	     * @param {string} tag The `toStringTag` of the object to clone.
	     * @param {Function} cloneFunc The function to clone values.
	     * @param {boolean} [isDeep] Specify a deep clone.
	     * @returns {Object} Returns the initialized clone.
	     */
	    function initCloneByTag(object, tag, cloneFunc, isDeep) {
	      var Ctor = object.constructor;
	      switch (tag) {
	        case arrayBufferTag:
	          return cloneArrayBuffer(object);
	
	        case boolTag:
	        case dateTag:
	          return new Ctor(+object);
	
	        case dataViewTag:
	          return cloneDataView(object, isDeep);
	
	        case float32Tag: case float64Tag:
	        case int8Tag: case int16Tag: case int32Tag:
	        case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:
	          return cloneTypedArray(object, isDeep);
	
	        case mapTag:
	          return cloneMap(object, isDeep, cloneFunc);
	
	        case numberTag:
	        case stringTag:
	          return new Ctor(object);
	
	        case regexpTag:
	          return cloneRegExp(object);
	
	        case setTag:
	          return cloneSet(object, isDeep, cloneFunc);
	
	        case symbolTag:
	          return cloneSymbol(object);
	      }
	    }
	
	    /**
	     * Inserts wrapper `details` in a comment at the top of the `source` body.
	     *
	     * @private
	     * @param {string} source The source to modify.
	     * @returns {Array} details The details to insert.
	     * @returns {string} Returns the modified source.
	     */
	    function insertWrapDetails(source, details) {
	      var length = details.length;
	      if (!length) {
	        return source;
	      }
	      var lastIndex = length - 1;
	      details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
	      details = details.join(length > 2 ? ', ' : ' ');
	      return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
	    }
	
	    /**
	     * Checks if `value` is a flattenable `arguments` object or array.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
	     */
	    function isFlattenable(value) {
	      return isArray(value) || isArguments(value) ||
	        !!(spreadableSymbol && value && value[spreadableSymbol]);
	    }
	
	    /**
	     * Checks if `value` is a valid array-like index.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
	     * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
	     */
	    function isIndex(value, length) {
	      length = length == null ? MAX_SAFE_INTEGER : length;
	      return !!length &&
	        (typeof value == 'number' || reIsUint.test(value)) &&
	        (value > -1 && value % 1 == 0 && value < length);
	    }
	
	    /**
	     * Checks if the given arguments are from an iteratee call.
	     *
	     * @private
	     * @param {*} value The potential iteratee value argument.
	     * @param {*} index The potential iteratee index or key argument.
	     * @param {*} object The potential iteratee object argument.
	     * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
	     *  else `false`.
	     */
	    function isIterateeCall(value, index, object) {
	      if (!isObject(object)) {
	        return false;
	      }
	      var type = typeof index;
	      if (type == 'number'
	            ? (isArrayLike(object) && isIndex(index, object.length))
	            : (type == 'string' && index in object)
	          ) {
	        return eq(object[index], value);
	      }
	      return false;
	    }
	
	    /**
	     * 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));
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * Checks if `func` has a lazy counterpart.
	     *
	     * @private
	     * @param {Function} func The function to check.
	     * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
	     *  else `false`.
	     */
	    function isLaziable(func) {
	      var funcName = getFuncName(func),
	          other = lodash[funcName];
	
	      if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
	        return false;
	      }
	      if (func === other) {
	        return true;
	      }
	      var data = getData(other);
	      return !!data && func === data[0];
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * Checks if `func` is capable of being masked.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `func` is maskable, else `false`.
	     */
	    var isMaskable = coreJsData ? isFunction : stubFalse;
	
	    /**
	     * Checks if `value` is likely a prototype object.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
	     */
	    function isPrototype(value) {
	      var Ctor = value && value.constructor,
	          proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
	
	      return value === proto;
	    }
	
	    /**
	     * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
	     *
	     * @private
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` if suitable for strict
	     *  equality comparisons, else `false`.
	     */
	    function isStrictComparable(value) {
	      return value === value && !isObject(value);
	    }
	
	    /**
	     * A specialized version of `matchesProperty` for source values suitable
	     * for strict equality comparisons, i.e. `===`.
	     *
	     * @private
	     * @param {string} key The key of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     */
	    function matchesStrictComparable(key, srcValue) {
	      return function(object) {
	        if (object == null) {
	          return false;
	        }
	        return object[key] === srcValue &&
	          (srcValue !== undefined || (key in Object(object)));
	      };
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Merges the function metadata of `source` into `data`.
	     *
	     * Merging metadata reduces the number of wrappers used to invoke a function.
	     * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
	     * may be applied regardless of execution order. Methods like `_.ary` and
	     * `_.rearg` modify function arguments, making the order in which they are
	     * executed important, preventing the merging of metadata. However, we make
	     * an exception for a safe combined case where curried functions have `_.ary`
	     * and or `_.rearg` applied.
	     *
	     * @private
	     * @param {Array} data The destination metadata.
	     * @param {Array} source The source metadata.
	     * @returns {Array} Returns `data`.
	     */
	    function mergeData(data, source) {
	      var bitmask = data[1],
	          srcBitmask = source[1],
	          newBitmask = bitmask | srcBitmask,
	          isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
	
	      var isCombo =
	        ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
	        ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
	        ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
	
	      // Exit early if metadata can't be merged.
	      if (!(isCommon || isCombo)) {
	        return data;
	      }
	      // Use source `thisArg` if available.
	      if (srcBitmask & BIND_FLAG) {
	        data[2] = source[2];
	        // Set when currying a bound function.
	        newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG;
	      }
	      // Compose partial arguments.
	      var value = source[3];
	      if (value) {
	        var partials = data[3];
	        data[3] = partials ? composeArgs(partials, value, source[4]) : value;
	        data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4];
	      }
	      // Compose partial right arguments.
	      value = source[5];
	      if (value) {
	        partials = data[5];
	        data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
	        data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6];
	      }
	      // Use source `argPos` if available.
	      value = source[7];
	      if (value) {
	        data[7] = value;
	      }
	      // Use source `ary` if it's smaller.
	      if (srcBitmask & ARY_FLAG) {
	        data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]);
	      }
	      // Use source `arity` if one is not provided.
	      if (data[9] == null) {
	        data[9] = source[9];
	      }
	      // Use source `func` and merge bitmasks.
	      data[0] = source[0];
	      data[1] = newBitmask;
	
	      return data;
	    }
	
	    /**
	     * Used by `_.defaultsDeep` to customize its `_.merge` use.
	     *
	     * @private
	     * @param {*} objValue The destination value.
	     * @param {*} srcValue The source value.
	     * @param {string} key The key of the property to merge.
	     * @param {Object} object The parent object of `objValue`.
	     * @param {Object} source The parent object of `srcValue`.
	     * @param {Object} [stack] Tracks traversed source values and their merged
	     *  counterparts.
	     * @returns {*} Returns the value to assign.
	     */
	    function mergeDefaults(objValue, srcValue, key, object, source, stack) {
	      if (isObject(objValue) && isObject(srcValue)) {
	        // Recursively merge objects and arrays (susceptible to call stack limits).
	        stack.set(srcValue, objValue);
	        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack);
	        stack['delete'](srcValue);
	      }
	      return objValue;
	    }
	
	    /**
	     * This function is like
	     * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	     * except that it includes inherited enumerable properties.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     */
	    function nativeKeysIn(object) {
	      var result = [];
	      if (object != null) {
	        for (var key in Object(object)) {
	          result.push(key);
	        }
	      }
	      return result;
	    }
	
	    /**
	     * A specialized version of `baseRest` which transforms the rest array.
	     *
	     * @private
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @param {Function} transform The rest array transform.
	     * @returns {Function} Returns the new function.
	     */
	    function overRest(func, start, transform) {
	      start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
	      return function() {
	        var args = arguments,
	            index = -1,
	            length = nativeMax(args.length - start, 0),
	            array = Array(length);
	
	        while (++index < length) {
	          array[index] = args[start + index];
	        }
	        index = -1;
	        var otherArgs = Array(start + 1);
	        while (++index < start) {
	          otherArgs[index] = args[index];
	        }
	        otherArgs[start] = transform(array);
	        return apply(func, this, otherArgs);
	      };
	    }
	
	    /**
	     * Gets the parent value at `path` of `object`.
	     *
	     * @private
	     * @param {Object} object The object to query.
	     * @param {Array} path The path to get the parent value of.
	     * @returns {*} Returns the parent value.
	     */
	    function parent(object, path) {
	      return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1));
	    }
	
	    /**
	     * Reorder `array` according to the specified indexes where the element at
	     * the first index is assigned as the first element, the element at
	     * the second index is assigned as the second element, and so on.
	     *
	     * @private
	     * @param {Array} array The array to reorder.
	     * @param {Array} indexes The arranged array indexes.
	     * @returns {Array} Returns `array`.
	     */
	    function reorder(array, indexes) {
	      var arrLength = array.length,
	          length = nativeMin(indexes.length, arrLength),
	          oldArray = copyArray(array);
	
	      while (length--) {
	        var index = indexes[length];
	        array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
	      }
	      return array;
	    }
	
	    /**
	     * Sets metadata for `func`.
	     *
	     * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
	     * period of time, it will trip its breaker and transition to an identity
	     * function to avoid garbage collection pauses in V8. See
	     * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
	     * for more details.
	     *
	     * @private
	     * @param {Function} func The function to associate metadata with.
	     * @param {*} data The metadata.
	     * @returns {Function} Returns `func`.
	     */
	    var setData = shortOut(baseSetData);
	
	    /**
	     * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout).
	     *
	     * @private
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @returns {number|Object} Returns the timer id or timeout object.
	     */
	    var setTimeout = ctxSetTimeout || function(func, wait) {
	      return root.setTimeout(func, wait);
	    };
	
	    /**
	     * Sets the `toString` method of `func` to return `string`.
	     *
	     * @private
	     * @param {Function} func The function to modify.
	     * @param {Function} string The `toString` result.
	     * @returns {Function} Returns `func`.
	     */
	    var setToString = shortOut(baseSetToString);
	
	    /**
	     * Sets the `toString` method of `wrapper` to mimic the source of `reference`
	     * with wrapper details in a comment at the top of the source body.
	     *
	     * @private
	     * @param {Function} wrapper The function to modify.
	     * @param {Function} reference The reference function.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @returns {Function} Returns `wrapper`.
	     */
	    function setWrapToString(wrapper, reference, bitmask) {
	      var source = (reference + '');
	      return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
	    }
	
	    /**
	     * Creates a function that'll short out and invoke `identity` instead
	     * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
	     * milliseconds.
	     *
	     * @private
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new shortable function.
	     */
	    function shortOut(func) {
	      var count = 0,
	          lastCalled = 0;
	
	      return function() {
	        var stamp = nativeNow(),
	            remaining = HOT_SPAN - (stamp - lastCalled);
	
	        lastCalled = stamp;
	        if (remaining > 0) {
	          if (++count >= HOT_COUNT) {
	            return arguments[0];
	          }
	        } else {
	          count = 0;
	        }
	        return func.apply(undefined, arguments);
	      };
	    }
	
	    /**
	     * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
	     *
	     * @private
	     * @param {Array} array The array to shuffle.
	     * @param {number} [size=array.length] The size of `array`.
	     * @returns {Array} Returns `array`.
	     */
	    function shuffleSelf(array, size) {
	      var index = -1,
	          length = array.length,
	          lastIndex = length - 1;
	
	      size = size === undefined ? length : size;
	      while (++index < size) {
	        var rand = baseRandom(index, lastIndex),
	            value = array[rand];
	
	        array[rand] = array[index];
	        array[index] = value;
	      }
	      array.length = size;
	      return array;
	    }
	
	    /**
	     * 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) {
	      string = toString(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;
	    });
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Converts `func` to its source code.
	     *
	     * @private
	     * @param {Function} func The function to process.
	     * @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 '';
	    }
	
	    /**
	     * Updates wrapper `details` based on `bitmask` flags.
	     *
	     * @private
	     * @returns {Array} details The details to modify.
	     * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
	     * @returns {Array} Returns `details`.
	     */
	    function updateWrapDetails(details, bitmask) {
	      arrayEach(wrapFlags, function(pair) {
	        var value = '_.' + pair[0];
	        if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
	          details.push(value);
	        }
	      });
	      return details.sort();
	    }
	
	    /**
	     * Creates a clone of `wrapper`.
	     *
	     * @private
	     * @param {Object} wrapper The wrapper to clone.
	     * @returns {Object} Returns the cloned wrapper.
	     */
	    function wrapperClone(wrapper) {
	      if (wrapper instanceof LazyWrapper) {
	        return wrapper.clone();
	      }
	      var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
	      result.__actions__ = copyArray(wrapper.__actions__);
	      result.__index__  = wrapper.__index__;
	      result.__values__ = wrapper.__values__;
	      return result;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an array of elements split into groups the length of `size`.
	     * If `array` can't be split evenly, the final chunk will be the remaining
	     * elements.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to process.
	     * @param {number} [size=1] The length of each chunk
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the new array of chunks.
	     * @example
	     *
	     * _.chunk(['a', 'b', 'c', 'd'], 2);
	     * // => [['a', 'b'], ['c', 'd']]
	     *
	     * _.chunk(['a', 'b', 'c', 'd'], 3);
	     * // => [['a', 'b', 'c'], ['d']]
	     */
	    function chunk(array, size, guard) {
	      if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
	        size = 1;
	      } else {
	        size = nativeMax(toInteger(size), 0);
	      }
	      var length = array ? array.length : 0;
	      if (!length || size < 1) {
	        return [];
	      }
	      var index = 0,
	          resIndex = 0,
	          result = Array(nativeCeil(length / size));
	
	      while (index < length) {
	        result[resIndex++] = baseSlice(array, index, (index += size));
	      }
	      return result;
	    }
	
	    /**
	     * Creates an array with all falsey values removed. The values `false`, `null`,
	     * `0`, `""`, `undefined`, and `NaN` are falsey.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to compact.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.compact([0, 1, false, 2, '', 3]);
	     * // => [1, 2, 3]
	     */
	    function compact(array) {
	      var index = -1,
	          length = array ? array.length : 0,
	          resIndex = 0,
	          result = [];
	
	      while (++index < length) {
	        var value = array[index];
	        if (value) {
	          result[resIndex++] = value;
	        }
	      }
	      return result;
	    }
	
	    /**
	     * Creates a new array concatenating `array` with any additional arrays
	     * and/or values.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to concatenate.
	     * @param {...*} [values] The values to concatenate.
	     * @returns {Array} Returns the new concatenated array.
	     * @example
	     *
	     * var array = [1];
	     * var other = _.concat(array, 2, [3], [[4]]);
	     *
	     * console.log(other);
	     * // => [1, 2, 3, [4]]
	     *
	     * console.log(array);
	     * // => [1]
	     */
	    function concat() {
	      var length = arguments.length;
	      if (!length) {
	        return [];
	      }
	      var args = Array(length - 1),
	          array = arguments[0],
	          index = length;
	
	      while (index--) {
	        args[index - 1] = arguments[index];
	      }
	      return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
	    }
	
	    /**
	     * Creates an array of `array` values not included in the other given arrays
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. The order and references of result values are
	     * determined by the first array.
	     *
	     * **Note:** Unlike `_.pullAll`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.without, _.xor
	     * @example
	     *
	     * _.difference([2, 1], [2, 3]);
	     * // => [1]
	     */
	    var difference = baseRest(function(array, values) {
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
	        : [];
	    });
	
	    /**
	     * This method is like `_.difference` except that it accepts `iteratee` which
	     * is invoked for each element of `array` and `values` to generate the criterion
	     * by which they're compared. The order and references of result values are
	     * determined by the first array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * **Note:** Unlike `_.pullAllBy`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
	     * // => [{ 'x': 2 }]
	     */
	    var differenceBy = baseRest(function(array, values) {
	      var iteratee = last(values);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2))
	        : [];
	    });
	
	    /**
	     * This method is like `_.difference` except that it accepts `comparator`
	     * which is invoked to compare elements of `array` to `values`. The order and
	     * references of result values are determined by the first array. The comparator
	     * is invoked with two arguments: (arrVal, othVal).
	     *
	     * **Note:** Unlike `_.pullAllWith`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...Array} [values] The values to exclude.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     *
	     * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
	     * // => [{ 'x': 2, 'y': 1 }]
	     */
	    var differenceWith = baseRest(function(array, values) {
	      var comparator = last(values);
	      if (isArrayLikeObject(comparator)) {
	        comparator = undefined;
	      }
	      return isArrayLikeObject(array)
	        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
	        : [];
	    });
	
	    /**
	     * Creates a slice of `array` with `n` elements dropped from the beginning.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to drop.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.drop([1, 2, 3]);
	     * // => [2, 3]
	     *
	     * _.drop([1, 2, 3], 2);
	     * // => [3]
	     *
	     * _.drop([1, 2, 3], 5);
	     * // => []
	     *
	     * _.drop([1, 2, 3], 0);
	     * // => [1, 2, 3]
	     */
	    function drop(array, n, guard) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      return baseSlice(array, n < 0 ? 0 : n, length);
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements dropped from the end.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to drop.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.dropRight([1, 2, 3]);
	     * // => [1, 2]
	     *
	     * _.dropRight([1, 2, 3], 2);
	     * // => [1]
	     *
	     * _.dropRight([1, 2, 3], 5);
	     * // => []
	     *
	     * _.dropRight([1, 2, 3], 0);
	     * // => [1, 2, 3]
	     */
	    function dropRight(array, n, guard) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      n = length - n;
	      return baseSlice(array, 0, n < 0 ? 0 : n);
	    }
	
	    /**
	     * Creates a slice of `array` excluding elements dropped from the end.
	     * Elements are dropped until `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.dropRightWhile(users, function(o) { return !o.active; });
	     * // => objects for ['barney']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.dropRightWhile(users, ['active', false]);
	     * // => objects for ['barney']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.dropRightWhile(users, 'active');
	     * // => objects for ['barney', 'fred', 'pebbles']
	     */
	    function dropRightWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), true, true)
	        : [];
	    }
	
	    /**
	     * Creates a slice of `array` excluding elements dropped from the beginning.
	     * Elements are dropped until `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.dropWhile(users, function(o) { return !o.active; });
	     * // => objects for ['pebbles']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.dropWhile(users, { 'user': 'barney', 'active': false });
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.dropWhile(users, ['active', false]);
	     * // => objects for ['pebbles']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.dropWhile(users, 'active');
	     * // => objects for ['barney', 'fred', 'pebbles']
	     */
	    function dropWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), true)
	        : [];
	    }
	
	    /**
	     * Fills elements of `array` with `value` from `start` up to, but not
	     * including, `end`.
	     *
	     * **Note:** This method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Array
	     * @param {Array} array The array to fill.
	     * @param {*} value The value to fill `array` with.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _.fill(array, 'a');
	     * console.log(array);
	     * // => ['a', 'a', 'a']
	     *
	     * _.fill(Array(3), 2);
	     * // => [2, 2, 2]
	     *
	     * _.fill([4, 6, 8, 10], '*', 1, 3);
	     * // => [4, '*', '*', 10]
	     */
	    function fill(array, value, start, end) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
	        start = 0;
	        end = length;
	      }
	      return baseFill(array, value, start, end);
	    }
	
	    /**
	     * This method is like `_.find` except that it returns the index of the first
	     * element `predicate` returns truthy for instead of the element itself.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {number} Returns the index of the found element, else `-1`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.findIndex(users, function(o) { return o.user == 'barney'; });
	     * // => 0
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findIndex(users, { 'user': 'fred', 'active': false });
	     * // => 1
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findIndex(users, ['active', false]);
	     * // => 0
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findIndex(users, 'active');
	     * // => 2
	     */
	    function findIndex(array, predicate, fromIndex) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return -1;
	      }
	      var index = fromIndex == null ? 0 : toInteger(fromIndex);
	      if (index < 0) {
	        index = nativeMax(length + index, 0);
	      }
	      return baseFindIndex(array, getIteratee(predicate, 3), index);
	    }
	
	    /**
	     * This method is like `_.findIndex` except that it iterates over elements
	     * of `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @param {number} [fromIndex=array.length-1] The index to search from.
	     * @returns {number} Returns the index of the found element, else `-1`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
	     * // => 2
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findLastIndex(users, { 'user': 'barney', 'active': true });
	     * // => 0
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findLastIndex(users, ['active', false]);
	     * // => 2
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findLastIndex(users, 'active');
	     * // => 0
	     */
	    function findLastIndex(array, predicate, fromIndex) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return -1;
	      }
	      var index = length - 1;
	      if (fromIndex !== undefined) {
	        index = toInteger(fromIndex);
	        index = fromIndex < 0
	          ? nativeMax(length + index, 0)
	          : nativeMin(index, length - 1);
	      }
	      return baseFindIndex(array, getIteratee(predicate, 3), index, true);
	    }
	
	    /**
	     * Flattens `array` a single level deep.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * _.flatten([1, [2, [3, [4]], 5]]);
	     * // => [1, 2, [3, [4]], 5]
	     */
	    function flatten(array) {
	      var length = array ? array.length : 0;
	      return length ? baseFlatten(array, 1) : [];
	    }
	
	    /**
	     * Recursively flattens `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * _.flattenDeep([1, [2, [3, [4]], 5]]);
	     * // => [1, 2, 3, 4, 5]
	     */
	    function flattenDeep(array) {
	      var length = array ? array.length : 0;
	      return length ? baseFlatten(array, INFINITY) : [];
	    }
	
	    /**
	     * Recursively flatten `array` up to `depth` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.4.0
	     * @category Array
	     * @param {Array} array The array to flatten.
	     * @param {number} [depth=1] The maximum recursion depth.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * var array = [1, [2, [3, [4]], 5]];
	     *
	     * _.flattenDepth(array, 1);
	     * // => [1, 2, [3, [4]], 5]
	     *
	     * _.flattenDepth(array, 2);
	     * // => [1, 2, 3, [4], 5]
	     */
	    function flattenDepth(array, depth) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      depth = depth === undefined ? 1 : toInteger(depth);
	      return baseFlatten(array, depth);
	    }
	
	    /**
	     * The inverse of `_.toPairs`; this method returns an object composed
	     * from key-value `pairs`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} pairs The key-value pairs.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.fromPairs([['a', 1], ['b', 2]]);
	     * // => { 'a': 1, 'b': 2 }
	     */
	    function fromPairs(pairs) {
	      var index = -1,
	          length = pairs ? pairs.length : 0,
	          result = {};
	
	      while (++index < length) {
	        var pair = pairs[index];
	        result[pair[0]] = pair[1];
	      }
	      return result;
	    }
	
	    /**
	     * Gets the first element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @alias first
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {*} Returns the first element of `array`.
	     * @example
	     *
	     * _.head([1, 2, 3]);
	     * // => 1
	     *
	     * _.head([]);
	     * // => undefined
	     */
	    function head(array) {
	      return (array && array.length) ? array[0] : undefined;
	    }
	
	    /**
	     * Gets the index at which the first occurrence of `value` is found in `array`
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. If `fromIndex` is negative, it's used as the
	     * offset from the end of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.indexOf([1, 2, 1, 2], 2);
	     * // => 1
	     *
	     * // Search from the `fromIndex`.
	     * _.indexOf([1, 2, 1, 2], 2, 2);
	     * // => 3
	     */
	    function indexOf(array, value, fromIndex) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return -1;
	      }
	      var index = fromIndex == null ? 0 : toInteger(fromIndex);
	      if (index < 0) {
	        index = nativeMax(length + index, 0);
	      }
	      return baseIndexOf(array, value, index);
	    }
	
	    /**
	     * Gets all but the last element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.initial([1, 2, 3]);
	     * // => [1, 2]
	     */
	    function initial(array) {
	      var length = array ? array.length : 0;
	      return length ? baseSlice(array, 0, -1) : [];
	    }
	
	    /**
	     * Creates an array of unique values that are included in all given arrays
	     * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons. The order and references of result values are
	     * determined by the first array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * _.intersection([2, 1], [2, 3]);
	     * // => [2]
	     */
	    var intersection = baseRest(function(arrays) {
	      var mapped = arrayMap(arrays, castArrayLikeObject);
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped)
	        : [];
	    });
	
	    /**
	     * This method is like `_.intersection` except that it accepts `iteratee`
	     * which is invoked for each element of each `arrays` to generate the criterion
	     * by which they're compared. The order and references of result values are
	     * determined by the first array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [2.1]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }]
	     */
	    var intersectionBy = baseRest(function(arrays) {
	      var iteratee = last(arrays),
	          mapped = arrayMap(arrays, castArrayLikeObject);
	
	      if (iteratee === last(mapped)) {
	        iteratee = undefined;
	      } else {
	        mapped.pop();
	      }
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped, getIteratee(iteratee, 2))
	        : [];
	    });
	
	    /**
	     * This method is like `_.intersection` except that it accepts `comparator`
	     * which is invoked to compare elements of `arrays`. The order and references
	     * of result values are determined by the first array. The comparator is
	     * invoked with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of intersecting values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.intersectionWith(objects, others, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }]
	     */
	    var intersectionWith = baseRest(function(arrays) {
	      var comparator = last(arrays),
	          mapped = arrayMap(arrays, castArrayLikeObject);
	
	      if (comparator === last(mapped)) {
	        comparator = undefined;
	      } else {
	        mapped.pop();
	      }
	      return (mapped.length && mapped[0] === arrays[0])
	        ? baseIntersection(mapped, undefined, comparator)
	        : [];
	    });
	
	    /**
	     * Converts all elements in `array` into a string separated by `separator`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to convert.
	     * @param {string} [separator=','] The element separator.
	     * @returns {string} Returns the joined string.
	     * @example
	     *
	     * _.join(['a', 'b', 'c'], '~');
	     * // => 'a~b~c'
	     */
	    function join(array, separator) {
	      return array ? nativeJoin.call(array, separator) : '';
	    }
	
	    /**
	     * Gets the last element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {*} Returns the last element of `array`.
	     * @example
	     *
	     * _.last([1, 2, 3]);
	     * // => 3
	     */
	    function last(array) {
	      var length = array ? array.length : 0;
	      return length ? array[length - 1] : undefined;
	    }
	
	    /**
	     * This method is like `_.indexOf` except that it iterates over elements of
	     * `array` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=array.length-1] The index to search from.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.lastIndexOf([1, 2, 1, 2], 2);
	     * // => 3
	     *
	     * // Search from the `fromIndex`.
	     * _.lastIndexOf([1, 2, 1, 2], 2, 2);
	     * // => 1
	     */
	    function lastIndexOf(array, value, fromIndex) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return -1;
	      }
	      var index = length;
	      if (fromIndex !== undefined) {
	        index = toInteger(fromIndex);
	        index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
	      }
	      return value === value
	        ? strictLastIndexOf(array, value, index)
	        : baseFindIndex(array, baseIsNaN, index, true);
	    }
	
	    /**
	     * Gets the element at index `n` of `array`. If `n` is negative, the nth
	     * element from the end is returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.11.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=0] The index of the element to return.
	     * @returns {*} Returns the nth element of `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'd'];
	     *
	     * _.nth(array, 1);
	     * // => 'b'
	     *
	     * _.nth(array, -2);
	     * // => 'c';
	     */
	    function nth(array, n) {
	      return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
	    }
	
	    /**
	     * Removes all given values from `array` using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
	     * to remove elements from an array by predicate.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {...*} [values] The values to remove.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
	     *
	     * _.pull(array, 'a', 'c');
	     * console.log(array);
	     * // => ['b', 'b']
	     */
	    var pull = baseRest(pullAll);
	
	    /**
	     * This method is like `_.pull` except that it accepts an array of values to remove.
	     *
	     * **Note:** Unlike `_.difference`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
	     *
	     * _.pullAll(array, ['a', 'c']);
	     * console.log(array);
	     * // => ['b', 'b']
	     */
	    function pullAll(array, values) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values)
	        : array;
	    }
	
	    /**
	     * This method is like `_.pullAll` except that it accepts `iteratee` which is
	     * invoked for each element of `array` and `values` to generate the criterion
	     * by which they're compared. The iteratee is invoked with one argument: (value).
	     *
	     * **Note:** Unlike `_.differenceBy`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
	     *
	     * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
	     * console.log(array);
	     * // => [{ 'x': 2 }]
	     */
	    function pullAllBy(array, values, iteratee) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values, getIteratee(iteratee, 2))
	        : array;
	    }
	
	    /**
	     * This method is like `_.pullAll` except that it accepts `comparator` which
	     * is invoked to compare elements of `array` to `values`. The comparator is
	     * invoked with two arguments: (arrVal, othVal).
	     *
	     * **Note:** Unlike `_.differenceWith`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Array} values The values to remove.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
	     *
	     * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
	     * console.log(array);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
	     */
	    function pullAllWith(array, values, comparator) {
	      return (array && array.length && values && values.length)
	        ? basePullAll(array, values, undefined, comparator)
	        : array;
	    }
	
	    /**
	     * Removes elements from `array` corresponding to `indexes` and returns an
	     * array of removed elements.
	     *
	     * **Note:** Unlike `_.at`, this method mutates `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {...(number|number[])} [indexes] The indexes of elements to remove.
	     * @returns {Array} Returns the new array of removed elements.
	     * @example
	     *
	     * var array = ['a', 'b', 'c', 'd'];
	     * var pulled = _.pullAt(array, [1, 3]);
	     *
	     * console.log(array);
	     * // => ['a', 'c']
	     *
	     * console.log(pulled);
	     * // => ['b', 'd']
	     */
	    var pullAt = flatRest(function(array, indexes) {
	      var length = array ? array.length : 0,
	          result = baseAt(array, indexes);
	
	      basePullAt(array, arrayMap(indexes, function(index) {
	        return isIndex(index, length) ? +index : index;
	      }).sort(compareAscending));
	
	      return result;
	    });
	
	    /**
	     * Removes all elements from `array` that `predicate` returns truthy for
	     * and returns an array of the removed elements. The predicate is invoked
	     * with three arguments: (value, index, array).
	     *
	     * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
	     * to pull elements from an array by value.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the new array of removed elements.
	     * @example
	     *
	     * var array = [1, 2, 3, 4];
	     * var evens = _.remove(array, function(n) {
	     *   return n % 2 == 0;
	     * });
	     *
	     * console.log(array);
	     * // => [1, 3]
	     *
	     * console.log(evens);
	     * // => [2, 4]
	     */
	    function remove(array, predicate) {
	      var result = [];
	      if (!(array && array.length)) {
	        return result;
	      }
	      var index = -1,
	          indexes = [],
	          length = array.length;
	
	      predicate = getIteratee(predicate, 3);
	      while (++index < length) {
	        var value = array[index];
	        if (predicate(value, index, array)) {
	          result.push(value);
	          indexes.push(index);
	        }
	      }
	      basePullAt(array, indexes);
	      return result;
	    }
	
	    /**
	     * Reverses `array` so that the first element becomes the last, the second
	     * element becomes the second to last, and so on.
	     *
	     * **Note:** This method mutates `array` and is based on
	     * [`Array#reverse`](https://mdn.io/Array/reverse).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to modify.
	     * @returns {Array} Returns `array`.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _.reverse(array);
	     * // => [3, 2, 1]
	     *
	     * console.log(array);
	     * // => [3, 2, 1]
	     */
	    function reverse(array) {
	      return array ? nativeReverse.call(array) : array;
	    }
	
	    /**
	     * Creates a slice of `array` from `start` up to, but not including, `end`.
	     *
	     * **Note:** This method is used instead of
	     * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
	     * returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to slice.
	     * @param {number} [start=0] The start position.
	     * @param {number} [end=array.length] The end position.
	     * @returns {Array} Returns the slice of `array`.
	     */
	    function slice(array, start, end) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
	        start = 0;
	        end = length;
	      }
	      else {
	        start = start == null ? 0 : toInteger(start);
	        end = end === undefined ? length : toInteger(end);
	      }
	      return baseSlice(array, start, end);
	    }
	
	    /**
	     * Uses a binary search to determine the lowest index at which `value`
	     * should be inserted into `array` in order to maintain its sort order.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * _.sortedIndex([30, 50], 40);
	     * // => 1
	     */
	    function sortedIndex(array, value) {
	      return baseSortedIndex(array, value);
	    }
	
	    /**
	     * This method is like `_.sortedIndex` except that it accepts `iteratee`
	     * which is invoked for `value` and each element of `array` to compute their
	     * sort ranking. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * var objects = [{ 'x': 4 }, { 'x': 5 }];
	     *
	     * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
	     * // => 0
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sortedIndexBy(objects, { 'x': 4 }, 'x');
	     * // => 0
	     */
	    function sortedIndexBy(array, value, iteratee) {
	      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2));
	    }
	
	    /**
	     * This method is like `_.indexOf` except that it performs a binary
	     * search on a sorted `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.sortedIndexOf([4, 5, 5, 5, 6], 5);
	     * // => 1
	     */
	    function sortedIndexOf(array, value) {
	      var length = array ? array.length : 0;
	      if (length) {
	        var index = baseSortedIndex(array, value);
	        if (index < length && eq(array[index], value)) {
	          return index;
	        }
	      }
	      return -1;
	    }
	
	    /**
	     * This method is like `_.sortedIndex` except that it returns the highest
	     * index at which `value` should be inserted into `array` in order to
	     * maintain its sort order.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * _.sortedLastIndex([4, 5, 5, 5, 6], 5);
	     * // => 4
	     */
	    function sortedLastIndex(array, value) {
	      return baseSortedIndex(array, value, true);
	    }
	
	    /**
	     * This method is like `_.sortedLastIndex` except that it accepts `iteratee`
	     * which is invoked for `value` and each element of `array` to compute their
	     * sort ranking. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The sorted array to inspect.
	     * @param {*} value The value to evaluate.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {number} Returns the index at which `value` should be inserted
	     *  into `array`.
	     * @example
	     *
	     * var objects = [{ 'x': 4 }, { 'x': 5 }];
	     *
	     * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; });
	     * // => 1
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x');
	     * // => 1
	     */
	    function sortedLastIndexBy(array, value, iteratee) {
	      return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true);
	    }
	
	    /**
	     * This method is like `_.lastIndexOf` except that it performs a binary
	     * search on a sorted `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {*} value The value to search for.
	     * @returns {number} Returns the index of the matched value, else `-1`.
	     * @example
	     *
	     * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5);
	     * // => 3
	     */
	    function sortedLastIndexOf(array, value) {
	      var length = array ? array.length : 0;
	      if (length) {
	        var index = baseSortedIndex(array, value, true) - 1;
	        if (eq(array[index], value)) {
	          return index;
	        }
	      }
	      return -1;
	    }
	
	    /**
	     * This method is like `_.uniq` except that it's designed and optimized
	     * for sorted arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.sortedUniq([1, 1, 2]);
	     * // => [1, 2]
	     */
	    function sortedUniq(array) {
	      return (array && array.length)
	        ? baseSortedUniq(array)
	        : [];
	    }
	
	    /**
	     * This method is like `_.uniqBy` except that it's designed and optimized
	     * for sorted arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee] The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
	     * // => [1.1, 2.3]
	     */
	    function sortedUniqBy(array, iteratee) {
	      return (array && array.length)
	        ? baseSortedUniq(array, getIteratee(iteratee, 2))
	        : [];
	    }
	
	    /**
	     * Gets all but the first element of `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.tail([1, 2, 3]);
	     * // => [2, 3]
	     */
	    function tail(array) {
	      var length = array ? array.length : 0;
	      return length ? baseSlice(array, 1, length) : [];
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements taken from the beginning.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to take.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.take([1, 2, 3]);
	     * // => [1]
	     *
	     * _.take([1, 2, 3], 2);
	     * // => [1, 2]
	     *
	     * _.take([1, 2, 3], 5);
	     * // => [1, 2, 3]
	     *
	     * _.take([1, 2, 3], 0);
	     * // => []
	     */
	    function take(array, n, guard) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      return baseSlice(array, 0, n < 0 ? 0 : n);
	    }
	
	    /**
	     * Creates a slice of `array` with `n` elements taken from the end.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {number} [n=1] The number of elements to take.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * _.takeRight([1, 2, 3]);
	     * // => [3]
	     *
	     * _.takeRight([1, 2, 3], 2);
	     * // => [2, 3]
	     *
	     * _.takeRight([1, 2, 3], 5);
	     * // => [1, 2, 3]
	     *
	     * _.takeRight([1, 2, 3], 0);
	     * // => []
	     */
	    function takeRight(array, n, guard) {
	      var length = array ? array.length : 0;
	      if (!length) {
	        return [];
	      }
	      n = (guard || n === undefined) ? 1 : toInteger(n);
	      n = length - n;
	      return baseSlice(array, n < 0 ? 0 : n, length);
	    }
	
	    /**
	     * Creates a slice of `array` with elements taken from the end. Elements are
	     * taken until `predicate` returns falsey. The predicate is invoked with
	     * three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': true },
	     *   { 'user': 'fred',    'active': false },
	     *   { 'user': 'pebbles', 'active': false }
	     * ];
	     *
	     * _.takeRightWhile(users, function(o) { return !o.active; });
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false });
	     * // => objects for ['pebbles']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.takeRightWhile(users, ['active', false]);
	     * // => objects for ['fred', 'pebbles']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.takeRightWhile(users, 'active');
	     * // => []
	     */
	    function takeRightWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3), false, true)
	        : [];
	    }
	
	    /**
	     * Creates a slice of `array` with elements taken from the beginning. Elements
	     * are taken until `predicate` returns falsey. The predicate is invoked with
	     * three arguments: (value, index, array).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Array
	     * @param {Array} array The array to query.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the slice of `array`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'active': false },
	     *   { 'user': 'fred',    'active': false},
	     *   { 'user': 'pebbles', 'active': true }
	     * ];
	     *
	     * _.takeWhile(users, function(o) { return !o.active; });
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.takeWhile(users, { 'user': 'barney', 'active': false });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.takeWhile(users, ['active', false]);
	     * // => objects for ['barney', 'fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.takeWhile(users, 'active');
	     * // => []
	     */
	    function takeWhile(array, predicate) {
	      return (array && array.length)
	        ? baseWhile(array, getIteratee(predicate, 3))
	        : [];
	    }
	
	    /**
	     * Creates an array of unique values, in order, from all given arrays using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * _.union([2], [1, 2]);
	     * // => [2, 1]
	     */
	    var union = baseRest(function(arrays) {
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
	    });
	
	    /**
	     * This method is like `_.union` except that it accepts `iteratee` which is
	     * invoked for each element of each `arrays` to generate the criterion by
	     * which uniqueness is computed. Result values are chosen from the first
	     * array in which the value occurs. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * _.unionBy([2.1], [1.2, 2.3], Math.floor);
	     * // => [2.1, 1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }, { 'x': 2 }]
	     */
	    var unionBy = baseRest(function(arrays) {
	      var iteratee = last(arrays);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2));
	    });
	
	    /**
	     * This method is like `_.union` except that it accepts `comparator` which
	     * is invoked to compare elements of `arrays`. Result values are chosen from
	     * the first array in which the value occurs. The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of combined values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.unionWith(objects, others, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
	     */
	    var unionWith = baseRest(function(arrays) {
	      var comparator = last(arrays);
	      if (isArrayLikeObject(comparator)) {
	        comparator = undefined;
	      }
	      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator);
	    });
	
	    /**
	     * Creates a duplicate-free version of an array, using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons, in which only the first occurrence of each element
	     * is kept. The order of result values is determined by the order they occur
	     * in the array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.uniq([2, 1, 2]);
	     * // => [2, 1]
	     */
	    function uniq(array) {
	      return (array && array.length)
	        ? baseUniq(array)
	        : [];
	    }
	
	    /**
	     * This method is like `_.uniq` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * uniqueness is computed. The order of result values is determined by the
	     * order they occur in the array. The iteratee is invoked with one argument:
	     * (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
	     * // => [2.1, 1.2]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 1 }, { 'x': 2 }]
	     */
	    function uniqBy(array, iteratee) {
	      return (array && array.length)
	        ? baseUniq(array, getIteratee(iteratee, 2))
	        : [];
	    }
	
	    /**
	     * This method is like `_.uniq` except that it accepts `comparator` which
	     * is invoked to compare elements of `array`. The order of result values is
	     * determined by the order they occur in the array.The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new duplicate free array.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.uniqWith(objects, _.isEqual);
	     * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
	     */
	    function uniqWith(array, comparator) {
	      return (array && array.length)
	        ? baseUniq(array, undefined, comparator)
	        : [];
	    }
	
	    /**
	     * This method is like `_.zip` except that it accepts an array of grouped
	     * elements and creates an array regrouping the elements to their pre-zip
	     * configuration.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.2.0
	     * @category Array
	     * @param {Array} array The array of grouped elements to process.
	     * @returns {Array} Returns the new array of regrouped elements.
	     * @example
	     *
	     * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]);
	     * // => [['a', 1, true], ['b', 2, false]]
	     *
	     * _.unzip(zipped);
	     * // => [['a', 'b'], [1, 2], [true, false]]
	     */
	    function unzip(array) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      var length = 0;
	      array = arrayFilter(array, function(group) {
	        if (isArrayLikeObject(group)) {
	          length = nativeMax(group.length, length);
	          return true;
	        }
	      });
	      return baseTimes(length, function(index) {
	        return arrayMap(array, baseProperty(index));
	      });
	    }
	
	    /**
	     * This method is like `_.unzip` except that it accepts `iteratee` to specify
	     * how regrouped values should be combined. The iteratee is invoked with the
	     * elements of each group: (...group).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Array
	     * @param {Array} array The array of grouped elements to process.
	     * @param {Function} [iteratee=_.identity] The function to combine
	     *  regrouped values.
	     * @returns {Array} Returns the new array of regrouped elements.
	     * @example
	     *
	     * var zipped = _.zip([1, 2], [10, 20], [100, 200]);
	     * // => [[1, 10, 100], [2, 20, 200]]
	     *
	     * _.unzipWith(zipped, _.add);
	     * // => [3, 30, 300]
	     */
	    function unzipWith(array, iteratee) {
	      if (!(array && array.length)) {
	        return [];
	      }
	      var result = unzip(array);
	      if (iteratee == null) {
	        return result;
	      }
	      return arrayMap(result, function(group) {
	        return apply(iteratee, undefined, group);
	      });
	    }
	
	    /**
	     * Creates an array excluding all given values using
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * for equality comparisons.
	     *
	     * **Note:** Unlike `_.pull`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {Array} array The array to inspect.
	     * @param {...*} [values] The values to exclude.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.difference, _.xor
	     * @example
	     *
	     * _.without([2, 1, 2, 3], 1, 2);
	     * // => [3]
	     */
	    var without = baseRest(function(array, values) {
	      return isArrayLikeObject(array)
	        ? baseDifference(array, values)
	        : [];
	    });
	
	    /**
	     * Creates an array of unique values that is the
	     * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference)
	     * of the given arrays. The order of result values is determined by the order
	     * they occur in the arrays.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @returns {Array} Returns the new array of filtered values.
	     * @see _.difference, _.without
	     * @example
	     *
	     * _.xor([2, 1], [2, 3]);
	     * // => [1, 3]
	     */
	    var xor = baseRest(function(arrays) {
	      return baseXor(arrayFilter(arrays, isArrayLikeObject));
	    });
	
	    /**
	     * This method is like `_.xor` except that it accepts `iteratee` which is
	     * invoked for each element of each `arrays` to generate the criterion by
	     * which by which they're compared. The order of result values is determined
	     * by the order they occur in the arrays. The iteratee is invoked with one
	     * argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor);
	     * // => [1.2, 3.4]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
	     * // => [{ 'x': 2 }]
	     */
	    var xorBy = baseRest(function(arrays) {
	      var iteratee = last(arrays);
	      if (isArrayLikeObject(iteratee)) {
	        iteratee = undefined;
	      }
	      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2));
	    });
	
	    /**
	     * This method is like `_.xor` except that it accepts `comparator` which is
	     * invoked to compare elements of `arrays`. The order of result values is
	     * determined by the order they occur in the arrays. The comparator is invoked
	     * with two arguments: (arrVal, othVal).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to inspect.
	     * @param {Function} [comparator] The comparator invoked per element.
	     * @returns {Array} Returns the new array of filtered values.
	     * @example
	     *
	     * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
	     * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
	     *
	     * _.xorWith(objects, others, _.isEqual);
	     * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
	     */
	    var xorWith = baseRest(function(arrays) {
	      var comparator = last(arrays);
	      if (isArrayLikeObject(comparator)) {
	        comparator = undefined;
	      }
	      return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator);
	    });
	
	    /**
	     * Creates an array of grouped elements, the first of which contains the
	     * first elements of the given arrays, the second of which contains the
	     * second elements of the given arrays, and so on.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to process.
	     * @returns {Array} Returns the new array of grouped elements.
	     * @example
	     *
	     * _.zip(['a', 'b'], [1, 2], [true, false]);
	     * // => [['a', 1, true], ['b', 2, false]]
	     */
	    var zip = baseRest(unzip);
	
	    /**
	     * This method is like `_.fromPairs` except that it accepts two arrays,
	     * one of property identifiers and one of corresponding values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.4.0
	     * @category Array
	     * @param {Array} [props=[]] The property identifiers.
	     * @param {Array} [values=[]] The property values.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.zipObject(['a', 'b'], [1, 2]);
	     * // => { 'a': 1, 'b': 2 }
	     */
	    function zipObject(props, values) {
	      return baseZipObject(props || [], values || [], assignValue);
	    }
	
	    /**
	     * This method is like `_.zipObject` except that it supports property paths.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.1.0
	     * @category Array
	     * @param {Array} [props=[]] The property identifiers.
	     * @param {Array} [values=[]] The property values.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
	     * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
	     */
	    function zipObjectDeep(props, values) {
	      return baseZipObject(props || [], values || [], baseSet);
	    }
	
	    /**
	     * This method is like `_.zip` except that it accepts `iteratee` to specify
	     * how grouped values should be combined. The iteratee is invoked with the
	     * elements of each group: (...group).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Array
	     * @param {...Array} [arrays] The arrays to process.
	     * @param {Function} [iteratee=_.identity] The function to combine grouped values.
	     * @returns {Array} Returns the new array of grouped elements.
	     * @example
	     *
	     * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
	     *   return a + b + c;
	     * });
	     * // => [111, 222]
	     */
	    var zipWith = baseRest(function(arrays) {
	      var length = arrays.length,
	          iteratee = length > 1 ? arrays[length - 1] : undefined;
	
	      iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined;
	      return unzipWith(arrays, iteratee);
	    });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates a `lodash` wrapper instance that wraps `value` with explicit method
	     * chain sequences enabled. The result of such sequences must be unwrapped
	     * with `_#value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.3.0
	     * @category Seq
	     * @param {*} value The value to wrap.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36 },
	     *   { 'user': 'fred',    'age': 40 },
	     *   { 'user': 'pebbles', 'age': 1 }
	     * ];
	     *
	     * var youngest = _
	     *   .chain(users)
	     *   .sortBy('age')
	     *   .map(function(o) {
	     *     return o.user + ' is ' + o.age;
	     *   })
	     *   .head()
	     *   .value();
	     * // => 'pebbles is 1'
	     */
	    function chain(value) {
	      var result = lodash(value);
	      result.__chain__ = true;
	      return result;
	    }
	
	    /**
	     * This method invokes `interceptor` and returns `value`. The interceptor
	     * is invoked with one argument; (value). The purpose of this method is to
	     * "tap into" a method chain sequence in order to modify intermediate results.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @param {*} value The value to provide to `interceptor`.
	     * @param {Function} interceptor The function to invoke.
	     * @returns {*} Returns `value`.
	     * @example
	     *
	     * _([1, 2, 3])
	     *  .tap(function(array) {
	     *    // Mutate input array.
	     *    array.pop();
	     *  })
	     *  .reverse()
	     *  .value();
	     * // => [2, 1]
	     */
	    function tap(value, interceptor) {
	      interceptor(value);
	      return value;
	    }
	
	    /**
	     * This method is like `_.tap` except that it returns the result of `interceptor`.
	     * The purpose of this method is to "pass thru" values replacing intermediate
	     * results in a method chain sequence.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Seq
	     * @param {*} value The value to provide to `interceptor`.
	     * @param {Function} interceptor The function to invoke.
	     * @returns {*} Returns the result of `interceptor`.
	     * @example
	     *
	     * _('  abc  ')
	     *  .chain()
	     *  .trim()
	     *  .thru(function(value) {
	     *    return [value];
	     *  })
	     *  .value();
	     * // => ['abc']
	     */
	    function thru(value, interceptor) {
	      return interceptor(value);
	    }
	
	    /**
	     * This method is the wrapper version of `_.at`.
	     *
	     * @name at
	     * @memberOf _
	     * @since 1.0.0
	     * @category Seq
	     * @param {...(string|string[])} [paths] The property paths of elements to pick.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
	     *
	     * _(object).at(['a[0].b.c', 'a[1]']).value();
	     * // => [3, 4]
	     */
	    var wrapperAt = flatRest(function(paths) {
	      var length = paths.length,
	          start = length ? paths[0] : 0,
	          value = this.__wrapped__,
	          interceptor = function(object) { return baseAt(object, paths); };
	
	      if (length > 1 || this.__actions__.length ||
	          !(value instanceof LazyWrapper) || !isIndex(start)) {
	        return this.thru(interceptor);
	      }
	      value = value.slice(start, +start + (length ? 1 : 0));
	      value.__actions__.push({
	        'func': thru,
	        'args': [interceptor],
	        'thisArg': undefined
	      });
	      return new LodashWrapper(value, this.__chain__).thru(function(array) {
	        if (length && !array.length) {
	          array.push(undefined);
	        }
	        return array;
	      });
	    });
	
	    /**
	     * Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
	     *
	     * @name chain
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36 },
	     *   { 'user': 'fred',   'age': 40 }
	     * ];
	     *
	     * // A sequence without explicit chaining.
	     * _(users).head();
	     * // => { 'user': 'barney', 'age': 36 }
	     *
	     * // A sequence with explicit chaining.
	     * _(users)
	     *   .chain()
	     *   .head()
	     *   .pick('user')
	     *   .value();
	     * // => { 'user': 'barney' }
	     */
	    function wrapperChain() {
	      return chain(this);
	    }
	
	    /**
	     * Executes the chain sequence and returns the wrapped result.
	     *
	     * @name commit
	     * @memberOf _
	     * @since 3.2.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var array = [1, 2];
	     * var wrapped = _(array).push(3);
	     *
	     * console.log(array);
	     * // => [1, 2]
	     *
	     * wrapped = wrapped.commit();
	     * console.log(array);
	     * // => [1, 2, 3]
	     *
	     * wrapped.last();
	     * // => 3
	     *
	     * console.log(array);
	     * // => [1, 2, 3]
	     */
	    function wrapperCommit() {
	      return new LodashWrapper(this.value(), this.__chain__);
	    }
	
	    /**
	     * Gets the next value on a wrapped object following the
	     * [iterator protocol](https://mdn.io/iteration_protocols#iterator).
	     *
	     * @name next
	     * @memberOf _
	     * @since 4.0.0
	     * @category Seq
	     * @returns {Object} Returns the next iterator value.
	     * @example
	     *
	     * var wrapped = _([1, 2]);
	     *
	     * wrapped.next();
	     * // => { 'done': false, 'value': 1 }
	     *
	     * wrapped.next();
	     * // => { 'done': false, 'value': 2 }
	     *
	     * wrapped.next();
	     * // => { 'done': true, 'value': undefined }
	     */
	    function wrapperNext() {
	      if (this.__values__ === undefined) {
	        this.__values__ = toArray(this.value());
	      }
	      var done = this.__index__ >= this.__values__.length,
	          value = done ? undefined : this.__values__[this.__index__++];
	
	      return { 'done': done, 'value': value };
	    }
	
	    /**
	     * Enables the wrapper to be iterable.
	     *
	     * @name Symbol.iterator
	     * @memberOf _
	     * @since 4.0.0
	     * @category Seq
	     * @returns {Object} Returns the wrapper object.
	     * @example
	     *
	     * var wrapped = _([1, 2]);
	     *
	     * wrapped[Symbol.iterator]() === wrapped;
	     * // => true
	     *
	     * Array.from(wrapped);
	     * // => [1, 2]
	     */
	    function wrapperToIterator() {
	      return this;
	    }
	
	    /**
	     * Creates a clone of the chain sequence planting `value` as the wrapped value.
	     *
	     * @name plant
	     * @memberOf _
	     * @since 3.2.0
	     * @category Seq
	     * @param {*} value The value to plant.
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var wrapped = _([1, 2]).map(square);
	     * var other = wrapped.plant([3, 4]);
	     *
	     * other.value();
	     * // => [9, 16]
	     *
	     * wrapped.value();
	     * // => [1, 4]
	     */
	    function wrapperPlant(value) {
	      var result,
	          parent = this;
	
	      while (parent instanceof baseLodash) {
	        var clone = wrapperClone(parent);
	        clone.__index__ = 0;
	        clone.__values__ = undefined;
	        if (result) {
	          previous.__wrapped__ = clone;
	        } else {
	          result = clone;
	        }
	        var previous = clone;
	        parent = parent.__wrapped__;
	      }
	      previous.__wrapped__ = value;
	      return result;
	    }
	
	    /**
	     * This method is the wrapper version of `_.reverse`.
	     *
	     * **Note:** This method mutates the wrapped array.
	     *
	     * @name reverse
	     * @memberOf _
	     * @since 0.1.0
	     * @category Seq
	     * @returns {Object} Returns the new `lodash` wrapper instance.
	     * @example
	     *
	     * var array = [1, 2, 3];
	     *
	     * _(array).reverse().value()
	     * // => [3, 2, 1]
	     *
	     * console.log(array);
	     * // => [3, 2, 1]
	     */
	    function wrapperReverse() {
	      var value = this.__wrapped__;
	      if (value instanceof LazyWrapper) {
	        var wrapped = value;
	        if (this.__actions__.length) {
	          wrapped = new LazyWrapper(this);
	        }
	        wrapped = wrapped.reverse();
	        wrapped.__actions__.push({
	          'func': thru,
	          'args': [reverse],
	          'thisArg': undefined
	        });
	        return new LodashWrapper(wrapped, this.__chain__);
	      }
	      return this.thru(reverse);
	    }
	
	    /**
	     * Executes the chain sequence to resolve the unwrapped value.
	     *
	     * @name value
	     * @memberOf _
	     * @since 0.1.0
	     * @alias toJSON, valueOf
	     * @category Seq
	     * @returns {*} Returns the resolved unwrapped value.
	     * @example
	     *
	     * _([1, 2, 3]).value();
	     * // => [1, 2, 3]
	     */
	    function wrapperValue() {
	      return baseWrapperValue(this.__wrapped__, this.__actions__);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The corresponding value of
	     * each key is the number of times the key was returned by `iteratee`. The
	     * iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * _.countBy([6.1, 4.2, 6.3], Math.floor);
	     * // => { '4': 1, '6': 2 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.countBy(['one', 'two', 'three'], 'length');
	     * // => { '3': 2, '5': 1 }
	     */
	    var countBy = createAggregator(function(result, value, key) {
	      if (hasOwnProperty.call(result, key)) {
	        ++result[key];
	      } else {
	        baseAssignValue(result, key, 1);
	      }
	    });
	
	    /**
	     * Checks if `predicate` returns truthy for **all** elements of `collection`.
	     * Iteration is stopped once `predicate` returns falsey. The predicate is
	     * invoked with three arguments: (value, index|key, collection).
	     *
	     * **Note:** This method returns `true` for
	     * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
	     * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
	     * elements of empty collections.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {boolean} Returns `true` if all elements pass the predicate check,
	     *  else `false`.
	     * @example
	     *
	     * _.every([true, 1, null, 'yes'], Boolean);
	     * // => false
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': false },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.every(users, { 'user': 'barney', 'active': false });
	     * // => false
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.every(users, ['active', false]);
	     * // => true
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.every(users, 'active');
	     * // => false
	     */
	    function every(collection, predicate, guard) {
	      var func = isArray(collection) ? arrayEvery : baseEvery;
	      if (guard && isIterateeCall(collection, predicate, guard)) {
	        predicate = undefined;
	      }
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Iterates over elements of `collection`, returning an array of all elements
	     * `predicate` returns truthy for. The predicate is invoked with three
	     * arguments: (value, index|key, collection).
	     *
	     * **Note:** Unlike `_.remove`, this method returns a new array.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     * @see _.reject
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': true },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * _.filter(users, function(o) { return !o.active; });
	     * // => objects for ['fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.filter(users, { 'age': 36, 'active': true });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.filter(users, ['active', false]);
	     * // => objects for ['fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.filter(users, 'active');
	     * // => objects for ['barney']
	     */
	    function filter(collection, predicate) {
	      var func = isArray(collection) ? arrayFilter : baseFilter;
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Iterates over elements of `collection`, returning the first element
	     * `predicate` returns truthy for. The predicate is invoked with three
	     * arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to inspect.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @returns {*} Returns the matched element, else `undefined`.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36, 'active': true },
	     *   { 'user': 'fred',    'age': 40, 'active': false },
	     *   { 'user': 'pebbles', 'age': 1,  'active': true }
	     * ];
	     *
	     * _.find(users, function(o) { return o.age < 40; });
	     * // => object for 'barney'
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.find(users, { 'age': 1, 'active': true });
	     * // => object for 'pebbles'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.find(users, ['active', false]);
	     * // => object for 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.find(users, 'active');
	     * // => object for 'barney'
	     */
	    var find = createFind(findIndex);
	
	    /**
	     * This method is like `_.find` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to inspect.
	     * @param {Function} [predicate=_.identity]
	     *  The function invoked per iteration.
	     * @param {number} [fromIndex=collection.length-1] The index to search from.
	     * @returns {*} Returns the matched element, else `undefined`.
	     * @example
	     *
	     * _.findLast([1, 2, 3, 4], function(n) {
	     *   return n % 2 == 1;
	     * });
	     * // => 3
	     */
	    var findLast = createFind(findLastIndex);
	
	    /**
	     * Creates a flattened array of values by running each element in `collection`
	     * thru `iteratee` and flattening the mapped results. The iteratee is invoked
	     * with three arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [n, n];
	     * }
	     *
	     * _.flatMap([1, 2], duplicate);
	     * // => [1, 1, 2, 2]
	     */
	    function flatMap(collection, iteratee) {
	      return baseFlatten(map(collection, iteratee), 1);
	    }
	
	    /**
	     * This method is like `_.flatMap` except that it recursively flattens the
	     * mapped results.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The function invoked per iteration.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [[[n, n]]];
	     * }
	     *
	     * _.flatMapDeep([1, 2], duplicate);
	     * // => [1, 1, 2, 2]
	     */
	    function flatMapDeep(collection, iteratee) {
	      return baseFlatten(map(collection, iteratee), INFINITY);
	    }
	
	    /**
	     * This method is like `_.flatMap` except that it recursively flattens the
	     * mapped results up to `depth` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The function invoked per iteration.
	     * @param {number} [depth=1] The maximum recursion depth.
	     * @returns {Array} Returns the new flattened array.
	     * @example
	     *
	     * function duplicate(n) {
	     *   return [[[n, n]]];
	     * }
	     *
	     * _.flatMapDepth([1, 2], duplicate, 2);
	     * // => [[1, 1], [2, 2]]
	     */
	    function flatMapDepth(collection, iteratee, depth) {
	      depth = depth === undefined ? 1 : toInteger(depth);
	      return baseFlatten(map(collection, iteratee), depth);
	    }
	
	    /**
	     * Iterates over elements of `collection` and invokes `iteratee` for each element.
	     * The iteratee is invoked with three arguments: (value, index|key, collection).
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * **Note:** As with other "Collections" methods, objects with a "length"
	     * property are iterated like arrays. To avoid this behavior use `_.forIn`
	     * or `_.forOwn` for object iteration.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @alias each
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     * @see _.forEachRight
	     * @example
	     *
	     * _.forEach([1, 2], function(value) {
	     *   console.log(value);
	     * });
	     * // => Logs `1` then `2`.
	     *
	     * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
	     */
	    function forEach(collection, iteratee) {
	      var func = isArray(collection) ? arrayEach : baseEach;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.forEach` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @alias eachRight
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array|Object} Returns `collection`.
	     * @see _.forEach
	     * @example
	     *
	     * _.forEachRight([1, 2], function(value) {
	     *   console.log(value);
	     * });
	     * // => Logs `2` then `1`.
	     */
	    function forEachRight(collection, iteratee) {
	      var func = isArray(collection) ? arrayEachRight : baseEachRight;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The order of grouped values
	     * is determined by the order they occur in `collection`. The corresponding
	     * value of each key is an array of elements responsible for generating the
	     * key. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * _.groupBy([6.1, 4.2, 6.3], Math.floor);
	     * // => { '4': [4.2], '6': [6.1, 6.3] }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.groupBy(['one', 'two', 'three'], 'length');
	     * // => { '3': ['one', 'two'], '5': ['three'] }
	     */
	    var groupBy = createAggregator(function(result, value, key) {
	      if (hasOwnProperty.call(result, key)) {
	        result[key].push(value);
	      } else {
	        baseAssignValue(result, key, [value]);
	      }
	    });
	
	    /**
	     * Checks if `value` is in `collection`. If `collection` is a string, it's
	     * checked for a substring of `value`, otherwise
	     * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
	     * is used for equality comparisons. If `fromIndex` is negative, it's used as
	     * the offset from the end of `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object|string} collection The collection to inspect.
	     * @param {*} value The value to search for.
	     * @param {number} [fromIndex=0] The index to search from.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
	     * @returns {boolean} Returns `true` if `value` is found, else `false`.
	     * @example
	     *
	     * _.includes([1, 2, 3], 1);
	     * // => true
	     *
	     * _.includes([1, 2, 3], 1, 2);
	     * // => false
	     *
	     * _.includes({ 'a': 1, 'b': 2 }, 1);
	     * // => true
	     *
	     * _.includes('abcd', 'bc');
	     * // => true
	     */
	    function includes(collection, value, fromIndex, guard) {
	      collection = isArrayLike(collection) ? collection : values(collection);
	      fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
	
	      var length = collection.length;
	      if (fromIndex < 0) {
	        fromIndex = nativeMax(length + fromIndex, 0);
	      }
	      return isString(collection)
	        ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
	        : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
	    }
	
	    /**
	     * Invokes the method at `path` of each element in `collection`, returning
	     * an array of the results of each invoked method. Any additional arguments
	     * are provided to each invoked method. If `path` is a function, it's invoked
	     * for, and `this` bound to, each element in `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Array|Function|string} path The path of the method to invoke or
	     *  the function invoked per iteration.
	     * @param {...*} [args] The arguments to invoke each method with.
	     * @returns {Array} Returns the array of results.
	     * @example
	     *
	     * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
	     * // => [[1, 5, 7], [1, 2, 3]]
	     *
	     * _.invokeMap([123, 456], String.prototype.split, '');
	     * // => [['1', '2', '3'], ['4', '5', '6']]
	     */
	    var invokeMap = baseRest(function(collection, path, args) {
	      var index = -1,
	          isFunc = typeof path == 'function',
	          isProp = isKey(path),
	          result = isArrayLike(collection) ? Array(collection.length) : [];
	
	      baseEach(collection, function(value) {
	        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
	        result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args);
	      });
	      return result;
	    });
	
	    /**
	     * Creates an object composed of keys generated from the results of running
	     * each element of `collection` thru `iteratee`. The corresponding value of
	     * each key is the last element responsible for generating the key. The
	     * iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity]
	     *  The iteratee to transform keys.
	     * @returns {Object} Returns the composed aggregate object.
	     * @example
	     *
	     * var array = [
	     *   { 'dir': 'left', 'code': 97 },
	     *   { 'dir': 'right', 'code': 100 }
	     * ];
	     *
	     * _.keyBy(array, function(o) {
	     *   return String.fromCharCode(o.code);
	     * });
	     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
	     *
	     * _.keyBy(array, 'dir');
	     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
	     */
	    var keyBy = createAggregator(function(result, value, key) {
	      baseAssignValue(result, key, value);
	    });
	
	    /**
	     * Creates an array of values by running each element in `collection` thru
	     * `iteratee`. The iteratee is invoked with three arguments:
	     * (value, index|key, collection).
	     *
	     * Many lodash methods are guarded to work as iteratees for methods like
	     * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
	     *
	     * The guarded methods are:
	     * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
	     * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
	     * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
	     * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new mapped array.
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * _.map([4, 8], square);
	     * // => [16, 64]
	     *
	     * _.map({ 'a': 4, 'b': 8 }, square);
	     * // => [16, 64] (iteration order is not guaranteed)
	     *
	     * var users = [
	     *   { 'user': 'barney' },
	     *   { 'user': 'fred' }
	     * ];
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.map(users, 'user');
	     * // => ['barney', 'fred']
	     */
	    function map(collection, iteratee) {
	      var func = isArray(collection) ? arrayMap : baseMap;
	      return func(collection, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.sortBy` except that it allows specifying the sort
	     * orders of the iteratees to sort by. If `orders` is unspecified, all values
	     * are sorted in ascending order. Otherwise, specify an order of "desc" for
	     * descending or "asc" for ascending sort order of corresponding values.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
	     *  The iteratees to sort by.
	     * @param {string[]} [orders] The sort orders of `iteratees`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
	     * @returns {Array} Returns the new sorted array.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'fred',   'age': 48 },
	     *   { 'user': 'barney', 'age': 34 },
	     *   { 'user': 'fred',   'age': 40 },
	     *   { 'user': 'barney', 'age': 36 }
	     * ];
	     *
	     * // Sort by `user` in ascending order and by `age` in descending order.
	     * _.orderBy(users, ['user', 'age'], ['asc', 'desc']);
	     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
	     */
	    function orderBy(collection, iteratees, orders, guard) {
	      if (collection == null) {
	        return [];
	      }
	      if (!isArray(iteratees)) {
	        iteratees = iteratees == null ? [] : [iteratees];
	      }
	      orders = guard ? undefined : orders;
	      if (!isArray(orders)) {
	        orders = orders == null ? [] : [orders];
	      }
	      return baseOrderBy(collection, iteratees, orders);
	    }
	
	    /**
	     * Creates an array of elements split into two groups, the first of which
	     * contains elements `predicate` returns truthy for, the second of which
	     * contains elements `predicate` returns falsey for. The predicate is
	     * invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the array of grouped elements.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney',  'age': 36, 'active': false },
	     *   { 'user': 'fred',    'age': 40, 'active': true },
	     *   { 'user': 'pebbles', 'age': 1,  'active': false }
	     * ];
	     *
	     * _.partition(users, function(o) { return o.active; });
	     * // => objects for [['fred'], ['barney', 'pebbles']]
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.partition(users, { 'age': 1, 'active': false });
	     * // => objects for [['pebbles'], ['barney', 'fred']]
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.partition(users, ['active', false]);
	     * // => objects for [['barney', 'pebbles'], ['fred']]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.partition(users, 'active');
	     * // => objects for [['fred'], ['barney', 'pebbles']]
	     */
	    var partition = createAggregator(function(result, value, key) {
	      result[key ? 0 : 1].push(value);
	    }, function() { return [[], []]; });
	
	    /**
	     * Reduces `collection` to a value which is the accumulated result of running
	     * each element in `collection` thru `iteratee`, where each successive
	     * invocation is supplied the return value of the previous. If `accumulator`
	     * is not given, the first element of `collection` is used as the initial
	     * value. The iteratee is invoked with four arguments:
	     * (accumulator, value, index|key, collection).
	     *
	     * Many lodash methods are guarded to work as iteratees for methods like
	     * `_.reduce`, `_.reduceRight`, and `_.transform`.
	     *
	     * The guarded methods are:
	     * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
	     * and `sortBy`
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The initial value.
	     * @returns {*} Returns the accumulated value.
	     * @see _.reduceRight
	     * @example
	     *
	     * _.reduce([1, 2], function(sum, n) {
	     *   return sum + n;
	     * }, 0);
	     * // => 3
	     *
	     * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
	     *   (result[value] || (result[value] = [])).push(key);
	     *   return result;
	     * }, {});
	     * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
	     */
	    function reduce(collection, iteratee, accumulator) {
	      var func = isArray(collection) ? arrayReduce : baseReduce,
	          initAccum = arguments.length < 3;
	
	      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach);
	    }
	
	    /**
	     * This method is like `_.reduce` except that it iterates over elements of
	     * `collection` from right to left.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The initial value.
	     * @returns {*} Returns the accumulated value.
	     * @see _.reduce
	     * @example
	     *
	     * var array = [[0, 1], [2, 3], [4, 5]];
	     *
	     * _.reduceRight(array, function(flattened, other) {
	     *   return flattened.concat(other);
	     * }, []);
	     * // => [4, 5, 2, 3, 0, 1]
	     */
	    function reduceRight(collection, iteratee, accumulator) {
	      var func = isArray(collection) ? arrayReduceRight : baseReduce,
	          initAccum = arguments.length < 3;
	
	      return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
	    }
	
	    /**
	     * The opposite of `_.filter`; this method returns the elements of `collection`
	     * that `predicate` does **not** return truthy for.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the new filtered array.
	     * @see _.filter
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': false },
	     *   { 'user': 'fred',   'age': 40, 'active': true }
	     * ];
	     *
	     * _.reject(users, function(o) { return !o.active; });
	     * // => objects for ['fred']
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.reject(users, { 'age': 40, 'active': true });
	     * // => objects for ['barney']
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.reject(users, ['active', false]);
	     * // => objects for ['fred']
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.reject(users, 'active');
	     * // => objects for ['barney']
	     */
	    function reject(collection, predicate) {
	      var func = isArray(collection) ? arrayFilter : baseFilter;
	      return func(collection, negate(getIteratee(predicate, 3)));
	    }
	
	    /**
	     * Gets a random element from `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to sample.
	     * @returns {*} Returns the random element.
	     * @example
	     *
	     * _.sample([1, 2, 3, 4]);
	     * // => 2
	     */
	    function sample(collection) {
	      var func = isArray(collection) ? arraySample : baseSample;
	      return func(collection);
	    }
	
	    /**
	     * Gets `n` random elements at unique keys from `collection` up to the
	     * size of `collection`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to sample.
	     * @param {number} [n=1] The number of elements to sample.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the random elements.
	     * @example
	     *
	     * _.sampleSize([1, 2, 3], 2);
	     * // => [3, 1]
	     *
	     * _.sampleSize([1, 2, 3], 4);
	     * // => [2, 3, 1]
	     */
	    function sampleSize(collection, n, guard) {
	      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
	        n = 1;
	      } else {
	        n = toInteger(n);
	      }
	      var func = isArray(collection) ? arraySampleSize : baseSampleSize;
	      return func(collection, n);
	    }
	
	    /**
	     * Creates an array of shuffled values, using a version of the
	     * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to shuffle.
	     * @returns {Array} Returns the new shuffled array.
	     * @example
	     *
	     * _.shuffle([1, 2, 3, 4]);
	     * // => [4, 1, 3, 2]
	     */
	    function shuffle(collection) {
	      var func = isArray(collection) ? arrayShuffle : baseShuffle;
	      return func(collection);
	    }
	
	    /**
	     * Gets the size of `collection` by returning its length for array-like
	     * values or the number of own enumerable string keyed properties for objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object|string} collection The collection to inspect.
	     * @returns {number} Returns the collection size.
	     * @example
	     *
	     * _.size([1, 2, 3]);
	     * // => 3
	     *
	     * _.size({ 'a': 1, 'b': 2 });
	     * // => 2
	     *
	     * _.size('pebbles');
	     * // => 7
	     */
	    function size(collection) {
	      if (collection == null) {
	        return 0;
	      }
	      if (isArrayLike(collection)) {
	        return isString(collection) ? stringSize(collection) : collection.length;
	      }
	      var tag = getTag(collection);
	      if (tag == mapTag || tag == setTag) {
	        return collection.size;
	      }
	      return baseKeys(collection).length;
	    }
	
	    /**
	     * Checks if `predicate` returns truthy for **any** element of `collection`.
	     * Iteration is stopped once `predicate` returns truthy. The predicate is
	     * invoked with three arguments: (value, index|key, collection).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {boolean} Returns `true` if any element passes the predicate check,
	     *  else `false`.
	     * @example
	     *
	     * _.some([null, 0, 'yes', false], Boolean);
	     * // => true
	     *
	     * var users = [
	     *   { 'user': 'barney', 'active': true },
	     *   { 'user': 'fred',   'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.some(users, { 'user': 'barney', 'active': false });
	     * // => false
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.some(users, ['active', false]);
	     * // => true
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.some(users, 'active');
	     * // => true
	     */
	    function some(collection, predicate, guard) {
	      var func = isArray(collection) ? arraySome : baseSome;
	      if (guard && isIterateeCall(collection, predicate, guard)) {
	        predicate = undefined;
	      }
	      return func(collection, getIteratee(predicate, 3));
	    }
	
	    /**
	     * Creates an array of elements, sorted in ascending order by the results of
	     * running each element in a collection thru each iteratee. This method
	     * performs a stable sort, that is, it preserves the original sort order of
	     * equal elements. The iteratees are invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Collection
	     * @param {Array|Object} collection The collection to iterate over.
	     * @param {...(Function|Function[])} [iteratees=[_.identity]]
	     *  The iteratees to sort by.
	     * @returns {Array} Returns the new sorted array.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'fred',   'age': 48 },
	     *   { 'user': 'barney', 'age': 36 },
	     *   { 'user': 'fred',   'age': 40 },
	     *   { 'user': 'barney', 'age': 34 }
	     * ];
	     *
	     * _.sortBy(users, [function(o) { return o.user; }]);
	     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
	     *
	     * _.sortBy(users, ['user', 'age']);
	     * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
	     */
	    var sortBy = baseRest(function(collection, iteratees) {
	      if (collection == null) {
	        return [];
	      }
	      var length = iteratees.length;
	      if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
	        iteratees = [];
	      } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
	        iteratees = [iteratees[0]];
	      }
	      return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
	    });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Gets the timestamp of the number of milliseconds that have elapsed since
	     * the Unix epoch (1 January 1970 00:00:00 UTC).
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Date
	     * @returns {number} Returns the timestamp.
	     * @example
	     *
	     * _.defer(function(stamp) {
	     *   console.log(_.now() - stamp);
	     * }, _.now());
	     * // => Logs the number of milliseconds it took for the deferred invocation.
	     */
	    var now = ctxNow || function() {
	      return root.Date.now();
	    };
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * The opposite of `_.before`; this method creates a function that invokes
	     * `func` once it's called `n` or more times.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {number} n The number of calls before `func` is invoked.
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * var saves = ['profile', 'settings'];
	     *
	     * var done = _.after(saves.length, function() {
	     *   console.log('done saving!');
	     * });
	     *
	     * _.forEach(saves, function(type) {
	     *   asyncSave({ 'type': type, 'complete': done });
	     * });
	     * // => Logs 'done saving!' after the two async saves have completed.
	     */
	    function after(n, func) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      n = toInteger(n);
	      return function() {
	        if (--n < 1) {
	          return func.apply(this, arguments);
	        }
	      };
	    }
	
	    /**
	     * Creates a function that invokes `func`, with up to `n` arguments,
	     * ignoring any additional arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to cap arguments for.
	     * @param {number} [n=func.length] The arity cap.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new capped function.
	     * @example
	     *
	     * _.map(['6', '8', '10'], _.ary(parseInt, 1));
	     * // => [6, 8, 10]
	     */
	    function ary(func, n, guard) {
	      n = guard ? undefined : n;
	      n = (func && n == null) ? func.length : n;
	      return createWrap(func, ARY_FLAG, undefined, undefined, undefined, undefined, n);
	    }
	
	    /**
	     * Creates a function that invokes `func`, with the `this` binding and arguments
	     * of the created function, while it's called less than `n` times. Subsequent
	     * calls to the created function return the result of the last `func` invocation.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {number} n The number of calls at which `func` is no longer invoked.
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * jQuery(element).on('click', _.before(5, addContactToList));
	     * // => Allows adding up to 4 contacts to the list.
	     */
	    function before(n, func) {
	      var result;
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      n = toInteger(n);
	      return function() {
	        if (--n > 0) {
	          result = func.apply(this, arguments);
	        }
	        if (n <= 1) {
	          func = undefined;
	        }
	        return result;
	      };
	    }
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of `thisArg`
	     * and `partials` prepended to the arguments it receives.
	     *
	     * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
	     * may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
	     * property of bound functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to bind.
	     * @param {*} thisArg The `this` binding of `func`.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new bound function.
	     * @example
	     *
	     * function greet(greeting, punctuation) {
	     *   return greeting + ' ' + this.user + punctuation;
	     * }
	     *
	     * var object = { 'user': 'fred' };
	     *
	     * var bound = _.bind(greet, object, 'hi');
	     * bound('!');
	     * // => 'hi fred!'
	     *
	     * // Bound with placeholders.
	     * var bound = _.bind(greet, object, _, '!');
	     * bound('hi');
	     * // => 'hi fred!'
	     */
	    var bind = baseRest(function(func, thisArg, partials) {
	      var bitmask = BIND_FLAG;
	      if (partials.length) {
	        var holders = replaceHolders(partials, getHolder(bind));
	        bitmask |= PARTIAL_FLAG;
	      }
	      return createWrap(func, bitmask, thisArg, partials, holders);
	    });
	
	    /**
	     * Creates a function that invokes the method at `object[key]` with `partials`
	     * prepended to the arguments it receives.
	     *
	     * This method differs from `_.bind` by allowing bound functions to reference
	     * methods that may be redefined or don't yet exist. See
	     * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
	     * for more details.
	     *
	     * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.10.0
	     * @category Function
	     * @param {Object} object The object to invoke the method on.
	     * @param {string} key The key of the method.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new bound function.
	     * @example
	     *
	     * var object = {
	     *   'user': 'fred',
	     *   'greet': function(greeting, punctuation) {
	     *     return greeting + ' ' + this.user + punctuation;
	     *   }
	     * };
	     *
	     * var bound = _.bindKey(object, 'greet', 'hi');
	     * bound('!');
	     * // => 'hi fred!'
	     *
	     * object.greet = function(greeting, punctuation) {
	     *   return greeting + 'ya ' + this.user + punctuation;
	     * };
	     *
	     * bound('!');
	     * // => 'hiya fred!'
	     *
	     * // Bound with placeholders.
	     * var bound = _.bindKey(object, 'greet', _, '!');
	     * bound('hi');
	     * // => 'hiya fred!'
	     */
	    var bindKey = baseRest(function(object, key, partials) {
	      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
	      if (partials.length) {
	        var holders = replaceHolders(partials, getHolder(bindKey));
	        bitmask |= PARTIAL_FLAG;
	      }
	      return createWrap(key, bitmask, object, partials, holders);
	    });
	
	    /**
	     * Creates a function that accepts arguments of `func` and either invokes
	     * `func` returning its result, if at least `arity` number of arguments have
	     * been provided, or returns a function that accepts the remaining `func`
	     * arguments, and so on. The arity of `func` may be specified if `func.length`
	     * is not sufficient.
	     *
	     * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
	     * may be used as a placeholder for provided arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of curried functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Function
	     * @param {Function} func The function to curry.
	     * @param {number} [arity=func.length] The arity of `func`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new curried function.
	     * @example
	     *
	     * var abc = function(a, b, c) {
	     *   return [a, b, c];
	     * };
	     *
	     * var curried = _.curry(abc);
	     *
	     * curried(1)(2)(3);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2)(3);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2, 3);
	     * // => [1, 2, 3]
	     *
	     * // Curried with placeholders.
	     * curried(1)(_, 3)(2);
	     * // => [1, 2, 3]
	     */
	    function curry(func, arity, guard) {
	      arity = guard ? undefined : arity;
	      var result = createWrap(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
	      result.placeholder = curry.placeholder;
	      return result;
	    }
	
	    /**
	     * This method is like `_.curry` except that arguments are applied to `func`
	     * in the manner of `_.partialRight` instead of `_.partial`.
	     *
	     * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for provided arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of curried functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to curry.
	     * @param {number} [arity=func.length] The arity of `func`.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the new curried function.
	     * @example
	     *
	     * var abc = function(a, b, c) {
	     *   return [a, b, c];
	     * };
	     *
	     * var curried = _.curryRight(abc);
	     *
	     * curried(3)(2)(1);
	     * // => [1, 2, 3]
	     *
	     * curried(2, 3)(1);
	     * // => [1, 2, 3]
	     *
	     * curried(1, 2, 3);
	     * // => [1, 2, 3]
	     *
	     * // Curried with placeholders.
	     * curried(3)(1, _)(2);
	     * // => [1, 2, 3]
	     */
	    function curryRight(func, arity, guard) {
	      arity = guard ? undefined : arity;
	      var result = createWrap(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
	      result.placeholder = curryRight.placeholder;
	      return result;
	    }
	
	    /**
	     * Creates a debounced function that delays invoking `func` until after `wait`
	     * milliseconds have elapsed since the last time the debounced function was
	     * invoked. The debounced function comes with a `cancel` method to cancel
	     * delayed `func` invocations and a `flush` method to immediately invoke them.
	     * Provide `options` to indicate whether `func` should be invoked on the
	     * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
	     * with the last arguments provided to the debounced function. Subsequent
	     * calls to the debounced function return the result of the last `func`
	     * invocation.
	     *
	     * **Note:** If `leading` and `trailing` options are `true`, `func` is
	     * invoked on the trailing edge of the timeout only if the debounced function
	     * is invoked more than once during the `wait` timeout.
	     *
	     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	     *
	     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	     * for details over the differences between `_.debounce` and `_.throttle`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to debounce.
	     * @param {number} [wait=0] The number of milliseconds to delay.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.leading=false]
	     *  Specify invoking on the leading edge of the timeout.
	     * @param {number} [options.maxWait]
	     *  The maximum time `func` is allowed to be delayed before it's invoked.
	     * @param {boolean} [options.trailing=true]
	     *  Specify invoking on the trailing edge of the timeout.
	     * @returns {Function} Returns the new debounced function.
	     * @example
	     *
	     * // Avoid costly calculations while the window size is in flux.
	     * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
	     *
	     * // Invoke `sendMail` when clicked, debouncing subsequent calls.
	     * jQuery(element).on('click', _.debounce(sendMail, 300, {
	     *   'leading': true,
	     *   'trailing': false
	     * }));
	     *
	     * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
	     * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
	     * var source = new EventSource('/stream');
	     * jQuery(source).on('message', debounced);
	     *
	     * // Cancel the trailing debounced invocation.
	     * jQuery(window).on('popstate', debounced.cancel);
	     */
	    function debounce(func, wait, options) {
	      var lastArgs,
	          lastThis,
	          maxWait,
	          result,
	          timerId,
	          lastCallTime,
	          lastInvokeTime = 0,
	          leading = false,
	          maxing = false,
	          trailing = true;
	
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      wait = toNumber(wait) || 0;
	      if (isObject(options)) {
	        leading = !!options.leading;
	        maxing = 'maxWait' in options;
	        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
	        trailing = 'trailing' in options ? !!options.trailing : trailing;
	      }
	
	      function invokeFunc(time) {
	        var args = lastArgs,
	            thisArg = lastThis;
	
	        lastArgs = lastThis = undefined;
	        lastInvokeTime = time;
	        result = func.apply(thisArg, args);
	        return result;
	      }
	
	      function leadingEdge(time) {
	        // Reset any `maxWait` timer.
	        lastInvokeTime = time;
	        // Start the timer for the trailing edge.
	        timerId = setTimeout(timerExpired, wait);
	        // Invoke the leading edge.
	        return leading ? invokeFunc(time) : result;
	      }
	
	      function remainingWait(time) {
	        var timeSinceLastCall = time - lastCallTime,
	            timeSinceLastInvoke = time - lastInvokeTime,
	            result = wait - timeSinceLastCall;
	
	        return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
	      }
	
	      function shouldInvoke(time) {
	        var timeSinceLastCall = time - lastCallTime,
	            timeSinceLastInvoke = time - lastInvokeTime;
	
	        // Either this is the first call, activity has stopped and we're at the
	        // trailing edge, the system time has gone backwards and we're treating
	        // it as the trailing edge, or we've hit the `maxWait` limit.
	        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
	          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
	      }
	
	      function timerExpired() {
	        var time = now();
	        if (shouldInvoke(time)) {
	          return trailingEdge(time);
	        }
	        // Restart the timer.
	        timerId = setTimeout(timerExpired, remainingWait(time));
	      }
	
	      function trailingEdge(time) {
	        timerId = undefined;
	
	        // Only invoke if we have `lastArgs` which means `func` has been
	        // debounced at least once.
	        if (trailing && lastArgs) {
	          return invokeFunc(time);
	        }
	        lastArgs = lastThis = undefined;
	        return result;
	      }
	
	      function cancel() {
	        if (timerId !== undefined) {
	          clearTimeout(timerId);
	        }
	        lastInvokeTime = 0;
	        lastArgs = lastCallTime = lastThis = timerId = undefined;
	      }
	
	      function flush() {
	        return timerId === undefined ? result : trailingEdge(now());
	      }
	
	      function debounced() {
	        var time = now(),
	            isInvoking = shouldInvoke(time);
	
	        lastArgs = arguments;
	        lastThis = this;
	        lastCallTime = time;
	
	        if (isInvoking) {
	          if (timerId === undefined) {
	            return leadingEdge(lastCallTime);
	          }
	          if (maxing) {
	            // Handle invocations in a tight loop.
	            timerId = setTimeout(timerExpired, wait);
	            return invokeFunc(lastCallTime);
	          }
	        }
	        if (timerId === undefined) {
	          timerId = setTimeout(timerExpired, wait);
	        }
	        return result;
	      }
	      debounced.cancel = cancel;
	      debounced.flush = flush;
	      return debounced;
	    }
	
	    /**
	     * Defers invoking the `func` until the current call stack has cleared. Any
	     * additional arguments are provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to defer.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {number} Returns the timer id.
	     * @example
	     *
	     * _.defer(function(text) {
	     *   console.log(text);
	     * }, 'deferred');
	     * // => Logs 'deferred' after one millisecond.
	     */
	    var defer = baseRest(function(func, args) {
	      return baseDelay(func, 1, args);
	    });
	
	    /**
	     * Invokes `func` after `wait` milliseconds. Any additional arguments are
	     * provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to delay.
	     * @param {number} wait The number of milliseconds to delay invocation.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {number} Returns the timer id.
	     * @example
	     *
	     * _.delay(function(text) {
	     *   console.log(text);
	     * }, 1000, 'later');
	     * // => Logs 'later' after one second.
	     */
	    var delay = baseRest(function(func, wait, args) {
	      return baseDelay(func, toNumber(wait) || 0, args);
	    });
	
	    /**
	     * Creates a function that invokes `func` with arguments reversed.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to flip arguments for.
	     * @returns {Function} Returns the new flipped function.
	     * @example
	     *
	     * var flipped = _.flip(function() {
	     *   return _.toArray(arguments);
	     * });
	     *
	     * flipped('a', 'b', 'c', 'd');
	     * // => ['d', 'c', 'b', 'a']
	     */
	    function flip(func) {
	      return createWrap(func, FLIP_FLAG);
	    }
	
	    /**
	     * 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 `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 && 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;
	
	    /**
	     * Creates a function that negates the result of the predicate `func`. The
	     * `func` predicate is invoked with the `this` binding and arguments of the
	     * created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} predicate The predicate to negate.
	     * @returns {Function} Returns the new negated function.
	     * @example
	     *
	     * function isEven(n) {
	     *   return n % 2 == 0;
	     * }
	     *
	     * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
	     * // => [1, 3, 5]
	     */
	    function negate(predicate) {
	      if (typeof predicate != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      return function() {
	        var args = arguments;
	        switch (args.length) {
	          case 0: return !predicate.call(this);
	          case 1: return !predicate.call(this, args[0]);
	          case 2: return !predicate.call(this, args[0], args[1]);
	          case 3: return !predicate.call(this, args[0], args[1], args[2]);
	        }
	        return !predicate.apply(this, args);
	      };
	    }
	
	    /**
	     * Creates a function that is restricted to invoking `func` once. Repeat calls
	     * to the function return the value of the first invocation. The `func` is
	     * invoked with the `this` binding and arguments of the created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to restrict.
	     * @returns {Function} Returns the new restricted function.
	     * @example
	     *
	     * var initialize = _.once(createApplication);
	     * initialize();
	     * initialize();
	     * // => `createApplication` is invoked once
	     */
	    function once(func) {
	      return before(2, func);
	    }
	
	    /**
	     * Creates a function that invokes `func` with its arguments transformed.
	     *
	     * @static
	     * @since 4.0.0
	     * @memberOf _
	     * @category Function
	     * @param {Function} func The function to wrap.
	     * @param {...(Function|Function[])} [transforms=[_.identity]]
	     *  The argument transforms.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * function doubled(n) {
	     *   return n * 2;
	     * }
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var func = _.overArgs(function(x, y) {
	     *   return [x, y];
	     * }, [square, doubled]);
	     *
	     * func(9, 3);
	     * // => [81, 6]
	     *
	     * func(10, 5);
	     * // => [100, 10]
	     */
	    var overArgs = castRest(function(func, transforms) {
	      transforms = (transforms.length == 1 && isArray(transforms[0]))
	        ? arrayMap(transforms[0], baseUnary(getIteratee()))
	        : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee()));
	
	      var funcsLength = transforms.length;
	      return baseRest(function(args) {
	        var index = -1,
	            length = nativeMin(args.length, funcsLength);
	
	        while (++index < length) {
	          args[index] = transforms[index].call(this, args[index]);
	        }
	        return apply(func, this, args);
	      });
	    });
	
	    /**
	     * Creates a function that invokes `func` with `partials` prepended to the
	     * arguments it receives. This method is like `_.bind` except it does **not**
	     * alter the `this` binding.
	     *
	     * The `_.partial.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of partially
	     * applied functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.2.0
	     * @category Function
	     * @param {Function} func The function to partially apply arguments to.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new partially applied function.
	     * @example
	     *
	     * function greet(greeting, name) {
	     *   return greeting + ' ' + name;
	     * }
	     *
	     * var sayHelloTo = _.partial(greet, 'hello');
	     * sayHelloTo('fred');
	     * // => 'hello fred'
	     *
	     * // Partially applied with placeholders.
	     * var greetFred = _.partial(greet, _, 'fred');
	     * greetFred('hi');
	     * // => 'hi fred'
	     */
	    var partial = baseRest(function(func, partials) {
	      var holders = replaceHolders(partials, getHolder(partial));
	      return createWrap(func, PARTIAL_FLAG, undefined, partials, holders);
	    });
	
	    /**
	     * This method is like `_.partial` except that partially applied arguments
	     * are appended to the arguments it receives.
	     *
	     * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
	     * builds, may be used as a placeholder for partially applied arguments.
	     *
	     * **Note:** This method doesn't set the "length" property of partially
	     * applied functions.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Function
	     * @param {Function} func The function to partially apply arguments to.
	     * @param {...*} [partials] The arguments to be partially applied.
	     * @returns {Function} Returns the new partially applied function.
	     * @example
	     *
	     * function greet(greeting, name) {
	     *   return greeting + ' ' + name;
	     * }
	     *
	     * var greetFred = _.partialRight(greet, 'fred');
	     * greetFred('hi');
	     * // => 'hi fred'
	     *
	     * // Partially applied with placeholders.
	     * var sayHelloTo = _.partialRight(greet, 'hello', _);
	     * sayHelloTo('fred');
	     * // => 'hello fred'
	     */
	    var partialRight = baseRest(function(func, partials) {
	      var holders = replaceHolders(partials, getHolder(partialRight));
	      return createWrap(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders);
	    });
	
	    /**
	     * Creates a function that invokes `func` with arguments arranged according
	     * to the specified `indexes` where the argument value at the first index is
	     * provided as the first argument, the argument value at the second index is
	     * provided as the second argument, and so on.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Function
	     * @param {Function} func The function to rearrange arguments for.
	     * @param {...(number|number[])} indexes The arranged argument indexes.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var rearged = _.rearg(function(a, b, c) {
	     *   return [a, b, c];
	     * }, [2, 0, 1]);
	     *
	     * rearged('b', 'c', 'a')
	     * // => ['a', 'b', 'c']
	     */
	    var rearg = flatRest(function(func, indexes) {
	      return createWrap(func, REARG_FLAG, undefined, undefined, undefined, indexes);
	    });
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of the
	     * created function and arguments from `start` and beyond provided as
	     * an array.
	     *
	     * **Note:** This method is based on the
	     * [rest parameter](https://mdn.io/rest_parameters).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to apply a rest parameter to.
	     * @param {number} [start=func.length-1] The start position of the rest parameter.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var say = _.rest(function(what, names) {
	     *   return what + ' ' + _.initial(names).join(', ') +
	     *     (_.size(names) > 1 ? ', & ' : '') + _.last(names);
	     * });
	     *
	     * say('hello', 'fred', 'barney', 'pebbles');
	     * // => 'hello fred, barney, & pebbles'
	     */
	    function rest(func, start) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      start = start === undefined ? start : toInteger(start);
	      return baseRest(func, start);
	    }
	
	    /**
	     * Creates a function that invokes `func` with the `this` binding of the
	     * create function and an array of arguments much like
	     * [`Function#apply`](http://www.ecma-international.org/ecma-262/7.0/#sec-function.prototype.apply).
	     *
	     * **Note:** This method is based on the
	     * [spread operator](https://mdn.io/spread_operator).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Function
	     * @param {Function} func The function to spread arguments over.
	     * @param {number} [start=0] The start position of the spread.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var say = _.spread(function(who, what) {
	     *   return who + ' says ' + what;
	     * });
	     *
	     * say(['fred', 'hello']);
	     * // => 'fred says hello'
	     *
	     * var numbers = Promise.all([
	     *   Promise.resolve(40),
	     *   Promise.resolve(36)
	     * ]);
	     *
	     * numbers.then(_.spread(function(x, y) {
	     *   return x + y;
	     * }));
	     * // => a Promise of 76
	     */
	    function spread(func, start) {
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      start = start === undefined ? 0 : nativeMax(toInteger(start), 0);
	      return baseRest(function(args) {
	        var array = args[start],
	            otherArgs = castSlice(args, 0, start);
	
	        if (array) {
	          arrayPush(otherArgs, array);
	        }
	        return apply(func, this, otherArgs);
	      });
	    }
	
	    /**
	     * Creates a throttled function that only invokes `func` at most once per
	     * every `wait` milliseconds. The throttled function comes with a `cancel`
	     * method to cancel delayed `func` invocations and a `flush` method to
	     * immediately invoke them. Provide `options` to indicate whether `func`
	     * should be invoked on the leading and/or trailing edge of the `wait`
	     * timeout. The `func` is invoked with the last arguments provided to the
	     * throttled function. Subsequent calls to the throttled function return the
	     * result of the last `func` invocation.
	     *
	     * **Note:** If `leading` and `trailing` options are `true`, `func` is
	     * invoked on the trailing edge of the timeout only if the throttled function
	     * is invoked more than once during the `wait` timeout.
	     *
	     * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
	     * until to the next tick, similar to `setTimeout` with a timeout of `0`.
	     *
	     * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
	     * for details over the differences between `_.throttle` and `_.debounce`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {Function} func The function to throttle.
	     * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.leading=true]
	     *  Specify invoking on the leading edge of the timeout.
	     * @param {boolean} [options.trailing=true]
	     *  Specify invoking on the trailing edge of the timeout.
	     * @returns {Function} Returns the new throttled function.
	     * @example
	     *
	     * // Avoid excessively updating the position while scrolling.
	     * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
	     *
	     * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
	     * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
	     * jQuery(element).on('click', throttled);
	     *
	     * // Cancel the trailing throttled invocation.
	     * jQuery(window).on('popstate', throttled.cancel);
	     */
	    function throttle(func, wait, options) {
	      var leading = true,
	          trailing = true;
	
	      if (typeof func != 'function') {
	        throw new TypeError(FUNC_ERROR_TEXT);
	      }
	      if (isObject(options)) {
	        leading = 'leading' in options ? !!options.leading : leading;
	        trailing = 'trailing' in options ? !!options.trailing : trailing;
	      }
	      return debounce(func, wait, {
	        'leading': leading,
	        'maxWait': wait,
	        'trailing': trailing
	      });
	    }
	
	    /**
	     * Creates a function that accepts up to one argument, ignoring any
	     * additional arguments.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Function
	     * @param {Function} func The function to cap arguments for.
	     * @returns {Function} Returns the new capped function.
	     * @example
	     *
	     * _.map(['6', '8', '10'], _.unary(parseInt));
	     * // => [6, 8, 10]
	     */
	    function unary(func) {
	      return ary(func, 1);
	    }
	
	    /**
	     * Creates a function that provides `value` to `wrapper` as its first
	     * argument. Any additional arguments provided to the function are appended
	     * to those provided to the `wrapper`. The wrapper is invoked with the `this`
	     * binding of the created function.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Function
	     * @param {*} value The value to wrap.
	     * @param {Function} [wrapper=identity] The wrapper function.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var p = _.wrap(_.escape, function(func, text) {
	     *   return '<p>' + func(text) + '</p>';
	     * });
	     *
	     * p('fred, barney, & pebbles');
	     * // => '<p>fred, barney, &amp; pebbles</p>'
	     */
	    function wrap(value, wrapper) {
	      wrapper = wrapper == null ? identity : wrapper;
	      return partial(wrapper, value);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Casts `value` as an array if it's not one.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.4.0
	     * @category Lang
	     * @param {*} value The value to inspect.
	     * @returns {Array} Returns the cast array.
	     * @example
	     *
	     * _.castArray(1);
	     * // => [1]
	     *
	     * _.castArray({ 'a': 1 });
	     * // => [{ 'a': 1 }]
	     *
	     * _.castArray('abc');
	     * // => ['abc']
	     *
	     * _.castArray(null);
	     * // => [null]
	     *
	     * _.castArray(undefined);
	     * // => [undefined]
	     *
	     * _.castArray();
	     * // => []
	     *
	     * var array = [1, 2, 3];
	     * console.log(_.castArray(array) === array);
	     * // => true
	     */
	    function castArray() {
	      if (!arguments.length) {
	        return [];
	      }
	      var value = arguments[0];
	      return isArray(value) ? value : [value];
	    }
	
	    /**
	     * Creates a shallow clone of `value`.
	     *
	     * **Note:** This method is loosely based on the
	     * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
	     * and supports cloning arrays, array buffers, booleans, date objects, maps,
	     * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
	     * arrays. The own enumerable properties of `arguments` objects are cloned
	     * as plain objects. An empty object is returned for uncloneable values such
	     * as error objects, functions, DOM nodes, and WeakMaps.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to clone.
	     * @returns {*} Returns the cloned value.
	     * @see _.cloneDeep
	     * @example
	     *
	     * var objects = [{ 'a': 1 }, { 'b': 2 }];
	     *
	     * var shallow = _.clone(objects);
	     * console.log(shallow[0] === objects[0]);
	     * // => true
	     */
	    function clone(value) {
	      return baseClone(value, false, true);
	    }
	
	    /**
	     * This method is like `_.clone` except that it accepts `customizer` which
	     * is invoked to produce the cloned value. If `customizer` returns `undefined`,
	     * cloning is handled by the method instead. The `customizer` is invoked with
	     * up to four arguments; (value [, index|key, object, stack]).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to clone.
	     * @param {Function} [customizer] The function to customize cloning.
	     * @returns {*} Returns the cloned value.
	     * @see _.cloneDeepWith
	     * @example
	     *
	     * function customizer(value) {
	     *   if (_.isElement(value)) {
	     *     return value.cloneNode(false);
	     *   }
	     * }
	     *
	     * var el = _.cloneWith(document.body, customizer);
	     *
	     * console.log(el === document.body);
	     * // => false
	     * console.log(el.nodeName);
	     * // => 'BODY'
	     * console.log(el.childNodes.length);
	     * // => 0
	     */
	    function cloneWith(value, customizer) {
	      return baseClone(value, false, true, customizer);
	    }
	
	    /**
	     * This method is like `_.clone` except that it recursively clones `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Lang
	     * @param {*} value The value to recursively clone.
	     * @returns {*} Returns the deep cloned value.
	     * @see _.clone
	     * @example
	     *
	     * var objects = [{ 'a': 1 }, { 'b': 2 }];
	     *
	     * var deep = _.cloneDeep(objects);
	     * console.log(deep[0] === objects[0]);
	     * // => false
	     */
	    function cloneDeep(value) {
	      return baseClone(value, true, true);
	    }
	
	    /**
	     * This method is like `_.cloneWith` except that it recursively clones `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to recursively clone.
	     * @param {Function} [customizer] The function to customize cloning.
	     * @returns {*} Returns the deep cloned value.
	     * @see _.cloneWith
	     * @example
	     *
	     * function customizer(value) {
	     *   if (_.isElement(value)) {
	     *     return value.cloneNode(true);
	     *   }
	     * }
	     *
	     * var el = _.cloneDeepWith(document.body, customizer);
	     *
	     * console.log(el === document.body);
	     * // => false
	     * console.log(el.nodeName);
	     * // => 'BODY'
	     * console.log(el.childNodes.length);
	     * // => 20
	     */
	    function cloneDeepWith(value, customizer) {
	      return baseClone(value, true, true, customizer);
	    }
	
	    /**
	     * Checks if `object` conforms to `source` by invoking the predicate
	     * properties of `source` with the corresponding property values of `object`.
	     *
	     * **Note:** This method is equivalent to `_.conforms` when `source` is
	     * partially applied.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.14.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {boolean} Returns `true` if `object` conforms, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2 };
	     *
	     * _.conformsTo(object, { 'b': function(n) { return n > 1; } });
	     * // => true
	     *
	     * _.conformsTo(object, { 'b': function(n) { return n > 2; } });
	     * // => false
	     */
	    function conformsTo(object, source) {
	      return source == null || baseConformsTo(object, source, keys(source));
	    }
	
	    /**
	     * 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);
	    }
	
	    /**
	     * Checks if `value` is greater than `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than `other`,
	     *  else `false`.
	     * @see _.lt
	     * @example
	     *
	     * _.gt(3, 1);
	     * // => true
	     *
	     * _.gt(3, 3);
	     * // => false
	     *
	     * _.gt(1, 3);
	     * // => false
	     */
	    var gt = createRelationalOperation(baseGt);
	
	    /**
	     * Checks if `value` is greater than or equal to `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is greater than or equal to
	     *  `other`, else `false`.
	     * @see _.lte
	     * @example
	     *
	     * _.gte(3, 1);
	     * // => true
	     *
	     * _.gte(3, 3);
	     * // => true
	     *
	     * _.gte(1, 3);
	     * // => false
	     */
	    var gte = createRelationalOperation(function(value, other) {
	      return value >= other;
	    });
	
	    /**
	     * Checks if `value` is likely an `arguments` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an `arguments` object,
	     *  else `false`.
	     * @example
	     *
	     * _.isArguments(function() { return arguments; }());
	     * // => true
	     *
	     * _.isArguments([1, 2, 3]);
	     * // => false
	     */
	    var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
	      return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
	        !propertyIsEnumerable.call(value, 'callee');
	    };
	
	    /**
	     * 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;
	
	    /**
	     * Checks if `value` is classified as an `ArrayBuffer` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`.
	     * @example
	     *
	     * _.isArrayBuffer(new ArrayBuffer(2));
	     * // => true
	     *
	     * _.isArrayBuffer(new Array(2));
	     * // => false
	     */
	    var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer;
	
	    /**
	     * Checks if `value` is array-like. A value is considered array-like if it's
	     * not a function and has a `value.length` that's an integer greater than or
	     * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
	     * @example
	     *
	     * _.isArrayLike([1, 2, 3]);
	     * // => true
	     *
	     * _.isArrayLike(document.body.children);
	     * // => true
	     *
	     * _.isArrayLike('abc');
	     * // => true
	     *
	     * _.isArrayLike(_.noop);
	     * // => false
	     */
	    function isArrayLike(value) {
	      return value != null && isLength(value.length) && !isFunction(value);
	    }
	
	    /**
	     * This method is like `_.isArrayLike` except that it also checks if `value`
	     * is an object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an array-like object,
	     *  else `false`.
	     * @example
	     *
	     * _.isArrayLikeObject([1, 2, 3]);
	     * // => true
	     *
	     * _.isArrayLikeObject(document.body.children);
	     * // => true
	     *
	     * _.isArrayLikeObject('abc');
	     * // => false
	     *
	     * _.isArrayLikeObject(_.noop);
	     * // => false
	     */
	    function isArrayLikeObject(value) {
	      return isObjectLike(value) && isArrayLike(value);
	    }
	
	    /**
	     * Checks if `value` is classified as a boolean primitive or object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a boolean, else `false`.
	     * @example
	     *
	     * _.isBoolean(false);
	     * // => true
	     *
	     * _.isBoolean(null);
	     * // => false
	     */
	    function isBoolean(value) {
	      return value === true || value === false ||
	        (isObjectLike(value) && objectToString.call(value) == boolTag);
	    }
	
	    /**
	     * Checks if `value` is a buffer.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
	     * @example
	     *
	     * _.isBuffer(new Buffer(2));
	     * // => true
	     *
	     * _.isBuffer(new Uint8Array(2));
	     * // => false
	     */
	    var isBuffer = nativeIsBuffer || stubFalse;
	
	    /**
	     * Checks if `value` is classified as a `Date` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a date object, else `false`.
	     * @example
	     *
	     * _.isDate(new Date);
	     * // => true
	     *
	     * _.isDate('Mon April 23 2012');
	     * // => false
	     */
	    var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate;
	
	    /**
	     * Checks if `value` is likely a DOM element.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
	     * @example
	     *
	     * _.isElement(document.body);
	     * // => true
	     *
	     * _.isElement('<body>');
	     * // => false
	     */
	    function isElement(value) {
	      return value != null && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value);
	    }
	
	    /**
	     * Checks if `value` is an empty object, collection, map, or set.
	     *
	     * Objects are considered empty if they have no own enumerable string keyed
	     * properties.
	     *
	     * Array-like values such as `arguments` objects, arrays, buffers, strings, or
	     * jQuery-like collections are considered empty if they have a `length` of `0`.
	     * Similarly, maps and sets are considered empty if they have a `size` of `0`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is empty, else `false`.
	     * @example
	     *
	     * _.isEmpty(null);
	     * // => true
	     *
	     * _.isEmpty(true);
	     * // => true
	     *
	     * _.isEmpty(1);
	     * // => true
	     *
	     * _.isEmpty([1, 2, 3]);
	     * // => false
	     *
	     * _.isEmpty({ 'a': 1 });
	     * // => false
	     */
	    function isEmpty(value) {
	      if (isArrayLike(value) &&
	          (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
	            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
	        return !value.length;
	      }
	      var tag = getTag(value);
	      if (tag == mapTag || tag == setTag) {
	        return !value.size;
	      }
	      if (isPrototype(value)) {
	        return !baseKeys(value).length;
	      }
	      for (var key in value) {
	        if (hasOwnProperty.call(value, key)) {
	          return false;
	        }
	      }
	      return true;
	    }
	
	    /**
	     * Performs a deep comparison between two values to determine if they are
	     * equivalent.
	     *
	     * **Note:** This method supports comparing arrays, array buffers, booleans,
	     * date objects, error objects, maps, numbers, `Object` objects, regexes,
	     * sets, strings, symbols, and typed arrays. `Object` objects are compared
	     * by their own, not inherited, enumerable properties. Functions and DOM
	     * nodes are **not** supported.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.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 };
	     *
	     * _.isEqual(object, other);
	     * // => true
	     *
	     * object === other;
	     * // => false
	     */
	    function isEqual(value, other) {
	      return baseIsEqual(value, other);
	    }
	
	    /**
	     * This method is like `_.isEqual` except that it accepts `customizer` which
	     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
	     * are handled by the method instead. The `customizer` is invoked with up to
	     * six arguments: (objValue, othValue [, index|key, object, other, stack]).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
	     * @example
	     *
	     * function isGreeting(value) {
	     *   return /^h(?:i|ello)$/.test(value);
	     * }
	     *
	     * function customizer(objValue, othValue) {
	     *   if (isGreeting(objValue) && isGreeting(othValue)) {
	     *     return true;
	     *   }
	     * }
	     *
	     * var array = ['hello', 'goodbye'];
	     * var other = ['hi', 'goodbye'];
	     *
	     * _.isEqualWith(array, other, customizer);
	     * // => true
	     */
	    function isEqualWith(value, other, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      var result = customizer ? customizer(value, other) : undefined;
	      return result === undefined ? baseIsEqual(value, other, customizer) : !!result;
	    }
	
	    /**
	     * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
	     * `SyntaxError`, `TypeError`, or `URIError` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an error object, else `false`.
	     * @example
	     *
	     * _.isError(new Error);
	     * // => true
	     *
	     * _.isError(Error);
	     * // => false
	     */
	    function isError(value) {
	      if (!isObjectLike(value)) {
	        return false;
	      }
	      return (objectToString.call(value) == errorTag) ||
	        (typeof value.message == 'string' && typeof value.name == 'string');
	    }
	
	    /**
	     * Checks if `value` is a finite primitive number.
	     *
	     * **Note:** This method is based on
	     * [`Number.isFinite`](https://mdn.io/Number/isFinite).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.
	     * @example
	     *
	     * _.isFinite(3);
	     * // => true
	     *
	     * _.isFinite(Number.MIN_VALUE);
	     * // => true
	     *
	     * _.isFinite(Infinity);
	     * // => false
	     *
	     * _.isFinite('3');
	     * // => false
	     */
	    function isFinite(value) {
	      return typeof value == 'number' && nativeIsFinite(value);
	    }
	
	    /**
	     * 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) {
	      // The use of `Object#toString` avoids issues with the `typeof` operator
	      // in Safari 9 which returns 'object' for typed array and other constructors.
	      var tag = isObject(value) ? objectToString.call(value) : '';
	      return tag == funcTag || tag == genTag || tag == proxyTag;
	    }
	
	    /**
	     * Checks if `value` is an integer.
	     *
	     * **Note:** This method is based on
	     * [`Number.isInteger`](https://mdn.io/Number/isInteger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is an integer, else `false`.
	     * @example
	     *
	     * _.isInteger(3);
	     * // => true
	     *
	     * _.isInteger(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isInteger(Infinity);
	     * // => false
	     *
	     * _.isInteger('3');
	     * // => false
	     */
	    function isInteger(value) {
	      return typeof value == 'number' && value == toInteger(value);
	    }
	
	    /**
	     * Checks if `value` is a valid array-like length.
	     *
	     * **Note:** This method is loosely based on
	     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
	     * @example
	     *
	     * _.isLength(3);
	     * // => true
	     *
	     * _.isLength(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isLength(Infinity);
	     * // => false
	     *
	     * _.isLength('3');
	     * // => false
	     */
	    function isLength(value) {
	      return typeof value == 'number' &&
	        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
	    }
	
	    /**
	     * 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');
	    }
	
	    /**
	     * 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';
	    }
	
	    /**
	     * Checks if `value` is classified as a `Map` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a map, else `false`.
	     * @example
	     *
	     * _.isMap(new Map);
	     * // => true
	     *
	     * _.isMap(new WeakMap);
	     * // => false
	     */
	    var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;
	
	    /**
	     * Performs a partial deep comparison between `object` and `source` to
	     * determine if `object` contains equivalent property values.
	     *
	     * **Note:** This method is equivalent to `_.matches` when `source` is
	     * partially applied.
	     *
	     * Partial comparisons will match empty array and empty object `source`
	     * values against any array or object value, respectively. See `_.isEqual`
	     * for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2 };
	     *
	     * _.isMatch(object, { 'b': 2 });
	     * // => true
	     *
	     * _.isMatch(object, { 'b': 1 });
	     * // => false
	     */
	    function isMatch(object, source) {
	      return object === source || baseIsMatch(object, source, getMatchData(source));
	    }
	
	    /**
	     * This method is like `_.isMatch` except that it accepts `customizer` which
	     * is invoked to compare values. If `customizer` returns `undefined`, comparisons
	     * are handled by the method instead. The `customizer` is invoked with five
	     * arguments: (objValue, srcValue, index|key, object, source).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {Object} object The object to inspect.
	     * @param {Object} source The object of property values to match.
	     * @param {Function} [customizer] The function to customize comparisons.
	     * @returns {boolean} Returns `true` if `object` is a match, else `false`.
	     * @example
	     *
	     * function isGreeting(value) {
	     *   return /^h(?:i|ello)$/.test(value);
	     * }
	     *
	     * function customizer(objValue, srcValue) {
	     *   if (isGreeting(objValue) && isGreeting(srcValue)) {
	     *     return true;
	     *   }
	     * }
	     *
	     * var object = { 'greeting': 'hello' };
	     * var source = { 'greeting': 'hi' };
	     *
	     * _.isMatchWith(object, source, customizer);
	     * // => true
	     */
	    function isMatchWith(object, source, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return baseIsMatch(object, source, getMatchData(source), customizer);
	    }
	
	    /**
	     * Checks if `value` is `NaN`.
	     *
	     * **Note:** This method is based on
	     * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
	     * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
	     * `undefined` and other non-number values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
	     * @example
	     *
	     * _.isNaN(NaN);
	     * // => true
	     *
	     * _.isNaN(new Number(NaN));
	     * // => true
	     *
	     * isNaN(undefined);
	     * // => true
	     *
	     * _.isNaN(undefined);
	     * // => false
	     */
	    function isNaN(value) {
	      // An `NaN` primitive is the only value that is not equal to itself.
	      // Perform the `toStringTag` check first to avoid errors with some
	      // ActiveX objects in IE.
	      return isNumber(value) && value != +value;
	    }
	
	    /**
	     * Checks if `value` is a pristine native function.
	     *
	     * **Note:** This method can't reliably detect native functions in the presence
	     * of the core-js package because core-js circumvents this kind of detection.
	     * Despite multiple requests, the core-js maintainer has made it clear: any
	     * attempt to fix the detection will be obstructed. As a result, we're left
	     * with little choice but to throw an error. Unfortunately, this also affects
	     * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill),
	     * which rely on core-js.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a native function,
	     *  else `false`.
	     * @example
	     *
	     * _.isNative(Array.prototype.push);
	     * // => true
	     *
	     * _.isNative(_);
	     * // => false
	     */
	    function isNative(value) {
	      if (isMaskable(value)) {
	        throw new Error(CORE_ERROR_TEXT);
	      }
	      return baseIsNative(value);
	    }
	
	    /**
	     * Checks if `value` is `null`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `null`, else `false`.
	     * @example
	     *
	     * _.isNull(null);
	     * // => true
	     *
	     * _.isNull(void 0);
	     * // => false
	     */
	    function isNull(value) {
	      return value === null;
	    }
	
	    /**
	     * Checks if `value` is `null` or `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is nullish, else `false`.
	     * @example
	     *
	     * _.isNil(null);
	     * // => true
	     *
	     * _.isNil(void 0);
	     * // => true
	     *
	     * _.isNil(NaN);
	     * // => false
	     */
	    function isNil(value) {
	      return value == null;
	    }
	
	    /**
	     * Checks if `value` is classified as a `Number` primitive or object.
	     *
	     * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
	     * classified as numbers, use the `_.isFinite` method.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a number, else `false`.
	     * @example
	     *
	     * _.isNumber(3);
	     * // => true
	     *
	     * _.isNumber(Number.MIN_VALUE);
	     * // => true
	     *
	     * _.isNumber(Infinity);
	     * // => true
	     *
	     * _.isNumber('3');
	     * // => false
	     */
	    function isNumber(value) {
	      return typeof value == 'number' ||
	        (isObjectLike(value) && objectToString.call(value) == numberTag);
	    }
	
	    /**
	     * 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) || objectToString.call(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);
	    }
	
	    /**
	     * Checks if `value` is classified as a `RegExp` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.1.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a regexp, else `false`.
	     * @example
	     *
	     * _.isRegExp(/abc/);
	     * // => true
	     *
	     * _.isRegExp('/abc/');
	     * // => false
	     */
	    var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp;
	
	    /**
	     * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754
	     * double precision number which isn't the result of a rounded unsafe integer.
	     *
	     * **Note:** This method is based on
	     * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a safe integer, else `false`.
	     * @example
	     *
	     * _.isSafeInteger(3);
	     * // => true
	     *
	     * _.isSafeInteger(Number.MIN_VALUE);
	     * // => false
	     *
	     * _.isSafeInteger(Infinity);
	     * // => false
	     *
	     * _.isSafeInteger('3');
	     * // => false
	     */
	    function isSafeInteger(value) {
	      return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER;
	    }
	
	    /**
	     * Checks if `value` is classified as a `Set` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a set, else `false`.
	     * @example
	     *
	     * _.isSet(new Set);
	     * // => true
	     *
	     * _.isSet(new WeakSet);
	     * // => false
	     */
	    var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;
	
	    /**
	     * Checks if `value` is classified as a `String` primitive or object.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a string, else `false`.
	     * @example
	     *
	     * _.isString('abc');
	     * // => true
	     *
	     * _.isString(1);
	     * // => false
	     */
	    function isString(value) {
	      return typeof value == 'string' ||
	        (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
	    }
	
	    /**
	     * 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) && objectToString.call(value) == symbolTag);
	    }
	
	    /**
	     * Checks if `value` is classified as a typed array.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
	     * @example
	     *
	     * _.isTypedArray(new Uint8Array);
	     * // => true
	     *
	     * _.isTypedArray([]);
	     * // => false
	     */
	    var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
	
	    /**
	     * Checks if `value` is `undefined`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
	     * @example
	     *
	     * _.isUndefined(void 0);
	     * // => true
	     *
	     * _.isUndefined(null);
	     * // => false
	     */
	    function isUndefined(value) {
	      return value === undefined;
	    }
	
	    /**
	     * Checks if `value` is classified as a `WeakMap` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a weak map, else `false`.
	     * @example
	     *
	     * _.isWeakMap(new WeakMap);
	     * // => true
	     *
	     * _.isWeakMap(new Map);
	     * // => false
	     */
	    function isWeakMap(value) {
	      return isObjectLike(value) && getTag(value) == weakMapTag;
	    }
	
	    /**
	     * Checks if `value` is classified as a `WeakSet` object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.3.0
	     * @category Lang
	     * @param {*} value The value to check.
	     * @returns {boolean} Returns `true` if `value` is a weak set, else `false`.
	     * @example
	     *
	     * _.isWeakSet(new WeakSet);
	     * // => true
	     *
	     * _.isWeakSet(new Set);
	     * // => false
	     */
	    function isWeakSet(value) {
	      return isObjectLike(value) && objectToString.call(value) == weakSetTag;
	    }
	
	    /**
	     * Checks if `value` is less than `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than `other`,
	     *  else `false`.
	     * @see _.gt
	     * @example
	     *
	     * _.lt(1, 3);
	     * // => true
	     *
	     * _.lt(3, 3);
	     * // => false
	     *
	     * _.lt(3, 1);
	     * // => false
	     */
	    var lt = createRelationalOperation(baseLt);
	
	    /**
	     * Checks if `value` is less than or equal to `other`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.9.0
	     * @category Lang
	     * @param {*} value The value to compare.
	     * @param {*} other The other value to compare.
	     * @returns {boolean} Returns `true` if `value` is less than or equal to
	     *  `other`, else `false`.
	     * @see _.gte
	     * @example
	     *
	     * _.lte(1, 3);
	     * // => true
	     *
	     * _.lte(3, 3);
	     * // => true
	     *
	     * _.lte(3, 1);
	     * // => false
	     */
	    var lte = createRelationalOperation(function(value, other) {
	      return value <= other;
	    });
	
	    /**
	     * Converts `value` to an array.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {Array} Returns the converted array.
	     * @example
	     *
	     * _.toArray({ 'a': 1, 'b': 2 });
	     * // => [1, 2]
	     *
	     * _.toArray('abc');
	     * // => ['a', 'b', 'c']
	     *
	     * _.toArray(1);
	     * // => []
	     *
	     * _.toArray(null);
	     * // => []
	     */
	    function toArray(value) {
	      if (!value) {
	        return [];
	      }
	      if (isArrayLike(value)) {
	        return isString(value) ? stringToArray(value) : copyArray(value);
	      }
	      if (iteratorSymbol && value[iteratorSymbol]) {
	        return iteratorToArray(value[iteratorSymbol]());
	      }
	      var tag = getTag(value),
	          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
	
	      return func(value);
	    }
	
	    /**
	     * Converts `value` to a finite number.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.12.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted number.
	     * @example
	     *
	     * _.toFinite(3.2);
	     * // => 3.2
	     *
	     * _.toFinite(Number.MIN_VALUE);
	     * // => 5e-324
	     *
	     * _.toFinite(Infinity);
	     * // => 1.7976931348623157e+308
	     *
	     * _.toFinite('3.2');
	     * // => 3.2
	     */
	    function toFinite(value) {
	      if (!value) {
	        return value === 0 ? value : 0;
	      }
	      value = toNumber(value);
	      if (value === INFINITY || value === -INFINITY) {
	        var sign = (value < 0 ? -1 : 1);
	        return sign * MAX_INTEGER;
	      }
	      return value === value ? value : 0;
	    }
	
	    /**
	     * Converts `value` to an integer.
	     *
	     * **Note:** This method is loosely based on
	     * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toInteger(3.2);
	     * // => 3
	     *
	     * _.toInteger(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toInteger(Infinity);
	     * // => 1.7976931348623157e+308
	     *
	     * _.toInteger('3.2');
	     * // => 3
	     */
	    function toInteger(value) {
	      var result = toFinite(value),
	          remainder = result % 1;
	
	      return result === result ? (remainder ? result - remainder : result) : 0;
	    }
	
	    /**
	     * Converts `value` to an integer suitable for use as the length of an
	     * array-like object.
	     *
	     * **Note:** This method is based on
	     * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toLength(3.2);
	     * // => 3
	     *
	     * _.toLength(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toLength(Infinity);
	     * // => 4294967295
	     *
	     * _.toLength('3.2');
	     * // => 3
	     */
	    function toLength(value) {
	      return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0;
	    }
	
	    /**
	     * Converts `value` to a number.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to process.
	     * @returns {number} Returns the number.
	     * @example
	     *
	     * _.toNumber(3.2);
	     * // => 3.2
	     *
	     * _.toNumber(Number.MIN_VALUE);
	     * // => 5e-324
	     *
	     * _.toNumber(Infinity);
	     * // => Infinity
	     *
	     * _.toNumber('3.2');
	     * // => 3.2
	     */
	    function toNumber(value) {
	      if (typeof value == 'number') {
	        return value;
	      }
	      if (isSymbol(value)) {
	        return NAN;
	      }
	      if (isObject(value)) {
	        var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
	        value = isObject(other) ? (other + '') : other;
	      }
	      if (typeof value != 'string') {
	        return value === 0 ? value : +value;
	      }
	      value = value.replace(reTrim, '');
	      var isBinary = reIsBinary.test(value);
	      return (isBinary || reIsOctal.test(value))
	        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
	        : (reIsBadHex.test(value) ? NAN : +value);
	    }
	
	    /**
	     * Converts `value` to a plain object flattening inherited enumerable string
	     * keyed properties of `value` to own properties of the plain object.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {Object} Returns the converted plain object.
	     * @example
	     *
	     * function Foo() {
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.assign({ 'a': 1 }, new Foo);
	     * // => { 'a': 1, 'b': 2 }
	     *
	     * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
	     * // => { 'a': 1, 'b': 2, 'c': 3 }
	     */
	    function toPlainObject(value) {
	      return copyObject(value, keysIn(value));
	    }
	
	    /**
	     * Converts `value` to a safe integer. A safe integer can be compared and
	     * represented correctly.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Lang
	     * @param {*} value The value to convert.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.toSafeInteger(3.2);
	     * // => 3
	     *
	     * _.toSafeInteger(Number.MIN_VALUE);
	     * // => 0
	     *
	     * _.toSafeInteger(Infinity);
	     * // => 9007199254740991
	     *
	     * _.toSafeInteger('3.2');
	     * // => 3
	     */
	    function toSafeInteger(value) {
	      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
	    }
	
	    /**
	     * 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);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Assigns own enumerable string keyed properties of source objects to the
	     * destination object. Source objects are applied from left to right.
	     * Subsequent sources overwrite property assignments of previous sources.
	     *
	     * **Note:** This method mutates `object` and is loosely based on
	     * [`Object.assign`](https://mdn.io/Object/assign).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.10.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.assignIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     * }
	     *
	     * function Bar() {
	     *   this.c = 3;
	     * }
	     *
	     * Foo.prototype.b = 2;
	     * Bar.prototype.d = 4;
	     *
	     * _.assign({ 'a': 0 }, new Foo, new Bar);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    var assign = createAssigner(function(object, source) {
	      if (isPrototype(source) || isArrayLike(source)) {
	        copyObject(source, keys(source), object);
	        return;
	      }
	      for (var key in source) {
	        if (hasOwnProperty.call(source, key)) {
	          assignValue(object, key, source[key]);
	        }
	      }
	    });
	
	    /**
	     * This method is like `_.assign` except that it iterates over own and
	     * inherited source properties.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias extend
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.assign
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     * }
	     *
	     * function Bar() {
	     *   this.c = 3;
	     * }
	     *
	     * Foo.prototype.b = 2;
	     * Bar.prototype.d = 4;
	     *
	     * _.assignIn({ 'a': 0 }, new Foo, new Bar);
	     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
	     */
	    var assignIn = createAssigner(function(object, source) {
	      copyObject(source, keysIn(source), object);
	    });
	
	    /**
	     * This method is like `_.assignIn` except that it accepts `customizer`
	     * which is invoked to produce the assigned values. If `customizer` returns
	     * `undefined`, assignment is handled by the method instead. The `customizer`
	     * is invoked with five arguments: (objValue, srcValue, key, object, source).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias extendWith
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @see _.assignWith
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   return _.isUndefined(objValue) ? srcValue : objValue;
	     * }
	     *
	     * var defaults = _.partialRight(_.assignInWith, customizer);
	     *
	     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
	      copyObject(source, keysIn(source), object, customizer);
	    });
	
	    /**
	     * This method is like `_.assign` except that it accepts `customizer`
	     * which is invoked to produce the assigned values. If `customizer` returns
	     * `undefined`, assignment is handled by the method instead. The `customizer`
	     * is invoked with five arguments: (objValue, srcValue, key, object, source).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @see _.assignInWith
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   return _.isUndefined(objValue) ? srcValue : objValue;
	     * }
	     *
	     * var defaults = _.partialRight(_.assignWith, customizer);
	     *
	     * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var assignWith = createAssigner(function(object, source, srcIndex, customizer) {
	      copyObject(source, keys(source), object, customizer);
	    });
	
	    /**
	     * Creates an array of values corresponding to `paths` of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {...(string|string[])} [paths] The property paths of elements to pick.
	     * @returns {Array} Returns the picked values.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
	     *
	     * _.at(object, ['a[0].b.c', 'a[1]']);
	     * // => [3, 4]
	     */
	    var at = flatRest(baseAt);
	
	    /**
	     * Creates an object that inherits from the `prototype` object. If a
	     * `properties` object is given, its own enumerable string keyed properties
	     * are assigned to the created object.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.3.0
	     * @category Object
	     * @param {Object} prototype The object to inherit from.
	     * @param {Object} [properties] The properties to assign to the object.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * function Shape() {
	     *   this.x = 0;
	     *   this.y = 0;
	     * }
	     *
	     * function Circle() {
	     *   Shape.call(this);
	     * }
	     *
	     * Circle.prototype = _.create(Shape.prototype, {
	     *   'constructor': Circle
	     * });
	     *
	     * var circle = new Circle;
	     * circle instanceof Circle;
	     * // => true
	     *
	     * circle instanceof Shape;
	     * // => true
	     */
	    function create(prototype, properties) {
	      var result = baseCreate(prototype);
	      return properties ? baseAssign(result, properties) : result;
	    }
	
	    /**
	     * Assigns own and inherited enumerable string keyed properties of source
	     * objects to the destination object for all destination properties that
	     * resolve to `undefined`. Source objects are applied from left to right.
	     * Once a property is set, additional values of the same property are ignored.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.defaultsDeep
	     * @example
	     *
	     * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
	     * // => { 'a': 1, 'b': 2 }
	     */
	    var defaults = baseRest(function(args) {
	      args.push(undefined, assignInDefaults);
	      return apply(assignInWith, undefined, args);
	    });
	
	    /**
	     * This method is like `_.defaults` except that it recursively assigns
	     * default properties.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @see _.defaults
	     * @example
	     *
	     * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } });
	     * // => { 'a': { 'b': 2, 'c': 3 } }
	     */
	    var defaultsDeep = baseRest(function(args) {
	      args.push(undefined, mergeDefaults);
	      return apply(mergeWith, undefined, args);
	    });
	
	    /**
	     * This method is like `_.find` except that it returns the key of the first
	     * element `predicate` returns truthy for instead of the element itself.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {string|undefined} Returns the key of the matched element,
	     *  else `undefined`.
	     * @example
	     *
	     * var users = {
	     *   'barney':  { 'age': 36, 'active': true },
	     *   'fred':    { 'age': 40, 'active': false },
	     *   'pebbles': { 'age': 1,  'active': true }
	     * };
	     *
	     * _.findKey(users, function(o) { return o.age < 40; });
	     * // => 'barney' (iteration order is not guaranteed)
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findKey(users, { 'age': 1, 'active': true });
	     * // => 'pebbles'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findKey(users, ['active', false]);
	     * // => 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findKey(users, 'active');
	     * // => 'barney'
	     */
	    function findKey(object, predicate) {
	      return baseFindKey(object, getIteratee(predicate, 3), baseForOwn);
	    }
	
	    /**
	     * This method is like `_.findKey` except that it iterates over elements of
	     * a collection in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @param {Function} [predicate=_.identity] The function invoked per iteration.
	     * @returns {string|undefined} Returns the key of the matched element,
	     *  else `undefined`.
	     * @example
	     *
	     * var users = {
	     *   'barney':  { 'age': 36, 'active': true },
	     *   'fred':    { 'age': 40, 'active': false },
	     *   'pebbles': { 'age': 1,  'active': true }
	     * };
	     *
	     * _.findLastKey(users, function(o) { return o.age < 40; });
	     * // => returns 'pebbles' assuming `_.findKey` returns 'barney'
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.findLastKey(users, { 'age': 36, 'active': true });
	     * // => 'barney'
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.findLastKey(users, ['active', false]);
	     * // => 'fred'
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.findLastKey(users, 'active');
	     * // => 'pebbles'
	     */
	    function findLastKey(object, predicate) {
	      return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight);
	    }
	
	    /**
	     * Iterates over own and inherited enumerable string keyed properties of an
	     * object and invokes `iteratee` for each property. The iteratee is invoked
	     * with three arguments: (value, key, object). Iteratee functions may exit
	     * iteration early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forInRight
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forIn(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
	     */
	    function forIn(object, iteratee) {
	      return object == null
	        ? object
	        : baseFor(object, getIteratee(iteratee, 3), keysIn);
	    }
	
	    /**
	     * This method is like `_.forIn` except that it iterates over properties of
	     * `object` in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forInRight(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'.
	     */
	    function forInRight(object, iteratee) {
	      return object == null
	        ? object
	        : baseForRight(object, getIteratee(iteratee, 3), keysIn);
	    }
	
	    /**
	     * Iterates over own enumerable string keyed properties of an object and
	     * invokes `iteratee` for each property. The iteratee is invoked with three
	     * arguments: (value, key, object). Iteratee functions may exit iteration
	     * early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forOwnRight
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forOwn(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'a' then 'b' (iteration order is not guaranteed).
	     */
	    function forOwn(object, iteratee) {
	      return object && baseForOwn(object, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * This method is like `_.forOwn` except that it iterates over properties of
	     * `object` in the opposite order.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.0.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns `object`.
	     * @see _.forOwn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.forOwnRight(new Foo, function(value, key) {
	     *   console.log(key);
	     * });
	     * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'.
	     */
	    function forOwnRight(object, iteratee) {
	      return object && baseForOwnRight(object, getIteratee(iteratee, 3));
	    }
	
	    /**
	     * Creates an array of function property names from own enumerable properties
	     * of `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @returns {Array} Returns the function names.
	     * @see _.functionsIn
	     * @example
	     *
	     * function Foo() {
	     *   this.a = _.constant('a');
	     *   this.b = _.constant('b');
	     * }
	     *
	     * Foo.prototype.c = _.constant('c');
	     *
	     * _.functions(new Foo);
	     * // => ['a', 'b']
	     */
	    function functions(object) {
	      return object == null ? [] : baseFunctions(object, keys(object));
	    }
	
	    /**
	     * Creates an array of function property names from own and inherited
	     * enumerable properties of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to inspect.
	     * @returns {Array} Returns the function names.
	     * @see _.functions
	     * @example
	     *
	     * function Foo() {
	     *   this.a = _.constant('a');
	     *   this.b = _.constant('b');
	     * }
	     *
	     * Foo.prototype.c = _.constant('c');
	     *
	     * _.functionsIn(new Foo);
	     * // => ['a', 'b', 'c']
	     */
	    function functionsIn(object) {
	      return object == null ? [] : baseFunctions(object, keysIn(object));
	    }
	
	    /**
	     * 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;
	    }
	
	    /**
	     * Checks if `path` is a direct property of `object`.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     * @example
	     *
	     * var object = { 'a': { 'b': 2 } };
	     * var other = _.create({ 'a': _.create({ 'b': 2 }) });
	     *
	     * _.has(object, 'a');
	     * // => true
	     *
	     * _.has(object, 'a.b');
	     * // => true
	     *
	     * _.has(object, ['a', 'b']);
	     * // => true
	     *
	     * _.has(other, 'a');
	     * // => false
	     */
	    function has(object, path) {
	      return object != null && hasPath(object, path, baseHas);
	    }
	
	    /**
	     * Checks if `path` is a direct or inherited property of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path to check.
	     * @returns {boolean} Returns `true` if `path` exists, else `false`.
	     * @example
	     *
	     * var object = _.create({ 'a': _.create({ 'b': 2 }) });
	     *
	     * _.hasIn(object, 'a');
	     * // => true
	     *
	     * _.hasIn(object, 'a.b');
	     * // => true
	     *
	     * _.hasIn(object, ['a', 'b']);
	     * // => true
	     *
	     * _.hasIn(object, 'b');
	     * // => false
	     */
	    function hasIn(object, path) {
	      return object != null && hasPath(object, path, baseHasIn);
	    }
	
	    /**
	     * Creates an object composed of the inverted keys and values of `object`.
	     * If `object` contains duplicate values, subsequent values overwrite
	     * property assignments of previous values.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.7.0
	     * @category Object
	     * @param {Object} object The object to invert.
	     * @returns {Object} Returns the new inverted object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2, 'c': 1 };
	     *
	     * _.invert(object);
	     * // => { '1': 'c', '2': 'b' }
	     */
	    var invert = createInverter(function(result, value, key) {
	      result[value] = key;
	    }, constant(identity));
	
	    /**
	     * This method is like `_.invert` except that the inverted object is generated
	     * from the results of running each element of `object` thru `iteratee`. The
	     * corresponding inverted value of each inverted key is an array of keys
	     * responsible for generating the inverted value. The iteratee is invoked
	     * with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.1.0
	     * @category Object
	     * @param {Object} object The object to invert.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {Object} Returns the new inverted object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': 2, 'c': 1 };
	     *
	     * _.invertBy(object);
	     * // => { '1': ['a', 'c'], '2': ['b'] }
	     *
	     * _.invertBy(object, function(value) {
	     *   return 'group' + value;
	     * });
	     * // => { 'group1': ['a', 'c'], 'group2': ['b'] }
	     */
	    var invertBy = createInverter(function(result, value, key) {
	      if (hasOwnProperty.call(result, value)) {
	        result[value].push(key);
	      } else {
	        result[value] = [key];
	      }
	    }, getIteratee);
	
	    /**
	     * Invokes the method at `path` of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {*} Returns the result of the invoked method.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
	     *
	     * _.invoke(object, 'a[0].b.c.slice', 1, 3);
	     * // => [2, 3]
	     */
	    var invoke = baseRest(baseInvoke);
	
	    /**
	     * Creates an array of the own enumerable property names of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects. See the
	     * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	     * for more details.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.keys(new Foo);
	     * // => ['a', 'b'] (iteration order is not guaranteed)
	     *
	     * _.keys('hi');
	     * // => ['0', '1']
	     */
	    function keys(object) {
	      return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
	    }
	
	    /**
	     * Creates an array of the own and inherited enumerable property names of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property names.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.keysIn(new Foo);
	     * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
	     */
	    function keysIn(object) {
	      return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
	    }
	
	    /**
	     * The opposite of `_.mapValues`; this method creates an object with the
	     * same values as `object` and keys generated by running each own enumerable
	     * string keyed property of `object` thru `iteratee`. The iteratee is invoked
	     * with three arguments: (value, key, object).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.8.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns the new mapped object.
	     * @see _.mapValues
	     * @example
	     *
	     * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
	     *   return key + value;
	     * });
	     * // => { 'a1': 1, 'b2': 2 }
	     */
	    function mapKeys(object, iteratee) {
	      var result = {};
	      iteratee = getIteratee(iteratee, 3);
	
	      baseForOwn(object, function(value, key, object) {
	        baseAssignValue(result, iteratee(value, key, object), value);
	      });
	      return result;
	    }
	
	    /**
	     * Creates an object with the same keys as `object` and values generated
	     * by running each own enumerable string keyed property of `object` thru
	     * `iteratee`. The iteratee is invoked with three arguments:
	     * (value, key, object).
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Object} Returns the new mapped object.
	     * @see _.mapKeys
	     * @example
	     *
	     * var users = {
	     *   'fred':    { 'user': 'fred',    'age': 40 },
	     *   'pebbles': { 'user': 'pebbles', 'age': 1 }
	     * };
	     *
	     * _.mapValues(users, function(o) { return o.age; });
	     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.mapValues(users, 'age');
	     * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
	     */
	    function mapValues(object, iteratee) {
	      var result = {};
	      iteratee = getIteratee(iteratee, 3);
	
	      baseForOwn(object, function(value, key, object) {
	        baseAssignValue(result, key, iteratee(value, key, object));
	      });
	      return result;
	    }
	
	    /**
	     * This method is like `_.assign` except that it recursively merges own and
	     * inherited enumerable string keyed properties of source objects into the
	     * destination object. Source properties that resolve to `undefined` are
	     * skipped if a destination value exists. Array and plain object properties
	     * are merged recursively. Other objects and value types are overridden by
	     * assignment. Source objects are applied from left to right. Subsequent
	     * sources overwrite property assignments of previous sources.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.5.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} [sources] The source objects.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {
	     *   'a': [{ 'b': 2 }, { 'd': 4 }]
	     * };
	     *
	     * var other = {
	     *   'a': [{ 'c': 3 }, { 'e': 5 }]
	     * };
	     *
	     * _.merge(object, other);
	     * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
	     */
	    var merge = createAssigner(function(object, source, srcIndex) {
	      baseMerge(object, source, srcIndex);
	    });
	
	    /**
	     * This method is like `_.merge` except that it accepts `customizer` which
	     * is invoked to produce the merged values of the destination and source
	     * properties. If `customizer` returns `undefined`, merging is handled by the
	     * method instead. The `customizer` is invoked with six arguments:
	     * (objValue, srcValue, key, object, source, stack).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The destination object.
	     * @param {...Object} sources The source objects.
	     * @param {Function} customizer The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * function customizer(objValue, srcValue) {
	     *   if (_.isArray(objValue)) {
	     *     return objValue.concat(srcValue);
	     *   }
	     * }
	     *
	     * var object = { 'a': [1], 'b': [2] };
	     * var other = { 'a': [3], 'b': [4] };
	     *
	     * _.mergeWith(object, other, customizer);
	     * // => { 'a': [1, 3], 'b': [2, 4] }
	     */
	    var mergeWith = createAssigner(function(object, source, srcIndex, customizer) {
	      baseMerge(object, source, srcIndex, customizer);
	    });
	
	    /**
	     * The opposite of `_.pick`; this method creates an object composed of the
	     * own and inherited enumerable string keyed properties of `object` that are
	     * not omitted.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {...(string|string[])} [props] The property identifiers to omit.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.omit(object, ['a', 'c']);
	     * // => { 'b': '2' }
	     */
	    var omit = flatRest(function(object, props) {
	      if (object == null) {
	        return {};
	      }
	      props = arrayMap(props, toKey);
	      return basePick(object, baseDifference(getAllKeysIn(object), props));
	    });
	
	    /**
	     * The opposite of `_.pickBy`; this method creates an object composed of
	     * the own and inherited enumerable string keyed properties of `object` that
	     * `predicate` doesn't return truthy for. The predicate is invoked with two
	     * arguments: (value, key).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {Function} [predicate=_.identity] The function invoked per property.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.omitBy(object, _.isNumber);
	     * // => { 'b': '2' }
	     */
	    function omitBy(object, predicate) {
	      return pickBy(object, negate(getIteratee(predicate)));
	    }
	
	    /**
	     * Creates an object composed of the picked `object` properties.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {...(string|string[])} [props] The property identifiers to pick.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.pick(object, ['a', 'c']);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    var pick = flatRest(function(object, props) {
	      return object == null ? {} : basePick(object, arrayMap(props, toKey));
	    });
	
	    /**
	     * Creates an object composed of the `object` properties `predicate` returns
	     * truthy for. The predicate is invoked with two arguments: (value, key).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The source object.
	     * @param {Function} [predicate=_.identity] The function invoked per property.
	     * @returns {Object} Returns the new object.
	     * @example
	     *
	     * var object = { 'a': 1, 'b': '2', 'c': 3 };
	     *
	     * _.pickBy(object, _.isNumber);
	     * // => { 'a': 1, 'c': 3 }
	     */
	    function pickBy(object, predicate) {
	      return object == null ? {} : basePickBy(object, getAllKeysIn(object), getIteratee(predicate));
	    }
	
	    /**
	     * This method is like `_.get` except that if the resolved value is a
	     * function it's invoked with the `this` binding of its parent object and
	     * its result is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @param {Array|string} path The path of the property to resolve.
	     * @param {*} [defaultValue] The value returned for `undefined` resolved values.
	     * @returns {*} Returns the resolved value.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
	     *
	     * _.result(object, 'a[0].b.c1');
	     * // => 3
	     *
	     * _.result(object, 'a[0].b.c2');
	     * // => 4
	     *
	     * _.result(object, 'a[0].b.c3', 'default');
	     * // => 'default'
	     *
	     * _.result(object, 'a[0].b.c3', _.constant('default'));
	     * // => 'default'
	     */
	    function result(object, path, defaultValue) {
	      path = isKey(path, object) ? [path] : castPath(path);
	
	      var index = -1,
	          length = path.length;
	
	      // Ensure the loop is entered when path is empty.
	      if (!length) {
	        object = undefined;
	        length = 1;
	      }
	      while (++index < length) {
	        var value = object == null ? undefined : object[toKey(path[index])];
	        if (value === undefined) {
	          index = length;
	          value = defaultValue;
	        }
	        object = isFunction(value) ? value.call(object) : value;
	      }
	      return object;
	    }
	
	    /**
	     * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
	     * it's created. Arrays are created for missing index properties while objects
	     * are created for all other missing properties. Use `_.setWith` to customize
	     * `path` creation.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	     *
	     * _.set(object, 'a[0].b.c', 4);
	     * console.log(object.a[0].b.c);
	     * // => 4
	     *
	     * _.set(object, ['x', '0', 'y', 'z'], 5);
	     * console.log(object.x[0].y.z);
	     * // => 5
	     */
	    function set(object, path, value) {
	      return object == null ? object : baseSet(object, path, value);
	    }
	
	    /**
	     * This method is like `_.set` except that it accepts `customizer` which is
	     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
	     * path creation is handled by the method instead. The `customizer` is invoked
	     * with three arguments: (nsValue, key, nsObject).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {*} value The value to set.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {};
	     *
	     * _.setWith(object, '[0][1]', 'a', Object);
	     * // => { '0': { '1': 'a' } }
	     */
	    function setWith(object, path, value, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return object == null ? object : baseSet(object, path, value, customizer);
	    }
	
	    /**
	     * Creates an array of own enumerable string keyed-value pairs for `object`
	     * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
	     * entries are returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias entries
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the key-value pairs.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.toPairs(new Foo);
	     * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
	     */
	    var toPairs = createToPairs(keys);
	
	    /**
	     * Creates an array of own and inherited enumerable string keyed-value pairs
	     * for `object` which can be consumed by `_.fromPairs`. If `object` is a map
	     * or set, its entries are returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @alias entriesIn
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the key-value pairs.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.toPairsIn(new Foo);
	     * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed)
	     */
	    var toPairsIn = createToPairs(keysIn);
	
	    /**
	     * An alternative to `_.reduce`; this method transforms `object` to a new
	     * `accumulator` object which is the result of running each of its own
	     * enumerable string keyed properties thru `iteratee`, with each invocation
	     * potentially mutating the `accumulator` object. If `accumulator` is not
	     * provided, a new object with the same `[[Prototype]]` will be used. The
	     * iteratee is invoked with four arguments: (accumulator, value, key, object).
	     * Iteratee functions may exit iteration early by explicitly returning `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.3.0
	     * @category Object
	     * @param {Object} object The object to iterate over.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @param {*} [accumulator] The custom accumulator value.
	     * @returns {*} Returns the accumulated value.
	     * @example
	     *
	     * _.transform([2, 3, 4], function(result, n) {
	     *   result.push(n *= n);
	     *   return n % 2 == 0;
	     * }, []);
	     * // => [4, 9]
	     *
	     * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
	     *   (result[value] || (result[value] = [])).push(key);
	     * }, {});
	     * // => { '1': ['a', 'c'], '2': ['b'] }
	     */
	    function transform(object, iteratee, accumulator) {
	      var isArr = isArray(object),
	          isArrLike = isArr || isBuffer(object) || isTypedArray(object);
	
	      iteratee = getIteratee(iteratee, 4);
	      if (accumulator == null) {
	        var Ctor = object && object.constructor;
	        if (isArrLike) {
	          accumulator = isArr ? new Ctor : [];
	        }
	        else if (isObject(object)) {
	          accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
	        }
	        else {
	          accumulator = {};
	        }
	      }
	      (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
	        return iteratee(accumulator, value, index, object);
	      });
	      return accumulator;
	    }
	
	    /**
	     * Removes the property at `path` of `object`.
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to unset.
	     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 7 } }] };
	     * _.unset(object, 'a[0].b.c');
	     * // => true
	     *
	     * console.log(object);
	     * // => { 'a': [{ 'b': {} }] };
	     *
	     * _.unset(object, ['a', '0', 'b', 'c']);
	     * // => true
	     *
	     * console.log(object);
	     * // => { 'a': [{ 'b': {} }] };
	     */
	    function unset(object, path) {
	      return object == null ? true : baseUnset(object, path);
	    }
	
	    /**
	     * This method is like `_.set` except that accepts `updater` to produce the
	     * value to set. Use `_.updateWith` to customize `path` creation. The `updater`
	     * is invoked with one argument: (value).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {Function} updater The function to produce the updated value.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = { 'a': [{ 'b': { 'c': 3 } }] };
	     *
	     * _.update(object, 'a[0].b.c', function(n) { return n * n; });
	     * console.log(object.a[0].b.c);
	     * // => 9
	     *
	     * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; });
	     * console.log(object.x[0].y.z);
	     * // => 0
	     */
	    function update(object, path, updater) {
	      return object == null ? object : baseUpdate(object, path, castFunction(updater));
	    }
	
	    /**
	     * This method is like `_.update` except that it accepts `customizer` which is
	     * invoked to produce the objects of `path`.  If `customizer` returns `undefined`
	     * path creation is handled by the method instead. The `customizer` is invoked
	     * with three arguments: (nsValue, key, nsObject).
	     *
	     * **Note:** This method mutates `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.6.0
	     * @category Object
	     * @param {Object} object The object to modify.
	     * @param {Array|string} path The path of the property to set.
	     * @param {Function} updater The function to produce the updated value.
	     * @param {Function} [customizer] The function to customize assigned values.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var object = {};
	     *
	     * _.updateWith(object, '[0][1]', _.constant('a'), Object);
	     * // => { '0': { '1': 'a' } }
	     */
	    function updateWith(object, path, updater, customizer) {
	      customizer = typeof customizer == 'function' ? customizer : undefined;
	      return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer);
	    }
	
	    /**
	     * Creates an array of the own enumerable string keyed property values of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property values.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.values(new Foo);
	     * // => [1, 2] (iteration order is not guaranteed)
	     *
	     * _.values('hi');
	     * // => ['h', 'i']
	     */
	    function values(object) {
	      return object ? baseValues(object, keys(object)) : [];
	    }
	
	    /**
	     * Creates an array of the own and inherited enumerable string keyed property
	     * values of `object`.
	     *
	     * **Note:** Non-object values are coerced to objects.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Object
	     * @param {Object} object The object to query.
	     * @returns {Array} Returns the array of property values.
	     * @example
	     *
	     * function Foo() {
	     *   this.a = 1;
	     *   this.b = 2;
	     * }
	     *
	     * Foo.prototype.c = 3;
	     *
	     * _.valuesIn(new Foo);
	     * // => [1, 2, 3] (iteration order is not guaranteed)
	     */
	    function valuesIn(object) {
	      return object == null ? [] : baseValues(object, keysIn(object));
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Clamps `number` within the inclusive `lower` and `upper` bounds.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Number
	     * @param {number} number The number to clamp.
	     * @param {number} [lower] The lower bound.
	     * @param {number} upper The upper bound.
	     * @returns {number} Returns the clamped number.
	     * @example
	     *
	     * _.clamp(-10, -5, 5);
	     * // => -5
	     *
	     * _.clamp(10, -5, 5);
	     * // => 5
	     */
	    function clamp(number, lower, upper) {
	      if (upper === undefined) {
	        upper = lower;
	        lower = undefined;
	      }
	      if (upper !== undefined) {
	        upper = toNumber(upper);
	        upper = upper === upper ? upper : 0;
	      }
	      if (lower !== undefined) {
	        lower = toNumber(lower);
	        lower = lower === lower ? lower : 0;
	      }
	      return baseClamp(toNumber(number), lower, upper);
	    }
	
	    /**
	     * Checks if `n` is between `start` and up to, but not including, `end`. If
	     * `end` is not specified, it's set to `start` with `start` then set to `0`.
	     * If `start` is greater than `end` the params are swapped to support
	     * negative ranges.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.3.0
	     * @category Number
	     * @param {number} number The number to check.
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @returns {boolean} Returns `true` if `number` is in the range, else `false`.
	     * @see _.range, _.rangeRight
	     * @example
	     *
	     * _.inRange(3, 2, 4);
	     * // => true
	     *
	     * _.inRange(4, 8);
	     * // => true
	     *
	     * _.inRange(4, 2);
	     * // => false
	     *
	     * _.inRange(2, 2);
	     * // => false
	     *
	     * _.inRange(1.2, 2);
	     * // => true
	     *
	     * _.inRange(5.2, 4);
	     * // => false
	     *
	     * _.inRange(-3, -2, -6);
	     * // => true
	     */
	    function inRange(number, start, end) {
	      start = toFinite(start);
	      if (end === undefined) {
	        end = start;
	        start = 0;
	      } else {
	        end = toFinite(end);
	      }
	      number = toNumber(number);
	      return baseInRange(number, start, end);
	    }
	
	    /**
	     * Produces a random number between the inclusive `lower` and `upper` bounds.
	     * If only one argument is provided a number between `0` and the given number
	     * is returned. If `floating` is `true`, or either `lower` or `upper` are
	     * floats, a floating-point number is returned instead of an integer.
	     *
	     * **Note:** JavaScript follows the IEEE-754 standard for resolving
	     * floating-point values which can produce unexpected results.
	     *
	     * @static
	     * @memberOf _
	     * @since 0.7.0
	     * @category Number
	     * @param {number} [lower=0] The lower bound.
	     * @param {number} [upper=1] The upper bound.
	     * @param {boolean} [floating] Specify returning a floating-point number.
	     * @returns {number} Returns the random number.
	     * @example
	     *
	     * _.random(0, 5);
	     * // => an integer between 0 and 5
	     *
	     * _.random(5);
	     * // => also an integer between 0 and 5
	     *
	     * _.random(5, true);
	     * // => a floating-point number between 0 and 5
	     *
	     * _.random(1.2, 5.2);
	     * // => a floating-point number between 1.2 and 5.2
	     */
	    function random(lower, upper, floating) {
	      if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) {
	        upper = floating = undefined;
	      }
	      if (floating === undefined) {
	        if (typeof upper == 'boolean') {
	          floating = upper;
	          upper = undefined;
	        }
	        else if (typeof lower == 'boolean') {
	          floating = lower;
	          lower = undefined;
	        }
	      }
	      if (lower === undefined && upper === undefined) {
	        lower = 0;
	        upper = 1;
	      }
	      else {
	        lower = toFinite(lower);
	        if (upper === undefined) {
	          upper = lower;
	          lower = 0;
	        } else {
	          upper = toFinite(upper);
	        }
	      }
	      if (lower > upper) {
	        var temp = lower;
	        lower = upper;
	        upper = temp;
	      }
	      if (floating || lower % 1 || upper % 1) {
	        var rand = nativeRandom();
	        return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper);
	      }
	      return baseRandom(lower, upper);
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the camel cased string.
	     * @example
	     *
	     * _.camelCase('Foo Bar');
	     * // => 'fooBar'
	     *
	     * _.camelCase('--foo-bar--');
	     * // => 'fooBar'
	     *
	     * _.camelCase('__FOO_BAR__');
	     * // => 'fooBar'
	     */
	    var camelCase = createCompounder(function(result, word, index) {
	      word = word.toLowerCase();
	      return result + (index ? capitalize(word) : word);
	    });
	
	    /**
	     * Converts the first character of `string` to upper case and the remaining
	     * to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to capitalize.
	     * @returns {string} Returns the capitalized string.
	     * @example
	     *
	     * _.capitalize('FRED');
	     * // => 'Fred'
	     */
	    function capitalize(string) {
	      return upperFirst(toString(string).toLowerCase());
	    }
	
	    /**
	     * Deburrs `string` by converting
	     * [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
	     * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
	     * letters to basic Latin letters and removing
	     * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to deburr.
	     * @returns {string} Returns the deburred string.
	     * @example
	     *
	     * _.deburr('déjà vu');
	     * // => 'deja vu'
	     */
	    function deburr(string) {
	      string = toString(string);
	      return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
	    }
	
	    /**
	     * Checks if `string` ends with the given target string.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {string} [target] The string to search for.
	     * @param {number} [position=string.length] The position to search up to.
	     * @returns {boolean} Returns `true` if `string` ends with `target`,
	     *  else `false`.
	     * @example
	     *
	     * _.endsWith('abc', 'c');
	     * // => true
	     *
	     * _.endsWith('abc', 'b');
	     * // => false
	     *
	     * _.endsWith('abc', 'b', 2);
	     * // => true
	     */
	    function endsWith(string, target, position) {
	      string = toString(string);
	      target = baseToString(target);
	
	      var length = string.length;
	      position = position === undefined
	        ? length
	        : baseClamp(toInteger(position), 0, length);
	
	      var end = position;
	      position -= target.length;
	      return position >= 0 && string.slice(position, end) == target;
	    }
	
	    /**
	     * Converts the characters "&", "<", ">", '"', and "'" in `string` to their
	     * corresponding HTML entities.
	     *
	     * **Note:** No other characters are escaped. To escape additional
	     * characters use a third-party library like [_he_](https://mths.be/he).
	     *
	     * Though the ">" character is escaped for symmetry, characters like
	     * ">" and "/" don't need escaping in HTML and have no special meaning
	     * unless they're part of a tag or unquoted attribute value. See
	     * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
	     * (under "semi-related fun fact") for more details.
	     *
	     * When working with HTML you should always
	     * [quote attribute values](http://wonko.com/post/html-escaping) to reduce
	     * XSS vectors.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category String
	     * @param {string} [string=''] The string to escape.
	     * @returns {string} Returns the escaped string.
	     * @example
	     *
	     * _.escape('fred, barney, & pebbles');
	     * // => 'fred, barney, &amp; pebbles'
	     */
	    function escape(string) {
	      string = toString(string);
	      return (string && reHasUnescapedHtml.test(string))
	        ? string.replace(reUnescapedHtml, escapeHtmlChar)
	        : string;
	    }
	
	    /**
	     * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
	     * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to escape.
	     * @returns {string} Returns the escaped string.
	     * @example
	     *
	     * _.escapeRegExp('[lodash](https://lodash.com/)');
	     * // => '\[lodash\]\(https://lodash\.com/\)'
	     */
	    function escapeRegExp(string) {
	      string = toString(string);
	      return (string && reHasRegExpChar.test(string))
	        ? string.replace(reRegExpChar, '\\$&')
	        : string;
	    }
	
	    /**
	     * Converts `string` to
	     * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the kebab cased string.
	     * @example
	     *
	     * _.kebabCase('Foo Bar');
	     * // => 'foo-bar'
	     *
	     * _.kebabCase('fooBar');
	     * // => 'foo-bar'
	     *
	     * _.kebabCase('__FOO_BAR__');
	     * // => 'foo-bar'
	     */
	    var kebabCase = createCompounder(function(result, word, index) {
	      return result + (index ? '-' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Converts `string`, as space separated words, to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the lower cased string.
	     * @example
	     *
	     * _.lowerCase('--Foo-Bar--');
	     * // => 'foo bar'
	     *
	     * _.lowerCase('fooBar');
	     * // => 'foo bar'
	     *
	     * _.lowerCase('__FOO_BAR__');
	     * // => 'foo bar'
	     */
	    var lowerCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Converts the first character of `string` to lower case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the converted string.
	     * @example
	     *
	     * _.lowerFirst('Fred');
	     * // => 'fred'
	     *
	     * _.lowerFirst('FRED');
	     * // => 'fRED'
	     */
	    var lowerFirst = createCaseFirst('toLowerCase');
	
	    /**
	     * Pads `string` on the left and right sides if it's shorter than `length`.
	     * Padding characters are truncated if they can't be evenly divided by `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.pad('abc', 8);
	     * // => '  abc   '
	     *
	     * _.pad('abc', 8, '_-');
	     * // => '_-abc_-_'
	     *
	     * _.pad('abc', 3);
	     * // => 'abc'
	     */
	    function pad(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      if (!length || strLength >= length) {
	        return string;
	      }
	      var mid = (length - strLength) / 2;
	      return (
	        createPadding(nativeFloor(mid), chars) +
	        string +
	        createPadding(nativeCeil(mid), chars)
	      );
	    }
	
	    /**
	     * Pads `string` on the right side if it's shorter than `length`. Padding
	     * characters are truncated if they exceed `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.padEnd('abc', 6);
	     * // => 'abc   '
	     *
	     * _.padEnd('abc', 6, '_-');
	     * // => 'abc_-_'
	     *
	     * _.padEnd('abc', 3);
	     * // => 'abc'
	     */
	    function padEnd(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      return (length && strLength < length)
	        ? (string + createPadding(length - strLength, chars))
	        : string;
	    }
	
	    /**
	     * Pads `string` on the left side if it's shorter than `length`. Padding
	     * characters are truncated if they exceed `length`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to pad.
	     * @param {number} [length=0] The padding length.
	     * @param {string} [chars=' '] The string used as padding.
	     * @returns {string} Returns the padded string.
	     * @example
	     *
	     * _.padStart('abc', 6);
	     * // => '   abc'
	     *
	     * _.padStart('abc', 6, '_-');
	     * // => '_-_abc'
	     *
	     * _.padStart('abc', 3);
	     * // => 'abc'
	     */
	    function padStart(string, length, chars) {
	      string = toString(string);
	      length = toInteger(length);
	
	      var strLength = length ? stringSize(string) : 0;
	      return (length && strLength < length)
	        ? (createPadding(length - strLength, chars) + string)
	        : string;
	    }
	
	    /**
	     * Converts `string` to an integer of the specified radix. If `radix` is
	     * `undefined` or `0`, a `radix` of `10` is used unless `value` is a
	     * hexadecimal, in which case a `radix` of `16` is used.
	     *
	     * **Note:** This method aligns with the
	     * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
	     *
	     * @static
	     * @memberOf _
	     * @since 1.1.0
	     * @category String
	     * @param {string} string The string to convert.
	     * @param {number} [radix=10] The radix to interpret `value` by.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {number} Returns the converted integer.
	     * @example
	     *
	     * _.parseInt('08');
	     * // => 8
	     *
	     * _.map(['6', '08', '10'], _.parseInt);
	     * // => [6, 8, 10]
	     */
	    function parseInt(string, radix, guard) {
	      if (guard || radix == null) {
	        radix = 0;
	      } else if (radix) {
	        radix = +radix;
	      }
	      return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0);
	    }
	
	    /**
	     * Repeats the given string `n` times.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to repeat.
	     * @param {number} [n=1] The number of times to repeat the string.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the repeated string.
	     * @example
	     *
	     * _.repeat('*', 3);
	     * // => '***'
	     *
	     * _.repeat('abc', 2);
	     * // => 'abcabc'
	     *
	     * _.repeat('abc', 0);
	     * // => ''
	     */
	    function repeat(string, n, guard) {
	      if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) {
	        n = 1;
	      } else {
	        n = toInteger(n);
	      }
	      return baseRepeat(toString(string), n);
	    }
	
	    /**
	     * Replaces matches for `pattern` in `string` with `replacement`.
	     *
	     * **Note:** This method is based on
	     * [`String#replace`](https://mdn.io/String/replace).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to modify.
	     * @param {RegExp|string} pattern The pattern to replace.
	     * @param {Function|string} replacement The match replacement.
	     * @returns {string} Returns the modified string.
	     * @example
	     *
	     * _.replace('Hi Fred', 'Fred', 'Barney');
	     * // => 'Hi Barney'
	     */
	    function replace() {
	      var args = arguments,
	          string = toString(args[0]);
	
	      return args.length < 3 ? string : string.replace(args[1], args[2]);
	    }
	
	    /**
	     * Converts `string` to
	     * [snake case](https://en.wikipedia.org/wiki/Snake_case).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the snake cased string.
	     * @example
	     *
	     * _.snakeCase('Foo Bar');
	     * // => 'foo_bar'
	     *
	     * _.snakeCase('fooBar');
	     * // => 'foo_bar'
	     *
	     * _.snakeCase('--FOO-BAR--');
	     * // => 'foo_bar'
	     */
	    var snakeCase = createCompounder(function(result, word, index) {
	      return result + (index ? '_' : '') + word.toLowerCase();
	    });
	
	    /**
	     * Splits `string` by `separator`.
	     *
	     * **Note:** This method is based on
	     * [`String#split`](https://mdn.io/String/split).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to split.
	     * @param {RegExp|string} separator The separator pattern to split by.
	     * @param {number} [limit] The length to truncate results to.
	     * @returns {Array} Returns the string segments.
	     * @example
	     *
	     * _.split('a-b-c', '-', 2);
	     * // => ['a', 'b']
	     */
	    function split(string, separator, limit) {
	      if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) {
	        separator = limit = undefined;
	      }
	      limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0;
	      if (!limit) {
	        return [];
	      }
	      string = toString(string);
	      if (string && (
	            typeof separator == 'string' ||
	            (separator != null && !isRegExp(separator))
	          )) {
	        separator = baseToString(separator);
	        if (!separator && hasUnicode(string)) {
	          return castSlice(stringToArray(string), 0, limit);
	        }
	      }
	      return string.split(separator, limit);
	    }
	
	    /**
	     * Converts `string` to
	     * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
	     *
	     * @static
	     * @memberOf _
	     * @since 3.1.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the start cased string.
	     * @example
	     *
	     * _.startCase('--foo-bar--');
	     * // => 'Foo Bar'
	     *
	     * _.startCase('fooBar');
	     * // => 'Foo Bar'
	     *
	     * _.startCase('__FOO_BAR__');
	     * // => 'FOO BAR'
	     */
	    var startCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + upperFirst(word);
	    });
	
	    /**
	     * Checks if `string` starts with the given target string.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {string} [target] The string to search for.
	     * @param {number} [position=0] The position to search from.
	     * @returns {boolean} Returns `true` if `string` starts with `target`,
	     *  else `false`.
	     * @example
	     *
	     * _.startsWith('abc', 'a');
	     * // => true
	     *
	     * _.startsWith('abc', 'b');
	     * // => false
	     *
	     * _.startsWith('abc', 'b', 1);
	     * // => true
	     */
	    function startsWith(string, target, position) {
	      string = toString(string);
	      position = baseClamp(toInteger(position), 0, string.length);
	      target = baseToString(target);
	      return string.slice(position, position + target.length) == target;
	    }
	
	    /**
	     * Creates a compiled template function that can interpolate data properties
	     * in "interpolate" delimiters, HTML-escape interpolated data properties in
	     * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data
	     * properties may be accessed as free variables in the template. If a setting
	     * object is given, it takes precedence over `_.templateSettings` values.
	     *
	     * **Note:** In the development build `_.template` utilizes
	     * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
	     * for easier debugging.
	     *
	     * For more information on precompiling templates see
	     * [lodash's custom builds documentation](https://lodash.com/custom-builds).
	     *
	     * For more information on Chrome extension sandboxes see
	     * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category String
	     * @param {string} [string=''] The template string.
	     * @param {Object} [options={}] The options object.
	     * @param {RegExp} [options.escape=_.templateSettings.escape]
	     *  The HTML "escape" delimiter.
	     * @param {RegExp} [options.evaluate=_.templateSettings.evaluate]
	     *  The "evaluate" delimiter.
	     * @param {Object} [options.imports=_.templateSettings.imports]
	     *  An object to import into the template as free variables.
	     * @param {RegExp} [options.interpolate=_.templateSettings.interpolate]
	     *  The "interpolate" delimiter.
	     * @param {string} [options.sourceURL='lodash.templateSources[n]']
	     *  The sourceURL of the compiled template.
	     * @param {string} [options.variable='obj']
	     *  The data object variable name.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Function} Returns the compiled template function.
	     * @example
	     *
	     * // Use the "interpolate" delimiter to create a compiled template.
	     * var compiled = _.template('hello <%= user %>!');
	     * compiled({ 'user': 'fred' });
	     * // => 'hello fred!'
	     *
	     * // Use the HTML "escape" delimiter to escape data property values.
	     * var compiled = _.template('<b><%- value %></b>');
	     * compiled({ 'value': '<script>' });
	     * // => '<b>&lt;script&gt;</b>'
	     *
	     * // Use the "evaluate" delimiter to execute JavaScript and generate HTML.
	     * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
	     * compiled({ 'users': ['fred', 'barney'] });
	     * // => '<li>fred</li><li>barney</li>'
	     *
	     * // Use the internal `print` function in "evaluate" delimiters.
	     * var compiled = _.template('<% print("hello " + user); %>!');
	     * compiled({ 'user': 'barney' });
	     * // => 'hello barney!'
	     *
	     * // Use the ES template literal delimiter as an "interpolate" delimiter.
	     * // Disable support by replacing the "interpolate" delimiter.
	     * var compiled = _.template('hello ${ user }!');
	     * compiled({ 'user': 'pebbles' });
	     * // => 'hello pebbles!'
	     *
	     * // Use backslashes to treat delimiters as plain text.
	     * var compiled = _.template('<%= "\\<%- value %\\>" %>');
	     * compiled({ 'value': 'ignored' });
	     * // => '<%- value %>'
	     *
	     * // Use the `imports` option to import `jQuery` as `jq`.
	     * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
	     * var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
	     * compiled({ 'users': ['fred', 'barney'] });
	     * // => '<li>fred</li><li>barney</li>'
	     *
	     * // Use the `sourceURL` option to specify a custom sourceURL for the template.
	     * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
	     * compiled(data);
	     * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
	     *
	     * // Use the `variable` option to ensure a with-statement isn't used in the compiled template.
	     * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
	     * compiled.source;
	     * // => function(data) {
	     * //   var __t, __p = '';
	     * //   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
	     * //   return __p;
	     * // }
	     *
	     * // Use custom template delimiters.
	     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
	     * var compiled = _.template('hello {{ user }}!');
	     * compiled({ 'user': 'mustache' });
	     * // => 'hello mustache!'
	     *
	     * // Use the `source` property to inline compiled templates for meaningful
	     * // line numbers in error messages and stack traces.
	     * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
	     *   var JST = {\
	     *     "main": ' + _.template(mainText).source + '\
	     *   };\
	     * ');
	     */
	    function template(string, options, guard) {
	      // Based on John Resig's `tmpl` implementation
	      // (http://ejohn.org/blog/javascript-micro-templating/)
	      // and Laura Doktorova's doT.js (https://github.com/olado/doT).
	      var settings = lodash.templateSettings;
	
	      if (guard && isIterateeCall(string, options, guard)) {
	        options = undefined;
	      }
	      string = toString(string);
	      options = assignInWith({}, options, settings, assignInDefaults);
	
	      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
	          importsKeys = keys(imports),
	          importsValues = baseValues(imports, importsKeys);
	
	      var isEscaping,
	          isEvaluating,
	          index = 0,
	          interpolate = options.interpolate || reNoMatch,
	          source = "__p += '";
	
	      // Compile the regexp to match each delimiter.
	      var reDelimiters = RegExp(
	        (options.escape || reNoMatch).source + '|' +
	        interpolate.source + '|' +
	        (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
	        (options.evaluate || reNoMatch).source + '|$'
	      , 'g');
	
	      // Use a sourceURL for easier debugging.
	      var sourceURL = '//# sourceURL=' +
	        ('sourceURL' in options
	          ? options.sourceURL
	          : ('lodash.templateSources[' + (++templateCounter) + ']')
	        ) + '\n';
	
	      string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
	        interpolateValue || (interpolateValue = esTemplateValue);
	
	        // Escape characters that can't be included in string literals.
	        source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar);
	
	        // Replace delimiters with snippets.
	        if (escapeValue) {
	          isEscaping = true;
	          source += "' +\n__e(" + escapeValue + ") +\n'";
	        }
	        if (evaluateValue) {
	          isEvaluating = true;
	          source += "';\n" + evaluateValue + ";\n__p += '";
	        }
	        if (interpolateValue) {
	          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
	        }
	        index = offset + match.length;
	
	        // The JS engine embedded in Adobe products needs `match` returned in
	        // order to produce the correct `offset` value.
	        return match;
	      });
	
	      source += "';\n";
	
	      // If `variable` is not specified wrap a with-statement around the generated
	      // code to add the data object to the top of the scope chain.
	      var variable = options.variable;
	      if (!variable) {
	        source = 'with (obj) {\n' + source + '\n}\n';
	      }
	      // Cleanup code by stripping empty strings.
	      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
	        .replace(reEmptyStringMiddle, '$1')
	        .replace(reEmptyStringTrailing, '$1;');
	
	      // Frame code as the function body.
	      source = 'function(' + (variable || 'obj') + ') {\n' +
	        (variable
	          ? ''
	          : 'obj || (obj = {});\n'
	        ) +
	        "var __t, __p = ''" +
	        (isEscaping
	           ? ', __e = _.escape'
	           : ''
	        ) +
	        (isEvaluating
	          ? ', __j = Array.prototype.join;\n' +
	            "function print() { __p += __j.call(arguments, '') }\n"
	          : ';\n'
	        ) +
	        source +
	        'return __p\n}';
	
	      var result = attempt(function() {
	        return Function(importsKeys, sourceURL + 'return ' + source)
	          .apply(undefined, importsValues);
	      });
	
	      // Provide the compiled function's source by its `toString` method or
	      // the `source` property as a convenience for inlining compiled templates.
	      result.source = source;
	      if (isError(result)) {
	        throw result;
	      }
	      return result;
	    }
	
	    /**
	     * Converts `string`, as a whole, to lower case just like
	     * [String#toLowerCase](https://mdn.io/toLowerCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the lower cased string.
	     * @example
	     *
	     * _.toLower('--Foo-Bar--');
	     * // => '--foo-bar--'
	     *
	     * _.toLower('fooBar');
	     * // => 'foobar'
	     *
	     * _.toLower('__FOO_BAR__');
	     * // => '__foo_bar__'
	     */
	    function toLower(value) {
	      return toString(value).toLowerCase();
	    }
	
	    /**
	     * Converts `string`, as a whole, to upper case just like
	     * [String#toUpperCase](https://mdn.io/toUpperCase).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the upper cased string.
	     * @example
	     *
	     * _.toUpper('--foo-bar--');
	     * // => '--FOO-BAR--'
	     *
	     * _.toUpper('fooBar');
	     * // => 'FOOBAR'
	     *
	     * _.toUpper('__foo_bar__');
	     * // => '__FOO_BAR__'
	     */
	    function toUpper(value) {
	      return toString(value).toUpperCase();
	    }
	
	    /**
	     * Removes leading and trailing whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trim('  abc  ');
	     * // => 'abc'
	     *
	     * _.trim('-_-abc-_-', '_-');
	     * // => 'abc'
	     *
	     * _.map(['  foo  ', '  bar  '], _.trim);
	     * // => ['foo', 'bar']
	     */
	    function trim(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrim, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          chrSymbols = stringToArray(chars),
	          start = charsStartIndex(strSymbols, chrSymbols),
	          end = charsEndIndex(strSymbols, chrSymbols) + 1;
	
	      return castSlice(strSymbols, start, end).join('');
	    }
	
	    /**
	     * Removes trailing whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trimEnd('  abc  ');
	     * // => '  abc'
	     *
	     * _.trimEnd('-_-abc-_-', '_-');
	     * // => '-_-abc'
	     */
	    function trimEnd(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrimEnd, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          end = charsEndIndex(strSymbols, stringToArray(chars)) + 1;
	
	      return castSlice(strSymbols, 0, end).join('');
	    }
	
	    /**
	     * Removes leading whitespace or specified characters from `string`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to trim.
	     * @param {string} [chars=whitespace] The characters to trim.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {string} Returns the trimmed string.
	     * @example
	     *
	     * _.trimStart('  abc  ');
	     * // => 'abc  '
	     *
	     * _.trimStart('-_-abc-_-', '_-');
	     * // => 'abc-_-'
	     */
	    function trimStart(string, chars, guard) {
	      string = toString(string);
	      if (string && (guard || chars === undefined)) {
	        return string.replace(reTrimStart, '');
	      }
	      if (!string || !(chars = baseToString(chars))) {
	        return string;
	      }
	      var strSymbols = stringToArray(string),
	          start = charsStartIndex(strSymbols, stringToArray(chars));
	
	      return castSlice(strSymbols, start).join('');
	    }
	
	    /**
	     * Truncates `string` if it's longer than the given maximum string length.
	     * The last characters of the truncated string are replaced with the omission
	     * string which defaults to "...".
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to truncate.
	     * @param {Object} [options={}] The options object.
	     * @param {number} [options.length=30] The maximum string length.
	     * @param {string} [options.omission='...'] The string to indicate text is omitted.
	     * @param {RegExp|string} [options.separator] The separator pattern to truncate to.
	     * @returns {string} Returns the truncated string.
	     * @example
	     *
	     * _.truncate('hi-diddly-ho there, neighborino');
	     * // => 'hi-diddly-ho there, neighbo...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'length': 24,
	     *   'separator': ' '
	     * });
	     * // => 'hi-diddly-ho there,...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'length': 24,
	     *   'separator': /,? +/
	     * });
	     * // => 'hi-diddly-ho there...'
	     *
	     * _.truncate('hi-diddly-ho there, neighborino', {
	     *   'omission': ' [...]'
	     * });
	     * // => 'hi-diddly-ho there, neig [...]'
	     */
	    function truncate(string, options) {
	      var length = DEFAULT_TRUNC_LENGTH,
	          omission = DEFAULT_TRUNC_OMISSION;
	
	      if (isObject(options)) {
	        var separator = 'separator' in options ? options.separator : separator;
	        length = 'length' in options ? toInteger(options.length) : length;
	        omission = 'omission' in options ? baseToString(options.omission) : omission;
	      }
	      string = toString(string);
	
	      var strLength = string.length;
	      if (hasUnicode(string)) {
	        var strSymbols = stringToArray(string);
	        strLength = strSymbols.length;
	      }
	      if (length >= strLength) {
	        return string;
	      }
	      var end = length - stringSize(omission);
	      if (end < 1) {
	        return omission;
	      }
	      var result = strSymbols
	        ? castSlice(strSymbols, 0, end).join('')
	        : string.slice(0, end);
	
	      if (separator === undefined) {
	        return result + omission;
	      }
	      if (strSymbols) {
	        end += (result.length - end);
	      }
	      if (isRegExp(separator)) {
	        if (string.slice(end).search(separator)) {
	          var match,
	              substring = result;
	
	          if (!separator.global) {
	            separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g');
	          }
	          separator.lastIndex = 0;
	          while ((match = separator.exec(substring))) {
	            var newEnd = match.index;
	          }
	          result = result.slice(0, newEnd === undefined ? end : newEnd);
	        }
	      } else if (string.indexOf(baseToString(separator), end) != end) {
	        var index = result.lastIndexOf(separator);
	        if (index > -1) {
	          result = result.slice(0, index);
	        }
	      }
	      return result + omission;
	    }
	
	    /**
	     * The inverse of `_.escape`; this method converts the HTML entities
	     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to
	     * their corresponding characters.
	     *
	     * **Note:** No other HTML entities are unescaped. To unescape additional
	     * HTML entities use a third-party library like [_he_](https://mths.be/he).
	     *
	     * @static
	     * @memberOf _
	     * @since 0.6.0
	     * @category String
	     * @param {string} [string=''] The string to unescape.
	     * @returns {string} Returns the unescaped string.
	     * @example
	     *
	     * _.unescape('fred, barney, &amp; pebbles');
	     * // => 'fred, barney, & pebbles'
	     */
	    function unescape(string) {
	      string = toString(string);
	      return (string && reHasEscapedHtml.test(string))
	        ? string.replace(reEscapedHtml, unescapeHtmlChar)
	        : string;
	    }
	
	    /**
	     * Converts `string`, as space separated words, to upper case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the upper cased string.
	     * @example
	     *
	     * _.upperCase('--foo-bar');
	     * // => 'FOO BAR'
	     *
	     * _.upperCase('fooBar');
	     * // => 'FOO BAR'
	     *
	     * _.upperCase('__foo_bar__');
	     * // => 'FOO BAR'
	     */
	    var upperCase = createCompounder(function(result, word, index) {
	      return result + (index ? ' ' : '') + word.toUpperCase();
	    });
	
	    /**
	     * Converts the first character of `string` to upper case.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category String
	     * @param {string} [string=''] The string to convert.
	     * @returns {string} Returns the converted string.
	     * @example
	     *
	     * _.upperFirst('fred');
	     * // => 'Fred'
	     *
	     * _.upperFirst('FRED');
	     * // => 'FRED'
	     */
	    var upperFirst = createCaseFirst('toUpperCase');
	
	    /**
	     * Splits `string` into an array of its words.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category String
	     * @param {string} [string=''] The string to inspect.
	     * @param {RegExp|string} [pattern] The pattern to match words.
	     * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
	     * @returns {Array} Returns the words of `string`.
	     * @example
	     *
	     * _.words('fred, barney, & pebbles');
	     * // => ['fred', 'barney', 'pebbles']
	     *
	     * _.words('fred, barney, & pebbles', /[^, ]+/g);
	     * // => ['fred', 'barney', '&', 'pebbles']
	     */
	    function words(string, pattern, guard) {
	      string = toString(string);
	      pattern = guard ? undefined : pattern;
	
	      if (pattern === undefined) {
	        return hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
	      }
	      return string.match(pattern) || [];
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Attempts to invoke `func`, returning either the result or the caught error
	     * object. Any additional arguments are provided to `func` when it's invoked.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Function} func The function to attempt.
	     * @param {...*} [args] The arguments to invoke `func` with.
	     * @returns {*} Returns the `func` result or error object.
	     * @example
	     *
	     * // Avoid throwing errors for invalid selectors.
	     * var elements = _.attempt(function(selector) {
	     *   return document.querySelectorAll(selector);
	     * }, '>_>');
	     *
	     * if (_.isError(elements)) {
	     *   elements = [];
	     * }
	     */
	    var attempt = baseRest(function(func, args) {
	      try {
	        return apply(func, undefined, args);
	      } catch (e) {
	        return isError(e) ? e : new Error(e);
	      }
	    });
	
	    /**
	     * Binds methods of an object to the object itself, overwriting the existing
	     * method.
	     *
	     * **Note:** This method doesn't set the "length" property of bound functions.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {Object} object The object to bind and assign the bound methods to.
	     * @param {...(string|string[])} methodNames The object method names to bind.
	     * @returns {Object} Returns `object`.
	     * @example
	     *
	     * var view = {
	     *   'label': 'docs',
	     *   'click': function() {
	     *     console.log('clicked ' + this.label);
	     *   }
	     * };
	     *
	     * _.bindAll(view, ['click']);
	     * jQuery(element).on('click', view.click);
	     * // => Logs 'clicked docs' when clicked.
	     */
	    var bindAll = flatRest(function(object, methodNames) {
	      arrayEach(methodNames, function(key) {
	        key = toKey(key);
	        baseAssignValue(object, key, bind(object[key], object));
	      });
	      return object;
	    });
	
	    /**
	     * Creates a function that iterates over `pairs` and invokes the corresponding
	     * function of the first predicate to return truthy. The predicate-function
	     * pairs are invoked with the `this` binding and arguments of the created
	     * function.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {Array} pairs The predicate-function pairs.
	     * @returns {Function} Returns the new composite function.
	     * @example
	     *
	     * var func = _.cond([
	     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
	     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
	     *   [_.stubTrue,                      _.constant('no match')]
	     * ]);
	     *
	     * func({ 'a': 1, 'b': 2 });
	     * // => 'matches A'
	     *
	     * func({ 'a': 0, 'b': 1 });
	     * // => 'matches B'
	     *
	     * func({ 'a': '1', 'b': '2' });
	     * // => 'no match'
	     */
	    function cond(pairs) {
	      var length = pairs ? pairs.length : 0,
	          toIteratee = getIteratee();
	
	      pairs = !length ? [] : arrayMap(pairs, function(pair) {
	        if (typeof pair[1] != 'function') {
	          throw new TypeError(FUNC_ERROR_TEXT);
	        }
	        return [toIteratee(pair[0]), pair[1]];
	      });
	
	      return baseRest(function(args) {
	        var index = -1;
	        while (++index < length) {
	          var pair = pairs[index];
	          if (apply(pair[0], this, args)) {
	            return apply(pair[1], this, args);
	          }
	        }
	      });
	    }
	
	    /**
	     * Creates a function that invokes the predicate properties of `source` with
	     * the corresponding property values of a given object, returning `true` if
	     * all predicates return truthy, else `false`.
	     *
	     * **Note:** The created function is equivalent to `_.conformsTo` with
	     * `source` partially applied.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {Object} source The object of property predicates to conform to.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 2, 'b': 1 },
	     *   { 'a': 1, 'b': 2 }
	     * ];
	     *
	     * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } }));
	     * // => [{ 'a': 1, 'b': 2 }]
	     */
	    function conforms(source) {
	      return baseConforms(baseClone(source, true));
	    }
	
	    /**
	     * Creates a function that returns `value`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Util
	     * @param {*} value The value to return from the new function.
	     * @returns {Function} Returns the new constant function.
	     * @example
	     *
	     * var objects = _.times(2, _.constant({ 'a': 1 }));
	     *
	     * console.log(objects);
	     * // => [{ 'a': 1 }, { 'a': 1 }]
	     *
	     * console.log(objects[0] === objects[1]);
	     * // => true
	     */
	    function constant(value) {
	      return function() {
	        return value;
	      };
	    }
	
	    /**
	     * Checks `value` to determine whether a default value should be returned in
	     * its place. The `defaultValue` is returned if `value` is `NaN`, `null`,
	     * or `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.14.0
	     * @category Util
	     * @param {*} value The value to check.
	     * @param {*} defaultValue The default value.
	     * @returns {*} Returns the resolved value.
	     * @example
	     *
	     * _.defaultTo(1, 10);
	     * // => 1
	     *
	     * _.defaultTo(undefined, 10);
	     * // => 10
	     */
	    function defaultTo(value, defaultValue) {
	      return (value == null || value !== value) ? defaultValue : value;
	    }
	
	    /**
	     * Creates a function that returns the result of invoking the given functions
	     * with the `this` binding of the created function, where each successive
	     * invocation is supplied the return value of the previous.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [funcs] The functions to invoke.
	     * @returns {Function} Returns the new composite function.
	     * @see _.flowRight
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var addSquare = _.flow([_.add, square]);
	     * addSquare(1, 2);
	     * // => 9
	     */
	    var flow = createFlow();
	
	    /**
	     * This method is like `_.flow` except that it creates a function that
	     * invokes the given functions from right to left.
	     *
	     * @static
	     * @since 3.0.0
	     * @memberOf _
	     * @category Util
	     * @param {...(Function|Function[])} [funcs] The functions to invoke.
	     * @returns {Function} Returns the new composite function.
	     * @see _.flow
	     * @example
	     *
	     * function square(n) {
	     *   return n * n;
	     * }
	     *
	     * var addSquare = _.flowRight([square, _.add]);
	     * addSquare(1, 2);
	     * // => 9
	     */
	    var flowRight = createFlow(true);
	
	    /**
	     * This method returns the first argument it receives.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {*} value Any value.
	     * @returns {*} Returns `value`.
	     * @example
	     *
	     * var object = { 'a': 1 };
	     *
	     * console.log(_.identity(object) === object);
	     * // => true
	     */
	    function identity(value) {
	      return value;
	    }
	
	    /**
	     * Creates a function that invokes `func` with the arguments of the created
	     * function. If `func` is a property name, the created function returns the
	     * property value for a given element. If `func` is an array or object, the
	     * created function returns `true` for elements that contain the equivalent
	     * source properties, otherwise it returns `false`.
	     *
	     * @static
	     * @since 4.0.0
	     * @memberOf _
	     * @category Util
	     * @param {*} [func=_.identity] The value to convert to a callback.
	     * @returns {Function} Returns the callback.
	     * @example
	     *
	     * var users = [
	     *   { 'user': 'barney', 'age': 36, 'active': true },
	     *   { 'user': 'fred',   'age': 40, 'active': false }
	     * ];
	     *
	     * // The `_.matches` iteratee shorthand.
	     * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
	     * // => [{ 'user': 'barney', 'age': 36, 'active': true }]
	     *
	     * // The `_.matchesProperty` iteratee shorthand.
	     * _.filter(users, _.iteratee(['user', 'fred']));
	     * // => [{ 'user': 'fred', 'age': 40 }]
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.map(users, _.iteratee('user'));
	     * // => ['barney', 'fred']
	     *
	     * // Create custom iteratee shorthands.
	     * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) {
	     *   return !_.isRegExp(func) ? iteratee(func) : function(string) {
	     *     return func.test(string);
	     *   };
	     * });
	     *
	     * _.filter(['abc', 'def'], /ef/);
	     * // => ['def']
	     */
	    function iteratee(func) {
	      return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));
	    }
	
	    /**
	     * Creates a function that performs a partial deep comparison between a given
	     * object and `source`, returning `true` if the given object has equivalent
	     * property values, else `false`.
	     *
	     * **Note:** The created function is equivalent to `_.isMatch` with `source`
	     * partially applied.
	     *
	     * Partial comparisons will match empty array and empty object `source`
	     * values against any array or object value, respectively. See `_.isEqual`
	     * for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Object} source The object of property values to match.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 1, 'b': 2, 'c': 3 },
	     *   { 'a': 4, 'b': 5, 'c': 6 }
	     * ];
	     *
	     * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
	     * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
	     */
	    function matches(source) {
	      return baseMatches(baseClone(source, true));
	    }
	
	    /**
	     * Creates a function that performs a partial deep comparison between the
	     * value at `path` of a given object to `srcValue`, returning `true` if the
	     * object value is equivalent, else `false`.
	     *
	     * **Note:** Partial comparisons will match empty array and empty object
	     * `srcValue` values against any array or object value, respectively. See
	     * `_.isEqual` for a list of supported value comparisons.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.2.0
	     * @category Util
	     * @param {Array|string} path The path of the property to get.
	     * @param {*} srcValue The value to match.
	     * @returns {Function} Returns the new spec function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': 1, 'b': 2, 'c': 3 },
	     *   { 'a': 4, 'b': 5, 'c': 6 }
	     * ];
	     *
	     * _.find(objects, _.matchesProperty('a', 4));
	     * // => { 'a': 4, 'b': 5, 'c': 6 }
	     */
	    function matchesProperty(path, srcValue) {
	      return baseMatchesProperty(path, baseClone(srcValue, true));
	    }
	
	    /**
	     * Creates a function that invokes the method at `path` of a given object.
	     * Any additional arguments are provided to the invoked method.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Util
	     * @param {Array|string} path The path of the method to invoke.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {Function} Returns the new invoker function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': { 'b': _.constant(2) } },
	     *   { 'a': { 'b': _.constant(1) } }
	     * ];
	     *
	     * _.map(objects, _.method('a.b'));
	     * // => [2, 1]
	     *
	     * _.map(objects, _.method(['a', 'b']));
	     * // => [2, 1]
	     */
	    var method = baseRest(function(path, args) {
	      return function(object) {
	        return baseInvoke(object, path, args);
	      };
	    });
	
	    /**
	     * The opposite of `_.method`; this method creates a function that invokes
	     * the method at a given path of `object`. Any additional arguments are
	     * provided to the invoked method.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.7.0
	     * @category Util
	     * @param {Object} object The object to query.
	     * @param {...*} [args] The arguments to invoke the method with.
	     * @returns {Function} Returns the new invoker function.
	     * @example
	     *
	     * var array = _.times(3, _.constant),
	     *     object = { 'a': array, 'b': array, 'c': array };
	     *
	     * _.map(['a[2]', 'c[0]'], _.methodOf(object));
	     * // => [2, 0]
	     *
	     * _.map([['a', '2'], ['c', '0']], _.methodOf(object));
	     * // => [2, 0]
	     */
	    var methodOf = baseRest(function(object, args) {
	      return function(path) {
	        return baseInvoke(object, path, args);
	      };
	    });
	
	    /**
	     * Adds all own enumerable string keyed function properties of a source
	     * object to the destination object. If `object` is a function, then methods
	     * are added to its prototype as well.
	     *
	     * **Note:** Use `_.runInContext` to create a pristine `lodash` function to
	     * avoid conflicts caused by modifying the original.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {Function|Object} [object=lodash] The destination object.
	     * @param {Object} source The object of functions to add.
	     * @param {Object} [options={}] The options object.
	     * @param {boolean} [options.chain=true] Specify whether mixins are chainable.
	     * @returns {Function|Object} Returns `object`.
	     * @example
	     *
	     * function vowels(string) {
	     *   return _.filter(string, function(v) {
	     *     return /[aeiou]/i.test(v);
	     *   });
	     * }
	     *
	     * _.mixin({ 'vowels': vowels });
	     * _.vowels('fred');
	     * // => ['e']
	     *
	     * _('fred').vowels().value();
	     * // => ['e']
	     *
	     * _.mixin({ 'vowels': vowels }, { 'chain': false });
	     * _('fred').vowels();
	     * // => ['e']
	     */
	    function mixin(object, source, options) {
	      var props = keys(source),
	          methodNames = baseFunctions(source, props);
	
	      if (options == null &&
	          !(isObject(source) && (methodNames.length || !props.length))) {
	        options = source;
	        source = object;
	        object = this;
	        methodNames = baseFunctions(source, keys(source));
	      }
	      var chain = !(isObject(options) && 'chain' in options) || !!options.chain,
	          isFunc = isFunction(object);
	
	      arrayEach(methodNames, function(methodName) {
	        var func = source[methodName];
	        object[methodName] = func;
	        if (isFunc) {
	          object.prototype[methodName] = function() {
	            var chainAll = this.__chain__;
	            if (chain || chainAll) {
	              var result = object(this.__wrapped__),
	                  actions = result.__actions__ = copyArray(this.__actions__);
	
	              actions.push({ 'func': func, 'args': arguments, 'thisArg': object });
	              result.__chain__ = chainAll;
	              return result;
	            }
	            return func.apply(object, arrayPush([this.value()], arguments));
	          };
	        }
	      });
	
	      return object;
	    }
	
	    /**
	     * Reverts the `_` variable to its previous value and returns a reference to
	     * the `lodash` function.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @returns {Function} Returns the `lodash` function.
	     * @example
	     *
	     * var lodash = _.noConflict();
	     */
	    function noConflict() {
	      if (root._ === this) {
	        root._ = oldDash;
	      }
	      return this;
	    }
	
	    /**
	     * This method returns `undefined`.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.3.0
	     * @category Util
	     * @example
	     *
	     * _.times(2, _.noop);
	     * // => [undefined, undefined]
	     */
	    function noop() {
	      // No operation performed.
	    }
	
	    /**
	     * Creates a function that gets the argument at index `n`. If `n` is negative,
	     * the nth argument from the end is returned.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {number} [n=0] The index of the argument to return.
	     * @returns {Function} Returns the new pass-thru function.
	     * @example
	     *
	     * var func = _.nthArg(1);
	     * func('a', 'b', 'c', 'd');
	     * // => 'b'
	     *
	     * var func = _.nthArg(-2);
	     * func('a', 'b', 'c', 'd');
	     * // => 'c'
	     */
	    function nthArg(n) {
	      n = toInteger(n);
	      return baseRest(function(args) {
	        return baseNth(args, n);
	      });
	    }
	
	    /**
	     * Creates a function that invokes `iteratees` with the arguments it receives
	     * and returns their results.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [iteratees=[_.identity]]
	     *  The iteratees to invoke.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.over([Math.max, Math.min]);
	     *
	     * func(1, 2, 3, 4);
	     * // => [4, 1]
	     */
	    var over = createOver(arrayMap);
	
	    /**
	     * Creates a function that checks if **all** of the `predicates` return
	     * truthy when invoked with the arguments it receives.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [predicates=[_.identity]]
	     *  The predicates to check.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.overEvery([Boolean, isFinite]);
	     *
	     * func('1');
	     * // => true
	     *
	     * func(null);
	     * // => false
	     *
	     * func(NaN);
	     * // => false
	     */
	    var overEvery = createOver(arrayEvery);
	
	    /**
	     * Creates a function that checks if **any** of the `predicates` return
	     * truthy when invoked with the arguments it receives.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {...(Function|Function[])} [predicates=[_.identity]]
	     *  The predicates to check.
	     * @returns {Function} Returns the new function.
	     * @example
	     *
	     * var func = _.overSome([Boolean, isFinite]);
	     *
	     * func('1');
	     * // => true
	     *
	     * func(null);
	     * // => true
	     *
	     * func(NaN);
	     * // => false
	     */
	    var overSome = createOver(arraySome);
	
	    /**
	     * Creates a function that returns the value at `path` of a given object.
	     *
	     * @static
	     * @memberOf _
	     * @since 2.4.0
	     * @category Util
	     * @param {Array|string} path The path of the property to get.
	     * @returns {Function} Returns the new accessor function.
	     * @example
	     *
	     * var objects = [
	     *   { 'a': { 'b': 2 } },
	     *   { 'a': { 'b': 1 } }
	     * ];
	     *
	     * _.map(objects, _.property('a.b'));
	     * // => [2, 1]
	     *
	     * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
	     * // => [1, 2]
	     */
	    function property(path) {
	      return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
	    }
	
	    /**
	     * The opposite of `_.property`; this method creates a function that returns
	     * the value at a given path of `object`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.0.0
	     * @category Util
	     * @param {Object} object The object to query.
	     * @returns {Function} Returns the new accessor function.
	     * @example
	     *
	     * var array = [0, 1, 2],
	     *     object = { 'a': array, 'b': array, 'c': array };
	     *
	     * _.map(['a[2]', 'c[0]'], _.propertyOf(object));
	     * // => [2, 0]
	     *
	     * _.map([['a', '2'], ['c', '0']], _.propertyOf(object));
	     * // => [2, 0]
	     */
	    function propertyOf(object) {
	      return function(path) {
	        return object == null ? undefined : baseGet(object, path);
	      };
	    }
	
	    /**
	     * Creates an array of numbers (positive and/or negative) progressing from
	     * `start` up to, but not including, `end`. A step of `-1` is used if a negative
	     * `start` is specified without an `end` or `step`. If `end` is not specified,
	     * it's set to `start` with `start` then set to `0`.
	     *
	     * **Note:** JavaScript follows the IEEE-754 standard for resolving
	     * floating-point values which can produce unexpected results.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} [step=1] The value to increment or decrement by.
	     * @returns {Array} Returns the range of numbers.
	     * @see _.inRange, _.rangeRight
	     * @example
	     *
	     * _.range(4);
	     * // => [0, 1, 2, 3]
	     *
	     * _.range(-4);
	     * // => [0, -1, -2, -3]
	     *
	     * _.range(1, 5);
	     * // => [1, 2, 3, 4]
	     *
	     * _.range(0, 20, 5);
	     * // => [0, 5, 10, 15]
	     *
	     * _.range(0, -4, -1);
	     * // => [0, -1, -2, -3]
	     *
	     * _.range(1, 4, 0);
	     * // => [1, 1, 1]
	     *
	     * _.range(0);
	     * // => []
	     */
	    var range = createRange();
	
	    /**
	     * This method is like `_.range` except that it populates values in
	     * descending order.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {number} [start=0] The start of the range.
	     * @param {number} end The end of the range.
	     * @param {number} [step=1] The value to increment or decrement by.
	     * @returns {Array} Returns the range of numbers.
	     * @see _.inRange, _.range
	     * @example
	     *
	     * _.rangeRight(4);
	     * // => [3, 2, 1, 0]
	     *
	     * _.rangeRight(-4);
	     * // => [-3, -2, -1, 0]
	     *
	     * _.rangeRight(1, 5);
	     * // => [4, 3, 2, 1]
	     *
	     * _.rangeRight(0, 20, 5);
	     * // => [15, 10, 5, 0]
	     *
	     * _.rangeRight(0, -4, -1);
	     * // => [-3, -2, -1, 0]
	     *
	     * _.rangeRight(1, 4, 0);
	     * // => [1, 1, 1]
	     *
	     * _.rangeRight(0);
	     * // => []
	     */
	    var rangeRight = createRange(true);
	
	    /**
	     * This method returns a new empty array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {Array} Returns the new empty array.
	     * @example
	     *
	     * var arrays = _.times(2, _.stubArray);
	     *
	     * console.log(arrays);
	     * // => [[], []]
	     *
	     * console.log(arrays[0] === arrays[1]);
	     * // => false
	     */
	    function stubArray() {
	      return [];
	    }
	
	    /**
	     * This method returns `false`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {boolean} Returns `false`.
	     * @example
	     *
	     * _.times(2, _.stubFalse);
	     * // => [false, false]
	     */
	    function stubFalse() {
	      return false;
	    }
	
	    /**
	     * This method returns a new empty object.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {Object} Returns the new empty object.
	     * @example
	     *
	     * var objects = _.times(2, _.stubObject);
	     *
	     * console.log(objects);
	     * // => [{}, {}]
	     *
	     * console.log(objects[0] === objects[1]);
	     * // => false
	     */
	    function stubObject() {
	      return {};
	    }
	
	    /**
	     * This method returns an empty string.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {string} Returns the empty string.
	     * @example
	     *
	     * _.times(2, _.stubString);
	     * // => ['', '']
	     */
	    function stubString() {
	      return '';
	    }
	
	    /**
	     * This method returns `true`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.13.0
	     * @category Util
	     * @returns {boolean} Returns `true`.
	     * @example
	     *
	     * _.times(2, _.stubTrue);
	     * // => [true, true]
	     */
	    function stubTrue() {
	      return true;
	    }
	
	    /**
	     * Invokes the iteratee `n` times, returning an array of the results of
	     * each invocation. The iteratee is invoked with one argument; (index).
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {number} n The number of times to invoke `iteratee`.
	     * @param {Function} [iteratee=_.identity] The function invoked per iteration.
	     * @returns {Array} Returns the array of results.
	     * @example
	     *
	     * _.times(3, String);
	     * // => ['0', '1', '2']
	     *
	     *  _.times(4, _.constant(0));
	     * // => [0, 0, 0, 0]
	     */
	    function times(n, iteratee) {
	      n = toInteger(n);
	      if (n < 1 || n > MAX_SAFE_INTEGER) {
	        return [];
	      }
	      var index = MAX_ARRAY_LENGTH,
	          length = nativeMin(n, MAX_ARRAY_LENGTH);
	
	      iteratee = getIteratee(iteratee);
	      n -= MAX_ARRAY_LENGTH;
	
	      var result = baseTimes(length, iteratee);
	      while (++index < n) {
	        iteratee(index);
	      }
	      return result;
	    }
	
	    /**
	     * Converts `value` to a property path array.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Util
	     * @param {*} value The value to convert.
	     * @returns {Array} Returns the new property path array.
	     * @example
	     *
	     * _.toPath('a.b.c');
	     * // => ['a', 'b', 'c']
	     *
	     * _.toPath('a[0].b.c');
	     * // => ['a', '0', 'b', 'c']
	     */
	    function toPath(value) {
	      if (isArray(value)) {
	        return arrayMap(value, toKey);
	      }
	      return isSymbol(value) ? [value] : copyArray(stringToPath(value));
	    }
	
	    /**
	     * Generates a unique ID. If `prefix` is given, the ID is appended to it.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Util
	     * @param {string} [prefix=''] The value to prefix the ID with.
	     * @returns {string} Returns the unique ID.
	     * @example
	     *
	     * _.uniqueId('contact_');
	     * // => 'contact_104'
	     *
	     * _.uniqueId();
	     * // => '105'
	     */
	    function uniqueId(prefix) {
	      var id = ++idCounter;
	      return toString(prefix) + id;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * Adds two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.4.0
	     * @category Math
	     * @param {number} augend The first number in an addition.
	     * @param {number} addend The second number in an addition.
	     * @returns {number} Returns the total.
	     * @example
	     *
	     * _.add(6, 4);
	     * // => 10
	     */
	    var add = createMathOperation(function(augend, addend) {
	      return augend + addend;
	    }, 0);
	
	    /**
	     * Computes `number` rounded up to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round up.
	     * @param {number} [precision=0] The precision to round up to.
	     * @returns {number} Returns the rounded up number.
	     * @example
	     *
	     * _.ceil(4.006);
	     * // => 5
	     *
	     * _.ceil(6.004, 2);
	     * // => 6.01
	     *
	     * _.ceil(6040, -2);
	     * // => 6100
	     */
	    var ceil = createRound('ceil');
	
	    /**
	     * Divide two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {number} dividend The first number in a division.
	     * @param {number} divisor The second number in a division.
	     * @returns {number} Returns the quotient.
	     * @example
	     *
	     * _.divide(6, 4);
	     * // => 1.5
	     */
	    var divide = createMathOperation(function(dividend, divisor) {
	      return dividend / divisor;
	    }, 1);
	
	    /**
	     * Computes `number` rounded down to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round down.
	     * @param {number} [precision=0] The precision to round down to.
	     * @returns {number} Returns the rounded down number.
	     * @example
	     *
	     * _.floor(4.006);
	     * // => 4
	     *
	     * _.floor(0.046, 2);
	     * // => 0.04
	     *
	     * _.floor(4060, -2);
	     * // => 4000
	     */
	    var floor = createRound('floor');
	
	    /**
	     * Computes the maximum value of `array`. If `array` is empty or falsey,
	     * `undefined` is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {*} Returns the maximum value.
	     * @example
	     *
	     * _.max([4, 2, 8, 6]);
	     * // => 8
	     *
	     * _.max([]);
	     * // => undefined
	     */
	    function max(array) {
	      return (array && array.length)
	        ? baseExtremum(array, identity, baseGt)
	        : undefined;
	    }
	
	    /**
	     * This method is like `_.max` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * the value is ranked. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {*} Returns the maximum value.
	     * @example
	     *
	     * var objects = [{ 'n': 1 }, { 'n': 2 }];
	     *
	     * _.maxBy(objects, function(o) { return o.n; });
	     * // => { 'n': 2 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.maxBy(objects, 'n');
	     * // => { 'n': 2 }
	     */
	    function maxBy(array, iteratee) {
	      return (array && array.length)
	        ? baseExtremum(array, getIteratee(iteratee, 2), baseGt)
	        : undefined;
	    }
	
	    /**
	     * Computes the mean of the values in `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {number} Returns the mean.
	     * @example
	     *
	     * _.mean([4, 2, 8, 6]);
	     * // => 5
	     */
	    function mean(array) {
	      return baseMean(array, identity);
	    }
	
	    /**
	     * This method is like `_.mean` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the value to be averaged.
	     * The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the mean.
	     * @example
	     *
	     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
	     *
	     * _.meanBy(objects, function(o) { return o.n; });
	     * // => 5
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.meanBy(objects, 'n');
	     * // => 5
	     */
	    function meanBy(array, iteratee) {
	      return baseMean(array, getIteratee(iteratee, 2));
	    }
	
	    /**
	     * Computes the minimum value of `array`. If `array` is empty or falsey,
	     * `undefined` is returned.
	     *
	     * @static
	     * @since 0.1.0
	     * @memberOf _
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {*} Returns the minimum value.
	     * @example
	     *
	     * _.min([4, 2, 8, 6]);
	     * // => 2
	     *
	     * _.min([]);
	     * // => undefined
	     */
	    function min(array) {
	      return (array && array.length)
	        ? baseExtremum(array, identity, baseLt)
	        : undefined;
	    }
	
	    /**
	     * This method is like `_.min` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the criterion by which
	     * the value is ranked. The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {*} Returns the minimum value.
	     * @example
	     *
	     * var objects = [{ 'n': 1 }, { 'n': 2 }];
	     *
	     * _.minBy(objects, function(o) { return o.n; });
	     * // => { 'n': 1 }
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.minBy(objects, 'n');
	     * // => { 'n': 1 }
	     */
	    function minBy(array, iteratee) {
	      return (array && array.length)
	        ? baseExtremum(array, getIteratee(iteratee, 2), baseLt)
	        : undefined;
	    }
	
	    /**
	     * Multiply two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.7.0
	     * @category Math
	     * @param {number} multiplier The first number in a multiplication.
	     * @param {number} multiplicand The second number in a multiplication.
	     * @returns {number} Returns the product.
	     * @example
	     *
	     * _.multiply(6, 4);
	     * // => 24
	     */
	    var multiply = createMathOperation(function(multiplier, multiplicand) {
	      return multiplier * multiplicand;
	    }, 1);
	
	    /**
	     * Computes `number` rounded to `precision`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.10.0
	     * @category Math
	     * @param {number} number The number to round.
	     * @param {number} [precision=0] The precision to round to.
	     * @returns {number} Returns the rounded number.
	     * @example
	     *
	     * _.round(4.006);
	     * // => 4
	     *
	     * _.round(4.006, 2);
	     * // => 4.01
	     *
	     * _.round(4060, -2);
	     * // => 4100
	     */
	    var round = createRound('round');
	
	    /**
	     * Subtract two numbers.
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {number} minuend The first number in a subtraction.
	     * @param {number} subtrahend The second number in a subtraction.
	     * @returns {number} Returns the difference.
	     * @example
	     *
	     * _.subtract(6, 4);
	     * // => 2
	     */
	    var subtract = createMathOperation(function(minuend, subtrahend) {
	      return minuend - subtrahend;
	    }, 0);
	
	    /**
	     * Computes the sum of the values in `array`.
	     *
	     * @static
	     * @memberOf _
	     * @since 3.4.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @returns {number} Returns the sum.
	     * @example
	     *
	     * _.sum([4, 2, 8, 6]);
	     * // => 20
	     */
	    function sum(array) {
	      return (array && array.length)
	        ? baseSum(array, identity)
	        : 0;
	    }
	
	    /**
	     * This method is like `_.sum` except that it accepts `iteratee` which is
	     * invoked for each element in `array` to generate the value to be summed.
	     * The iteratee is invoked with one argument: (value).
	     *
	     * @static
	     * @memberOf _
	     * @since 4.0.0
	     * @category Math
	     * @param {Array} array The array to iterate over.
	     * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
	     * @returns {number} Returns the sum.
	     * @example
	     *
	     * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
	     *
	     * _.sumBy(objects, function(o) { return o.n; });
	     * // => 20
	     *
	     * // The `_.property` iteratee shorthand.
	     * _.sumBy(objects, 'n');
	     * // => 20
	     */
	    function sumBy(array, iteratee) {
	      return (array && array.length)
	        ? baseSum(array, getIteratee(iteratee, 2))
	        : 0;
	    }
	
	    /*------------------------------------------------------------------------*/
	
	    // Add methods that return wrapped values in chain sequences.
	    lodash.after = after;
	    lodash.ary = ary;
	    lodash.assign = assign;
	    lodash.assignIn = assignIn;
	    lodash.assignInWith = assignInWith;
	    lodash.assignWith = assignWith;
	    lodash.at = at;
	    lodash.before = before;
	    lodash.bind = bind;
	    lodash.bindAll = bindAll;
	    lodash.bindKey = bindKey;
	    lodash.castArray = castArray;
	    lodash.chain = chain;
	    lodash.chunk = chunk;
	    lodash.compact = compact;
	    lodash.concat = concat;
	    lodash.cond = cond;
	    lodash.conforms = conforms;
	    lodash.constant = constant;
	    lodash.countBy = countBy;
	    lodash.create = create;
	    lodash.curry = curry;
	    lodash.curryRight = curryRight;
	    lodash.debounce = debounce;
	    lodash.defaults = defaults;
	    lodash.defaultsDeep = defaultsDeep;
	    lodash.defer = defer;
	    lodash.delay = delay;
	    lodash.difference = difference;
	    lodash.differenceBy = differenceBy;
	    lodash.differenceWith = differenceWith;
	    lodash.drop = drop;
	    lodash.dropRight = dropRight;
	    lodash.dropRightWhile = dropRightWhile;
	    lodash.dropWhile = dropWhile;
	    lodash.fill = fill;
	    lodash.filter = filter;
	    lodash.flatMap = flatMap;
	    lodash.flatMapDeep = flatMapDeep;
	    lodash.flatMapDepth = flatMapDepth;
	    lodash.flatten = flatten;
	    lodash.flattenDeep = flattenDeep;
	    lodash.flattenDepth = flattenDepth;
	    lodash.flip = flip;
	    lodash.flow = flow;
	    lodash.flowRight = flowRight;
	    lodash.fromPairs = fromPairs;
	    lodash.functions = functions;
	    lodash.functionsIn = functionsIn;
	    lodash.groupBy = groupBy;
	    lodash.initial = initial;
	    lodash.intersection = intersection;
	    lodash.intersectionBy = intersectionBy;
	    lodash.intersectionWith = intersectionWith;
	    lodash.invert = invert;
	    lodash.invertBy = invertBy;
	    lodash.invokeMap = invokeMap;
	    lodash.iteratee = iteratee;
	    lodash.keyBy = keyBy;
	    lodash.keys = keys;
	    lodash.keysIn = keysIn;
	    lodash.map = map;
	    lodash.mapKeys = mapKeys;
	    lodash.mapValues = mapValues;
	    lodash.matches = matches;
	    lodash.matchesProperty = matchesProperty;
	    lodash.memoize = memoize;
	    lodash.merge = merge;
	    lodash.mergeWith = mergeWith;
	    lodash.method = method;
	    lodash.methodOf = methodOf;
	    lodash.mixin = mixin;
	    lodash.negate = negate;
	    lodash.nthArg = nthArg;
	    lodash.omit = omit;
	    lodash.omitBy = omitBy;
	    lodash.once = once;
	    lodash.orderBy = orderBy;
	    lodash.over = over;
	    lodash.overArgs = overArgs;
	    lodash.overEvery = overEvery;
	    lodash.overSome = overSome;
	    lodash.partial = partial;
	    lodash.partialRight = partialRight;
	    lodash.partition = partition;
	    lodash.pick = pick;
	    lodash.pickBy = pickBy;
	    lodash.property = property;
	    lodash.propertyOf = propertyOf;
	    lodash.pull = pull;
	    lodash.pullAll = pullAll;
	    lodash.pullAllBy = pullAllBy;
	    lodash.pullAllWith = pullAllWith;
	    lodash.pullAt = pullAt;
	    lodash.range = range;
	    lodash.rangeRight = rangeRight;
	    lodash.rearg = rearg;
	    lodash.reject = reject;
	    lodash.remove = remove;
	    lodash.rest = rest;
	    lodash.reverse = reverse;
	    lodash.sampleSize = sampleSize;
	    lodash.set = set;
	    lodash.setWith = setWith;
	    lodash.shuffle = shuffle;
	    lodash.slice = slice;
	    lodash.sortBy = sortBy;
	    lodash.sortedUniq = sortedUniq;
	    lodash.sortedUniqBy = sortedUniqBy;
	    lodash.split = split;
	    lodash.spread = spread;
	    lodash.tail = tail;
	    lodash.take = take;
	    lodash.takeRight = takeRight;
	    lodash.takeRightWhile = takeRightWhile;
	    lodash.takeWhile = takeWhile;
	    lodash.tap = tap;
	    lodash.throttle = throttle;
	    lodash.thru = thru;
	    lodash.toArray = toArray;
	    lodash.toPairs = toPairs;
	    lodash.toPairsIn = toPairsIn;
	    lodash.toPath = toPath;
	    lodash.toPlainObject = toPlainObject;
	    lodash.transform = transform;
	    lodash.unary = unary;
	    lodash.union = union;
	    lodash.unionBy = unionBy;
	    lodash.unionWith = unionWith;
	    lodash.uniq = uniq;
	    lodash.uniqBy = uniqBy;
	    lodash.uniqWith = uniqWith;
	    lodash.unset = unset;
	    lodash.unzip = unzip;
	    lodash.unzipWith = unzipWith;
	    lodash.update = update;
	    lodash.updateWith = updateWith;
	    lodash.values = values;
	    lodash.valuesIn = valuesIn;
	    lodash.without = without;
	    lodash.words = words;
	    lodash.wrap = wrap;
	    lodash.xor = xor;
	    lodash.xorBy = xorBy;
	    lodash.xorWith = xorWith;
	    lodash.zip = zip;
	    lodash.zipObject = zipObject;
	    lodash.zipObjectDeep = zipObjectDeep;
	    lodash.zipWith = zipWith;
	
	    // Add aliases.
	    lodash.entries = toPairs;
	    lodash.entriesIn = toPairsIn;
	    lodash.extend = assignIn;
	    lodash.extendWith = assignInWith;
	
	    // Add methods to `lodash.prototype`.
	    mixin(lodash, lodash);
	
	    /*------------------------------------------------------------------------*/
	
	    // Add methods that return unwrapped values in chain sequences.
	    lodash.add = add;
	    lodash.attempt = attempt;
	    lodash.camelCase = camelCase;
	    lodash.capitalize = capitalize;
	    lodash.ceil = ceil;
	    lodash.clamp = clamp;
	    lodash.clone = clone;
	    lodash.cloneDeep = cloneDeep;
	    lodash.cloneDeepWith = cloneDeepWith;
	    lodash.cloneWith = cloneWith;
	    lodash.conformsTo = conformsTo;
	    lodash.deburr = deburr;
	    lodash.defaultTo = defaultTo;
	    lodash.divide = divide;
	    lodash.endsWith = endsWith;
	    lodash.eq = eq;
	    lodash.escape = escape;
	    lodash.escapeRegExp = escapeRegExp;
	    lodash.every = every;
	    lodash.find = find;
	    lodash.findIndex = findIndex;
	    lodash.findKey = findKey;
	    lodash.findLast = findLast;
	    lodash.findLastIndex = findLastIndex;
	    lodash.findLastKey = findLastKey;
	    lodash.floor = floor;
	    lodash.forEach = forEach;
	    lodash.forEachRight = forEachRight;
	    lodash.forIn = forIn;
	    lodash.forInRight = forInRight;
	    lodash.forOwn = forOwn;
	    lodash.forOwnRight = forOwnRight;
	    lodash.get = get;
	    lodash.gt = gt;
	    lodash.gte = gte;
	    lodash.has = has;
	    lodash.hasIn = hasIn;
	    lodash.head = head;
	    lodash.identity = identity;
	    lodash.includes = includes;
	    lodash.indexOf = indexOf;
	    lodash.inRange = inRange;
	    lodash.invoke = invoke;
	    lodash.isArguments = isArguments;
	    lodash.isArray = isArray;
	    lodash.isArrayBuffer = isArrayBuffer;
	    lodash.isArrayLike = isArrayLike;
	    lodash.isArrayLikeObject = isArrayLikeObject;
	    lodash.isBoolean = isBoolean;
	    lodash.isBuffer = isBuffer;
	    lodash.isDate = isDate;
	    lodash.isElement = isElement;
	    lodash.isEmpty = isEmpty;
	    lodash.isEqual = isEqual;
	    lodash.isEqualWith = isEqualWith;
	    lodash.isError = isError;
	    lodash.isFinite = isFinite;
	    lodash.isFunction = isFunction;
	    lodash.isInteger = isInteger;
	    lodash.isLength = isLength;
	    lodash.isMap = isMap;
	    lodash.isMatch = isMatch;
	    lodash.isMatchWith = isMatchWith;
	    lodash.isNaN = isNaN;
	    lodash.isNative = isNative;
	    lodash.isNil = isNil;
	    lodash.isNull = isNull;
	    lodash.isNumber = isNumber;
	    lodash.isObject = isObject;
	    lodash.isObjectLike = isObjectLike;
	    lodash.isPlainObject = isPlainObject;
	    lodash.isRegExp = isRegExp;
	    lodash.isSafeInteger = isSafeInteger;
	    lodash.isSet = isSet;
	    lodash.isString = isString;
	    lodash.isSymbol = isSymbol;
	    lodash.isTypedArray = isTypedArray;
	    lodash.isUndefined = isUndefined;
	    lodash.isWeakMap = isWeakMap;
	    lodash.isWeakSet = isWeakSet;
	    lodash.join = join;
	    lodash.kebabCase = kebabCase;
	    lodash.last = last;
	    lodash.lastIndexOf = lastIndexOf;
	    lodash.lowerCase = lowerCase;
	    lodash.lowerFirst = lowerFirst;
	    lodash.lt = lt;
	    lodash.lte = lte;
	    lodash.max = max;
	    lodash.maxBy = maxBy;
	    lodash.mean = mean;
	    lodash.meanBy = meanBy;
	    lodash.min = min;
	    lodash.minBy = minBy;
	    lodash.stubArray = stubArray;
	    lodash.stubFalse = stubFalse;
	    lodash.stubObject = stubObject;
	    lodash.stubString = stubString;
	    lodash.stubTrue = stubTrue;
	    lodash.multiply = multiply;
	    lodash.nth = nth;
	    lodash.noConflict = noConflict;
	    lodash.noop = noop;
	    lodash.now = now;
	    lodash.pad = pad;
	    lodash.padEnd = padEnd;
	    lodash.padStart = padStart;
	    lodash.parseInt = parseInt;
	    lodash.random = random;
	    lodash.reduce = reduce;
	    lodash.reduceRight = reduceRight;
	    lodash.repeat = repeat;
	    lodash.replace = replace;
	    lodash.result = result;
	    lodash.round = round;
	    lodash.runInContext = runInContext;
	    lodash.sample = sample;
	    lodash.size = size;
	    lodash.snakeCase = snakeCase;
	    lodash.some = some;
	    lodash.sortedIndex = sortedIndex;
	    lodash.sortedIndexBy = sortedIndexBy;
	    lodash.sortedIndexOf = sortedIndexOf;
	    lodash.sortedLastIndex = sortedLastIndex;
	    lodash.sortedLastIndexBy = sortedLastIndexBy;
	    lodash.sortedLastIndexOf = sortedLastIndexOf;
	    lodash.startCase = startCase;
	    lodash.startsWith = startsWith;
	    lodash.subtract = subtract;
	    lodash.sum = sum;
	    lodash.sumBy = sumBy;
	    lodash.template = template;
	    lodash.times = times;
	    lodash.toFinite = toFinite;
	    lodash.toInteger = toInteger;
	    lodash.toLength = toLength;
	    lodash.toLower = toLower;
	    lodash.toNumber = toNumber;
	    lodash.toSafeInteger = toSafeInteger;
	    lodash.toString = toString;
	    lodash.toUpper = toUpper;
	    lodash.trim = trim;
	    lodash.trimEnd = trimEnd;
	    lodash.trimStart = trimStart;
	    lodash.truncate = truncate;
	    lodash.unescape = unescape;
	    lodash.uniqueId = uniqueId;
	    lodash.upperCase = upperCase;
	    lodash.upperFirst = upperFirst;
	
	    // Add aliases.
	    lodash.each = forEach;
	    lodash.eachRight = forEachRight;
	    lodash.first = head;
	
	    mixin(lodash, (function() {
	      var source = {};
	      baseForOwn(lodash, function(func, methodName) {
	        if (!hasOwnProperty.call(lodash.prototype, methodName)) {
	          source[methodName] = func;
	        }
	      });
	      return source;
	    }()), { 'chain': false });
	
	    /*------------------------------------------------------------------------*/
	
	    /**
	     * The semantic version number.
	     *
	     * @static
	     * @memberOf _
	     * @type {string}
	     */
	    lodash.VERSION = VERSION;
	
	    // Assign default placeholders.
	    arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) {
	      lodash[methodName].placeholder = lodash;
	    });
	
	    // Add `LazyWrapper` methods for `_.drop` and `_.take` variants.
	    arrayEach(['drop', 'take'], function(methodName, index) {
	      LazyWrapper.prototype[methodName] = function(n) {
	        var filtered = this.__filtered__;
	        if (filtered && !index) {
	          return new LazyWrapper(this);
	        }
	        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
	
	        var result = this.clone();
	        if (filtered) {
	          result.__takeCount__ = nativeMin(n, result.__takeCount__);
	        } else {
	          result.__views__.push({
	            'size': nativeMin(n, MAX_ARRAY_LENGTH),
	            'type': methodName + (result.__dir__ < 0 ? 'Right' : '')
	          });
	        }
	        return result;
	      };
	
	      LazyWrapper.prototype[methodName + 'Right'] = function(n) {
	        return this.reverse()[methodName](n).reverse();
	      };
	    });
	
	    // Add `LazyWrapper` methods that accept an `iteratee` value.
	    arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) {
	      var type = index + 1,
	          isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG;
	
	      LazyWrapper.prototype[methodName] = function(iteratee) {
	        var result = this.clone();
	        result.__iteratees__.push({
	          'iteratee': getIteratee(iteratee, 3),
	          'type': type
	        });
	        result.__filtered__ = result.__filtered__ || isFilter;
	        return result;
	      };
	    });
	
	    // Add `LazyWrapper` methods for `_.head` and `_.last`.
	    arrayEach(['head', 'last'], function(methodName, index) {
	      var takeName = 'take' + (index ? 'Right' : '');
	
	      LazyWrapper.prototype[methodName] = function() {
	        return this[takeName](1).value()[0];
	      };
	    });
	
	    // Add `LazyWrapper` methods for `_.initial` and `_.tail`.
	    arrayEach(['initial', 'tail'], function(methodName, index) {
	      var dropName = 'drop' + (index ? '' : 'Right');
	
	      LazyWrapper.prototype[methodName] = function() {
	        return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1);
	      };
	    });
	
	    LazyWrapper.prototype.compact = function() {
	      return this.filter(identity);
	    };
	
	    LazyWrapper.prototype.find = function(predicate) {
	      return this.filter(predicate).head();
	    };
	
	    LazyWrapper.prototype.findLast = function(predicate) {
	      return this.reverse().find(predicate);
	    };
	
	    LazyWrapper.prototype.invokeMap = baseRest(function(path, args) {
	      if (typeof path == 'function') {
	        return new LazyWrapper(this);
	      }
	      return this.map(function(value) {
	        return baseInvoke(value, path, args);
	      });
	    });
	
	    LazyWrapper.prototype.reject = function(predicate) {
	      return this.filter(negate(getIteratee(predicate)));
	    };
	
	    LazyWrapper.prototype.slice = function(start, end) {
	      start = toInteger(start);
	
	      var result = this;
	      if (result.__filtered__ && (start > 0 || end < 0)) {
	        return new LazyWrapper(result);
	      }
	      if (start < 0) {
	        result = result.takeRight(-start);
	      } else if (start) {
	        result = result.drop(start);
	      }
	      if (end !== undefined) {
	        end = toInteger(end);
	        result = end < 0 ? result.dropRight(-end) : result.take(end - start);
	      }
	      return result;
	    };
	
	    LazyWrapper.prototype.takeRightWhile = function(predicate) {
	      return this.reverse().takeWhile(predicate).reverse();
	    };
	
	    LazyWrapper.prototype.toArray = function() {
	      return this.take(MAX_ARRAY_LENGTH);
	    };
	
	    // Add `LazyWrapper` methods to `lodash.prototype`.
	    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
	      var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName),
	          isTaker = /^(?:head|last)$/.test(methodName),
	          lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName],
	          retUnwrapped = isTaker || /^find/.test(methodName);
	
	      if (!lodashFunc) {
	        return;
	      }
	      lodash.prototype[methodName] = function() {
	        var value = this.__wrapped__,
	            args = isTaker ? [1] : arguments,
	            isLazy = value instanceof LazyWrapper,
	            iteratee = args[0],
	            useLazy = isLazy || isArray(value);
	
	        var interceptor = function(value) {
	          var result = lodashFunc.apply(lodash, arrayPush([value], args));
	          return (isTaker && chainAll) ? result[0] : result;
	        };
	
	        if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) {
	          // Avoid lazy use if the iteratee has a "length" value other than `1`.
	          isLazy = useLazy = false;
	        }
	        var chainAll = this.__chain__,
	            isHybrid = !!this.__actions__.length,
	            isUnwrapped = retUnwrapped && !chainAll,
	            onlyLazy = isLazy && !isHybrid;
	
	        if (!retUnwrapped && useLazy) {
	          value = onlyLazy ? value : new LazyWrapper(this);
	          var result = func.apply(value, args);
	          result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined });
	          return new LodashWrapper(result, chainAll);
	        }
	        if (isUnwrapped && onlyLazy) {
	          return func.apply(this, args);
	        }
	        result = this.thru(interceptor);
	        return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result;
	      };
	    });
	
	    // Add `Array` methods to `lodash.prototype`.
	    arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
	      var func = arrayProto[methodName],
	          chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
	          retUnwrapped = /^(?:pop|shift)$/.test(methodName);
	
	      lodash.prototype[methodName] = function() {
	        var args = arguments;
	        if (retUnwrapped && !this.__chain__) {
	          var value = this.value();
	          return func.apply(isArray(value) ? value : [], args);
	        }
	        return this[chainName](function(value) {
	          return func.apply(isArray(value) ? value : [], args);
	        });
	      };
	    });
	
	    // Map minified method names to their real names.
	    baseForOwn(LazyWrapper.prototype, function(func, methodName) {
	      var lodashFunc = lodash[methodName];
	      if (lodashFunc) {
	        var key = (lodashFunc.name + ''),
	            names = realNames[key] || (realNames[key] = []);
	
	        names.push({ 'name': methodName, 'func': lodashFunc });
	      }
	    });
	
	    realNames[createHybrid(undefined, BIND_KEY_FLAG).name] = [{
	      'name': 'wrapper',
	      'func': undefined
	    }];
	
	    // Add methods to `LazyWrapper`.
	    LazyWrapper.prototype.clone = lazyClone;
	    LazyWrapper.prototype.reverse = lazyReverse;
	    LazyWrapper.prototype.value = lazyValue;
	
	    // Add chain sequence methods to the `lodash` wrapper.
	    lodash.prototype.at = wrapperAt;
	    lodash.prototype.chain = wrapperChain;
	    lodash.prototype.commit = wrapperCommit;
	    lodash.prototype.next = wrapperNext;
	    lodash.prototype.plant = wrapperPlant;
	    lodash.prototype.reverse = wrapperReverse;
	    lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
	
	    // Add lazy aliases.
	    lodash.prototype.first = lodash.prototype.head;
	
	    if (iteratorSymbol) {
	      lodash.prototype[iteratorSymbol] = wrapperToIterator;
	    }
	    return lodash;
	  });
	
	  /*--------------------------------------------------------------------------*/
	
	  // Export lodash.
	  var _ = runInContext();
	
	  // Some AMD build optimizers, like r.js, check for condition patterns like:
	  if (true) {
	    // Expose Lodash on the global object to prevent errors when Lodash is
	    // loaded by a script tag in the presence of an AMD loader.
	    // See http://requirejs.org/docs/errors.html#mismatch for more details.
	    // Use `_.noConflict` to remove Lodash from the global object.
	    root._ = _;
	
	    // Define as an anonymous module so, through path mapping, it can be
	    // referenced as the "underscore" module.
	    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
	      return _;
	    }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
	  }
	  // Check for `exports` after `define` in case a build optimizer adds it.
	  else if (freeModule) {
	    // Export for Node.js.
	    (freeModule.exports = _)._ = _;
	    // Export for CommonJS support.
	    freeExports._ = _;
	  }
	  else {
	    // Export to the global object.
	    root._ = _;
	  }
	}.call(this));
	
	/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(77)(module)))

/***/ },
/* 409 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 410 */,
/* 411 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	
	
	var ReactDOM = __webpack_require__(16);
	
	function renderConditionalPanel(_ref) {
	  var condition = _ref.condition;
	  var closePanel = _ref.closePanel;
	  var setBreakpoint = _ref.setBreakpoint;
	
	  var panel = document.createElement("div");
	
	  function onKey(e) {
	    if (e.key != "Enter") {
	      return;
	    }
	
	    setBreakpoint(e.target.value);
	    closePanel();
	  }
	
	  ReactDOM.render(dom.div({ className: "conditional-breakpoint-panel" }, dom.input({
	    defaultValue: condition,
	    placeholder: "This breakpoint will pause when the expression is true",
	    onKeyPress: onKey
	  })), panel);
	
	  return panel;
	}
	
	module.exports = {
	  renderConditionalPanel
	};

/***/ },
/* 412 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var ReactDOM = __webpack_require__(16);
	
	var PropTypes = React.PropTypes;
	
	var classnames = __webpack_require__(211);
	var Svg = __webpack_require__(310);
	
	var breakpointSvg = document.createElement("div");
	ReactDOM.render(Svg("breakpoint"), breakpointSvg);
	
	function makeMarker(isDisabled) {
	  var bp = breakpointSvg.cloneNode(true);
	  bp.className = classnames("editor new-breakpoint", { "breakpoint-disabled": isDisabled });
	
	  return bp;
	}
	
	var Breakpoint = React.createClass({
	  propTypes: {
	    breakpoint: PropTypes.object,
	    editor: PropTypes.object
	  },
	
	  displayName: "Breakpoint",
	
	  addBreakpoint() {
	    var bp = this.props.breakpoint;
	    var line = bp.location.line - 1;
	
	    this.props.editor.setGutterMarker(line, "breakpoints", makeMarker(bp.disabled));
	    this.props.editor.addLineClass(line, "line", "new-breakpoint");
	    if (bp.condition) {
	      this.props.editor.addLineClass(line, "line", "has-condition");
	    }
	  },
	
	  shouldComponentUpdate(nextProps) {
	    return this.props.editor !== nextProps.editor || this.props.breakpoint.disabled !== nextProps.breakpoint.disabled || this.props.breakpoint.condition !== nextProps.breakpoint.condition;
	  },
	
	  componentDidMount() {
	    if (!this.props.editor) {
	      return;
	    }
	
	    this.addBreakpoint();
	  },
	
	  componentDidUpdate() {
	    this.addBreakpoint();
	  },
	
	  componentWillUnmount() {
	    if (!this.props.editor) {
	      return;
	    }
	
	    var bp = this.props.breakpoint;
	    var line = bp.location.line - 1;
	
	    this.props.editor.setGutterMarker(line, "breakpoints", null);
	    this.props.editor.removeLineClass(line, "line", "new-breakpoint");
	    this.props.editor.removeLineClass(line, "line", "has-condition");
	  },
	
	  render() {
	    return null;
	  }
	});
	
	module.exports = Breakpoint;

/***/ },
/* 413 */
/***/ function(module, exports, __webpack_require__) {

	var _require = __webpack_require__(28);
	
	var Menu = _require.Menu;
	var MenuItem = _require.MenuItem;
	
	var _require2 = __webpack_require__(89);
	
	var isFirefoxPanel = _require2.isFirefoxPanel;
	
	
	function createPopup(doc) {
	  var popup = doc.createElement("menupopup");
	
	  if (popup.openPopupAtScreen) {
	    return popup;
	  }
	
	  function preventDefault(e) {
	    e.preventDefault();
	    e.returnValue = false;
	  }
	
	  var mask = document.querySelector("#contextmenu-mask");
	  if (!mask) {
	    mask = doc.createElement("div");
	    mask.id = "contextmenu-mask";
	    document.body.appendChild(mask);
	  }
	
	  mask.onclick = () => popup.hidePopup();
	
	  popup.openPopupAtScreen = function (clientX, clientY) {
	    this.style.setProperty("left", clientX + "px");
	    this.style.setProperty("top", clientY + "px");
	    mask = document.querySelector("#contextmenu-mask");
	    window.onwheel = preventDefault;
	    mask.classList.add("show");
	    this.dispatchEvent(new Event("popupshown"));
	    this.popupshown;
	  };
	
	  popup.hidePopup = function () {
	    this.remove();
	    mask = document.querySelector("#contextmenu-mask");
	    mask.classList.remove("show");
	    window.onwheel = null;
	  };
	
	  return popup;
	}
	
	if (!isFirefoxPanel()) {
	  Menu.prototype.createPopup = createPopup;
	}
	
	function onShown(menu, popup) {
	  popup.childNodes.forEach((menuitem, index) => {
	    var item = menu.items[index];
	    menuitem.onclick = () => {
	      item.click();
	      popup.hidePopup();
	    };
	  });
	}
	
	function showMenu(e, items) {
	  var menu = new Menu();
	  items.forEach(item => menu.append(new MenuItem(item)));
	
	  if (isFirefoxPanel()) {
	    return menu.popup(e.screenX, e.screenY, { doc: window.parent.document });
	  }
	
	  menu.on("open", (_, popup) => onShown(menu, popup));
	  return menu.popup(e.clientX, e.clientY, { doc: document });
	}
	
	function buildMenu(items) {
	  return items.map(itm => {
	    var hide = typeof itm.hidden === "function" ? itm.hidden() : itm.hidden;
	    return hide ? null : itm.item;
	  }).filter(itm => itm !== null);
	}
	
	module.exports = {
	  showMenu,
	  buildMenu
	};

/***/ },
/* 414 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 415 */,
/* 416 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var _require3 = __webpack_require__(259);
	
	var getPause = _require3.getPause;
	var getIsWaitingOnBreak = _require3.getIsWaitingOnBreak;
	var getBreakpointsDisabled = _require3.getBreakpointsDisabled;
	var getShouldPauseOnExceptions = _require3.getShouldPauseOnExceptions;
	var getShouldIgnoreCaughtExceptions = _require3.getShouldIgnoreCaughtExceptions;
	var getBreakpoints = _require3.getBreakpoints;
	var getBreakpointsLoading = _require3.getBreakpointsLoading;
	
	var _require4 = __webpack_require__(89);
	
	var isEnabled = _require4.isEnabled;
	
	var Svg = __webpack_require__(310);
	var ImPropTypes = __webpack_require__(235);
	
	var _require5 = __webpack_require__(30);
	
	var appinfo = _require5.Services.appinfo;
	
	var shiftKey = appinfo.OS === "Darwin" ? "\u21E7" : "Shift+";
	var ctrlKey = appinfo.OS === "Linux" ? "Ctrl+" : "";
	
	var actions = __webpack_require__(262);
	var Breakpoints = React.createFactory(__webpack_require__(417));
	var Expressions = React.createFactory(__webpack_require__(420));
	var Scopes = React.createFactory(__webpack_require__(424));
	var Frames = React.createFactory(__webpack_require__(444));
	var Accordion = React.createFactory(__webpack_require__(447));
	__webpack_require__(450);
	
	function debugBtn(onClick, type, className, tooltip) {
	  className = `${ type } ${ className }`;
	  return dom.span({ onClick, className, key: type }, Svg(type, { title: tooltip }));
	}
	
	var RightSidebar = React.createClass({
	  propTypes: {
	    sources: PropTypes.object,
	    selectedSource: PropTypes.object,
	    resume: PropTypes.func,
	    stepIn: PropTypes.func,
	    stepOut: PropTypes.func,
	    stepOver: PropTypes.func,
	    toggleAllBreakpoints: PropTypes.func,
	    breakOnNext: PropTypes.func,
	    pause: ImPropTypes.map,
	    pauseOnExceptions: PropTypes.func,
	    shouldPauseOnExceptions: PropTypes.bool,
	    shouldIgnoreCaughtExceptions: PropTypes.bool,
	    breakpoints: ImPropTypes.map,
	    isWaitingOnBreak: PropTypes.bool,
	    breakpointsDisabled: PropTypes.bool,
	    breakpointsLoading: PropTypes.bool,
	    evaluateExpressions: PropTypes.func
	  },
	
	  contextTypes: {
	    shortcuts: PropTypes.object
	  },
	
	  displayName: "RightSidebar",
	
	  getInitialState() {
	    return {
	      expressionInputVisibility: true
	    };
	  },
	
	  resume() {
	    if (this.props.pause) {
	      this.props.resume();
	    } else if (!this.props.isWaitingOnBreak) {
	      this.props.breakOnNext();
	    }
	  },
	
	  stepOver() {
	    if (!this.props.pause) {
	      return;
	    }
	    this.props.stepOver();
	  },
	
	  stepIn() {
	    if (!this.props.pause) {
	      return;
	    }
	    this.props.stepIn();
	  },
	
	  stepOut() {
	    if (!this.props.pause) {
	      return;
	    }
	    this.props.stepOut();
	  },
	
	  componentWillUnmount() {
	    var shortcuts = this.context.shortcuts;
	    shortcuts.off("F8", this.resume);
	    shortcuts.off("F10", this.stepOver);
	    shortcuts.off(`${ ctrlKey }F11`, this.stepIn);
	    shortcuts.off(`${ ctrlKey }Shift+F11`, this.stepOut);
	  },
	
	  componentDidMount() {
	    var shortcuts = this.context.shortcuts;
	    shortcuts.on("F8", this.resume);
	    shortcuts.on("F10", this.stepOver);
	    shortcuts.on(`${ ctrlKey }F11`, this.stepIn);
	    shortcuts.on(`${ ctrlKey }Shift+F11`, this.stepOut);
	  },
	
	  renderStepButtons() {
	    var className = this.props.pause ? "active" : "disabled";
	    return [debugBtn(this.stepOver, "stepOver", className, L10N.getStr("stepOverTooltip")), debugBtn(this.stepIn, "stepIn", className, L10N.getFormatStr("stepInTooltip", ctrlKey)), debugBtn(this.stepOut, "stepOut", className, L10N.getFormatStr("stepOutTooltip", ctrlKey + shiftKey))];
	  },
	
	  renderPauseButton() {
	    var _props = this.props;
	    var pause = _props.pause;
	    var breakOnNext = _props.breakOnNext;
	    var isWaitingOnBreak = _props.isWaitingOnBreak;
	
	
	    if (pause) {
	      return debugBtn(this.resume, "resume", "active", L10N.getStr("resumeButtonTooltip"));
	    }
	
	    if (isWaitingOnBreak) {
	      return debugBtn(null, "pause", "disabled", L10N.getStr("pausePendingButtonTooltip"));
	    }
	
	    return debugBtn(breakOnNext, "pause", "active", L10N.getStr("pauseButtonTooltip"));
	  },
	
	  /*
	   * The pause on exception button has three states in this order:
	   *  1. don't pause on exceptions      [false, false]
	   *  2. pause on uncaught exceptions   [true, true]
	   *  3. pause on all exceptions        [true, false]
	  */
	  renderPauseOnExceptions() {
	    var _props2 = this.props;
	    var shouldPauseOnExceptions = _props2.shouldPauseOnExceptions;
	    var shouldIgnoreCaughtExceptions = _props2.shouldIgnoreCaughtExceptions;
	    var pauseOnExceptions = _props2.pauseOnExceptions;
	
	
	    if (!shouldPauseOnExceptions && !shouldIgnoreCaughtExceptions) {
	      return debugBtn(() => pauseOnExceptions(true, true), "pause-exceptions", "enabled", L10N.getStr("ignoreExceptions"));
	    }
	
	    if (shouldPauseOnExceptions && shouldIgnoreCaughtExceptions) {
	      return debugBtn(() => pauseOnExceptions(true, false), "pause-exceptions", "uncaught enabled", L10N.getStr("pauseOnUncaughtExceptions"));
	    }
	
	    return debugBtn(() => pauseOnExceptions(false, false), "pause-exceptions", "all enabled", L10N.getStr("pauseOnExceptions"));
	  },
	
	  renderDisableBreakpoints() {
	    var _props3 = this.props;
	    var toggleAllBreakpoints = _props3.toggleAllBreakpoints;
	    var breakpoints = _props3.breakpoints;
	    var breakpointsDisabled = _props3.breakpointsDisabled;
	    var breakpointsLoading = _props3.breakpointsLoading;
	
	
	    if (breakpoints.size == 0 || breakpointsLoading) {
	      return debugBtn(null, "toggleBreakpoints", "disabled", "Disable Breakpoints");
	    }
	
	    return debugBtn(() => toggleAllBreakpoints(!breakpointsDisabled), "toggleBreakpoints", breakpointsDisabled ? "breakpoints-disabled" : "", "Disable Breakpoints");
	  },
	
	  getItems() {
	    var expressionInputVisibility = this.state.expressionInputVisibility;
	
	    var items = [{ header: L10N.getStr("breakpoints.header"),
	      component: Breakpoints,
	      opened: true }, { header: L10N.getStr("callStack.header"),
	      component: Frames }, { header: L10N.getStr("scopes.header"),
	      component: Scopes }];
	    if (isEnabled("watchExpressions")) {
	      items.unshift({ header: L10N.getStr("watchExpressions.header"),
	        buttons: [debugBtn(evt => {
	          evt.stopPropagation();
	          this.props.evaluateExpressions();
	        }, "domain", "accordion-button", "Refresh"), debugBtn(evt => {
	          evt.stopPropagation();
	          this.setState({
	            expressionInputVisibility: !expressionInputVisibility
	          });
	        }, "file", "accordion-button", "Add Watch Expression")],
	        component: Expressions,
	        componentProps: { expressionInputVisibility },
	        opened: true
	      });
	    }
	    return items;
	  },
	
	  render() {
	    return dom.div({ className: "right-sidebar",
	      style: { overflowX: "hidden" } }, dom.div({ className: "command-bar" }, this.renderPauseButton(), this.renderStepButtons(), this.renderDisableBreakpoints(), this.renderPauseOnExceptions()), Accordion({
	      items: this.getItems()
	    }));
	  }
	
	});
	
	module.exports = connect(state => {
	  return {
	    pause: getPause(state),
	    isWaitingOnBreak: getIsWaitingOnBreak(state),
	    shouldPauseOnExceptions: getShouldPauseOnExceptions(state),
	    shouldIgnoreCaughtExceptions: getShouldIgnoreCaughtExceptions(state),
	    breakpointsDisabled: getBreakpointsDisabled(state),
	    breakpoints: getBreakpoints(state),
	    breakpointsLoading: getBreakpointsLoading(state)
	  };
	}, dispatch => bindActionCreators(actions, dispatch))(RightSidebar);

/***/ },
/* 417 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var ImPropTypes = __webpack_require__(235);
	var classnames = __webpack_require__(211);
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(259);
	
	var getSource = _require3.getSource;
	var getPause = _require3.getPause;
	var getBreakpoints = _require3.getBreakpoints;
	
	var _require4 = __webpack_require__(255);
	
	var makeLocationId = _require4.makeLocationId;
	
	var _require5 = __webpack_require__(244);
	
	var truncateStr = _require5.truncateStr;
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var _require6 = __webpack_require__(244);
	
	var endTruncateStr = _require6.endTruncateStr;
	
	var _require7 = __webpack_require__(278);
	
	var basename = _require7.basename;
	
	var CloseButton = __webpack_require__(336);
	
	__webpack_require__(418);
	
	function isCurrentlyPausedAtBreakpoint(state, breakpoint) {
	  var pause = getPause(state);
	  if (!pause || pause.get("isInterrupted")) {
	    return false;
	  }
	
	  var bpId = makeLocationId(breakpoint.location);
	  var pausedId = makeLocationId(pause.getIn(["frame", "location"]).toJS());
	
	  return bpId === pausedId;
	}
	
	function renderSourceLocation(source, line) {
	  var url = source.get("url") ? basename(source.get("url")) : null;
	  // const line = url !== "" ? `: ${line}` : "";
	  return url ? dom.div({ className: "location" }, `${ endTruncateStr(url, 30) }: ${ line }`) : null;
	}
	
	var Breakpoints = React.createClass({
	  propTypes: {
	    breakpoints: ImPropTypes.map.isRequired,
	    enableBreakpoint: PropTypes.func.isRequired,
	    disableBreakpoint: PropTypes.func.isRequired,
	    selectSource: PropTypes.func.isRequired,
	    removeBreakpoint: PropTypes.func.isRequired
	  },
	
	  displayName: "Breakpoints",
	
	  handleCheckbox(breakpoint) {
	    if (breakpoint.loading) {
	      return;
	    }
	
	    if (breakpoint.disabled) {
	      this.props.enableBreakpoint(breakpoint.location);
	    } else {
	      this.props.disableBreakpoint(breakpoint.location);
	    }
	  },
	
	  selectBreakpoint(breakpoint) {
	    var sourceId = breakpoint.location.sourceId;
	    var line = breakpoint.location.line;
	    this.props.selectSource(sourceId, { line });
	  },
	
	  removeBreakpoint(event, breakpoint) {
	    event.stopPropagation();
	    this.props.removeBreakpoint(breakpoint.location);
	  },
	
	  renderBreakpoint(breakpoint) {
	    var snippet = truncateStr(breakpoint.text || "", 30);
	    var locationId = breakpoint.locationId;
	    var line = breakpoint.location.line;
	    var isCurrentlyPaused = breakpoint.isCurrentlyPaused;
	    var isDisabled = breakpoint.disabled;
	
	    return dom.div({
	      className: classnames({
	        breakpoint,
	        paused: isCurrentlyPaused,
	        disabled: isDisabled
	      }),
	      key: locationId,
	      onClick: () => this.selectBreakpoint(breakpoint)
	    }, dom.input({
	      type: "checkbox",
	      className: "breakpoint-checkbox",
	      checked: !isDisabled,
	      onChange: () => this.handleCheckbox(breakpoint),
	      // Prevent clicking on the checkbox from triggering the onClick of
	      // the surrounding div
	      onClick: ev => ev.stopPropagation()
	    }), dom.div({ className: "breakpoint-label", title: breakpoint.text }, dom.div({}, renderSourceLocation(breakpoint.location.source, line))), dom.div({ className: "breakpoint-snippet" }, snippet), CloseButton({
	      handleClick: ev => this.removeBreakpoint(ev, breakpoint)
	    }));
	  },
	
	  render() {
	    var breakpoints = this.props.breakpoints;
	
	    return dom.div({ className: "pane breakpoints-list" }, breakpoints.size === 0 ? dom.div({ className: "pane-info" }, "No Breakpoints") : breakpoints.valueSeq().map(bp => {
	      return this.renderBreakpoint(bp);
	    }));
	  }
	});
	
	function _getBreakpoints(state) {
	  return getBreakpoints(state).map(bp => {
	    var source = getSource(state, bp.location.sourceId);
	    var isCurrentlyPaused = isCurrentlyPausedAtBreakpoint(state, bp);
	    var locationId = makeLocationId(bp.location);
	
	    bp = Object.assign({}, bp);
	    bp.location.source = source;
	    bp.locationId = locationId;
	    bp.isCurrentlyPaused = isCurrentlyPaused;
	    return bp;
	  }).filter(bp => bp.location.source);
	}
	
	module.exports = connect((state, props) => ({
	  breakpoints: _getBreakpoints(state)
	}), dispatch => bindActionCreators(actions, dispatch))(Breakpoints);

/***/ },
/* 418 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 419 */,
/* 420 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var ImPropTypes = __webpack_require__(235);
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(259);
	
	var getExpressions = _require3.getExpressions;
	var getPause = _require3.getPause;
	
	var Rep = React.createFactory(__webpack_require__(421));
	var CloseButton = React.createFactory(__webpack_require__(336));
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	
	__webpack_require__(422);
	
	var Expressions = React.createClass({
	  propTypes: {
	    expressions: ImPropTypes.list,
	    addExpression: PropTypes.func,
	    updateExpression: PropTypes.func,
	    deleteExpression: PropTypes.func,
	    expressionInputVisibility: PropTypes.bool,
	    loadObjectProperties: PropTypes.func,
	    loadedObjects: ImPropTypes.map
	  },
	
	  displayName: "Expressions",
	
	  inputKeyPress(e, _ref) {
	    var id = _ref.id;
	
	    if (e.key !== "Enter") {
	      return;
	    }
	    var addExpression = this.props.addExpression;
	
	    var expression = {
	      input: e.target.value
	    };
	    if (id !== undefined) {
	      expression.id = id;
	    }
	    e.target.value = "";
	    addExpression(expression);
	  },
	
	  updateExpression(e, _ref2) {
	    var id = _ref2.id;
	
	    e.stopPropagation();
	    var updateExpression = this.props.updateExpression;
	
	    var expression = {
	      id,
	      input: e.target.textContent
	    };
	    updateExpression(expression);
	  },
	
	  renderExpressionValue(value) {
	    if (!value) {
	      return dom.span({ className: "expression-error" }, "<not available>");
	    }
	    if (value.exception) {
	      return Rep({ object: value.exception });
	    }
	    return Rep({ object: value.result });
	  },
	
	  deleteExpression(e, expression) {
	    e.stopPropagation();
	    var deleteExpression = this.props.deleteExpression;
	
	    deleteExpression(expression);
	  },
	
	  renderExpressionUpdating(expression) {
	    return dom.span({ className: "expression-input-container" }, dom.input({ type: "text",
	      className: "input-expression",
	      onKeyPress: e => this.inputKeyPress(e, expression),
	      defaultValue: expression.input,
	      ref: c => {
	        this._input = c;
	      }
	    }));
	  },
	
	  renderExpression(expression) {
	    return dom.span({ className: "expression-output-container",
	      key: expression.id }, dom.span({ className: "expression-input",
	      onClick: e => this.updateExpression(e, expression) }, expression.input), dom.span({ className: "expression-seperator" }, ": "), dom.span({ className: "expression-value" }, this.renderExpressionValue(expression.value)), CloseButton({ handleClick: e => this.deleteExpression(e, expression) }));
	  },
	
	  renderExpressionContainer(expression) {
	    return dom.div({ className: "expression-container",
	      key: expression.id + expression.input }, expression.updating ? this.renderExpressionUpdating(expression) : this.renderExpression(expression));
	  },
	
	  componentDidUpdate() {
	    if (this._input) {
	      this._input.focus();
	    }
	  },
	
	  render() {
	    var expressions = this.props.expressions;
	
	    return dom.span({ className: "pane expressions-list" }, this.props.expressionInputVisibility ? dom.input({ type: "text",
	      className: "input-expression",
	      placeholder: "Add Watch Expression",
	      onKeyPress: e => this.inputKeyPress(e, {}) }) : null, expressions.toSeq().map(expression => this.renderExpressionContainer(expression)));
	  }
	});
	
	module.exports = connect(state => ({ pauseInfo: getPause(state),
	  expressions: getExpressions(state)
	}), dispatch => bindActionCreators(actions, dispatch))(Expressions);

/***/ },
/* 421 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(30);
	
	var rep = _require.rep;
	var Grip = _require.Grip;
	
	var Rep = React.createFactory(rep);
	
	function renderRep(_ref) {
	  var object = _ref.object;
	  var mode = _ref.mode;
	
	  return Rep({ object, defaultRep: Grip, mode });
	}
	
	module.exports = renderRep;

/***/ },
/* 422 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 423 */,
/* 424 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	
	var _require2 = __webpack_require__(19);
	
	var connect = _require2.connect;
	
	var ImPropTypes = __webpack_require__(235);
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(259);
	
	var getSelectedFrame = _require3.getSelectedFrame;
	var getLoadedObjects = _require3.getLoadedObjects;
	var getPause = _require3.getPause;
	
	var ObjectInspector = React.createFactory(__webpack_require__(425));
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var toPairs = __webpack_require__(428);
	
	__webpack_require__(442);
	
	function info(text) {
	  return dom.div({ className: "pane-info" }, text);
	}
	
	// Create the tree nodes representing all the variables and arguments
	// for the bindings from a scope.
	function getBindingVariables(bindings, parentName) {
	  var args = bindings.arguments.map(arg => toPairs(arg)[0]);
	  var variables = toPairs(bindings.variables);
	
	  return args.concat(variables).filter(binding => !(binding[1].value.missingArguments || binding[1].value.optimizedOut)).map(binding => ({
	    name: binding[0],
	    path: parentName + "/" + binding[0],
	    contents: binding[1]
	  }));
	}
	
	function getSpecialVariables(pauseInfo, path) {
	  var thrown = pauseInfo.getIn(["why", "frameFinished", "throw"]);
	  var returned = pauseInfo.getIn(["why", "frameFinished", "return"]);
	  var vars = [];
	
	  if (thrown) {
	    // handle dehydrating exception strings and errors.
	    thrown = thrown.toJS ? thrown.toJS() : thrown;
	
	    vars.push({
	      name: "<exception>",
	      path: path + "/<exception>",
	      contents: { value: thrown }
	    });
	  }
	
	  if (returned) {
	    vars.push({
	      name: "<return>",
	      path: path + "/<return>",
	      contents: { value: returned.toJS() }
	    });
	  }
	
	  return vars;
	}
	
	function getThisVariable(frame, path) {
	  var this_ = frame.this;
	
	  if (!this_) {
	    return null;
	  }
	
	  return {
	    name: "<this>",
	    path: path + "/<this>",
	    contents: { value: this_ }
	  };
	}
	
	function getScopes(pauseInfo, selectedFrame) {
	  if (!pauseInfo || !selectedFrame) {
	    return null;
	  }
	
	  var selectedScope = selectedFrame.scope;
	
	  if (!selectedScope) {
	    return null;
	  }
	
	  var scopes = [];
	
	  var scope = selectedScope;
	  var pausedScopeActor = pauseInfo.getIn(["frame", "scope"]).get("actor");
	
	  do {
	    var type = scope.type;
	    var key = scope.actor;
	    if (type === "function" || type === "block") {
	      var bindings = scope.bindings;
	      var title = void 0;
	      if (type === "function") {
	        title = scope.function.displayName || "(anonymous)";
	      } else {
	        title = "Block";
	      }
	
	      var vars = getBindingVariables(bindings, title);
	
	      // show exception, return, and this variables in innermost scope
	      if (scope.actor === pausedScopeActor) {
	        vars = vars.concat(getSpecialVariables(pauseInfo, key));
	      }
	
	      if (scope.actor === selectedScope.actor) {
	        var this_ = getThisVariable(selectedFrame, key);
	
	        if (this_) {
	          vars.push(this_);
	        }
	      }
	
	      if (vars && vars.length) {
	        vars.sort((a, b) => a.name.localeCompare(b.name));
	        scopes.push({ name: title, path: key, contents: vars });
	      }
	    } else if (type === "object") {
	      var value = scope.object;
	      // If this is the global window scope, mark it as such so that it will
	      // preview Window: Global instead of Window: Window
	      if (value.class === "Window") {
	        value = Object.assign({}, scope.object, { isGlobal: true });
	      }
	      scopes.push({
	        name: scope.object.class,
	        path: key,
	        contents: { value }
	      });
	    }
	  } while (scope = scope.parent); // eslint-disable-line no-cond-assign
	
	  return scopes;
	}
	
	var Scopes = React.createClass({
	  propTypes: {
	    pauseInfo: ImPropTypes.map,
	    loadedObjects: ImPropTypes.map,
	    loadObjectProperties: PropTypes.func,
	    selectedFrame: PropTypes.object
	  },
	
	  displayName: "Scopes",
	
	  getInitialState() {
	    var _props = this.props;
	    var pauseInfo = _props.pauseInfo;
	    var selectedFrame = _props.selectedFrame;
	
	    return { scopes: getScopes(pauseInfo, selectedFrame) };
	  },
	
	  componentWillReceiveProps(nextProps) {
	    var _props2 = this.props;
	    var pauseInfo = _props2.pauseInfo;
	    var selectedFrame = _props2.selectedFrame;
	
	    var pauseInfoChanged = pauseInfo !== nextProps.pauseInfo;
	    var selectedFrameChange = selectedFrame !== nextProps.selectedFrame;
	
	    if (pauseInfoChanged || selectedFrameChange) {
	      this.setState({
	        scopes: getScopes(nextProps.pauseInfo, nextProps.selectedFrame)
	      });
	    }
	  },
	
	  render() {
	    var _props3 = this.props;
	    var pauseInfo = _props3.pauseInfo;
	    var loadObjectProperties = _props3.loadObjectProperties;
	    var loadedObjects = _props3.loadedObjects;
	    var scopes = this.state.scopes;
	
	
	    var scopeInspector = info(L10N.getStr("scopes.notAvailable"));
	    if (scopes) {
	      scopeInspector = ObjectInspector({
	        roots: scopes,
	        getObjectProperties: id => loadedObjects.get(id),
	        loadObjectProperties: loadObjectProperties
	      });
	    }
	
	    return dom.div({ className: "pane scopes-list" }, pauseInfo ? scopeInspector : info(L10N.getStr("scopes.notPaused")));
	  }
	});
	
	module.exports = connect(state => ({
	  pauseInfo: getPause(state),
	  selectedFrame: getSelectedFrame(state),
	  loadedObjects: getLoadedObjects(state)
	}), dispatch => bindActionCreators(actions, dispatch))(Scopes);

/***/ },
/* 425 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var classnames = __webpack_require__(211);
	var ManagedTree = React.createFactory(__webpack_require__(394));
	var Svg = __webpack_require__(310);
	var Rep = __webpack_require__(421);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	
	__webpack_require__(426);
	
	// This implements a component that renders an interactive inspector
	// for looking at JavaScript objects. It expects descriptions of
	// objects from the protocol, and will dynamically fetch child
	// properties as objects are expanded.
	//
	// If you want to inspect a single object, pass the name and the
	// protocol descriptor of it:
	//
	//  ObjectInspector({
	//    name: "foo",
	//    desc: { writable: true, ..., { value: { actor: "1", ... }}},
	//    ...
	//  })
	//
	// If you want multiple top-level objects (like scopes), you can pass
	// an array of manually constructed nodes as `roots`:
	//
	//  ObjectInspector({
	//    roots: [{ name: ... }, ...],
	//    ...
	//  });
	
	// There are 3 types of nodes: a simple node with a children array, an
	// object that has properties that should be children when they are
	// fetched, and a primitive value that should be displayed with no
	// children.
	
	function nodeHasChildren(item) {
	  return Array.isArray(item.contents);
	}
	
	function nodeHasProperties(item) {
	  return !nodeHasChildren(item) && item.contents.value.type === "object";
	}
	
	function nodeIsPrimitive(item) {
	  return !nodeHasChildren(item) && !nodeHasProperties(item);
	}
	
	function createNode(name, path, contents) {
	  // The path is important to uniquely identify the item in the entire
	  // tree. This helps debugging & optimizes React's rendering of large
	  // lists. The path will be separated by property name,
	  // i.e. `{ foo: { bar: { baz: 5 }}}` will have a path of `foo/bar/baz`
	  // for the inner object.
	  return { name, path, contents };
	}
	
	var ObjectInspector = React.createClass({
	  propTypes: {
	    name: PropTypes.string,
	    desc: PropTypes.object,
	    roots: PropTypes.array,
	    getObjectProperties: PropTypes.func.isRequired,
	    loadObjectProperties: PropTypes.func.isRequired
	  },
	
	  displayName: "ObjectInspector",
	
	  getInitialState() {
	    // Cache of dynamically built nodes. We shouldn't need to clear
	    // this out ever, since we don't ever "switch out" the object
	    // being inspected.
	    this.actorCache = {};
	    return {};
	  },
	
	  makeNodesForProperties(objProps, parentPath) {
	    var ownProperties = objProps.ownProperties;
	    var prototype = objProps.prototype;
	
	
	    var nodes = Object.keys(ownProperties).filter(name => {
	      // Ignore non-concrete values like getters and setters
	      // for now by making sure we have a value.
	      return "value" in ownProperties[name];
	    }).map(name => {
	      return createNode(name, parentPath + "/" + name, ownProperties[name]);
	    });
	
	    // Add the prototype if it exists and is not null
	    if (prototype && prototype.type !== "null") {
	      nodes.push(createNode("__proto__", parentPath + "/__proto__", { value: prototype }));
	    }
	
	    return nodes;
	  },
	
	  getChildren(item) {
	    var getObjectProperties = this.props.getObjectProperties;
	
	    var obj = item.contents;
	
	    // Nodes can either have children already, or be an object with
	    // properties that we need to go and fetch.
	    if (nodeHasChildren(item)) {
	      return item.contents;
	    } else if (nodeHasProperties(item)) {
	      var actor = obj.value.actor;
	
	      // Because we are dynamically creating the tree as the user
	      // expands it (not precalcuated tree structure), we cache child
	      // arrays. This not only helps performance, but is necessary
	      // because the expanded state depends on instances of nodes
	      // being the same across renders. If we didn't do this, each
	      // node would be a new instance every render.
	      var key = item.path;
	      if (this.actorCache[key]) {
	        return this.actorCache[key];
	      }
	
	      var loadedProps = getObjectProperties(actor);
	      if (loadedProps) {
	        var children = this.makeNodesForProperties(loadedProps, item.path);
	        this.actorCache[actor] = children;
	        return children;
	      }
	      return [];
	    }
	    return [];
	  },
	
	  renderItem(item, depth, focused, _, expanded, _ref) {
	    var setExpanded = _ref.setExpanded;
	
	    var objectValue = void 0;
	    if (nodeHasProperties(item) || nodeIsPrimitive(item)) {
	      var object = item.contents.value;
	      objectValue = Rep({ object, mode: "tiny" });
	    }
	
	    return dom.div({ className: classnames("node", { focused }),
	      style: { marginLeft: depth * 15 },
	      onClick: e => {
	        e.stopPropagation();
	        setExpanded(item, !expanded);
	      }
	    }, Svg("arrow", {
	      className: classnames({
	        expanded: expanded,
	        hidden: nodeIsPrimitive(item)
	      })
	    }), dom.span({ className: "object-label" }, item.name), dom.span({ className: "object-delimiter" }, objectValue ? ": " : ""), dom.span({ className: "object-value" }, objectValue || ""));
	  },
	
	  render() {
	    var _props = this.props;
	    var name = _props.name;
	    var desc = _props.desc;
	    var loadObjectProperties = _props.loadObjectProperties;
	
	
	    var roots = this.props.roots;
	    if (!roots) {
	      roots = [createNode(name, name, desc)];
	    }
	
	    return ManagedTree({
	      itemHeight: 20,
	      getParent: item => null,
	      getChildren: this.getChildren,
	      getRoots: () => roots,
	      getKey: item => item.path,
	      autoExpand: 0,
	      disabledFocus: true,
	      onExpand: item => {
	        if (nodeHasProperties(item)) {
	          loadObjectProperties(item.contents.value);
	        }
	      },
	
	      renderItem: this.renderItem
	    });
	  }
	});
	
	module.exports = ObjectInspector;

/***/ },
/* 426 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 427 */,
/* 428 */
/***/ function(module, exports, __webpack_require__) {

	var createToPairs = __webpack_require__(429),
	    keys = __webpack_require__(439);
	
	/**
	 * Creates an array of own enumerable string keyed-value pairs for `object`
	 * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
	 * entries are returned.
	 *
	 * @static
	 * @memberOf _
	 * @since 4.0.0
	 * @alias entries
	 * @category Object
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the key-value pairs.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.toPairs(new Foo);
	 * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
	 */
	var toPairs = createToPairs(keys);
	
	module.exports = toPairs;


/***/ },
/* 429 */
/***/ function(module, exports, __webpack_require__) {

	var baseToPairs = __webpack_require__(430),
	    getTag = __webpack_require__(431),
	    mapToArray = __webpack_require__(437),
	    setToPairs = __webpack_require__(438);
	
	/** `Object#toString` result references. */
	var mapTag = '[object Map]',
	    setTag = '[object Set]';
	
	/**
	 * Creates a `_.toPairs` or `_.toPairsIn` function.
	 *
	 * @private
	 * @param {Function} keysFunc The function to get the keys of a given object.
	 * @returns {Function} Returns the new pairs function.
	 */
	function createToPairs(keysFunc) {
	  return function(object) {
	    var tag = getTag(object);
	    if (tag == mapTag) {
	      return mapToArray(object);
	    }
	    if (tag == setTag) {
	      return setToPairs(object);
	    }
	    return baseToPairs(object, keysFunc(object));
	  };
	}
	
	module.exports = createToPairs;


/***/ },
/* 430 */
/***/ function(module, exports, __webpack_require__) {

	var arrayMap = __webpack_require__(135);
	
	/**
	 * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
	 * of key-value pairs for `object` corresponding to the property names of `props`.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @param {Array} props The property names to get values for.
	 * @returns {Object} Returns the key-value pairs.
	 */
	function baseToPairs(object, props) {
	  return arrayMap(props, function(key) {
	    return [key, object[key]];
	  });
	}
	
	module.exports = baseToPairs;


/***/ },
/* 431 */
/***/ function(module, exports, __webpack_require__) {

	var DataView = __webpack_require__(432),
	    Map = __webpack_require__(125),
	    Promise = __webpack_require__(433),
	    Set = __webpack_require__(434),
	    WeakMap = __webpack_require__(435),
	    baseGetTag = __webpack_require__(436),
	    toSource = __webpack_require__(111);
	
	/** `Object#toString` result references. */
	var mapTag = '[object Map]',
	    objectTag = '[object Object]',
	    promiseTag = '[object Promise]',
	    setTag = '[object Set]',
	    weakMapTag = '[object WeakMap]';
	
	var dataViewTag = '[object DataView]';
	
	/** 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 objectToString = objectProto.toString;
	
	/** Used to detect maps, sets, and weakmaps. */
	var dataViewCtorString = toSource(DataView),
	    mapCtorString = toSource(Map),
	    promiseCtorString = toSource(Promise),
	    setCtorString = toSource(Set),
	    weakMapCtorString = toSource(WeakMap);
	
	/**
	 * Gets the `toStringTag` of `value`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the `toStringTag`.
	 */
	var getTag = baseGetTag;
	
	// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
	if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
	    (Map && getTag(new Map) != mapTag) ||
	    (Promise && getTag(Promise.resolve()) != promiseTag) ||
	    (Set && getTag(new Set) != setTag) ||
	    (WeakMap && getTag(new WeakMap) != weakMapTag)) {
	  getTag = function(value) {
	    var result = objectToString.call(value),
	        Ctor = result == objectTag ? value.constructor : undefined,
	        ctorString = Ctor ? toSource(Ctor) : undefined;
	
	    if (ctorString) {
	      switch (ctorString) {
	        case dataViewCtorString: return dataViewTag;
	        case mapCtorString: return mapTag;
	        case promiseCtorString: return promiseTag;
	        case setCtorString: return setTag;
	        case weakMapCtorString: return weakMapTag;
	      }
	    }
	    return result;
	  };
	}
	
	module.exports = getTag;


/***/ },
/* 432 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103),
	    root = __webpack_require__(109);
	
	/* Built-in method references that are verified to be native. */
	var DataView = getNative(root, 'DataView');
	
	module.exports = DataView;


/***/ },
/* 433 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103),
	    root = __webpack_require__(109);
	
	/* Built-in method references that are verified to be native. */
	var Promise = getNative(root, 'Promise');
	
	module.exports = Promise;


/***/ },
/* 434 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103),
	    root = __webpack_require__(109);
	
	/* Built-in method references that are verified to be native. */
	var Set = getNative(root, 'Set');
	
	module.exports = Set;


/***/ },
/* 435 */
/***/ function(module, exports, __webpack_require__) {

	var getNative = __webpack_require__(103),
	    root = __webpack_require__(109);
	
	/* Built-in method references that are verified to be native. */
	var WeakMap = getNative(root, 'WeakMap');
	
	module.exports = WeakMap;


/***/ },
/* 436 */
/***/ 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 objectToString = objectProto.toString;
	
	/**
	 * The base implementation of `getTag`.
	 *
	 * @private
	 * @param {*} value The value to query.
	 * @returns {string} Returns the `toStringTag`.
	 */
	function baseGetTag(value) {
	  return objectToString.call(value);
	}
	
	module.exports = baseGetTag;


/***/ },
/* 437 */
/***/ function(module, exports) {

	/**
	 * Converts `map` to its key-value pairs.
	 *
	 * @private
	 * @param {Object} map The map to convert.
	 * @returns {Array} Returns the key-value pairs.
	 */
	function mapToArray(map) {
	  var index = -1,
	      result = Array(map.size);
	
	  map.forEach(function(value, key) {
	    result[++index] = [key, value];
	  });
	  return result;
	}
	
	module.exports = mapToArray;


/***/ },
/* 438 */
/***/ function(module, exports) {

	/**
	 * Converts `set` to its value-value pairs.
	 *
	 * @private
	 * @param {Object} set The set to convert.
	 * @returns {Array} Returns the value-value pairs.
	 */
	function setToPairs(set) {
	  var index = -1,
	      result = Array(set.size);
	
	  set.forEach(function(value) {
	    result[++index] = [value, value];
	  });
	  return result;
	}
	
	module.exports = setToPairs;


/***/ },
/* 439 */
/***/ function(module, exports, __webpack_require__) {

	var arrayLikeKeys = __webpack_require__(379),
	    baseKeys = __webpack_require__(440),
	    isArrayLike = __webpack_require__(367);
	
	/**
	 * Creates an array of the own enumerable property names of `object`.
	 *
	 * **Note:** Non-object values are coerced to objects. See the
	 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
	 * for more details.
	 *
	 * @static
	 * @since 0.1.0
	 * @memberOf _
	 * @category Object
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 * @example
	 *
	 * function Foo() {
	 *   this.a = 1;
	 *   this.b = 2;
	 * }
	 *
	 * Foo.prototype.c = 3;
	 *
	 * _.keys(new Foo);
	 * // => ['a', 'b'] (iteration order is not guaranteed)
	 *
	 * _.keys('hi');
	 * // => ['0', '1']
	 */
	function keys(object) {
	  return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
	}
	
	module.exports = keys;


/***/ },
/* 440 */
/***/ function(module, exports, __webpack_require__) {

	var isPrototype = __webpack_require__(363),
	    nativeKeys = __webpack_require__(441);
	
	/** Used for built-in method references. */
	var objectProto = Object.prototype;
	
	/** Used to check objects for own properties. */
	var hasOwnProperty = objectProto.hasOwnProperty;
	
	/**
	 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
	 *
	 * @private
	 * @param {Object} object The object to query.
	 * @returns {Array} Returns the array of property names.
	 */
	function baseKeys(object) {
	  if (!isPrototype(object)) {
	    return nativeKeys(object);
	  }
	  var result = [];
	  for (var key in Object(object)) {
	    if (hasOwnProperty.call(object, key) && key != 'constructor') {
	      result.push(key);
	    }
	  }
	  return result;
	}
	
	module.exports = baseKeys;


/***/ },
/* 441 */
/***/ function(module, exports, __webpack_require__) {

	var overArg = __webpack_require__(7);
	
	/* Built-in method references for those with the same name as other `lodash` methods. */
	var nativeKeys = overArg(Object.keys, Object);
	
	module.exports = nativeKeys;


/***/ },
/* 442 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 443 */,
/* 444 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	var div = dom.div;
	
	var _require = __webpack_require__(3);
	
	var bindActionCreators = _require.bindActionCreators;
	
	var _require2 = __webpack_require__(19);
	
	var connect = _require2.connect;
	
	var ImPropTypes = __webpack_require__(235);
	var actions = __webpack_require__(262);
	
	var _require3 = __webpack_require__(244);
	
	var endTruncateStr = _require3.endTruncateStr;
	
	var _require4 = __webpack_require__(277);
	
	var getFilename = _require4.getFilename;
	
	var _require5 = __webpack_require__(259);
	
	var getFrames = _require5.getFrames;
	var getSelectedFrame = _require5.getSelectedFrame;
	var getSource = _require5.getSource;
	
	
	if (typeof window == "object") {
	  __webpack_require__(445);
	}
	
	var NUM_FRAMES_SHOWN = 7;
	
	function renderFrameTitle(frame) {
	  return div({ className: "title" }, endTruncateStr(frame.displayName, 40));
	}
	
	function renderFrameLocation(frame) {
	  var filename = getFilename(frame.source);
	  return div({ className: "location" }, `${ filename }: ${ frame.location.line }`);
	}
	
	var Frames = React.createClass({
	  propTypes: {
	    frames: ImPropTypes.list,
	    selectedFrame: PropTypes.object,
	    selectFrame: PropTypes.func.isRequired
	  },
	
	  displayName: "Frames",
	
	  getInitialState() {
	    return { showAllFrames: false };
	  },
	
	  toggleFramesDisplay() {
	    this.setState({
	      showAllFrames: !this.state.showAllFrames
	    });
	  },
	
	  renderFrame(frame) {
	    var _props = this.props;
	    var selectedFrame = _props.selectedFrame;
	    var selectFrame = _props.selectFrame;
	
	
	    var selectedClass = selectedFrame && (selectedFrame.id === frame.id ? "selected" : "");
	
	    return dom.li({ key: frame.id,
	      className: `frame ${ selectedClass }`,
	      onMouseDown: () => selectFrame(frame),
	      tabIndex: 0
	    }, renderFrameTitle(frame), renderFrameLocation(frame));
	  },
	
	  renderFrames() {
	    var frames = this.props.frames;
	
	    if (!frames) {
	      return null;
	    }
	
	    var numFramesToShow = this.state.showAllFrames ? frames.size : NUM_FRAMES_SHOWN;
	    frames = frames.slice(0, numFramesToShow);
	
	    return dom.ul({}, frames.map(frame => this.renderFrame(frame)));
	  },
	
	  renderToggleButton() {
	    var frames = this.props.frames;
	
	    var buttonMessage = this.state.showAllFrames ? L10N.getStr("callStack.collapse") : L10N.getStr("callStack.expand");
	
	    if (frames.size < NUM_FRAMES_SHOWN) {
	      return null;
	    }
	
	    return dom.div({ className: "show-more", onClick: this.toggleFramesDisplay }, buttonMessage);
	  },
	
	  render() {
	    var frames = this.props.frames;
	
	
	    if (!frames) {
	      return div({ className: "pane frames" }, div({ className: "pane-info empty" }, L10N.getStr("callStack.notPaused")));
	    }
	
	    return div({ className: "pane frames" }, this.renderFrames(), this.renderToggleButton());
	  }
	});
	
	function getAndProcessFrames(state) {
	  var frames = getFrames(state);
	  if (!frames) {
	    return null;
	  }
	  return frames.filter(frame => getSource(state, frame.location.sourceId)).map(frame => Object.assign({}, frame, {
	    source: getSource(state, frame.location.sourceId).toJS()
	  }));
	}
	
	module.exports = connect(state => ({
	  frames: getAndProcessFrames(state),
	  selectedFrame: getSelectedFrame(state)
	}), dispatch => bindActionCreators(actions, dispatch))(Frames);

/***/ },
/* 445 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 446 */,
/* 447 */
/***/ function(module, exports, __webpack_require__) {

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	var div = dom.div;
	var span = dom.span;
	
	var Svg = __webpack_require__(310);
	
	__webpack_require__(448);
	
	var Accordion = React.createClass({
	  propTypes: {
	    items: PropTypes.array
	  },
	
	  displayName: "Accordion",
	
	  getInitialState: function () {
	    return { opened: this.props.items.map(item => item.opened),
	      created: [] };
	  },
	
	  handleHeaderClick: function (i) {
	    var opened = [].concat(_toConsumableArray(this.state.opened));
	    var created = [].concat(_toConsumableArray(this.state.created));
	    var item = this.props.items[i];
	
	    opened[i] = !opened[i];
	    created[i] = true;
	
	    if (opened[i] && item.onOpened) {
	      item.onOpened();
	    }
	
	    this.setState({ opened, created });
	  },
	
	  renderContainer: function (item, i) {
	    var _state = this.state;
	    var opened = _state.opened;
	    var created = _state.created;
	
	    var containerClassName = item.header.toLowerCase().replace(/\s/g, "-") + "-pane";
	
	    return div({ className: containerClassName, key: i }, div({ className: "_header",
	      onClick: () => this.handleHeaderClick(i) }, Svg("arrow", { className: opened[i] ? "expanded" : "" }), item.header, item.buttons ? dom.span({ className: "header-buttons" }, item.buttons.map((button, id) => span({ key: id }, button))) : null), created[i] || opened[i] ? div({ className: "_content",
	      style: { display: opened[i] ? "block" : "none" }
	    }, React.createElement(item.component, item.componentProps || {})) : null);
	  },
	
	  render: function () {
	    return div({ className: "accordion" }, this.props.items.map(this.renderContainer));
	  }
	});
	
	module.exports = Accordion;

/***/ },
/* 448 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 449 */,
/* 450 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 451 */,
/* 452 */
/***/ function(module, exports, __webpack_require__) {

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	var ImPropTypes = __webpack_require__(235);
	
	var _require = __webpack_require__(19);
	
	var connect = _require.connect;
	
	var _require2 = __webpack_require__(3);
	
	var bindActionCreators = _require2.bindActionCreators;
	
	var _require3 = __webpack_require__(259);
	
	var getSelectedSource = _require3.getSelectedSource;
	var getSourceTabs = _require3.getSourceTabs;
	var getFileSearchState = _require3.getFileSearchState;
	
	var _require4 = __webpack_require__(277);
	
	var getFilename = _require4.getFilename;
	
	var classnames = __webpack_require__(211);
	var actions = __webpack_require__(262);
	
	var _require5 = __webpack_require__(89);
	
	var isEnabled = _require5.isEnabled;
	
	var CloseButton = __webpack_require__(336);
	var Svg = __webpack_require__(310);
	var Dropdown = React.createFactory(__webpack_require__(453));
	
	var _require6 = __webpack_require__(413);
	
	var showMenu = _require6.showMenu;
	var buildMenu = _require6.buildMenu;
	
	
	__webpack_require__(454);
	__webpack_require__(456);
	
	/*
	 * Finds the hidden tabs by comparing the tabs' top offset.
	 * hidden tabs will have a great top offset.
	 *
	 * @param sourceTabs Immutable.list
	 * @param sourceTabEls HTMLCollection
	 *
	 * @returns Immutable.list
	 */
	function getHiddenTabs(sourceTabs, sourceTabEls) {
	  sourceTabEls = [].slice.call(sourceTabEls);
	  function getTopOffset() {
	    var topOffsets = sourceTabEls.map(t => t.getBoundingClientRect().top);
	    return Math.min.apply(Math, _toConsumableArray(topOffsets));
	  }
	
	  var tabTopOffset = getTopOffset();
	  return sourceTabs.filter((tab, index) => {
	    return sourceTabEls[index].getBoundingClientRect().top > tabTopOffset;
	  });
	}
	
	var SourceTabs = React.createClass({
	  propTypes: {
	    sourceTabs: ImPropTypes.list,
	    selectedSource: ImPropTypes.map,
	    selectSource: PropTypes.func.isRequired,
	    closeTab: PropTypes.func.isRequired,
	    toggleFileSearch: PropTypes.func.isRequired
	  },
	
	  displayName: "SourceTabs",
	
	  getInitialState() {
	    return {
	      dropdownShown: false,
	      hiddenSourceTabs: null
	    };
	  },
	
	  componentDidUpdate() {
	    this.updateHiddenSourceTabs(this.props.sourceTabs);
	  },
	
	  onTabContextMenu(event, tab) {
	    event.preventDefault();
	    this.showContextMenu(event, tab);
	  },
	
	  showContextMenu(e, tab) {
	    var _props = this.props;
	    var closeTab = _props.closeTab;
	    var sourceTabs = _props.sourceTabs;
	
	
	    var closeTabLabel = L10N.getStr("sourceTabs.closeTab");
	    var closeOtherTabsLabel = L10N.getStr("sourceTabs.closeOtherTabs");
	    var closeTabsToRightLabel = L10N.getStr("sourceTabs.closeTabsToRight");
	    var closeAllTabsLabel = L10N.getStr("sourceTabs.closeAllTabs");
	
	    var tabs = sourceTabs.map(t => t.get("id"));
	
	    var closeTabMenuItem = {
	      id: "node-menu-close-tab",
	      label: closeTabLabel,
	      accesskey: "C",
	      disabled: false,
	      click: () => closeTab(tab)
	    };
	
	    var closeOtherTabsMenuItem = {
	      id: "node-menu-close-other-tabs",
	      label: closeOtherTabsLabel,
	      accesskey: "O",
	      disabled: false,
	      click: () => {
	        tabs.forEach(t => {
	          if (t !== tab) {
	            closeTab(t);
	          }
	        });
	      }
	    };
	
	    var closeTabsToRightMenuItem = {
	      id: "node-menu-close-tabs-to-right",
	      label: closeTabsToRightLabel,
	      accesskey: "R",
	      disabled: false,
	      click: () => {
	        tabs.reverse().every(t => {
	          if (t === tab) {
	            return false;
	          }
	          closeTab(t);
	          return true;
	        });
	      }
	    };
	
	    var closeAllTabsMenuItem = {
	      id: "node-menu-close-all-tabs",
	      label: closeAllTabsLabel,
	      accesskey: "A",
	      disabled: false,
	      click: () => tabs.forEach(closeTab)
	    };
	
	    showMenu(e, buildMenu([{ item: closeTabMenuItem }, { item: closeOtherTabsMenuItem, hidden: () => tabs.size === 1 }, { item: closeTabsToRightMenuItem, hidden: () => tabs.some((t, i) => t === tab && tabs.size - 1 === i) }, { item: closeAllTabsMenuItem }]));
	  },
	
	  /*
	   * Updates the hiddenSourceTabs state, by
	   * finding the source tabs who have wrapped and are not on the top row.
	   */
	  updateHiddenSourceTabs(sourceTabs) {
	    if (!this.refs.sourceTabs) {
	      return;
	    }
	
	    var sourceTabEls = this.refs.sourceTabs.children;
	    var hiddenSourceTabs = getHiddenTabs(sourceTabs, sourceTabEls);
	
	    if (!hiddenSourceTabs.equals(this.state.hiddenSourceTabs)) {
	      this.setState({ hiddenSourceTabs });
	    }
	  },
	
	  toggleSourcesDropdown(e) {
	    this.setState({
	      dropdownShown: !this.state.dropdownShown
	    });
	  },
	
	  renderDropdownSource(source) {
	    var selectSource = this.props.selectSource;
	
	    var filename = getFilename(source.toJS());
	
	    return dom.li({
	      key: source.get("id"),
	      onClick: () => {
	        // const tabIndex = getLastVisibleTabIndex(sourceTabs, sourceTabEls);
	        var tabIndex = 0;
	        selectSource(source.get("id"), { tabIndex });
	      }
	    }, filename);
	  },
	
	  renderTabs() {
	    var sourceTabs = this.props.sourceTabs;
	    return dom.div({ className: "source-tabs", ref: "sourceTabs" }, sourceTabs.map(this.renderTab));
	  },
	
	  renderTab(source) {
	    var _props2 = this.props;
	    var selectedSource = _props2.selectedSource;
	    var selectSource = _props2.selectSource;
	    var closeTab = _props2.closeTab;
	
	    var filename = getFilename(source.toJS());
	    var active = source.get("id") == selectedSource.get("id");
	
	    function onClickClose(ev) {
	      ev.stopPropagation();
	      closeTab(source.get("id"));
	    }
	
	    return dom.div({
	      className: classnames("source-tab", { active }),
	      key: source.get("id"),
	      onClick: () => selectSource(source.get("id")),
	      onContextMenu: e => this.onTabContextMenu(e, source.get("id")),
	      title: source.get("url")
	    }, dom.div({ className: "filename" }, filename), CloseButton({ handleClick: onClickClose }));
	  },
	
	  renderNewButton() {
	    return dom.div({
	      className: "new-tab-btn",
	      onClick: () => this.props.toggleFileSearch(true)
	    }, Svg("plus"));
	  },
	
	  renderDropdown() {
	    var hiddenSourceTabs = this.state.hiddenSourceTabs;
	    if (!hiddenSourceTabs || hiddenSourceTabs.size == 0) {
	      return dom.div({});
	    }
	
	    return Dropdown({
	      panel: dom.ul({}, this.state.hiddenSourceTabs.map(this.renderDropdownSource))
	    });
	  },
	
	  render() {
	    if (!isEnabled("tabs")) {
	      return dom.div({ className: "source-header" });
	    }
	
	    return dom.div({ className: "source-header" }, this.renderTabs(), this.renderNewButton(), this.renderDropdown());
	  }
	});
	
	module.exports = connect(state => ({
	  selectedSource: getSelectedSource(state),
	  sourceTabs: getSourceTabs(state),
	  searchOn: getFileSearchState(state)
	}), dispatch => bindActionCreators(actions, dispatch))(SourceTabs);

/***/ },
/* 453 */
/***/ function(module, exports, __webpack_require__) {

	var React = __webpack_require__(2);
	var dom = React.DOM;
	var PropTypes = React.PropTypes;
	
	
	var Dropdown = React.createClass({
	  propTypes: {
	    panel: PropTypes.object
	  },
	
	  displayName: "Dropdown",
	
	  getInitialState() {
	    return {
	      dropdownShown: false
	    };
	  },
	
	  toggleDropdown(e) {
	    this.setState({
	      dropdownShown: !this.state.dropdownShown
	    });
	  },
	
	  renderPanel() {
	    return dom.div({
	      className: "dropdown",
	      onClick: this.toggleDropdown,
	      style: { display: this.state.dropdownShown ? "block" : "none" }
	    }, this.props.panel);
	  },
	
	  renderButton() {
	    return dom.span({
	      className: "dropdown-button",
	      onClick: this.toggleDropdown
	    }, "»");
	  },
	
	  renderMask() {
	    return dom.div({
	      className: "dropdown-mask",
	      onClick: this.toggleDropdown,
	      style: { display: this.state.dropdownShown ? "block" : "none" }
	    });
	  },
	
	  render() {
	    return dom.div({}, this.renderPanel(), this.renderButton(), this.renderMask());
	  }
	
	});
	
	module.exports = Dropdown;

/***/ },
/* 454 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 455 */,
/* 456 */
/***/ function(module, exports) {

	// removed by extract-text-webpack-plugin

/***/ },
/* 457 */,
/* 458 */
/***/ function(module, exports) {

	module.exports = {
		"breakpoints.header": "Breakpoints",
		"callStack.header": "Call Stack",
		"callStack.notPaused": "Not Paused",
		"callStack.collapse": "Collapse Rows",
		"callStack.expand": "Expand Rows",
		"editor.searchResults": "%d of %d results",
		"editor.noResults": "no results",
		"editor.addBreakpoint": "Add Breakpoint",
		"editor.removeBreakpoint": "Remove Breakpoint",
		"editor.editBreakpoint": "Edit Breakpoint",
		"editor.addConditionalBreakpoint": "Add Conditional Breakpoint",
		"scopes.header": "Scopes",
		"scopes.notAvailable": "Scopes Unavailable",
		"scopes.notPaused": "Not Paused",
		"sources.header": "Sources",
		"sources.search": "%S to search",
		"watchExpressions.header": "Watch Expressions",
		"welcome.search": "%S to search for files",
		"sourceSearch.search": "Search...",
		"sourceSearch.resultsSummary": "%d instances of \"%S\"",
		"sourceSearch.noResults": "No files matching %S found",
		"ignoreExceptions": "Ignore exceptions. Click to pause on uncaught exceptions",
		"pauseOnUncaughtExceptions": "Pause on uncaught exceptions. Click to pause on all exceptions",
		"pauseOnExceptions": "Pause on all exceptions. Click to ignore exceptions",
		"stepOutTooltip": "Step Out (%SF11)",
		"stepInTooltip": "Step In (%SF11)",
		"stepOverTooltip": "Step Over (F10)",
		"resumeButtonTooltip": "Click to resume (F8)",
		"pausePendingButtonTooltip": "Waiting for next execution",
		"pauseButtonTooltip": "Click to pause (F8)",
		"sourceTabs.closeTab": "Close tab",
		"sourceTabs.closeOtherTabs": "Close others",
		"sourceTabs.closeTabsToRight": "Close tabs to the right",
		"sourceTabs.closeAllTabs": "Close all tabs"
	};

/***/ },
/* 459 */
/***/ function(module, exports, __webpack_require__) {

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
	
	var _require = __webpack_require__(30);
	
	var sprintf = _require.sprintf;
	
	var 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) {
	  for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	    args[_key - 1] = arguments[_key];
	  }
	
	  return sprintf.apply(undefined, [getStr(name)].concat(_toConsumableArray(args)));
	}
	
	module.exports = {
	  getStr,
	  getFormatStr,
	  setBundle
	};

/***/ }
/******/ ]);
//# sourceMappingURL=bundle.js.map
