code: function TextareaState(input) {
  
    // Aliases
    var stateObj = this;
    var inputArea = input;
    this.init = function () {
      this.setInputAreaSelectionStartEnd();
      this.text = inputArea.getContent();
    };
  
    // Sets the selected text in the input box after we've performed an
    // operation.
    this.setInputAreaSelection = function () {
      inputArea.focus();
      inputArea.setSelection(stateObj.start, stateObj.end);
    };
  
    this.setInputAreaSelectionStartEnd = function () {
      stateObj.start = Math.min(
        inputArea.selectionMgr.selectionStart,
        inputArea.selectionMgr.selectionEnd
      );
      stateObj.end = Math.max(
        inputArea.selectionMgr.selectionStart,
        inputArea.selectionMgr.selectionEnd
      );
    };
  
    // Restore this state into the input area.
    this.restore = function () {
  
      if (stateObj.text !== undefined && stateObj.text != inputArea.getContent()) {
        inputArea.setContent(stateObj.text);
      }
      this.setInputAreaSelection();
    };
  
    // Gets a collection of HTML chunks from the inptut textarea.
    this.getChunks = function () {
  
      var chunk = new Chunks();
      chunk.before = util.fixEolChars(stateObj.text.substring(0, stateObj.start));
      chunk.startTag = "";
      chunk.selection = util.fixEolChars(stateObj.text.substring(stateObj.start, stateObj.end));
      chunk.endTag = "";
      chunk.after = util.fixEolChars(stateObj.text.substring(stateObj.end));
  
      return chunk;
    };
  
    // Sets the TextareaState properties given a chunk of markdown.
    this.setChunks = function (chunk) {
  
      chunk.before = chunk.before + chunk.startTag;
      chunk.after = chunk.endTag + chunk.after;
  
      this.start = chunk.before.length;
      this.end = chunk.before.length + chunk.selection.length;
      this.text = chunk.before + chunk.selection + chunk.after;
    };
    this.init();
  }
docs: The input textarea state/contents. This is used to implement undo/redo by the undo manager.