[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/vendor/codemirror/lib/ -> addons.js (source)

   1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
   2  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
   3  
   4  (function(mod) {
   5    if (typeof exports == "object" && typeof module == "object") // CommonJS
   6      mod(require("../../lib/codemirror"));
   7    else if (typeof define == "function" && define.amd) // AMD
   8      define(["../../lib/codemirror"], mod);
   9    else // Plain browser env
  10      mod(CodeMirror);
  11  })(function(CodeMirror) {
  12    "use strict";
  13  
  14    CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
  15      if (old == CodeMirror.Init) old = false;
  16      if (!old == !val) return;
  17      if (val) setFullscreen(cm);
  18      else setNormal(cm);
  19    });
  20  
  21    function setFullscreen(cm) {
  22      var wrap = cm.getWrapperElement();
  23      cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
  24                                    width: wrap.style.width, height: wrap.style.height};
  25      wrap.style.width = "";
  26      wrap.style.height = "auto";
  27      wrap.className += " CodeMirror-fullscreen";
  28      document.documentElement.style.overflow = "hidden";
  29      cm.refresh();
  30    }
  31  
  32    function setNormal(cm) {
  33      var wrap = cm.getWrapperElement();
  34      wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
  35      document.documentElement.style.overflow = "";
  36      var info = cm.state.fullScreenRestore;
  37      wrap.style.width = info.width; wrap.style.height = info.height;
  38      window.scrollTo(info.scrollLeft, info.scrollTop);
  39      cm.refresh();
  40    }
  41  });
  42   // CodeMirror, copyright (c) by Marijn Haverbeke and others
  43  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
  44  
  45  (function (mod) {
  46    if (typeof exports == "object" && typeof module == "object") // CommonJS
  47      mod(require("../../lib/codemirror"));
  48    else if (typeof define == "function" && define.amd) // AMD
  49      define(["../../lib/codemirror"], mod);
  50    else // Plain browser env
  51      mod(CodeMirror);
  52  })(function (CodeMirror) {
  53    CodeMirror.defineExtension("addPanel", function (node, options) {
  54      options = options || {};
  55  
  56      if (!this.state.panels) initPanels(this);
  57  
  58      var info = this.state.panels;
  59      var wrapper = info.wrapper;
  60      var cmWrapper = this.getWrapperElement();
  61      var replace = options.replace instanceof Panel && !options.replace.cleared;
  62  
  63      if (options.after instanceof Panel && !options.after.cleared) {
  64        wrapper.insertBefore(node, options.before.node.nextSibling);
  65      } else if (options.before instanceof Panel && !options.before.cleared) {
  66        wrapper.insertBefore(node, options.before.node);
  67      } else if (replace) {
  68        wrapper.insertBefore(node, options.replace.node);
  69        options.replace.clear(true);
  70      } else if (options.position == "bottom") {
  71        wrapper.appendChild(node);
  72      } else if (options.position == "before-bottom") {
  73        wrapper.insertBefore(node, cmWrapper.nextSibling);
  74      } else if (options.position == "after-top") {
  75        wrapper.insertBefore(node, cmWrapper);
  76      } else {
  77        wrapper.insertBefore(node, wrapper.firstChild);
  78      }
  79  
  80      var height = (options && options.height) || node.offsetHeight;
  81  
  82      var panel = new Panel(this, node, options, height);
  83      info.panels.push(panel);
  84  
  85      this.setSize();
  86      if (options.stable && isAtTop(this, node))
  87        this.scrollTo(null, this.getScrollInfo().top + height);
  88  
  89      return panel;
  90    });
  91  
  92    function Panel(cm, node, options, height) {
  93      this.cm = cm;
  94      this.node = node;
  95      this.options = options;
  96      this.height = height;
  97      this.cleared = false;
  98    }
  99  
 100    /* when skipRemove is true, clear() was called from addPanel().
 101     * Thus removePanels() should not be called (issue 5518) */
 102    Panel.prototype.clear = function (skipRemove) {
 103      if (this.cleared) return;
 104      this.cleared = true;
 105      var info = this.cm.state.panels;
 106      info.panels.splice(info.panels.indexOf(this), 1);
 107      this.cm.setSize();
 108      if (this.options.stable && isAtTop(this.cm, this.node))
 109        this.cm.scrollTo(null, this.cm.getScrollInfo().top - this.height)
 110      info.wrapper.removeChild(this.node);
 111      if (info.panels.length == 0 && !skipRemove) removePanels(this.cm);
 112    };
 113  
 114    Panel.prototype.changed = function () {
 115      this.height = this.node.getBoundingClientRect().height;
 116      this.cm.setSize();
 117    };
 118  
 119    function initPanels(cm) {
 120      var wrap = cm.getWrapperElement()
 121      var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
 122      var height = parseInt(style.height);
 123      var info = cm.state.panels = {
 124        setHeight: wrap.style.height,
 125        panels: [],
 126        wrapper: document.createElement("div")
 127      };
 128      var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo()
 129      wrap.parentNode.insertBefore(info.wrapper, wrap);
 130      info.wrapper.appendChild(wrap);
 131      cm.scrollTo(scrollPos.left, scrollPos.top)
 132      if (hasFocus) cm.focus();
 133  
 134      cm._setSize = cm.setSize;
 135      if (height != null) cm.setSize = function (width, newHeight) {
 136        if (!newHeight) newHeight = info.wrapper.offsetHeight;
 137        info.setHeight = newHeight;
 138        if (typeof newHeight != "number") {
 139          var px = /^(\d+\.?\d*)px$/.exec(newHeight);
 140          if (px) {
 141            newHeight = Number(px[1]);
 142          } else {
 143            info.wrapper.style.height = newHeight;
 144            newHeight = info.wrapper.offsetHeight;
 145          }
 146        }
 147        var editorheight = newHeight - info.panels
 148          .map(function (p) { return p.node.getBoundingClientRect().height; })
 149          .reduce(function (a, b) { return a + b; }, 0);
 150        cm._setSize(width, editorheight);
 151        height = newHeight;
 152      };
 153    }
 154  
 155    function removePanels(cm) {
 156      var info = cm.state.panels;
 157      cm.state.panels = null;
 158  
 159      var wrap = cm.getWrapperElement()
 160      var hasFocus = cm.hasFocus(), scrollPos = cm.getScrollInfo()
 161      info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
 162      cm.scrollTo(scrollPos.left, scrollPos.top)
 163      if (hasFocus) cm.focus();
 164      wrap.style.height = info.setHeight;
 165      cm.setSize = cm._setSize;
 166      cm.setSize();
 167    }
 168  
 169    function isAtTop(cm, dom) {
 170      for (var sibling = dom.nextSibling; sibling; sibling = sibling.nextSibling)
 171        if (sibling == cm.getWrapperElement()) return true
 172      return false
 173    }
 174  });
 175   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 176  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 177  
 178  (function(mod) {
 179    if (typeof exports == "object" && typeof module == "object") // CommonJS
 180      mod(require("../../lib/codemirror"));
 181    else if (typeof define == "function" && define.amd) // AMD
 182      define(["../../lib/codemirror"], mod);
 183    else // Plain browser env
 184      mod(CodeMirror);
 185  })(function(CodeMirror) {
 186    var defaults = {
 187      pairs: "()[]{}''\"\"",
 188      closeBefore: ")]}'\":;>",
 189      triples: "",
 190      explode: "[]{}"
 191    };
 192  
 193    var Pos = CodeMirror.Pos;
 194  
 195    CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
 196      if (old && old != CodeMirror.Init) {
 197        cm.removeKeyMap(keyMap);
 198        cm.state.closeBrackets = null;
 199      }
 200      if (val) {
 201        ensureBound(getOption(val, "pairs"))
 202        cm.state.closeBrackets = val;
 203        cm.addKeyMap(keyMap);
 204      }
 205    });
 206  
 207    function getOption(conf, name) {
 208      if (name == "pairs" && typeof conf == "string") return conf;
 209      if (typeof conf == "object" && conf[name] != null) return conf[name];
 210      return defaults[name];
 211    }
 212  
 213    var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
 214    function ensureBound(chars) {
 215      for (var i = 0; i < chars.length; i++) {
 216        var ch = chars.charAt(i), key = "'" + ch + "'"
 217        if (!keyMap[key]) keyMap[key] = handler(ch)
 218      }
 219    }
 220    ensureBound(defaults.pairs + "`")
 221  
 222    function handler(ch) {
 223      return function(cm) { return handleChar(cm, ch); };
 224    }
 225  
 226    function getConfig(cm) {
 227      var deflt = cm.state.closeBrackets;
 228      if (!deflt || deflt.override) return deflt;
 229      var mode = cm.getModeAt(cm.getCursor());
 230      return mode.closeBrackets || deflt;
 231    }
 232  
 233    function handleBackspace(cm) {
 234      var conf = getConfig(cm);
 235      if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
 236  
 237      var pairs = getOption(conf, "pairs");
 238      var ranges = cm.listSelections();
 239      for (var i = 0; i < ranges.length; i++) {
 240        if (!ranges[i].empty()) return CodeMirror.Pass;
 241        var around = charsAround(cm, ranges[i].head);
 242        if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
 243      }
 244      for (var i = ranges.length - 1; i >= 0; i--) {
 245        var cur = ranges[i].head;
 246        cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
 247      }
 248    }
 249  
 250    function handleEnter(cm) {
 251      var conf = getConfig(cm);
 252      var explode = conf && getOption(conf, "explode");
 253      if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
 254  
 255      var ranges = cm.listSelections();
 256      for (var i = 0; i < ranges.length; i++) {
 257        if (!ranges[i].empty()) return CodeMirror.Pass;
 258        var around = charsAround(cm, ranges[i].head);
 259        if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
 260      }
 261      cm.operation(function() {
 262        var linesep = cm.lineSeparator() || "\n";
 263        cm.replaceSelection(linesep + linesep, null);
 264        moveSel(cm, -1)
 265        ranges = cm.listSelections();
 266        for (var i = 0; i < ranges.length; i++) {
 267          var line = ranges[i].head.line;
 268          cm.indentLine(line, null, true);
 269          cm.indentLine(line + 1, null, true);
 270        }
 271      });
 272    }
 273  
 274    function moveSel(cm, dir) {
 275      var newRanges = [], ranges = cm.listSelections(), primary = 0
 276      for (var i = 0; i < ranges.length; i++) {
 277        var range = ranges[i]
 278        if (range.head == cm.getCursor()) primary = i
 279        var pos = range.head.ch || dir > 0 ? {line: range.head.line, ch: range.head.ch + dir} : {line: range.head.line - 1}
 280        newRanges.push({anchor: pos, head: pos})
 281      }
 282      cm.setSelections(newRanges, primary)
 283    }
 284  
 285    function contractSelection(sel) {
 286      var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
 287      return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
 288              head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
 289    }
 290  
 291    function handleChar(cm, ch) {
 292      var conf = getConfig(cm);
 293      if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
 294  
 295      var pairs = getOption(conf, "pairs");
 296      var pos = pairs.indexOf(ch);
 297      if (pos == -1) return CodeMirror.Pass;
 298  
 299      var closeBefore = getOption(conf,"closeBefore");
 300  
 301      var triples = getOption(conf, "triples");
 302  
 303      var identical = pairs.charAt(pos + 1) == ch;
 304      var ranges = cm.listSelections();
 305      var opening = pos % 2 == 0;
 306  
 307      var type;
 308      for (var i = 0; i < ranges.length; i++) {
 309        var range = ranges[i], cur = range.head, curType;
 310        var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
 311        if (opening && !range.empty()) {
 312          curType = "surround";
 313        } else if ((identical || !opening) && next == ch) {
 314          if (identical && stringStartsAfter(cm, cur))
 315            curType = "both";
 316          else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
 317            curType = "skipThree";
 318          else
 319            curType = "skip";
 320        } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
 321                   cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
 322          if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
 323          curType = "addFour";
 324        } else if (identical) {
 325          var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
 326          if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
 327          else return CodeMirror.Pass;
 328        } else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
 329          curType = "both";
 330        } else {
 331          return CodeMirror.Pass;
 332        }
 333        if (!type) type = curType;
 334        else if (type != curType) return CodeMirror.Pass;
 335      }
 336  
 337      var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
 338      var right = pos % 2 ? ch : pairs.charAt(pos + 1);
 339      cm.operation(function() {
 340        if (type == "skip") {
 341          moveSel(cm, 1)
 342        } else if (type == "skipThree") {
 343          moveSel(cm, 3)
 344        } else if (type == "surround") {
 345          var sels = cm.getSelections();
 346          for (var i = 0; i < sels.length; i++)
 347            sels[i] = left + sels[i] + right;
 348          cm.replaceSelections(sels, "around");
 349          sels = cm.listSelections().slice();
 350          for (var i = 0; i < sels.length; i++)
 351            sels[i] = contractSelection(sels[i]);
 352          cm.setSelections(sels);
 353        } else if (type == "both") {
 354          cm.replaceSelection(left + right, null);
 355          cm.triggerElectric(left + right);
 356          moveSel(cm, -1)
 357        } else if (type == "addFour") {
 358          cm.replaceSelection(left + left + left + left, "before");
 359          moveSel(cm, 1)
 360        }
 361      });
 362    }
 363  
 364    function charsAround(cm, pos) {
 365      var str = cm.getRange(Pos(pos.line, pos.ch - 1),
 366                            Pos(pos.line, pos.ch + 1));
 367      return str.length == 2 ? str : null;
 368    }
 369  
 370    function stringStartsAfter(cm, pos) {
 371      var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
 372      return /\bstring/.test(token.type) && token.start == pos.ch &&
 373        (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
 374    }
 375  });
 376   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 377  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 378  
 379  /**
 380   * Tag-closer extension for CodeMirror.
 381   *
 382   * This extension adds an "autoCloseTags" option that can be set to
 383   * either true to get the default behavior, or an object to further
 384   * configure its behavior.
 385   *
 386   * These are supported options:
 387   *
 388   * `whenClosing` (default true)
 389   *   Whether to autoclose when the '/' of a closing tag is typed.
 390   * `whenOpening` (default true)
 391   *   Whether to autoclose the tag when the final '>' of an opening
 392   *   tag is typed.
 393   * `dontCloseTags` (default is empty tags for HTML, none for XML)
 394   *   An array of tag names that should not be autoclosed.
 395   * `indentTags` (default is block tags for HTML, none for XML)
 396   *   An array of tag names that should, when opened, cause a
 397   *   blank line to be added inside the tag, and the blank line and
 398   *   closing line to be indented.
 399   * `emptyTags` (default is none)
 400   *   An array of XML tag names that should be autoclosed with '/>'.
 401   *
 402   * See demos/closetag.html for a usage example.
 403   */
 404  
 405  (function(mod) {
 406    if (typeof exports == "object" && typeof module == "object") // CommonJS
 407      mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
 408    else if (typeof define == "function" && define.amd) // AMD
 409      define(["../../lib/codemirror", "../fold/xml-fold"], mod);
 410    else // Plain browser env
 411      mod(CodeMirror);
 412  })(function(CodeMirror) {
 413    CodeMirror.defineOption("autoCloseTags", false, function(cm, val, old) {
 414      if (old != CodeMirror.Init && old)
 415        cm.removeKeyMap("autoCloseTags");
 416      if (!val) return;
 417      var map = {name: "autoCloseTags"};
 418      if (typeof val != "object" || val.whenClosing !== false)
 419        map["'/'"] = function(cm) { return autoCloseSlash(cm); };
 420      if (typeof val != "object" || val.whenOpening !== false)
 421        map["'>'"] = function(cm) { return autoCloseGT(cm); };
 422      cm.addKeyMap(map);
 423    });
 424  
 425    var htmlDontClose = ["area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param",
 426                         "source", "track", "wbr"];
 427    var htmlIndent = ["applet", "blockquote", "body", "button", "div", "dl", "fieldset", "form", "frameset", "h1", "h2", "h3", "h4",
 428                      "h5", "h6", "head", "html", "iframe", "layer", "legend", "object", "ol", "p", "select", "table", "ul"];
 429  
 430    function autoCloseGT(cm) {
 431      if (cm.getOption("disableInput")) return CodeMirror.Pass;
 432      var ranges = cm.listSelections(), replacements = [];
 433      var opt = cm.getOption("autoCloseTags");
 434      for (var i = 0; i < ranges.length; i++) {
 435        if (!ranges[i].empty()) return CodeMirror.Pass;
 436        var pos = ranges[i].head, tok = cm.getTokenAt(pos);
 437        var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
 438        var tagInfo = inner.mode.xmlCurrentTag && inner.mode.xmlCurrentTag(state)
 439        var tagName = tagInfo && tagInfo.name
 440        if (!tagName) return CodeMirror.Pass
 441  
 442        var html = inner.mode.configuration == "html";
 443        var dontCloseTags = (typeof opt == "object" && opt.dontCloseTags) || (html && htmlDontClose);
 444        var indentTags = (typeof opt == "object" && opt.indentTags) || (html && htmlIndent);
 445  
 446        if (tok.end > pos.ch) tagName = tagName.slice(0, tagName.length - tok.end + pos.ch);
 447        var lowerTagName = tagName.toLowerCase();
 448        // Don't process the '>' at the end of an end-tag or self-closing tag
 449        if (!tagName ||
 450            tok.type == "string" && (tok.end != pos.ch || !/[\"\']/.test(tok.string.charAt(tok.string.length - 1)) || tok.string.length == 1) ||
 451            tok.type == "tag" && tagInfo.close ||
 452            tok.string.indexOf("/") == (pos.ch - tok.start - 1) || // match something like <someTagName />
 453            dontCloseTags && indexOf(dontCloseTags, lowerTagName) > -1 ||
 454            closingTagExists(cm, inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state) || [], tagName, pos, true))
 455          return CodeMirror.Pass;
 456  
 457        var emptyTags = typeof opt == "object" && opt.emptyTags;
 458        if (emptyTags && indexOf(emptyTags, tagName) > -1) {
 459          replacements[i] = { text: "/>", newPos: CodeMirror.Pos(pos.line, pos.ch + 2) };
 460          continue;
 461        }
 462  
 463        var indent = indentTags && indexOf(indentTags, lowerTagName) > -1;
 464        replacements[i] = {indent: indent,
 465                           text: ">" + (indent ? "\n\n" : "") + "</" + tagName + ">",
 466                           newPos: indent ? CodeMirror.Pos(pos.line + 1, 0) : CodeMirror.Pos(pos.line, pos.ch + 1)};
 467      }
 468  
 469      var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnAutoClose);
 470      for (var i = ranges.length - 1; i >= 0; i--) {
 471        var info = replacements[i];
 472        cm.replaceRange(info.text, ranges[i].head, ranges[i].anchor, "+insert");
 473        var sel = cm.listSelections().slice(0);
 474        sel[i] = {head: info.newPos, anchor: info.newPos};
 475        cm.setSelections(sel);
 476        if (!dontIndentOnAutoClose && info.indent) {
 477          cm.indentLine(info.newPos.line, null, true);
 478          cm.indentLine(info.newPos.line + 1, null, true);
 479        }
 480      }
 481    }
 482  
 483    function autoCloseCurrent(cm, typingSlash) {
 484      var ranges = cm.listSelections(), replacements = [];
 485      var head = typingSlash ? "/" : "</";
 486      var opt = cm.getOption("autoCloseTags");
 487      var dontIndentOnAutoClose = (typeof opt == "object" && opt.dontIndentOnSlash);
 488      for (var i = 0; i < ranges.length; i++) {
 489        if (!ranges[i].empty()) return CodeMirror.Pass;
 490        var pos = ranges[i].head, tok = cm.getTokenAt(pos);
 491        var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state;
 492        if (typingSlash && (tok.type == "string" || tok.string.charAt(0) != "<" ||
 493                            tok.start != pos.ch - 1))
 494          return CodeMirror.Pass;
 495        // Kludge to get around the fact that we are not in XML mode
 496        // when completing in JS/CSS snippet in htmlmixed mode. Does not
 497        // work for other XML embedded languages (there is no general
 498        // way to go from a mixed mode to its current XML state).
 499        var replacement, mixed = inner.mode.name != "xml" && cm.getMode().name == "htmlmixed"
 500        if (mixed && inner.mode.name == "javascript") {
 501          replacement = head + "script";
 502        } else if (mixed && inner.mode.name == "css") {
 503          replacement = head + "style";
 504        } else {
 505          var context = inner.mode.xmlCurrentContext && inner.mode.xmlCurrentContext(state)
 506          var top = context.length ? context[context.length - 1] : ""
 507          if (!context || (context.length && closingTagExists(cm, context, top, pos)))
 508            return CodeMirror.Pass;
 509          replacement = head + top
 510        }
 511        if (cm.getLine(pos.line).charAt(tok.end) != ">") replacement += ">";
 512        replacements[i] = replacement;
 513      }
 514      cm.replaceSelections(replacements);
 515      ranges = cm.listSelections();
 516      if (!dontIndentOnAutoClose) {
 517          for (var i = 0; i < ranges.length; i++)
 518              if (i == ranges.length - 1 || ranges[i].head.line < ranges[i + 1].head.line)
 519                  cm.indentLine(ranges[i].head.line);
 520      }
 521    }
 522  
 523    function autoCloseSlash(cm) {
 524      if (cm.getOption("disableInput")) return CodeMirror.Pass;
 525      return autoCloseCurrent(cm, true);
 526    }
 527  
 528    CodeMirror.commands.closeTag = function(cm) { return autoCloseCurrent(cm); };
 529  
 530    function indexOf(collection, elt) {
 531      if (collection.indexOf) return collection.indexOf(elt);
 532      for (var i = 0, e = collection.length; i < e; ++i)
 533        if (collection[i] == elt) return i;
 534      return -1;
 535    }
 536  
 537    // If xml-fold is loaded, we use its functionality to try and verify
 538    // whether a given tag is actually unclosed.
 539    function closingTagExists(cm, context, tagName, pos, newTag) {
 540      if (!CodeMirror.scanForClosingTag) return false;
 541      var end = Math.min(cm.lastLine() + 1, pos.line + 500);
 542      var nextClose = CodeMirror.scanForClosingTag(cm, pos, null, end);
 543      if (!nextClose || nextClose.tag != tagName) return false;
 544      // If the immediate wrapping context contains onCx instances of
 545      // the same tag, a closing tag only exists if there are at least
 546      // that many closing tags of that type following.
 547      var onCx = newTag ? 1 : 0
 548      for (var i = context.length - 1; i >= 0; i--) {
 549        if (context[i] == tagName) ++onCx
 550        else break
 551      }
 552      pos = nextClose.to;
 553      for (var i = 1; i < onCx; i++) {
 554        var next = CodeMirror.scanForClosingTag(cm, pos, null, end);
 555        if (!next || next.tag != tagName) return false;
 556        pos = next.to;
 557      }
 558      return true;
 559    }
 560  });
 561   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 562  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 563  
 564  (function(mod) {
 565    if (typeof exports == "object" && typeof module == "object") // CommonJS
 566      mod(require("../../lib/codemirror"));
 567    else if (typeof define == "function" && define.amd) // AMD
 568      define(["../../lib/codemirror"], mod);
 569    else // Plain browser env
 570      mod(CodeMirror);
 571  })(function(CodeMirror) {
 572    var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
 573      (document.documentMode == null || document.documentMode < 8);
 574  
 575    var Pos = CodeMirror.Pos;
 576  
 577    var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
 578  
 579    function bracketRegex(config) {
 580      return config && config.bracketRegex || /[(){}[\]]/
 581    }
 582  
 583    function findMatchingBracket(cm, where, config) {
 584      var line = cm.getLineHandle(where.line), pos = where.ch - 1;
 585      var afterCursor = config && config.afterCursor
 586      if (afterCursor == null)
 587        afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
 588      var re = bracketRegex(config)
 589  
 590      // A cursor is defined as between two characters, but in in vim command mode
 591      // (i.e. not insert mode), the cursor is visually represented as a
 592      // highlighted box on top of the 2nd character. Otherwise, we allow matches
 593      // from before or after the cursor.
 594      var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
 595          re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
 596      if (!match) return null;
 597      var dir = match.charAt(1) == ">" ? 1 : -1;
 598      if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
 599      var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
 600  
 601      var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style, config);
 602      if (found == null) return null;
 603      return {from: Pos(where.line, pos), to: found && found.pos,
 604              match: found && found.ch == match.charAt(0), forward: dir > 0};
 605    }
 606  
 607    // bracketRegex is used to specify which type of bracket to scan
 608    // should be a regexp, e.g. /[[\]]/
 609    //
 610    // Note: If "where" is on an open bracket, then this bracket is ignored.
 611    //
 612    // Returns false when no bracket was found, null when it reached
 613    // maxScanLines and gave up
 614    function scanForBracket(cm, where, dir, style, config) {
 615      var maxScanLen = (config && config.maxScanLineLength) || 10000;
 616      var maxScanLines = (config && config.maxScanLines) || 1000;
 617  
 618      var stack = [];
 619      var re = bracketRegex(config)
 620      var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
 621                            : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
 622      for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
 623        var line = cm.getLine(lineNo);
 624        if (!line) continue;
 625        var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
 626        if (line.length > maxScanLen) continue;
 627        if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
 628        for (; pos != end; pos += dir) {
 629          var ch = line.charAt(pos);
 630          if (re.test(ch) && (style === undefined ||
 631                              (cm.getTokenTypeAt(Pos(lineNo, pos + 1)) || "") == (style || ""))) {
 632            var match = matching[ch];
 633            if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
 634            else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
 635            else stack.pop();
 636          }
 637        }
 638      }
 639      return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
 640    }
 641  
 642    function matchBrackets(cm, autoclear, config) {
 643      // Disable brace matching in long lines, since it'll cause hugely slow updates
 644      var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000,
 645        highlightNonMatching = config && config.highlightNonMatching;
 646      var marks = [], ranges = cm.listSelections();
 647      for (var i = 0; i < ranges.length; i++) {
 648        var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
 649        if (match && (match.match || highlightNonMatching !== false) && cm.getLine(match.from.line).length <= maxHighlightLen) {
 650          var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
 651          marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
 652          if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
 653            marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
 654        }
 655      }
 656  
 657      if (marks.length) {
 658        // Kludge to work around the IE bug from issue #1193, where text
 659        // input stops going to the textarea whenever this fires.
 660        if (ie_lt8 && cm.state.focused) cm.focus();
 661  
 662        var clear = function() {
 663          cm.operation(function() {
 664            for (var i = 0; i < marks.length; i++) marks[i].clear();
 665          });
 666        };
 667        if (autoclear) setTimeout(clear, 800);
 668        else return clear;
 669      }
 670    }
 671  
 672    function doMatchBrackets(cm) {
 673      cm.operation(function() {
 674        if (cm.state.matchBrackets.currentlyHighlighted) {
 675          cm.state.matchBrackets.currentlyHighlighted();
 676          cm.state.matchBrackets.currentlyHighlighted = null;
 677        }
 678        cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
 679      });
 680    }
 681  
 682    function clearHighlighted(cm) {
 683      if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
 684        cm.state.matchBrackets.currentlyHighlighted();
 685        cm.state.matchBrackets.currentlyHighlighted = null;
 686      }
 687    }
 688  
 689    CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
 690      if (old && old != CodeMirror.Init) {
 691        cm.off("cursorActivity", doMatchBrackets);
 692        cm.off("focus", doMatchBrackets)
 693        cm.off("blur", clearHighlighted)
 694        clearHighlighted(cm);
 695      }
 696      if (val) {
 697        cm.state.matchBrackets = typeof val == "object" ? val : {};
 698        cm.on("cursorActivity", doMatchBrackets);
 699        cm.on("focus", doMatchBrackets)
 700        cm.on("blur", clearHighlighted)
 701      }
 702    });
 703  
 704    CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
 705    CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
 706      // Backwards-compatibility kludge
 707      if (oldConfig || typeof config == "boolean") {
 708        if (!oldConfig) {
 709          config = config ? {strict: true} : null
 710        } else {
 711          oldConfig.strict = config
 712          config = oldConfig
 713        }
 714      }
 715      return findMatchingBracket(this, pos, config)
 716    });
 717    CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
 718      return scanForBracket(this, pos, dir, style, config);
 719    });
 720  });
 721   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 722  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 723  
 724  (function(mod) {
 725    if (typeof exports == "object" && typeof module == "object") // CommonJS
 726      mod(require("../../lib/codemirror"), require("../fold/xml-fold"));
 727    else if (typeof define == "function" && define.amd) // AMD
 728      define(["../../lib/codemirror", "../fold/xml-fold"], mod);
 729    else // Plain browser env
 730      mod(CodeMirror);
 731  })(function(CodeMirror) {
 732    "use strict";
 733  
 734    CodeMirror.defineOption("matchTags", false, function(cm, val, old) {
 735      if (old && old != CodeMirror.Init) {
 736        cm.off("cursorActivity", doMatchTags);
 737        cm.off("viewportChange", maybeUpdateMatch);
 738        clear(cm);
 739      }
 740      if (val) {
 741        cm.state.matchBothTags = typeof val == "object" && val.bothTags;
 742        cm.on("cursorActivity", doMatchTags);
 743        cm.on("viewportChange", maybeUpdateMatch);
 744        doMatchTags(cm);
 745      }
 746    });
 747  
 748    function clear(cm) {
 749      if (cm.state.tagHit) cm.state.tagHit.clear();
 750      if (cm.state.tagOther) cm.state.tagOther.clear();
 751      cm.state.tagHit = cm.state.tagOther = null;
 752    }
 753  
 754    function doMatchTags(cm) {
 755      cm.state.failedTagMatch = false;
 756      cm.operation(function() {
 757        clear(cm);
 758        if (cm.somethingSelected()) return;
 759        var cur = cm.getCursor(), range = cm.getViewport();
 760        range.from = Math.min(range.from, cur.line); range.to = Math.max(cur.line + 1, range.to);
 761        var match = CodeMirror.findMatchingTag(cm, cur, range);
 762        if (!match) return;
 763        if (cm.state.matchBothTags) {
 764          var hit = match.at == "open" ? match.open : match.close;
 765          if (hit) cm.state.tagHit = cm.markText(hit.from, hit.to, {className: "CodeMirror-matchingtag"});
 766        }
 767        var other = match.at == "close" ? match.open : match.close;
 768        if (other)
 769          cm.state.tagOther = cm.markText(other.from, other.to, {className: "CodeMirror-matchingtag"});
 770        else
 771          cm.state.failedTagMatch = true;
 772      });
 773    }
 774  
 775    function maybeUpdateMatch(cm) {
 776      if (cm.state.failedTagMatch) doMatchTags(cm);
 777    }
 778  
 779    CodeMirror.commands.toMatchingTag = function(cm) {
 780      var found = CodeMirror.findMatchingTag(cm, cm.getCursor());
 781      if (found) {
 782        var other = found.at == "close" ? found.open : found.close;
 783        if (other) cm.extendSelection(other.to, other.from);
 784      }
 785    };
 786  });
 787   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 788  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 789  
 790  (function(mod) {
 791    if (typeof exports == "object" && typeof module == "object") // CommonJS
 792      mod(require("../../lib/codemirror"));
 793    else if (typeof define == "function" && define.amd) // AMD
 794      define(["../../lib/codemirror"], mod);
 795    else // Plain browser env
 796      mod(CodeMirror);
 797  })(function(CodeMirror) {
 798  "use strict";
 799  
 800  function bracketFolding(pairs) {
 801    return function(cm, start) {
 802      var line = start.line, lineText = cm.getLine(line);
 803  
 804      function findOpening(pair) {
 805        var tokenType;
 806        for (var at = start.ch, pass = 0;;) {
 807          var found = at <= 0 ? -1 : lineText.lastIndexOf(pair[0], at - 1);
 808          if (found == -1) {
 809            if (pass == 1) break;
 810            pass = 1;
 811            at = lineText.length;
 812            continue;
 813          }
 814          if (pass == 1 && found < start.ch) break;
 815          tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));
 816          if (!/^(comment|string)/.test(tokenType)) return {ch: found + 1, tokenType: tokenType, pair: pair};
 817          at = found - 1;
 818        }
 819      }
 820  
 821      function findRange(found) {
 822        var count = 1, lastLine = cm.lastLine(), end, startCh = found.ch, endCh
 823        outer: for (var i = line; i <= lastLine; ++i) {
 824          var text = cm.getLine(i), pos = i == line ? startCh : 0;
 825          for (;;) {
 826            var nextOpen = text.indexOf(found.pair[0], pos), nextClose = text.indexOf(found.pair[1], pos);
 827            if (nextOpen < 0) nextOpen = text.length;
 828            if (nextClose < 0) nextClose = text.length;
 829            pos = Math.min(nextOpen, nextClose);
 830            if (pos == text.length) break;
 831            if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == found.tokenType) {
 832              if (pos == nextOpen) ++count;
 833              else if (!--count) { end = i; endCh = pos; break outer; }
 834            }
 835            ++pos;
 836          }
 837        }
 838  
 839        if (end == null || line == end) return null
 840        return {from: CodeMirror.Pos(line, startCh),
 841                to: CodeMirror.Pos(end, endCh)};
 842      }
 843  
 844      var found = []
 845      for (var i = 0; i < pairs.length; i++) {
 846        var open = findOpening(pairs[i])
 847        if (open) found.push(open)
 848      }
 849      found.sort(function(a, b) { return a.ch - b.ch })
 850      for (var i = 0; i < found.length; i++) {
 851        var range = findRange(found[i])
 852        if (range) return range
 853      }
 854      return null
 855    }
 856  }
 857  
 858  CodeMirror.registerHelper("fold", "brace", bracketFolding([["{", "}"], ["[", "]"]]));
 859  
 860  CodeMirror.registerHelper("fold", "brace-paren", bracketFolding([["{", "}"], ["[", "]"], ["(", ")"]]));
 861  
 862  CodeMirror.registerHelper("fold", "import", function(cm, start) {
 863    function hasImport(line) {
 864      if (line < cm.firstLine() || line > cm.lastLine()) return null;
 865      var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
 866      if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
 867      if (start.type != "keyword" || start.string != "import") return null;
 868      // Now find closing semicolon, return its position
 869      for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {
 870        var text = cm.getLine(i), semi = text.indexOf(";");
 871        if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};
 872      }
 873    }
 874  
 875    var startLine = start.line, has = hasImport(startLine), prev;
 876    if (!has || hasImport(startLine - 1) || ((prev = hasImport(startLine - 2)) && prev.end.line == startLine - 1))
 877      return null;
 878    for (var end = has.end;;) {
 879      var next = hasImport(end.line + 1);
 880      if (next == null) break;
 881      end = next.end;
 882    }
 883    return {from: cm.clipPos(CodeMirror.Pos(startLine, has.startCh + 1)), to: end};
 884  });
 885  
 886  CodeMirror.registerHelper("fold", "include", function(cm, start) {
 887    function hasInclude(line) {
 888      if (line < cm.firstLine() || line > cm.lastLine()) return null;
 889      var start = cm.getTokenAt(CodeMirror.Pos(line, 1));
 890      if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));
 891      if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8;
 892    }
 893  
 894    var startLine = start.line, has = hasInclude(startLine);
 895    if (has == null || hasInclude(startLine - 1) != null) return null;
 896    for (var end = startLine;;) {
 897      var next = hasInclude(end + 1);
 898      if (next == null) break;
 899      ++end;
 900    }
 901    return {from: CodeMirror.Pos(startLine, has + 1),
 902            to: cm.clipPos(CodeMirror.Pos(end))};
 903  });
 904  
 905  });
 906   // CodeMirror, copyright (c) by Marijn Haverbeke and others
 907  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
 908  
 909  (function(mod) {
 910    if (typeof exports == "object" && typeof module == "object") // CommonJS
 911      mod(require("../../lib/codemirror"));
 912    else if (typeof define == "function" && define.amd) // AMD
 913      define(["../../lib/codemirror"], mod);
 914    else // Plain browser env
 915      mod(CodeMirror);
 916  })(function(CodeMirror) {
 917    "use strict";
 918  
 919    function doFold(cm, pos, options, force) {
 920      if (options && options.call) {
 921        var finder = options;
 922        options = null;
 923      } else {
 924        var finder = getOption(cm, options, "rangeFinder");
 925      }
 926      if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0);
 927      var minSize = getOption(cm, options, "minFoldSize");
 928  
 929      function getRange(allowFolded) {
 930        var range = finder(cm, pos);
 931        if (!range || range.to.line - range.from.line < minSize) return null;
 932        if (force === "fold") return range;
 933  
 934        var marks = cm.findMarksAt(range.from);
 935        for (var i = 0; i < marks.length; ++i) {
 936          if (marks[i].__isFold) {
 937            if (!allowFolded) return null;
 938            range.cleared = true;
 939            marks[i].clear();
 940          }
 941        }
 942        return range;
 943      }
 944  
 945      var range = getRange(true);
 946      if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) {
 947        pos = CodeMirror.Pos(pos.line - 1, 0);
 948        range = getRange(false);
 949      }
 950      if (!range || range.cleared || force === "unfold") return;
 951  
 952      var myWidget = makeWidget(cm, options, range);
 953      CodeMirror.on(myWidget, "mousedown", function(e) {
 954        myRange.clear();
 955        CodeMirror.e_preventDefault(e);
 956      });
 957      var myRange = cm.markText(range.from, range.to, {
 958        replacedWith: myWidget,
 959        clearOnEnter: getOption(cm, options, "clearOnEnter"),
 960        __isFold: true
 961      });
 962      myRange.on("clear", function(from, to) {
 963        CodeMirror.signal(cm, "unfold", cm, from, to);
 964      });
 965      CodeMirror.signal(cm, "fold", cm, range.from, range.to);
 966    }
 967  
 968    function makeWidget(cm, options, range) {
 969      var widget = getOption(cm, options, "widget");
 970  
 971      if (typeof widget == "function") {
 972        widget = widget(range.from, range.to);
 973      }
 974  
 975      if (typeof widget == "string") {
 976        var text = document.createTextNode(widget);
 977        widget = document.createElement("span");
 978        widget.appendChild(text);
 979        widget.className = "CodeMirror-foldmarker";
 980      } else if (widget) {
 981        widget = widget.cloneNode(true)
 982      }
 983      return widget;
 984    }
 985  
 986    // Clumsy backwards-compatible interface
 987    CodeMirror.newFoldFunction = function(rangeFinder, widget) {
 988      return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };
 989    };
 990  
 991    // New-style interface
 992    CodeMirror.defineExtension("foldCode", function(pos, options, force) {
 993      doFold(this, pos, options, force);
 994    });
 995  
 996    CodeMirror.defineExtension("isFolded", function(pos) {
 997      var marks = this.findMarksAt(pos);
 998      for (var i = 0; i < marks.length; ++i)
 999        if (marks[i].__isFold) return true;
1000    });
1001  
1002    CodeMirror.commands.toggleFold = function(cm) {
1003      cm.foldCode(cm.getCursor());
1004    };
1005    CodeMirror.commands.fold = function(cm) {
1006      cm.foldCode(cm.getCursor(), null, "fold");
1007    };
1008    CodeMirror.commands.unfold = function(cm) {
1009      cm.foldCode(cm.getCursor(), { scanUp: false }, "unfold");
1010    };
1011    CodeMirror.commands.foldAll = function(cm) {
1012      cm.operation(function() {
1013        for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
1014          cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "fold");
1015      });
1016    };
1017    CodeMirror.commands.unfoldAll = function(cm) {
1018      cm.operation(function() {
1019        for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)
1020          cm.foldCode(CodeMirror.Pos(i, 0), { scanUp: false }, "unfold");
1021      });
1022    };
1023  
1024    CodeMirror.registerHelper("fold", "combine", function() {
1025      var funcs = Array.prototype.slice.call(arguments, 0);
1026      return function(cm, start) {
1027        for (var i = 0; i < funcs.length; ++i) {
1028          var found = funcs[i](cm, start);
1029          if (found) return found;
1030        }
1031      };
1032    });
1033  
1034    CodeMirror.registerHelper("fold", "auto", function(cm, start) {
1035      var helpers = cm.getHelpers(start, "fold");
1036      for (var i = 0; i < helpers.length; i++) {
1037        var cur = helpers[i](cm, start);
1038        if (cur) return cur;
1039      }
1040    });
1041  
1042    var defaultOptions = {
1043      rangeFinder: CodeMirror.fold.auto,
1044      widget: "\u2194",
1045      minFoldSize: 0,
1046      scanUp: false,
1047      clearOnEnter: true
1048    };
1049  
1050    CodeMirror.defineOption("foldOptions", null);
1051  
1052    function getOption(cm, options, name) {
1053      if (options && options[name] !== undefined)
1054        return options[name];
1055      var editorOptions = cm.options.foldOptions;
1056      if (editorOptions && editorOptions[name] !== undefined)
1057        return editorOptions[name];
1058      return defaultOptions[name];
1059    }
1060  
1061    CodeMirror.defineExtension("foldOption", function(options, name) {
1062      return getOption(this, options, name);
1063    });
1064  });
1065   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1066  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1067  
1068  (function(mod) {
1069    if (typeof exports == "object" && typeof module == "object") // CommonJS
1070      mod(require("../../lib/codemirror"), require("./foldcode"));
1071    else if (typeof define == "function" && define.amd) // AMD
1072      define(["../../lib/codemirror", "./foldcode"], mod);
1073    else // Plain browser env
1074      mod(CodeMirror);
1075  })(function(CodeMirror) {
1076    "use strict";
1077  
1078    CodeMirror.defineOption("foldGutter", false, function(cm, val, old) {
1079      if (old && old != CodeMirror.Init) {
1080        cm.clearGutter(cm.state.foldGutter.options.gutter);
1081        cm.state.foldGutter = null;
1082        cm.off("gutterClick", onGutterClick);
1083        cm.off("changes", onChange);
1084        cm.off("viewportChange", onViewportChange);
1085        cm.off("fold", onFold);
1086        cm.off("unfold", onFold);
1087        cm.off("swapDoc", onChange);
1088      }
1089      if (val) {
1090        cm.state.foldGutter = new State(parseOptions(val));
1091        updateInViewport(cm);
1092        cm.on("gutterClick", onGutterClick);
1093        cm.on("changes", onChange);
1094        cm.on("viewportChange", onViewportChange);
1095        cm.on("fold", onFold);
1096        cm.on("unfold", onFold);
1097        cm.on("swapDoc", onChange);
1098      }
1099    });
1100  
1101    var Pos = CodeMirror.Pos;
1102  
1103    function State(options) {
1104      this.options = options;
1105      this.from = this.to = 0;
1106    }
1107  
1108    function parseOptions(opts) {
1109      if (opts === true) opts = {};
1110      if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter";
1111      if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open";
1112      if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded";
1113      return opts;
1114    }
1115  
1116    function isFolded(cm, line) {
1117      var marks = cm.findMarks(Pos(line, 0), Pos(line + 1, 0));
1118      for (var i = 0; i < marks.length; ++i) {
1119        if (marks[i].__isFold) {
1120          var fromPos = marks[i].find(-1);
1121          if (fromPos && fromPos.line === line)
1122            return marks[i];
1123        }
1124      }
1125    }
1126  
1127    function marker(spec) {
1128      if (typeof spec == "string") {
1129        var elt = document.createElement("div");
1130        elt.className = spec + " CodeMirror-guttermarker-subtle";
1131        return elt;
1132      } else {
1133        return spec.cloneNode(true);
1134      }
1135    }
1136  
1137    function updateFoldInfo(cm, from, to) {
1138      var opts = cm.state.foldGutter.options, cur = from - 1;
1139      var minSize = cm.foldOption(opts, "minFoldSize");
1140      var func = cm.foldOption(opts, "rangeFinder");
1141      // we can reuse the built-in indicator element if its className matches the new state
1142      var clsFolded = typeof opts.indicatorFolded == "string" && classTest(opts.indicatorFolded);
1143      var clsOpen = typeof opts.indicatorOpen == "string" && classTest(opts.indicatorOpen);
1144      cm.eachLine(from, to, function(line) {
1145        ++cur;
1146        var mark = null;
1147        var old = line.gutterMarkers;
1148        if (old) old = old[opts.gutter];
1149        if (isFolded(cm, cur)) {
1150          if (clsFolded && old && clsFolded.test(old.className)) return;
1151          mark = marker(opts.indicatorFolded);
1152        } else {
1153          var pos = Pos(cur, 0);
1154          var range = func && func(cm, pos);
1155          if (range && range.to.line - range.from.line >= minSize) {
1156            if (clsOpen && old && clsOpen.test(old.className)) return;
1157            mark = marker(opts.indicatorOpen);
1158          }
1159        }
1160        if (!mark && !old) return;
1161        cm.setGutterMarker(line, opts.gutter, mark);
1162      });
1163    }
1164  
1165    // copied from CodeMirror/src/util/dom.js
1166    function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
1167  
1168    function updateInViewport(cm) {
1169      var vp = cm.getViewport(), state = cm.state.foldGutter;
1170      if (!state) return;
1171      cm.operation(function() {
1172        updateFoldInfo(cm, vp.from, vp.to);
1173      });
1174      state.from = vp.from; state.to = vp.to;
1175    }
1176  
1177    function onGutterClick(cm, line, gutter) {
1178      var state = cm.state.foldGutter;
1179      if (!state) return;
1180      var opts = state.options;
1181      if (gutter != opts.gutter) return;
1182      var folded = isFolded(cm, line);
1183      if (folded) folded.clear();
1184      else cm.foldCode(Pos(line, 0), opts);
1185    }
1186  
1187    function onChange(cm) {
1188      var state = cm.state.foldGutter;
1189      if (!state) return;
1190      var opts = state.options;
1191      state.from = state.to = 0;
1192      clearTimeout(state.changeUpdate);
1193      state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);
1194    }
1195  
1196    function onViewportChange(cm) {
1197      var state = cm.state.foldGutter;
1198      if (!state) return;
1199      var opts = state.options;
1200      clearTimeout(state.changeUpdate);
1201      state.changeUpdate = setTimeout(function() {
1202        var vp = cm.getViewport();
1203        if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {
1204          updateInViewport(cm);
1205        } else {
1206          cm.operation(function() {
1207            if (vp.from < state.from) {
1208              updateFoldInfo(cm, vp.from, state.from);
1209              state.from = vp.from;
1210            }
1211            if (vp.to > state.to) {
1212              updateFoldInfo(cm, state.to, vp.to);
1213              state.to = vp.to;
1214            }
1215          });
1216        }
1217      }, opts.updateViewportTimeSpan || 400);
1218    }
1219  
1220    function onFold(cm, from) {
1221      var state = cm.state.foldGutter;
1222      if (!state) return;
1223      var line = from.line;
1224      if (line >= state.from && line < state.to)
1225        updateFoldInfo(cm, line, line + 1);
1226    }
1227  });
1228   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1229  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1230  
1231  (function(mod) {
1232    if (typeof exports == "object" && typeof module == "object") // CommonJS
1233      mod(require("../../lib/codemirror"));
1234    else if (typeof define == "function" && define.amd) // AMD
1235      define(["../../lib/codemirror"], mod);
1236    else // Plain browser env
1237      mod(CodeMirror);
1238  })(function(CodeMirror) {
1239    "use strict";
1240  
1241    var Pos = CodeMirror.Pos;
1242    function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }
1243  
1244    var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
1245    var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
1246    var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g");
1247  
1248    function Iter(cm, line, ch, range) {
1249      this.line = line; this.ch = ch;
1250      this.cm = cm; this.text = cm.getLine(line);
1251      this.min = range ? Math.max(range.from, cm.firstLine()) : cm.firstLine();
1252      this.max = range ? Math.min(range.to - 1, cm.lastLine()) : cm.lastLine();
1253    }
1254  
1255    function tagAt(iter, ch) {
1256      var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));
1257      return type && /\btag\b/.test(type);
1258    }
1259  
1260    function nextLine(iter) {
1261      if (iter.line >= iter.max) return;
1262      iter.ch = 0;
1263      iter.text = iter.cm.getLine(++iter.line);
1264      return true;
1265    }
1266    function prevLine(iter) {
1267      if (iter.line <= iter.min) return;
1268      iter.text = iter.cm.getLine(--iter.line);
1269      iter.ch = iter.text.length;
1270      return true;
1271    }
1272  
1273    function toTagEnd(iter) {
1274      for (;;) {
1275        var gt = iter.text.indexOf(">", iter.ch);
1276        if (gt == -1) { if (nextLine(iter)) continue; else return; }
1277        if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }
1278        var lastSlash = iter.text.lastIndexOf("/", gt);
1279        var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
1280        iter.ch = gt + 1;
1281        return selfClose ? "selfClose" : "regular";
1282      }
1283    }
1284    function toTagStart(iter) {
1285      for (;;) {
1286        var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1;
1287        if (lt == -1) { if (prevLine(iter)) continue; else return; }
1288        if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }
1289        xmlTagStart.lastIndex = lt;
1290        iter.ch = lt;
1291        var match = xmlTagStart.exec(iter.text);
1292        if (match && match.index == lt) return match;
1293      }
1294    }
1295  
1296    function toNextTag(iter) {
1297      for (;;) {
1298        xmlTagStart.lastIndex = iter.ch;
1299        var found = xmlTagStart.exec(iter.text);
1300        if (!found) { if (nextLine(iter)) continue; else return; }
1301        if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }
1302        iter.ch = found.index + found[0].length;
1303        return found;
1304      }
1305    }
1306    function toPrevTag(iter) {
1307      for (;;) {
1308        var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1;
1309        if (gt == -1) { if (prevLine(iter)) continue; else return; }
1310        if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }
1311        var lastSlash = iter.text.lastIndexOf("/", gt);
1312        var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt));
1313        iter.ch = gt + 1;
1314        return selfClose ? "selfClose" : "regular";
1315      }
1316    }
1317  
1318    function findMatchingClose(iter, tag) {
1319      var stack = [];
1320      for (;;) {
1321        var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);
1322        if (!next || !(end = toTagEnd(iter))) return;
1323        if (end == "selfClose") continue;
1324        if (next[1]) { // closing tag
1325          for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {
1326            stack.length = i;
1327            break;
1328          }
1329          if (i < 0 && (!tag || tag == next[2])) return {
1330            tag: next[2],
1331            from: Pos(startLine, startCh),
1332            to: Pos(iter.line, iter.ch)
1333          };
1334        } else { // opening tag
1335          stack.push(next[2]);
1336        }
1337      }
1338    }
1339    function findMatchingOpen(iter, tag) {
1340      var stack = [];
1341      for (;;) {
1342        var prev = toPrevTag(iter);
1343        if (!prev) return;
1344        if (prev == "selfClose") { toTagStart(iter); continue; }
1345        var endLine = iter.line, endCh = iter.ch;
1346        var start = toTagStart(iter);
1347        if (!start) return;
1348        if (start[1]) { // closing tag
1349          stack.push(start[2]);
1350        } else { // opening tag
1351          for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {
1352            stack.length = i;
1353            break;
1354          }
1355          if (i < 0 && (!tag || tag == start[2])) return {
1356            tag: start[2],
1357            from: Pos(iter.line, iter.ch),
1358            to: Pos(endLine, endCh)
1359          };
1360        }
1361      }
1362    }
1363  
1364    CodeMirror.registerHelper("fold", "xml", function(cm, start) {
1365      var iter = new Iter(cm, start.line, 0);
1366      for (;;) {
1367        var openTag = toNextTag(iter)
1368        if (!openTag || iter.line != start.line) return
1369        var end = toTagEnd(iter)
1370        if (!end) return
1371        if (!openTag[1] && end != "selfClose") {
1372          var startPos = Pos(iter.line, iter.ch);
1373          var endPos = findMatchingClose(iter, openTag[2]);
1374          return endPos && cmp(endPos.from, startPos) > 0 ? {from: startPos, to: endPos.from} : null
1375        }
1376      }
1377    });
1378    CodeMirror.findMatchingTag = function(cm, pos, range) {
1379      var iter = new Iter(cm, pos.line, pos.ch, range);
1380      if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return;
1381      var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);
1382      var start = end && toTagStart(iter);
1383      if (!end || !start || cmp(iter, pos) > 0) return;
1384      var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};
1385      if (end == "selfClose") return {open: here, close: null, at: "open"};
1386  
1387      if (start[1]) { // closing tag
1388        return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"};
1389      } else { // opening tag
1390        iter = new Iter(cm, to.line, to.ch, range);
1391        return {open: here, close: findMatchingClose(iter, start[2]), at: "open"};
1392      }
1393    };
1394  
1395    CodeMirror.findEnclosingTag = function(cm, pos, range, tag) {
1396      var iter = new Iter(cm, pos.line, pos.ch, range);
1397      for (;;) {
1398        var open = findMatchingOpen(iter, tag);
1399        if (!open) break;
1400        var forward = new Iter(cm, pos.line, pos.ch, range);
1401        var close = findMatchingClose(forward, open.tag);
1402        if (close) return {open: open, close: close};
1403      }
1404    };
1405  
1406    // Used by addon/edit/closetag.js
1407    CodeMirror.scanForClosingTag = function(cm, pos, name, end) {
1408      var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);
1409      return findMatchingClose(iter, name);
1410    };
1411  });
1412   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1413  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1414  
1415  (function(mod) {
1416    if (typeof exports == "object" && typeof module == "object") // CommonJS
1417      mod(require("../../lib/codemirror"), "cjs");
1418    else if (typeof define == "function" && define.amd) // AMD
1419      define(["../../lib/codemirror"], function(CM) { mod(CM, "amd"); });
1420    else // Plain browser env
1421      mod(CodeMirror, "plain");
1422  })(function(CodeMirror, env) {
1423    if (!CodeMirror.modeURL) CodeMirror.modeURL = "../mode/%N/%N.js";
1424  
1425    var loading = {};
1426    function splitCallback(cont, n) {
1427      var countDown = n;
1428      return function() { if (--countDown == 0) cont(); };
1429    }
1430    function ensureDeps(mode, cont, options) {
1431      var modeObj = CodeMirror.modes[mode], deps = modeObj && modeObj.dependencies;
1432      if (!deps) return cont();
1433      var missing = [];
1434      for (var i = 0; i < deps.length; ++i) {
1435        if (!CodeMirror.modes.hasOwnProperty(deps[i]))
1436          missing.push(deps[i]);
1437      }
1438      if (!missing.length) return cont();
1439      var split = splitCallback(cont, missing.length);
1440      for (var i = 0; i < missing.length; ++i)
1441        CodeMirror.requireMode(missing[i], split, options);
1442    }
1443  
1444    CodeMirror.requireMode = function(mode, cont, options) {
1445      if (typeof mode != "string") mode = mode.name;
1446      if (CodeMirror.modes.hasOwnProperty(mode)) return ensureDeps(mode, cont, options);
1447      if (loading.hasOwnProperty(mode)) return loading[mode].push(cont);
1448  
1449      var file = options && options.path ? options.path(mode) : CodeMirror.modeURL.replace(/%N/g, mode);
1450      if (options && options.loadMode) {
1451        options.loadMode(file, function() { ensureDeps(mode, cont, options) })
1452      } else if (env == "plain") {
1453        var script = document.createElement("script");
1454        script.src = file;
1455        var others = document.getElementsByTagName("script")[0];
1456        var list = loading[mode] = [cont];
1457        CodeMirror.on(script, "load", function() {
1458          ensureDeps(mode, function() {
1459            for (var i = 0; i < list.length; ++i) list[i]();
1460          }, options);
1461        });
1462        others.parentNode.insertBefore(script, others);
1463      } else if (env == "cjs") {
1464        require(file);
1465        cont();
1466      } else if (env == "amd") {
1467        requirejs([file], cont);
1468      }
1469    };
1470  
1471    CodeMirror.autoLoadMode = function(instance, mode, options) {
1472      if (!CodeMirror.modes.hasOwnProperty(mode))
1473        CodeMirror.requireMode(mode, function() {
1474          instance.setOption("mode", instance.getOption("mode"));
1475        }, options);
1476    };
1477  });
1478   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1479  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1480  
1481  (function(mod) {
1482    if (typeof exports == "object" && typeof module == "object") // CommonJS
1483      mod(require("../../lib/codemirror"));
1484    else if (typeof define == "function" && define.amd) // AMD
1485      define(["../../lib/codemirror"], mod);
1486    else // Plain browser env
1487      mod(CodeMirror);
1488  })(function(CodeMirror) {
1489  "use strict";
1490  
1491  CodeMirror.multiplexingMode = function(outer /*, others */) {
1492    // Others should be {open, close, mode [, delimStyle] [, innerStyle] [, parseDelimiters]} objects
1493    var others = Array.prototype.slice.call(arguments, 1);
1494  
1495    function indexOf(string, pattern, from, returnEnd) {
1496      if (typeof pattern == "string") {
1497        var found = string.indexOf(pattern, from);
1498        return returnEnd && found > -1 ? found + pattern.length : found;
1499      }
1500      var m = pattern.exec(from ? string.slice(from) : string);
1501      return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
1502    }
1503  
1504    return {
1505      startState: function() {
1506        return {
1507          outer: CodeMirror.startState(outer),
1508          innerActive: null,
1509          inner: null,
1510          startingInner: false
1511        };
1512      },
1513  
1514      copyState: function(state) {
1515        return {
1516          outer: CodeMirror.copyState(outer, state.outer),
1517          innerActive: state.innerActive,
1518          inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner),
1519          startingInner: state.startingInner
1520        };
1521      },
1522  
1523      token: function(stream, state) {
1524        if (!state.innerActive) {
1525          var cutOff = Infinity, oldContent = stream.string;
1526          for (var i = 0; i < others.length; ++i) {
1527            var other = others[i];
1528            var found = indexOf(oldContent, other.open, stream.pos);
1529            if (found == stream.pos) {
1530              if (!other.parseDelimiters) stream.match(other.open);
1531              state.startingInner = !!other.parseDelimiters
1532              state.innerActive = other;
1533  
1534              // Get the outer indent, making sure to handle CodeMirror.Pass
1535              var outerIndent = 0;
1536              if (outer.indent) {
1537                var possibleOuterIndent = outer.indent(state.outer, "", "");
1538                if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent;
1539              }
1540  
1541              state.inner = CodeMirror.startState(other.mode, outerIndent);
1542              return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
1543            } else if (found != -1 && found < cutOff) {
1544              cutOff = found;
1545            }
1546          }
1547          if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
1548          var outerToken = outer.token(stream, state.outer);
1549          if (cutOff != Infinity) stream.string = oldContent;
1550          return outerToken;
1551        } else {
1552          var curInner = state.innerActive, oldContent = stream.string;
1553          if (!curInner.close && stream.sol()) {
1554            state.innerActive = state.inner = null;
1555            return this.token(stream, state);
1556          }
1557          var found = curInner.close && !state.startingInner ?
1558              indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
1559          if (found == stream.pos && !curInner.parseDelimiters) {
1560            stream.match(curInner.close);
1561            state.innerActive = state.inner = null;
1562            return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
1563          }
1564          if (found > -1) stream.string = oldContent.slice(0, found);
1565          var innerToken = curInner.mode.token(stream, state.inner);
1566          if (found > -1) stream.string = oldContent;
1567          else if (stream.pos > stream.start) state.startingInner = false
1568  
1569          if (found == stream.pos && curInner.parseDelimiters)
1570            state.innerActive = state.inner = null;
1571  
1572          if (curInner.innerStyle) {
1573            if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
1574            else innerToken = curInner.innerStyle;
1575          }
1576  
1577          return innerToken;
1578        }
1579      },
1580  
1581      indent: function(state, textAfter, line) {
1582        var mode = state.innerActive ? state.innerActive.mode : outer;
1583        if (!mode.indent) return CodeMirror.Pass;
1584        return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line);
1585      },
1586  
1587      blankLine: function(state) {
1588        var mode = state.innerActive ? state.innerActive.mode : outer;
1589        if (mode.blankLine) {
1590          mode.blankLine(state.innerActive ? state.inner : state.outer);
1591        }
1592        if (!state.innerActive) {
1593          for (var i = 0; i < others.length; ++i) {
1594            var other = others[i];
1595            if (other.open === "\n") {
1596              state.innerActive = other;
1597              state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "", "") : 0);
1598            }
1599          }
1600        } else if (state.innerActive.close === "\n") {
1601          state.innerActive = state.inner = null;
1602        }
1603      },
1604  
1605      electricChars: outer.electricChars,
1606  
1607      innerMode: function(state) {
1608        return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
1609      }
1610    };
1611  };
1612  
1613  });
1614   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1615  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1616  
1617  (function(mod) {
1618    if (typeof exports == "object" && typeof module == "object") // CommonJS
1619      mod(require("../../lib/codemirror"));
1620    else if (typeof define == "function" && define.amd) // AMD
1621      define(["../../lib/codemirror"], mod);
1622    else // Plain browser env
1623      mod(CodeMirror);
1624  })(function(CodeMirror) {
1625    "use strict";
1626  
1627    CodeMirror.defineExtension("annotateScrollbar", function(options) {
1628      if (typeof options == "string") options = {className: options};
1629      return new Annotation(this, options);
1630    });
1631  
1632    CodeMirror.defineOption("scrollButtonHeight", 0);
1633  
1634    function Annotation(cm, options) {
1635      this.cm = cm;
1636      this.options = options;
1637      this.buttonHeight = options.scrollButtonHeight || cm.getOption("scrollButtonHeight");
1638      this.annotations = [];
1639      this.doRedraw = this.doUpdate = null;
1640      this.div = cm.getWrapperElement().appendChild(document.createElement("div"));
1641      this.div.style.cssText = "position: absolute; right: 0; top: 0; z-index: 7; pointer-events: none";
1642      this.computeScale();
1643  
1644      function scheduleRedraw(delay) {
1645        clearTimeout(self.doRedraw);
1646        self.doRedraw = setTimeout(function() { self.redraw(); }, delay);
1647      }
1648  
1649      var self = this;
1650      cm.on("refresh", this.resizeHandler = function() {
1651        clearTimeout(self.doUpdate);
1652        self.doUpdate = setTimeout(function() {
1653          if (self.computeScale()) scheduleRedraw(20);
1654        }, 100);
1655      });
1656      cm.on("markerAdded", this.resizeHandler);
1657      cm.on("markerCleared", this.resizeHandler);
1658      if (options.listenForChanges !== false)
1659        cm.on("changes", this.changeHandler = function() {
1660          scheduleRedraw(250);
1661        });
1662    }
1663  
1664    Annotation.prototype.computeScale = function() {
1665      var cm = this.cm;
1666      var hScale = (cm.getWrapperElement().clientHeight - cm.display.barHeight - this.buttonHeight * 2) /
1667        cm.getScrollerElement().scrollHeight
1668      if (hScale != this.hScale) {
1669        this.hScale = hScale;
1670        return true;
1671      }
1672    };
1673  
1674    Annotation.prototype.update = function(annotations) {
1675      this.annotations = annotations;
1676      this.redraw();
1677    };
1678  
1679    Annotation.prototype.redraw = function(compute) {
1680      if (compute !== false) this.computeScale();
1681      var cm = this.cm, hScale = this.hScale;
1682  
1683      var frag = document.createDocumentFragment(), anns = this.annotations;
1684  
1685      var wrapping = cm.getOption("lineWrapping");
1686      var singleLineH = wrapping && cm.defaultTextHeight() * 1.5;
1687      var curLine = null, curLineObj = null;
1688  
1689      function getY(pos, top) {
1690        if (curLine != pos.line) {
1691          curLine = pos.line
1692          curLineObj = cm.getLineHandle(pos.line)
1693          var visual = cm.getLineHandleVisualStart(curLineObj)
1694          if (visual != curLineObj) {
1695            curLine = cm.getLineNumber(visual)
1696            curLineObj = visual
1697          }
1698        }
1699        if ((curLineObj.widgets && curLineObj.widgets.length) ||
1700            (wrapping && curLineObj.height > singleLineH))
1701          return cm.charCoords(pos, "local")[top ? "top" : "bottom"];
1702        var topY = cm.heightAtLine(curLineObj, "local");
1703        return topY + (top ? 0 : curLineObj.height);
1704      }
1705  
1706      var lastLine = cm.lastLine()
1707      if (cm.display.barWidth) for (var i = 0, nextTop; i < anns.length; i++) {
1708        var ann = anns[i];
1709        if (ann.to.line > lastLine) continue;
1710        var top = nextTop || getY(ann.from, true) * hScale;
1711        var bottom = getY(ann.to, false) * hScale;
1712        while (i < anns.length - 1) {
1713          if (anns[i + 1].to.line > lastLine) break;
1714          nextTop = getY(anns[i + 1].from, true) * hScale;
1715          if (nextTop > bottom + .9) break;
1716          ann = anns[++i];
1717          bottom = getY(ann.to, false) * hScale;
1718        }
1719        if (bottom == top) continue;
1720        var height = Math.max(bottom - top, 3);
1721  
1722        var elt = frag.appendChild(document.createElement("div"));
1723        elt.style.cssText = "position: absolute; right: 0px; width: " + Math.max(cm.display.barWidth - 1, 2) + "px; top: "
1724          + (top + this.buttonHeight) + "px; height: " + height + "px";
1725        elt.className = this.options.className;
1726        if (ann.id) {
1727          elt.setAttribute("annotation-id", ann.id);
1728        }
1729      }
1730      this.div.textContent = "";
1731      this.div.appendChild(frag);
1732    };
1733  
1734    Annotation.prototype.clear = function() {
1735      this.cm.off("refresh", this.resizeHandler);
1736      this.cm.off("markerAdded", this.resizeHandler);
1737      this.cm.off("markerCleared", this.resizeHandler);
1738      if (this.changeHandler) this.cm.off("changes", this.changeHandler);
1739      this.div.parentNode.removeChild(this.div);
1740    };
1741  });
1742   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1743  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1744  
1745  (function(mod) {
1746    if (typeof exports == "object" && typeof module == "object") // CommonJS
1747      mod(require("../../lib/codemirror"));
1748    else if (typeof define == "function" && define.amd) // AMD
1749      define(["../../lib/codemirror"], mod);
1750    else // Plain browser env
1751      mod(CodeMirror);
1752  })(function(CodeMirror) {
1753    "use strict";
1754  
1755    function Bar(cls, orientation, scroll) {
1756      this.orientation = orientation;
1757      this.scroll = scroll;
1758      this.screen = this.total = this.size = 1;
1759      this.pos = 0;
1760  
1761      this.node = document.createElement("div");
1762      this.node.className = cls + "-" + orientation;
1763      this.inner = this.node.appendChild(document.createElement("div"));
1764  
1765      var self = this;
1766      CodeMirror.on(this.inner, "mousedown", function(e) {
1767        if (e.which != 1) return;
1768        CodeMirror.e_preventDefault(e);
1769        var axis = self.orientation == "horizontal" ? "pageX" : "pageY";
1770        var start = e[axis], startpos = self.pos;
1771        function done() {
1772          CodeMirror.off(document, "mousemove", move);
1773          CodeMirror.off(document, "mouseup", done);
1774        }
1775        function move(e) {
1776          if (e.which != 1) return done();
1777          self.moveTo(startpos + (e[axis] - start) * (self.total / self.size));
1778        }
1779        CodeMirror.on(document, "mousemove", move);
1780        CodeMirror.on(document, "mouseup", done);
1781      });
1782  
1783      CodeMirror.on(this.node, "click", function(e) {
1784        CodeMirror.e_preventDefault(e);
1785        var innerBox = self.inner.getBoundingClientRect(), where;
1786        if (self.orientation == "horizontal")
1787          where = e.clientX < innerBox.left ? -1 : e.clientX > innerBox.right ? 1 : 0;
1788        else
1789          where = e.clientY < innerBox.top ? -1 : e.clientY > innerBox.bottom ? 1 : 0;
1790        self.moveTo(self.pos + where * self.screen);
1791      });
1792  
1793      function onWheel(e) {
1794        var moved = CodeMirror.wheelEventPixels(e)[self.orientation == "horizontal" ? "x" : "y"];
1795        var oldPos = self.pos;
1796        self.moveTo(self.pos + moved);
1797        if (self.pos != oldPos) CodeMirror.e_preventDefault(e);
1798      }
1799      CodeMirror.on(this.node, "mousewheel", onWheel);
1800      CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
1801    }
1802  
1803    Bar.prototype.setPos = function(pos, force) {
1804      if (pos < 0) pos = 0;
1805      if (pos > this.total - this.screen) pos = this.total - this.screen;
1806      if (!force && pos == this.pos) return false;
1807      this.pos = pos;
1808      this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
1809        (pos * (this.size / this.total)) + "px";
1810      return true
1811    };
1812  
1813    Bar.prototype.moveTo = function(pos) {
1814      if (this.setPos(pos)) this.scroll(pos, this.orientation);
1815    }
1816  
1817    var minButtonSize = 10;
1818  
1819    Bar.prototype.update = function(scrollSize, clientSize, barSize) {
1820      var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
1821      if (sizeChanged) {
1822        this.screen = clientSize;
1823        this.total = scrollSize;
1824        this.size = barSize;
1825      }
1826  
1827      var buttonSize = this.screen * (this.size / this.total);
1828      if (buttonSize < minButtonSize) {
1829        this.size -= minButtonSize - buttonSize;
1830        buttonSize = minButtonSize;
1831      }
1832      this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
1833        buttonSize + "px";
1834      this.setPos(this.pos, sizeChanged);
1835    };
1836  
1837    function SimpleScrollbars(cls, place, scroll) {
1838      this.addClass = cls;
1839      this.horiz = new Bar(cls, "horizontal", scroll);
1840      place(this.horiz.node);
1841      this.vert = new Bar(cls, "vertical", scroll);
1842      place(this.vert.node);
1843      this.width = null;
1844    }
1845  
1846    SimpleScrollbars.prototype.update = function(measure) {
1847      if (this.width == null) {
1848        var style = window.getComputedStyle ? window.getComputedStyle(this.horiz.node) : this.horiz.node.currentStyle;
1849        if (style) this.width = parseInt(style.height);
1850      }
1851      var width = this.width || 0;
1852  
1853      var needsH = measure.scrollWidth > measure.clientWidth + 1;
1854      var needsV = measure.scrollHeight > measure.clientHeight + 1;
1855      this.vert.node.style.display = needsV ? "block" : "none";
1856      this.horiz.node.style.display = needsH ? "block" : "none";
1857  
1858      if (needsV) {
1859        this.vert.update(measure.scrollHeight, measure.clientHeight,
1860                         measure.viewHeight - (needsH ? width : 0));
1861        this.vert.node.style.bottom = needsH ? width + "px" : "0";
1862      }
1863      if (needsH) {
1864        this.horiz.update(measure.scrollWidth, measure.clientWidth,
1865                          measure.viewWidth - (needsV ? width : 0) - measure.barLeft);
1866        this.horiz.node.style.right = needsV ? width + "px" : "0";
1867        this.horiz.node.style.left = measure.barLeft + "px";
1868      }
1869  
1870      return {right: needsV ? width : 0, bottom: needsH ? width : 0};
1871    };
1872  
1873    SimpleScrollbars.prototype.setScrollTop = function(pos) {
1874      this.vert.setPos(pos);
1875    };
1876  
1877    SimpleScrollbars.prototype.setScrollLeft = function(pos) {
1878      this.horiz.setPos(pos);
1879    };
1880  
1881    SimpleScrollbars.prototype.clear = function() {
1882      var parent = this.horiz.node.parentNode;
1883      parent.removeChild(this.horiz.node);
1884      parent.removeChild(this.vert.node);
1885    };
1886  
1887    CodeMirror.scrollbarModel.simple = function(place, scroll) {
1888      return new SimpleScrollbars("CodeMirror-simplescroll", place, scroll);
1889    };
1890    CodeMirror.scrollbarModel.overlay = function(place, scroll) {
1891      return new SimpleScrollbars("CodeMirror-overlayscroll", place, scroll);
1892    };
1893  });
1894   // CodeMirror, copyright (c) by Marijn Haverbeke and others
1895  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
1896  
1897  // Highlighting text that matches the selection
1898  //
1899  // Defines an option highlightSelectionMatches, which, when enabled,
1900  // will style strings that match the selection throughout the
1901  // document.
1902  //
1903  // The option can be set to true to simply enable it, or to a
1904  // {minChars, style, wordsOnly, showToken, delay} object to explicitly
1905  // configure it. minChars is the minimum amount of characters that should be
1906  // selected for the behavior to occur, and style is the token style to
1907  // apply to the matches. This will be prefixed by "cm-" to create an
1908  // actual CSS class name. If wordsOnly is enabled, the matches will be
1909  // highlighted only if the selected text is a word. showToken, when enabled,
1910  // will cause the current token to be highlighted when nothing is selected.
1911  // delay is used to specify how much time to wait, in milliseconds, before
1912  // highlighting the matches. If annotateScrollbar is enabled, the occurrences
1913  // will be highlighted on the scrollbar via the matchesonscrollbar addon.
1914  
1915  (function(mod) {
1916    if (typeof exports == "object" && typeof module == "object") // CommonJS
1917      mod(require("../../lib/codemirror"), require("./matchesonscrollbar"));
1918    else if (typeof define == "function" && define.amd) // AMD
1919      define(["../../lib/codemirror", "./matchesonscrollbar"], mod);
1920    else // Plain browser env
1921      mod(CodeMirror);
1922  })(function(CodeMirror) {
1923    "use strict";
1924  
1925    var defaults = {
1926      style: "matchhighlight",
1927      minChars: 2,
1928      delay: 100,
1929      wordsOnly: false,
1930      annotateScrollbar: false,
1931      showToken: false,
1932      trim: true
1933    }
1934  
1935    function State(options) {
1936      this.options = {}
1937      for (var name in defaults)
1938        this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
1939      this.overlay = this.timeout = null;
1940      this.matchesonscroll = null;
1941      this.active = false;
1942    }
1943  
1944    CodeMirror.defineOption("highlightSelectionMatches", false, function(cm, val, old) {
1945      if (old && old != CodeMirror.Init) {
1946        removeOverlay(cm);
1947        clearTimeout(cm.state.matchHighlighter.timeout);
1948        cm.state.matchHighlighter = null;
1949        cm.off("cursorActivity", cursorActivity);
1950        cm.off("focus", onFocus)
1951      }
1952      if (val) {
1953        var state = cm.state.matchHighlighter = new State(val);
1954        if (cm.hasFocus()) {
1955          state.active = true
1956          highlightMatches(cm)
1957        } else {
1958          cm.on("focus", onFocus)
1959        }
1960        cm.on("cursorActivity", cursorActivity);
1961      }
1962    });
1963  
1964    function cursorActivity(cm) {
1965      var state = cm.state.matchHighlighter;
1966      if (state.active || cm.hasFocus()) scheduleHighlight(cm, state)
1967    }
1968  
1969    function onFocus(cm) {
1970      var state = cm.state.matchHighlighter
1971      if (!state.active) {
1972        state.active = true
1973        scheduleHighlight(cm, state)
1974      }
1975    }
1976  
1977    function scheduleHighlight(cm, state) {
1978      clearTimeout(state.timeout);
1979      state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
1980    }
1981  
1982    function addOverlay(cm, query, hasBoundary, style) {
1983      var state = cm.state.matchHighlighter;
1984      cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
1985      if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
1986        var searchFor = hasBoundary ? new RegExp((/\w/.test(query.charAt(0)) ? "\\b" : "") +
1987                                                 query.replace(/[\\\[.+*?(){|^$]/g, "\\$&") +
1988                                                 (/\w/.test(query.charAt(query.length - 1)) ? "\\b" : "")) : query;
1989        state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, false,
1990          {className: "CodeMirror-selection-highlight-scrollbar"});
1991      }
1992    }
1993  
1994    function removeOverlay(cm) {
1995      var state = cm.state.matchHighlighter;
1996      if (state.overlay) {
1997        cm.removeOverlay(state.overlay);
1998        state.overlay = null;
1999        if (state.matchesonscroll) {
2000          state.matchesonscroll.clear();
2001          state.matchesonscroll = null;
2002        }
2003      }
2004    }
2005  
2006    function highlightMatches(cm) {
2007      cm.operation(function() {
2008        var state = cm.state.matchHighlighter;
2009        removeOverlay(cm);
2010        if (!cm.somethingSelected() && state.options.showToken) {
2011          var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
2012          var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
2013          while (start && re.test(line.charAt(start - 1))) --start;
2014          while (end < line.length && re.test(line.charAt(end))) ++end;
2015          if (start < end)
2016            addOverlay(cm, line.slice(start, end), re, state.options.style);
2017          return;
2018        }
2019        var from = cm.getCursor("from"), to = cm.getCursor("to");
2020        if (from.line != to.line) return;
2021        if (state.options.wordsOnly && !isWord(cm, from, to)) return;
2022        var selection = cm.getRange(from, to)
2023        if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
2024        if (selection.length >= state.options.minChars)
2025          addOverlay(cm, selection, false, state.options.style);
2026      });
2027    }
2028  
2029    function isWord(cm, from, to) {
2030      var str = cm.getRange(from, to);
2031      if (str.match(/^\w+$/) !== null) {
2032          if (from.ch > 0) {
2033              var pos = {line: from.line, ch: from.ch - 1};
2034              var chr = cm.getRange(pos, from);
2035              if (chr.match(/\W/) === null) return false;
2036          }
2037          if (to.ch < cm.getLine(from.line).length) {
2038              var pos = {line: to.line, ch: to.ch + 1};
2039              var chr = cm.getRange(to, pos);
2040              if (chr.match(/\W/) === null) return false;
2041          }
2042          return true;
2043      } else return false;
2044    }
2045  
2046    function boundariesAround(stream, re) {
2047      return (!stream.start || !re.test(stream.string.charAt(stream.start - 1))) &&
2048        (stream.pos == stream.string.length || !re.test(stream.string.charAt(stream.pos)));
2049    }
2050  
2051    function makeOverlay(query, hasBoundary, style) {
2052      return {token: function(stream) {
2053        if (stream.match(query) &&
2054            (!hasBoundary || boundariesAround(stream, hasBoundary)))
2055          return style;
2056        stream.next();
2057        stream.skipTo(query.charAt(0)) || stream.skipToEnd();
2058      }};
2059    }
2060  });
2061   // CodeMirror, copyright (c) by Marijn Haverbeke and others
2062  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
2063  
2064  (function(mod) {
2065    if (typeof exports == "object" && typeof module == "object") // CommonJS
2066      mod(require("../../lib/codemirror"), require("./searchcursor"), require("../scroll/annotatescrollbar"));
2067    else if (typeof define == "function" && define.amd) // AMD
2068      define(["../../lib/codemirror", "./searchcursor", "../scroll/annotatescrollbar"], mod);
2069    else // Plain browser env
2070      mod(CodeMirror);
2071  })(function(CodeMirror) {
2072    "use strict";
2073  
2074    CodeMirror.defineExtension("showMatchesOnScrollbar", function(query, caseFold, options) {
2075      if (typeof options == "string") options = {className: options};
2076      if (!options) options = {};
2077      return new SearchAnnotation(this, query, caseFold, options);
2078    });
2079  
2080    function SearchAnnotation(cm, query, caseFold, options) {
2081      this.cm = cm;
2082      this.options = options;
2083      var annotateOptions = {listenForChanges: false};
2084      for (var prop in options) annotateOptions[prop] = options[prop];
2085      if (!annotateOptions.className) annotateOptions.className = "CodeMirror-search-match";
2086      this.annotation = cm.annotateScrollbar(annotateOptions);
2087      this.query = query;
2088      this.caseFold = caseFold;
2089      this.gap = {from: cm.firstLine(), to: cm.lastLine() + 1};
2090      this.matches = [];
2091      this.update = null;
2092  
2093      this.findMatches();
2094      this.annotation.update(this.matches);
2095  
2096      var self = this;
2097      cm.on("change", this.changeHandler = function(_cm, change) { self.onChange(change); });
2098    }
2099  
2100    var MAX_MATCHES = 1000;
2101  
2102    SearchAnnotation.prototype.findMatches = function() {
2103      if (!this.gap) return;
2104      for (var i = 0; i < this.matches.length; i++) {
2105        var match = this.matches[i];
2106        if (match.from.line >= this.gap.to) break;
2107        if (match.to.line >= this.gap.from) this.matches.splice(i--, 1);
2108      }
2109      var cursor = this.cm.getSearchCursor(this.query, CodeMirror.Pos(this.gap.from, 0), {caseFold: this.caseFold, multiline: this.options.multiline});
2110      var maxMatches = this.options && this.options.maxMatches || MAX_MATCHES;
2111      while (cursor.findNext()) {
2112        var match = {from: cursor.from(), to: cursor.to()};
2113        if (match.from.line >= this.gap.to) break;
2114        this.matches.splice(i++, 0, match);
2115        if (this.matches.length > maxMatches) break;
2116      }
2117      this.gap = null;
2118    };
2119  
2120    function offsetLine(line, changeStart, sizeChange) {
2121      if (line <= changeStart) return line;
2122      return Math.max(changeStart, line + sizeChange);
2123    }
2124  
2125    SearchAnnotation.prototype.onChange = function(change) {
2126      var startLine = change.from.line;
2127      var endLine = CodeMirror.changeEnd(change).line;
2128      var sizeChange = endLine - change.to.line;
2129      if (this.gap) {
2130        this.gap.from = Math.min(offsetLine(this.gap.from, startLine, sizeChange), change.from.line);
2131        this.gap.to = Math.max(offsetLine(this.gap.to, startLine, sizeChange), change.from.line);
2132      } else {
2133        this.gap = {from: change.from.line, to: endLine + 1};
2134      }
2135  
2136      if (sizeChange) for (var i = 0; i < this.matches.length; i++) {
2137        var match = this.matches[i];
2138        var newFrom = offsetLine(match.from.line, startLine, sizeChange);
2139        if (newFrom != match.from.line) match.from = CodeMirror.Pos(newFrom, match.from.ch);
2140        var newTo = offsetLine(match.to.line, startLine, sizeChange);
2141        if (newTo != match.to.line) match.to = CodeMirror.Pos(newTo, match.to.ch);
2142      }
2143      clearTimeout(this.update);
2144      var self = this;
2145      this.update = setTimeout(function() { self.updateAfterChange(); }, 250);
2146    };
2147  
2148    SearchAnnotation.prototype.updateAfterChange = function() {
2149      this.findMatches();
2150      this.annotation.update(this.matches);
2151    };
2152  
2153    SearchAnnotation.prototype.clear = function() {
2154      this.cm.off("change", this.changeHandler);
2155      this.annotation.clear();
2156    };
2157  });
2158   // CodeMirror, copyright (c) by Marijn Haverbeke and others
2159  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
2160  
2161  // Define search commands. Depends on dialog.js or another
2162  // implementation of the openDialog method.
2163  
2164  // Replace works a little oddly -- it will do the replace on the next
2165  // Ctrl-G (or whatever is bound to findNext) press. You prevent a
2166  // replace by making sure the match is no longer selected when hitting
2167  // Ctrl-G.
2168  
2169  (function(mod) {
2170    if (typeof exports == "object" && typeof module == "object") // CommonJS
2171      mod(require("../../lib/codemirror"), require("./searchcursor"), require("../dialog/dialog"));
2172    else if (typeof define == "function" && define.amd) // AMD
2173      define(["../../lib/codemirror", "./searchcursor", "../dialog/dialog"], mod);
2174    else // Plain browser env
2175      mod(CodeMirror);
2176  })(function(CodeMirror) {
2177    "use strict";
2178  
2179    // default search panel location
2180    CodeMirror.defineOption("search", {bottom: false});
2181  
2182    function searchOverlay(query, caseInsensitive) {
2183      if (typeof query == "string")
2184        query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), caseInsensitive ? "gi" : "g");
2185      else if (!query.global)
2186        query = new RegExp(query.source, query.ignoreCase ? "gi" : "g");
2187  
2188      return {token: function(stream) {
2189        query.lastIndex = stream.pos;
2190        var match = query.exec(stream.string);
2191        if (match && match.index == stream.pos) {
2192          stream.pos += match[0].length || 1;
2193          return "searching";
2194        } else if (match) {
2195          stream.pos = match.index;
2196        } else {
2197          stream.skipToEnd();
2198        }
2199      }};
2200    }
2201  
2202    function SearchState() {
2203      this.posFrom = this.posTo = this.lastQuery = this.query = null;
2204      this.overlay = null;
2205    }
2206  
2207    function getSearchState(cm) {
2208      return cm.state.search || (cm.state.search = new SearchState());
2209    }
2210  
2211    function queryCaseInsensitive(query) {
2212      return typeof query == "string" && query == query.toLowerCase();
2213    }
2214  
2215    function getSearchCursor(cm, query, pos) {
2216      // Heuristic: if the query string is all lowercase, do a case insensitive search.
2217      return cm.getSearchCursor(query, pos, {caseFold: queryCaseInsensitive(query), multiline: true});
2218    }
2219  
2220    function persistentDialog(cm, text, deflt, onEnter, onKeyDown) {
2221      cm.openDialog(text, onEnter, {
2222        value: deflt,
2223        selectValueOnOpen: true,
2224        closeOnEnter: false,
2225        onClose: function() { clearSearch(cm); },
2226        onKeyDown: onKeyDown,
2227        bottom: cm.options.search.bottom
2228      });
2229    }
2230  
2231    function dialog(cm, text, shortText, deflt, f) {
2232      if (cm.openDialog) cm.openDialog(text, f, {value: deflt, selectValueOnOpen: true, bottom: cm.options.search.bottom});
2233      else f(prompt(shortText, deflt));
2234    }
2235  
2236    function confirmDialog(cm, text, shortText, fs) {
2237      if (cm.openConfirm) cm.openConfirm(text, fs);
2238      else if (confirm(shortText)) fs[0]();
2239    }
2240  
2241    function parseString(string) {
2242      return string.replace(/\\([nrt\\])/g, function(match, ch) {
2243        if (ch == "n") return "\n"
2244        if (ch == "r") return "\r"
2245        if (ch == "t") return "\t"
2246        if (ch == "\\") return "\\"
2247        return match
2248      })
2249    }
2250  
2251    function parseQuery(query) {
2252      var isRE = query.match(/^\/(.*)\/([a-z]*)$/);
2253      if (isRE) {
2254        try { query = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i"); }
2255        catch(e) {} // Not a regular expression after all, do a string search
2256      } else {
2257        query = parseString(query)
2258      }
2259      if (typeof query == "string" ? query == "" : query.test(""))
2260        query = /x^/;
2261      return query;
2262    }
2263  
2264    function startSearch(cm, state, query) {
2265      state.queryText = query;
2266      state.query = parseQuery(query);
2267      cm.removeOverlay(state.overlay, queryCaseInsensitive(state.query));
2268      state.overlay = searchOverlay(state.query, queryCaseInsensitive(state.query));
2269      cm.addOverlay(state.overlay);
2270      if (cm.showMatchesOnScrollbar) {
2271        if (state.annotate) { state.annotate.clear(); state.annotate = null; }
2272        state.annotate = cm.showMatchesOnScrollbar(state.query, queryCaseInsensitive(state.query));
2273      }
2274    }
2275  
2276    function doSearch(cm, rev, persistent, immediate) {
2277      var state = getSearchState(cm);
2278      if (state.query) return findNext(cm, rev);
2279      var q = cm.getSelection() || state.lastQuery;
2280      if (q instanceof RegExp && q.source == "x^") q = null
2281      if (persistent && cm.openDialog) {
2282        var hiding = null
2283        var searchNext = function(query, event) {
2284          CodeMirror.e_stop(event);
2285          if (!query) return;
2286          if (query != state.queryText) {
2287            startSearch(cm, state, query);
2288            state.posFrom = state.posTo = cm.getCursor();
2289          }
2290          if (hiding) hiding.style.opacity = 1
2291          findNext(cm, event.shiftKey, function(_, to) {
2292            var dialog
2293            if (to.line < 3 && document.querySelector &&
2294                (dialog = cm.display.wrapper.querySelector(".CodeMirror-dialog")) &&
2295                dialog.getBoundingClientRect().bottom - 4 > cm.cursorCoords(to, "window").top)
2296              (hiding = dialog).style.opacity = .4
2297          })
2298        };
2299        persistentDialog(cm, getQueryDialog(cm), q, searchNext, function(event, query) {
2300          var keyName = CodeMirror.keyName(event)
2301          var extra = cm.getOption('extraKeys'), cmd = (extra && extra[keyName]) || CodeMirror.keyMap[cm.getOption("keyMap")][keyName]
2302          if (cmd == "findNext" || cmd == "findPrev" ||
2303            cmd == "findPersistentNext" || cmd == "findPersistentPrev") {
2304            CodeMirror.e_stop(event);
2305            startSearch(cm, getSearchState(cm), query);
2306            cm.execCommand(cmd);
2307          } else if (cmd == "find" || cmd == "findPersistent") {
2308            CodeMirror.e_stop(event);
2309            searchNext(query, event);
2310          }
2311        });
2312        if (immediate && q) {
2313          startSearch(cm, state, q);
2314          findNext(cm, rev);
2315        }
2316      } else {
2317        dialog(cm, getQueryDialog(cm), "Search for:", q, function(query) {
2318          if (query && !state.query) cm.operation(function() {
2319            startSearch(cm, state, query);
2320            state.posFrom = state.posTo = cm.getCursor();
2321            findNext(cm, rev);
2322          });
2323        });
2324      }
2325    }
2326  
2327    function findNext(cm, rev, callback) {cm.operation(function() {
2328      var state = getSearchState(cm);
2329      var cursor = getSearchCursor(cm, state.query, rev ? state.posFrom : state.posTo);
2330      if (!cursor.find(rev)) {
2331        cursor = getSearchCursor(cm, state.query, rev ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(cm.firstLine(), 0));
2332        if (!cursor.find(rev)) return;
2333      }
2334      cm.setSelection(cursor.from(), cursor.to());
2335      cm.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
2336      state.posFrom = cursor.from(); state.posTo = cursor.to();
2337      if (callback) callback(cursor.from(), cursor.to())
2338    });}
2339  
2340    function clearSearch(cm) {cm.operation(function() {
2341      var state = getSearchState(cm);
2342      state.lastQuery = state.query;
2343      if (!state.query) return;
2344      state.query = state.queryText = null;
2345      cm.removeOverlay(state.overlay);
2346      if (state.annotate) { state.annotate.clear(); state.annotate = null; }
2347    });}
2348  
2349    function el(tag, attrs) {
2350      var element = tag ? document.createElement(tag) : document.createDocumentFragment();
2351      for (var key in attrs) {
2352        element[key] = attrs[key];
2353      }
2354      for (var i = 2; i < arguments.length; i++) {
2355        var child = arguments[i]
2356        element.appendChild(typeof child == "string" ? document.createTextNode(child) : child);
2357      }
2358      return element;
2359    }
2360  
2361    function getQueryDialog(cm)  {
2362      var label = el("label", {className: "CodeMirror-search-label"},
2363                     cm.phrase("Search:"),
2364                     el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field",
2365                                  id: "CodeMirror-search-field"}));
2366      label.setAttribute("for","CodeMirror-search-field");
2367      return el("", null, label, " ",
2368                el("span", {style: "color: #666", className: "CodeMirror-search-hint"},
2369                   cm.phrase("(Use /re/ syntax for regexp search)")));
2370    }
2371    function getReplaceQueryDialog(cm) {
2372      return el("", null, " ",
2373                el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}), " ",
2374                el("span", {style: "color: #666", className: "CodeMirror-search-hint"},
2375                   cm.phrase("(Use /re/ syntax for regexp search)")));
2376    }
2377    function getReplacementQueryDialog(cm) {
2378      return el("", null,
2379                el("span", {className: "CodeMirror-search-label"}, cm.phrase("With:")), " ",
2380                el("input", {type: "text", "style": "width: 10em", className: "CodeMirror-search-field"}));
2381    }
2382    function getDoReplaceConfirm(cm) {
2383      return el("", null,
2384                el("span", {className: "CodeMirror-search-label"}, cm.phrase("Replace?")), " ",
2385                el("button", {}, cm.phrase("Yes")), " ",
2386                el("button", {}, cm.phrase("No")), " ",
2387                el("button", {}, cm.phrase("All")), " ",
2388                el("button", {}, cm.phrase("Stop")));
2389    }
2390  
2391    function replaceAll(cm, query, text) {
2392      cm.operation(function() {
2393        for (var cursor = getSearchCursor(cm, query); cursor.findNext();) {
2394          if (typeof query != "string") {
2395            var match = cm.getRange(cursor.from(), cursor.to()).match(query);
2396            cursor.replace(text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
2397          } else cursor.replace(text);
2398        }
2399      });
2400    }
2401  
2402    function replace(cm, all) {
2403      if (cm.getOption("readOnly")) return;
2404      var query = cm.getSelection() || getSearchState(cm).lastQuery;
2405      var dialogText = all ? cm.phrase("Replace all:") : cm.phrase("Replace:")
2406      var fragment = el("", null,
2407                        el("span", {className: "CodeMirror-search-label"}, dialogText),
2408                        getReplaceQueryDialog(cm))
2409      dialog(cm, fragment, dialogText, query, function(query) {
2410        if (!query) return;
2411        query = parseQuery(query);
2412        dialog(cm, getReplacementQueryDialog(cm), cm.phrase("Replace with:"), "", function(text) {
2413          text = parseString(text)
2414          if (all) {
2415            replaceAll(cm, query, text)
2416          } else {
2417            clearSearch(cm);
2418            var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
2419            var advance = function() {
2420              var start = cursor.from(), match;
2421              if (!(match = cursor.findNext())) {
2422                cursor = getSearchCursor(cm, query);
2423                if (!(match = cursor.findNext()) ||
2424                    (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return;
2425              }
2426              cm.setSelection(cursor.from(), cursor.to());
2427              cm.scrollIntoView({from: cursor.from(), to: cursor.to()});
2428              confirmDialog(cm, getDoReplaceConfirm(cm), cm.phrase("Replace?"),
2429                            [function() {doReplace(match);}, advance,
2430                             function() {replaceAll(cm, query, text)}]);
2431            };
2432            var doReplace = function(match) {
2433              cursor.replace(typeof query == "string" ? text :
2434                             text.replace(/\$(\d)/g, function(_, i) {return match[i];}));
2435              advance();
2436            };
2437            advance();
2438          }
2439        });
2440      });
2441    }
2442  
2443    CodeMirror.commands.find = function(cm) {clearSearch(cm); doSearch(cm);};
2444    CodeMirror.commands.findPersistent = function(cm) {clearSearch(cm); doSearch(cm, false, true);};
2445    CodeMirror.commands.findPersistentNext = function(cm) {doSearch(cm, false, true, true);};
2446    CodeMirror.commands.findPersistentPrev = function(cm) {doSearch(cm, true, true, true);};
2447    CodeMirror.commands.findNext = doSearch;
2448    CodeMirror.commands.findPrev = function(cm) {doSearch(cm, true);};
2449    CodeMirror.commands.clearSearch = clearSearch;
2450    CodeMirror.commands.replace = replace;
2451    CodeMirror.commands.replaceAll = function(cm) {replace(cm, true);};
2452  });
2453   // CodeMirror, copyright (c) by Marijn Haverbeke and others
2454  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
2455  
2456  (function(mod) {
2457    if (typeof exports == "object" && typeof module == "object") // CommonJS
2458      mod(require("../../lib/codemirror"))
2459    else if (typeof define == "function" && define.amd) // AMD
2460      define(["../../lib/codemirror"], mod)
2461    else // Plain browser env
2462      mod(CodeMirror)
2463  })(function(CodeMirror) {
2464    "use strict"
2465    var Pos = CodeMirror.Pos
2466  
2467    function regexpFlags(regexp) {
2468      var flags = regexp.flags
2469      return flags != null ? flags : (regexp.ignoreCase ? "i" : "")
2470        + (regexp.global ? "g" : "")
2471        + (regexp.multiline ? "m" : "")
2472    }
2473  
2474    function ensureFlags(regexp, flags) {
2475      var current = regexpFlags(regexp), target = current
2476      for (var i = 0; i < flags.length; i++) if (target.indexOf(flags.charAt(i)) == -1)
2477        target += flags.charAt(i)
2478      return current == target ? regexp : new RegExp(regexp.source, target)
2479    }
2480  
2481    function maybeMultiline(regexp) {
2482      return /\\s|\\n|\n|\\W|\\D|\[\^/.test(regexp.source)
2483    }
2484  
2485    function searchRegexpForward(doc, regexp, start) {
2486      regexp = ensureFlags(regexp, "g")
2487      for (var line = start.line, ch = start.ch, last = doc.lastLine(); line <= last; line++, ch = 0) {
2488        regexp.lastIndex = ch
2489        var string = doc.getLine(line), match = regexp.exec(string)
2490        if (match)
2491          return {from: Pos(line, match.index),
2492                  to: Pos(line, match.index + match[0].length),
2493                  match: match}
2494      }
2495    }
2496  
2497    function searchRegexpForwardMultiline(doc, regexp, start) {
2498      if (!maybeMultiline(regexp)) return searchRegexpForward(doc, regexp, start)
2499  
2500      regexp = ensureFlags(regexp, "gm")
2501      var string, chunk = 1
2502      for (var line = start.line, last = doc.lastLine(); line <= last;) {
2503        // This grows the search buffer in exponentially-sized chunks
2504        // between matches, so that nearby matches are fast and don't
2505        // require concatenating the whole document (in case we're
2506        // searching for something that has tons of matches), but at the
2507        // same time, the amount of retries is limited.
2508        for (var i = 0; i < chunk; i++) {
2509          if (line > last) break
2510          var curLine = doc.getLine(line++)
2511          string = string == null ? curLine : string + "\n" + curLine
2512        }
2513        chunk = chunk * 2
2514        regexp.lastIndex = start.ch
2515        var match = regexp.exec(string)
2516        if (match) {
2517          var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
2518          var startLine = start.line + before.length - 1, startCh = before[before.length - 1].length
2519          return {from: Pos(startLine, startCh),
2520                  to: Pos(startLine + inside.length - 1,
2521                          inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
2522                  match: match}
2523        }
2524      }
2525    }
2526  
2527    function lastMatchIn(string, regexp, endMargin) {
2528      var match, from = 0
2529      while (from <= string.length) {
2530        regexp.lastIndex = from
2531        var newMatch = regexp.exec(string)
2532        if (!newMatch) break
2533        var end = newMatch.index + newMatch[0].length
2534        if (end > string.length - endMargin) break
2535        if (!match || end > match.index + match[0].length)
2536          match = newMatch
2537        from = newMatch.index + 1
2538      }
2539      return match
2540    }
2541  
2542    function searchRegexpBackward(doc, regexp, start) {
2543      regexp = ensureFlags(regexp, "g")
2544      for (var line = start.line, ch = start.ch, first = doc.firstLine(); line >= first; line--, ch = -1) {
2545        var string = doc.getLine(line)
2546        var match = lastMatchIn(string, regexp, ch < 0 ? 0 : string.length - ch)
2547        if (match)
2548          return {from: Pos(line, match.index),
2549                  to: Pos(line, match.index + match[0].length),
2550                  match: match}
2551      }
2552    }
2553  
2554    function searchRegexpBackwardMultiline(doc, regexp, start) {
2555      if (!maybeMultiline(regexp)) return searchRegexpBackward(doc, regexp, start)
2556      regexp = ensureFlags(regexp, "gm")
2557      var string, chunkSize = 1, endMargin = doc.getLine(start.line).length - start.ch
2558      for (var line = start.line, first = doc.firstLine(); line >= first;) {
2559        for (var i = 0; i < chunkSize && line >= first; i++) {
2560          var curLine = doc.getLine(line--)
2561          string = string == null ? curLine : curLine + "\n" + string
2562        }
2563        chunkSize *= 2
2564  
2565        var match = lastMatchIn(string, regexp, endMargin)
2566        if (match) {
2567          var before = string.slice(0, match.index).split("\n"), inside = match[0].split("\n")
2568          var startLine = line + before.length, startCh = before[before.length - 1].length
2569          return {from: Pos(startLine, startCh),
2570                  to: Pos(startLine + inside.length - 1,
2571                          inside.length == 1 ? startCh + inside[0].length : inside[inside.length - 1].length),
2572                  match: match}
2573        }
2574      }
2575    }
2576  
2577    var doFold, noFold
2578    if (String.prototype.normalize) {
2579      doFold = function(str) { return str.normalize("NFD").toLowerCase() }
2580      noFold = function(str) { return str.normalize("NFD") }
2581    } else {
2582      doFold = function(str) { return str.toLowerCase() }
2583      noFold = function(str) { return str }
2584    }
2585  
2586    // Maps a position in a case-folded line back to a position in the original line
2587    // (compensating for codepoints increasing in number during folding)
2588    function adjustPos(orig, folded, pos, foldFunc) {
2589      if (orig.length == folded.length) return pos
2590      for (var min = 0, max = pos + Math.max(0, orig.length - folded.length);;) {
2591        if (min == max) return min
2592        var mid = (min + max) >> 1
2593        var len = foldFunc(orig.slice(0, mid)).length
2594        if (len == pos) return mid
2595        else if (len > pos) max = mid
2596        else min = mid + 1
2597      }
2598    }
2599  
2600    function searchStringForward(doc, query, start, caseFold) {
2601      // Empty string would match anything and never progress, so we
2602      // define it to match nothing instead.
2603      if (!query.length) return null
2604      var fold = caseFold ? doFold : noFold
2605      var lines = fold(query).split(/\r|\n\r?/)
2606  
2607      search: for (var line = start.line, ch = start.ch, last = doc.lastLine() + 1 - lines.length; line <= last; line++, ch = 0) {
2608        var orig = doc.getLine(line).slice(ch), string = fold(orig)
2609        if (lines.length == 1) {
2610          var found = string.indexOf(lines[0])
2611          if (found == -1) continue search
2612          var start = adjustPos(orig, string, found, fold) + ch
2613          return {from: Pos(line, adjustPos(orig, string, found, fold) + ch),
2614                  to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold) + ch)}
2615        } else {
2616          var cutFrom = string.length - lines[0].length
2617          if (string.slice(cutFrom) != lines[0]) continue search
2618          for (var i = 1; i < lines.length - 1; i++)
2619            if (fold(doc.getLine(line + i)) != lines[i]) continue search
2620          var end = doc.getLine(line + lines.length - 1), endString = fold(end), lastLine = lines[lines.length - 1]
2621          if (endString.slice(0, lastLine.length) != lastLine) continue search
2622          return {from: Pos(line, adjustPos(orig, string, cutFrom, fold) + ch),
2623                  to: Pos(line + lines.length - 1, adjustPos(end, endString, lastLine.length, fold))}
2624        }
2625      }
2626    }
2627  
2628    function searchStringBackward(doc, query, start, caseFold) {
2629      if (!query.length) return null
2630      var fold = caseFold ? doFold : noFold
2631      var lines = fold(query).split(/\r|\n\r?/)
2632  
2633      search: for (var line = start.line, ch = start.ch, first = doc.firstLine() - 1 + lines.length; line >= first; line--, ch = -1) {
2634        var orig = doc.getLine(line)
2635        if (ch > -1) orig = orig.slice(0, ch)
2636        var string = fold(orig)
2637        if (lines.length == 1) {
2638          var found = string.lastIndexOf(lines[0])
2639          if (found == -1) continue search
2640          return {from: Pos(line, adjustPos(orig, string, found, fold)),
2641                  to: Pos(line, adjustPos(orig, string, found + lines[0].length, fold))}
2642        } else {
2643          var lastLine = lines[lines.length - 1]
2644          if (string.slice(0, lastLine.length) != lastLine) continue search
2645          for (var i = 1, start = line - lines.length + 1; i < lines.length - 1; i++)
2646            if (fold(doc.getLine(start + i)) != lines[i]) continue search
2647          var top = doc.getLine(line + 1 - lines.length), topString = fold(top)
2648          if (topString.slice(topString.length - lines[0].length) != lines[0]) continue search
2649          return {from: Pos(line + 1 - lines.length, adjustPos(top, topString, top.length - lines[0].length, fold)),
2650                  to: Pos(line, adjustPos(orig, string, lastLine.length, fold))}
2651        }
2652      }
2653    }
2654  
2655    function SearchCursor(doc, query, pos, options) {
2656      this.atOccurrence = false
2657      this.afterEmptyMatch = false
2658      this.doc = doc
2659      pos = pos ? doc.clipPos(pos) : Pos(0, 0)
2660      this.pos = {from: pos, to: pos}
2661  
2662      var caseFold
2663      if (typeof options == "object") {
2664        caseFold = options.caseFold
2665      } else { // Backwards compat for when caseFold was the 4th argument
2666        caseFold = options
2667        options = null
2668      }
2669  
2670      if (typeof query == "string") {
2671        if (caseFold == null) caseFold = false
2672        this.matches = function(reverse, pos) {
2673          return (reverse ? searchStringBackward : searchStringForward)(doc, query, pos, caseFold)
2674        }
2675      } else {
2676        query = ensureFlags(query, "gm")
2677        if (!options || options.multiline !== false)
2678          this.matches = function(reverse, pos) {
2679            return (reverse ? searchRegexpBackwardMultiline : searchRegexpForwardMultiline)(doc, query, pos)
2680          }
2681        else
2682          this.matches = function(reverse, pos) {
2683            return (reverse ? searchRegexpBackward : searchRegexpForward)(doc, query, pos)
2684          }
2685      }
2686    }
2687  
2688    SearchCursor.prototype = {
2689      findNext: function() {return this.find(false)},
2690      findPrevious: function() {return this.find(true)},
2691  
2692      find: function(reverse) {
2693        var head = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);
2694        if (this.afterEmptyMatch && this.atOccurrence) {
2695          // do not return the same 0 width match twice
2696          head = Pos(head.line, head.ch)
2697          if (reverse) {
2698            head.ch--;
2699            if (head.ch < 0) {
2700              head.line--;
2701              head.ch = (this.doc.getLine(head.line) || "").length;
2702            }
2703          } else {
2704            head.ch++;
2705            if (head.ch > (this.doc.getLine(head.line) || "").length) {
2706              head.ch = 0;
2707              head.line++;
2708            }
2709          }
2710          if (CodeMirror.cmpPos(head, this.doc.clipPos(head)) != 0) {
2711             return this.atOccurrence = false
2712          }
2713        }
2714        var result = this.matches(reverse, head)
2715        this.afterEmptyMatch = result && CodeMirror.cmpPos(result.from, result.to) == 0
2716  
2717        if (result) {
2718          this.pos = result
2719          this.atOccurrence = true
2720          return this.pos.match || true
2721        } else {
2722          var end = Pos(reverse ? this.doc.firstLine() : this.doc.lastLine() + 1, 0)
2723          this.pos = {from: end, to: end}
2724          return this.atOccurrence = false
2725        }
2726      },
2727  
2728      from: function() {if (this.atOccurrence) return this.pos.from},
2729      to: function() {if (this.atOccurrence) return this.pos.to},
2730  
2731      replace: function(newText, origin) {
2732        if (!this.atOccurrence) return
2733        var lines = CodeMirror.splitLines(newText)
2734        this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin)
2735        this.pos.to = Pos(this.pos.from.line + lines.length - 1,
2736                          lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0))
2737      }
2738    }
2739  
2740    CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) {
2741      return new SearchCursor(this.doc, query, pos, caseFold)
2742    })
2743    CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) {
2744      return new SearchCursor(this, query, pos, caseFold)
2745    })
2746  
2747    CodeMirror.defineExtension("selectMatches", function(query, caseFold) {
2748      var ranges = []
2749      var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold)
2750      while (cur.findNext()) {
2751        if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break
2752        ranges.push({anchor: cur.from(), head: cur.to()})
2753      }
2754      if (ranges.length)
2755        this.setSelections(ranges, 0)
2756    })
2757  });
2758   // CodeMirror, copyright (c) by Marijn Haverbeke and others
2759  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
2760  
2761  (function(mod) {
2762    if (typeof exports == "object" && typeof module == "object") // CommonJS
2763      mod(require("../../lib/codemirror"));
2764    else if (typeof define == "function" && define.amd) // AMD
2765      define(["../../lib/codemirror"], mod);
2766    else // Plain browser env
2767      mod(CodeMirror);
2768  })(function(CodeMirror) {
2769    "use strict";
2770    var WRAP_CLASS = "CodeMirror-activeline";
2771    var BACK_CLASS = "CodeMirror-activeline-background";
2772    var GUTT_CLASS = "CodeMirror-activeline-gutter";
2773  
2774    CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) {
2775      var prev = old == CodeMirror.Init ? false : old;
2776      if (val == prev) return
2777      if (prev) {
2778        cm.off("beforeSelectionChange", selectionChange);
2779        clearActiveLines(cm);
2780        delete cm.state.activeLines;
2781      }
2782      if (val) {
2783        cm.state.activeLines = [];
2784        updateActiveLines(cm, cm.listSelections());
2785        cm.on("beforeSelectionChange", selectionChange);
2786      }
2787    });
2788  
2789    function clearActiveLines(cm) {
2790      for (var i = 0; i < cm.state.activeLines.length; i++) {
2791        cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS);
2792        cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS);
2793        cm.removeLineClass(cm.state.activeLines[i], "gutter", GUTT_CLASS);
2794      }
2795    }
2796  
2797    function sameArray(a, b) {
2798      if (a.length != b.length) return false;
2799      for (var i = 0; i < a.length; i++)
2800        if (a[i] != b[i]) return false;
2801      return true;
2802    }
2803  
2804    function updateActiveLines(cm, ranges) {
2805      var active = [];
2806      for (var i = 0; i < ranges.length; i++) {
2807        var range = ranges[i];
2808        var option = cm.getOption("styleActiveLine");
2809        if (typeof option == "object" && option.nonEmpty ? range.anchor.line != range.head.line : !range.empty())
2810          continue
2811        var line = cm.getLineHandleVisualStart(range.head.line);
2812        if (active[active.length - 1] != line) active.push(line);
2813      }
2814      if (sameArray(cm.state.activeLines, active)) return;
2815      cm.operation(function() {
2816        clearActiveLines(cm);
2817        for (var i = 0; i < active.length; i++) {
2818          cm.addLineClass(active[i], "wrap", WRAP_CLASS);
2819          cm.addLineClass(active[i], "background", BACK_CLASS);
2820          cm.addLineClass(active[i], "gutter", GUTT_CLASS);
2821        }
2822        cm.state.activeLines = active;
2823      });
2824    }
2825  
2826    function selectionChange(cm, sel) {
2827      updateActiveLines(cm, sel.ranges);
2828    }
2829  });
2830   // CodeMirror, copyright (c) by Marijn Haverbeke and others
2831  // Distributed under an MIT license: https://codemirror.net/5/LICENSE
2832  
2833  (function(mod) {
2834    if (typeof exports == "object" && typeof module == "object") // CommonJS
2835      mod(require("../lib/codemirror"));
2836    else if (typeof define == "function" && define.amd) // AMD
2837      define(["../lib/codemirror"], mod);
2838    else // Plain browser env
2839      mod(CodeMirror);
2840  })(function(CodeMirror) {
2841    "use strict";
2842  
2843    CodeMirror.modeInfo = [
2844      {name: "APL", mime: "text/apl", mode: "apl", ext: ["dyalog", "apl"]},
2845      {name: "PGP", mimes: ["application/pgp", "application/pgp-encrypted", "application/pgp-keys", "application/pgp-signature"], mode: "asciiarmor", ext: ["asc", "pgp", "sig"]},
2846      {name: "ASN.1", mime: "text/x-ttcn-asn", mode: "asn.1", ext: ["asn", "asn1"]},
2847      {name: "Asterisk", mime: "text/x-asterisk", mode: "asterisk", file: /^extensions\.conf$/i},
2848      {name: "Brainfuck", mime: "text/x-brainfuck", mode: "brainfuck", ext: ["b", "bf"]},
2849      {name: "C", mime: "text/x-csrc", mode: "clike", ext: ["c", "h", "ino"]},
2850      {name: "C++", mime: "text/x-c++src", mode: "clike", ext: ["cpp", "c++", "cc", "cxx", "hpp", "h++", "hh", "hxx"], alias: ["cpp"]},
2851      {name: "Cobol", mime: "text/x-cobol", mode: "cobol", ext: ["cob", "cpy", "cbl"]},
2852      {name: "C#", mime: "text/x-csharp", mode: "clike", ext: ["cs"], alias: ["csharp", "cs"]},
2853      {name: "Clojure", mime: "text/x-clojure", mode: "clojure", ext: ["clj", "cljc", "cljx"]},
2854      {name: "ClojureScript", mime: "text/x-clojurescript", mode: "clojure", ext: ["cljs"]},
2855      {name: "Closure Stylesheets (GSS)", mime: "text/x-gss", mode: "css", ext: ["gss"]},
2856      {name: "CMake", mime: "text/x-cmake", mode: "cmake", ext: ["cmake", "cmake.in"], file: /^CMakeLists\.txt$/},
2857      {name: "CoffeeScript", mimes: ["application/vnd.coffeescript", "text/coffeescript", "text/x-coffeescript"], mode: "coffeescript", ext: ["coffee"], alias: ["coffee", "coffee-script"]},
2858      {name: "Common Lisp", mime: "text/x-common-lisp", mode: "commonlisp", ext: ["cl", "lisp", "el"], alias: ["lisp"]},
2859      {name: "Cypher", mime: "application/x-cypher-query", mode: "cypher", ext: ["cyp", "cypher"]},
2860      {name: "Cython", mime: "text/x-cython", mode: "python", ext: ["pyx", "pxd", "pxi"]},
2861      {name: "Crystal", mime: "text/x-crystal", mode: "crystal", ext: ["cr"]},
2862      {name: "CSS", mime: "text/css", mode: "css", ext: ["css"]},
2863      {name: "CQL", mime: "text/x-cassandra", mode: "sql", ext: ["cql"]},
2864      {name: "D", mime: "text/x-d", mode: "d", ext: ["d"]},
2865      {name: "Dart", mimes: ["application/dart", "text/x-dart"], mode: "dart", ext: ["dart"]},
2866      {name: "diff", mime: "text/x-diff", mode: "diff", ext: ["diff", "patch"]},
2867      {name: "Django", mime: "text/x-django", mode: "django"},
2868      {name: "Dockerfile", mime: "text/x-dockerfile", mode: "dockerfile", file: /^Dockerfile$/},
2869      {name: "DTD", mime: "application/xml-dtd", mode: "dtd", ext: ["dtd"]},
2870      {name: "Dylan", mime: "text/x-dylan", mode: "dylan", ext: ["dylan", "dyl", "intr"]},
2871      {name: "EBNF", mime: "text/x-ebnf", mode: "ebnf"},
2872      {name: "ECL", mime: "text/x-ecl", mode: "ecl", ext: ["ecl"]},
2873      {name: "edn", mime: "application/edn", mode: "clojure", ext: ["edn"]},
2874      {name: "Eiffel", mime: "text/x-eiffel", mode: "eiffel", ext: ["e"]},
2875      {name: "Elm", mime: "text/x-elm", mode: "elm", ext: ["elm"]},
2876      {name: "Embedded JavaScript", mime: "application/x-ejs", mode: "htmlembedded", ext: ["ejs"]},
2877      {name: "Embedded Ruby", mime: "application/x-erb", mode: "htmlembedded", ext: ["erb"]},
2878      {name: "Erlang", mime: "text/x-erlang", mode: "erlang", ext: ["erl"]},
2879      {name: "Esper", mime: "text/x-esper", mode: "sql"},
2880      {name: "Factor", mime: "text/x-factor", mode: "factor", ext: ["factor"]},
2881      {name: "FCL", mime: "text/x-fcl", mode: "fcl"},
2882      {name: "Forth", mime: "text/x-forth", mode: "forth", ext: ["forth", "fth", "4th"]},
2883      {name: "Fortran", mime: "text/x-fortran", mode: "fortran", ext: ["f", "for", "f77", "f90", "f95"]},
2884      {name: "F#", mime: "text/x-fsharp", mode: "mllike", ext: ["fs"], alias: ["fsharp"]},
2885      {name: "Gas", mime: "text/x-gas", mode: "gas", ext: ["s"]},
2886      {name: "Gherkin", mime: "text/x-feature", mode: "gherkin", ext: ["feature"]},
2887      {name: "GitHub Flavored Markdown", mime: "text/x-gfm", mode: "gfm", file: /^(readme|contributing|history)\.md$/i},
2888      {name: "Go", mime: "text/x-go", mode: "go", ext: ["go"]},
2889      {name: "Groovy", mime: "text/x-groovy", mode: "groovy", ext: ["groovy", "gradle"], file: /^Jenkinsfile$/},
2890      {name: "HAML", mime: "text/x-haml", mode: "haml", ext: ["haml"]},
2891      {name: "Haskell", mime: "text/x-haskell", mode: "haskell", ext: ["hs"]},
2892      {name: "Haskell (Literate)", mime: "text/x-literate-haskell", mode: "haskell-literate", ext: ["lhs"]},
2893      {name: "Haxe", mime: "text/x-haxe", mode: "haxe", ext: ["hx"]},
2894      {name: "HXML", mime: "text/x-hxml", mode: "haxe", ext: ["hxml"]},
2895      {name: "ASP.NET", mime: "application/x-aspx", mode: "htmlembedded", ext: ["aspx"], alias: ["asp", "aspx"]},
2896      {name: "HTML", mime: "text/html", mode: "htmlmixed", ext: ["html", "htm", "handlebars", "hbs"], alias: ["xhtml"]},
2897      {name: "HTTP", mime: "message/http", mode: "http"},
2898      {name: "IDL", mime: "text/x-idl", mode: "idl", ext: ["pro"]},
2899      {name: "Pug", mime: "text/x-pug", mode: "pug", ext: ["jade", "pug"], alias: ["jade"]},
2900      {name: "Java", mime: "text/x-java", mode: "clike", ext: ["java"]},
2901      {name: "Java Server Pages", mime: "application/x-jsp", mode: "htmlembedded", ext: ["jsp"], alias: ["jsp"]},
2902      {name: "JavaScript", mimes: ["text/javascript", "text/ecmascript", "application/javascript", "application/x-javascript", "application/ecmascript"],
2903       mode: "javascript", ext: ["js"], alias: ["ecmascript", "js", "node"]},
2904      {name: "JSON", mimes: ["application/json", "application/x-json"], mode: "javascript", ext: ["json", "map"], alias: ["json5"]},
2905      {name: "JSON-LD", mime: "application/ld+json", mode: "javascript", ext: ["jsonld"], alias: ["jsonld"]},
2906      {name: "JSX", mime: "text/jsx", mode: "jsx", ext: ["jsx"]},
2907      {name: "Jinja2", mime: "text/jinja2", mode: "jinja2", ext: ["j2", "jinja", "jinja2"]},
2908      {name: "Julia", mime: "text/x-julia", mode: "julia", ext: ["jl"], alias: ["jl"]},
2909      {name: "Kotlin", mime: "text/x-kotlin", mode: "clike", ext: ["kt"]},
2910      {name: "LESS", mime: "text/x-less", mode: "css", ext: ["less"]},
2911      {name: "LiveScript", mime: "text/x-livescript", mode: "livescript", ext: ["ls"], alias: ["ls"]},
2912      {name: "Lua", mime: "text/x-lua", mode: "lua", ext: ["lua"]},
2913      {name: "Markdown", mime: "text/x-markdown", mode: "markdown", ext: ["markdown", "md", "mkd"]},
2914      {name: "mIRC", mime: "text/mirc", mode: "mirc"},
2915      {name: "MariaDB SQL", mime: "text/x-mariadb", mode: "sql"},
2916      {name: "Mathematica", mime: "text/x-mathematica", mode: "mathematica", ext: ["m", "nb", "wl", "wls"]},
2917      {name: "Modelica", mime: "text/x-modelica", mode: "modelica", ext: ["mo"]},
2918      {name: "MUMPS", mime: "text/x-mumps", mode: "mumps", ext: ["mps"]},
2919      {name: "MS SQL", mime: "text/x-mssql", mode: "sql"},
2920      {name: "mbox", mime: "application/mbox", mode: "mbox", ext: ["mbox"]},
2921      {name: "MySQL", mime: "text/x-mysql", mode: "sql"},
2922      {name: "Nginx", mime: "text/x-nginx-conf", mode: "nginx", file: /nginx.*\.conf$/i},
2923      {name: "NSIS", mime: "text/x-nsis", mode: "nsis", ext: ["nsh", "nsi"]},
2924      {name: "NTriples", mimes: ["application/n-triples", "application/n-quads", "text/n-triples"],
2925       mode: "ntriples", ext: ["nt", "nq"]},
2926      {name: "Objective-C", mime: "text/x-objectivec", mode: "clike", ext: ["m"], alias: ["objective-c", "objc"]},
2927      {name: "Objective-C++", mime: "text/x-objectivec++", mode: "clike", ext: ["mm"], alias: ["objective-c++", "objc++"]},
2928      {name: "OCaml", mime: "text/x-ocaml", mode: "mllike", ext: ["ml", "mli", "mll", "mly"]},
2929      {name: "Octave", mime: "text/x-octave", mode: "octave", ext: ["m"]},
2930      {name: "Oz", mime: "text/x-oz", mode: "oz", ext: ["oz"]},
2931      {name: "Pascal", mime: "text/x-pascal", mode: "pascal", ext: ["p", "pas"]},
2932      {name: "PEG.js", mime: "null", mode: "pegjs", ext: ["jsonld"]},
2933      {name: "Perl", mime: "text/x-perl", mode: "perl", ext: ["pl", "pm"]},
2934      {name: "PHP", mimes: ["text/x-php", "application/x-httpd-php", "application/x-httpd-php-open"], mode: "php", ext: ["php", "php3", "php4", "php5", "php7", "phtml"]},
2935      {name: "Pig", mime: "text/x-pig", mode: "pig", ext: ["pig"]},
2936      {name: "Plain Text", mime: "text/plain", mode: "null", ext: ["txt", "text", "conf", "def", "list", "log"]},
2937      {name: "PLSQL", mime: "text/x-plsql", mode: "sql", ext: ["pls"]},
2938      {name: "PostgreSQL", mime: "text/x-pgsql", mode: "sql"},
2939      {name: "PowerShell", mime: "application/x-powershell", mode: "powershell", ext: ["ps1", "psd1", "psm1"]},
2940      {name: "Properties files", mime: "text/x-properties", mode: "properties", ext: ["properties", "ini", "in"], alias: ["ini", "properties"]},
2941      {name: "ProtoBuf", mime: "text/x-protobuf", mode: "protobuf", ext: ["proto"]},
2942      {name: "Python", mime: "text/x-python", mode: "python", ext: ["BUILD", "bzl", "py", "pyw"], file: /^(BUCK|BUILD)$/},
2943      {name: "Puppet", mime: "text/x-puppet", mode: "puppet", ext: ["pp"]},
2944      {name: "Q", mime: "text/x-q", mode: "q", ext: ["q"]},
2945      {name: "R", mime: "text/x-rsrc", mode: "r", ext: ["r", "R"], alias: ["rscript"]},
2946      {name: "reStructuredText", mime: "text/x-rst", mode: "rst", ext: ["rst"], alias: ["rst"]},
2947      {name: "RPM Changes", mime: "text/x-rpm-changes", mode: "rpm"},
2948      {name: "RPM Spec", mime: "text/x-rpm-spec", mode: "rpm", ext: ["spec"]},
2949      {name: "Ruby", mime: "text/x-ruby", mode: "ruby", ext: ["rb"], alias: ["jruby", "macruby", "rake", "rb", "rbx"]},
2950      {name: "Rust", mime: "text/x-rustsrc", mode: "rust", ext: ["rs"]},
2951      {name: "SAS", mime: "text/x-sas", mode: "sas", ext: ["sas"]},
2952      {name: "Sass", mime: "text/x-sass", mode: "sass", ext: ["sass"]},
2953      {name: "Scala", mime: "text/x-scala", mode: "clike", ext: ["scala"]},
2954      {name: "Scheme", mime: "text/x-scheme", mode: "scheme", ext: ["scm", "ss"]},
2955      {name: "SCSS", mime: "text/x-scss", mode: "css", ext: ["scss"]},
2956      {name: "Shell", mimes: ["text/x-sh", "application/x-sh"], mode: "shell", ext: ["sh", "ksh", "bash"], alias: ["bash", "sh", "zsh"], file: /^PKGBUILD$/},
2957      {name: "Sieve", mime: "application/sieve", mode: "sieve", ext: ["siv", "sieve"]},
2958      {name: "Slim", mimes: ["text/x-slim", "application/x-slim"], mode: "slim", ext: ["slim"]},
2959      {name: "Smalltalk", mime: "text/x-stsrc", mode: "smalltalk", ext: ["st"]},
2960      {name: "Smarty", mime: "text/x-smarty", mode: "smarty", ext: ["tpl"]},
2961      {name: "Solr", mime: "text/x-solr", mode: "solr"},
2962      {name: "SML", mime: "text/x-sml", mode: "mllike", ext: ["sml", "sig", "fun", "smackspec"]},
2963      {name: "Soy", mime: "text/x-soy", mode: "soy", ext: ["soy"], alias: ["closure template"]},
2964      {name: "SPARQL", mime: "application/sparql-query", mode: "sparql", ext: ["rq", "sparql"], alias: ["sparul"]},
2965      {name: "Spreadsheet", mime: "text/x-spreadsheet", mode: "spreadsheet", alias: ["excel", "formula"]},
2966      {name: "SQL", mime: "text/x-sql", mode: "sql", ext: ["sql"]},
2967      {name: "SQLite", mime: "text/x-sqlite", mode: "sql"},
2968      {name: "Squirrel", mime: "text/x-squirrel", mode: "clike", ext: ["nut"]},
2969      {name: "Stylus", mime: "text/x-styl", mode: "stylus", ext: ["styl"]},
2970      {name: "Swift", mime: "text/x-swift", mode: "swift", ext: ["swift"]},
2971      {name: "sTeX", mime: "text/x-stex", mode: "stex"},
2972      {name: "LaTeX", mime: "text/x-latex", mode: "stex", ext: ["text", "ltx", "tex"], alias: ["tex"]},
2973      {name: "SystemVerilog", mime: "text/x-systemverilog", mode: "verilog", ext: ["v", "sv", "svh"]},
2974      {name: "Tcl", mime: "text/x-tcl", mode: "tcl", ext: ["tcl"]},
2975      {name: "Textile", mime: "text/x-textile", mode: "textile", ext: ["textile"]},
2976      {name: "TiddlyWiki", mime: "text/x-tiddlywiki", mode: "tiddlywiki"},
2977      {name: "Tiki wiki", mime: "text/tiki", mode: "tiki"},
2978      {name: "TOML", mime: "text/x-toml", mode: "toml", ext: ["toml"]},
2979      {name: "Tornado", mime: "text/x-tornado", mode: "tornado"},
2980      {name: "troff", mime: "text/troff", mode: "troff", ext: ["1", "2", "3", "4", "5", "6", "7", "8", "9"]},
2981      {name: "TTCN", mime: "text/x-ttcn", mode: "ttcn", ext: ["ttcn", "ttcn3", "ttcnpp"]},
2982      {name: "TTCN_CFG", mime: "text/x-ttcn-cfg", mode: "ttcn-cfg", ext: ["cfg"]},
2983      {name: "Turtle", mime: "text/turtle", mode: "turtle", ext: ["ttl"]},
2984      {name: "TypeScript", mime: "application/typescript", mode: "javascript", ext: ["ts"], alias: ["ts"]},
2985      {name: "TypeScript-JSX", mime: "text/typescript-jsx", mode: "jsx", ext: ["tsx"], alias: ["tsx"]},
2986      {name: "Twig", mime: "text/x-twig", mode: "twig"},
2987      {name: "Web IDL", mime: "text/x-webidl", mode: "webidl", ext: ["webidl"]},
2988      {name: "VB.NET", mime: "text/x-vb", mode: "vb", ext: ["vb"]},
2989      {name: "VBScript", mime: "text/vbscript", mode: "vbscript", ext: ["vbs"]},
2990      {name: "Velocity", mime: "text/velocity", mode: "velocity", ext: ["vtl"]},
2991      {name: "Verilog", mime: "text/x-verilog", mode: "verilog", ext: ["v"]},
2992      {name: "VHDL", mime: "text/x-vhdl", mode: "vhdl", ext: ["vhd", "vhdl"]},
2993      {name: "Vue.js Component", mimes: ["script/x-vue", "text/x-vue"], mode: "vue", ext: ["vue"]},
2994      {name: "XML", mimes: ["application/xml", "text/xml"], mode: "xml", ext: ["xml", "xsl", "xsd", "svg"], alias: ["rss", "wsdl", "xsd"]},
2995      {name: "XQuery", mime: "application/xquery", mode: "xquery", ext: ["xy", "xquery"]},
2996      {name: "Yacas", mime: "text/x-yacas", mode: "yacas", ext: ["ys"]},
2997      {name: "YAML", mimes: ["text/x-yaml", "text/yaml"], mode: "yaml", ext: ["yaml", "yml"], alias: ["yml"]},
2998      {name: "Z80", mime: "text/x-z80", mode: "z80", ext: ["z80"]},
2999      {name: "mscgen", mime: "text/x-mscgen", mode: "mscgen", ext: ["mscgen", "mscin", "msc"]},
3000      {name: "xu", mime: "text/x-xu", mode: "mscgen", ext: ["xu"]},
3001      {name: "msgenny", mime: "text/x-msgenny", mode: "mscgen", ext: ["msgenny"]},
3002      {name: "WebAssembly", mime: "text/webassembly", mode: "wast", ext: ["wat", "wast"]},
3003    ];
3004    // Ensure all modes have a mime property for backwards compatibility
3005    for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
3006      var info = CodeMirror.modeInfo[i];
3007      if (info.mimes) info.mime = info.mimes[0];
3008    }
3009  
3010    CodeMirror.findModeByMIME = function(mime) {
3011      mime = mime.toLowerCase();
3012      for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
3013        var info = CodeMirror.modeInfo[i];
3014        if (info.mime == mime) return info;
3015        if (info.mimes) for (var j = 0; j < info.mimes.length; j++)
3016          if (info.mimes[j] == mime) return info;
3017      }
3018      if (/\+xml$/.test(mime)) return CodeMirror.findModeByMIME("application/xml")
3019      if (/\+json$/.test(mime)) return CodeMirror.findModeByMIME("application/json")
3020    };
3021  
3022    CodeMirror.findModeByExtension = function(ext) {
3023      ext = ext.toLowerCase();
3024      for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
3025        var info = CodeMirror.modeInfo[i];
3026        if (info.ext) for (var j = 0; j < info.ext.length; j++)
3027          if (info.ext[j] == ext) return info;
3028      }
3029    };
3030  
3031    CodeMirror.findModeByFileName = function(filename) {
3032      for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
3033        var info = CodeMirror.modeInfo[i];
3034        if (info.file && info.file.test(filename)) return info;
3035      }
3036      var dot = filename.lastIndexOf(".");
3037      var ext = dot > -1 && filename.substring(dot + 1, filename.length);
3038      if (ext) return CodeMirror.findModeByExtension(ext);
3039    };
3040  
3041    CodeMirror.findModeByName = function(name) {
3042      name = name.toLowerCase();
3043      for (var i = 0; i < CodeMirror.modeInfo.length; i++) {
3044        var info = CodeMirror.modeInfo[i];
3045        if (info.name.toLowerCase() == name) return info;
3046        if (info.alias) for (var j = 0; j < info.alias.length; j++)
3047          if (info.alias[j].toLowerCase() == name) return info;
3048      }
3049    };
3050  });


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer