text: 'use strict';
  
  function _extends() {
    _extends = Object.assign || function(target) {
      for (var i = 1; i < arguments.length; i++) {
        var source = arguments[i];
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
      return target;
    };
    return _extends.apply(this, arguments);
  }
  
  function _typeof(obj) {
    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
      _typeof = function _typeof(obj) {
        return typeof obj;
      };
    } else {
      _typeof = function _typeof(obj) {
        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
      };
    }
    return _typeof(obj);
  }
  
  var __extends = void 0 && (void 0).__extends || function() {
    var _extendStatics = function extendStatics(d, b) {
      _extendStatics = Object.setPrototypeOf || {
        __proto__: []
      }
      instanceof Array && function(d, b) {
        d.__proto__ = b;
      } || function(d, b) {
        for (var p in b) {
          if (b.hasOwnProperty(p)) d[p] = b[p];
        }
      };
  
      return _extendStatics(d, b);
    };
  
    return function(d, b) {
      _extendStatics(d, b);
  
      function __() {
        this.constructor = d;
      }
  
      d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
  }();
  
  Object.defineProperty(exports, '__esModule', {
    value: true
  });
  
  var React = require('react');
  
  var SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
  var cm;
  
  if (!SERVER_RENDERED) {
    cm = require('codemirror');
  }
  
  var Helper = function() {
    function Helper() {}
  
    Helper.equals = function(x, y) {
      var _this = this;
  
      var ok = Object.keys,
        tx = _typeof(x),
        ty = _typeof(y);
  
      return x && y && tx === 'object' && tx === ty ? ok(x).length === ok(y).length && ok(x).every(function(key) {
        return _this.equals(x[key], y[key]);
      }) : x === y;
    };
  
    return Helper;
  }();
  
  var Shared = function() {
    function Shared(editor, props) {
      this.editor = editor;
      this.props = props;
    }
  
    Shared.prototype.delegateCursor = function(position, scroll, focus) {
      var doc = this.editor.getDoc();
  
      if (focus) {
        this.editor.focus();
      }
  
      scroll ? doc.setCursor(position) : doc.setCursor(position, null, {
        scroll: false
      });
    };
  
    Shared.prototype.delegateScroll = function(coordinates) {
      this.editor.scrollTo(coordinates.x, coordinates.y);
    };
  
    Shared.prototype.delegateSelection = function(ranges, focus) {
      var doc = this.editor.getDoc();
      doc.setSelections(ranges);
  
      if (focus) {
        this.editor.focus();
      }
    };
  
    Shared.prototype.apply = function(props) {
      if (props && props.selection && props.selection.ranges) {
        this.delegateSelection(props.selection.ranges, props.selection.focus || false);
      }
  
      if (props && props.cursor) {
        this.delegateCursor(props.cursor, props.autoScroll || false, this.editor.getOption('autofocus') || false);
      }
  
      if (props && props.scroll) {
        this.delegateScroll(props.scroll);
      }
    };
  
    Shared.prototype.applyNext = function(props, next, preserved) {
      if (props && props.selection && props.selection.ranges) {
        if (next && next.selection && next.selection.ranges && !Helper.equals(props.selection.ranges, next.selection.ranges)) {
          this.delegateSelection(next.selection.ranges, next.selection.focus || false);
        }
      }
  
      if (props && props.cursor) {
        if (next && next.cursor && !Helper.equals(props.cursor, next.cursor)) {
          this.delegateCursor(preserved.cursor || next.cursor, next.autoScroll || false, next.autoCursor || false);
        }
      }
  
      if (props && props.scroll) {
        if (next && next.scroll && !Helper.equals(props.scroll, next.scroll)) {
          this.delegateScroll(next.scroll);
        }
      }
    };
  
    Shared.prototype.applyUserDefined = function(props, preserved) {
      if (preserved && preserved.cursor) {
        this.delegateCursor(preserved.cursor, props.autoScroll || false, this.editor.getOption('autofocus') || false);
      }
    };
  
    Shared.prototype.wire = function(props) {
      var _this = this;
  
      Object.keys(props || {}).filter(function(p) {
        return /^on/.test(p);
      }).forEach(function(prop) {
        switch (prop) {
          case 'onBlur':
            {
              _this.editor.on('blur', function(cm, event) {
                _this.props.onBlur(_this.editor, event);
              });
            }
            break;
  
          case 'onContextMenu':
            {
              _this.editor.on('contextmenu', function(cm, event) {
                _this.props.onContextMenu(_this.editor, event);
              });
  
              break;
            }
  
          case 'onCopy':
            {
              _this.editor.on('copy', function(cm, event) {
                _this.props.onCopy(_this.editor, event);
              });
  
              break;
            }
  
          case 'onCursor':
            {
              _this.editor.on('cursorActivity', function(cm) {
                _this.props.onCursor(_this.editor, _this.editor.getDoc().getCursor());
              });
            }
            break;
  
          case 'onCursorActivity':
            {
              _this.editor.on('cursorActivity', function(cm) {
                _this.props.onCursorActivity(_this.editor);
              });
            }
            break;
  
          case 'onCut':
            {
              _this.editor.on('cut', function(cm, event) {
                _this.props.onCut(_this.editor, event);
              });
  
              break;
            }
  
          case 'onDblClick':
            {
              _this.editor.on('dblclick', function(cm, event) {
                _this.props.onDblClick(_this.editor, event);
              });
  
              break;
            }
  
          case 'onDragEnter':
            {
              _this.editor.on('dragenter', function(cm, event) {
                _this.props.onDragEnter(_this.editor, event);
              });
            }
            break;
  
          case 'onDragLeave':
            {
              _this.editor.on('dragleave', function(cm, event) {
                _this.props.onDragLeave(_this.editor, event);
              });
  
              break;
            }
  
          case 'onDragOver':
            {
              _this.editor.on('dragover', function(cm, event) {
                _this.props.onDragOver(_this.editor, event);
              });
            }
            break;
  
          case 'onDragStart':
            {
              _this.editor.on('dragstart', function(cm, event) {
                _this.props.onDragStart(_this.editor, event);
              });
  
              break;
            }
  
          case 'onDrop':
            {
              _this.editor.on('drop', function(cm, event) {
                _this.props.onDrop(_this.editor, event);
              });
            }
            break;
  
          case 'onFocus':
            {
              _this.editor.on('focus', function(cm, event) {
                _this.props.onFocus(_this.editor, event);
              });
            }
            break;
  
          case 'onGutterClick':
            {
              _this.editor.on('gutterClick', function(cm, lineNumber, gutter, event) {
                _this.props.onGutterClick(_this.editor, lineNumber, gutter, event);
              });
            }
            break;
  
          case 'onKeyDown':
            {
              _this.editor.on('keydown', function(cm, event) {
                _this.props.onKeyDown(_this.editor, event);
              });
            }
            break;
  
          case 'onKeyPress':
            {
              _this.editor.on('keypress', function(cm, event) {
                _this.props.onKeyPress(_this.editor, event);
              });
            }
            break;
  
          case 'onKeyUp':
            {
              _this.editor.on('keyup', function(cm, event) {
                _this.props.onKeyUp(_this.editor, event);
              });
            }
            break;
  
          case 'onMouseDown':
            {
              _this.editor.on('mousedown', function(cm, event) {
                _this.props.onMouseDown(_this.editor, event);
              });
  
              break;
            }
  
          case 'onPaste':
            {
              _this.editor.on('paste', function(cm, event) {
                _this.props.onPaste(_this.editor, event);
              });
  
              break;
            }
  
          case 'onRenderLine':
            {
              _this.editor.on('renderLine', function(cm, line, element) {
                _this.props.onRenderLine(_this.editor, line, element);
              });
  
              break;
            }
  
          case 'onScroll':
            {
              _this.editor.on('scroll', function(cm) {
                _this.props.onScroll(_this.editor, _this.editor.getScrollInfo());
              });
            }
            break;
  
          case 'onSelection':
            {
              _this.editor.on('beforeSelectionChange', function(cm, data) {
                _this.props.onSelection(_this.editor, data);
              });
            }
            break;
  
          case 'onTouchStart':
            {
              _this.editor.on('touchstart', function(cm, event) {
                _this.props.onTouchStart(_this.editor, event);
              });
  
              break;
            }
  
          case 'onUpdate':
            {
              _this.editor.on('update', function(cm) {
                _this.props.onUpdate(_this.editor);
              });
            }
            break;
  
          case 'onViewportChange':
            {
              _this.editor.on('viewportChange', function(cm, from, to) {
                _this.props.onViewportChange(_this.editor, from, to);
              });
            }
            break;
        }
      });
    };
  
    return Shared;
  }();
  
  var Controlled = function(_super) {
    __extends(Controlled, _super);
  
    function Controlled(props) {
      var _this = _super.call(this, props) || this;
  
      if (SERVER_RENDERED) return _this;
      _this.applied = false;
      _this.appliedNext = false;
      _this.appliedUserDefined = false;
      _this.deferred = null;
      _this.emulating = false;
      _this.hydrated = false;
  
      _this.initCb = function() {
        if (_this.props.editorDidConfigure) {
          _this.props.editorDidConfigure(_this.editor);
        }
      };
  
      _this.mounted = false;
      return _this;
    }
  
    Controlled.prototype.hydrate = function(props) {
      var _this = this;
  
      var _options = props && props.options ? props.options : {};
  
      var userDefinedOptions = _extends({}, cm.defaults, this.editor.options, _options);
  
      var optionDelta = Object.keys(userDefinedOptions).some(function(key) {
        return _this.editor.getOption(key) !== userDefinedOptions[key];
      });
  
      if (optionDelta) {
        Object.keys(userDefinedOptions).forEach(function(key) {
          if (_options.hasOwnProperty(key)) {
            if (_this.editor.getOption(key) !== userDefinedOptions[key]) {
              _this.editor.setOption(key, userDefinedOptions[key]);
  
              _this.mirror.setOption(key, userDefinedOptions[key]);
            }
          }
        });
      }
  
      if (!this.hydrated) {
        this.deferred ? this.resolveChange() : this.initChange(props.value || '');
      }
  
      this.hydrated = true;
    };
  
    Controlled.prototype.initChange = function(value) {
      this.emulating = true;
      var doc = this.editor.getDoc();
      var lastLine = doc.lastLine();
      var lastChar = doc.getLine(doc.lastLine()).length;
      doc.replaceRange(value || '', {
        line: 0,
        ch: 0
      }, {
        line: lastLine,
        ch: lastChar
      });
      this.mirror.setValue(value);
      doc.clearHistory();
      this.mirror.clearHistory();
      this.emulating = false;
    };
  
    Controlled.prototype.resolveChange = function() {
      this.emulating = true;
      var doc = this.editor.getDoc();
  
      if (this.deferred.origin === 'undo') {
        doc.undo();
      } else if (this.deferred.origin === 'redo') {
        doc.redo();
      } else {
        doc.replaceRange(this.deferred.text, this.deferred.from, this.deferred.to, this.deferred.origin);
      }
  
      this.emulating = false;
      this.deferred = null;
    };
  
    Controlled.prototype.mirrorChange = function(deferred) {
      var doc = this.editor.getDoc();
  
      if (deferred.origin === 'undo') {
        doc.setHistory(this.mirror.getHistory());
        this.mirror.undo();
      } else if (deferred.origin === 'redo') {
        doc.setHistory(this.mirror.getHistory());
        this.mirror.redo();
      } else {
        this.mirror.replaceRange(deferred.text, deferred.from, deferred.to, deferred.origin);
      }
  
      return this.mirror.getValue();
    };
  
    Controlled.prototype.componentDidMount = function() {
      var _this = this;
  
      if (SERVER_RENDERED) return;
  
      if (this.props.defineMode) {
        if (this.props.defineMode.name && this.props.defineMode.fn) {
          cm.defineMode(this.props.defineMode.name, this.props.defineMode.fn);
        }
      }
  
      var initOptions = _extends({}, cm.defaults, this.props.initOptions);
  
      this.editor = cm(this.ref, initOptions);
      this.shared = new Shared(this.editor, this.props);
      this.mirror = cm(function() {});
      this.editor.on('electricInput', function() {
        _this.mirror.setHistory(_this.editor.getDoc().getHistory());
      });
      this.editor.on('cursorActivity', function() {
        _this.mirror.setCursor(_this.editor.getDoc().getCursor());
      });
      this.editor.on('beforeChange', function(cm, data) {
        if (_this.emulating) {
          return;
        }
  
        data.cancel();
        _this.deferred = data;
  
        var phantomChange = _this.mirrorChange(_this.deferred);
  
        if (_this.props.onBeforeChange) _this.props.onBeforeChange(_this.editor, _this.deferred, phantomChange);
      });
      this.editor.on('change', function(cm, data) {
        if (!_this.mounted) {
          return;
        }
  
        if (_this.props.onChange) {
          _this.props.onChange(_this.editor, data, _this.editor.getValue());
        }
      });
      this.hydrate(this.props);
      this.shared.apply(this.props);
      this.applied = true;
      this.mounted = true;
      this.shared.wire(this.props);
  
      if (this.editor.getOption('autofocus')) {
        this.editor.focus();
      }
  
      if (this.props.editorDidMount) {
        this.props.editorDidMount(this.editor, this.editor.getValue(), this.initCb);
      }
    };
  
    Controlled.prototype.componentWillReceiveProps = function(nextProps) {
      if (SERVER_RENDERED) return;
      var preserved = {
        cursor: null
      };
  
      if (nextProps.value !== this.props.value) {
        this.hydrated = false;
      }
  
      if (!this.props.autoCursor && this.props.autoCursor !== undefined) {
        preserved.cursor = this.editor.getDoc().getCursor();
      }
  
      this.hydrate(nextProps);
  
      if (!this.appliedNext) {
        this.shared.applyNext(this.props, nextProps, preserved);
        this.appliedNext = true;
      }
  
      this.shared.applyUserDefined(this.props, preserved);
      this.appliedUserDefined = true;
    };
  
    Controlled.prototype.componentWillUnmount = function() {
      if (SERVER_RENDERED) return;
  
      if (this.props.editorWillUnmount) {
        this.props.editorWillUnmount(cm);
      }
    };
  
    Controlled.prototype.shouldComponentUpdate = function(nextProps, nextState) {
      return !SERVER_RENDERED;
    };
  
    Controlled.prototype.render = function() {
      var _this = this;
  
      if (SERVER_RENDERED) return null;
      var className = this.props.className ? 'react-codemirror2 ' + this.props.className : 'react-codemirror2';
      return React.createElement('div', {
        className: className,
        ref: function ref(self) {
          return _this.ref = self;
        }
      });
    };
  
    return Controlled;
  }(React.Component);
  
  exports.Controlled = Controlled;
  
  var UnControlled = function(_super) {
    __extends(UnControlled, _super);
  
    function UnControlled(props) {
      var _this = _super.call(this, props) || this;
  
      if (SERVER_RENDERED) return _this;
      _this.applied = false;
      _this.appliedUserDefined = false;
      _this.continueChange = false;
      _this.detached = false;
      _this.hydrated = false;
  
      _this.initCb = function() {
        if (_this.props.editorDidConfigure) {
          _this.props.editorDidConfigure(_this.editor);
        }
      };
  
      _this.mounted = false;
  
      _this.onBeforeChangeCb = function() {
        _this.continueChange = true;
      };
  
      return _this;
    }
  
    UnControlled.prototype.hydrate = function(props) {
      var _this = this;
  
      var _options = props && props.options ? props.options : {};
  
      var userDefinedOptions = _extends({}, cm.defaults, this.editor.options, _options);
  
      var optionDelta = Object.keys(userDefinedOptions).some(function(key) {
        return _this.editor.getOption(key) !== userDefinedOptions[key];
      });
  
      if (optionDelta) {
        Object.keys(userDefinedOptions).forEach(function(key) {
          if (_options.hasOwnProperty(key)) {
            if (_this.editor.getOption(key) !== userDefinedOptions[key]) {
              _this.editor.setOption(key, userDefinedOptions[key]);
            }
          }
        });
      }
  
      if (!this.hydrated) {
        var doc = this.editor.getDoc();
        var lastLine = doc.lastLine();
        var lastChar = doc.getLine(doc.lastLine()).length;
        doc.replaceRange(props.value || '', {
          line: 0,
          ch: 0
        }, {
          line: lastLine,
          ch: lastChar
        });
      }
  
      this.hydrated = true;
    };
  
    UnControlled.prototype.componentDidMount = function() {
      var _this = this;
  
      if (SERVER_RENDERED) return;
      this.detached = this.props.detach === true;
  
      if (this.props.defineMode) {
        if (this.props.defineMode.name && this.props.defineMode.fn) {
          cm.defineMode(this.props.defineMode.name, this.props.defineMode.fn);
        }
      }
  
      var initOptions = _extends({}, cm.defaults, this.props.initOptions);
  
      this.editor = cm(this.ref, initOptions);
      this.shared = new Shared(this.editor, this.props);
      this.editor.on('beforeChange', function(cm, data) {
        if (_this.props.onBeforeChange) {
          _this.props.onBeforeChange(_this.editor, data, _this.editor.getValue(), _this.onBeforeChangeCb);
        }
      });
      this.editor.on('change', function(cm, data) {
        if (!_this.mounted || !_this.props.onChange) {
          return;
        }
  
        if (_this.props.onBeforeChange) {
          if (_this.continueChange) {
            _this.props.onChange(_this.editor, data, _this.editor.getValue());
          }
        } else {
          _this.props.onChange(_this.editor, data, _this.editor.getValue());
        }
      });
      this.hydrate(this.props);
      this.shared.apply(this.props);
      this.applied = true;
      this.mounted = true;
      this.shared.wire(this.props);
      this.editor.getDoc().clearHistory();
  
      if (this.props.editorDidMount) {
        this.props.editorDidMount(this.editor, this.editor.getValue(), this.initCb);
      }
    };
  
    UnControlled.prototype.componentWillReceiveProps = function(nextProps) {
      if (this.detached && nextProps.detach === false) {
        this.detached = false;
  
        if (this.props.editorDidAttach) {
          this.props.editorDidAttach(this.editor);
        }
      }
  
      if (!this.detached && nextProps.detach === true) {
        this.detached = true;
  
        if (this.props.editorDidDetach) {
          this.props.editorDidDetach(this.editor);
        }
      }
  
      if (SERVER_RENDERED || this.detached) return;
      var preserved = {
        cursor: null
      };
  
      if (nextProps.value !== this.props.value) {
        this.hydrated = false;
        this.applied = false;
        this.appliedUserDefined = false;
      }
  
      if (!this.props.autoCursor && this.props.autoCursor !== undefined) {
        preserved.cursor = this.editor.getDoc().getCursor();
      }
  
      this.hydrate(nextProps);
  
      if (!this.applied) {
        this.shared.apply(this.props);
        this.applied = true;
      }
  
      if (!this.appliedUserDefined) {
        this.shared.applyUserDefined(this.props, preserved);
        this.appliedUserDefined = true;
      }
    };
  
    UnControlled.prototype.componentWillUnmount = function() {
      if (SERVER_RENDERED) return;
  
      if (this.props.editorWillUnmount) {
        this.props.editorWillUnmount(cm);
      }
    };
  
    UnControlled.prototype.shouldComponentUpdate = function(nextProps, nextState) {
      var update = true;
      if (SERVER_RENDERED) update = false;
      if (this.detached) update = false;
      return update;
    };
  
    UnControlled.prototype.render = function() {
      var _this = this;
  
      if (SERVER_RENDERED) return null;
      var className = this.props.className ? 'react-codemirror2 ' + this.props.className : 'react-codemirror2';
      return React.createElement('div', {
        className: className,
        ref: function ref(self) {
          return _this.ref = self;
        }
      });
    };
  
    return UnControlled;
  }(React.Component);
  
  exports.UnControlled = UnControlled;