text: define("ace/snippets", ["require", "exports", "module", "ace/lib/oop", "ace/lib/event_emitter", "ace/lib/lang", "ace/range", "ace/range_list", "ace/keyboard/hash_handler", "ace/tokenizer", "ace/clipboard", "ace/lib/dom", "ace/editor"], function(e, t, n) {
    "use strict";
  
    function h(e) {
      var t = (new Date).toLocaleString("en-us", e);
      return t.length == 1 ? "0" + t : t
    }
    var r = e("./lib/oop"),
      i = e("./lib/event_emitter").EventEmitter,
      s = e("./lib/lang"),
      o = e("./range").Range,
      u = e("./range_list").RangeList,
      a = e("./keyboard/hash_handler").HashHandler,
      f = e("./tokenizer").Tokenizer,
      l = e("./clipboard"),
      c = {
        CURRENT_WORD: function(e) {
          return e.session.getTextRange(e.session.getWordRange())
        },
        SELECTION: function(e, t, n) {
          var r = e.session.getTextRange();
          return n ? r.replace(/\n\r?([ \t]*\S)/g, "\n" + n + "$1") : r
        },
        CURRENT_LINE: function(e) {
          return e.session.getLine(e.getCursorPosition().row)
        },
        PREV_LINE: function(e) {
          return e.session.getLine(e.getCursorPosition().row - 1)
        },
        LINE_INDEX: function(e) {
          return e.getCursorPosition().row
        },
        LINE_NUMBER: function(e) {
          return e.getCursorPosition().row + 1
        },
        SOFT_TABS: function(e) {
          return e.session.getUseSoftTabs() ? "YES" : "NO"
        },
        TAB_SIZE: function(e) {
          return e.session.getTabSize()
        },
        CLIPBOARD: function(e) {
          return l.getText && l.getText()
        },
        FILENAME: function(e) {
          return /[^/\\]*$/.exec(this.FILEPATH(e))[0]
        },
        FILENAME_BASE: function(e) {
          return /[^/\\]*$/.exec(this.FILEPATH(e))[0].replace(/\.[^.]*$/, "")
        },
        DIRECTORY: function(e) {
          return this.FILEPATH(e).replace(/[^/\\]*$/, "")
        },
        FILEPATH: function(e) {
          return "/not implemented.txt"
        },
        WORKSPACE_NAME: function() {
          return "Unknown"
        },
        FULLNAME: function() {
          return "Unknown"
        },
        BLOCK_COMMENT_START: function(e) {
          var t = e.session.$mode || {};
          return t.blockComment && t.blockComment.start || ""
        },
        BLOCK_COMMENT_END: function(e) {
          var t = e.session.$mode || {};
          return t.blockComment && t.blockComment.end || ""
        },
        LINE_COMMENT: function(e) {
          var t = e.session.$mode || {};
          return t.lineCommentStart || ""
        },
        CURRENT_YEAR: h.bind(null, {
          year: "numeric"
        }),
        CURRENT_YEAR_SHORT: h.bind(null, {
          year: "2-digit"
        }),
        CURRENT_MONTH: h.bind(null, {
          month: "numeric"
        }),
        CURRENT_MONTH_NAME: h.bind(null, {
          month: "long"
        }),
        CURRENT_MONTH_NAME_SHORT: h.bind(null, {
          month: "short"
        }),
        CURRENT_DATE: h.bind(null, {
          day: "2-digit"
        }),
        CURRENT_DAY_NAME: h.bind(null, {
          weekday: "long"
        }),
        CURRENT_DAY_NAME_SHORT: h.bind(null, {
          weekday: "short"
        }),
        CURRENT_HOUR: h.bind(null, {
          hour: "2-digit",
          hour12: !1
        }),
        CURRENT_MINUTE: h.bind(null, {
          minute: "2-digit"
        }),
        CURRENT_SECOND: h.bind(null, {
          second: "2-digit"
        })
      };
    c.SELECTED_TEXT = c.SELECTION;
    var p = function() {
      this.snippetMap = {}, this.snippetNameMap = {}
    };
    (function() {
      r.implement(this, i), this.getTokenizer = function() {
        return p.$tokenizer || this.createTokenizer()
      }, this.createTokenizer = function() {
        function e(e) {
          return e = e.substr(1), /^\d+$/.test(e) ? [{
            tabstopId: parseInt(e, 10)
          }] : [{
            text: e
          }]
        }
  
        function t(e) {
          return "(?:[^\\\\" + e + "]|\\\\.)"
        }
        var n = {
          regex: "/(" + t("/") + "+)/",
          onMatch: function(e, t, n) {
            var r = n[0];
            return r.fmtString = !0, r.guard = e.slice(1, -1), r.flag = "", ""
          },
          next: "formatString"
        };
        return p.$tokenizer = new f({
          start: [{
            regex: /\\./,
            onMatch: function(e, t, n) {
              var r = e[1];
              return r == "}" && n.length ? e = r : "`$\\".indexOf(r) != -1 && (e = r), [e]
            }
          }, {
            regex: /}/,
            onMatch: function(e, t, n) {
              return [n.length ? n.shift() : e]
            }
          }, {
            regex: /\$(?:\d+|\w+)/,
            onMatch: e
          }, {
            regex: /\$\{[\dA-Z_a-z]+/,
            onMatch: function(t, n, r) {
              var i = e(t.substr(1));
              return r.unshift(i[0]), i
            },
            next: "snippetVar"
          }, {
            regex: /\n/,
            token: "newline",
            merge: !1
          }],
          snippetVar: [{
            regex: "\\|" + t("\\|") + "*\\|",
            onMatch: function(e, t, n) {
              var r = e.slice(1, -1).replace(/\\[,|\\]|,/g, function(e) {
                return e.length == 2 ? e[1] : "\0"
              }).split("\0").map(function(e) {
                return {
                  value: e
                }
              });
              return n[0].choices = r, [r[0]]
            },
            next: "start"
          }, n, {
            regex: "([^:}\\\\]|\\\\.)*:?",
            token: "",
            next: "start"
          }],
          formatString: [{
            regex: /:/,
            onMatch: function(e, t, n) {
              return n.length && n[0].expectElse ? (n[0].expectElse = !1, n[0].ifEnd = {
                elseEnd: n[0]
              }, [n[0].ifEnd]) : ":"
            }
          }, {
            regex: /\\./,
            onMatch: function(e, t, n) {
              var r = e[1];
              return r == "}" && n.length ? e = r : "`$\\".indexOf(r) != -1 ? e = r : r == "n" ? e = "\n" : r == "t" ? e = "	" : "ulULE".indexOf(r) != -1 && (e = {
                changeCase: r,
                local: r > "a"
              }), [e]
            }
          }, {
            regex: "/\\w*}",
            onMatch: function(e, t, n) {
              var r = n.shift();
              return r && (r.flag = e.slice(1, -1)), this.next = r && r.tabstopId ? "start" : "", [r || e]
            },
            next: "start"
          }, {
            regex: /\$(?:\d+|\w+)/,
            onMatch: function(e, t, n) {
              return [{
                text: e.slice(1)
              }]
            }
          }, {
            regex: /\${\w+/,
            onMatch: function(e, t, n) {
              var r = {
                text: e.slice(2)
              };
              return n.unshift(r), [r]
            },
            next: "formatStringVar"
          }, {
            regex: /\n/,
            token: "newline",
            merge: !1
          }, {
            regex: /}/,
            onMatch: function(e, t, n) {
              var r = n.shift();
              return this.next = r && r.tabstopId ? "start" : "", [r || e]
            },
            next: "start"
          }],
          formatStringVar: [{
            regex: /:\/\w+}/,
            onMatch: function(e, t, n) {
              var r = n[0];
              return r.formatFunction = e.slice(2, -1), [n.shift()]
            },
            next: "formatString"
          }, n, {
            regex: /:[\?\-+]?/,
            onMatch: function(e, t, n) {
              e[1] == "+" && (n[0].ifEnd = n[0]), e[1] == "?" && (n[0].expectElse = !0)
            },
            next: "formatString"
          }, {
            regex: "([^:}\\\\]|\\\\.)*:?",
            token: "",
            next: "formatString"
          }]
        }), p.$tokenizer
      }, this.tokenizeTmSnippet = function(e, t) {
        return this.getTokenizer().getLineTokens(e, t).tokens.map(function(e) {
          return e.value || e
        })
      }, this.getVariableValue = function(e, t, n) {
        if (/^\d+$/.test(t)) return (this.variables.__ || {})[t] || "";
        if (/^[A-Z]\d+$/.test(t)) return (this.variables[t[0] + "__"] || {})[t.substr(1)] || "";
        t = t.replace(/^TM_/, "");
        if (!this.variables.hasOwnProperty(t)) return "";
        var r = this.variables[t];
        return typeof r == "function" && (r = this.variables[t](e, t, n)), r == null ? "" : r
      }, this.variables = c, this.tmStrFormat = function(e, t, n) {
        if (!t.fmt) return e;
        var r = t.flag || "",
          i = t.guard;
        i = new RegExp(i, r.replace(/[^gim]/g, ""));
        var s = typeof t.fmt == "string" ? this.tokenizeTmSnippet(t.fmt, "formatString") : t.fmt,
          o = this,
          u = e.replace(i, function() {
            var e = o.variables.__;
            o.variables.__ = [].slice.call(arguments);
            var t = o.resolveVariables(s, n),
              r = "E";
            for (var i = 0; i < t.length; i++) {
              var u = t[i];
              if (typeof u == "object") {
                t[i] = "";
                if (u.changeCase && u.local) {
                  var a = t[i + 1];
                  a && typeof a == "string" && (u.changeCase == "u" ? t[i] = a[0].toUpperCase() : t[i] = a[0].toLowerCase(), t[i + 1] = a.substr(1))
                }
                else u.changeCase && (r = u.changeCase)
              }
              else r == "U" ? t[i] = u.toUpperCase() : r == "L" && (t[i] = u.toLowerCase())
            }
            return o.variables.__ = e, t.join("")
          });
        return u
      }, this.tmFormatFunction = function(e, t, n) {
        return t.formatFunction == "upcase" ? e.toUpperCase() : t.formatFunction == "downcase" ? e.toLowerCase() : e
      }, this.resolveVariables = function(e, t) {
        function f(t) {
          var n = e.indexOf(t, s + 1);
          n != -1 && (s = n)
        }
        var n = [],
          r = "",
          i = !0;
        for (var s = 0; s < e.length; s++) {
          var o = e[s];
          if (typeof o == "string") {
            n.push(o), o == "\n" ? (i = !0, r = "") : i && (r = /^\t*/.exec(o)[0], i = /\S/.test(o));
            continue
          }
          if (!o) continue;
          i = !1;
          if (o.fmtString) {
            var u = e.indexOf(o, s + 1);
            u == -1 && (u = e.length), o.fmt = e.slice(s + 1, u), s = u
          }
          if (o.text) {
            var a = this.getVariableValue(t, o.text, r) + "";
            o.fmtString && (a = this.tmStrFormat(a, o, t)), o.formatFunction && (a = this.tmFormatFunction(a, o, t)), a && !o.ifEnd ? (n.push(a), f(o)) : !a && o.ifEnd && f(o.ifEnd)
          }
          else o.elseEnd ? f(o.elseEnd) : o.tabstopId != null ? n.push(o) : o.changeCase != null && n.push(o)
        }
        return n
      }, this.insertSnippetForSelection = function(e, t) {
        function f(e) {
          var t = [];
          for (var n = 0; n < e.length; n++) {
            var r = e[n];
            if (typeof r == "object") {
              if (a[r.tabstopId]) continue;
              var i = e.lastIndexOf(r, n - 1);
              r = t[i] || {
                tabstopId: r.tabstopId
              }
            }
            t[n] = r
          }
          return t
        }
        var n = e.getCursorPosition(),
          r = e.session.getLine(n.row),
          i = e.session.getTabString(),
          s = r.match(/^\s*/)[0];
        n.column < s.length && (s = s.slice(0, n.column)), t = t.replace(/\r/g, "");
        var o = this.tokenizeTmSnippet(t);
        o = this.resolveVariables(o, e), o = o.map(function(e) {
          return e == "\n" ? e + s : typeof e == "string" ? e.replace(/\t/g, i) : e
        });
        var u = [];
        o.forEach(function(e, t) {
          if (typeof e != "object") return;
          var n = e.tabstopId,
            r = u[n];
          r || (r = u[n] = [], r.index = n, r.value = "", r.parents = {});
          if (r.indexOf(e) !== -1) return;
          e.choices && !r.choices && (r.choices = e.choices), r.push(e);
          var i = o.indexOf(e, t + 1);
          if (i === -1) return;
          var s = o.slice(t + 1, i),
            a = s.some(function(e) {
              return typeof e == "object"
            });
          a && !r.value ? r.value = s : s.length && (!r.value || typeof r.value != "string") && (r.value = s.join(""))
        }), u.forEach(function(e) {
          e.length = 0
        });
        var a = {};
        for (var l = 0; l < o.length; l++) {
          var c = o[l];
          if (typeof c != "object") continue;
          var h = c.tabstopId,
            p = u[h],
            v = o.indexOf(c, l + 1);
          if (a[h]) {
            a[h] === c && (delete a[h], Object.keys(a).forEach(function(e) {
              p.parents[e] = !0
            }));
            continue
          }
          a[h] = c;
          var m = p.value;
          typeof m != "string" ? m = f(m) : c.fmt && (m = this.tmStrFormat(m, c, e)), o.splice.apply(o, [l + 1, Math.max(0, v - l)].concat(m, c)), p.indexOf(c) === -1 && p.push(c)
        }
        var g = 0,
          y = 0,
          b = "";
        o.forEach(function(e) {
          if (typeof e == "string") {
            var t = e.split("\n");
            t.length > 1 ? (y = t[t.length - 1].length, g += t.length - 1) : y += e.length, b += e
          }
          else e && (e.start ? e.end = {
            row: g,
            column: y
          } : e.start = {
            row: g,
            column: y
          })
        });
        var w = e.getSelectionRange(),
          E = e.session.replace(w, b),
          S = new d(e),
          x = e.inVirtualSelectionMode && e.selection.index;
        S.addTabstops(u, w.start, E, x)
      }, this.insertSnippet = function(e, t) {
        var n = this;
        if (e.inVirtualSelectionMode) return n.insertSnippetForSelection(e, t);
        e.forEachSelection(function() {
          n.insertSnippetForSelection(e, t)
        }, null, {
          keepOrder: !0
        }), e.tabstopManager && e.tabstopManager.tabNext()
      }, this.$getScope = function(e) {
        var t = e.session.$mode.$id || "";
        t = t.split("/").pop();
        if (t === "html" || t === "php") {
          t === "php" && !e.session.$mode.inlinePhp && (t = "html");
          var n = e.getCursorPosition(),
            r = e.session.getState(n.row);
          typeof r == "object" && (r = r[0]), r.substring && (r.substring(0, 3) == "js-" ? t = "javascript" : r.substring(0, 4) == "css-" ? t = "css" : r.substring(0, 4) == "php-" && (t = "php"))
        }
        return t
      }, this.getActiveScopes = function(e) {
        var t = this.$getScope(e),
          n = [t],
          r = this.snippetMap;
        return r[t] && r[t].includeScopes && n.push.apply(n, r[t].includeScopes), n.push("_"), n
      }, this.expandWithTab = function(e, t) {
        var n = this,
          r = e.forEachSelection(function() {
            return n.expandSnippetForSelection(e, t)
          }, null, {
            keepOrder: !0
          });
        return r && e.tabstopManager && e.tabstopManager.tabNext(), r
      }, this.expandSnippetForSelection = function(e, t) {
        var n = e.getCursorPosition(),
          r = e.session.getLine(n.row),
          i = r.substring(0, n.column),
          s = r.substr(n.column),
          o = this.snippetMap,
          u;
        return this.getActiveScopes(e).some(function(e) {
          var t = o[e];
          return t && (u = this.findMatchingSnippet(t, i, s)), !!u
        }, this), u ? t && t.dryRun ? !0 : (e.session.doc.removeInLine(n.row, n.column - u.replaceBefore.length, n.column + u.replaceAfter.length), this.variables.M__ = u.matchBefore, this.variables.T__ = u.matchAfter, this.insertSnippetForSelection(e, u.content), this.variables.M__ = this.variables.T__ = null, !0) : !1
      }, this.findMatchingSnippet = function(e, t, n) {
        for (var r = e.length; r--;) {
          var i = e[r];
          if (i.startRe && !i.startRe.test(t)) continue;
          if (i.endRe && !i.endRe.test(n)) continue;
          if (!i.startRe && !i.endRe) continue;
          return i.matchBefore = i.startRe ? i.startRe.exec(t) : [""], i.matchAfter = i.endRe ? i.endRe.exec(n) : [""], i.replaceBefore = i.triggerRe ? i.triggerRe.exec(t)[0] : "", i.replaceAfter = i.endTriggerRe ? i.endTriggerRe.exec(n)[0] : "", i
        }
      }, this.snippetMap = {}, this.snippetNameMap = {}, this.register = function(e, t) {
        function o(e) {
          return e && !/^\^?\(.*\)\$?$|^\\b$/.test(e) && (e = "(?:" + e + ")"), e || ""
        }
  
        function u(e, t, n) {
          return e = o(e), t = o(t), n ? (e = t + e, e && e[e.length - 1] != "$" && (e += "$")) : (e += t, e && e[0] != "^" && (e = "^" + e)), new RegExp(e)
        }
  
        function a(e) {
          e.scope || (e.scope = t || "_"), t = e.scope, n[t] || (n[t] = [], r[t] = {});
          var o = r[t];
          if (e.name) {
            var a = o[e.name];
            a && i.unregister(a), o[e.name] = e
          }
          n[t].push(e), e.prefix && (e.tabTrigger = e.prefix), !e.content && e.body && (e.content = Array.isArray(e.body) ? e.body.join("\n") : e.body), e.tabTrigger && !e.trigger && (!e.guard && /^\w/.test(e.tabTrigger) && (e.guard = "\\b"), e.trigger = s.escapeRegExp(e.tabTrigger));
          if (!e.trigger && !e.guard && !e.endTrigger && !e.endGuard) return;
          e.startRe = u(e.trigger, e.guard, !0), e.triggerRe = new RegExp(e.trigger), e.endRe = u(e.endTrigger, e.endGuard, !0), e.endTriggerRe = new RegExp(e.endTrigger)
        }
        var n = this.snippetMap,
          r = this.snippetNameMap,
          i = this;
        e || (e = []), Array.isArray(e) ? e.forEach(a) : Object.keys(e).forEach(function(t) {
          a(e[t])
        }), this._signal("registerSnippets", {
          scope: t
        })
      }, this.unregister = function(e, t) {
        function i(e) {
          var i = r[e.scope || t];
          if (i && i[e.name]) {
            delete i[e.name];
            var s = n[e.scope || t],
              o = s && s.indexOf(e);
            o >= 0 && s.splice(o, 1)
          }
        }
        var n = this.snippetMap,
          r = this.snippetNameMap;
        e.content ? i(e) : Array.isArray(e) && e.forEach(i)
      }, this.parseSnippetFile = function(e) {
        e = e.replace(/\r/g, "");
        var t = [],
          n = {},
          r = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm,
          i;
        while (i = r.exec(e)) {
          if (i[1]) try {
            n = JSON.parse(i[1]), t.push(n)
          }
          catch (s) {}
          if (i[4]) n.content = i[4].replace(/^\t/gm, ""), t.push(n), n = {};
          else {
            var o = i[2],
              u = i[3];
            if (o == "regex") {
              var a = /\/((?:[^\/\\]|\\.)*)|$/g;
              n.guard = a.exec(u)[1], n.trigger = a.exec(u)[1], n.endTrigger = a.exec(u)[1], n.endGuard = a.exec(u)[1]
            }
            else o == "snippet" ? (n.tabTrigger = u.match(/^\S*/)[0], n.name || (n.name = u)) : o && (n[o] = u)
          }
        }
        return t
      }, this.getSnippetByName = function(e, t) {
        var n = this.snippetNameMap,
          r;
        return this.getActiveScopes(t).some(function(t) {
          var i = n[t];
          return i && (r = i[e]), !!r
        }, this), r
      }
    }).call(p.prototype);
    var d = function(e) {
      if (e.tabstopManager) return e.tabstopManager;
      e.tabstopManager = this, this.$onChange = this.onChange.bind(this), this.$onChangeSelection = s.delayedCall(this.onChangeSelection.bind(this)).schedule, this.$onChangeSession = this.onChangeSession.bind(this), this.$onAfterExec = this.onAfterExec.bind(this), this.attach(e)
    };
    (function() {
      this.attach = function(e) {
        this.index = 0, this.ranges = [], this.tabstops = [], this.$openTabstops = null, this.selectedTabstop = null, this.editor = e, this.editor.on("change", this.$onChange), this.editor.on("changeSelection", this.$onChangeSelection), this.editor.on("changeSession", this.$onChangeSession), this.editor.commands.on("afterExec", this.$onAfterExec), this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler)
      }, this.detach = function() {
        this.tabstops.forEach(this.removeTabstopMarkers, this), this.ranges = null, this.tabstops = null, this.selectedTabstop = null, this.editor.removeListener("change", this.$onChange), this.editor.removeListener("changeSelection", this.$onChangeSelection), this.editor.removeListener("changeSession", this.$onChangeSession), this.editor.commands.removeListener("afterExec", this.$onAfterExec), this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.tabstopManager = null, this.editor = null
      }, this.onChange = function(e) {
        var t = e.action[0] == "r",
          n = this.selectedTabstop || {},
          r = n.parents || {},
          i = (this.tabstops || []).slice();
        for (var s = 0; s < i.length; s++) {
          var o = i[s],
            u = o == n || r[o.index];
          o.rangeList.$bias = u ? 0 : 1;
          if (e.action == "remove" && o !== n) {
            var a = o.parents && o.parents[n.index],
              f = o.rangeList.pointIndex(e.start, a);
            f = f < 0 ? -f - 1 : f + 1;
            var l = o.rangeList.pointIndex(e.end, a);
            l = l < 0 ? -l - 1 : l - 1;
            var c = o.rangeList.ranges.slice(f, l);
            for (var h = 0; h < c.length; h++) this.removeRange(c[h])
          }
          o.rangeList.$onChange(e)
        }
        var p = this.editor.session;
        !this.$inChange && t && p.getLength() == 1 && !p.getValue() && this.detach()
      }, this.updateLinkedFields = function() {
        var e = this.selectedTabstop;
        if (!e || !e.hasLinkedRanges || !e.firstNonLinked) return;
        this.$inChange = !0;
        var n = this.editor.session,
          r = n.getTextRange(e.firstNonLinked);
        for (var i = 0; i < e.length; i++) {
          var s = e[i];
          if (!s.linked) continue;
          var o = s.original,
            u = t.snippetManager.tmStrFormat(r, o, this.editor);
          n.replace(s, u)
        }
        this.$inChange = !1
      }, this.onAfterExec = function(e) {
        e.command && !e.command.readOnly && this.updateLinkedFields()
      }, this.onChangeSelection = function() {
        if (!this.editor) return;
        var e = this.editor.selection.lead,
          t = this.editor.selection.anchor,
          n = this.editor.selection.isEmpty();
        for (var r = 0; r < this.ranges.length; r++) {
          if (this.ranges[r].linked) continue;
          var i = this.ranges[r].contains(e.row, e.column),
            s = n || this.ranges[r].contains(t.row, t.column);
          if (i && s) return
        }
        this.detach()
      }, this.onChangeSession = function() {
        this.detach()
      }, this.tabNext = function(e) {
        var t = this.tabstops.length,
          n = this.index + (e || 1);
        n = Math.min(Math.max(n, 1), t), n == t && (n = 0), this.selectTabstop(n), n === 0 && this.detach()
      }, this.selectTabstop = function(e) {
        this.$openTabstops = null;
        var t = this.tabstops[this.index];
        t && this.addTabstopMarkers(t), this.index = e, t = this.tabstops[this.index];
        if (!t || !t.length) return;
        this.selectedTabstop = t;
        var n = t.firstNonLinked || t;
        t.choices && (n.cursor = n.start);
        if (!this.editor.inVirtualSelectionMode) {
          var r = this.editor.multiSelect;
          r.toSingleRange(n);
          for (var i = 0; i < t.length; i++) {
            if (t.hasLinkedRanges && t[i].linked) continue;
            r.addRange(t[i].clone(), !0)
          }
        }
        else this.editor.selection.fromOrientedRange(n);
        this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler), this.selectedTabstop && this.selectedTabstop.choices && this.editor.execCommand("startAutocomplete", {
          matches: this.selectedTabstop.choices
        })
      }, this.addTabstops = function(e, t, n) {
        var r = this.useLink || !this.editor.getOption("enableMultiselect");
        this.$openTabstops || (this.$openTabstops = []);
        if (!e[0]) {
          var i = o.fromPoints(n, n);
          m(i.start, t), m(i.end, t), e[0] = [i], e[0].index = 0
        }
        var s = this.index,
          a = [s + 1, 0],
          f = this.ranges;
        e.forEach(function(e, n) {
          var i = this.$openTabstops[n] || e;
          for (var s = 0; s < e.length; s++) {
            var l = e[s],
              c = o.fromPoints(l.start, l.end || l.start);
            v(c.start, t), v(c.end, t), c.original = l, c.tabstop = i, f.push(c), i != e ? i.unshift(c) : i[s] = c, l.fmtString || i.firstNonLinked && r ? (c.linked = !0, i.hasLinkedRanges = !0) : i.firstNonLinked || (i.firstNonLinked = c)
          }
          i.firstNonLinked || (i.hasLinkedRanges = !1), i === e && (a.push(i), this.$openTabstops[n] = i), this.addTabstopMarkers(i), i.rangeList = i.rangeList || new u, i.rangeList.$bias = 0, i.rangeList.addList(i)
        }, this), a.length > 2 && (this.tabstops.length && a.push(a.splice(2, 1)[0]), this.tabstops.splice.apply(this.tabstops, a))
      }, this.addTabstopMarkers = function(e) {
        var t = this.editor.session;
        e.forEach(function(e) {
          e.markerId || (e.markerId = t.addMarker(e, "ace_snippet-marker", "text"))
        })
      }, this.removeTabstopMarkers = function(e) {
        var t = this.editor.session;
        e.forEach(function(e) {
          t.removeMarker(e.markerId), e.markerId = null
        })
      }, this.removeRange = function(e) {
        var t = e.tabstop.indexOf(e);
        t != -1 && e.tabstop.splice(t, 1), t = this.ranges.indexOf(e), t != -1 && this.ranges.splice(t, 1), t = e.tabstop.rangeList.ranges.indexOf(e), t != -1 && e.tabstop.splice(t, 1), this.editor.session.removeMarker(e.markerId), e.tabstop.length || (t = this.tabstops.indexOf(e.tabstop), t != -1 && this.tabstops.splice(t, 1), this.tabstops.length || this.detach())
      }, this.keyboardHandler = new a, this.keyboardHandler.bindKeys({
        Tab: function(e) {
          if (t.snippetManager && t.snippetManager.expandWithTab(e)) return;
          e.tabstopManager.tabNext(1), e.renderer.scrollCursorIntoView()
        },
        "Shift-Tab": function(e) {
          e.tabstopManager.tabNext(-1), e.renderer.scrollCursorIntoView()
        },
        Esc: function(e) {
          e.tabstopManager.detach()
        }
      })
    }).call(d.prototype);
    var v = function(e, t) {
        e.row == 0 && (e.column += t.column), e.row += t.row
      },
      m = function(e, t) {
        e.row == t.row && (e.column -= t.column), e.row -= t.row
      };
    e("./lib/dom").importCssString(".ace_snippet-marker {    -moz-box-sizing: border-box;    box-sizing: border-box;    background: rgba(194, 193, 208, 0.09);    border: 1px dotted rgba(211, 208, 235, 0.62);    position: absolute;}"), t.snippetManager = new p;
    var g = e("./editor").Editor;
    (function() {
      this.insertSnippet = function(e, n) {
        return t.snippetManager.insertSnippet(this, e, n)
      }, this.expandSnippet = function(e) {
        return t.snippetManager.expandWithTab(this, e)
      }
    }).call(g.prototype)
  }), define("ace/autocomplete/popup", ["require", "exports", "module", "ace/virtual_renderer", "ace/editor", "ace/range", "ace/lib/event", "ace/lib/lang", "ace/lib/dom"], function(e, t, n) {
    "use strict";
    var r = e("../virtual_renderer").VirtualRenderer,
      i = e("../editor").Editor,
      s = e("../range").Range,
      o = e("../lib/event"),
      u = e("../lib/lang"),
      a = e("../lib/dom"),
      f = function(e) {
        var t = new r(e);
        t.$maxLines = 4;
        var n = new i(t);
        return n.setHighlightActiveLine(!1), n.setShowPrintMargin(!1), n.renderer.setShowGutter(!1), n.renderer.setHighlightGutterLine(!1), n.$mouseHandler.$focusTimeout = 0, n.$highlightTagPending = !0, n
      },
      l = function(e) {
        var t = a.createElement("div"),
          n = new f(t);
        e && e.appendChild(t), t.style.display = "none", n.renderer.content.style.cursor = "default", n.renderer.setStyle("ace_autocomplete"), n.setOption("displayIndentGuides", !1), n.setOption("dragDelay", 150);
        var r = function() {};
        n.focus = r, n.$isFocused = !0, n.renderer.$cursorLayer.restartTimer = r, n.renderer.$cursorLayer.element.style.opacity = 0, n.renderer.$maxLines = 8, n.renderer.$keepTextAreaAtCursor = !1, n.setHighlightActiveLine(!1), n.session.highlight(""), n.session.$searchHighlight.clazz = "ace_highlight-marker", n.on("mousedown", function(e) {
          var t = e.getDocumentPosition();
          n.selection.moveToPosition(t), c.start.row = c.end.row = t.row, e.stop()
        });
        var i, l = new s(-1, 0, -1, Infinity),
          c = new s(-1, 0, -1, Infinity);
        c.id = n.session.addMarker(c, "ace_active-line", "fullLine"), n.setSelectOnHover = function(e) {
          e ? l.id && (n.session.removeMarker(l.id), l.id = null) : l.id = n.session.addMarker(l, "ace_line-hover", "fullLine")
        }, n.setSelectOnHover(!1), n.on("mousemove", function(e) {
          if (!i) {
            i = e;
            return
          }
          if (i.x == e.x && i.y == e.y) return;
          i = e, i.scrollTop = n.renderer.scrollTop;
          var t = i.getDocumentPosition().row;
          l.start.row != t && (l.id || n.setRow(t), p(t))
        }), n.renderer.on("beforeRender", function() {
          if (i && l.start.row != -1) {
            i.$pos = null;
            var e = i.getDocumentPosition().row;
            l.id || n.setRow(e), p(e, !0)
          }
        }), n.renderer.on("afterRender", function() {
          var e = n.getRow(),
            t = n.renderer.$textLayer,
            r = t.element.childNodes[e - t.config.firstRow];
          r !== t.selectedNode && t.selectedNode && a.removeCssClass(t.selectedNode, "ace_selected"), t.selectedNode = r, r && a.addCssClass(r, "ace_selected")
        });
        var h = function() {
            p(-1)
          },
          p = function(e, t) {
            e !== l.start.row && (l.start.row = l.end.row = e, t || n.session._emit("changeBackMarker"), n._emit("changeHoverMarker"))
          };
        n.getHoveredRow = function() {
          return l.start.row
        }, o.addListener(n.container, "mouseout", h), n.on("hide", h), n.on("changeSelection", h), n.session.doc.getLength = function() {
          return n.data.length
        }, n.session.doc.getLine = function(e) {
          var t = n.data[e];
          return typeof t == "string" ? t : t && t.value || ""
        };
        var d = n.session.bgTokenizer;
        return d.$tokenizeRow = function(e) {
          function s(e, n) {
            e && r.push({
              type: (t.className || "") + (n || ""),
              value: e
            })
          }
          var t = n.data[e],
            r = [];
          if (!t) return r;
          typeof t == "string" && (t = {
            value: t
          });
          var i = t.caption || t.value || t.name,
            o = i.toLowerCase(),
            u = (n.filterText || "").toLowerCase(),
            a = 0,
            f = 0;
          for (var l = 0; l <= u.length; l++)
            if (l != f && (t.matchMask & 1 << l || l == u.length)) {
              var c = u.slice(f, l);
              f = l;
              var h = o.indexOf(c, a);
              if (h == -1) continue;
              s(i.slice(a, h), ""), a = h + c.length, s(i.slice(h, a), "completion-highlight")
            } return s(i.slice(a, i.length), ""), t.meta && r.push({
            type: "completion-meta",
            value: t.meta
          }), t.message && r.push({
            type: "completion-message",
            value: t.message
          }), r
        }, d.$updateOnChange = r, d.start = r, n.session.$computeWidth = function() {
          return this.screenWidth = 0
        }, n.isOpen = !1, n.isTopdown = !1, n.autoSelect = !0, n.filterText = "", n.data = [], n.setData = function(e, t) {
          n.filterText = t || "", n.setValue(u.stringRepeat("\n", e.length), -1), n.data = e || [], n.setRow(0)
        }, n.getData = function(e) {
          return n.data[e]
        }, n.getRow = function() {
          return c.start.row
        }, n.setRow = function(e) {
          e = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length, e)), c.start.row != e && (n.selection.clearSelection(), c.start.row = c.end.row = e || 0, n.session._emit("changeBackMarker"), n.moveCursorTo(e || 0, 0), n.isOpen && n._signal("select"))
        }, n.on("changeSelection", function() {
          n.isOpen && n.setRow(n.selection.lead.row), n.renderer.scrollCursorIntoView()
        }), n.hide = function() {
          this.container.style.display = "none", this._signal("hide"), n.isOpen = !1
        }, n.show = function(e, t, r) {
          var s = this.container,
            o = window.innerHeight,
            u = window.innerWidth,
            a = this.renderer,
            f = a.$maxLines * t * 1.4,
            l = e.top + this.$borderSize,
            c = l > o / 2 && !r;
          c && l + t + f > o ? (a.$maxPixelHeight = l - 2 * this.$borderSize, s.style.top = "", s.style.bottom = o - l + "px", n.isTopdown = !1) : (l += t, a.$maxPixelHeight = o - l - .2 * t, s.style.top = l + "px", s.style.bottom = "", n.isTopdown = !0), s.style.display = "";
          var h = e.left;
          h + s.offsetWidth > u && (h = u - s.offsetWidth), s.style.left = h + "px", this._signal("show"), i = null, n.isOpen = !0
        }, n.goTo = function(e) {
          var t = this.getRow(),
            n = this.session.getLength() - 1;
          switch (e) {
            case "up":
              t = t <= 0 ? n : t - 1;
              break;
            case "down":
              t = t >= n ? -1 : t + 1;
              break;
            case "start":
              t = 0;
              break;
            case "end":
              t = n
          }
          this.setRow(t)
        }, n.getTextLeftOffset = function() {
          return this.$borderSize + this.renderer.$padding + this.$imageSize
        }, n.$imageSize = 0, n.$borderSize = 1, n
      };
    a.importCssString(".ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #CAD6FA;    z-index: 1;}.ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {    background-color: #3a674e;}.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid #abbffe;    margin-top: -1px;    background: rgba(233,233,253,0.4);    position: absolute;    z-index: 2;}.ace_dark.ace_editor.ace_autocomplete .ace_line-hover {    border: 1px solid rgba(109, 150, 13, 0.8);    background: rgba(58, 103, 78, 0.62);}.ace_completion-meta {    opacity: 0.5;    margin: 0.9em;}.ace_completion-message {    color: blue;}.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #2d69c7;}.ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{    color: #93ca12;}.ace_editor.ace_autocomplete {    width: 300px;    z-index: 200000;    border: 1px lightgray solid;    position: fixed;    box-shadow: 2px 3px 5px rgba(0,0,0,.2);    line-height: 1.4;    background: #fefefe;    color: #111;}.ace_dark.ace_editor.ace_autocomplete {    border: 1px #484747 solid;    box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);    line-height: 1.4;    background: #25282c;    color: #c1c1c1;}", "autocompletion.css"), t.AcePopup = l, t.$singleLineEditor = f
  }), define("ace/autocomplete/util", ["require", "exports", "module"], function(e, t, n) {
    "use strict";
    t.parForEach = function(e, t, n) {
      var r = 0,
        i = e.length;
      i === 0 && n();
      for (var s = 0; s < i; s++) t(e[s], function(e, t) {
        r++, r === i && n(e, t)
      })
    };
    var r = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
    t.retrievePrecedingIdentifier = function(e, t, n) {
      n = n || r;
      var i = [];
      for (var s = t - 1; s >= 0; s--) {
        if (!n.test(e[s])) break;
        i.push(e[s])
      }
      return i.reverse().join("")
    }, t.retrieveFollowingIdentifier = function(e, t, n) {
      n = n || r;
      var i = [];
      for (var s = t; s < e.length; s++) {
        if (!n.test(e[s])) break;
        i.push(e[s])
      }
      return i
    }, t.getCompletionPrefix = function(e) {
      var t = e.getCursorPosition(),
        n = e.session.getLine(t.row),
        r;
      return e.completers.forEach(function(e) {
        e.identifierRegexps && e.identifierRegexps.forEach(function(e) {
          !r && e && (r = this.retrievePrecedingIdentifier(n, t.column, e))
        }.bind(this))
      }.bind(this)), r || this.retrievePrecedingIdentifier(n, t.column)
    }
  }), define("ace/autocomplete", ["require", "exports", "module", "ace/keyboard/hash_handler", "ace/autocomplete/popup", "ace/autocomplete/util", "ace/lib/lang", "ace/lib/dom", "ace/snippets", "ace/config"], function(e, t, n) {
    "use strict";
    var r = e("./keyboard/hash_handler").HashHandler,
      i = e("./autocomplete/popup").AcePopup,
      s = e("./autocomplete/util"),
      o = e("./lib/lang"),
      u = e("./lib/dom"),
      a = e("./snippets").snippetManager,
      f = e("./config"),
      l = function() {
        this.autoInsert = !1, this.autoSelect = !0, this.exactMatch = !1, this.gatherCompletionsId = 0, this.keyboardHandler = new r, this.keyboardHandler.bindKeys(this.commands), this.blurListener = this.blurListener.bind(this), this.changeListener = this.changeListener.bind(this), this.mousedownListener = this.mousedownListener.bind(this), this.mousewheelListener = this.mousewheelListener.bind(this), this.changeTimer = o.delayedCall(function() {
          this.updateCompletions(!0)
        }.bind(this)), this.tooltipTimer = o.delayedCall(this.updateDocTooltip.bind(this), 50)
      };
    (function() {
      this.$init = function() {
        return this.popup = new i(document.body || document.documentElement), this.popup.on("click", function(e) {
          this.insertMatch(), e.stop()
        }.bind(this)), this.popup.focus = this.editor.focus.bind(this.editor), this.popup.on("show", this.tooltipTimer.bind(null, null)), this.popup.on("select", this.tooltipTimer.bind(null, null)), this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null)), this.popup
      }, this.getPopup = function() {
        return this.popup || this.$init()
      }, this.openPopup = function(e, t, n) {
        this.popup || this.$init(), this.popup.autoSelect = this.autoSelect, this.popup.setData(this.completions.filtered, this.completions.filterText), e.keyBinding.addKeyboardHandler(this.keyboardHandler);
        var r = e.renderer;
        this.popup.setRow(this.autoSelect ? 0 : -1);
        if (!n) {
          this.popup.setTheme(e.getTheme()), this.popup.setFontSize(e.getFontSize());
          var i = r.layerConfig.lineHeight,
            s = r.$cursorLayer.getPixelPosition(this.base, !0);
          s.left -= this.popup.getTextLeftOffset();
          var o = e.container.getBoundingClientRect();
          s.top += o.top - r.layerConfig.offset, s.left += o.left - e.renderer.scrollLeft, s.left += r.gutterWidth, this.popup.show(s, i)
        }
        else n && !t && this.detach();
        this.changeTimer.cancel()
      }, this.detach = function() {
        this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler), this.editor.off("changeSelection", this.changeListener), this.editor.off("blur", this.blurListener), this.editor.off("mousedown", this.mousedownListener), this.editor.off("mousewheel", this.mousewheelListener), this.changeTimer.cancel(), this.hideDocTooltip(), this.gatherCompletionsId += 1, this.popup && this.popup.isOpen && this.popup.hide(), this.base && this.base.detach(), this.activated = !1, this.completions = this.base = null
      }, this.changeListener = function(e) {
        var t = this.editor.selection.lead;
        (t.row != this.base.row || t.column < this.base.column) && this.detach(), this.activated ? this.changeTimer.schedule() : this.detach()
      }, this.blurListener = function(e) {
        var t = document.activeElement,
          n = this.editor.textInput.getElement(),
          r = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget),
          i = this.popup && this.popup.container;
        t != n && t.parentNode != i && !r && t != this.tooltipNode && e.relatedTarget != n && this.detach()
      }, this.mousedownListener = function(e) {
        this.detach()
      }, this.mousewheelListener = function(e) {
        this.detach()
      }, this.goTo = function(e) {
        this.popup.goTo(e)
      }, this.insertMatch = function(e, t) {
        e || (e = this.popup.getData(this.popup.getRow()));
        if (!e) return !1;
        var n = this.completions;
        this.editor.startOperation({
          command: {
            name: "insertMatch"
          }
        });
        if (e.completer && e.completer.insertMatch) e.completer.insertMatch(this.editor, e);
        else {
          if (n.filterText) {
            var r = this.editor.selection.getAllRanges();
            for (var i = 0, s; s = r[i]; i++) s.start.column -= n.filterText.length, this.editor.session.remove(s)
          }
          e.snippet ? a.insertSnippet(this.editor, e.snippet) : this.editor.execCommand("insertstring", e.value || e)
        }
        this.completions == n && this.detach(), this.editor.endOperation()
      }, this.commands = {
        Up: function(e) {
          e.completer.goTo("up")
        },
        Down: function(e) {
          e.completer.goTo("down")
        },
        "Ctrl-Up|Ctrl-Home": function(e) {
          e.completer.goTo("start")
        },
        "Ctrl-Down|Ctrl-End": function(e) {
          e.completer.goTo("end")
        },
        Esc: function(e) {
          e.completer.detach()
        },
        Return: function(e) {
          return e.completer.insertMatch()
        },
        "Shift-Return": function(e) {
          e.completer.insertMatch(null, {
            deleteSuffix: !0
          })
        },
        Tab: function(e) {
          var t = e.completer.insertMatch();
          if (!!t || !!e.tabstopManager) return t;
          e.completer.goTo("down")
        },
        PageUp: function(e) {
          e.completer.popup.gotoPageUp()
        },
        PageDown: function(e) {
          e.completer.popup.gotoPageDown()
        }
      }, this.gatherCompletions = function(e, t) {
        var n = e.getSession(),
          r = e.getCursorPosition(),
          i = s.getCompletionPrefix(e);
        this.base = n.doc.createAnchor(r.row, r.column - i.length), this.base.$insertRight = !0;
        var o = [],
          u = e.completers.length;
        return e.completers.forEach(function(a, f) {
          a.getCompletions(e, n, r, i, function(n, r) {
            !n && r && (o = o.concat(r)), t(null, {
              prefix: s.getCompletionPrefix(e),
              matches: o,
              finished: --u === 0
            })
          })
        }), !0
      }, this.showPopup = function(e, t) {
        this.editor && this.detach(), this.activated = !0, this.editor = e, e.completer != this && (e.completer && e.completer.detach(), e.completer = this), e.on("changeSelection", this.changeListener), e.on("blur", this.blurListener), e.on("mousedown", this.mousedownListener), e.on("mousewheel", this.mousewheelListener), this.updateCompletions(!1, t)
      }, this.updateCompletions = function(e, t) {
        if (e && this.base && this.completions) {
          var n = this.editor.getCursorPosition(),
            r = this.editor.session.getTextRange({
              start: this.base,
              end: n
            });
          if (r == this.completions.filterText) return;
          this.completions.setFilter(r);
          if (!this.completions.filtered.length) return this.detach();
          if (this.completions.filtered.length == 1 && this.completions.filtered[0].value == r && !this.completions.filtered[0].snippet) return this.detach();
          this.openPopup(this.editor, r, e);
          return
        }
        if (t && t.matches) {
          var n = this.editor.getSelectionRange().start;
          return this.base = this.editor.session.doc.createAnchor(n.row, n.column), this.base.$insertRight = !0, this.completions = new c(t.matches), this.openPopup(this.editor, "", e)
        }
        var i = this.gatherCompletionsId;
        this.gatherCompletions(this.editor, function(t, n) {
          var r = function() {
              if (!n.finished) return;
              return this.detach()
            }.bind(this),
            s = n.prefix,
            o = n && n.matches;
          if (!o || !o.length) return r();
          if (s.indexOf(n.prefix) !== 0 || i != this.gatherCompletionsId) return;
          this.completions = new c(o), this.exactMatch && (this.completions.exactMatch = !0), this.completions.setFilter(s);
          var u = this.completions.filtered;
          if (!u.length) return r();
          if (u.length == 1 && u[0].value == s && !u[0].snippet) return r();
          if (this.autoInsert && u.length == 1 && n.finished) return this.insertMatch(u[0]);
          this.openPopup(this.editor, s, e)
        }.bind(this))
      }, this.cancelContextMenu = function() {
        this.editor.$mouseHandler.cancelContextMenu()
      }, this.updateDocTooltip = function() {
        var e = this.popup,
          t = e.data,
          n = t && (t[e.getHoveredRow()] || t[e.getRow()]),
          r = null;
        if (!n || !this.editor || !this.popup.isOpen) return this.hideDocTooltip();
        this.editor.completers.some(function(e) {
          return e.getDocTooltip && (r = e.getDocTooltip(n)), r
        }), !r && typeof n != "string" && (r = n), typeof r == "string" && (r = {
          docText: r
        });
        if (!r || !r.docHTML && !r.docText) return this.hideDocTooltip();
        this.showDocTooltip(r)
      }, this.showDocTooltip = function(e) {
        this.tooltipNode || (this.tooltipNode = u.createElement("div"), this.tooltipNode.className = "ace_tooltip ace_doc-tooltip", this.tooltipNode.style.margin = 0, this.tooltipNode.style.pointerEvents = "auto", this.tooltipNode.tabIndex = -1, this.tooltipNode.onblur = this.blurListener.bind(this), this.tooltipNode.onclick = this.onTooltipClick.bind(this));
        var t = this.tooltipNode;
        e.docHTML ? t.innerHTML = e.docHTML : e.docText && (t.textContent = e.docText), t.parentNode || document.body.appendChild(t);
        var n = this.popup,
          r = n.container.getBoundingClientRect();
        t.style.top = n.container.style.top, t.style.bottom = n.container.style.bottom, t.style.display = "block", window.innerWidth - r.right < 320 ? r.left < 320 ? n.isTopdown ? (t.style.top = r.bottom + "px", t.style.left = r.left + "px", t.style.right = "", t.style.bottom = "") : (t.style.top = n.container.offsetTop - t.offsetHeight + "px", t.style.left = r.left + "px", t.style.right = "", t.style.bottom = "") : (t.style.right = window.innerWidth - r.left + "px", t.style.left = "") : (t.style.left = r.right + 1 + "px", t.style.right = "")
      }, this.hideDocTooltip = function() {
        this.tooltipTimer.cancel();
        if (!this.tooltipNode) return;
        var e = this.tooltipNode;
        !this.editor.isFocused() && document.activeElement == e && this.editor.focus(), this.tooltipNode = null, e.parentNode && e.parentNode.removeChild(e)
      }, this.onTooltipClick = function(e) {
        var t = e.target;
        while (t && t != this.tooltipNode) {
          if (t.nodeName == "A" && t.href) {
            t.rel = "noreferrer", t.target = "_blank";
            break
          }
          t = t.parentNode
        }
      }, this.destroy = function() {
        this.detach();
        if (this.popup) {
          this.popup.destroy();
          var e = this.popup.container;
          e && e.parentNode && e.parentNode.removeChild(e)
        }
        this.editor && this.editor.completer == this && this.editor.completer == null, this.popup = null
      }
    }).call(l.prototype), l.for = function(e) {
      return e.completer ? e.completer : (f.get("sharedPopups") ? (l.$shared || (l.$sharedInstance = new l), e.completer = l.$sharedInstance) : (e.completer = new l, e.once("destroy", function(e, t) {
        t.completer.destroy()
      })), e.completer)
    }, l.startCommand = {
      name: "startAutocomplete",
      exec: function(e, t) {
        var n = l.for(e);
        n.autoInsert = !1, n.autoSelect = !0, n.showPopup(e, t), n.cancelContextMenu()
      },
      bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
    };
    var c = function(e, t) {
      this.all = e, this.filtered = e, this.filterText = t || "", this.exactMatch = !1
    };
    (function() {
      this.setFilter = function(e) {
        if (e.length > this.filterText && e.lastIndexOf(this.filterText, 0) === 0) var t = this.filtered;
        else var t = this.all;
        this.filterText = e, t = this.filterCompletions(t, this.filterText), t = t.sort(function(e, t) {
          return t.exactMatch - e.exactMatch || t.$score - e.$score || (e.caption || e.value).localeCompare(t.caption || t.value)
        });
        var n = null;
        t = t.filter(function(e) {
          var t = e.snippet || e.caption || e.value;
          return t === n ? !1 : (n = t, !0)
        }), this.filtered = t
      }, this.filterCompletions = function(e, t) {
        var n = [],
          r = t.toUpperCase(),
          i = t.toLowerCase();
        e: for (var s = 0, o; o = e[s]; s++) {
          var u = o.caption || o.value || o.snippet;
          if (!u) continue;
          var a = -1,
            f = 0,
            l = 0,
            c, h;
          if (this.exactMatch) {
            if (t !== u.substr(0, t.length)) continue e
          }
          else {
            var p = u.toLowerCase().indexOf(i);
            if (p > -1) l = p;
            else
              for (var d = 0; d < t.length; d++) {
                var v = u.indexOf(i[d], a + 1),
                  m = u.indexOf(r[d], a + 1);
                c = v >= 0 ? m < 0 || v < m ? v : m : m;
                if (c < 0) continue e;
                h = c - a - 1, h > 0 && (a === -1 && (l += 10), l += h, f |= 1 << d), a = c
              }
          }
          o.matchMask = f, o.exactMatch = l ? 0 : 1, o.$score = (o.score || 0) - l, n.push(o)
        }
        return n
      }
    }).call(c.prototype), t.Autocomplete = l, t.FilteredList = c
  }), define("ace/autocomplete/text_completer", ["require", "exports", "module", "ace/range"], function(e, t, n) {
    function s(e, t) {
      var n = e.getTextRange(r.fromPoints({
        row: 0,
        column: 0
      }, t));
      return n.split(i).length - 1
    }
  
    function o(e, t) {
      var n = s(e, t),
        r = e.getValue().split(i),
        o = Object.create(null),
        u = r[n];
      return r.forEach(function(e, t) {
        if (!e || e === u) return;
        var i = Math.abs(n - t),
          s = r.length - i;
        o[e] ? o[e] = Math.max(s, o[e]) : o[e] = s
      }), o
    }
    var r = e("../range").Range,
      i = /[^a-zA-Z_0-9\$\-\u00C0-\u1FFF\u2C00-\uD7FF\w]+/;
    t.getCompletions = function(e, t, n, r, i) {
      var s = o(t, n),
        u = Object.keys(s);
      i(null, u.map(function(e) {
        return {
          caption: e,
          value: e,
          score: s[e],
          meta: "local"
        }
      }))
    }
  }), define("ace/ext/language_tools", ["require", "exports", "module", "ace/snippets", "ace/autocomplete", "ace/config", "ace/lib/lang", "ace/autocomplete/util", "ace/autocomplete/text_completer", "ace/editor", "ace/config"], function(e, t, n) {
    "use strict";
    var r = e("../snippets").snippetManager,
      i = e("../autocomplete").Autocomplete,
      s = e("../config"),
      o = e("../lib/lang"),
      u = e("../autocomplete/util"),
      a = e("../autocomplete/text_completer"),
      f = {
        getCompletions: function(e, t, n, r, i) {
          if (t.$mode.completer) return t.$mode.completer.getCompletions(e, t, n, r, i);
          var s = e.session.getState(n.row),
            o = t.$mode.getCompletions(s, t, n, r);
          i(null, o)
        }
      },
      l = {
        getCompletions: function(e, t, n, i, s) {
          var o = [],
            u = t.getTokenAt(n.row, n.column);
          u && u.type.match(/(tag-name|tag-open|tag-whitespace|attribute-name|attribute-value)\.xml$/) ? o.push("html-tag") : o = r.getActiveScopes(e);
          var a = r.snippetMap,
            f = [];
          o.forEach(function(e) {
            var t = a[e] || [];
            for (var n = t.length; n--;) {
              var r = t[n],
                i = r.name || r.tabTrigger;
              if (!i) continue;
              f.push({
                caption: i,
                snippet: r.content,
                meta: r.tabTrigger && !r.name ? r.tabTrigger + "\u21e5 " : "snippet",
                type: "snippet"
              })
            }
          }, this), s(null, f)
        },
        getDocTooltip: function(e) {
          e.type == "snippet" && !e.docHTML && (e.docHTML = ["<b>", o.escapeHTML(e.caption), "</b>", "<hr></hr>", o.escapeHTML(e.snippet)].join(""))
        }
      },
      c = [l, a, f];
    t.setCompleters = function(e) {
      c.length = 0, e && c.push.apply(c, e)
    }, t.addCompleter = function(e) {
      c.push(e)
    }, t.textCompleter = a, t.keyWordCompleter = f, t.snippetCompleter = l;
    var h = {
        name: "expandSnippet",
        exec: function(e) {
          return r.expandWithTab(e)
        },
        bindKey: "Tab"
      },
      p = function(e, t) {
        d(t.session.$mode)
      },
      d = function(e) {
        typeof e == "string" && (e = s.$modes[e]);
        if (!e) return;
        r.files || (r.files = {}), v(e.$id, e.snippetFileId), e.modes && e.modes.forEach(d)
      },
      v = function(e, t) {
        if (!t || !e || r.files[e]) return;
        r.files[e] = {}, s.loadModule(t, function(t) {
          if (!t) return;
          r.files[e] = t, !t.snippets && t.snippetText && (t.snippets = r.parseSnippetFile(t.snippetText)), r.register(t.snippets || [], t.scope), t.includeScopes && (r.snippetMap[t.scope].includeScopes = t.includeScopes, t.includeScopes.forEach(function(e) {
            d("ace/mode/" + e)
          }))
        })
      },
      m = function(e) {
        var t = e.editor,
          n = t.completer && t.completer.activated;
        if (e.command.name === "backspace") n && !u.getCompletionPrefix(t) && t.completer.detach();
        else if (e.command.name === "insertstring") {
          var r = u.getCompletionPrefix(t);
          if (r && !n) {
            var s = i.for(t);
            s.autoInsert = !1, s.showPopup(t)
          }
        }
      },
      g = e("../editor").Editor;
    e("../config").defineOptions(g.prototype, "editor", {
      enableBasicAutocompletion: {
        set: function(e) {
          e ? (this.completers || (this.completers = Array.isArray(e) ? e : c), this.commands.addCommand(i.startCommand)) : this.commands.removeCommand(i.startCommand)
        },
        value: !1
      },
      enableLiveAutocompletion: {
        set: function(e) {
          e ? (this.completers || (this.completers = Array.isArray(e) ? e : c), this.commands.on("afterExec", m)) : this.commands.removeListener("afterExec", m)
        },
        value: !1
      },
      enableSnippets: {
        set: function(e) {
          e ? (this.commands.addCommand(h), this.on("changeMode", p), p(null, this)) : (this.commands.removeCommand(h), this.off("changeMode", p))
        },
        value: !1
      }
    })
  });
  (function() {
    window.require(["ace/ext/language_tools"], function(m) {
      if (typeof module == "object" && typeof exports == "object" && module) {
        module.exports = m;
      }
    });
  })();