text: (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('mobx'), require('react'), require('react-dom')) :
  	typeof define === 'function' && define.amd ? define(['exports', 'mobx', 'react', 'react-dom'], factory) :
  	(factory((global.mobxReact = {}),global.mobx,global.React,global.ReactDOM));
  }(this, (function (exports,mobx,react,reactDom) { 'use strict';
  
  // These functions can be stubbed out in specific environments
  var unstable_batchedUpdates$1 = undefined;
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
    return typeof obj;
  } : function (obj) {
    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  };
  
  
  
  
  
  var asyncGenerator = function () {
    function AwaitValue(value) {
      this.value = value;
    }
  
    function AsyncGenerator(gen) {
      var front, back;
  
      function send(key, arg) {
        return new Promise(function (resolve, reject) {
          var request = {
            key: key,
            arg: arg,
            resolve: resolve,
            reject: reject,
            next: null
          };
  
          if (back) {
            back = back.next = request;
          } else {
            front = back = request;
            resume(key, arg);
          }
        });
      }
  
      function resume(key, arg) {
        try {
          var result = gen[key](arg);
          var value = result.value;
  
          if (value instanceof AwaitValue) {
            Promise.resolve(value.value).then(function (arg) {
              resume("next", arg);
            }, function (arg) {
              resume("throw", arg);
            });
          } else {
            settle(result.done ? "return" : "normal", result.value);
          }
        } catch (err) {
          settle("throw", err);
        }
      }
  
      function settle(type, value) {
        switch (type) {
          case "return":
            front.resolve({
              value: value,
              done: true
            });
            break;
  
          case "throw":
            front.reject(value);
            break;
  
          default:
            front.resolve({
              value: value,
              done: false
            });
            break;
        }
  
        front = front.next;
  
        if (front) {
          resume(front.key, front.arg);
        } else {
          back = null;
        }
      }
  
      this._invoke = send;
  
      if (typeof gen.return !== "function") {
        this.return = undefined;
      }
    }
  
    if (typeof Symbol === "function" && Symbol.asyncIterator) {
      AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
        return this;
      };
    }
  
    AsyncGenerator.prototype.next = function (arg) {
      return this._invoke("next", arg);
    };
  
    AsyncGenerator.prototype.throw = function (arg) {
      return this._invoke("throw", arg);
    };
  
    AsyncGenerator.prototype.return = function (arg) {
      return this._invoke("return", arg);
    };
  
    return {
      wrap: function (fn) {
        return function () {
          return new AsyncGenerator(fn.apply(this, arguments));
        };
      },
      await: function (value) {
        return new AwaitValue(value);
      }
    };
  }();
  
  
  
  
  
  var classCallCheck = function (instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  };
  
  var createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }
  
    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();
  
  
  
  
  
  
  
  
  
  var inherits = function (subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
      throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
  
    subClass.prototype = Object.create(superClass && superClass.prototype, {
      constructor: {
        value: subClass,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  };
  
  
  
  
  
  
  
  
  
  
  
  var possibleConstructorReturn = function (self, call) {
    if (!self) {
      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
  
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
  };
  
  var EventEmitter = function () {
      function EventEmitter() {
          classCallCheck(this, EventEmitter);
          this.listeners = [];
      }
  
      createClass(EventEmitter, [{
          key: "on",
          value: function on(cb) {
              var _this = this;
  
              this.listeners.push(cb);
              return function () {
                  var index = _this.listeners.indexOf(cb);
                  if (index !== -1) _this.listeners.splice(index, 1);
              };
          }
      }, {
          key: "emit",
          value: function emit(data) {
              this.listeners.forEach(function (fn) {
                  return fn(data);
              });
          }
      }]);
      return EventEmitter;
  }();
  
  /**
   * Copyright 2015, Yahoo! Inc.
   * Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
   */
  'use strict';
  
  var REACT_STATICS = {
      childContextTypes: true,
      contextTypes: true,
      defaultProps: true,
      displayName: true,
      getDefaultProps: true,
      mixins: true,
      propTypes: true,
      type: true
  };
  
  var KNOWN_STATICS = {
    name: true,
    length: true,
    prototype: true,
    caller: true,
    callee: true,
    arguments: true,
    arity: true
  };
  
  var defineProperty$1 = Object.defineProperty;
  var getOwnPropertyNames = Object.getOwnPropertyNames;
  var getOwnPropertySymbols = Object.getOwnPropertySymbols;
  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  var getPrototypeOf = Object.getPrototypeOf;
  var objectPrototype = getPrototypeOf && getPrototypeOf(Object);
  
  var hoistNonReactStatics = function hoistNonReactStatics(targetComponent, sourceComponent, blacklist) {
      if (typeof sourceComponent !== 'string') { // don't hoist over string (html) components
  
          if (objectPrototype) {
              var inheritedComponent = getPrototypeOf(sourceComponent);
              if (inheritedComponent && inheritedComponent !== objectPrototype) {
                  hoistNonReactStatics(targetComponent, inheritedComponent, blacklist);
              }
          }
  
          var keys = getOwnPropertyNames(sourceComponent);
  
          if (getOwnPropertySymbols) {
              keys = keys.concat(getOwnPropertySymbols(sourceComponent));
          }
  
          for (var i = 0; i < keys.length; ++i) {
              var key = keys[i];
              if (!REACT_STATICS[key] && !KNOWN_STATICS[key] && (!blacklist || !blacklist[key])) {
                  var descriptor = getOwnPropertyDescriptor(sourceComponent, key);
                  try { // Avoid failures from read-only properties
                      defineProperty$1(targetComponent, key, descriptor);
                  } catch (e) {}
              }
          }
  
          return targetComponent;
      }
  
      return targetComponent;
  };
  
  // Copied from React.PropTypes
  function createChainableTypeChecker(validate) {
      function checkType(isRequired, props, propName, componentName, location, propFullName) {
          for (var _len = arguments.length, rest = Array(_len > 6 ? _len - 6 : 0), _key = 6; _key < _len; _key++) {
              rest[_key - 6] = arguments[_key];
          }
  
          return mobx.untracked(function () {
              componentName = componentName || "<<anonymous>>";
              propFullName = propFullName || propName;
              if (props[propName] == null) {
                  if (isRequired) {
                      var actual = props[propName] === null ? "null" : "undefined";
                      return new Error("The " + location + " `" + propFullName + "` is marked as required " + "in `" + componentName + "`, but its value is `" + actual + "`.");
                  }
                  return null;
              } else {
                  return validate.apply(undefined, [props, propName, componentName, location, propFullName].concat(rest));
              }
          });
      }
  
      var chainedCheckType = checkType.bind(null, false);
      chainedCheckType.isRequired = checkType.bind(null, true);
      return chainedCheckType;
  }
  
  // Copied from React.PropTypes
  function isSymbol(propType, propValue) {
      // Native Symbol.
      if (propType === "symbol") {
          return true;
      }
  
      // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol'
      if (propValue["@@toStringTag"] === "Symbol") {
          return true;
      }
  
      // Fallback for non-spec compliant Symbols which are polyfilled.
      if (typeof Symbol === "function" && propValue instanceof Symbol) {
          return true;
      }
  
      return false;
  }
  
  // Copied from React.PropTypes
  function getPropType(propValue) {
      var propType = typeof propValue === "undefined" ? "undefined" : _typeof(propValue);
      if (Array.isArray(propValue)) {
          return "array";
      }
      if (propValue instanceof RegExp) {
          // Old webkits (at least until Android 4.0) return 'function' rather than
          // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
          // passes PropTypes.object.
          return "object";
      }
      if (isSymbol(propType, propValue)) {
          return "symbol";
      }
      return propType;
  }
  
  // This handles more types than `getPropType`. Only used for error messages.
  // Copied from React.PropTypes
  function getPreciseType(propValue) {
      var propType = getPropType(propValue);
      if (propType === "object") {
          if (propValue instanceof Date) {
              return "date";
          } else if (propValue instanceof RegExp) {
              return "regexp";
          }
      }
      return propType;
  }
  
  function createObservableTypeCheckerCreator(allowNativeType, mobxType) {
      return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
          return mobx.untracked(function () {
              if (allowNativeType) {
                  if (getPropType(props[propName]) === mobxType.toLowerCase()) return null;
              }
              var mobxChecker = void 0;
              switch (mobxType) {
                  case "Array":
                      mobxChecker = mobx.isObservableArray;
                      break;
                  case "Object":
                      mobxChecker = mobx.isObservableObject;
                      break;
                  case "Map":
                      mobxChecker = mobx.isObservableMap;
                      break;
                  default:
                      throw new Error("Unexpected mobxType: " + mobxType);
              }
              var propValue = props[propName];
              if (!mobxChecker(propValue)) {
                  var preciseType = getPreciseType(propValue);
                  var nativeTypeExpectationMessage = allowNativeType ? " or javascript `" + mobxType.toLowerCase() + "`" : "";
                  return new Error("Invalid prop `" + propFullName + "` of type `" + preciseType + "` supplied to" + " `" + componentName + "`, expected `mobx.Observable" + mobxType + "`" + nativeTypeExpectationMessage + ".");
              }
              return null;
          });
      });
  }
  
  function createObservableArrayOfTypeChecker(allowNativeType, typeChecker) {
      return createChainableTypeChecker(function (props, propName, componentName, location, propFullName) {
          for (var _len2 = arguments.length, rest = Array(_len2 > 5 ? _len2 - 5 : 0), _key2 = 5; _key2 < _len2; _key2++) {
              rest[_key2 - 5] = arguments[_key2];
          }
  
          return mobx.untracked(function () {
              if (typeof typeChecker !== "function") {
                  return new Error("Property `" + propFullName + "` of component `" + componentName + "` has " + "invalid PropType notation.");
              }
              var error = createObservableTypeCheckerCreator(allowNativeType, "Array")(props, propName, componentName);
              if (error instanceof Error) return error;
              var propValue = props[propName];
              for (var i = 0; i < propValue.length; i++) {
                  error = typeChecker.apply(undefined, [propValue, i, componentName, location, propFullName + "[" + i + "]"].concat(rest));
                  if (error instanceof Error) return error;
              }
              return null;
          });
      });
  }
  
  var observableArray = createObservableTypeCheckerCreator(false, "Array");
  var observableArrayOf = createObservableArrayOfTypeChecker.bind(null, false);
  var observableMap = createObservableTypeCheckerCreator(false, "Map");
  var observableObject = createObservableTypeCheckerCreator(false, "Object");
  var arrayOrObservableArray = createObservableTypeCheckerCreator(true, "Array");
  var arrayOrObservableArrayOf = createObservableArrayOfTypeChecker.bind(null, true);
  var objectOrObservableObject = createObservableTypeCheckerCreator(true, "Object");
  
  
  
  var propTypes = Object.freeze({
  	observableArray: observableArray,
  	observableArrayOf: observableArrayOf,
  	observableMap: observableMap,
  	observableObject: observableObject,
  	arrayOrObservableArray: arrayOrObservableArray,
  	arrayOrObservableArrayOf: arrayOrObservableArrayOf,
  	objectOrObservableObject: objectOrObservableObject
  });
  
  function isStateless(component) {
      // `function() {}` has prototype, but `() => {}` doesn't
      // `() => {}` via Babel has prototype too.
      return !(component.prototype && component.prototype.render);
  }
  
  var injectorContextTypes = {
      mobxStores: objectOrObservableObject
  };
  Object.seal(injectorContextTypes);
  
  var proxiedInjectorProps = {
      contextTypes: {
          get: function get$$1() {
              return injectorContextTypes;
          },
          set: function set$$1(_) {
              console.warn("Mobx Injector: you are trying to attach `contextTypes` on an component decorated with `inject` (or `observer`) HOC. Please specify the contextTypes on the wrapped component instead. It is accessible through the `wrappedComponent`");
          },
          configurable: true,
          enumerable: false
      },
      isMobxInjector: {
          value: true,
          writable: true,
          configurable: true,
          enumerable: true
      }
  
      /**
       * Store Injection
       */
  };function createStoreInjector(grabStoresFn, component, injectNames) {
      var _class, _temp2;
  
      var displayName = "inject-" + (component.displayName || component.name || component.constructor && component.constructor.name || "Unknown");
      if (injectNames) displayName += "-with-" + injectNames;
  
      var Injector = (_temp2 = _class = function (_Component) {
          inherits(Injector, _Component);
  
          function Injector() {
              var _ref;
  
              var _temp, _this, _ret;
  
              classCallCheck(this, Injector);
  
              for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
                  args[_key] = arguments[_key];
              }
  
              return _ret = (_temp = (_this = possibleConstructorReturn(this, (_ref = Injector.__proto__ || Object.getPrototypeOf(Injector)).call.apply(_ref, [this].concat(args))), _this), _this.storeRef = function (instance) {
                  _this.wrappedInstance = instance;
              }, _temp), possibleConstructorReturn(_this, _ret);
          }
  
          createClass(Injector, [{
              key: "render",
              value: function render() {
                  // Optimization: it might be more efficient to apply the mapper function *outside* the render method
                  // (if the mapper is a function), that could avoid expensive(?) re-rendering of the injector component
                  // See this test: 'using a custom injector is not too reactive' in inject.js
                  var newProps = {};
                  for (var key in this.props) {
                      if (this.props.hasOwnProperty(key)) {
                          newProps[key] = this.props[key];
                      }
                  }var additionalProps = grabStoresFn(this.context.mobxStores || {}, newProps, this.context) || {};
                  for (var _key2 in additionalProps) {
                      newProps[_key2] = additionalProps[_key2];
                  }
  
                  if (!isStateless(component)) {
                      newProps.ref = this.storeRef;
                  }
  
                  return react.createElement(component, newProps);
              }
          }]);
          return Injector;
      }(react.Component), _class.displayName = displayName, _temp2);
  
      // Static fields from component should be visible on the generated Injector
  
      hoistNonReactStatics(Injector, component);
  
      Injector.wrappedComponent = component;
      Object.defineProperties(Injector, proxiedInjectorProps);
  
      return Injector;
  }
  
  function grabStoresByName(storeNames) {
      return function (baseStores, nextProps) {
          storeNames.forEach(function (storeName) {
              if (storeName in nextProps // prefer props over stores
              ) return;
              if (!(storeName in baseStores)) throw new Error("MobX injector: Store '" + storeName + "' is not available! Make sure it is provided by some Provider");
              nextProps[storeName] = baseStores[storeName];
          });
          return nextProps;
      };
  }
  
  /**
   * higher order component that injects stores to a child.
   * takes either a varargs list of strings, which are stores read from the context,
   * or a function that manually maps the available stores from the context to props:
   * storesToProps(mobxStores, props, context) => newProps
   */
  function inject() /* fn(stores, nextProps) or ...storeNames */{
      var grabStoresFn = void 0;
      if (typeof arguments[0] === "function") {
          grabStoresFn = arguments[0];
          return function (componentClass) {
              var injected = createStoreInjector(grabStoresFn, componentClass);
              injected.isMobxInjector = false; // supress warning
              // mark the Injector as observer, to make it react to expressions in `grabStoresFn`,
              // see #111
              injected = observer(injected);
              injected.isMobxInjector = true; // restore warning
              return injected;
          };
      } else {
          var storeNames = [];
          for (var i = 0; i < arguments.length; i++) {
              storeNames[i] = arguments[i];
          }grabStoresFn = grabStoresByName(storeNames);
          return function (componentClass) {
              return createStoreInjector(grabStoresFn, componentClass, storeNames.join("-"));
          };
      }
  }
  
  /**
   * dev tool support
   */
  var isDevtoolsEnabled = false;
  
  var isUsingStaticRendering = false;
  
  var warnedAboutObserverInjectDeprecation = false;
  
  // WeakMap<Node, Object>;
  var componentByNodeRegistery = typeof WeakMap !== "undefined" ? new WeakMap() : undefined;
  var renderReporter = new EventEmitter();
  
  function findDOMNode$2(component) {
      if (reactDom.findDOMNode) {
          try {
              return reactDom.findDOMNode(component);
          } catch (e) {
              // findDOMNode will throw in react-test-renderer, see:
              // See https://github.com/mobxjs/mobx-react/issues/216
              // Is there a better heuristic?
              return null;
          }
      }
      return null;
  }
  
  function reportRendering(component) {
      var node = findDOMNode$2(component);
      if (node && componentByNodeRegistery) componentByNodeRegistery.set(node, component);
  
      renderReporter.emit({
          event: "render",
          renderTime: component.__$mobRenderEnd - component.__$mobRenderStart,
          totalTime: Date.now() - component.__$mobRenderStart,
          component: component,
          node: node
      });
  }
  
  function trackComponents() {
      if (typeof WeakMap === "undefined") throw new Error("[mobx-react] tracking components is not supported in this browser.");
      if (!isDevtoolsEnabled) isDevtoolsEnabled = true;
  }
  
  function useStaticRendering(useStaticRendering) {
      isUsingStaticRendering = useStaticRendering;
  }
  
  /**
   * Errors reporter
   */
  
  var errorsReporter = new EventEmitter();
  
  /**
   * Utilities
   */
  
  function patch(target, funcName) {
      var runMixinFirst = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  
      var base = target[funcName];
      var mixinFunc = reactiveMixin[funcName];
      var f = !base ? mixinFunc : runMixinFirst === true ? function () {
          mixinFunc.apply(this, arguments);
          base.apply(this, arguments);
      } : function () {
          base.apply(this, arguments);
          mixinFunc.apply(this, arguments);
      };
  
      // MWE: ideally we freeze here to protect against accidental overwrites in component instances, see #195
      // ...but that breaks react-hot-loader, see #231...
      target[funcName] = f;
  }
  
  function isObjectShallowModified(prev, next) {
      if (null == prev || null == next || (typeof prev === "undefined" ? "undefined" : _typeof(prev)) !== "object" || (typeof next === "undefined" ? "undefined" : _typeof(next)) !== "object") {
          return prev !== next;
      }
      var keys = Object.keys(prev);
      if (keys.length !== Object.keys(next).length) {
          return true;
      }
      var key = void 0;
      for (var i = keys.length - 1; i >= 0, key = keys[i]; i--) {
          if (next[key] !== prev[key]) {
              return true;
          }
      }
      return false;
  }
  
  /**
   * ReactiveMixin
   */
  var reactiveMixin = {
      componentWillMount: function componentWillMount() {
          var _this = this;
  
          if (isUsingStaticRendering === true) return;
          // Generate friendly name for debugging
          var initialName = this.displayName || this.name || this.constructor && (this.constructor.displayName || this.constructor.name) || "<component>";
          var rootNodeID = this._reactInternalInstance && this._reactInternalInstance._rootNodeID;
  
          /**
           * If props are shallowly modified, react will render anyway,
           * so atom.reportChanged() should not result in yet another re-render
           */
          var skipRender = false;
          /**
           * forceUpdate will re-assign this.props. We don't want that to cause a loop,
           * so detect these changes
           */
          var isForcingUpdate = false;
  
          function makePropertyObservableReference(propName) {
              var valueHolder = this[propName];
              var atom = new mobx.Atom("reactive " + propName);
              Object.defineProperty(this, propName, {
                  configurable: true,
                  enumerable: true,
                  get: function get$$1() {
                      atom.reportObserved();
                      return valueHolder;
                  },
                  set: function set$$1(v) {
                      if (!isForcingUpdate && isObjectShallowModified(valueHolder, v)) {
                          valueHolder = v;
                          skipRender = true;
                          atom.reportChanged();
                          skipRender = false;
                      } else {
                          valueHolder = v;
                      }
                  }
              });
          }
  
          // make this.props an observable reference, see #124
          makePropertyObservableReference.call(this, "props");
          // make state an observable reference
          makePropertyObservableReference.call(this, "state");
  
          // wire up reactive render
          var baseRender = this.render.bind(this);
          var reaction = null;
          var isRenderingPending = false;
  
          var initialRender = function initialRender() {
              reaction = new mobx.Reaction(initialName + "#" + rootNodeID + ".render()", function () {
                  if (!isRenderingPending) {
                      // N.B. Getting here *before mounting* means that a component constructor has side effects (see the relevant test in misc.js)
                      // This unidiomatic React usage but React will correctly warn about this so we continue as usual
                      // See #85 / Pull #44
                      isRenderingPending = true;
                      if (typeof _this.componentWillReact === "function") _this.componentWillReact(); // TODO: wrap in action?
                      if (_this.__$mobxIsUnmounted !== true) {
                          // If we are unmounted at this point, componentWillReact() had a side effect causing the component to unmounted
                          // TODO: remove this check? Then react will properly warn about the fact that this should not happen? See #73
                          // However, people also claim this migth happen during unit tests..
                          var hasError = true;
                          try {
                              isForcingUpdate = true;
                              if (!skipRender) react.Component.prototype.forceUpdate.call(_this);
                              hasError = false;
                          } finally {
                              isForcingUpdate = false;
                              if (hasError) reaction.dispose();
                          }
                      }
                  }
              });
              reaction.reactComponent = _this;
              reactiveRender.$mobx = reaction;
              _this.render = reactiveRender;
              return reactiveRender();
          };
  
          var reactiveRender = function reactiveRender() {
              isRenderingPending = false;
              var exception = undefined;
              var rendering = undefined;
              reaction.track(function () {
                  if (isDevtoolsEnabled) {
                      _this.__$mobRenderStart = Date.now();
                  }
                  try {
                      rendering = mobx.extras.allowStateChanges(false, baseRender);
                  } catch (e) {
                      exception = e;
                  }
                  if (isDevtoolsEnabled) {
                      _this.__$mobRenderEnd = Date.now();
                  }
              });
              if (exception) {
                  errorsReporter.emit(exception);
                  throw exception;
              }
              return rendering;
          };
  
          this.render = initialRender;
      },
  
      componentWillUnmount: function componentWillUnmount() {
          if (isUsingStaticRendering === true) return;
          this.render.$mobx && this.render.$mobx.dispose();
          this.__$mobxIsUnmounted = true;
          if (isDevtoolsEnabled) {
              var node = findDOMNode$2(this);
              if (node && componentByNodeRegistery) {
                  componentByNodeRegistery.delete(node);
              }
              renderReporter.emit({
                  event: "destroy",
                  component: this,
                  node: node
              });
          }
      },
  
      componentDidMount: function componentDidMount() {
          if (isDevtoolsEnabled) {
              reportRendering(this);
          }
      },
  
      componentDidUpdate: function componentDidUpdate() {
          if (isDevtoolsEnabled) {
              reportRendering(this);
          }
      },
  
      shouldComponentUpdate: function shouldComponentUpdate(nextProps, nextState) {
          if (isUsingStaticRendering) {
              console.warn("[mobx-react] It seems that a re-rendering of a React component is triggered while in static (server-side) mode. Please make sure components are rendered only once server-side.");
          }
          // update on any state changes (as is the default)
          if (this.state !== nextState) {
              return true;
          }
          // update if props are shallowly not equal, inspired by PureRenderMixin
          // we could return just 'false' here, and avoid the `skipRender` checks etc
          // however, it is nicer if lifecycle events are triggered like usually,
          // so we return true here if props are shallowly modified.
          return isObjectShallowModified(this.props, nextProps);
      }
  
      /**
       * Observer function / decorator
       */
  };function observer(arg1, arg2) {
      if (typeof arg1 === "string") {
          throw new Error("Store names should be provided as array");
      }
      if (Array.isArray(arg1)) {
          // component needs stores
          if (!warnedAboutObserverInjectDeprecation) {
              warnedAboutObserverInjectDeprecation = true;
              console.warn('Mobx observer: Using observer to inject stores is deprecated since 4.0. Use `@inject("store1", "store2") @observer ComponentClass` or `inject("store1", "store2")(observer(componentClass))` instead of `@observer(["store1", "store2"]) ComponentClass`');
          }
          if (!arg2) {
              // invoked as decorator
              return function (componentClass) {
                  return observer(arg1, componentClass);
              };
          } else {
              return inject.apply(null, arg1)(observer(arg2));
          }
      }
      var componentClass = arg1;
  
      if (componentClass.isMobxInjector === true) {
          console.warn("Mobx observer: You are trying to use 'observer' on a component that already has 'inject'. Please apply 'observer' before applying 'inject'");
      }
  
      // Stateless function component:
      // If it is function but doesn't seem to be a react class constructor,
      // wrap it to a react class automatically
      if (typeof componentClass === "function" && (!componentClass.prototype || !componentClass.prototype.render) && !componentClass.isReactClass && !react.Component.isPrototypeOf(componentClass)) {
          var _class, _temp;
  
          return observer((_temp = _class = function (_Component) {
              inherits(_class, _Component);
  
              function _class() {
                  classCallCheck(this, _class);
                  return possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
              }
  
              createClass(_class, [{
                  key: "render",
                  value: function render() {
                      return componentClass.call(this, this.props, this.context);
                  }
              }]);
              return _class;
          }(react.Component), _class.displayName = componentClass.displayName || componentClass.name, _class.contextTypes = componentClass.contextTypes, _class.propTypes = componentClass.propTypes, _class.defaultProps = componentClass.defaultProps, _temp));
      }
  
      if (!componentClass) {
          throw new Error("Please pass a valid component to 'observer'");
      }
  
      var target = componentClass.prototype || componentClass;
      mixinLifecycleEvents(target);
      componentClass.isMobXReactObserver = true;
      return componentClass;
  }
  
  function mixinLifecycleEvents(target) {
      patch(target, "componentWillMount", true);["componentDidMount", "componentWillUnmount", "componentDidUpdate"].forEach(function (funcName) {
          patch(target, funcName);
      });
      if (!target.shouldComponentUpdate) {
          target.shouldComponentUpdate = reactiveMixin.shouldComponentUpdate;
      }
  }
  
  // TODO: support injection somehow as well?
  var Observer = observer(function (_ref) {
      var children = _ref.children;
      return children();
  });
  
  Observer.displayName = "Observer";
  
  Observer.propTypes = {
      children: function children(propValue, key, componentName, location, propFullName) {
          if (typeof propValue[key] !== "function") return new Error("Invalid prop `" + propFullName + "` of type `" + _typeof(propValue[key]) + "` supplied to" + " `" + componentName + "`, expected `function`.");
      }
  };
  
  var _class;
  var _temp;
  
  var specialReactKeys = { children: true, key: true, ref: true };
  
  var Provider = (_temp = _class = function (_Component) {
      inherits(Provider, _Component);
  
      function Provider() {
          classCallCheck(this, Provider);
          return possibleConstructorReturn(this, (Provider.__proto__ || Object.getPrototypeOf(Provider)).apply(this, arguments));
      }
  
      createClass(Provider, [{
          key: "render",
          value: function render() {
              return react.Children.only(this.props.children);
          }
      }, {
          key: "getChildContext",
          value: function getChildContext() {
              var stores = {};
              // inherit stores
              var baseStores = this.context.mobxStores;
              if (baseStores) for (var key in baseStores) {
                  stores[key] = baseStores[key];
              }
              // add own stores
              for (var _key in this.props) {
                  if (!specialReactKeys[_key] && _key !== "suppressChangedStoreWarning") stores[_key] = this.props[_key];
              }return {
                  mobxStores: stores
              };
          }
      }, {
          key: "componentWillReceiveProps",
          value: function componentWillReceiveProps(nextProps) {
              // Maybe this warning is too aggressive?
              if (Object.keys(nextProps).length !== Object.keys(this.props).length) console.warn("MobX Provider: The set of provided stores has changed. Please avoid changing stores as the change might not propagate to all children");
              if (!nextProps.suppressChangedStoreWarning) for (var key in nextProps) {
                  if (!specialReactKeys[key] && this.props[key] !== nextProps[key]) console.warn("MobX Provider: Provided store '" + key + "' has changed. Please avoid replacing stores as the change might not propagate to all children");
              }
          }
      }]);
      return Provider;
  }(react.Component), _class.contextTypes = {
      mobxStores: objectOrObservableObject
  }, _class.childContextTypes = {
      mobxStores: objectOrObservableObject.isRequired
  }, _temp);
  
  if (!react.Component) throw new Error("mobx-react requires React to be available");
  if (!mobx.extras) throw new Error("mobx-react requires mobx to be available");
  
  if (typeof reactDom.unstable_batchedUpdates === "function") mobx.extras.setReactionScheduler(reactDom.unstable_batchedUpdates);else if (typeof unstable_batchedUpdates$1 === "function") mobx.extras.setReactionScheduler(unstable_batchedUpdates$1);
  
  var onError = function onError(fn) {
      return errorsReporter.on(fn);
  };
  
  /* DevTool support */
  // See: https://github.com/andykog/mobx-devtools/blob/d8976c24b8cb727ed59f9a0bc905a009df79e221/src/backend/installGlobalHook.js
  
  if ((typeof __MOBX_DEVTOOLS_GLOBAL_HOOK__ === "undefined" ? "undefined" : _typeof(__MOBX_DEVTOOLS_GLOBAL_HOOK__)) === "object") {
      var mobx$1 = { spy: mobx.spy, extras: mobx.extras };
      var mobxReact = { renderReporter: renderReporter, componentByNodeRegistery: componentByNodeRegistery, trackComponents: trackComponents };
      __MOBX_DEVTOOLS_GLOBAL_HOOK__.injectMobxReact(mobxReact, mobx$1);
  }
  
  exports.propTypes = propTypes;
  exports.PropTypes = propTypes;
  exports.onError = onError;
  exports.observer = observer;
  exports.Observer = Observer;
  exports.renderReporter = renderReporter;
  exports.componentByNodeRegistery = componentByNodeRegistery;
  exports.trackComponents = trackComponents;
  exports.useStaticRendering = useStaticRendering;
  exports.Provider = Provider;
  exports.inject = inject;
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  