'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _reactAddons = require('react/addons');

var _reactAddons2 = _interopRequireDefault(_reactAddons);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _reactSpinkit = require('react-spinkit');

var _reactSpinkit2 = _interopRequireDefault(_reactSpinkit);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _fluxEditorActions = require('../flux/EditorActions');

var _fluxEditorActions2 = _interopRequireDefault(_fluxEditorActions);

var _fluxEditorStore = require('../flux/EditorStore');

var _fluxEditorStore2 = _interopRequireDefault(_fluxEditorStore);

var _DebugEditor = require('./DebugEditor');

var _DebugEditor2 = _interopRequireDefault(_DebugEditor);

var _coreRichText = require('../core/RichText');

var _coreDom = require('../core/dom');

var _SwarmClientMixin = require('./SwarmClientMixin');

var _SwarmClientMixin2 = _interopRequireDefault(_SwarmClientMixin);

var _TextReplicaMixin = require('./TextReplicaMixin');

var _TextReplicaMixin2 = _interopRequireDefault(_TextReplicaMixin);

var _SharedCursorMixin = require('./SharedCursorMixin');

var _SharedCursorMixin2 = _interopRequireDefault(_SharedCursorMixin);

var _TextInput = require('./TextInput');

var _TextInput2 = _interopRequireDefault(_TextInput);

var _coreAttributes = require('../core/attributes');

var _coreEditorCommon = require('../core/EditorCommon');

var _coreReplica = require('../core/replica');

var _coreTextFontMetrics = require('../core/TextFontMetrics');

var _coreTextFontMetrics2 = _interopRequireDefault(_coreTextFontMetrics);

require('../styles/internal.less');

var T = _reactAddons2['default'].PropTypes;
var nbsp = String.fromCharCode(160);

exports['default'] = _reactAddons2['default'].createClass({
  displayName: 'Editor',

  propTypes: {
    id: T.string.isRequired,
    fonts: T.shape({
      regular: T.object,
      bold: T.object,
      boldItalic: T.object,
      italic: T.object
    }),
    fontSize: T.number.isRequired,
    minFontSize: T.number.isRequired,
    unitsPerEm: T.number.isRequired,
    width: T.number.isRequired,
    marginH: T.number.isRequired,
    marginV: T.number.isRequired,
    userId: T.string.isRequired,
    userName: T.string,
    cursorColorSpace: T.arrayOf(T.string), // TODO allow it to be a function as well
    initialFocus: T.bool
  },

  mixins: [_SwarmClientMixin2['default'], _TextReplicaMixin2['default'], _SharedCursorMixin2['default']],

  getDefaultProps: function getDefaultProps() {
    return {
      initialFocus: true,
      // The default cursor color space is a less harsh variation of the 11 Boynton colors:
      // http://alumni.media.mit.edu/~wad/color/palette.html
      // See also:
      // http://stackoverflow.com/a/4382138/430128
      // https://eleanormaclure.files.wordpress.com/2011/03/colour-coding.pdf
      cursorColorSpace: ['rgb(29, 105, 20)', // green
      'rgb(129, 38, 192)', // purple,
      'rgb(42, 75, 215)', // blue
      'rgb(41, 208, 208)', // cyan
      'rgb(173, 35, 35)', // red
      'rgb(255, 146, 51)', // orange
      'rgb(129, 197, 122)', // light green
      'rgb(157, 175, 255)', // light blue
      'rgb(255, 205, 243)', // pink
      'rgb(255, 238, 51)', // yellow
      'rgb(129, 74, 25)' // brown
      ]
    };
  },

  getInitialState: function getInitialState() {
    return _fluxEditorStore2['default'].getState();
  },

  componentWillMount: function componentWillMount() {
    _coreTextFontMetrics2['default'].setConfig(this.props);

    this._createReplica();
    _fluxEditorActions2['default'].initialize(this.props, this.replica);
  },

  componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
    _coreTextFontMetrics2['default'].setConfig(this.props);
    _fluxEditorActions2['default'].initialize(nextProps, this.replica);
  },

  componentDidMount: function componentDidMount() {
    this.clickCount = 0;
    _fluxEditorStore2['default'].listen(this.onStateChange);
  },

  componentDidUpdate: function componentDidUpdate() {
    if (!this.caret) {
      this.caret = _reactAddons2['default'].findDOMNode(this.refs.caret);
    }
    if (this.caret) {
      var scrollByToCursor = (0, _coreDom.scrollByToVisible)(this.caret, 5);
      if (scrollByToCursor.xDelta !== 0 || scrollByToCursor.yDelta !== 0) {
        window.scrollBy(scrollByToCursor.xDelta, scrollByToCursor.yDelta);
      }
    }
  },

  componentWillUnmount: function componentWillUnmount() {
    _fluxEditorStore2['default'].unlisten(this.onStateChange);
  },

  onStateChange: function onStateChange(state) {
    this.setState(state);
  },

  _createReplica: function _createReplica() {
    this.createTextReplica();
    this.registerCb(this._replicaInitCb, this._replicaUpdateCb);
  },

  _replicaInitCb: function _replicaInitCb(spec, op, replica) {
    // eslint-disable-line no-unused-vars
    // set our own replica for future use
    this.replicaSource = (0, _coreReplica.sourceOf)(spec);
    _fluxEditorActions2['default'].replicaInitialized();
    this.createSharedCursor();
  },

  _replicaUpdateCb: function _replicaUpdateCb(spec, op, replica) {
    // eslint-disable-line no-unused-vars
    if (this.replicaSource === (0, _coreReplica.sourceOf)(spec)) return;
    _fluxEditorActions2['default'].replicaUpdated();
  },

  _mouseEventToCoordinates: function _mouseEventToCoordinates(e) {
    // target is the particular element within the editor clicked on, current target is the entire editor div
    var targetPosition = (0, _coreDom.elementPosition)(e.currentTarget);

    return {
      x: e.pageX - targetPosition.x,
      y: e.pageY - targetPosition.y
    };
  },

  _doOnSingleClick: function _doOnSingleClick(e) {
    var coordinates = this._mouseEventToCoordinates(e);
    if (!coordinates) {
      return;
    }

    if (e.shiftKey) {
      _fluxEditorActions2['default'].selectToCoordinates(coordinates);
    } else {
      _fluxEditorActions2['default'].navigateToCoordinates(coordinates);
    }
  },

  _doOnDoubleClick: function _doOnDoubleClick() {
    _fluxEditorActions2['default'].selectWordAtCurrentPosition();
  },

  _onMouseDown: function _onMouseDown(e) {
    var _this = this;

    if (!this.state.focus) {
      _fluxEditorActions2['default'].focusInput();
    }

    if (this.clickReset) {
      clearTimeout(this.clickReset);
      this.clickReset = null;
    }
    var clickCount = this.clickCount;
    this.clickCount += 1;
    this.clickReset = setTimeout(function () {
      _this.clickCount = 0;
    }, 250);

    if (clickCount === 0) {
      this._doOnSingleClick(e);
    } else if (clickCount === 1) {
      // note that _doOnSingleClick has already executed here
      this._doOnDoubleClick(e);
    } //else if(this.clickCount === 2) // TODO handle triple-click

    e.preventDefault();
    e.stopPropagation();
  },

  _onMouseMove: function _onMouseMove(e) {
    if (e.buttons !== 1) return;

    if (!this.state.focus) {
      _fluxEditorActions2['default'].focusInput();
    }

    var coordinates = this._mouseEventToCoordinates(e);
    if (!coordinates) return;

    _fluxEditorActions2['default'].selectToCoordinates(coordinates);

    e.preventDefault();
    e.stopPropagation();
  },

  _remoteCursorHover: function _remoteCursorHover(id, e) {
    _fluxEditorActions2['default'].revealRemoteCursorName(this.state.remoteCursors[id]);

    e.preventDefault();
    e.stopPropagation();
  },

  // RENDERING ---------------------------------------------------------------------------------------------------------

  _searchLinesWithSelection: function _searchLinesWithSelection(selection) {
    if (!selection) {
      selection = {
        selectionActive: this.state.selectionActive,
        selectionLeftChar: this.state.selectionLeftChar,
        selectionRightChar: this.state.selectionRightChar
      };
    }

    if (!this.state.lines || this.state.lines.length === 0 || !selection.selectionActive) {
      return null;
    }

    var left = (0, _coreEditorCommon.lineContainingChar)(this.state.lines, this.replica.getCharRelativeTo(selection.selectionLeftChar, 1, 'eof'));
    var right = (0, _coreEditorCommon.lineContainingChar)(this.state.lines.slice(left.index), selection.selectionRightChar, null);

    return {
      left: left.index,
      right: right.index + left.index
    };
  },

  _renderSelectionOverlay: function _renderSelectionOverlay(lineIndex, lineHeight, selection, remote) {
    var _this2 = this;

    if (!selection.selectionActive) {
      return null;
    }

    var linesWithSelection = this._searchLinesWithSelection(selection);

    // lines outside the selection range
    if (linesWithSelection && (lineIndex < linesWithSelection.left || lineIndex > linesWithSelection.right)) {
      return null;
    }

    var selectionDiv = function selectionDiv(leftX, widthX) {
      var height = Math.round(lineHeight * 10) / 10;
      var selectionStyle = {
        top: 0,
        left: leftX,
        width: widthX,
        height: height
      };

      // named selection border and bg colors same as cursor, opacity somewhere around 0.15 (then keeps reducing about every second by 0.001), no color attribute
      var setColor = undefined;
      if (remote) {
        setColor = remote.color;
      } else if (!_this2.state.focus) {
        setColor = 'rgb(0, 0, 0)';
      }

      if (setColor) {
        selectionStyle.borderTopColor = setColor;
        selectionStyle.borderBottomColor = setColor;
        selectionStyle.backgroundColor = setColor;
        selectionStyle.opacity = 0.15;
        selectionStyle.color = setColor;
      }

      var key = undefined;
      if (remote) {
        var id = remote.model._id;
        key = 'selection-' + lineIndex + '-' + id;
      } else {
        key = 'selection-' + lineIndex;
      }

      return _reactAddons2['default'].createElement('div', { className: 'ritzy-internal-text-selection-overlay text-selection-overlay ritzy-internal-text-htmloverlay ritzy-internal-text-htmloverlay-under-text ritzy-internal-ui-unprintable',
        style: selectionStyle, key: key });
    };

    var line = this.state.lines[lineIndex];

    // middle lines
    if (linesWithSelection && (lineIndex > linesWithSelection.left && lineIndex < linesWithSelection.right)) {
      var _selectionWidthX = line.advance;
      if (line.isEof() || line.end.char === '\n') {
        _selectionWidthX += _coreTextFontMetrics2['default'].advanceXForSpace(this.props.fontSize);
      }
      return selectionDiv(0, _selectionWidthX);
    }

    // last line with EOF
    if (line && line.isEof() && selection.selectionRightChar === _coreRichText.EOF) {
      return selectionDiv(0, _coreTextFontMetrics2['default'].advanceXForSpace(this.props.fontSize));
    }

    // empty editor (no line and selection is from BASE_CHAR to EOF)
    if (!line && (0, _coreEditorCommon.charEq)(selection.selectionLeftChar, _coreRichText.BASE_CHAR) && (0, _coreEditorCommon.charEq)(selection.selectionRightChar, _coreRichText.EOF)) {
      return selectionDiv(0, _coreTextFontMetrics2['default'].advanceXForSpace(this.props.fontSize));
    }

    var selectionLeftX = 0;
    var selectionWidthX = undefined;
    var selectionAddSpace = undefined;

    if (lineIndex === linesWithSelection.left) {
      // TODO change selection height and font size dynamically
      selectionLeftX = _coreTextFontMetrics2['default'].advanceXForChars(this.props.fontSize, line.charsTo(selection.selectionLeftChar));
    }

    if (lineIndex === linesWithSelection.right) {
      var selectionChars = selectionLeftX > 0 ? line.charsBetween(selection.selectionLeftChar, selection.selectionRightChar) : line.charsTo(selection.selectionRightChar);

      if (selectionChars.length === 0) {
        return null;
      }
      selectionWidthX = _coreTextFontMetrics2['default'].advanceXForChars(this.props.fontSize, selectionChars);
      selectionAddSpace = selectionChars[selectionChars.length - 1].char === '\n';
    } else {
      selectionWidthX = line.advance - selectionLeftX;
      selectionAddSpace = line.isEof() || line.end.char === '\n';
    }

    if (selectionAddSpace) {
      selectionWidthX += _coreTextFontMetrics2['default'].advanceXForSpace(this.props.fontSize);
    }

    return selectionDiv(selectionLeftX, selectionWidthX);
  },

  _renderRemoteSelectionOverlays: function _renderRemoteSelectionOverlays(lineIndex, lineHeight) {
    var _this3 = this;

    return Object.keys(this.state.remoteCursors).filter(function (id) {
      return _this3.state.remoteCursors[id].model.selectionActive;
    }).map(function (id) {
      var remoteCursor = _this3.state.remoteCursors[id];
      var remoteSelection = {
        selectionActive: remoteCursor.model.selectionActive,
        selectionLeftChar: remoteCursor.model.selectionLeftChar,
        selectionRightChar: remoteCursor.model.selectionRightChar
      };
      return _this3._renderSelectionOverlay(lineIndex, lineHeight, remoteSelection, remoteCursor);
    });
  },

  _renderStyledText: function _renderStyledText(id, text, attributes) {
    var hasAttribute = (0, _coreAttributes.hasAttributeFor)(attributes);

    // vertical alignment
    var superscript = hasAttribute(_coreAttributes.ATTR.SUPERSCRIPT);
    var subscript = hasAttribute(_coreAttributes.ATTR.SUBSCRIPT);
    var verticalAlign = (0, _classnames2['default'])({
      'super': superscript,
      sub: subscript,
      baseline: !(superscript || subscript)
    });

    // font size, weight, style
    var fontSize = _coreTextFontMetrics2['default'].fontSizeFromAttributes(this.props.fontSize, attributes);
    var fontWeight = hasAttribute(_coreAttributes.ATTR.BOLD) ? 'bold' : 'normal';
    var fontStyle = hasAttribute(_coreAttributes.ATTR.ITALIC) ? 'italic' : 'normal';

    // text-decoration
    var underline = hasAttribute(_coreAttributes.ATTR.UNDERLINE);
    var strikethrough = hasAttribute(_coreAttributes.ATTR.STRIKETHROUGH);
    var textDecoration = (0, _classnames2['default'])({
      none: !(underline || strikethrough),
      underline: underline,
      'line-through': strikethrough
    });

    var style = {
      color: '#000000',
      backgroundColor: 'transparent',
      fontFamily: 'Open Sans', // TODO test other fonts, make the font selectable
      fontSize: fontSize,
      fontWeight: fontWeight,
      fontStyle: fontStyle,
      fontVariant: 'normal',
      textDecoration: textDecoration,
      verticalAlign: verticalAlign
    };

    return _reactAddons2['default'].createElement(
      'span',
      { style: style, key: id },
      text
    );
  },

  _splitIntoLines: function _splitIntoLines() {
    var _this4 = this;

    if (!this.state.lines) return [];

    return this.state.lines.map(function (line) {
      return line.chunks.map(function (chunk) {
        var chars = line.chars.slice(chunk.start, chunk.end);
        return _this4._renderStyledText(chars[0].id, chars.map(function (c) {
          return c.char === ' ' ? nbsp : c.char;
        }).join(''), chunk.attributes);
      });
    });
  },

  _renderLine: function _renderLine(line, index, lineHeight) {
    var blockHeight = 10000;
    var blockTop = _coreTextFontMetrics2['default'].top(this.props.fontSize) - blockHeight;
    var selection = {
      selectionActive: this.state.selectionActive,
      selectionLeftChar: this.state.selectionLeftChar,
      selectionRightChar: this.state.selectionRightChar
    };

    // TODO set lineHeight based on font sizes used in line chunks
    // the span wrapper around the text is required so that the text does not shift up/down when using superscript/subscript
    return _reactAddons2['default'].createElement(
      'div',
      { className: 'ritzy-internal-text-lineview text-lineview', style: { height: lineHeight, direction: 'ltr', textAlign: 'left' }, key: index },
      this._renderSelectionOverlay(index, lineHeight, selection),
      this._renderRemoteSelectionOverlays(index, lineHeight),
      _reactAddons2['default'].createElement(
        'div',
        { className: 'ritzy-internal-text-lineview-content text-lineview-content', style: { marginLeft: 0, paddingTop: 0 } },
        _reactAddons2['default'].createElement('span', { style: { display: 'inline-block', height: blockHeight } }),
        _reactAddons2['default'].createElement(
          'span',
          { style: { display: 'inline-block', position: 'relative', top: blockTop } },
          _reactAddons2['default'].createElement(
            'span',
            { key: 'text', className: 'ritzy-internal-editor-inline-block ritzy-internal-text-lineview-text-block' },
            line
          )
        )
      )
    );
  },

  _cursorPosition: function _cursorPosition(lineHeight, position, positionEolStart) {
    // the initial render before the component is mounted has no position or lines
    if (!position || !this.state.lines) {
      return null;
    }

    if ((0, _coreEditorCommon.charEq)(_coreRichText.BASE_CHAR, position) || this.state.lines.length === 0) {
      return {
        position: position,
        positionEolStart: positionEolStart,
        left: this.props.marginH,
        top: this.props.marginV
      };
    }

    var result = (0, _coreEditorCommon.lineContainingChar)(this.state.lines, position, positionEolStart);
    if (!result) {
      return null;
    }
    var line = result.line;
    var index = result.index;
    var endOfLine = result.endOfLine;

    var previousLineHeights = line ? lineHeight * index : 0;

    var cursorAdvanceX = undefined;

    if (!line || endOfLine && positionEolStart && index < this.state.lines.length - 1) {
      cursorAdvanceX = 0;
    } else {
      var positionChars = line.charsTo(position);
      cursorAdvanceX = _coreTextFontMetrics2['default'].advanceXForChars(this.props.fontSize, positionChars);
    }

    return {
      position: position,
      positionEolStart: positionEolStart,
      left: this.props.marginH + cursorAdvanceX,
      top: this.props.marginV + previousLineHeights
    };
  },

  _renderInput: function _renderInput(cursorPosition) {
    var position = cursorPosition ? cursorPosition.top : 0;

    return _reactAddons2['default'].createElement(_TextInput2['default'], { id: this.props.id, ref: 'input', position: position, focused: this.state.focus });
  },

  _renderCursor: function _renderCursor(cursorPosition, lineHeight, remote) {
    // the initial render before the component is mounted has no position
    if (!cursorPosition) {
      return null;
    }

    var cursorClasses = (0, _classnames2['default'])('ritzy-internal-text-cursor text-cursor', 'ritzy-internal-ui-unprintable', {
      'ritzy-internal-text-cursor-blink': !this.state.cursorMotion && !remote
    });

    var italicAtPosition = cursorPosition.position.attributes && cursorPosition.position.attributes[_coreAttributes.ATTR.ITALIC] && !remote;
    var italicActive = this.state.activeAttributes && this.state.activeAttributes[_coreAttributes.ATTR.ITALIC] && !remote;
    var italicInactive = this.state.activeAttributes && !this.state.activeAttributes[_coreAttributes.ATTR.ITALIC] && !remote;

    var caretClasses = (0, _classnames2['default'])('ritzy-internal-text-cursor-caret text-cursor-caret', {
      'ritzy-internal-text-cursor-italic': italicActive || italicAtPosition && !italicInactive
    });

    var cursorStyle = {
      left: cursorPosition.left,
      top: cursorPosition.top
    };

    if (!remote && (this.state.selectionActive || !this.state.focus)) {
      cursorStyle.opacity = 0;
      cursorStyle.visibility = 'hidden';
    } else {
      cursorStyle.opacity = 1;
    }

    var cursorHeight = Math.round(lineHeight * 10) / 10;

    if (remote) {
      var id = remote.model._id;
      var key = 'cursor-' + id;
      var remoteCursorHover = _lodash2['default'].partial(this._remoteCursorHover, id);
      var revealName = this.state.remoteNameReveal.indexOf(id) > -1;
      var cursorTopStyle = {
        backgroundColor: remote.color,
        opacity: 1
      };
      var cursorNameStyle = {
        backgroundColor: remote.color
      };
      if (revealName) {
        cursorTopStyle.display = 'none';
        cursorNameStyle.opacity = 1;
      } else {
        cursorNameStyle.opacity = 0;
        cursorNameStyle.display = 'none';
      }

      return _reactAddons2['default'].createElement(
        'div',
        { className: cursorClasses, style: cursorStyle, key: key },
        _reactAddons2['default'].createElement('div', { className: caretClasses, style: { borderColor: remote.color, height: cursorHeight }, onMouseOver: remoteCursorHover }),
        _reactAddons2['default'].createElement('div', { className: 'ritzy-internal-text-cursor-top text-cursor-top', style: cursorTopStyle, onMouseOver: remoteCursorHover }),
        _reactAddons2['default'].createElement(
          'div',
          { className: 'ritzy-internal-text-cursor-name text-cursor-name', style: cursorNameStyle },
          remote.model.name
        )
      );
    } else {
      return _reactAddons2['default'].createElement(
        'div',
        { className: cursorClasses, style: cursorStyle, key: 'cursor', ref: 'cursor' },
        _reactAddons2['default'].createElement('div', { className: caretClasses, style: { borderColor: 'black', height: cursorHeight }, key: 'caret', ref: 'caret' }),
        _reactAddons2['default'].createElement('div', { className: 'ritzy-internal-text-cursor-top text-cursor-top', style: { opacity: 1 } }),
        _reactAddons2['default'].createElement('div', { className: 'ritzy-internal-text-cursor-name text-cursor-name', style: { opacity: 1 } })
      );
    }
  },

  _renderRemoteCursors: function _renderRemoteCursors(lineHeight) {
    var _this5 = this;

    return Object.keys(this.state.remoteCursors).filter(function (id) {
      return _this5.state.remoteCursors[id].model.position;
    }).map(function (id) {
      var remoteCursor = _this5.state.remoteCursors[id];
      var remotePosition = undefined;
      try {
        remotePosition = _this5.replica.getChar(remoteCursor.model.position);
      } catch (e) {
        console.warn('Error obtaining remote position, ignoring.', e);
        return null;
      }
      // do not display remote cursor in same position as local one
      if (!_this5.state.focus || !(remoteCursor.model.positionEolStart === _this5.state.positionEolStart && (0, _coreEditorCommon.charEq)(remotePosition, _this5.state.position))) {
        var cursorPosition = _this5._cursorPosition(lineHeight, remotePosition, remoteCursor.model.positionEolStart);
        return _this5._renderCursor(cursorPosition, lineHeight, remoteCursor);
      }
      return null;
    });
  },

  _renderEditorContents: function _renderEditorContents() {
    var _this6 = this;

    if (this.state.loaded) {
      var _ret = (function () {
        var lines = _this6._splitIntoLines();
        var lineHeight = _coreTextFontMetrics2['default'].lineHeight(_this6.props.fontSize);
        var cursorPosition = _this6._cursorPosition(lineHeight, _this6.state.position, _this6.state.positionEolStart);

        return {
          v: _reactAddons2['default'].createElement(
            'div',
            null,
            _this6._renderInput(cursorPosition),
            _reactAddons2['default'].createElement(
              'div',
              { className: 'ritzy-internal-text-contents text-contents', style: { position: 'relative' } },
              lines.length > 0 ? lines.map(function (line, index) {
                return _this6._renderLine(line, index, lineHeight);
              }) : _this6._renderLine(nbsp, 0, lineHeight)
            ),
            _this6._renderCursor(cursorPosition, lineHeight),
            _this6._renderRemoteCursors(lineHeight)
          )
        };
      })();

      if (typeof _ret === 'object') return _ret.v;
    } else {
      return _reactAddons2['default'].createElement(_reactSpinkit2['default'], { spinnerName: 'three-bounce', noFadeIn: true });
    }
  },

  render: function render() {
    //console.trace('render')
    var wrapperStyle = {
      width: this.props.width,
      padding: this.props.marginV + 'px ' + this.props.marginH + 'px'
    };

    return _reactAddons2['default'].createElement(
      'div',
      null,
      _reactAddons2['default'].createElement(
        'div',
        { className: 'ritzy-internal-text-content-wrapper text-content-wrapper',
          style: wrapperStyle, onMouseDown: this._onMouseDown, onMouseMove: this._onMouseMove },
        this._renderEditorContents()
      ),
      _reactAddons2['default'].createElement(_DebugEditor2['default'], { editorState: this.state, replica: this.replica, searchLinesWithSelection: this._searchLinesWithSelection })
    );
  }

});
module.exports = exports['default'];
/*<DebugEditor editorState={this.state} replica={this.replica} searchLinesWithSelection={this._searchLinesWithSelection}/>*/