function words(e) {
  for (var m = {}, h = e.split(" "), g = 0; g < h.length; ++g) m[h[g]] = true;
  return m;
}
var blockKeywordsStr = "body catch class do else enum for foreach foreach_reverse if in interface mixin out scope struct switch try union unittest version while with", parserConfig = {
  keywords: words("abstract alias align asm assert auto break case cast cdouble cent cfloat const continue debug default delegate delete deprecated export extern final finally function goto immutable import inout invariant is lazy macro module new nothrow override package pragma private protected public pure ref return shared short static super synchronized template this throw typedef typeid typeof volatile __FILE__ __LINE__ __gshared __traits __vector __parameters " + blockKeywordsStr),
  blockKeywords: words(blockKeywordsStr),
  builtin: words("bool byte char creal dchar double float idouble ifloat int ireal long real short ubyte ucent uint ulong ushort wchar wstring void size_t sizediff_t"),
  atoms: words("exit failure success true false null"),
  hooks: { "@": function(e, m) {
    return e.eatWhile(/[\w\$_]/), "meta";
  } }
}, statementIndentUnit = parserConfig.statementIndentUnit, keywords = parserConfig.keywords, builtin = parserConfig.builtin, blockKeywords = parserConfig.blockKeywords, atoms = parserConfig.atoms, hooks = parserConfig.hooks, multiLineStrings = parserConfig.multiLineStrings, isOperatorChar = /[+\-*&%=<>!?|\/]/, curPunc;
function tokenBase(e, m) {
  var h = e.next();
  if (hooks[h]) {
    var g = hooks[h](e, m);
    if (g !== false) return g;
  }
  if (h == '"' || h == "'" || h == "`") return m.tokenize = tokenString(h), m.tokenize(e, m);
  if (/[\[\]{}\(\),;\:\.]/.test(h)) return curPunc = h, null;
  if (/\d/.test(h)) return e.eatWhile(/[\w\.]/), "number";
  if (h == "/") {
    if (e.eat("+")) return m.tokenize = tokenNestedComment, tokenNestedComment(e, m);
    if (e.eat("*")) return m.tokenize = tokenComment, tokenComment(e, m);
    if (e.eat("/")) return e.skipToEnd(), "comment";
  }
  if (isOperatorChar.test(h)) return e.eatWhile(isOperatorChar), "operator";
  e.eatWhile(/[\w\$_\xa1-\uffff]/);
  var b = e.current();
  return keywords.propertyIsEnumerable(b) ? (blockKeywords.propertyIsEnumerable(b) && (curPunc = "newstatement"), "keyword") : builtin.propertyIsEnumerable(b) ? (blockKeywords.propertyIsEnumerable(b) && (curPunc = "newstatement"), "builtin") : atoms.propertyIsEnumerable(b) ? "atom" : "variable";
}
function tokenString(e) {
  return function(m, h) {
    for (var g = false, _, v = false; (_ = m.next()) != null; ) {
      if (_ == e && !g) {
        v = true;
        break;
      }
      g = !g && _ == "\\";
    }
    return (v || !(g || multiLineStrings)) && (h.tokenize = null), "string";
  };
}
function tokenComment(e, m) {
  for (var h = false, g; g = e.next(); ) {
    if (g == "/" && h) {
      m.tokenize = null;
      break;
    }
    h = g == "*";
  }
  return "comment";
}
function tokenNestedComment(e, m) {
  for (var h = false, g; g = e.next(); ) {
    if (g == "/" && h) {
      m.tokenize = null;
      break;
    }
    h = g == "+";
  }
  return "comment";
}
function Context(e, m, h, g, _) {
  this.indented = e, this.column = m, this.type = h, this.align = g, this.prev = _;
}
function pushContext(e, m, h) {
  var g = e.indented;
  return e.context && e.context.type == "statement" && (g = e.context.indented), e.context = new Context(g, m, h, null, e.context);
}
function popContext(e) {
  var m = e.context.type;
  return (m == ")" || m == "]" || m == "}") && (e.indented = e.context.indented), e.context = e.context.prev;
}
const d = {
  name: "d",
  startState: function(e) {
    return {
      tokenize: null,
      context: new Context(-e, 0, "top", false),
      indented: 0,
      startOfLine: true
    };
  },
  token: function(e, m) {
    var h = m.context;
    if (e.sol() && (h.align ?? (h.align = false), m.indented = e.indentation(), m.startOfLine = true), e.eatSpace()) return null;
    curPunc = null;
    var g = (m.tokenize || tokenBase)(e, m);
    if (g == "comment" || g == "meta") return g;
    if (h.align ?? (h.align = true), (curPunc == ";" || curPunc == ":" || curPunc == ",") && h.type == "statement") popContext(m);
    else if (curPunc == "{") pushContext(m, e.column(), "}");
    else if (curPunc == "[") pushContext(m, e.column(), "]");
    else if (curPunc == "(") pushContext(m, e.column(), ")");
    else if (curPunc == "}") {
      for (; h.type == "statement"; ) h = popContext(m);
      for (h.type == "}" && (h = popContext(m)); h.type == "statement"; ) h = popContext(m);
    } else curPunc == h.type ? popContext(m) : ((h.type == "}" || h.type == "top") && curPunc != ";" || h.type == "statement" && curPunc == "newstatement") && pushContext(m, e.column(), "statement");
    return m.startOfLine = false, g;
  },
  indent: function(e, m, h) {
    if (e.tokenize != tokenBase && e.tokenize != null) return null;
    var _ = e.context, v = m && m.charAt(0);
    _.type == "statement" && v == "}" && (_ = _.prev);
    var y = v == _.type;
    return _.type == "statement" ? _.indented + (v == "{" ? 0 : statementIndentUnit || h.unit) : _.align ? _.column + (y ? 0 : 1) : _.indented + (y ? 0 : h.unit);
  },
  languageData: {
    indentOnInput: /^\s*[{}]$/,
    commentTokens: {
      line: "//",
      block: {
        open: "/*",
        close: "*/"
      }
    }
  }
};
export {
  d as t
};
