text: 'use strict';
  
  var _assign = require('object-assign');
  var invariant = require('fbjs/lib/invariant');
  var emptyObject = require('fbjs/lib/emptyObject');
  var React = require('react');
  var warning = require('fbjs/lib/warning');
  var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment');
  var performanceNow = require('fbjs/lib/performanceNow');
  var emptyFunction = require('fbjs/lib/emptyFunction');
  var checkPropTypes = require('prop-types/checkPropTypes');
  var shallowEqual = require('fbjs/lib/shallowEqual');
  
  /**
   * Copyright (c) 2013-present, 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.
   *
   * @providesModule reactProdInvariant
   * 
   */
  
  var injected$1 = false;
  
  var ReactComponentEnvironment = {
    /**
     * Optionally injectable hook for swapping out mount images in the middle of
     * the tree.
     */
    replaceNodeWithMarkup: null,
  
    /**
     * Optionally injectable hook for processing a queue of child updates. Will
     * later move into MultiChildComponents.
     */
    processChildrenUpdates: null,
  
    injection: {
      injectEnvironment: function (environment) {
        !!injected$1 ? invariant(false, 'ReactCompositeComponent: injectEnvironment() can only be called once.') : void 0;
        ReactComponentEnvironment.replaceNodeWithMarkup = environment.replaceNodeWithMarkup;
        ReactComponentEnvironment.processChildrenUpdates = environment.processChildrenUpdates;
        injected$1 = true;
      }
    }
  };
  
  var ReactComponentEnvironment_1 = ReactComponentEnvironment;
  
  /**
   * Static poolers. Several custom versions for each potential number of
   * arguments. A completely generic pooler is easy to implement, but would
   * require accessing the `arguments` object. In each of these, `this` refers to
   * the Class itself, not an instance. If any others are needed, simply add them
   * here, or in their own files.
   */
  var oneArgumentPooler = function (copyFieldsFrom) {
    var Klass = this;
    if (Klass.instancePool.length) {
      var instance = Klass.instancePool.pop();
      Klass.call(instance, copyFieldsFrom);
      return instance;
    } else {
      return new Klass(copyFieldsFrom);
    }
  };
  
  var twoArgumentPooler = function (a1, a2) {
    var Klass = this;
    if (Klass.instancePool.length) {
      var instance = Klass.instancePool.pop();
      Klass.call(instance, a1, a2);
      return instance;
    } else {
      return new Klass(a1, a2);
    }
  };
  
  var threeArgumentPooler = function (a1, a2, a3) {
    var Klass = this;
    if (Klass.instancePool.length) {
      var instance = Klass.instancePool.pop();
      Klass.call(instance, a1, a2, a3);
      return instance;
    } else {
      return new Klass(a1, a2, a3);
    }
  };
  
  var fourArgumentPooler = function (a1, a2, a3, a4) {
    var Klass = this;
    if (Klass.instancePool.length) {
      var instance = Klass.instancePool.pop();
      Klass.call(instance, a1, a2, a3, a4);
      return instance;
    } else {
      return new Klass(a1, a2, a3, a4);
    }
  };
  
  var standardReleaser = function (instance) {
    var Klass = this;
    !(instance instanceof Klass) ? invariant(false, 'Trying to release an instance into a pool of a different type.') : void 0;
    instance.destructor();
    if (Klass.instancePool.length < Klass.poolSize) {
      Klass.instancePool.push(instance);
    }
  };
  
  var DEFAULT_POOL_SIZE = 10;
  var DEFAULT_POOLER = oneArgumentPooler;
  
  /**
   * Augments `CopyConstructor` to be a poolable class, augmenting only the class
   * itself (statically) not adding any prototypical fields. Any CopyConstructor
   * you give this may have a `poolSize` property, and will look for a
   * prototypical `destructor` on instances.
   *
   * @param {Function} CopyConstructor Constructor that can be used to reset.
   * @param {Function} pooler Customizable pooler.
   */
  var addPoolingTo = function (CopyConstructor, pooler) {
    // Casting as any so that flow ignores the actual implementation and trusts
    // it to match the type we declared
    var NewKlass = CopyConstructor;
    NewKlass.instancePool = [];
    NewKlass.getPooled = pooler || DEFAULT_POOLER;
    if (!NewKlass.poolSize) {
      NewKlass.poolSize = DEFAULT_POOL_SIZE;
    }
    NewKlass.release = standardReleaser;
    return NewKlass;
  };
  
  var PooledClass = {
    addPoolingTo: addPoolingTo,
    oneArgumentPooler: oneArgumentPooler,
    twoArgumentPooler: twoArgumentPooler,
    threeArgumentPooler: threeArgumentPooler,
    fourArgumentPooler: fourArgumentPooler
  };
  
  var PooledClass_1 = PooledClass;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule ReactFeatureFlags
   * 
   */
  
  var ReactFeatureFlags = {
    // When true, call console.time() before and .timeEnd() after each top-level
    // render (both initial renders and updates). Useful when looking at prod-mode
    // timeline profiles in Chrome, for example.
    logTopLevelRenders: false,
    prepareNewChildrenBeforeUnmountInStack: true,
    disableNewFiberFeatures: false,
    enableAsyncSubtreeAPI: false
  };
  
  var ReactFeatureFlags_1 = ReactFeatureFlags;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule ReactTypeOfWork
   * 
   */
  
  var ReactTypeOfWork = {
    IndeterminateComponent: 0, // Before we know whether it is functional or class
    FunctionalComponent: 1,
    ClassComponent: 2,
    HostRoot: 3, // Root of a host tree. Could be nested inside another node.
    HostPortal: 4, // A subtree. Could be an entry point to a different renderer.
    HostComponent: 5,
    HostText: 6,
    CoroutineComponent: 7,
    CoroutineHandlerPhase: 8,
    YieldComponent: 9,
    Fragment: 10
  };
  
  var ClassComponent = ReactTypeOfWork.ClassComponent;
  
  
  
  
  /**
   * @param {?object} object
   * @return {boolean} True if `object` is a valid owner.
   * @final
   */
  function isValidOwner(object) {
    return !!(object && typeof object.attachRef === 'function' && typeof object.detachRef === 'function');
  }
  
  /**
   * ReactOwners are capable of storing references to owned components.
   *
   * All components are capable of //being// referenced by owner components, but
   * only ReactOwner components are capable of //referencing// owned components.
   * The named reference is known as a "ref".
   *
   * Refs are available when mounted and updated during reconciliation.
   *
   *   var MyComponent = React.createClass({
   *     render: function() {
   *       return (
   *         <div onClick={this.handleClick}>
   *           <CustomComponent ref="custom" />
   *         </div>
   *       );
   *     },
   *     handleClick: function() {
   *       this.refs.custom.handleClick();
   *     },
   *     componentDidMount: function() {
   *       this.refs.custom.initialize();
   *     }
   *   });
   *
   * Refs should rarely be used. When refs are used, they should only be done to
   * control data that is not handled by React's data flow.
   *
   * @class ReactOwner
   */
  var ReactOwner = {
    /**
     * Adds a component by ref to an owner component.
     *
     * @param {ReactComponent} component Component to reference.
     * @param {string} ref Name by which to refer to the component.
     * @param {ReactOwner} owner Component on which to record the ref.
     * @final
     * @internal
     */
    addComponentAsRefTo: function (component, ref, owner) {
      if (owner && owner.tag === ClassComponent) {
        var inst = owner.stateNode;
        var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs;
        refs[ref] = component.getPublicInstance();
      } else {
        !isValidOwner(owner) ? invariant(false, 'addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : void 0;
        owner.attachRef(ref, component);
      }
    },
  
    /**
     * Removes a component by ref from an owner component.
     *
     * @param {ReactComponent} component Component to dereference.
     * @param {string} ref Name of the ref to remove.
     * @param {ReactOwner} owner Component on which the ref is recorded.
     * @final
     * @internal
     */
    removeComponentAsRefFrom: function (component, ref, owner) {
      if (owner && owner.tag === ClassComponent) {
        var inst = owner.stateNode;
        if (inst && inst.refs[ref] === component.getPublicInstance()) {
          delete inst.refs[ref];
        }
      } else {
        !isValidOwner(owner) ? invariant(false, 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. You might be removing a ref to a component that was not created inside a component\'s `render` method, or you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner).') : void 0;
        var ownerPublicInstance = owner.getPublicInstance();
        // Check that `component`'s owner is still alive and that `component` is still the current ref
        // because we do not want to detach the ref if another component stole it.
        if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) {
          owner.detachRef(ref);
        }
      }
    }
  };
  
  var ReactOwner_1 = ReactOwner;
  
  var ReactCompositeComponentTypes$1 = {
    ImpureClass: 0,
    PureClass: 1,
    StatelessFunctional: 2
  }; /**
      * Copyright 2013-present, 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.
      *
      * @providesModule ReactCompositeComponentTypes
      * 
      */
  
  var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
  
  var ReactGlobalSharedState = {
    ReactCurrentOwner: ReactInternals.ReactCurrentOwner
  };
  
  {
    _assign(ReactGlobalSharedState, {
      ReactComponentTreeHook: ReactInternals.ReactComponentTreeHook,
      ReactDebugCurrentFrame: ReactInternals.ReactDebugCurrentFrame
    });
  }
  
  var ReactGlobalSharedState_1 = ReactGlobalSharedState;
  
  var ReactRef = {};
  
  {
    var ReactCompositeComponentTypes = ReactCompositeComponentTypes$1;
  
    var _require = ReactGlobalSharedState_1,
        ReactComponentTreeHook = _require.ReactComponentTreeHook;
  
    var warning$1 = warning;
  
    var warnedAboutStatelessRefs = {};
  }
  
  function attachRef(ref, component, owner) {
    {
      if (component._compositeType === ReactCompositeComponentTypes.StatelessFunctional) {
        var info = '';
        var ownerName = void 0;
        if (owner) {
          if (typeof owner.getName === 'function') {
            ownerName = owner.getName();
          }
          if (ownerName) {
            info += '\n\nCheck the render method of `' + ownerName + '`.';
          }
        }
  
        var warningKey = ownerName || component._debugID;
        var element = component._currentElement;
        if (element && element._source) {
          warningKey = element._source.fileName + ':' + element._source.lineNumber;
        }
        if (!warnedAboutStatelessRefs[warningKey]) {
          warnedAboutStatelessRefs[warningKey] = true;
          warning$1(false, 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, ReactComponentTreeHook.getStackAddendumByID(component._debugID));
        }
      }
    }
  
    if (typeof ref === 'function') {
      ref(component.getPublicInstance());
    } else {
      // Legacy ref
      ReactOwner_1.addComponentAsRefTo(component, ref, owner);
    }
  }
  
  function detachRef(ref, component, owner) {
    if (typeof ref === 'function') {
      ref(null);
    } else {
      // Legacy ref
      ReactOwner_1.removeComponentAsRefFrom(component, ref, owner);
    }
  }
  
  ReactRef.attachRefs = function (instance, element) {
    if (element === null || typeof element !== 'object') {
      return;
    }
    var ref = element.ref;
    if (ref != null) {
      attachRef(ref, instance, element._owner);
    }
  };
  
  ReactRef.shouldUpdateRefs = function (prevElement, nextElement) {
    // If either the owner or a `ref` has changed, make sure the newest owner
    // has stored a reference to `this`, and the previous owner (if different)
    // has forgotten the reference to `this`. We use the element instead
    // of the public this.props because the post processing cannot determine
    // a ref. The ref conceptually lives on the element.
  
    // TODO: Should this even be possible? The owner cannot change because
    // it's forbidden by shouldUpdateReactComponent. The ref can change
    // if you swap the keys of but not the refs. Reconsider where this check
    // is made. It probably belongs where the key checking and
    // instantiateReactComponent is done.
  
    var prevRef = null;
    var prevOwner = null;
    if (prevElement !== null && typeof prevElement === 'object') {
      prevRef = prevElement.ref;
      prevOwner = prevElement._owner;
    }
  
    var nextRef = null;
    var nextOwner = null;
    if (nextElement !== null && typeof nextElement === 'object') {
      nextRef = nextElement.ref;
      nextOwner = nextElement._owner;
    }
  
    return prevRef !== nextRef ||
    // If owner changes but we have an unchanged function ref, don't update refs
    typeof nextRef === 'string' && nextOwner !== prevOwner;
  };
  
  ReactRef.detachRefs = function (instance, element) {
    if (element === null || typeof element !== 'object') {
      return;
    }
    var ref = element.ref;
    if (ref != null) {
      detachRef(ref, instance, element._owner);
    }
  };
  
  var ReactRef_1 = ReactRef;
  
  var ReactInvalidSetStateWarningHook = {};
  
  {
    var processingChildContext = false;
  
    var warnInvalidSetState = function () {
      warning(!processingChildContext, 'setState(...): Cannot call setState() inside getChildContext()');
    };
  
    ReactInvalidSetStateWarningHook = {
      onBeginProcessingChildContext: function () {
        processingChildContext = true;
      },
      onEndProcessingChildContext: function () {
        processingChildContext = false;
      },
      onSetState: function () {
        warnInvalidSetState();
      }
    };
  }
  
  var ReactInvalidSetStateWarningHook_1 = ReactInvalidSetStateWarningHook;
  
  /**
   * Copyright 2016-present, 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.
   *
   * @providesModule ReactHostOperationHistoryHook
   * 
   */
  
  // Trust the developer to only use this with a true check
  var ReactHostOperationHistoryHook = null;
  
  {
    var history = [];
  
    ReactHostOperationHistoryHook = {
      onHostOperation: function (operation) {
        history.push(operation);
      },
      clearHistory: function () {
        if (ReactHostOperationHistoryHook._preventClearing) {
          // Should only be used for tests.
          return;
        }
  
        history = [];
      },
      getHistory: function () {
        return history;
      }
    };
  }
  
  var ReactHostOperationHistoryHook_1 = ReactHostOperationHistoryHook;
  
  var ReactComponentTreeHook$1 = ReactGlobalSharedState_1.ReactComponentTreeHook;
  
  
  
  
  // Trust the developer to only use this with a true check
  var ReactDebugTool$1 = null;
  
  {
    var hooks = [];
    var didHookThrowForEvent = {};
  
    var callHook = function (event, fn, context, arg1, arg2, arg3, arg4, arg5) {
      try {
        fn.call(context, arg1, arg2, arg3, arg4, arg5);
      } catch (e) {
        warning(didHookThrowForEvent[event], 'Exception thrown by hook while handling %s: %s', event, e + '\n' + e.stack);
        didHookThrowForEvent[event] = true;
      }
    };
  
    var emitEvent = function (event, arg1, arg2, arg3, arg4, arg5) {
      for (var i = 0; i < hooks.length; i++) {
        var hook = hooks[i];
        var fn = hook[event];
        if (fn) {
          callHook(event, fn, hook, arg1, arg2, arg3, arg4, arg5);
        }
      }
    };
  
    var isProfiling = false;
    var flushHistory = [];
    var lifeCycleTimerStack = [];
    var currentFlushNesting = 0;
    var currentFlushMeasurements = [];
    var currentFlushStartTime = 0;
    var currentTimerDebugID = null;
    var currentTimerStartTime = 0;
    var currentTimerNestedFlushDuration = 0;
    var currentTimerType = null;
  
    var lifeCycleTimerHasWarned = false;
  
    var clearHistory = function () {
      ReactComponentTreeHook$1.purgeUnmountedComponents();
      ReactHostOperationHistoryHook_1.clearHistory();
    };
  
    var getTreeSnapshot = function (registeredIDs) {
      return registeredIDs.reduce(function (tree, id) {
        var ownerID = ReactComponentTreeHook$1.getOwnerID(id);
        var parentID = ReactComponentTreeHook$1.getParentID(id);
        tree[id] = {
          displayName: ReactComponentTreeHook$1.getDisplayName(id),
          text: ReactComponentTreeHook$1.getText(id),
          updateCount: ReactComponentTreeHook$1.getUpdateCount(id),
          childIDs: ReactComponentTreeHook$1.getChildIDs(id),
          // Text nodes don't have owners but this is close enough.
          ownerID: ownerID || parentID && ReactComponentTreeHook$1.getOwnerID(parentID) || 0,
          parentID: parentID
        };
        return tree;
      }, {});
    };
  
    var resetMeasurements = function () {
      var previousStartTime = currentFlushStartTime;
      var previousMeasurements = currentFlushMeasurements;
      var previousOperations = ReactHostOperationHistoryHook_1.getHistory();
  
      if (currentFlushNesting === 0) {
        currentFlushStartTime = 0;
        currentFlushMeasurements = [];
        clearHistory();
        return;
      }
  
      if (previousMeasurements.length || previousOperations.length) {
        var registeredIDs = ReactComponentTreeHook$1.getRegisteredIDs();
        flushHistory.push({
          duration: performanceNow() - previousStartTime,
          measurements: previousMeasurements || [],
          operations: previousOperations || [],
          treeSnapshot: getTreeSnapshot(registeredIDs)
        });
      }
  
      clearHistory();
      currentFlushStartTime = performanceNow();
      currentFlushMeasurements = [];
    };
  
    var checkDebugID = function (debugID) {
      var allowRoot = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
      if (allowRoot && debugID === 0) {
        return;
      }
      if (!debugID) {
        warning(false, 'ReactDebugTool: debugID may not be empty.');
      }
    };
  
    var beginLifeCycleTimer = function (debugID, timerType) {
      if (currentFlushNesting === 0) {
        return;
      }
      if (currentTimerType && !lifeCycleTimerHasWarned) {
        warning(false, 'There is an internal error in the React performance measurement code.' + '\n\nDid not expect %s timer to start while %s timer is still in ' + 'progress for %s instance.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another');
        lifeCycleTimerHasWarned = true;
      }
      currentTimerStartTime = performanceNow();
      currentTimerNestedFlushDuration = 0;
      currentTimerDebugID = debugID;
      currentTimerType = timerType;
    };
  
    var endLifeCycleTimer = function (debugID, timerType) {
      if (currentFlushNesting === 0) {
        return;
      }
      if (currentTimerType !== timerType && !lifeCycleTimerHasWarned) {
        warning(false, 'There is an internal error in the React performance measurement code. ' + 'We did not expect %s timer to stop while %s timer is still in ' + 'progress for %s instance. Please report this as a bug in React.', timerType, currentTimerType || 'no', debugID === currentTimerDebugID ? 'the same' : 'another');
        lifeCycleTimerHasWarned = true;
      }
      if (isProfiling) {
        currentFlushMeasurements.push({
          timerType: timerType,
          instanceID: debugID,
          duration: performanceNow() - currentTimerStartTime - currentTimerNestedFlushDuration
        });
      }
      currentTimerStartTime = 0;
      currentTimerNestedFlushDuration = 0;
      currentTimerDebugID = null;
      currentTimerType = null;
    };
  
    var pauseCurrentLifeCycleTimer = function () {
      var currentTimer = {
        startTime: currentTimerStartTime,
        nestedFlushStartTime: performanceNow(),
        debugID: currentTimerDebugID,
        timerType: currentTimerType
      };
      lifeCycleTimerStack.push(currentTimer);
      currentTimerStartTime = 0;
      currentTimerNestedFlushDuration = 0;
      currentTimerDebugID = null;
      currentTimerType = null;
    };
  
    var resumeCurrentLifeCycleTimer = function () {
      var _lifeCycleTimerStack$ = lifeCycleTimerStack.pop(),
          startTime = _lifeCycleTimerStack$.startTime,
          nestedFlushStartTime = _lifeCycleTimerStack$.nestedFlushStartTime,
          debugID = _lifeCycleTimerStack$.debugID,
          timerType = _lifeCycleTimerStack$.timerType;
  
      var nestedFlushDuration = performanceNow() - nestedFlushStartTime;
      currentTimerStartTime = startTime;
      currentTimerNestedFlushDuration += nestedFlushDuration;
      currentTimerDebugID = debugID;
      currentTimerType = timerType;
    };
  
    var lastMarkTimeStamp = 0;
    var canUsePerformanceMeasure = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
  
    var shouldMark = function (debugID) {
      if (!isProfiling || !canUsePerformanceMeasure) {
        return false;
      }
      var element = ReactComponentTreeHook$1.getElement(debugID);
      if (element == null || typeof element !== 'object') {
        return false;
      }
      var isHostElement = typeof element.type === 'string';
      if (isHostElement) {
        return false;
      }
      return true;
    };
  
    var markBegin = function (debugID, markType) {
      if (!shouldMark(debugID)) {
        return;
      }
  
      var markName = debugID + '::' + markType;
      lastMarkTimeStamp = performanceNow();
      performance.mark(markName);
    };
  
    var markEnd = function (debugID, markType) {
      if (!shouldMark(debugID)) {
        return;
      }
  
      var markName = debugID + '::' + markType;
      var displayName = ReactComponentTreeHook$1.getDisplayName(debugID) || 'Unknown';
  
      // Chrome has an issue of dropping markers recorded too fast:
      // https://bugs.chromium.org/p/chromium/issues/detail?id=640652
      // To work around this, we will not report very small measurements.
      // I determined the magic number by tweaking it back and forth.
      // 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe.
      // When the bug is fixed, we can `measure()` unconditionally if we want to.
      var timeStamp = performanceNow();
      if (timeStamp - lastMarkTimeStamp > 0.1) {
        var measurementName = displayName + ' [' + markType + ']';
        performance.measure(measurementName, markName);
      }
  
      performance.clearMarks(markName);
      if (measurementName) {
        performance.clearMeasures(measurementName);
      }
    };
  
    ReactDebugTool$1 = {
      addHook: function (hook) {
        hooks.push(hook);
      },
      removeHook: function (hook) {
        for (var i = 0; i < hooks.length; i++) {
          if (hooks[i] === hook) {
            hooks.splice(i, 1);
            i--;
          }
        }
      },
      isProfiling: function () {
        return isProfiling;
      },
      beginProfiling: function () {
        if (isProfiling) {
          return;
        }
  
        isProfiling = true;
        flushHistory.length = 0;
        resetMeasurements();
        ReactDebugTool$1.addHook(ReactHostOperationHistoryHook_1);
      },
      endProfiling: function () {
        if (!isProfiling) {
          return;
        }
  
        isProfiling = false;
        resetMeasurements();
        ReactDebugTool$1.removeHook(ReactHostOperationHistoryHook_1);
      },
      getFlushHistory: function () {
        return flushHistory;
      },
      onBeginFlush: function () {
        currentFlushNesting++;
        resetMeasurements();
        pauseCurrentLifeCycleTimer();
        emitEvent('onBeginFlush');
      },
      onEndFlush: function () {
        resetMeasurements();
        currentFlushNesting--;
        resumeCurrentLifeCycleTimer();
        emitEvent('onEndFlush');
      },
      onBeginLifeCycleTimer: function (debugID, timerType) {
        checkDebugID(debugID);
        emitEvent('onBeginLifeCycleTimer', debugID, timerType);
        markBegin(debugID, timerType);
        beginLifeCycleTimer(debugID, timerType);
      },
      onEndLifeCycleTimer: function (debugID, timerType) {
        checkDebugID(debugID);
        endLifeCycleTimer(debugID, timerType);
        markEnd(debugID, timerType);
        emitEvent('onEndLifeCycleTimer', debugID, timerType);
      },
      onBeginProcessingChildContext: function () {
        emitEvent('onBeginProcessingChildContext');
      },
      onEndProcessingChildContext: function () {
        emitEvent('onEndProcessingChildContext');
      },
      onHostOperation: function (operation) {
        checkDebugID(operation.instanceID);
        emitEvent('onHostOperation', operation);
      },
      onSetState: function () {
        emitEvent('onSetState');
      },
      onSetChildren: function (debugID, childDebugIDs) {
        checkDebugID(debugID);
        childDebugIDs.forEach(checkDebugID);
        emitEvent('onSetChildren', debugID, childDebugIDs);
      },
      onBeforeMountComponent: function (debugID, element, parentDebugID) {
        checkDebugID(debugID);
        checkDebugID(parentDebugID, true);
        emitEvent('onBeforeMountComponent', debugID, element, parentDebugID);
        markBegin(debugID, 'mount');
      },
      onMountComponent: function (debugID) {
        checkDebugID(debugID);
        markEnd(debugID, 'mount');
        emitEvent('onMountComponent', debugID);
      },
      onBeforeUpdateComponent: function (debugID, element) {
        checkDebugID(debugID);
        emitEvent('onBeforeUpdateComponent', debugID, element);
        markBegin(debugID, 'update');
      },
      onUpdateComponent: function (debugID) {
        checkDebugID(debugID);
        markEnd(debugID, 'update');
        emitEvent('onUpdateComponent', debugID);
      },
      onBeforeUnmountComponent: function (debugID) {
        checkDebugID(debugID);
        emitEvent('onBeforeUnmountComponent', debugID);
        markBegin(debugID, 'unmount');
      },
      onUnmountComponent: function (debugID) {
        checkDebugID(debugID);
        markEnd(debugID, 'unmount');
        emitEvent('onUnmountComponent', debugID);
      },
      onTestEvent: function () {
        emitEvent('onTestEvent');
      }
    };
  
    ReactDebugTool$1.addHook(ReactInvalidSetStateWarningHook_1);
    ReactDebugTool$1.addHook(ReactComponentTreeHook$1);
    var url = ExecutionEnvironment.canUseDOM && window.location.href || '';
    if (/[?&]react_perf\b/.test(url)) {
      ReactDebugTool$1.beginProfiling();
    }
  }
  
  var ReactDebugTool_1 = ReactDebugTool$1;
  
  // Trust the developer to only use ReactInstrumentation with a true check
  
  var debugTool = null;
  
  {
    var ReactDebugTool = ReactDebugTool_1;
    debugTool = ReactDebugTool;
  }
  
  var ReactInstrumentation = { debugTool: debugTool };
  
  /**
   * Helper to call ReactRef.attachRefs with this composite component, split out
   * to avoid allocations in the transaction mount-ready queue.
   */
  function attachRefs() {
    ReactRef_1.attachRefs(this, this._currentElement);
  }
  
  var ReactReconciler = {
    /**
     * Initializes the component, renders markup, and registers event listeners.
     *
     * @param {ReactComponent} internalInstance
     * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
     * @param {?object} the containing host component instance
     * @param {?object} info about the host container
     * @return {?string} Rendered markup to be inserted into the DOM.
     * @final
     * @internal
     */
    mountComponent: function (internalInstance, transaction, hostParent, hostContainerInfo, context, parentDebugID) // 0 in production and for roots
    {
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onBeforeMountComponent(internalInstance._debugID, internalInstance._currentElement, parentDebugID);
        }
      }
      var markup = internalInstance.mountComponent(transaction, hostParent, hostContainerInfo, context, parentDebugID);
      if (internalInstance._currentElement && internalInstance._currentElement.ref != null) {
        transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
      }
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID);
        }
      }
      return markup;
    },
  
    /**
     * Returns a value that can be passed to
     * ReactComponentEnvironment.replaceNodeWithMarkup.
     */
    getHostNode: function (internalInstance) {
      return internalInstance.getHostNode();
    },
  
    /**
     * Releases any resources allocated by `mountComponent`.
     *
     * @final
     * @internal
     */
    unmountComponent: function (internalInstance, safely, skipLifecycle) {
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onBeforeUnmountComponent(internalInstance._debugID);
        }
      }
      ReactRef_1.detachRefs(internalInstance, internalInstance._currentElement);
      internalInstance.unmountComponent(safely, skipLifecycle);
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID);
        }
      }
    },
  
    /**
     * Update a component using a new element.
     *
     * @param {ReactComponent} internalInstance
     * @param {ReactElement} nextElement
     * @param {ReactReconcileTransaction} transaction
     * @param {object} context
     * @internal
     */
    receiveComponent: function (internalInstance, nextElement, transaction, context) {
      var prevElement = internalInstance._currentElement;
  
      if (nextElement === prevElement && context === internalInstance._context) {
        // Since elements are immutable after the owner is rendered,
        // we can do a cheap identity compare here to determine if this is a
        // superfluous reconcile. It's possible for state to be mutable but such
        // change should trigger an update of the owner which would recreate
        // the element. We explicitly check for the existence of an owner since
        // it's possible for an element created outside a composite to be
        // deeply mutated and reused.
  
        // TODO: Bailing out early is just a perf optimization right?
        // TODO: Removing the return statement should affect correctness?
        return;
      }
  
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, nextElement);
        }
      }
  
      var refsChanged = ReactRef_1.shouldUpdateRefs(prevElement, nextElement);
  
      if (refsChanged) {
        ReactRef_1.detachRefs(internalInstance, prevElement);
      }
  
      internalInstance.receiveComponent(nextElement, transaction, context);
  
      if (refsChanged && internalInstance._currentElement && internalInstance._currentElement.ref != null) {
        transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
      }
  
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
        }
      }
    },
  
    /**
     * Flush any dirty changes in a component.
     *
     * @param {ReactComponent} internalInstance
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    performUpdateIfNecessary: function (internalInstance, transaction, updateBatchNumber) {
      if (internalInstance._updateBatchNumber !== updateBatchNumber) {
        // The component's enqueued batch number should always be the current
        // batch or the following one.
        warning(internalInstance._updateBatchNumber == null || internalInstance._updateBatchNumber === updateBatchNumber + 1, 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + 'pending %s)', updateBatchNumber, internalInstance._updateBatchNumber);
        return;
      }
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onBeforeUpdateComponent(internalInstance._debugID, internalInstance._currentElement);
        }
      }
      internalInstance.performUpdateIfNecessary(transaction);
      {
        if (internalInstance._debugID !== 0) {
          ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
        }
      }
    }
  };
  
  var ReactReconciler_1 = ReactReconciler;
  
  var OBSERVED_ERROR = {};
  
  /**
   * `Transaction` creates a black box that is able to wrap any method such that
   * certain invariants are maintained before and after the method is invoked
   * (Even if an exception is thrown while invoking the wrapped method). Whoever
   * instantiates a transaction can provide enforcers of the invariants at
   * creation time. The `Transaction` class itself will supply one additional
   * automatic invariant for you - the invariant that any transaction instance
   * should not be run while it is already being run. You would typically create a
   * single instance of a `Transaction` for reuse multiple times, that potentially
   * is used to wrap several different methods. Wrappers are extremely simple -
   * they only require implementing two methods.
   *
   * <pre>
   *                       wrappers (injected at creation time)
   *                                      +        +
   *                                      |        |
   *                    +-----------------|--------|--------------+
   *                    |                 v        |              |
   *                    |      +---------------+   |              |
   *                    |   +--|    wrapper1   |---|----+         |
   *                    |   |  +---------------+   v    |         |
   *                    |   |          +-------------+  |         |
   *                    |   |     +----|   wrapper2  |--------+   |
   *                    |   |     |    +-------------+  |     |   |
   *                    |   |     |                     |     |   |
   *                    |   v     v                     v     v   | wrapper
   *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
   * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
   * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
   *                    | |   | |   |   |         |   |   | |   | |
   *                    | |   | |   |   |         |   |   | |   | |
   *                    | |   | |   |   |         |   |   | |   | |
   *                    | +---+ +---+   +---------+   +---+ +---+ |
   *                    |  initialize                    close    |
   *                    +-----------------------------------------+
   * </pre>
   *
   * Use cases:
   * - Preserving the input selection ranges before/after reconciliation.
   *   Restoring selection even in the event of an unexpected error.
   * - Deactivating events while rearranging the DOM, preventing blurs/focuses,
   *   while guaranteeing that afterwards, the event system is reactivated.
   * - Flushing a queue of collected DOM mutations to the main UI thread after a
   *   reconciliation takes place in a worker thread.
   * - Invoking any collected `componentDidUpdate` callbacks after rendering new
   *   content.
   * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue
   *   to preserve the `scrollTop` (an automatic scroll aware DOM).
   * - (Future use case): Layout calculations before and after DOM updates.
   *
   * Transactional plugin API:
   * - A module that has an `initialize` method that returns any precomputation.
   * - and a `close` method that accepts the precomputation. `close` is invoked
   *   when the wrapped process is completed, or has failed.
   *
   * @param {Array<TransactionalWrapper>} transactionWrapper Wrapper modules
   * that implement `initialize` and `close`.
   * @return {Transaction} Single transaction for reuse in thread.
   *
   * @class Transaction
   */
  var TransactionImpl = {
    /**
     * Sets up this instance so that it is prepared for collecting metrics. Does
     * so such that this setup method may be used on an instance that is already
     * initialized, in a way that does not consume additional memory upon reuse.
     * That can be useful if you decide to make your subclass of this mixin a
     * "PooledClass".
     */
    reinitializeTransaction: function () {
      this.transactionWrappers = this.getTransactionWrappers();
      if (this.wrapperInitData) {
        this.wrapperInitData.length = 0;
      } else {
        this.wrapperInitData = [];
      }
      this._isInTransaction = false;
    },
  
    _isInTransaction: false,
  
    /**
     * @abstract
     * @return {Array<TransactionWrapper>} Array of transaction wrappers.
     */
    getTransactionWrappers: null,
  
    isInTransaction: function () {
      return !!this._isInTransaction;
    },
  
    /**
     * Executes the function within a safety window. Use this for the top level
     * methods that result in large amounts of computation/mutations that would
     * need to be safety checked. The optional arguments helps prevent the need
     * to bind in many cases.
     *
     * @param {function} method Member of scope to call.
     * @param {Object} scope Scope to invoke from.
     * @param {Object?=} a Argument to pass to the method.
     * @param {Object?=} b Argument to pass to the method.
     * @param {Object?=} c Argument to pass to the method.
     * @param {Object?=} d Argument to pass to the method.
     * @param {Object?=} e Argument to pass to the method.
     * @param {Object?=} f Argument to pass to the method.
     *
     * @return {*} Return value from `method`.
     */
    perform: function (method, scope, a, b, c, d, e, f) {
      !!this.isInTransaction() ? invariant(false, 'Transaction.perform(...): Cannot initialize a transaction when there is already an outstanding transaction.') : void 0;
      var errorThrown;
      var ret;
      try {
        this._isInTransaction = true;
        // Catching errors makes debugging more difficult, so we start with
        // errorThrown set to true before setting it to false after calling
        // close -- if it's still set to true in the finally block, it means
        // one of these calls threw.
        errorThrown = true;
        this.initializeAll(0);
        ret = method.call(scope, a, b, c, d, e, f);
        errorThrown = false;
      } finally {
        try {
          if (errorThrown) {
            // If `method` throws, prefer to show that stack trace over any thrown
            // by invoking `closeAll`.
            try {
              this.closeAll(0);
            } catch (err) {}
          } else {
            // Since `method` didn't throw, we don't want to silence the exception
            // here.
            this.closeAll(0);
          }
        } finally {
          this._isInTransaction = false;
        }
      }
      return ret;
    },
  
    initializeAll: function (startIndex) {
      var transactionWrappers = this.transactionWrappers;
      for (var i = startIndex; i < transactionWrappers.length; i++) {
        var wrapper = transactionWrappers[i];
        try {
          // Catching errors makes debugging more difficult, so we start with the
          // OBSERVED_ERROR state before overwriting it with the real return value
          // of initialize -- if it's still set to OBSERVED_ERROR in the finally
          // block, it means wrapper.initialize threw.
          this.wrapperInitData[i] = OBSERVED_ERROR;
          this.wrapperInitData[i] = wrapper.initialize ? wrapper.initialize.call(this) : null;
        } finally {
          if (this.wrapperInitData[i] === OBSERVED_ERROR) {
            // The initializer for wrapper i threw an error; initialize the
            // remaining wrappers but silence any exceptions from them to ensure
            // that the first error is the one to bubble up.
            try {
              this.initializeAll(i + 1);
            } catch (err) {}
          }
        }
      }
    },
  
    /**
     * Invokes each of `this.transactionWrappers.close[i]` functions, passing into
     * them the respective return values of `this.transactionWrappers.init[i]`
     * (`close`rs that correspond to initializers that failed will not be
     * invoked).
     */
    closeAll: function (startIndex) {
      !this.isInTransaction() ? invariant(false, 'Transaction.closeAll(): Cannot close transaction when none are open.') : void 0;
      var transactionWrappers = this.transactionWrappers;
      for (var i = startIndex; i < transactionWrappers.length; i++) {
        var wrapper = transactionWrappers[i];
        var initData = this.wrapperInitData[i];
        var errorThrown;
        try {
          // Catching errors makes debugging more difficult, so we start with
          // errorThrown set to true before setting it to false after calling
          // close -- if it's still set to true in the finally block, it means
          // wrapper.close threw.
          errorThrown = true;
          if (initData !== OBSERVED_ERROR && wrapper.close) {
            wrapper.close.call(this, initData);
          }
          errorThrown = false;
        } finally {
          if (errorThrown) {
            // The closer for wrapper i threw an error; close the remaining
            // wrappers but silence any exceptions from them to ensure that the
            // first error is the one to bubble up.
            try {
              this.closeAll(i + 1);
            } catch (e) {}
          }
        }
      }
      this.wrapperInitData.length = 0;
    }
  };
  
  var Transaction = TransactionImpl;
  
  var dirtyComponents = [];
  var updateBatchNumber = 0;
  
  var batchingStrategy = null;
  
  function ensureInjected() {
    !(ReactUpdates.ReactReconcileTransaction && batchingStrategy) ? invariant(false, 'ReactUpdates: must inject a reconcile transaction class and batching strategy') : void 0;
  }
  
  var NESTED_UPDATES = {
    initialize: function () {
      this.dirtyComponentsLength = dirtyComponents.length;
    },
    close: function () {
      if (this.dirtyComponentsLength !== dirtyComponents.length) {
        // Additional updates were enqueued by componentDidUpdate handlers or
        // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run
        // these new updates so that if A's componentDidUpdate calls setState on
        // B, B will update before the callback A's updater provided when calling
        // setState.
        dirtyComponents.splice(0, this.dirtyComponentsLength);
        flushBatchedUpdates();
      } else {
        dirtyComponents.length = 0;
      }
    }
  };
  
  var TRANSACTION_WRAPPERS$1 = [NESTED_UPDATES];
  
  function ReactUpdatesFlushTransaction() {
    this.reinitializeTransaction();
    this.dirtyComponentsLength = null;
    this.reconcileTransaction = ReactUpdates.ReactReconcileTransaction.getPooled(
    /* useCreateElement */true);
  }
  
  _assign(ReactUpdatesFlushTransaction.prototype, Transaction, {
    getTransactionWrappers: function () {
      return TRANSACTION_WRAPPERS$1;
    },
  
    destructor: function () {
      this.dirtyComponentsLength = null;
      ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction);
      this.reconcileTransaction = null;
    },
  
    perform: function (method, scope, a) {
      // Essentially calls `this.reconcileTransaction.perform(method, scope, a)`
      // with this transaction's wrappers around it.
      return Transaction.perform.call(this, this.reconcileTransaction.perform, this.reconcileTransaction, method, scope, a);
    }
  });
  
  PooledClass_1.addPoolingTo(ReactUpdatesFlushTransaction);
  
  function batchedUpdates(callback, a, b, c, d, e) {
    ensureInjected();
    return batchingStrategy.batchedUpdates(callback, a, b, c, d, e);
  }
  
  /**
   * Array comparator for ReactComponents by mount ordering.
   *
   * @param {ReactComponent} c1 first component you're comparing
   * @param {ReactComponent} c2 second component you're comparing
   * @return {number} Return value usable by Array.prototype.sort().
   */
  function mountOrderComparator(c1, c2) {
    return c1._mountOrder - c2._mountOrder;
  }
  
  function runBatchedUpdates(transaction) {
    var len = transaction.dirtyComponentsLength;
    !(len === dirtyComponents.length) ? invariant(false, 'Expected flush transaction\'s stored dirty-components length (%s) to match dirty-components array length (%s).', len, dirtyComponents.length) : void 0;
  
    // Since reconciling a component higher in the owner hierarchy usually (not
    // always -- see shouldComponentUpdate()) will reconcile children, reconcile
    // them before their children by sorting the array.
    dirtyComponents.sort(mountOrderComparator);
  
    // Any updates enqueued while reconciling must be performed after this entire
    // batch. Otherwise, if dirtyComponents is [A, B] where A has children B and
    // C, B could update twice in a single batch if C's render enqueues an update
    // to B (since B would have already updated, we should skip it, and the only
    // way we can know to do so is by checking the batch counter).
    updateBatchNumber++;
  
    for (var i = 0; i < len; i++) {
      // If a component is unmounted before pending changes apply, it will still
      // be here, but we assume that it has cleared its _pendingCallbacks and
      // that performUpdateIfNecessary is a noop.
      var component = dirtyComponents[i];
  
      var markerName;
      if (ReactFeatureFlags_1.logTopLevelRenders) {
        var namedComponent = component;
        // Duck type TopLevelWrapper. This is probably always true.
        if (component._currentElement.type.isReactTopLevelWrapper) {
          namedComponent = component._renderedComponent;
        }
        markerName = 'React update: ' + namedComponent.getName();
        console.time(markerName);
      }
  
      ReactReconciler_1.performUpdateIfNecessary(component, transaction.reconcileTransaction, updateBatchNumber);
  
      if (markerName) {
        console.timeEnd(markerName);
      }
    }
  }
  
  var flushBatchedUpdates = function () {
    // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
    // array and perform any updates enqueued by mount-ready handlers (i.e.,
    // componentDidUpdate) but we need to check here too in order to catch
    // updates enqueued by setState callbacks.
    while (dirtyComponents.length) {
      var transaction = ReactUpdatesFlushTransaction.getPooled();
      transaction.perform(runBatchedUpdates, null, transaction);
      ReactUpdatesFlushTransaction.release(transaction);
    }
  };
  
  /**
   * Mark a component as needing a rerender, adding an optional callback to a
   * list of functions which will be executed once the rerender occurs.
   */
  function enqueueUpdate(component) {
    ensureInjected();
  
    // Various parts of our code (such as ReactCompositeComponent's
    // _renderValidatedComponent) assume that calls to render aren't nested;
    // verify that that's the case. (This is called by each top-level update
    // function, like setState, forceUpdate, etc.; creation and
    // destruction of top-level components is guarded in ReactMount.)
  
    if (!batchingStrategy.isBatchingUpdates) {
      batchingStrategy.batchedUpdates(enqueueUpdate, component);
      return;
    }
  
    dirtyComponents.push(component);
    if (component._updateBatchNumber == null) {
      component._updateBatchNumber = updateBatchNumber + 1;
    }
  }
  
  var ReactUpdatesInjection = {
    injectReconcileTransaction: function (ReconcileTransaction) {
      !ReconcileTransaction ? invariant(false, 'ReactUpdates: must provide a reconcile transaction class') : void 0;
      ReactUpdates.ReactReconcileTransaction = ReconcileTransaction;
    },
  
    injectBatchingStrategy: function (_batchingStrategy) {
      !_batchingStrategy ? invariant(false, 'ReactUpdates: must provide a batching strategy') : void 0;
      !(typeof _batchingStrategy.batchedUpdates === 'function') ? invariant(false, 'ReactUpdates: must provide a batchedUpdates() function') : void 0;
      !(typeof _batchingStrategy.isBatchingUpdates === 'boolean') ? invariant(false, 'ReactUpdates: must provide an isBatchingUpdates boolean attribute') : void 0;
      batchingStrategy = _batchingStrategy;
    },
  
    getBatchingStrategy: function () {
      return batchingStrategy;
    }
  };
  
  var ReactUpdates = {
    /**
     * React references `ReactReconcileTransaction` using this property in order
     * to allow dependency injection.
     *
     * @internal
     */
    ReactReconcileTransaction: null,
  
    batchedUpdates: batchedUpdates,
    enqueueUpdate: enqueueUpdate,
    flushBatchedUpdates: flushBatchedUpdates,
    injection: ReactUpdatesInjection
  };
  
  var ReactUpdates_1 = ReactUpdates;
  
  var RESET_BATCHED_UPDATES = {
    initialize: emptyFunction,
    close: function () {
      ReactDefaultBatchingStrategy.isBatchingUpdates = false;
    }
  };
  
  var FLUSH_BATCHED_UPDATES = {
    initialize: emptyFunction,
    close: ReactUpdates_1.flushBatchedUpdates.bind(ReactUpdates_1)
  };
  
  var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];
  
  function ReactDefaultBatchingStrategyTransaction() {
    this.reinitializeTransaction();
  }
  
  _assign(ReactDefaultBatchingStrategyTransaction.prototype, Transaction, {
    getTransactionWrappers: function () {
      return TRANSACTION_WRAPPERS;
    }
  });
  
  var transaction = new ReactDefaultBatchingStrategyTransaction();
  
  var ReactDefaultBatchingStrategy = {
    isBatchingUpdates: false,
  
    /**
     * Call the provided function in a context within which calls to `setState`
     * and friends are batched such that components aren't updated unnecessarily.
     */
    batchedUpdates: function (callback, a, b, c, d, e) {
      var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
  
      ReactDefaultBatchingStrategy.isBatchingUpdates = true;
  
      // The code is written this way to avoid extra allocations
      if (alreadyBatchingUpdates) {
        return callback(a, b, c, d, e);
      } else {
        return transaction.perform(callback, null, a, b, c, d, e);
      }
    }
  };
  
  var ReactDefaultBatchingStrategy_1 = ReactDefaultBatchingStrategy;
  
  /**
   * Copyright 2014-present, 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.
   *
   * @providesModule ReactEmptyComponent
   */
  
  var emptyComponentFactory;
  
  var ReactEmptyComponentInjection = {
    injectEmptyComponentFactory: function (factory) {
      emptyComponentFactory = factory;
    }
  };
  
  var ReactEmptyComponent = {
    create: function (instantiate) {
      return emptyComponentFactory(instantiate);
    }
  };
  
  ReactEmptyComponent.injection = ReactEmptyComponentInjection;
  
  var ReactEmptyComponent_1 = ReactEmptyComponent;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule ReactInstanceMap
   */
  
  /**
   * `ReactInstanceMap` maintains a mapping from a public facing stateful
   * instance (key) and the internal representation (value). This allows public
   * methods to accept the user facing instance as an argument and map them back
   * to internal methods.
   */
  
  // TODO: Replace this with ES6: var ReactInstanceMap = new Map();
  
  var ReactInstanceMap = {
    /**
     * This API should be called `delete` but we'd have to make sure to always
     * transform these to strings for IE support. When this transform is fully
     * supported we can rename it.
     */
    remove: function (key) {
      key._reactInternalInstance = undefined;
    },
  
    get: function (key) {
      return key._reactInternalInstance;
    },
  
    has: function (key) {
      return key._reactInternalInstance !== undefined;
    },
  
    set: function (key, value) {
      key._reactInternalInstance = value;
    }
  };
  
  var ReactInstanceMap_1 = ReactInstanceMap;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule KeyEscapeUtils
   * 
   */
  
  /**
   * Escape and wrap key so it is safe to use as a reactid
   *
   * @param {string} key to be escaped.
   * @return {string} the escaped key.
   */
  
  function escape(key) {
    var escapeRegex = /[=:]/g;
    var escaperLookup = {
      '=': '=0',
      ':': '=2'
    };
    var escapedString = ('' + key).replace(escapeRegex, function (match) {
      return escaperLookup[match];
    });
  
    return '$' + escapedString;
  }
  
  /**
   * Unescape and unwrap key for human-readable display
   *
   * @param {string} key to unescape.
   * @return {string} the unescaped key.
   */
  function unescape(key) {
    var unescapeRegex = /(=0|=2)/g;
    var unescaperLookup = {
      '=0': '=',
      '=2': ':'
    };
    var keySubstring = key[0] === '.' && key[1] === '$' ? key.substring(2) : key.substring(1);
  
    return ('' + keySubstring).replace(unescapeRegex, function (match) {
      return unescaperLookup[match];
    });
  }
  
  var KeyEscapeUtils = {
    escape: escape,
    unescape: unescape
  };
  
  var KeyEscapeUtils_1 = KeyEscapeUtils;
  
  var caughtError = null;
  
  var invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) {
    var funcArgs = Array.prototype.slice.call(arguments, 3);
    try {
      func.apply(context, funcArgs);
    } catch (error) {
      return error;
    }
    return null;
  };
  
  {
    /**
     * To help development we can get better devtools integration by simulating a
     * real browser event.
     */
    if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
      var fakeNode = document.createElement('react');
      var depth = 0;
  
      invokeGuardedCallback = function (name, func, context, a, b, c, d, e, f) {
        depth++;
        var thisDepth = depth;
        var funcArgs = Array.prototype.slice.call(arguments, 3);
        var boundFunc = function () {
          func.apply(context, funcArgs);
        };
        var fakeEventError = null;
        var onFakeEventError = function (event) {
          // Don't capture nested errors
          if (depth === thisDepth) {
            fakeEventError = event.error;
          }
        };
        var evtType = 'react-' + (name ? name : 'invokeguardedcallback') + '-' + depth;
        window.addEventListener('error', onFakeEventError);
        fakeNode.addEventListener(evtType, boundFunc, false);
        var evt = document.createEvent('Event');
        evt.initEvent(evtType, false, false);
        fakeNode.dispatchEvent(evt);
        fakeNode.removeEventListener(evtType, boundFunc, false);
        window.removeEventListener('error', onFakeEventError);
        depth--;
        return fakeEventError;
      };
    }
  }
  
  var rethrowCaughtError = function () {
    if (caughtError) {
      var error = caughtError;
      caughtError = null;
      throw error;
    }
  };
  
  var ReactErrorUtils = {
    injection: {
      injectErrorUtils: function (injectedErrorUtils) {
        invariant(typeof injectedErrorUtils.invokeGuardedCallback === 'function', 'Injected invokeGuardedCallback() must be a function.');
        invokeGuardedCallback = injectedErrorUtils.invokeGuardedCallback;
      }
    },
  
    /**
     * Call a function while guarding against errors that happens within it.
     * Returns an error if it throws, otherwise null.
     *
     * @param {String} name of the guard to use for logging or debugging
     * @param {Function} func The function to invoke
     * @param {*} context The context to use when calling the function
     * @param {...*} args Arguments for function
     */
    invokeGuardedCallback: function (name, func, context, a, b, c, d, e, f) {
      return invokeGuardedCallback.apply(this, arguments);
    },
  
    /**
     * Same as invokeGuardedCallback, but instead of returning an error, it stores
     * it in a global so it can be rethrown by `rethrowCaughtError` later.
     *
     * @param {String} name of the guard to use for logging or debugging
     * @param {Function} func The function to invoke
     * @param {*} context The context to use when calling the function
     * @param {...*} args Arguments for function
     */
    invokeGuardedCallbackAndCatchFirstError: function (name, func, context, a, b, c, d, e, f) {
      var error = ReactErrorUtils.invokeGuardedCallback.apply(this, arguments);
      if (error !== null && caughtError === null) {
        caughtError = error;
      }
    },
  
    /**
     * During execution of guarded functions we will capture the first error which
     * we will rethrow to be handled by the top level error handler.
     */
    rethrowCaughtError: function () {
      return rethrowCaughtError.apply(this, arguments);
    }
  };
  
  var ReactErrorUtils_1 = ReactErrorUtils;
  
  var ReactNodeTypes = {
    HOST: 0,
    COMPOSITE: 1,
    EMPTY: 2,
  
    getType: function (node) {
      if (node === null || node === false) {
        return ReactNodeTypes.EMPTY;
      } else if (React.isValidElement(node)) {
        if (typeof node.type === 'function') {
          return ReactNodeTypes.COMPOSITE;
        } else {
          return ReactNodeTypes.HOST;
        }
      }
      invariant(false, 'Unexpected node: %s', node);
    }
  };
  
  var ReactNodeTypes_1 = ReactNodeTypes;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule shouldUpdateReactComponent
   */
  
  /**
   * Given a `prevElement` and `nextElement`, determines if the existing
   * instance should be updated as opposed to being destroyed or replaced by a new
   * instance. Both arguments are elements. This ensures that this logic can
   * operate on stateless trees without any backing instance.
   *
   * @param {?object} prevElement
   * @param {?object} nextElement
   * @return {boolean} True if the existing instance should be updated.
   * @protected
   */
  
  function shouldUpdateReactComponent(prevElement, nextElement) {
    var prevEmpty = prevElement === null || prevElement === false;
    var nextEmpty = nextElement === null || nextElement === false;
    if (prevEmpty || nextEmpty) {
      return prevEmpty === nextEmpty;
    }
  
    var prevType = typeof prevElement;
    var nextType = typeof nextElement;
    if (prevType === 'string' || prevType === 'number') {
      return nextType === 'string' || nextType === 'number';
    } else {
      return nextType === 'object' && prevElement.type === nextElement.type && prevElement.key === nextElement.key;
    }
  }
  
  var shouldUpdateReactComponent_1 = shouldUpdateReactComponent;
  
  var ReactCurrentOwner$1 = ReactGlobalSharedState_1.ReactCurrentOwner;
  
  {
    var _require2 = ReactGlobalSharedState_1,
        ReactDebugCurrentFrame = _require2.ReactDebugCurrentFrame;
  
    var warningAboutMissingGetChildContext = {};
  }
  
  
  
  
  
  
  
  
  function StatelessComponent(Component) {}
  StatelessComponent.prototype.render = function () {
    var Component = ReactInstanceMap_1.get(this)._currentElement.type;
    var element = Component(this.props, this.context, this.updater);
    return element;
  };
  
  function shouldConstruct(Component) {
    return !!(Component.prototype && Component.prototype.isReactComponent);
  }
  
  function isPureComponent(Component) {
    return !!(Component.prototype && Component.prototype.isPureReactComponent);
  }
  
  // Separated into a function to contain deoptimizations caused by try/finally.
  function measureLifeCyclePerf(fn, debugID, timerType) {
    if (debugID === 0) {
      // Top-level wrappers (see ReactMount) and empty components (see
      // ReactDOMEmptyComponent) are invisible to hooks and devtools.
      // Both are implementation details that should go away in the future.
      return fn();
    }
  
    ReactInstrumentation.debugTool.onBeginLifeCycleTimer(debugID, timerType);
    try {
      return fn();
    } finally {
      ReactInstrumentation.debugTool.onEndLifeCycleTimer(debugID, timerType);
    }
  }
  
  /**
   * ------------------ The Life-Cycle of a Composite Component ------------------
   *
   * - constructor: Initialization of state. The instance is now retained.
   *   - componentWillMount
   *   - render
   *   - [children's constructors]
   *     - [children's componentWillMount and render]
   *     - [children's componentDidMount]
   *     - componentDidMount
   *
   *       Update Phases:
   *       - componentWillReceiveProps (only called if parent updated)
   *       - shouldComponentUpdate
   *         - componentWillUpdate
   *           - render
   *           - [children's constructors or receive props phases]
   *         - componentDidUpdate
   *
   *     - componentWillUnmount
   *     - [children's componentWillUnmount]
   *   - [children destroyed]
   * - (destroyed): The instance is now blank, released by React and ready for GC.
   *
   * -----------------------------------------------------------------------------
   */
  
  /**
   * An incrementing ID assigned to each component when it is mounted. This is
   * used to enforce the order in which `ReactUpdates` updates dirty components.
   *
   * @private
   */
  var nextMountID = 1;
  
  /**
   * @lends {ReactCompositeComponent.prototype}
   */
  var ReactCompositeComponent = {
    /**
     * Base constructor for all composite component.
     *
     * @param {ReactElement} element
     * @final
     * @internal
     */
    construct: function (element) {
      this._currentElement = element;
      this._rootNodeID = 0;
      this._compositeType = null;
      this._instance = null;
      this._hostParent = null;
      this._hostContainerInfo = null;
  
      // See ReactUpdateQueue
      this._updateBatchNumber = null;
      this._pendingElement = null;
      this._pendingStateQueue = null;
      this._pendingReplaceState = false;
      this._pendingForceUpdate = false;
  
      this._renderedNodeType = null;
      this._renderedComponent = null;
      this._context = null;
      this._mountOrder = 0;
      this._topLevelWrapper = null;
  
      // See ReactUpdates and ReactUpdateQueue.
      this._pendingCallbacks = null;
  
      // ComponentWillUnmount shall only be called once
      this._calledComponentWillUnmount = false;
  
      {
        this._warnedAboutRefsInRender = false;
      }
    },
  
    /**
     * Initializes the component, renders markup, and registers event listeners.
     *
     * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
     * @param {?object} hostParent
     * @param {?object} hostContainerInfo
     * @param {?object} context
     * @return {?string} Rendered markup to be inserted into the DOM.
     * @final
     * @internal
     */
    mountComponent: function (transaction, hostParent, hostContainerInfo, context) {
      var _this = this;
  
      this._context = context;
      this._mountOrder = nextMountID++;
      this._hostParent = hostParent;
      this._hostContainerInfo = hostContainerInfo;
  
      var publicProps = this._currentElement.props;
      var publicContext = this._processContext(context);
  
      var Component = this._currentElement.type;
  
      var updateQueue = transaction.getUpdateQueue();
  
      // Initialize the public class
      var doConstruct = shouldConstruct(Component);
      var inst = this._constructComponent(doConstruct, publicProps, publicContext, updateQueue);
      var renderedElement;
  
      // Support functional components
      if (!doConstruct && (inst == null || inst.render == null)) {
        renderedElement = inst;
        {
          warning(!Component.childContextTypes, '%s(...): childContextTypes cannot be defined on a functional component.', Component.displayName || Component.name || 'Component');
        }
        !(inst === null || inst === false || React.isValidElement(inst)) ? invariant(false, '%s(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component') : void 0;
        inst = new StatelessComponent(Component);
        this._compositeType = ReactCompositeComponentTypes$1.StatelessFunctional;
      } else {
        if (isPureComponent(Component)) {
          this._compositeType = ReactCompositeComponentTypes$1.PureClass;
        } else {
          this._compositeType = ReactCompositeComponentTypes$1.ImpureClass;
        }
      }
  
      {
        // This will throw later in _renderValidatedComponent, but add an early
        // warning now to help debugging
        if (inst.render == null) {
          warning(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', Component.displayName || Component.name || 'Component');
        }
  
        var propsMutated = inst.props !== publicProps;
        var componentName = Component.displayName || Component.name || 'Component';
  
        warning(inst.props === undefined || !propsMutated, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", componentName, componentName);
      }
  
      // These should be set up in the constructor, but as a convenience for
      // simpler class abstractions, we set them up after the fact.
      inst.props = publicProps;
      inst.context = publicContext;
      inst.refs = emptyObject;
      inst.updater = updateQueue;
  
      this._instance = inst;
  
      // Store a reference from the instance back to the internal representation
      ReactInstanceMap_1.set(inst, this);
  
      {
        // Since plain JS classes are defined without any special initialization
        // logic, we can not catch common errors early. Therefore, we have to
        // catch them here, at initialization time, instead.
        warning(!inst.getInitialState || inst.getInitialState.isReactClassApproved || inst.state, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', this.getName() || 'a component');
        warning(!inst.getDefaultProps || inst.getDefaultProps.isReactClassApproved, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', this.getName() || 'a component');
        warning(!inst.propTypes, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', this.getName() || 'a component');
        warning(!inst.contextTypes, 'contextTypes was defined as an instance property on %s. Use a ' + 'static property to define contextTypes instead.', this.getName() || 'a component');
        warning(typeof inst.componentShouldUpdate !== 'function', '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', this.getName() || 'A component');
        warning(typeof inst.componentDidUnmount !== 'function', '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', this.getName() || 'A component');
        warning(typeof inst.componentWillRecieveProps !== 'function', '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', this.getName() || 'A component');
        if (isPureComponent(Component) && typeof inst.shouldComponentUpdate !== 'undefined') {
          warning(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', this.getName() || 'A pure component');
        }
        warning(!inst.defaultProps, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', this.getName() || 'a component', this.getName() || 'a component');
      }
  
      var initialState = inst.state;
      if (initialState === undefined) {
        inst.state = initialState = null;
      }
      !(typeof initialState === 'object' && !Array.isArray(initialState)) ? invariant(false, '%s.state: must be set to an object or null', this.getName() || 'ReactCompositeComponent') : void 0;
  
      this._pendingStateQueue = null;
      this._pendingReplaceState = false;
      this._pendingForceUpdate = false;
  
      if (inst.componentWillMount) {
        {
          measureLifeCyclePerf(function () {
            return inst.componentWillMount();
          }, this._debugID, 'componentWillMount');
        }
        // When mounting, calls to `setState` by `componentWillMount` will set
        // `this._pendingStateQueue` without triggering a re-render.
        if (this._pendingStateQueue) {
          inst.state = this._processPendingState(inst.props, inst.context);
        }
      }
  
      var markup;
      if (inst.unstable_handleError) {
        markup = this.performInitialMountWithErrorHandling(renderedElement, hostParent, hostContainerInfo, transaction, context);
      } else {
        markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
      }
  
      if (inst.componentDidMount) {
        {
          transaction.getReactMountReady().enqueue(function () {
            measureLifeCyclePerf(function () {
              return inst.componentDidMount();
            }, _this._debugID, 'componentDidMount');
          });
        }
      }
  
      // setState callbacks during willMount should end up here
      var callbacks = this._pendingCallbacks;
      if (callbacks) {
        this._pendingCallbacks = null;
        for (var i = 0; i < callbacks.length; i++) {
          transaction.getReactMountReady().enqueue(callbacks[i], inst);
        }
      }
  
      return markup;
    },
  
    _constructComponent: function (doConstruct, publicProps, publicContext, updateQueue) {
      {
        ReactCurrentOwner$1.current = this;
        try {
          return this._constructComponentWithoutOwner(doConstruct, publicProps, publicContext, updateQueue);
        } finally {
          ReactCurrentOwner$1.current = null;
        }
      }
    },
  
    _constructComponentWithoutOwner: function (doConstruct, publicProps, publicContext, updateQueue) {
      var Component = this._currentElement.type;
  
      if (doConstruct) {
        {
          return measureLifeCyclePerf(function () {
            return new Component(publicProps, publicContext, updateQueue);
          }, this._debugID, 'ctor');
        }
      }
  
      // This can still be an instance in case of factory components
      // but we'll count this as time spent rendering as the more common case.
      {
        return measureLifeCyclePerf(function () {
          return Component(publicProps, publicContext, updateQueue);
        }, this._debugID, 'render');
      }
    },
  
    performInitialMountWithErrorHandling: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
      var markup;
      var checkpoint = transaction.checkpoint();
      try {
        markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
      } catch (e) {
        // Roll back to checkpoint, handle error (which may add items to the transaction), and take a new checkpoint
        transaction.rollback(checkpoint);
        this._instance.unstable_handleError(e);
        if (this._pendingStateQueue) {
          this._instance.state = this._processPendingState(this._instance.props, this._instance.context);
        }
        checkpoint = transaction.checkpoint();
        this._renderedComponent.unmountComponent(true /* safely */
        , // Don't call componentWillUnmount() because they never fully mounted:
        true /* skipLifecyle */
        );
        transaction.rollback(checkpoint);
  
        // Try again - we've informed the component about the error, so they can render an error message this time.
        // If this throws again, the error will bubble up (and can be caught by a higher error boundary).
        markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context);
      }
      return markup;
    },
  
    performInitialMount: function (renderedElement, hostParent, hostContainerInfo, transaction, context) {
      // If not a stateless component, we now render
      if (renderedElement === undefined) {
        renderedElement = this._renderValidatedComponent();
      }
  
      var nodeType = ReactNodeTypes_1.getType(renderedElement);
      this._renderedNodeType = nodeType;
      var child = this._instantiateReactComponent(renderedElement, nodeType !== ReactNodeTypes_1.EMPTY /* shouldHaveDebugID */
      );
      this._renderedComponent = child;
  
      var debugID = 0;
      {
        debugID = this._debugID;
      }
  
      var markup = ReactReconciler_1.mountComponent(child, transaction, hostParent, hostContainerInfo, this._processChildContext(context), debugID);
  
      {
        if (debugID !== 0) {
          var childDebugIDs = child._debugID !== 0 ? [child._debugID] : [];
          ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs);
        }
      }
  
      return markup;
    },
  
    getHostNode: function () {
      return ReactReconciler_1.getHostNode(this._renderedComponent);
    },
  
    /**
     * Releases any resources allocated by `mountComponent`.
     *
     * @final
     * @internal
     */
    unmountComponent: function (safely, skipLifecycle) {
      if (!this._renderedComponent) {
        return;
      }
  
      var inst = this._instance;
  
      if (inst.componentWillUnmount && !inst._calledComponentWillUnmount) {
        inst._calledComponentWillUnmount = true;
  
        if (safely) {
          if (!skipLifecycle) {
            var name = this.getName() + '.componentWillUnmount()';
            ReactErrorUtils_1.invokeGuardedCallbackAndCatchFirstError(name, inst.componentWillUnmount, inst);
          }
        } else {
          {
            measureLifeCyclePerf(function () {
              return inst.componentWillUnmount();
            }, this._debugID, 'componentWillUnmount');
          }
        }
      }
  
      if (this._renderedComponent) {
        ReactReconciler_1.unmountComponent(this._renderedComponent, safely, skipLifecycle);
        this._renderedNodeType = null;
        this._renderedComponent = null;
        this._instance = null;
      }
  
      // Reset pending fields
      // Even if this component is scheduled for another update in ReactUpdates,
      // it would still be ignored because these fields are reset.
      this._pendingStateQueue = null;
      this._pendingReplaceState = false;
      this._pendingForceUpdate = false;
      this._pendingCallbacks = null;
      this._pendingElement = null;
  
      // These fields do not really need to be reset since this object is no
      // longer accessible.
      this._context = null;
      this._rootNodeID = 0;
      this._topLevelWrapper = null;
  
      // Delete the reference from the instance to this internal representation
      // which allow the internals to be properly cleaned up even if the user
      // leaks a reference to the public instance.
      ReactInstanceMap_1.remove(inst);
  
      // Some existing components rely on inst.props even after they've been
      // destroyed (in event handlers).
      // TODO: inst.props = null;
      // TODO: inst.state = null;
      // TODO: inst.context = null;
    },
  
    /**
     * Filters the context object to only contain keys specified in
     * `contextTypes`
     *
     * @param {object} context
     * @return {?object}
     * @private
     */
    _maskContext: function (context) {
      var Component = this._currentElement.type;
      var contextTypes = Component.contextTypes;
      if (!contextTypes) {
        return emptyObject;
      }
      var maskedContext = {};
      for (var contextName in contextTypes) {
        maskedContext[contextName] = context[contextName];
      }
      return maskedContext;
    },
  
    /**
     * Filters the context object to only contain keys specified in
     * `contextTypes`, and asserts that they are valid.
     *
     * @param {object} context
     * @return {?object}
     * @private
     */
    _processContext: function (context) {
      var maskedContext = this._maskContext(context);
      {
        var Component = this._currentElement.type;
        if (Component.contextTypes) {
          this._checkContextTypes(Component.contextTypes, maskedContext, 'context');
        }
      }
      return maskedContext;
    },
  
    /**
     * @param {object} currentContext
     * @return {object}
     * @private
     */
    _processChildContext: function (currentContext) {
      var Component = this._currentElement.type;
      var inst = this._instance;
      var childContext;
  
      if (typeof inst.getChildContext === 'function') {
        {
          ReactInstrumentation.debugTool.onBeginProcessingChildContext();
          try {
            childContext = inst.getChildContext();
          } finally {
            ReactInstrumentation.debugTool.onEndProcessingChildContext();
          }
        }
  
        !(typeof Component.childContextTypes === 'object') ? invariant(false, '%s.getChildContext(): childContextTypes must be defined in order to use getChildContext().', this.getName() || 'ReactCompositeComponent') : void 0;
        {
          this._checkContextTypes(Component.childContextTypes, childContext, 'child context');
        }
        for (var name in childContext) {
          !(name in Component.childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', this.getName() || 'ReactCompositeComponent', name) : void 0;
        }
        return _assign({}, currentContext, childContext);
      } else {
        {
          var componentName = this.getName();
  
          if (!warningAboutMissingGetChildContext[componentName]) {
            warningAboutMissingGetChildContext[componentName] = true;
            warning(!Component.childContextTypes, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
          }
        }
      }
      return currentContext;
    },
  
    /**
     * Assert that the context types are valid
     *
     * @param {object} typeSpecs Map of context field to a ReactPropType
     * @param {object} values Runtime values that need to be type-checked
     * @param {string} location e.g. "prop", "context", "child context"
     * @private
     */
    _checkContextTypes: function (typeSpecs, values, location) {
      {
        ReactDebugCurrentFrame.current = this._debugID;
        checkPropTypes(typeSpecs, values, location, this.getName(), ReactDebugCurrentFrame.getStackAddendum);
        ReactDebugCurrentFrame.current = null;
      }
    },
  
    receiveComponent: function (nextElement, transaction, nextContext) {
      var prevElement = this._currentElement;
      var prevContext = this._context;
  
      this._pendingElement = null;
  
      this.updateComponent(transaction, prevElement, nextElement, prevContext, nextContext);
    },
  
    /**
     * If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
     * is set, update the component.
     *
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    performUpdateIfNecessary: function (transaction) {
      if (this._pendingElement != null) {
        ReactReconciler_1.receiveComponent(this, this._pendingElement, transaction, this._context);
      } else if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
        this.updateComponent(transaction, this._currentElement, this._currentElement, this._context, this._context);
      } else {
        var callbacks = this._pendingCallbacks;
        this._pendingCallbacks = null;
        if (callbacks) {
          for (var j = 0; j < callbacks.length; j++) {
            transaction.getReactMountReady().enqueue(callbacks[j], this.getPublicInstance());
          }
        }
        this._updateBatchNumber = null;
      }
    },
  
    /**
     * Perform an update to a mounted component. The componentWillReceiveProps and
     * shouldComponentUpdate methods are called, then (assuming the update isn't
     * skipped) the remaining update lifecycle methods are called and the DOM
     * representation is updated.
     *
     * By default, this implements React's rendering and reconciliation algorithm.
     * Sophisticated clients may wish to override this.
     *
     * @param {ReactReconcileTransaction} transaction
     * @param {ReactElement} prevParentElement
     * @param {ReactElement} nextParentElement
     * @internal
     * @overridable
     */
    updateComponent: function (transaction, prevParentElement, nextParentElement, prevUnmaskedContext, nextUnmaskedContext) {
      var inst = this._instance;
      !(inst != null) ? invariant(false, 'Attempted to update component `%s` that has already been unmounted (or failed to mount).', this.getName() || 'ReactCompositeComponent') : void 0;
  
      var willReceive = false;
      var nextContext;
  
      // Determine if the context has changed or not
      if (this._context === nextUnmaskedContext) {
        nextContext = inst.context;
      } else {
        nextContext = this._processContext(nextUnmaskedContext);
        willReceive = true;
      }
  
      var prevProps = prevParentElement.props;
      var nextProps = nextParentElement.props;
  
      // Not a simple state update but a props update
      if (prevParentElement !== nextParentElement) {
        willReceive = true;
      }
  
      // An update here will schedule an update but immediately set
      // _pendingStateQueue which will ensure that any state updates gets
      // immediately reconciled instead of waiting for the next batch.
      if (willReceive && inst.componentWillReceiveProps) {
        var beforeState = inst.state;
        {
          measureLifeCyclePerf(function () {
            return inst.componentWillReceiveProps(nextProps, nextContext);
          }, this._debugID, 'componentWillReceiveProps');
        }
        var afterState = inst.state;
        if (beforeState !== afterState) {
          inst.state = beforeState;
          inst.updater.enqueueReplaceState(inst, afterState);
          {
            warning(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', this.getName() || 'ReactCompositeComponent');
          }
        }
      }
  
      // If updating happens to enqueue any new updates, we shouldn't execute new
      // callbacks until the next render happens, so stash the callbacks first.
      var callbacks = this._pendingCallbacks;
      this._pendingCallbacks = null;
  
      var nextState = this._processPendingState(nextProps, nextContext);
      var shouldUpdate = true;
      if (!this._pendingForceUpdate) {
        var prevState = inst.state;
        shouldUpdate = willReceive || nextState !== prevState;
        if (inst.shouldComponentUpdate) {
          {
            shouldUpdate = measureLifeCyclePerf(function () {
              return inst.shouldComponentUpdate(nextProps, nextState, nextContext);
            }, this._debugID, 'shouldComponentUpdate');
          }
        } else {
          if (this._compositeType === ReactCompositeComponentTypes$1.PureClass) {
            shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);
          }
        }
      }
  
      {
        warning(shouldUpdate !== undefined, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', this.getName() || 'ReactCompositeComponent');
      }
  
      this._updateBatchNumber = null;
      if (shouldUpdate) {
        this._pendingForceUpdate = false;
        // Will set `this.props`, `this.state` and `this.context`.
        this._performComponentUpdate(nextParentElement, nextProps, nextState, nextContext, transaction, nextUnmaskedContext);
      } else {
        // If it's determined that a component should not update, we still want
        // to set props and state but we shortcut the rest of the update.
        this._currentElement = nextParentElement;
        this._context = nextUnmaskedContext;
        inst.props = nextProps;
        inst.state = nextState;
        inst.context = nextContext;
      }
  
      if (callbacks) {
        for (var j = 0; j < callbacks.length; j++) {
          transaction.getReactMountReady().enqueue(callbacks[j], this.getPublicInstance());
        }
      }
    },
  
    _processPendingState: function (props, context) {
      var inst = this._instance;
      var queue = this._pendingStateQueue;
      var replace = this._pendingReplaceState;
      this._pendingReplaceState = false;
      this._pendingStateQueue = null;
  
      if (!queue) {
        return inst.state;
      }
  
      if (replace && queue.length === 1) {
        return queue[0];
      }
  
      var nextState = replace ? queue[0] : inst.state;
      var dontMutate = true;
      for (var i = replace ? 1 : 0; i < queue.length; i++) {
        var partial = queue[i];
        var partialState = typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial;
        if (partialState) {
          if (dontMutate) {
            dontMutate = false;
            nextState = _assign({}, nextState, partialState);
          } else {
            _assign(nextState, partialState);
          }
        }
      }
  
      return nextState;
    },
  
    /**
     * Merges new props and state, notifies delegate methods of update and
     * performs update.
     *
     * @param {ReactElement} nextElement Next element
     * @param {object} nextProps Next public object to set as properties.
     * @param {?object} nextState Next object to set as state.
     * @param {?object} nextContext Next public object to set as context.
     * @param {ReactReconcileTransaction} transaction
     * @param {?object} unmaskedContext
     * @private
     */
    _performComponentUpdate: function (nextElement, nextProps, nextState, nextContext, transaction, unmaskedContext) {
      var _this2 = this;
  
      var inst = this._instance;
  
      var hasComponentDidUpdate = !!inst.componentDidUpdate;
      var prevProps;
      var prevState;
      if (hasComponentDidUpdate) {
        prevProps = inst.props;
        prevState = inst.state;
      }
  
      if (inst.componentWillUpdate) {
        {
          measureLifeCyclePerf(function () {
            return inst.componentWillUpdate(nextProps, nextState, nextContext);
          }, this._debugID, 'componentWillUpdate');
        }
      }
  
      this._currentElement = nextElement;
      this._context = unmaskedContext;
      inst.props = nextProps;
      inst.state = nextState;
      inst.context = nextContext;
  
      if (inst.unstable_handleError) {
        this._updateRenderedComponentWithErrorHandling(transaction, unmaskedContext);
      } else {
        this._updateRenderedComponent(transaction, unmaskedContext);
      }
  
      if (hasComponentDidUpdate) {
        {
          transaction.getReactMountReady().enqueue(function () {
            measureLifeCyclePerf(inst.componentDidUpdate.bind(inst, prevProps, prevState), _this2._debugID, 'componentDidUpdate');
          });
        }
      }
    },
  
    /**
     * Call the component's `render` method and update the DOM accordingly.
     *
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    _updateRenderedComponentWithErrorHandling: function (transaction, context) {
      var checkpoint = transaction.checkpoint();
      try {
        this._updateRenderedComponent(transaction, context);
      } catch (e) {
        // Roll back to checkpoint, handle error (which may add items to the transaction),
        // and take a new checkpoint
        transaction.rollback(checkpoint);
        this._instance.unstable_handleError(e);
        if (this._pendingStateQueue) {
          this._instance.state = this._processPendingState(this._instance.props, this._instance.context);
        }
        checkpoint = transaction.checkpoint();
  
        // Gracefully update to a clean state
        this._updateRenderedComponentWithNextElement(transaction, context, null, true /* safely */
        );
  
        // Try again - we've informed the component about the error, so they can render an error message this time.
        // If this throws again, the error will bubble up (and can be caught by a higher error boundary).
        this._updateRenderedComponent(transaction, context);
      }
    },
  
    /**
     * Call the component's `render` method and update the DOM accordingly.
     *
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    _updateRenderedComponent: function (transaction, context) {
      var nextRenderedElement = this._renderValidatedComponent();
      this._updateRenderedComponentWithNextElement(transaction, context, nextRenderedElement, false /* safely */
      );
    },
  
    /**
     * Call the component's `render` method and update the DOM accordingly.
     *
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    _updateRenderedComponentWithNextElement: function (transaction, context, nextRenderedElement, safely) {
      var prevComponentInstance = this._renderedComponent;
      var prevRenderedElement = prevComponentInstance._currentElement;
  
      var debugID = 0;
      {
        debugID = this._debugID;
      }
  
      if (shouldUpdateReactComponent_1(prevRenderedElement, nextRenderedElement)) {
        ReactReconciler_1.receiveComponent(prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context));
      } else {
        var oldHostNode = ReactReconciler_1.getHostNode(prevComponentInstance);
  
        if (!ReactFeatureFlags_1.prepareNewChildrenBeforeUnmountInStack) {
          ReactReconciler_1.unmountComponent(prevComponentInstance, safely, false /* skipLifecycle */
          );
        }
  
        var nodeType = ReactNodeTypes_1.getType(nextRenderedElement);
        this._renderedNodeType = nodeType;
        var child = this._instantiateReactComponent(nextRenderedElement, nodeType !== ReactNodeTypes_1.EMPTY /* shouldHaveDebugID */
        );
        this._renderedComponent = child;
  
        var nextMarkup = ReactReconciler_1.mountComponent(child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID);
  
        if (ReactFeatureFlags_1.prepareNewChildrenBeforeUnmountInStack) {
          ReactReconciler_1.unmountComponent(prevComponentInstance, safely, false /* skipLifecycle */
          );
        }
  
        {
          if (debugID !== 0) {
            var childDebugIDs = child._debugID !== 0 ? [child._debugID] : [];
            ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs);
          }
        }
  
        this._replaceNodeWithMarkup(oldHostNode, nextMarkup, prevComponentInstance);
      }
    },
  
    /**
     * Overridden in shallow rendering.
     *
     * @protected
     */
    _replaceNodeWithMarkup: function (oldHostNode, nextMarkup, prevInstance) {
      ReactComponentEnvironment_1.replaceNodeWithMarkup(oldHostNode, nextMarkup, prevInstance);
    },
  
    /**
     * @protected
     */
    _renderValidatedComponentWithoutOwnerOrContext: function () {
      var inst = this._instance;
      var renderedElement;
  
      {
        renderedElement = measureLifeCyclePerf(function () {
          return inst.render();
        }, this._debugID, 'render');
      }
  
      {
        // We allow auto-mocks to proceed as if they're returning null.
        if (renderedElement === undefined && inst.render._isMockFunction) {
          // This is probably bad practice. Consider warning here and
          // deprecating this convenience.
          renderedElement = null;
        }
      }
  
      return renderedElement;
    },
  
    /**
     * @private
     */
    _renderValidatedComponent: function () {
      var renderedElement;
      if ('development' !== 'production' || this._compositeType !== ReactCompositeComponentTypes$1.StatelessFunctional) {
        ReactCurrentOwner$1.current = this;
        try {
          renderedElement = this._renderValidatedComponentWithoutOwnerOrContext();
        } finally {
          ReactCurrentOwner$1.current = null;
        }
      } else {
        renderedElement = this._renderValidatedComponentWithoutOwnerOrContext();
      }
      !(
      // TODO: An `isValidNode` function would probably be more appropriate
      renderedElement === null || renderedElement === false || React.isValidElement(renderedElement)) ? invariant(false, '%s.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.', this.getName() || 'ReactCompositeComponent') : void 0;
  
      return renderedElement;
    },
  
    /**
     * Lazily allocates the refs object and stores `component` as `ref`.
     *
     * @param {string} ref Reference name.
     * @param {component} component Component to store as `ref`.
     * @final
     * @private
     */
    attachRef: function (ref, component) {
      var inst = this.getPublicInstance();
      !(inst != null) ? invariant(false, 'Stateless function components cannot have refs.') : void 0;
      var publicComponentInstance = component.getPublicInstance();
      var refs = inst.refs === emptyObject ? inst.refs = {} : inst.refs;
      refs[ref] = publicComponentInstance;
    },
  
    /**
     * Detaches a reference name.
     *
     * @param {string} ref Name to dereference.
     * @final
     * @private
     */
    detachRef: function (ref) {
      var refs = this.getPublicInstance().refs;
      delete refs[ref];
    },
  
    /**
     * Get a text description of the component that can be used to identify it
     * in error messages.
     * @return {string} The name or null.
     * @internal
     */
    getName: function () {
      var type = this._currentElement.type;
      var constructor = this._instance && this._instance.constructor;
      return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null;
    },
  
    /**
     * Get the publicly accessible representation of this component - i.e. what
     * is exposed by refs and returned by render. Can be null for stateless
     * components.
     *
     * @return {ReactComponent} the public component instance.
     * @internal
     */
    getPublicInstance: function () {
      var inst = this._instance;
      if (this._compositeType === ReactCompositeComponentTypes$1.StatelessFunctional) {
        return null;
      }
      return inst;
    },
  
    // Stub
    _instantiateReactComponent: null
  };
  
  var ReactCompositeComponent_1 = ReactCompositeComponent;
  
  var genericComponentClass = null;
  var textComponentClass = null;
  
  var ReactHostComponentInjection = {
    // This accepts a class that receives the tag string. This is a catch all
    // that can render any kind of tag.
    injectGenericComponentClass: function (componentClass) {
      genericComponentClass = componentClass;
    },
    // This accepts a text component class that takes the text string to be
    // rendered as props.
    injectTextComponentClass: function (componentClass) {
      textComponentClass = componentClass;
    }
  };
  
  /**
   * Get a host internal component class for a specific tag.
   *
   * @param {ReactElement} element The element to create.
   * @return {function} The internal class constructor function.
   */
  function createInternalComponent(element) {
    !genericComponentClass ? invariant(false, 'There is no registered component for the tag %s', element.type) : void 0;
    return new genericComponentClass(element);
  }
  
  /**
   * @param {ReactText} text
   * @return {ReactComponent}
   */
  function createInstanceForText(text) {
    return new textComponentClass(text);
  }
  
  /**
   * @param {ReactComponent} component
   * @return {boolean}
   */
  function isTextComponent(component) {
    return component instanceof textComponentClass;
  }
  
  var ReactHostComponent = {
    createInternalComponent: createInternalComponent,
    createInstanceForText: createInstanceForText,
    isTextComponent: isTextComponent,
    injection: ReactHostComponentInjection
  };
  
  var ReactHostComponent_1 = ReactHostComponent;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule getNextDebugID
   * 
   */
  
  var nextDebugID = 1;
  
  function getNextDebugID() {
    return nextDebugID++;
  }
  
  var getNextDebugID_1 = getNextDebugID;
  
  // To avoid a cyclic dependency, we create the final class in this module
  var ReactCompositeComponentWrapper = function (element) {
    this.construct(element);
  };
  
  function getDeclarationErrorAddendum(owner) {
    if (owner) {
      var name = owner.getName();
      if (name) {
        return '\n\nCheck the render method of `' + name + '`.';
      }
    }
    return '';
  }
  
  /**
   * Check if the type reference is a known internal type. I.e. not a user
   * provided composite type.
   *
   * @param {function} type
   * @return {boolean} Returns true if this is a valid internal type.
   */
  function isInternalComponentType(type) {
    return typeof type === 'function' && typeof type.prototype !== 'undefined' && typeof type.prototype.mountComponent === 'function' && typeof type.prototype.receiveComponent === 'function';
  }
  
  /**
   * Given a ReactNode, create an instance that will actually be mounted.
   *
   * @param {ReactNode} node
   * @param {boolean} shouldHaveDebugID
   * @return {object} A new instance of the element's constructor.
   * @protected
   */
  function instantiateReactComponent(node, shouldHaveDebugID) {
    var instance;
  
    if (node === null || node === false) {
      instance = ReactEmptyComponent_1.create(instantiateReactComponent);
    } else if (typeof node === 'object') {
      var element = node;
      var type = element.type;
      if (typeof type !== 'function' && typeof type !== 'string') {
        var info = '';
        {
          if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
            info += ' You likely forgot to export your component from the file ' + "it's defined in.";
          }
        }
        info += getDeclarationErrorAddendum(element._owner);
        invariant(false, 'Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s', type == null ? type : typeof type, info);
      }
  
      // Special case string values
      if (typeof element.type === 'string') {
        instance = ReactHostComponent_1.createInternalComponent(element);
      } else if (isInternalComponentType(element.type)) {
        // This is temporarily available for custom components that are not string
        // representations. I.e. ART. Once those are updated to use the string
        // representation, we can drop this code path.
        instance = new element.type(element);
  
        // We renamed this. Allow the old name for compat. :(
        if (!instance.getHostNode) {
          instance.getHostNode = instance.getNativeNode;
        }
      } else {
        instance = new ReactCompositeComponentWrapper(element);
      }
    } else if (typeof node === 'string' || typeof node === 'number') {
      instance = ReactHostComponent_1.createInstanceForText(node);
    } else {
      invariant(false, 'Encountered invalid React node of type %s', typeof node);
    }
  
    {
      warning(typeof instance.mountComponent === 'function' && typeof instance.receiveComponent === 'function' && typeof instance.getHostNode === 'function' && typeof instance.unmountComponent === 'function', 'Only React Components can be mounted.');
    }
  
    // These two fields are used by the DOM and ART diffing algorithms
    // respectively. Instead of using expandos on components, we should be
    // storing the state needed by the diffing algorithms elsewhere.
    instance._mountIndex = 0;
    instance._mountImage = null;
  
    {
      instance._debugID = shouldHaveDebugID ? getNextDebugID_1() : 0;
    }
  
    // Internal instances should fully constructed at this point, so they should
    // not get any new fields added to them at this point.
    {
      if (Object.preventExtensions) {
        Object.preventExtensions(instance);
      }
    }
  
    return instance;
  }
  
  _assign(ReactCompositeComponentWrapper.prototype, ReactCompositeComponent_1, {
    _instantiateReactComponent: instantiateReactComponent
  });
  
  var instantiateReactComponent_1 = instantiateReactComponent;
  
  /**
   * Copyright 2014-present, 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.
   *
   * @providesModule ReactElementSymbol
   * 
   */
  
  // The Symbol used to tag the ReactElement type. If there is no native Symbol
  // nor polyfill, then a plain number is used for performance.
  
  var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
  
  var ReactElementSymbol = REACT_ELEMENT_TYPE;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule getIteratorFn
   * 
   */
  
  /* global Symbol */
  
  var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
  var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec.
  
  /**
   * Returns the iterator method function contained on the iterable object.
   *
   * Be sure to invoke the function with the iterable as context:
   *
   *     var iteratorFn = getIteratorFn(myIterable);
   *     if (iteratorFn) {
   *       var iterator = iteratorFn.call(myIterable);
   *       ...
   *     }
   *
   * @param {?object} maybeIterable
   * @return {?function}
   */
  function getIteratorFn(maybeIterable) {
    var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
    if (typeof iteratorFn === 'function') {
      return iteratorFn;
    }
  }
  
  var getIteratorFn_1 = getIteratorFn;
  
  {
    var getCurrentStackAddendum = ReactGlobalSharedState_1.ReactComponentTreeHook.getCurrentStackAddendum;
  }
  
  var SEPARATOR = '.';
  var SUBSEPARATOR = ':';
  
  /**
   * This is inlined from ReactElement since this file is shared between
   * isomorphic and renderers. We could extract this to a
   *
   */
  
  /**
   * TODO: Test that a single child and an array with one item have the same key
   * pattern.
   */
  
  var didWarnAboutMaps = false;
  
  /**
   * Generate a key string that identifies a component within a set.
   *
   * @param {*} component A component that could contain a manual key.
   * @param {number} index Index that is used if a manual key is not provided.
   * @return {string}
   */
  function getComponentKey(component, index) {
    // Do some typechecking here since we call this blindly. We want to ensure
    // that we don't block potential future ES APIs.
    if (component && typeof component === 'object' && component.key != null) {
      // Explicit key
      return KeyEscapeUtils_1.escape(component.key);
    }
    // Implicit key determined by the index in the set
    return index.toString(36);
  }
  
  /**
   * @param {?*} children Children tree container.
   * @param {!string} nameSoFar Name of the key path so far.
   * @param {!function} callback Callback to invoke with each child found.
   * @param {?*} traverseContext Used to pass information throughout the traversal
   * process.
   * @return {!number} The number of children in this subtree.
   */
  function traverseStackChildrenImpl(children, nameSoFar, callback, traverseContext) {
    var type = typeof children;
  
    if (type === 'undefined' || type === 'boolean') {
      // All of the above are perceived as null.
      children = null;
    }
  
    if (children === null || type === 'string' || type === 'number' ||
    // The following is inlined from ReactElement. This means we can optimize
    // some checks. React Fiber also inlines this logic for similar purposes.
    type === 'object' && children.$$typeof === ReactElementSymbol) {
      callback(traverseContext, children,
      // If it's the only child, treat the name as if it was wrapped in an array
      // so that it's consistent if the number of children grows.
      nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
      return 1;
    }
  
    var child;
    var nextName;
    var subtreeCount = 0; // Count of children found in the current subtree.
    var nextNamePrefix = nameSoFar === '' ? SEPARATOR : nameSoFar + SUBSEPARATOR;
  
    if (Array.isArray(children)) {
      for (var i = 0; i < children.length; i++) {
        child = children[i];
        nextName = nextNamePrefix + getComponentKey(child, i);
        subtreeCount += traverseStackChildrenImpl(child, nextName, callback, traverseContext);
      }
    } else {
      var iteratorFn = getIteratorFn_1(children);
      if (iteratorFn) {
        {
          // Warn about using Maps as children
          if (iteratorFn === children.entries) {
            warning(didWarnAboutMaps, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.%s', getCurrentStackAddendum());
            didWarnAboutMaps = true;
          }
        }
  
        var iterator = iteratorFn.call(children);
        var step;
        var ii = 0;
        while (!(step = iterator.next()).done) {
          child = step.value;
          nextName = nextNamePrefix + getComponentKey(child, ii++);
          subtreeCount += traverseStackChildrenImpl(child, nextName, callback, traverseContext);
        }
      } else if (type === 'object') {
        var addendum = '';
        {
          addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentStackAddendum();
        }
        var childrenString = '' + children;
        invariant(false, 'Objects are not valid as a React child (found: %s).%s', childrenString === '[object Object]' ? 'object with keys {' + Object.keys(children).join(', ') + '}' : childrenString, addendum);
      }
    }
  
    return subtreeCount;
  }
  
  /**
   * Traverses children that are typically specified as `props.children`, but
   * might also be specified through attributes:
   *
   * - `traverseStackChildren(this.props.children, ...)`
   * - `traverseStackChildren(this.props.leftPanelChildren, ...)`
   *
   * The `traverseContext` is an optional argument that is passed through the
   * entire traversal. It can be used to store accumulations or anything else that
   * the callback might find relevant.
   *
   * @param {?*} children Children tree object.
   * @param {!function} callback To invoke upon traversing each child.
   * @param {?*} traverseContext Context for traversal.
   * @return {!number} The number of children in this subtree.
   */
  function traverseStackChildren(children, callback, traverseContext) {
    if (children == null) {
      return 0;
    }
  
    return traverseStackChildrenImpl(children, '', callback, traverseContext);
  }
  
  var traverseStackChildren_1 = traverseStackChildren;
  
  var ReactComponentTreeHook$2;
  
  if (typeof process !== 'undefined' && process.env && 'development' === 'test') {
    // Temporary hack.
    // Inline requires don't work well with Jest:
    // https://github.com/facebook/react/issues/7240
    // Remove the inline requires when we don't need them anymore:
    // https://github.com/facebook/react/pull/7178
    ReactComponentTreeHook$2 = ReactGlobalSharedState_1.ReactComponentTreeHook;
  }
  
  function instantiateChild(childInstances, child, name, selfDebugID) {
    // We found a component instance.
    var keyUnique = childInstances[name] === undefined;
    {
      if (!ReactComponentTreeHook$2) {
        ReactComponentTreeHook$2 = ReactGlobalSharedState_1.ReactComponentTreeHook;
      }
      if (!keyUnique) {
        warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils_1.unescape(name), ReactComponentTreeHook$2.getStackAddendumByID(selfDebugID));
      }
    }
    if (child != null && keyUnique) {
      childInstances[name] = instantiateReactComponent_1(child, true);
    }
  }
  
  /**
   * ReactChildReconciler provides helpers for initializing or updating a set of
   * children. Its output is suitable for passing it onto ReactMultiChild which
   * does diffed reordering and insertion.
   */
  var ReactChildReconciler = {
    /**
     * Generates a "mount image" for each of the supplied children. In the case
     * of `ReactDOMComponent`, a mount image is a string of markup.
     *
     * @param {?object} nestedChildNodes Nested child maps.
     * @return {?object} A set of child instances.
     * @internal
     */
    instantiateChildren: function (nestedChildNodes, transaction, context, selfDebugID) // 0 in production and for roots
    {
      if (nestedChildNodes == null) {
        return null;
      }
      var childInstances = {};
  
      {
        traverseStackChildren_1(nestedChildNodes, function (childInsts, child, name) {
          return instantiateChild(childInsts, child, name, selfDebugID);
        }, childInstances);
      }
      return childInstances;
    },
  
    /**
     * Updates the rendered children and returns a new set of children.
     *
     * @param {?object} prevChildren Previously initialized set of children.
     * @param {?object} nextChildren Flat child element maps.
     * @param {ReactReconcileTransaction} transaction
     * @param {object} context
     * @return {?object} A new set of child instances.
     * @internal
     */
    updateChildren: function (prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID) // 0 in production and for roots
    {
      // We currently don't have a way to track moves here but if we use iterators
      // instead of for..in we can zip the iterators and check if an item has
      // moved.
      // TODO: If nothing has changed, return the prevChildren object so that we
      // can quickly bailout if nothing has changed.
      if (!nextChildren && !prevChildren) {
        return;
      }
      var name;
      var prevChild;
      for (name in nextChildren) {
        if (!nextChildren.hasOwnProperty(name)) {
          continue;
        }
        prevChild = prevChildren && prevChildren[name];
        var prevElement = prevChild && prevChild._currentElement;
        var nextElement = nextChildren[name];
        if (prevChild != null && shouldUpdateReactComponent_1(prevElement, nextElement)) {
          ReactReconciler_1.receiveComponent(prevChild, nextElement, transaction, context);
          nextChildren[name] = prevChild;
        } else {
          if (!ReactFeatureFlags_1.prepareNewChildrenBeforeUnmountInStack && prevChild) {
            removedNodes[name] = ReactReconciler_1.getHostNode(prevChild);
            ReactReconciler_1.unmountComponent(prevChild, false /* safely */
            , false /* skipLifecycle */
            );
          }
          // The child must be instantiated before it's mounted.
          var nextChildInstance = instantiateReactComponent_1(nextElement, true);
          nextChildren[name] = nextChildInstance;
          // Creating mount image now ensures refs are resolved in right order
          // (see https://github.com/facebook/react/pull/7101 for explanation).
          var nextChildMountImage = ReactReconciler_1.mountComponent(nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID);
          mountImages.push(nextChildMountImage);
          if (ReactFeatureFlags_1.prepareNewChildrenBeforeUnmountInStack && prevChild) {
            removedNodes[name] = ReactReconciler_1.getHostNode(prevChild);
            ReactReconciler_1.unmountComponent(prevChild, false /* safely */
            , false /* skipLifecycle */
            );
          }
        }
      }
      // Unmount children that are no longer present.
      for (name in prevChildren) {
        if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) {
          prevChild = prevChildren[name];
          removedNodes[name] = ReactReconciler_1.getHostNode(prevChild);
          ReactReconciler_1.unmountComponent(prevChild, false /* safely */
          , false /* skipLifecycle */
          );
        }
      }
    },
  
    /**
     * Unmounts all rendered children. This should be used to clean up children
     * when this component is unmounted.
     *
     * @param {?object} renderedChildren Previously initialized set of children.
     * @internal
     */
    unmountChildren: function (renderedChildren, safely, skipLifecycle) {
      for (var name in renderedChildren) {
        if (renderedChildren.hasOwnProperty(name)) {
          var renderedChild = renderedChildren[name];
          ReactReconciler_1.unmountComponent(renderedChild, safely, skipLifecycle);
        }
      }
    }
  };
  
  var ReactChildReconciler_1 = ReactChildReconciler;
  
  var ReactComponentTreeHook$3;
  
  if (typeof process !== 'undefined' && process.env && 'development' === 'test') {
    // Temporary hack.
    // Inline requires don't work well with Jest:
    // https://github.com/facebook/react/issues/7240
    // Remove the inline requires when we don't need them anymore:
    // https://github.com/facebook/react/pull/7178
    ReactComponentTreeHook$3 = ReactGlobalSharedState_1.ReactComponentTreeHook;
  }
  
  /**
   * @param {function} traverseContext Context passed through traversal.
   * @param {?ReactComponent} child React child component.
   * @param {!string} name String name of key path to child.
   * @param {number=} selfDebugID Optional debugID of the current internal instance.
   */
  function flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID) {
    // We found a component instance.
    if (traverseContext && typeof traverseContext === 'object') {
      var result = traverseContext;
      var keyUnique = result[name] === undefined;
      {
        if (!ReactComponentTreeHook$3) {
          ReactComponentTreeHook$3 = ReactGlobalSharedState_1.ReactComponentTreeHook;
        }
        if (!keyUnique) {
          warning(false, 'flattenChildren(...): Encountered two children with the same key, ' + '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils_1.unescape(name), ReactComponentTreeHook$3.getStackAddendumByID(selfDebugID));
        }
      }
      if (keyUnique && child != null) {
        result[name] = child;
      }
    }
  }
  
  /**
   * Flattens children that are typically specified as `props.children`. Any null
   * children will not be included in the resulting object.
   * @return {!object} flattened children keyed by name.
   */
  function flattenStackChildren(children, selfDebugID) {
    if (children == null) {
      return children;
    }
    var result = {};
  
    {
      traverseStackChildren_1(children, function (traverseContext, child, name) {
        return flattenSingleChildIntoContext(traverseContext, child, name, selfDebugID);
      }, result);
    }
    return result;
  }
  
  var flattenStackChildren_1 = flattenStackChildren;
  
  var ReactCurrentOwner = ReactGlobalSharedState_1.ReactCurrentOwner;
  
  
  
  
  
  /**
   * Make an update for markup to be rendered and inserted at a supplied index.
   *
   * @param {string} markup Markup that renders into an element.
   * @param {number} toIndex Destination index.
   * @private
   */
  function makeInsertMarkup(markup, afterNode, toIndex) {
    // NOTE: Null values reduce hidden classes.
    return {
      type: 'INSERT_MARKUP',
      content: markup,
      fromIndex: null,
      fromNode: null,
      toIndex: toIndex,
      afterNode: afterNode
    };
  }
  
  /**
   * Make an update for moving an existing element to another index.
   *
   * @param {number} fromIndex Source index of the existing element.
   * @param {number} toIndex Destination index of the element.
   * @private
   */
  function makeMove(child, afterNode, toIndex) {
    // NOTE: Null values reduce hidden classes.
    return {
      type: 'MOVE_EXISTING',
      content: null,
      fromIndex: child._mountIndex,
      fromNode: ReactReconciler_1.getHostNode(child),
      toIndex: toIndex,
      afterNode: afterNode
    };
  }
  
  /**
   * Make an update for removing an element at an index.
   *
   * @param {number} fromIndex Index of the element to remove.
   * @private
   */
  function makeRemove(child, node) {
    // NOTE: Null values reduce hidden classes.
    return {
      type: 'REMOVE_NODE',
      content: null,
      fromIndex: child._mountIndex,
      fromNode: node,
      toIndex: null,
      afterNode: null
    };
  }
  
  /**
   * Make an update for setting the markup of a node.
   *
   * @param {string} markup Markup that renders into an element.
   * @private
   */
  function makeSetMarkup(markup) {
    // NOTE: Null values reduce hidden classes.
    return {
      type: 'SET_MARKUP',
      content: markup,
      fromIndex: null,
      fromNode: null,
      toIndex: null,
      afterNode: null
    };
  }
  
  /**
   * Make an update for setting the text content.
   *
   * @param {string} textContent Text content to set.
   * @private
   */
  function makeTextContent(textContent) {
    // NOTE: Null values reduce hidden classes.
    return {
      type: 'TEXT_CONTENT',
      content: textContent,
      fromIndex: null,
      fromNode: null,
      toIndex: null,
      afterNode: null
    };
  }
  
  /**
   * Push an update, if any, onto the queue. Creates a new queue if none is
   * passed and always returns the queue. Mutative.
   */
  function enqueue(queue, update) {
    if (update) {
      queue = queue || [];
      queue.push(update);
    }
    return queue;
  }
  
  /**
   * Processes any enqueued updates.
   *
   * @private
   */
  function processQueue(inst, updateQueue) {
    ReactComponentEnvironment_1.processChildrenUpdates(inst, updateQueue);
  }
  
  var setChildrenForInstrumentation = emptyFunction;
  {
    var getDebugID = function (inst) {
      if (!inst._debugID) {
        // Check for ART-like instances. TODO: This is silly/gross.
        var internal;
        if (internal = ReactInstanceMap_1.get(inst)) {
          inst = internal;
        }
      }
      return inst._debugID;
    };
    setChildrenForInstrumentation = function (children) {
      var debugID = getDebugID(this);
      // TODO: React Native empty components are also multichild.
      // This means they still get into this method but don't have _debugID.
      if (debugID !== 0) {
        ReactInstrumentation.debugTool.onSetChildren(debugID, children ? Object.keys(children).map(function (key) {
          return children[key]._debugID;
        }) : []);
      }
    };
  }
  
  /**
   * Provides common functionality for components that must reconcile multiple
   * children. This is used by `ReactDOMComponent` to mount, update, and
   * unmount child components.
   */
  var ReactMultiChild = {
    _reconcilerInstantiateChildren: function (nestedChildren, transaction, context) {
      {
        var selfDebugID = getDebugID(this);
        if (this._currentElement) {
          try {
            ReactCurrentOwner.current = this._currentElement._owner;
            return ReactChildReconciler_1.instantiateChildren(nestedChildren, transaction, context, selfDebugID);
          } finally {
            ReactCurrentOwner.current = null;
          }
        }
      }
      return ReactChildReconciler_1.instantiateChildren(nestedChildren, transaction, context);
    },
  
    _reconcilerUpdateChildren: function (prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context) {
      var nextChildren;
      var selfDebugID = 0;
      {
        selfDebugID = getDebugID(this);
        if (this._currentElement) {
          try {
            ReactCurrentOwner.current = this._currentElement._owner;
            nextChildren = flattenStackChildren_1(nextNestedChildrenElements, selfDebugID);
          } finally {
            ReactCurrentOwner.current = null;
          }
          ReactChildReconciler_1.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID);
          return nextChildren;
        }
      }
      nextChildren = flattenStackChildren_1(nextNestedChildrenElements, selfDebugID);
      ReactChildReconciler_1.updateChildren(prevChildren, nextChildren, mountImages, removedNodes, transaction, this, this._hostContainerInfo, context, selfDebugID);
      return nextChildren;
    },
  
    /**
     * Generates a "mount image" for each of the supplied children. In the case
     * of `ReactDOMComponent`, a mount image is a string of markup.
     *
     * @param {?object} nestedChildren Nested child maps.
     * @return {array} An array of mounted representations.
     * @internal
     */
    mountChildren: function (nestedChildren, transaction, context) {
      var children = this._reconcilerInstantiateChildren(nestedChildren, transaction, context);
      this._renderedChildren = children;
  
      var mountImages = [];
      var index = 0;
      for (var name in children) {
        if (children.hasOwnProperty(name)) {
          var child = children[name];
          var selfDebugID = 0;
          {
            selfDebugID = getDebugID(this);
          }
          var mountImage = ReactReconciler_1.mountComponent(child, transaction, this, this._hostContainerInfo, context, selfDebugID);
          child._mountIndex = index++;
          mountImages.push(mountImage);
        }
      }
  
      {
        setChildrenForInstrumentation.call(this, children);
      }
  
      return mountImages;
    },
  
    /**
     * Replaces any rendered children with a text content string.
     *
     * @param {string} nextContent String of content.
     * @internal
     */
    updateTextContent: function (nextContent) {
      var prevChildren = this._renderedChildren;
      // Remove any rendered children.
      ReactChildReconciler_1.unmountChildren(prevChildren, false /* safely */
      , false /* skipLifecycle */
      );
      for (var name in prevChildren) {
        if (prevChildren.hasOwnProperty(name)) {
          invariant(false, 'updateTextContent called on non-empty component.');
        }
      }
      // Set new text content.
      var updates = [makeTextContent(nextContent)];
      processQueue(this, updates);
    },
  
    /**
     * Replaces any rendered children with a markup string.
     *
     * @param {string} nextMarkup String of markup.
     * @internal
     */
    updateMarkup: function (nextMarkup) {
      var prevChildren = this._renderedChildren;
      // Remove any rendered children.
      ReactChildReconciler_1.unmountChildren(prevChildren, false /* safely */
      , false /* skipLifecycle */
      );
      for (var name in prevChildren) {
        if (prevChildren.hasOwnProperty(name)) {
          invariant(false, 'updateTextContent called on non-empty component.');
        }
      }
      var updates = [makeSetMarkup(nextMarkup)];
      processQueue(this, updates);
    },
  
    /**
     * Updates the rendered children with new children.
     *
     * @param {?object} nextNestedChildrenElements Nested child element maps.
     * @param {ReactReconcileTransaction} transaction
     * @internal
     */
    updateChildren: function (nextNestedChildrenElements, transaction, context) {
      // Hook used by React ART
      this._updateChildren(nextNestedChildrenElements, transaction, context);
    },
  
    /**
     * @param {?object} nextNestedChildrenElements Nested child element maps.
     * @param {ReactReconcileTransaction} transaction
     * @final
     * @protected
     */
    _updateChildren: function (nextNestedChildrenElements, transaction, context) {
      var prevChildren = this._renderedChildren;
      var removedNodes = {};
      var mountImages = [];
      var nextChildren = this._reconcilerUpdateChildren(prevChildren, nextNestedChildrenElements, mountImages, removedNodes, transaction, context);
      if (!nextChildren && !prevChildren) {
        return;
      }
      var updates = null;
      var name;
      // `nextIndex` will increment for each child in `nextChildren`, but
      // `lastIndex` will be the last index visited in `prevChildren`.
      var nextIndex = 0;
      var lastIndex = 0;
      // `nextMountIndex` will increment for each newly mounted child.
      var nextMountIndex = 0;
      var lastPlacedNode = null;
      for (name in nextChildren) {
        if (!nextChildren.hasOwnProperty(name)) {
          continue;
        }
        var prevChild = prevChildren && prevChildren[name];
        var nextChild = nextChildren[name];
        if (prevChild === nextChild) {
          updates = enqueue(updates, this.moveChild(prevChild, lastPlacedNode, nextIndex, lastIndex));
          lastIndex = Math.max(prevChild._mountIndex, lastIndex);
          prevChild._mountIndex = nextIndex;
        } else {
          if (prevChild) {
            // Update `lastIndex` before `_mountIndex` gets unset by unmounting.
            lastIndex = Math.max(prevChild._mountIndex, lastIndex);
            // The `removedNodes` loop below will actually remove the child.
          }
          // The child must be instantiated before it's mounted.
          updates = enqueue(updates, this._mountChildAtIndex(nextChild, mountImages[nextMountIndex], lastPlacedNode, nextIndex, transaction, context));
          nextMountIndex++;
        }
        nextIndex++;
        lastPlacedNode = ReactReconciler_1.getHostNode(nextChild);
      }
      // Remove children that are no longer present.
      for (name in removedNodes) {
        if (removedNodes.hasOwnProperty(name)) {
          updates = enqueue(updates, this._unmountChild(prevChildren[name], removedNodes[name]));
        }
      }
      if (updates) {
        processQueue(this, updates);
      }
      this._renderedChildren = nextChildren;
  
      {
        setChildrenForInstrumentation.call(this, nextChildren);
      }
    },
  
    /**
     * Unmounts all rendered children. This should be used to clean up children
     * when this component is unmounted. It does not actually perform any
     * backend operations.
     *
     * @internal
     */
    unmountChildren: function (safely, skipLifecycle) {
      var renderedChildren = this._renderedChildren;
      ReactChildReconciler_1.unmountChildren(renderedChildren, safely, skipLifecycle);
      this._renderedChildren = null;
    },
  
    /**
     * Moves a child component to the supplied index.
     *
     * @param {ReactComponent} child Component to move.
     * @param {number} toIndex Destination index of the element.
     * @param {number} lastIndex Last index visited of the siblings of `child`.
     * @protected
     */
    moveChild: function (child, afterNode, toIndex, lastIndex) {
      // If the index of `child` is less than `lastIndex`, then it needs to
      // be moved. Otherwise, we do not need to move it because a child will be
      // inserted or moved before `child`.
      if (child._mountIndex < lastIndex) {
        return makeMove(child, afterNode, toIndex);
      }
    },
  
    /**
     * Creates a child component.
     *
     * @param {ReactComponent} child Component to create.
     * @param {string} mountImage Markup to insert.
     * @protected
     */
    createChild: function (child, afterNode, mountImage) {
      return makeInsertMarkup(mountImage, afterNode, child._mountIndex);
    },
  
    /**
     * Removes a child component.
     *
     * @param {ReactComponent} child Child to remove.
     * @protected
     */
    removeChild: function (child, node) {
      return makeRemove(child, node);
    },
  
    /**
     * Mounts a child with the supplied name.
     *
     * NOTE: This is part of `updateChildren` and is here for readability.
     *
     * @param {ReactComponent} child Component to mount.
     * @param {string} name Name of the child.
     * @param {number} index Index at which to insert the child.
     * @param {ReactReconcileTransaction} transaction
     * @private
     */
    _mountChildAtIndex: function (child, mountImage, afterNode, index, transaction, context) {
      child._mountIndex = index;
      return this.createChild(child, afterNode, mountImage);
    },
  
    /**
     * Unmounts a rendered child.
     *
     * NOTE: This is part of `updateChildren` and is here for readability.
     *
     * @param {ReactComponent} child Component to unmount.
     * @private
     */
    _unmountChild: function (child, node) {
      var update = this.removeChild(child, node);
      child._mountIndex = null;
      return update;
    }
  };
  
  var ReactMultiChild_1 = ReactMultiChild;
  
  function getHostComponentFromComposite(inst) {
    var type;
  
    while ((type = inst._renderedNodeType) === ReactNodeTypes_1.COMPOSITE) {
      inst = inst._renderedComponent;
    }
  
    if (type === ReactNodeTypes_1.HOST) {
      return inst._renderedComponent;
    } else if (type === ReactNodeTypes_1.EMPTY) {
      return null;
    }
  }
  
  var getHostComponentFromComposite_1 = getHostComponentFromComposite;
  
  var _extends = _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 defaultTestOptions = {
    createNodeMock: function () {
      return null;
    }
  };
  
  /**
   * Temporary (?) hack so that we can store all top-level pending updates on
   * composites instead of having to worry about different types of components
   * here.
   */
  var TopLevelWrapper = function () {};
  TopLevelWrapper.prototype.isReactComponent = {};
  {
    TopLevelWrapper.displayName = 'TopLevelWrapper';
  }
  TopLevelWrapper.prototype.render = function () {
    return this.props.child;
  };
  TopLevelWrapper.isReactTopLevelWrapper = true;
  
  /**
   * Mounts this component and inserts it into the DOM.
   *
   * @param {ReactComponent} componentInstance The instance to mount.
   * @param {ReactReconcileTransaction} transaction
   * @param {Object} hostParent
   * @param {Object} hostContainerInfo
   */
  function mountComponentIntoNode(componentInstance, transaction, hostParent, hostContainerInfo) {
    var image = ReactReconciler_1.mountComponent(componentInstance, transaction, null, hostContainerInfo, emptyObject);
    componentInstance._renderedComponent._topLevelWrapper = componentInstance;
    return image;
  }
  
  /**
   * Batched mount.
   *
   * @param {ReactComponent} componentInstance The instance to mount.
   * @param {number} rootID ID of the root node.
   * @param {number} containerTag container element to mount into.
   */
  function batchedMountComponentIntoNode(componentInstance, options) {
    var transaction = ReactUpdates_1.ReactReconcileTransaction.getPooled(true);
    var image = transaction.perform(mountComponentIntoNode, null, componentInstance, transaction, null, options);
    ReactUpdates_1.ReactReconcileTransaction.release(transaction);
    return image;
  }
  
  var ReactTestInstance = function (component) {
    this._component = component;
  };
  ReactTestInstance.prototype.getInstance = function () {
    return this._component._renderedComponent.getPublicInstance();
  };
  ReactTestInstance.prototype.update = function (nextElement) {
    !this._component ? invariant(false, 'ReactTestRenderer: .update() can\'t be called after unmount.') : void 0;
    var nextWrappedElement = React.createElement(TopLevelWrapper, {
      child: nextElement
    });
    var component = this._component;
    ReactUpdates_1.batchedUpdates(function () {
      var transaction = ReactUpdates_1.ReactReconcileTransaction.getPooled(true);
      transaction.perform(function () {
        ReactReconciler_1.receiveComponent(component, nextWrappedElement, transaction, emptyObject);
      });
      ReactUpdates_1.ReactReconcileTransaction.release(transaction);
    });
  };
  ReactTestInstance.prototype.unmount = function (nextElement) {
    var component = this._component;
    ReactUpdates_1.batchedUpdates(function () {
      var transaction = ReactUpdates_1.ReactReconcileTransaction.getPooled(true);
      transaction.perform(function () {
        ReactReconciler_1.unmountComponent(component, false /* safely */
        , false /* skipLifecycle */
        );
      });
      ReactUpdates_1.ReactReconcileTransaction.release(transaction);
    });
    this._component = null;
  };
  ReactTestInstance.prototype.toTree = function () {
    return toTree(this._component._renderedComponent);
  };
  ReactTestInstance.prototype.toJSON = function () {
    var inst = getHostComponentFromComposite_1(this._component);
    if (inst === null) {
      return null;
    }
    return inst.toJSON();
  };
  
  function toTree(component) {
    var element = component._currentElement;
    if (!React.isValidElement(element)) {
      return element;
    }
    if (!component._renderedComponent) {
      var rendered = [];
      for (var key in component._renderedChildren) {
        var inst = component._renderedChildren[key];
        var json = toTree(inst);
        if (json !== undefined) {
          rendered.push(json);
        }
      }
  
      return {
        nodeType: 'host',
        type: element.type,
        props: _extends({}, element.props),
        instance: component._nodeMock,
        rendered: rendered
      };
    } else {
      return {
        nodeType: 'component',
        type: element.type,
        props: _extends({}, element.props),
        instance: component._instance,
        rendered: toTree(component._renderedComponent)
      };
    }
  }
  
  /**
   * As soon as `ReactMount` is refactored to not rely on the DOM, we can share
   * code between the two. For now, we'll hard code the ID logic.
   */
  var ReactTestMount = {
    render: function (nextElement, options) {
      var nextWrappedElement = React.createElement(TopLevelWrapper, {
        child: nextElement
      });
  
      var instance = instantiateReactComponent_1(nextWrappedElement, false);
  
      // The initial render is synchronous but any updates that happen during
      // rendering, in componentWillMount or componentDidMount, will be batched
      // according to the current batching strategy.
      ReactUpdates_1.batchedUpdates(batchedMountComponentIntoNode, instance, _assign({}, defaultTestOptions, options));
      return new ReactTestInstance(instance);
    }
  };
  
  var ReactTestMount_1 = ReactTestMount;
  
  function validateCallback(callback) {
    invariant(!callback || typeof callback === 'function', 'Invalid argument passed as callback. Expected a function. Instead ' + 'received: %s', callback);
  }
  
  var validateCallback_1 = validateCallback;
  
  function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  
  
  
  
  
  /**
   * A specialized pseudo-event module to help keep track of components waiting to
   * be notified when their DOM representations are available for use.
   *
   * This implements `PooledClass`, so you should never need to instantiate this.
   * Instead, use `CallbackQueue.getPooled()`.
   *
   * @class CallbackQueue
   * @implements PooledClass
   * @internal
   */
  
  var CallbackQueue = function () {
    function CallbackQueue(arg) {
      _classCallCheck$1(this, CallbackQueue);
  
      this._callbacks = null;
      this._contexts = null;
      this._arg = arg;
    }
  
    /**
     * Enqueues a callback to be invoked when `notifyAll` is invoked.
     *
     * @param {function} callback Invoked when `notifyAll` is invoked.
     * @param {?object} context Context to call `callback` with.
     * @internal
     */
  
  
    CallbackQueue.prototype.enqueue = function enqueue(callback, context) {
      this._callbacks = this._callbacks || [];
      this._callbacks.push(callback);
      this._contexts = this._contexts || [];
      this._contexts.push(context);
    };
  
    /**
     * Invokes all enqueued callbacks and clears the queue. This is invoked after
     * the DOM representation of a component has been created or updated.
     *
     * @internal
     */
  
  
    CallbackQueue.prototype.notifyAll = function notifyAll() {
      var callbacks = this._callbacks;
      var contexts = this._contexts;
      var arg = this._arg;
      if (callbacks && contexts) {
        !(callbacks.length === contexts.length) ? invariant(false, 'Mismatched list of contexts in callback queue') : void 0;
        this._callbacks = null;
        this._contexts = null;
        for (var i = 0; i < callbacks.length; i++) {
          validateCallback_1(callbacks[i]);
          callbacks[i].call(contexts[i], arg);
        }
        callbacks.length = 0;
        contexts.length = 0;
      }
    };
  
    CallbackQueue.prototype.checkpoint = function checkpoint() {
      return this._callbacks ? this._callbacks.length : 0;
    };
  
    CallbackQueue.prototype.rollback = function rollback(len) {
      if (this._callbacks && this._contexts) {
        this._callbacks.length = len;
        this._contexts.length = len;
      }
    };
  
    /**
     * Resets the internal queue.
     *
     * @internal
     */
  
  
    CallbackQueue.prototype.reset = function reset() {
      this._callbacks = null;
      this._contexts = null;
    };
  
    /**
     * `PooledClass` looks for this.
     */
  
  
    CallbackQueue.prototype.destructor = function destructor() {
      this.reset();
    };
  
    return CallbackQueue;
  }();
  
  var CallbackQueue_1 = PooledClass_1.addPoolingTo(CallbackQueue);
  
  var ReactCurrentOwner$2 = ReactGlobalSharedState_1.ReactCurrentOwner;
  
  {
    var warning$2 = warning;
    var warnOnInvalidCallback = function (callback, callerName) {
      warning$2(callback === null || typeof callback === 'function', '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, '' + callback);
    };
  }
  
  function enqueueUpdate$1(internalInstance) {
    ReactUpdates_1.enqueueUpdate(internalInstance);
  }
  
  function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
    var internalInstance = ReactInstanceMap_1.get(publicInstance);
    if (!internalInstance) {
      {
        var ctor = publicInstance.constructor;
        warning$2(false, 'Can only update a mounted or mounting component. This usually means ' + 'you called setState, replaceState, or forceUpdate on an unmounted ' + 'component. This is a no-op.\n\nPlease check the code for the ' + '%s component.', ctor && (ctor.displayName || ctor.name) || 'ReactClass');
      }
      return null;
    }
  
    {
      warning$2(ReactCurrentOwner$2.current == null, 'Cannot update during an existing state transition (such as within ' + "`render` or another component's constructor). Render methods should " + 'be a pure function of props and state; constructor side-effects are ' + 'an anti-pattern, but can be moved to `componentWillMount`.');
    }
  
    return internalInstance;
  }
  
  /**
   * ReactUpdateQueue allows for state updates to be scheduled into a later
   * reconciliation step.
   */
  var ReactUpdateQueue = {
    /**
     * Checks whether or not this composite component is mounted.
     * @param {ReactClass} publicInstance The instance we want to test.
     * @return {boolean} True if mounted, false otherwise.
     * @protected
     * @final
     */
    isMounted: function (publicInstance) {
      {
        var owner = ReactCurrentOwner$2.current;
        if (owner !== null) {
          warning$2(owner._warnedAboutRefsInRender, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', owner.getName() || 'A component');
          owner._warnedAboutRefsInRender = true;
        }
      }
      var internalInstance = ReactInstanceMap_1.get(publicInstance);
      if (internalInstance) {
        // During componentWillMount and render this will still be null but after
        // that will always render to something. At least for now. So we can use
        // this hack.
        return !!internalInstance._renderedComponent;
      } else {
        return false;
      }
    },
  
    enqueueCallbackInternal: function (internalInstance, callback) {
      if (internalInstance._pendingCallbacks) {
        internalInstance._pendingCallbacks.push(callback);
      } else {
        internalInstance._pendingCallbacks = [callback];
      }
      enqueueUpdate$1(internalInstance);
    },
  
    /**
     * Forces an update. This should only be invoked when it is known with
     * certainty that we are **not** in a DOM transaction.
     *
     * You may want to call this when you know that some deeper aspect of the
     * component's state has changed but `setState` was not called.
     *
     * This will not invoke `shouldComponentUpdate`, but it will invoke
     * `componentWillUpdate` and `componentDidUpdate`.
     *
     * @param {ReactClass} publicInstance The instance that should rerender.
     * @param {?function} callback Called after component is updated.
     * @param {?string} Name of the calling function in the public API.
     * @internal
     */
    enqueueForceUpdate: function (publicInstance, callback, callerName) {
      var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
  
      if (!internalInstance) {
        return;
      }
  
      callback = callback === undefined ? null : callback;
      if (callback !== null) {
        {
          warnOnInvalidCallback(callback, callerName);
        }
        if (internalInstance._pendingCallbacks) {
          internalInstance._pendingCallbacks.push(callback);
        } else {
          internalInstance._pendingCallbacks = [callback];
        }
      }
  
      internalInstance._pendingForceUpdate = true;
  
      enqueueUpdate$1(internalInstance);
    },
  
    /**
     * Replaces all of the state. Always use this or `setState` to mutate state.
     * You should treat `this.state` as immutable.
     *
     * There is no guarantee that `this.state` will be immediately updated, so
     * accessing `this.state` after calling this method may return the old value.
     *
     * @param {ReactClass} publicInstance The instance that should rerender.
     * @param {object} completeState Next state.
     * @param {?function} callback Called after state is updated.
     * @param {?string} Name of the calling function in the public API.
     * @internal
     */
    enqueueReplaceState: function (publicInstance, completeState, callback, callerName) {
      var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
  
      if (!internalInstance) {
        return;
      }
  
      internalInstance._pendingStateQueue = [completeState];
      internalInstance._pendingReplaceState = true;
  
      callback = callback === undefined ? null : callback;
      if (callback !== null) {
        {
          warnOnInvalidCallback(callback, callerName);
        }
        if (internalInstance._pendingCallbacks) {
          internalInstance._pendingCallbacks.push(callback);
        } else {
          internalInstance._pendingCallbacks = [callback];
        }
      }
  
      enqueueUpdate$1(internalInstance);
    },
  
    /**
     * Sets a subset of the state. This only exists because _pendingState is
     * internal. This provides a merging strategy that is not available to deep
     * properties which is confusing. TODO: Expose pendingState or don't use it
     * during the merge.
     *
     * @param {ReactClass} publicInstance The instance that should rerender.
     * @param {object} partialState Next partial state to be merged with state.
     * @param {?function} callback Called after state is updated.
     * @param {?string} Name of the calling function in the public API.
     * @internal
     */
    enqueueSetState: function (publicInstance, partialState, callback, callerName) {
      {
        ReactInstrumentation.debugTool.onSetState();
        warning$2(partialState != null, 'setState(...): You passed an undefined or null state object; ' + 'instead, use forceUpdate().');
      }
  
      var internalInstance = getInternalInstanceReadyForUpdate(publicInstance);
  
      if (!internalInstance) {
        return;
      }
  
      var queue = internalInstance._pendingStateQueue || (internalInstance._pendingStateQueue = []);
      queue.push(partialState);
  
      callback = callback === undefined ? null : callback;
      if (callback !== null) {
        {
          warnOnInvalidCallback(callback, callerName);
        }
        if (internalInstance._pendingCallbacks) {
          internalInstance._pendingCallbacks.push(callback);
        } else {
          internalInstance._pendingCallbacks = [callback];
        }
      }
  
      enqueueUpdate$1(internalInstance);
    },
  
    enqueueElementInternal: function (internalInstance, nextElement, nextContext) {
      internalInstance._pendingElement = nextElement;
      // TODO: introduce _pendingContext instead of setting it directly.
      internalInstance._context = nextContext;
      enqueueUpdate$1(internalInstance);
    }
  };
  
  var ReactUpdateQueue_1 = ReactUpdateQueue;
  
  /**
   * Provides a `CallbackQueue` queue for collecting `onDOMReady` callbacks during
   * the performing of the transaction.
   */
  var ON_DOM_READY_QUEUEING = {
    /**
     * Initializes the internal `onDOMReady` queue.
     */
    initialize: function () {
      this.reactMountReady.reset();
    },
  
    /**
     * After DOM is flushed, invoke all registered `onDOMReady` callbacks.
     */
    close: function () {
      this.reactMountReady.notifyAll();
    }
  };
  
  /**
   * Executed within the scope of the `Transaction` instance. Consider these as
   * being member methods, but with an implied ordering while being isolated from
   * each other.
   */
  var TRANSACTION_WRAPPERS$2 = [ON_DOM_READY_QUEUEING];
  
  /**
   * Currently:
   * - The order that these are listed in the transaction is critical:
   * - Suppresses events.
   * - Restores selection range.
   *
   * Future:
   * - Restore document/overflow scroll positions that were unintentionally
   *   modified via DOM insertions above the top viewport boundary.
   * - Implement/integrate with customized constraint based layout system and keep
   *   track of which dimensions must be remeasured.
   *
   * @class ReactTestReconcileTransaction
   */
  function ReactTestReconcileTransaction(testOptions) {
    this.reinitializeTransaction();
    this.testOptions = testOptions;
    this.reactMountReady = CallbackQueue_1.getPooled(this);
  }
  
  var Mixin = {
    /**
     * @see Transaction
     * @abstract
     * @final
     * @return {array<object>} List of operation wrap procedures.
     *   TODO: convert to array<TransactionWrapper>
     */
    getTransactionWrappers: function () {
      return TRANSACTION_WRAPPERS$2;
    },
  
    /**
     * @return {object} The queue to collect `onDOMReady` callbacks with.
     *   TODO: convert to ReactMountReady
     */
    getReactMountReady: function () {
      return this.reactMountReady;
    },
  
    /**
     * @return {object} the options passed to ReactTestRenderer
     */
    getTestOptions: function () {
      return this.testOptions;
    },
  
    /**
     * @return {object} The queue to collect React async events.
     */
    getUpdateQueue: function () {
      return ReactUpdateQueue_1;
    },
  
    /**
     * Save current transaction state -- if the return value from this method is
     * passed to `rollback`, the transaction will be reset to that state.
     */
    checkpoint: function () {
      // reactMountReady is the our only stateful wrapper
      return this.reactMountReady.checkpoint();
    },
  
    rollback: function (checkpoint) {
      this.reactMountReady.rollback(checkpoint);
    },
  
    /**
     * `PooledClass` looks for this, and will invoke this before allowing this
     * instance to be reused.
     */
    destructor: function () {
      CallbackQueue_1.release(this.reactMountReady);
      this.reactMountReady = null;
    }
  };
  
  _assign(ReactTestReconcileTransaction.prototype, Transaction, ReactTestReconcileTransaction, Mixin);
  
  PooledClass_1.addPoolingTo(ReactTestReconcileTransaction);
  
  var ReactTestReconcileTransaction_1 = ReactTestReconcileTransaction;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule ReactTestTextComponent
   * @preventMunge
   * 
   */
  
  function _classCallCheck$2(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var ReactTestTextComponent = function () {
    function ReactTestTextComponent(element) {
      _classCallCheck$2(this, ReactTestTextComponent);
  
      this._currentElement = element;
    }
  
    ReactTestTextComponent.prototype.receiveComponent = function receiveComponent(nextElement) {
      this._currentElement = nextElement;
    };
  
    ReactTestTextComponent.prototype.toJSON = function toJSON() {
      return this._currentElement;
    };
  
    ReactTestTextComponent.prototype.mountComponent = function mountComponent() {};
  
    ReactTestTextComponent.prototype.getHostNode = function getHostNode() {};
  
    ReactTestTextComponent.prototype.unmountComponent = function unmountComponent() {};
  
    return ReactTestTextComponent;
  }();
  
  var ReactTestTextComponent_1 = ReactTestTextComponent;
  
  /**
   * Copyright 2013-present, 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.
   *
   * @providesModule ReactTestEmptyComponent
   * @preventMunge
   * 
   */
  
  function _classCallCheck$3(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var ReactTestEmptyComponent = function () {
    function ReactTestEmptyComponent() {
      _classCallCheck$3(this, ReactTestEmptyComponent);
  
      this._currentElement = null;
    }
  
    ReactTestEmptyComponent.prototype.receiveComponent = function receiveComponent() {};
  
    ReactTestEmptyComponent.prototype.toJSON = function toJSON() {};
  
    ReactTestEmptyComponent.prototype.mountComponent = function mountComponent() {};
  
    ReactTestEmptyComponent.prototype.getHostNode = function getHostNode() {};
  
    ReactTestEmptyComponent.prototype.unmountComponent = function unmountComponent() {};
  
    return ReactTestEmptyComponent;
  }();
  
  var ReactTestEmptyComponent_1 = ReactTestEmptyComponent;
  
  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"); } }
  
  
  
  
  
  
  
  
  
  
  
  
  
  var injected = false;
  function inject() {
    if (injected) {
      return;
    }
  
    injected = true;
  
    ReactUpdates_1.injection.injectReconcileTransaction(ReactTestReconcileTransaction_1);
    ReactUpdates_1.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy_1);
  
    ReactHostComponent_1.injection.injectGenericComponentClass(ReactTestComponent);
    ReactHostComponent_1.injection.injectTextComponentClass(ReactTestTextComponent_1);
    ReactEmptyComponent_1.injection.injectEmptyComponentFactory(function () {
      return new ReactTestEmptyComponent_1();
    });
  
    ReactComponentEnvironment_1.injection.injectEnvironment({
      processChildrenUpdates: function () {},
      replaceNodeWithMarkup: function () {}
    });
  }
  
  /**
   * Drill down (through composites and empty components) until we get a native or
   * native text component.
   *
   * This is pretty polymorphic but unavoidable with the current structure we have
   * for `_renderedChildren`.
   */
  function getRenderedHostOrTextFromComponent(component) {
    var rendered;
    while (rendered = component._renderedComponent) {
      component = rendered;
    }
    return component;
  }
  
  var UNSET = {};
  
  var ReactTestComponent = function () {
    function ReactTestComponent(element) {
      _classCallCheck(this, ReactTestComponent);
  
      this._currentElement = element;
      this._renderedChildren = null;
      this._topLevelWrapper = null;
      this._hostContainerInfo = null;
      this._nodeMock = UNSET;
    }
  
    ReactTestComponent.prototype.mountComponent = function mountComponent(transaction, nativeParent, hostContainerInfo, context) {
      var element = this._currentElement;
      this._hostContainerInfo = hostContainerInfo;
      this._nodeMock = hostContainerInfo.createNodeMock(element);
      // $FlowFixMe https://github.com/facebook/flow/issues/1805
      this.mountChildren(element.props.children, transaction, context);
    };
  
    ReactTestComponent.prototype.receiveComponent = function receiveComponent(nextElement, transaction, context) {
      this._currentElement = nextElement;
      // $FlowFixMe https://github.com/facebook/flow/issues/1805
      this.updateChildren(nextElement.props.children, transaction, context);
    };
  
    ReactTestComponent.prototype.getPublicInstance = function getPublicInstance() {
      invariant(this._nodeMock !== UNSET, 'getPublicInstance should not be called before component is mounted.');
      return this._nodeMock;
    };
  
    ReactTestComponent.prototype.toJSON = function toJSON() {
      // not using `children`, but I don't want to rewrite without destructuring
      // eslint-disable-next-line no-unused-vars
      var _currentElement$props = this._currentElement.props,
          children = _currentElement$props.children,
          props = _objectWithoutProperties(_currentElement$props, ['children']);
  
      var childrenJSON = [];
      for (var key in this._renderedChildren) {
        var inst = this._renderedChildren[key];
        inst = getRenderedHostOrTextFromComponent(inst);
        var json = inst.toJSON();
        if (json !== undefined) {
          childrenJSON.push(json);
        }
      }
      var object = {
        type: this._currentElement.type,
        props: props,
        children: childrenJSON.length ? childrenJSON : null
      };
      Object.defineProperty(object, '$$typeof', {
        value: Symbol['for']('react.test.json')
      });
      return object;
    };
  
    ReactTestComponent.prototype.getHostNode = function getHostNode() {};
  
    ReactTestComponent.prototype.unmountComponent = function unmountComponent(safely, skipLifecycle) {
      // $FlowFixMe https://github.com/facebook/flow/issues/1805
      this.unmountChildren(safely, skipLifecycle);
    };
  
    return ReactTestComponent;
  }();
  
  _assign(ReactTestComponent.prototype, ReactMultiChild_1);
  
  // =============================================================================
  
  var ReactTestRenderer = {
    create: function (element, options) {
      inject();
  
      return ReactTestMount_1.render(element, options);
    },
    /* eslint-disable camelcase */
    unstable_batchedUpdates: ReactUpdates_1.batchedUpdates
  };
  
  var ReactTestRendererStack = ReactTestRenderer;
  
  module.exports = ReactTestRendererStack;
  