text: (function (mod) {
      if (typeof exports == "object" && typeof module == "object") // CommonJS
          mod(require("../../lib/codemirror"));
      else if (typeof define == "function" && define.amd) // AMD
          define(["../../lib/codemirror"], mod);
      else // Plain browser env
          mod(CodeMirror);
  })(function (CodeMirror) {
      "use strict";
  
      CodeMirror.defineMode("q", function (config) {
          var indentUnit = config.indentUnit,
              curPunc,
              keywords = buildRE(["abs", "acos", "aj", "aj0", "all", "and", "any", "asc", "asin", "asof", "atan", "attr", "avg", "avgs", "bin", "by", "ceiling", "cols", "cor", "cos", "count", "cov", "cross", "csv", "cut", "delete", "deltas", "desc", "dev", "differ", "distinct", "div", "do", "each", "ej", "enlist", "eval", "except", "exec", "exit", "exp", "fby", "fills", "first", "fkeys", "flip", "floor", "from", "get", "getenv", "group", "gtime", "hclose", "hcount", "hdel", "hopen", "hsym", "iasc", "idesc", "if", "ij", "in", "insert", "inter", "inv", "key", "keys", "last", "like", "list", "lj", "load", "log", "lower", "lsq", "ltime", "ltrim", "mavg", "max", "maxs", "mcount", "md5", "mdev", "med", "meta", "min", "mins", "mmax", "mmin", "mmu", "mod", "msum", "neg", "next", "not", "null", "or", "over", "parse", "peach", "pj", "plist", "prd", "prds", "prev", "prior", "rand", "rank", "ratios", "raze", "read0", "read1", "reciprocal", "reverse", "rload", "rotate", "rsave", "rtrim", "save", "scan", "select", "set", "setenv", "show", "signum", "sin", "sqrt", "ss", "ssr", "string", "sublist", "sum", "sums", "sv", "system", "tables", "tan", "til", "trim", "txf", "type", "uj", "ungroup", "union", "update", "upper", "upsert", "value", "var", "view", "views", "vs", "wavg", "where", "where", "while", "within", "wj", "wj1", "wsum", "xasc", "xbar", "xcol", "xcols", "xdesc", "xexp", "xgroup", "xkey", "xlog", "xprev", "xrank"]),
              E = /[|/&^!+:\\\-*%$=~#;@><,?_\'\"\[\(\]\)\s{}]/;
  
          function buildRE(w) {
              return new RegExp("^(" + w.join("|") + ")$");
          }
  
          function tokenBase(stream, state) {
              var sol = stream.sol(), c = stream.next();
              curPunc = null;
              if (sol)
                  if (c == "/")
                      return (state.tokenize = tokenLineComment)(stream, state);
                  else if (c == "\\") {
                      if (stream.eol() || /\s/.test(stream.peek()))
                          return stream.skipToEnd(), /^\\\s*$/.test(stream.current()) ? (state.tokenize = tokenCommentToEOF)(stream, state) : state.tokenize = tokenBase, "comment";
                      else
                          return state.tokenize = tokenBase, "builtin";
                  }
              if (/\s/.test(c))
                  return stream.peek() == "/" ? (stream.skipToEnd(), "comment") : "whitespace";
              if (c == '"')
                  return (state.tokenize = tokenString)(stream, state);
              if (c == '`')
                  return stream.eatWhile(/[A-Z|a-z|\d|_|:|\/|\.]/), "symbol";
              if (("." == c && /\d/.test(stream.peek())) || /\d/.test(c)) {
                  var t = null;
                  stream.backUp(1);
                  if (stream.match(/^\d{4}\.\d{2}(m|\.\d{2}([D|T](\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)?)?)/)
                      || stream.match(/^\d+D(\d{2}(:\d{2}(:\d{2}(\.\d{1,9})?)?)?)/)
                      || stream.match(/^\d{2}:\d{2}(:\d{2}(\.\d{1,9})?)?/)
                      || stream.match(/^\d+[ptuv]{1}/))
                      t = "temporal";
                  else if (stream.match(/^0[NwW]{1}/)
                      || stream.match(/^0x[\d|a-f|A-F]*/)
                      || stream.match(/^[0|1]+[b]{1}/)
                      || stream.match(/^\d+[chijn]{1}/)
                      || stream.match(/-?\d*(\.\d*)?(e[+\-]?\d+)?(e|f)?/))
                      t = "number";
                  return (t && (!(c = stream.peek()) || E.test(c))) ? t : (stream.next(), "error");
              }
              if (/[A-Z|a-z]|\./.test(c))
                  return stream.eatWhile(/[A-Z|a-z|\.|_|\d]/), keywords.test(stream.current()) ? "keyword" : "variable";
              if (/[|/&^!+:\\\-*%$=~#;@><\.,?_\']/.test(c))
                  return null;
              if (/[{}\(\[\]\)]/.test(c))
                  return null;
              return "error";
          }
  
          function tokenLineComment(stream, state) {
              return stream.skipToEnd(), /\/\s*$/.test(stream.current()) ? (state.tokenize = tokenBlockComment)(stream, state) : (state.tokenize = tokenBase), "comment";
          }
  
          function tokenBlockComment(stream, state) {
              var f = stream.sol() && stream.peek() == "\\";
              stream.skipToEnd();
              if (f && /^\\\s*$/.test(stream.current()))
                  state.tokenize = tokenBase;
              return "comment";
          }
  
          function tokenCommentToEOF(stream) {
              return stream.skipToEnd(), "comment";
          }
  
          function tokenString(stream, state) {
              var escaped = false, next, end = false;
              while ((next = stream.next())) {
                  if (next == "\"" && !escaped) {
                      end = true;
                      break;
                  }
                  escaped = !escaped && next == "\\";
              }
              if (end) state.tokenize = tokenBase;
              return "string";
          }
  
          function pushContext(state, type, col) {
              state.context = {prev: state.context, indent: state.indent, col: col, type: type};
          }
  
          function popContext(state) {
              state.indent = state.context.indent;
              state.context = state.context.prev;
          }
  
          return {
              startState: function () {
                  return {
                      tokenize: tokenBase,
                      context: null,
                      indent: 0,
                      col: 0
                  };
              },
              token: function (stream, state) {
                  if (stream.sol()) {
                      if (state.context && state.context.align == null)
                          state.context.align = false;
                      state.indent = stream.indentation();
                  }
                  //if (stream.eatSpace()) return null;
                  var style = state.tokenize(stream, state);
                  if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") {
                      state.context.align = true;
                  }
                  if (curPunc == "(") pushContext(state, ")", stream.column());
                  else if (curPunc == "[") pushContext(state, "]", stream.column());
                  else if (curPunc == "{") pushContext(state, "}", stream.column());
                  else if (/[\]\}\)]/.test(curPunc)) {
                      while (state.context && state.context.type == "pattern") popContext(state);
                      if (state.context && curPunc == state.context.type) popContext(state);
                  }
                  else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state);
                  else if (/atom|string|variable/.test(style) && state.context) {
                      if (/[\}\]]/.test(state.context.type))
                          pushContext(state, "pattern", stream.column());
                      else if (state.context.type == "pattern" && !state.context.align) {
                          state.context.align = true;
                          state.context.col = stream.column();
                      }
                  }
                  return style;
              },
              indent: function (state, textAfter) {
                  var firstChar = textAfter && textAfter.charAt(0);
                  var context = state.context;
                  if (/[\]\}]/.test(firstChar))
                      while (context && context.type == "pattern") context = context.prev;
                  var closing = context && firstChar == context.type;
                  if (!context)
                      return 0;
                  else if (context.type == "pattern")
                      return context.col;
                  else if (context.align)
                      return context.col + (closing ? 0 : 1);
                  else
                      return context.indent + (closing ? 0 : indentUnit);
              }
          };
      });
      CodeMirror.defineMIME("text/x-q", "q");
  
  });
  