text: // CodeMirror, copyright (c) by Marijn Haverbeke and others
  // Distributed under an MIT license: http://codemirror.net/LICENSE
  /**
   * @modifier NHN FE Development Lab <dl_javascript@nhn.com>
   */
  import CodeMirror from 'codemirror';
  
  /*eslint-disable */
  CodeMirror.commands.replaceLineTextToUpper = cm => {
    if (cm.getOption('disableInput')) {
      return CodeMirror.Pass;
    }
  
    const ranges = cm.listSelections();
    const lineAdjustment = -1;
  
    for (let i = 0; i < ranges.length; i++) {
      const range = ranges[i];
      const from = range.anchor;
      const to = range.head;
  
      if (isSameLineSelection(range) && to.line > 0) {
        replaceSingleLine(cm, from, to, lineAdjustment);
      } else if (!isRangeCollapsed(range)) {
        const topLine = from.line < to.line ? from.line : to.line;
  
        if (topLine > 0) {
          const upper = from.line === topLine ? from : to;
          const bottom = from.line === topLine ? to : from;
          replaceMultiLine(cm, upper, bottom, lineAdjustment);
        }
      }
    }
  };
  
  CodeMirror.commands.replaceLineTextToLower = cm => {
    if (cm.getOption('disableInput')) {
      return CodeMirror.Pass;
    }
  
    const ranges = cm.listSelections();
    const lineAdjustment = 1;
  
    for (let i = 0; i < ranges.length; i++) {
      const range = ranges[i];
      const from = range.anchor;
      const to = range.head;
      const isLastLine = to.line === cm.lastLine();
  
      if (isSameLineSelection(range) && !isLastLine) {
        replaceSingleLine(cm, from, to, lineAdjustment);
      } else if (!isRangeCollapsed(range)) {
        const topLine = from.line < to.line ? from.line : to.line;
        const upper = from.line === topLine ? from : to;
        const bottom = from.line === topLine ? to : from;
  
        if (bottom.line < cm.lastLine()) {
          replaceMultiLine(cm, upper, bottom, lineAdjustment);
        }
      }
    }
  };
  
  function isRangeCollapsed(range) {
    return isSameLineSelection(range) && range.anchor.ch === range.head.ch;
  }
  
  function isSameLineSelection(range) {
    return range.anchor.line === range.head.line;
  }
  
  function replaceSingleLine(cm, from, to, lineAdjustment) {
    const currentLine = cm.getLine(to.line);
    const replacement = cm.getLine(to.line + lineAdjustment);
    const range = {
      anchor: from,
      head: to
    };
  
    cm.replaceRange(
      replacement,
      {
        line: to.line,
        ch: 0
      },
      {
        line: to.line,
        ch: currentLine.length
      },
      '+input'
    );
  
    cm.replaceRange(
      currentLine,
      {
        line: to.line + lineAdjustment,
        ch: 0
      },
      {
        line: to.line + lineAdjustment,
        ch: replacement.length
      },
      '+input'
    );
  
    if (isRangeCollapsed(range)) {
      cm.setCursor({
        line: to.line + lineAdjustment,
        ch: to.ch
      });
    } else {
      cm.setSelection(
        {
          line: from.line + lineAdjustment,
          ch: from.ch
        },
        {
          line: to.line + lineAdjustment,
          ch: to.ch
        }
      );
    }
  }
  
  function replaceMultiLine(cm, upper, bottom, lineAdjustment) {
    const rangeContent = cm.getRange(
      {
        line: upper.line,
        ch: 0
      },
      {
        line: bottom.line,
        ch: cm.getLine(bottom.line).length
      }
    );
    const edgeLineOfConcern = lineAdjustment > 0 ? bottom : upper;
    const replacement = cm.getLine(edgeLineOfConcern.line + lineAdjustment);
    let targetLine;
  
    if (lineAdjustment > 0) {
      targetLine = upper;
    } else {
      targetLine = bottom;
    }
  
    cm.replaceRange(
      replacement,
      {
        line: targetLine.line,
        ch: 0
      },
      {
        line: targetLine.line,
        ch: cm.getLine(targetLine.line).length
      },
      '+input'
    );
  
    cm.replaceRange(
      rangeContent,
      {
        line: upper.line + lineAdjustment,
        ch: 0
      },
      {
        line: bottom.line + lineAdjustment,
        ch: cm.getLine(bottom.line + lineAdjustment).length
      },
      '+input'
    );
  
    cm.setSelection(
      {
        line: upper.line + lineAdjustment,
        ch: upper.ch
      },
      {
        line: bottom.line + lineAdjustment,
        ch: bottom.ch
      }
    );
  }
  