var __accessCheck = (obj, member, msg) => {
  if (!member.has(obj))
    throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
  __accessCheck(obj, member, "read from private field");
  return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
  if (member.has(obj))
    throw TypeError("Cannot add the same private member more than once");
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
  __accessCheck(obj, member, "write to private field");
  setter ? setter.call(obj, value) : member.set(obj, value);
  return value;
};

// node_modules/prettier/doc.mjs
var __defProp = Object.defineProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var public_exports = {};
__export(public_exports, {
  builders: () => builders,
  printer: () => printer,
  utils: () => utils
});
var DOC_TYPE_STRING = "string";
var DOC_TYPE_ARRAY = "array";
var DOC_TYPE_CURSOR = "cursor";
var DOC_TYPE_INDENT = "indent";
var DOC_TYPE_ALIGN = "align";
var DOC_TYPE_TRIM = "trim";
var DOC_TYPE_GROUP = "group";
var DOC_TYPE_FILL = "fill";
var DOC_TYPE_IF_BREAK = "if-break";
var DOC_TYPE_INDENT_IF_BREAK = "indent-if-break";
var DOC_TYPE_LINE_SUFFIX = "line-suffix";
var DOC_TYPE_LINE_SUFFIX_BOUNDARY = "line-suffix-boundary";
var DOC_TYPE_LINE = "line";
var DOC_TYPE_LABEL = "label";
var DOC_TYPE_BREAK_PARENT = "break-parent";
var VALID_OBJECT_DOC_TYPES = /* @__PURE__ */ new Set([
  DOC_TYPE_CURSOR,
  DOC_TYPE_INDENT,
  DOC_TYPE_ALIGN,
  DOC_TYPE_TRIM,
  DOC_TYPE_GROUP,
  DOC_TYPE_FILL,
  DOC_TYPE_IF_BREAK,
  DOC_TYPE_INDENT_IF_BREAK,
  DOC_TYPE_LINE_SUFFIX,
  DOC_TYPE_LINE_SUFFIX_BOUNDARY,
  DOC_TYPE_LINE,
  DOC_TYPE_LABEL,
  DOC_TYPE_BREAK_PARENT
]);
function getDocType(doc) {
  if (typeof doc === "string") {
    return DOC_TYPE_STRING;
  }
  if (Array.isArray(doc)) {
    return DOC_TYPE_ARRAY;
  }
  if (!doc) {
    return;
  }
  const { type } = doc;
  if (VALID_OBJECT_DOC_TYPES.has(type)) {
    return type;
  }
}
var get_doc_type_default = getDocType;
var disjunctionListFormat = (list) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(list);
function getDocErrorMessage(doc) {
  const type = doc === null ? "null" : typeof doc;
  if (type !== "string" && type !== "object") {
    return `Unexpected doc '${type}', 
Expected it to be 'string' or 'object'.`;
  }
  if (get_doc_type_default(doc)) {
    throw new Error("doc is valid.");
  }
  const objectType = Object.prototype.toString.call(doc);
  if (objectType !== "[object Object]") {
    return `Unexpected doc '${objectType}'.`;
  }
  const EXPECTED_TYPE_VALUES = disjunctionListFormat(
    [...VALID_OBJECT_DOC_TYPES].map((type2) => `'${type2}'`)
  );
  return `Unexpected doc.type '${doc.type}'.
Expected it to be ${EXPECTED_TYPE_VALUES}.`;
}
var InvalidDocError = class extends Error {
  name = "InvalidDocError";
  constructor(doc) {
    super(getDocErrorMessage(doc));
    this.doc = doc;
  }
};
var invalid_doc_error_default = InvalidDocError;
var traverseDocOnExitStackMarker = {};
function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) {
  const docsStack = [doc];
  while (docsStack.length > 0) {
    const doc2 = docsStack.pop();
    if (doc2 === traverseDocOnExitStackMarker) {
      onExit(docsStack.pop());
      continue;
    }
    if (onExit) {
      docsStack.push(doc2, traverseDocOnExitStackMarker);
    }
    const docType = get_doc_type_default(doc2);
    if (!docType) {
      throw new invalid_doc_error_default(doc2);
    }
    if ((onEnter == null ? void 0 : onEnter(doc2)) === false) {
      continue;
    }
    switch (docType) {
      case DOC_TYPE_ARRAY:
      case DOC_TYPE_FILL: {
        const parts = docType === DOC_TYPE_ARRAY ? doc2 : doc2.parts;
        for (let ic = parts.length, i = ic - 1; i >= 0; --i) {
          docsStack.push(parts[i]);
        }
        break;
      }
      case DOC_TYPE_IF_BREAK:
        docsStack.push(doc2.flatContents, doc2.breakContents);
        break;
      case DOC_TYPE_GROUP:
        if (shouldTraverseConditionalGroups && doc2.expandedStates) {
          for (let ic = doc2.expandedStates.length, i = ic - 1; i >= 0; --i) {
            docsStack.push(doc2.expandedStates[i]);
          }
        } else {
          docsStack.push(doc2.contents);
        }
        break;
      case DOC_TYPE_ALIGN:
      case DOC_TYPE_INDENT:
      case DOC_TYPE_INDENT_IF_BREAK:
      case DOC_TYPE_LABEL:
      case DOC_TYPE_LINE_SUFFIX:
        docsStack.push(doc2.contents);
        break;
      case DOC_TYPE_STRING:
      case DOC_TYPE_CURSOR:
      case DOC_TYPE_TRIM:
      case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
      case DOC_TYPE_LINE:
      case DOC_TYPE_BREAK_PARENT:
        break;
      default:
        throw new invalid_doc_error_default(doc2);
    }
  }
}
var traverse_doc_default = traverseDoc;
var noop = () => {
};
var assertDoc = true ? noop : function(doc) {
  traverse_doc_default(doc, (doc2) => {
    if (checked.has(doc2)) {
      return false;
    }
    if (typeof doc2 !== "string") {
      checked.add(doc2);
    }
  });
};
var assertDocArray = true ? noop : function(docs, optional = false) {
  if (optional && !docs) {
    return;
  }
  if (!Array.isArray(docs)) {
    throw new TypeError("Unexpected doc array.");
  }
  for (const doc of docs) {
    assertDoc(doc);
  }
};
function indent(contents) {
  assertDoc(contents);
  return { type: DOC_TYPE_INDENT, contents };
}
function align(widthOrString, contents) {
  assertDoc(contents);
  return { type: DOC_TYPE_ALIGN, contents, n: widthOrString };
}
function group(contents, opts = {}) {
  assertDoc(contents);
  assertDocArray(
    opts.expandedStates,
    /* optional */
    true
  );
  return {
    type: DOC_TYPE_GROUP,
    id: opts.id,
    contents,
    break: Boolean(opts.shouldBreak),
    expandedStates: opts.expandedStates
  };
}
function dedentToRoot(contents) {
  return align(Number.NEGATIVE_INFINITY, contents);
}
function markAsRoot(contents) {
  return align({ type: "root" }, contents);
}
function dedent(contents) {
  return align(-1, contents);
}
function conditionalGroup(states, opts) {
  return group(states[0], { ...opts, expandedStates: states });
}
function fill(parts) {
  assertDocArray(parts);
  return { type: DOC_TYPE_FILL, parts };
}
function ifBreak(breakContents, flatContents = "", opts = {}) {
  assertDoc(breakContents);
  if (flatContents !== "") {
    assertDoc(flatContents);
  }
  return {
    type: DOC_TYPE_IF_BREAK,
    breakContents,
    flatContents,
    groupId: opts.groupId
  };
}
function indentIfBreak(contents, opts) {
  assertDoc(contents);
  return {
    type: DOC_TYPE_INDENT_IF_BREAK,
    contents,
    groupId: opts.groupId,
    negate: opts.negate
  };
}
function lineSuffix(contents) {
  assertDoc(contents);
  return { type: DOC_TYPE_LINE_SUFFIX, contents };
}
var lineSuffixBoundary = { type: DOC_TYPE_LINE_SUFFIX_BOUNDARY };
var breakParent = { type: DOC_TYPE_BREAK_PARENT };
var trim = { type: DOC_TYPE_TRIM };
var hardlineWithoutBreakParent = { type: DOC_TYPE_LINE, hard: true };
var literallineWithoutBreakParent = {
  type: DOC_TYPE_LINE,
  hard: true,
  literal: true
};
var line = { type: DOC_TYPE_LINE };
var softline = { type: DOC_TYPE_LINE, soft: true };
var hardline = [hardlineWithoutBreakParent, breakParent];
var literalline = [literallineWithoutBreakParent, breakParent];
var cursor = { type: DOC_TYPE_CURSOR };
function join(separator, docs) {
  assertDoc(separator);
  assertDocArray(docs);
  const parts = [];
  for (let i = 0; i < docs.length; i++) {
    if (i !== 0) {
      parts.push(separator);
    }
    parts.push(docs[i]);
  }
  return parts;
}
function addAlignmentToDoc(doc, size, tabWidth) {
  assertDoc(doc);
  let aligned = doc;
  if (size > 0) {
    for (let i = 0; i < Math.floor(size / tabWidth); ++i) {
      aligned = indent(aligned);
    }
    aligned = align(size % tabWidth, aligned);
    aligned = align(Number.NEGATIVE_INFINITY, aligned);
  }
  return aligned;
}
function label(label2, contents) {
  assertDoc(contents);
  return label2 ? { type: DOC_TYPE_LABEL, label: label2, contents } : contents;
}
var at = (isOptionalObject, object, index) => {
  if (isOptionalObject && (object === void 0 || object === null)) {
    return;
  }
  if (Array.isArray(object) || typeof object === "string") {
    return object[index < 0 ? object.length + index : index];
  }
  return object.at(index);
};
var at_default = at;
var stringReplaceAll = (isOptionalObject, original, pattern, replacement) => {
  if (isOptionalObject && (original === void 0 || original === null)) {
    return;
  }
  if (original.replaceAll) {
    return original.replaceAll(pattern, replacement);
  }
  if (pattern.global) {
    return original.replace(pattern, replacement);
  }
  return original.split(pattern).join(replacement);
};
var string_replace_all_default = stringReplaceAll;
function convertEndOfLineToChars(value) {
  switch (value) {
    case "cr":
      return "\r";
    case "crlf":
      return "\r\n";
    default:
      return "\n";
  }
}
var emoji_regex_default = () => {
  return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26F9(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC3\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC08\uDC26](?:\u200D\u2B1B)?|[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE])))?))?|\uDC6F(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDD75(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC2\uDECE-\uDEDB\uDEE0-\uDEE8]|\uDD3C(?:\u200D[\u2640\u2642]\uFE0F?|\uD83C[\uDFFB-\uDFFF])?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF-\uDDB3\uDDBC\uDDBD]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
};
var eastasianwidth_default = {
  eastAsianWidth(character) {
    var x = character.charCodeAt(0);
    var y = character.length == 2 ? character.charCodeAt(1) : 0;
    var codePoint = x;
    if (55296 <= x && x <= 56319 && 56320 <= y && y <= 57343) {
      x &= 1023;
      y &= 1023;
      codePoint = x << 10 | y;
      codePoint += 65536;
    }
    if (12288 == codePoint || 65281 <= codePoint && codePoint <= 65376 || 65504 <= codePoint && codePoint <= 65510) {
      return "F";
    }
    if (4352 <= codePoint && codePoint <= 4447 || 4515 <= codePoint && codePoint <= 4519 || 4602 <= codePoint && codePoint <= 4607 || 9001 <= codePoint && codePoint <= 9002 || 11904 <= codePoint && codePoint <= 11929 || 11931 <= codePoint && codePoint <= 12019 || 12032 <= codePoint && codePoint <= 12245 || 12272 <= codePoint && codePoint <= 12283 || 12289 <= codePoint && codePoint <= 12350 || 12353 <= codePoint && codePoint <= 12438 || 12441 <= codePoint && codePoint <= 12543 || 12549 <= codePoint && codePoint <= 12589 || 12593 <= codePoint && codePoint <= 12686 || 12688 <= codePoint && codePoint <= 12730 || 12736 <= codePoint && codePoint <= 12771 || 12784 <= codePoint && codePoint <= 12830 || 12832 <= codePoint && codePoint <= 12871 || 12880 <= codePoint && codePoint <= 13054 || 13056 <= codePoint && codePoint <= 19903 || 19968 <= codePoint && codePoint <= 42124 || 42128 <= codePoint && codePoint <= 42182 || 43360 <= codePoint && codePoint <= 43388 || 44032 <= codePoint && codePoint <= 55203 || 55216 <= codePoint && codePoint <= 55238 || 55243 <= codePoint && codePoint <= 55291 || 63744 <= codePoint && codePoint <= 64255 || 65040 <= codePoint && codePoint <= 65049 || 65072 <= codePoint && codePoint <= 65106 || 65108 <= codePoint && codePoint <= 65126 || 65128 <= codePoint && codePoint <= 65131 || 110592 <= codePoint && codePoint <= 110593 || 127488 <= codePoint && codePoint <= 127490 || 127504 <= codePoint && codePoint <= 127546 || 127552 <= codePoint && codePoint <= 127560 || 127568 <= codePoint && codePoint <= 127569 || 131072 <= codePoint && codePoint <= 194367 || 177984 <= codePoint && codePoint <= 196605 || 196608 <= codePoint && codePoint <= 262141) {
      return "W";
    }
    return "N";
  }
};
var notAsciiRegex = /[^\x20-\x7F]/;
function getStringWidth(text) {
  if (!text) {
    return 0;
  }
  if (!notAsciiRegex.test(text)) {
    return text.length;
  }
  text = text.replace(emoji_regex_default(), "  ");
  let width = 0;
  for (const character of text) {
    const codePoint = character.codePointAt(0);
    if (codePoint <= 31 || codePoint >= 127 && codePoint <= 159) {
      continue;
    }
    if (codePoint >= 768 && codePoint <= 879) {
      continue;
    }
    const code = eastasianwidth_default.eastAsianWidth(character);
    width += code === "F" || code === "W" ? 2 : 1;
  }
  return width;
}
var get_string_width_default = getStringWidth;
var getDocParts = (doc) => {
  if (Array.isArray(doc)) {
    return doc;
  }
  if (doc.type !== DOC_TYPE_FILL) {
    throw new Error(`Expect doc to be 'array' or '${DOC_TYPE_FILL}'.`);
  }
  return doc.parts;
};
function mapDoc(doc, cb) {
  if (typeof doc === "string") {
    return cb(doc);
  }
  const mapped = /* @__PURE__ */ new Map();
  return rec(doc);
  function rec(doc2) {
    if (mapped.has(doc2)) {
      return mapped.get(doc2);
    }
    const result = process2(doc2);
    mapped.set(doc2, result);
    return result;
  }
  function process2(doc2) {
    switch (get_doc_type_default(doc2)) {
      case DOC_TYPE_ARRAY:
        return cb(doc2.map(rec));
      case DOC_TYPE_FILL:
        return cb({
          ...doc2,
          parts: doc2.parts.map(rec)
        });
      case DOC_TYPE_IF_BREAK:
        return cb({
          ...doc2,
          breakContents: rec(doc2.breakContents),
          flatContents: rec(doc2.flatContents)
        });
      case DOC_TYPE_GROUP: {
        let {
          expandedStates,
          contents
        } = doc2;
        if (expandedStates) {
          expandedStates = expandedStates.map(rec);
          contents = expandedStates[0];
        } else {
          contents = rec(contents);
        }
        return cb({
          ...doc2,
          contents,
          expandedStates
        });
      }
      case DOC_TYPE_ALIGN:
      case DOC_TYPE_INDENT:
      case DOC_TYPE_INDENT_IF_BREAK:
      case DOC_TYPE_LABEL:
      case DOC_TYPE_LINE_SUFFIX:
        return cb({
          ...doc2,
          contents: rec(doc2.contents)
        });
      case DOC_TYPE_STRING:
      case DOC_TYPE_CURSOR:
      case DOC_TYPE_TRIM:
      case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
      case DOC_TYPE_LINE:
      case DOC_TYPE_BREAK_PARENT:
        return cb(doc2);
      default:
        throw new invalid_doc_error_default(doc2);
    }
  }
}
function findInDoc(doc, fn, defaultValue) {
  let result = defaultValue;
  let shouldSkipFurtherProcessing = false;
  function findInDocOnEnterFn(doc2) {
    if (shouldSkipFurtherProcessing) {
      return false;
    }
    const maybeResult = fn(doc2);
    if (maybeResult !== void 0) {
      shouldSkipFurtherProcessing = true;
      result = maybeResult;
    }
  }
  traverse_doc_default(doc, findInDocOnEnterFn);
  return result;
}
function willBreakFn(doc) {
  if (doc.type === DOC_TYPE_GROUP && doc.break) {
    return true;
  }
  if (doc.type === DOC_TYPE_LINE && doc.hard) {
    return true;
  }
  if (doc.type === DOC_TYPE_BREAK_PARENT) {
    return true;
  }
}
function willBreak(doc) {
  return findInDoc(doc, willBreakFn, false);
}
function breakParentGroup(groupStack) {
  if (groupStack.length > 0) {
    const parentGroup = at_default(
      /* isOptionalObject*/
      false,
      groupStack,
      -1
    );
    if (!parentGroup.expandedStates && !parentGroup.break) {
      parentGroup.break = "propagated";
    }
  }
  return null;
}
function propagateBreaks(doc) {
  const alreadyVisitedSet = /* @__PURE__ */ new Set();
  const groupStack = [];
  function propagateBreaksOnEnterFn(doc2) {
    if (doc2.type === DOC_TYPE_BREAK_PARENT) {
      breakParentGroup(groupStack);
    }
    if (doc2.type === DOC_TYPE_GROUP) {
      groupStack.push(doc2);
      if (alreadyVisitedSet.has(doc2)) {
        return false;
      }
      alreadyVisitedSet.add(doc2);
    }
  }
  function propagateBreaksOnExitFn(doc2) {
    if (doc2.type === DOC_TYPE_GROUP) {
      const group22 = groupStack.pop();
      if (group22.break) {
        breakParentGroup(groupStack);
      }
    }
  }
  traverse_doc_default(
    doc,
    propagateBreaksOnEnterFn,
    propagateBreaksOnExitFn,
    /* shouldTraverseConditionalGroups */
    true
  );
}
function removeLinesFn(doc) {
  if (doc.type === DOC_TYPE_LINE && !doc.hard) {
    return doc.soft ? "" : " ";
  }
  if (doc.type === DOC_TYPE_IF_BREAK) {
    return doc.flatContents;
  }
  return doc;
}
function removeLines(doc) {
  return mapDoc(doc, removeLinesFn);
}
function stripTrailingHardlineFromParts(parts) {
  parts = [...parts];
  while (parts.length >= 2 && at_default(
    /* isOptionalObject*/
    false,
    parts,
    -2
  ).type === DOC_TYPE_LINE && at_default(
    /* isOptionalObject*/
    false,
    parts,
    -1
  ).type === DOC_TYPE_BREAK_PARENT) {
    parts.length -= 2;
  }
  if (parts.length > 0) {
    const lastPart = stripTrailingHardlineFromDoc(at_default(
      /* isOptionalObject*/
      false,
      parts,
      -1
    ));
    parts[parts.length - 1] = lastPart;
  }
  return parts;
}
function stripTrailingHardlineFromDoc(doc) {
  switch (get_doc_type_default(doc)) {
    case DOC_TYPE_ALIGN:
    case DOC_TYPE_INDENT:
    case DOC_TYPE_INDENT_IF_BREAK:
    case DOC_TYPE_GROUP:
    case DOC_TYPE_LINE_SUFFIX:
    case DOC_TYPE_LABEL: {
      const contents = stripTrailingHardlineFromDoc(doc.contents);
      return {
        ...doc,
        contents
      };
    }
    case DOC_TYPE_IF_BREAK:
      return {
        ...doc,
        breakContents: stripTrailingHardlineFromDoc(doc.breakContents),
        flatContents: stripTrailingHardlineFromDoc(doc.flatContents)
      };
    case DOC_TYPE_FILL:
      return {
        ...doc,
        parts: stripTrailingHardlineFromParts(doc.parts)
      };
    case DOC_TYPE_ARRAY:
      return stripTrailingHardlineFromParts(doc);
    case DOC_TYPE_STRING:
      return doc.replace(/[\n\r]*$/, "");
    case DOC_TYPE_CURSOR:
    case DOC_TYPE_TRIM:
    case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
    case DOC_TYPE_LINE:
    case DOC_TYPE_BREAK_PARENT:
      break;
    default:
      throw new invalid_doc_error_default(doc);
  }
  return doc;
}
function stripTrailingHardline(doc) {
  return stripTrailingHardlineFromDoc(cleanDoc(doc));
}
function cleanDocFn(doc) {
  switch (get_doc_type_default(doc)) {
    case DOC_TYPE_FILL:
      if (doc.parts.every((part) => part === "")) {
        return "";
      }
      break;
    case DOC_TYPE_GROUP:
      if (!doc.contents && !doc.id && !doc.break && !doc.expandedStates) {
        return "";
      }
      if (doc.contents.type === DOC_TYPE_GROUP && doc.contents.id === doc.id && doc.contents.break === doc.break && doc.contents.expandedStates === doc.expandedStates) {
        return doc.contents;
      }
      break;
    case DOC_TYPE_ALIGN:
    case DOC_TYPE_INDENT:
    case DOC_TYPE_INDENT_IF_BREAK:
    case DOC_TYPE_LINE_SUFFIX:
      if (!doc.contents) {
        return "";
      }
      break;
    case DOC_TYPE_IF_BREAK:
      if (!doc.flatContents && !doc.breakContents) {
        return "";
      }
      break;
    case DOC_TYPE_ARRAY: {
      const parts = [];
      for (const part of doc) {
        if (!part) {
          continue;
        }
        const [currentPart, ...restParts] = Array.isArray(part) ? part : [part];
        if (typeof currentPart === "string" && typeof at_default(
          /* isOptionalObject*/
          false,
          parts,
          -1
        ) === "string") {
          parts[parts.length - 1] += currentPart;
        } else {
          parts.push(currentPart);
        }
        parts.push(...restParts);
      }
      if (parts.length === 0) {
        return "";
      }
      if (parts.length === 1) {
        return parts[0];
      }
      return parts;
    }
    case DOC_TYPE_STRING:
    case DOC_TYPE_CURSOR:
    case DOC_TYPE_TRIM:
    case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
    case DOC_TYPE_LINE:
    case DOC_TYPE_LABEL:
    case DOC_TYPE_BREAK_PARENT:
      break;
    default:
      throw new invalid_doc_error_default(doc);
  }
  return doc;
}
function cleanDoc(doc) {
  return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
}
function replaceEndOfLine(doc, replacement = literalline) {
  return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join(replacement, currentDoc.split("\n")) : currentDoc);
}
function canBreakFn(doc) {
  if (doc.type === DOC_TYPE_LINE) {
    return true;
  }
}
function canBreak(doc) {
  return findInDoc(doc, canBreakFn, false);
}
var MODE_BREAK = Symbol("MODE_BREAK");
var MODE_FLAT = Symbol("MODE_FLAT");
var CURSOR_PLACEHOLDER = Symbol("cursor");
function rootIndent() {
  return {
    value: "",
    length: 0,
    queue: []
  };
}
function makeIndent(ind, options) {
  return generateInd(ind, {
    type: "indent"
  }, options);
}
function makeAlign(indent22, widthOrDoc, options) {
  if (widthOrDoc === Number.NEGATIVE_INFINITY) {
    return indent22.root || rootIndent();
  }
  if (widthOrDoc < 0) {
    return generateInd(indent22, {
      type: "dedent"
    }, options);
  }
  if (!widthOrDoc) {
    return indent22;
  }
  if (widthOrDoc.type === "root") {
    return {
      ...indent22,
      root: indent22
    };
  }
  const alignType = typeof widthOrDoc === "string" ? "stringAlign" : "numberAlign";
  return generateInd(indent22, {
    type: alignType,
    n: widthOrDoc
  }, options);
}
function generateInd(ind, newPart, options) {
  const queue = newPart.type === "dedent" ? ind.queue.slice(0, -1) : [...ind.queue, newPart];
  let value = "";
  let length = 0;
  let lastTabs = 0;
  let lastSpaces = 0;
  for (const part of queue) {
    switch (part.type) {
      case "indent":
        flush();
        if (options.useTabs) {
          addTabs(1);
        } else {
          addSpaces(options.tabWidth);
        }
        break;
      case "stringAlign":
        flush();
        value += part.n;
        length += part.n.length;
        break;
      case "numberAlign":
        lastTabs += 1;
        lastSpaces += part.n;
        break;
      default:
        throw new Error(`Unexpected type '${part.type}'`);
    }
  }
  flushSpaces();
  return {
    ...ind,
    value,
    length,
    queue
  };
  function addTabs(count) {
    value += "	".repeat(count);
    length += options.tabWidth * count;
  }
  function addSpaces(count) {
    value += " ".repeat(count);
    length += count;
  }
  function flush() {
    if (options.useTabs) {
      flushTabs();
    } else {
      flushSpaces();
    }
  }
  function flushTabs() {
    if (lastTabs > 0) {
      addTabs(lastTabs);
    }
    resetLast();
  }
  function flushSpaces() {
    if (lastSpaces > 0) {
      addSpaces(lastSpaces);
    }
    resetLast();
  }
  function resetLast() {
    lastTabs = 0;
    lastSpaces = 0;
  }
}
function trim2(out) {
  let trimCount = 0;
  let cursorCount = 0;
  let outIndex = out.length;
  outer:
    while (outIndex--) {
      const last = out[outIndex];
      if (last === CURSOR_PLACEHOLDER) {
        cursorCount++;
        continue;
      }
      if (false) {
        throw new Error(`Unexpected value in trim: '${typeof last}'`);
      }
      for (let charIndex = last.length - 1; charIndex >= 0; charIndex--) {
        const char = last[charIndex];
        if (char === " " || char === "	") {
          trimCount++;
        } else {
          out[outIndex] = last.slice(0, charIndex + 1);
          break outer;
        }
      }
    }
  if (trimCount > 0 || cursorCount > 0) {
    out.length = outIndex + 1;
    while (cursorCount-- > 0) {
      out.push(CURSOR_PLACEHOLDER);
    }
  }
  return trimCount;
}
function fits(next, restCommands, width, hasLineSuffix, groupModeMap, mustBeFlat) {
  if (width === Number.POSITIVE_INFINITY) {
    return true;
  }
  let restIdx = restCommands.length;
  const cmds = [next];
  const out = [];
  while (width >= 0) {
    if (cmds.length === 0) {
      if (restIdx === 0) {
        return true;
      }
      cmds.push(restCommands[--restIdx]);
      continue;
    }
    const {
      mode,
      doc
    } = cmds.pop();
    switch (get_doc_type_default(doc)) {
      case DOC_TYPE_STRING:
        out.push(doc);
        width -= get_string_width_default(doc);
        break;
      case DOC_TYPE_ARRAY:
      case DOC_TYPE_FILL: {
        const parts = getDocParts(doc);
        for (let i = parts.length - 1; i >= 0; i--) {
          cmds.push({
            mode,
            doc: parts[i]
          });
        }
        break;
      }
      case DOC_TYPE_INDENT:
      case DOC_TYPE_ALIGN:
      case DOC_TYPE_INDENT_IF_BREAK:
      case DOC_TYPE_LABEL:
        cmds.push({
          mode,
          doc: doc.contents
        });
        break;
      case DOC_TYPE_TRIM:
        width += trim2(out);
        break;
      case DOC_TYPE_GROUP: {
        if (mustBeFlat && doc.break) {
          return false;
        }
        const groupMode = doc.break ? MODE_BREAK : mode;
        const contents = doc.expandedStates && groupMode === MODE_BREAK ? at_default(
          /* isOptionalObject*/
          false,
          doc.expandedStates,
          -1
        ) : doc.contents;
        cmds.push({
          mode: groupMode,
          doc: contents
        });
        break;
      }
      case DOC_TYPE_IF_BREAK: {
        const groupMode = doc.groupId ? groupModeMap[doc.groupId] || MODE_FLAT : mode;
        const contents = groupMode === MODE_BREAK ? doc.breakContents : doc.flatContents;
        if (contents) {
          cmds.push({
            mode,
            doc: contents
          });
        }
        break;
      }
      case DOC_TYPE_LINE:
        if (mode === MODE_BREAK || doc.hard) {
          return true;
        }
        if (!doc.soft) {
          out.push(" ");
          width--;
        }
        break;
      case DOC_TYPE_LINE_SUFFIX:
        hasLineSuffix = true;
        break;
      case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
        if (hasLineSuffix) {
          return false;
        }
        break;
    }
  }
  return false;
}
function printDocToString(doc, options) {
  const groupModeMap = {};
  const width = options.printWidth;
  const newLine = convertEndOfLineToChars(options.endOfLine);
  let pos = 0;
  const cmds = [{
    ind: rootIndent(),
    mode: MODE_BREAK,
    doc
  }];
  const out = [];
  let shouldRemeasure = false;
  const lineSuffix22 = [];
  let printedCursorCount = 0;
  propagateBreaks(doc);
  while (cmds.length > 0) {
    const {
      ind,
      mode,
      doc: doc2
    } = cmds.pop();
    switch (get_doc_type_default(doc2)) {
      case DOC_TYPE_STRING: {
        const formatted = newLine !== "\n" ? string_replace_all_default(
          /* isOptionalObject*/
          false,
          doc2,
          "\n",
          newLine
        ) : doc2;
        out.push(formatted);
        if (cmds.length > 0) {
          pos += get_string_width_default(formatted);
        }
        break;
      }
      case DOC_TYPE_ARRAY:
        for (let i = doc2.length - 1; i >= 0; i--) {
          cmds.push({
            ind,
            mode,
            doc: doc2[i]
          });
        }
        break;
      case DOC_TYPE_CURSOR:
        if (printedCursorCount >= 2) {
          throw new Error("There are too many 'cursor' in doc.");
        }
        out.push(CURSOR_PLACEHOLDER);
        printedCursorCount++;
        break;
      case DOC_TYPE_INDENT:
        cmds.push({
          ind: makeIndent(ind, options),
          mode,
          doc: doc2.contents
        });
        break;
      case DOC_TYPE_ALIGN:
        cmds.push({
          ind: makeAlign(ind, doc2.n, options),
          mode,
          doc: doc2.contents
        });
        break;
      case DOC_TYPE_TRIM:
        pos -= trim2(out);
        break;
      case DOC_TYPE_GROUP:
        switch (mode) {
          case MODE_FLAT:
            if (!shouldRemeasure) {
              cmds.push({
                ind,
                mode: doc2.break ? MODE_BREAK : MODE_FLAT,
                doc: doc2.contents
              });
              break;
            }
          case MODE_BREAK: {
            shouldRemeasure = false;
            const next = {
              ind,
              mode: MODE_FLAT,
              doc: doc2.contents
            };
            const rem = width - pos;
            const hasLineSuffix = lineSuffix22.length > 0;
            if (!doc2.break && fits(next, cmds, rem, hasLineSuffix, groupModeMap)) {
              cmds.push(next);
            } else {
              if (doc2.expandedStates) {
                const mostExpanded = at_default(
                  /* isOptionalObject*/
                  false,
                  doc2.expandedStates,
                  -1
                );
                if (doc2.break) {
                  cmds.push({
                    ind,
                    mode: MODE_BREAK,
                    doc: mostExpanded
                  });
                  break;
                } else {
                  for (let i = 1; i < doc2.expandedStates.length + 1; i++) {
                    if (i >= doc2.expandedStates.length) {
                      cmds.push({
                        ind,
                        mode: MODE_BREAK,
                        doc: mostExpanded
                      });
                      break;
                    } else {
                      const state = doc2.expandedStates[i];
                      const cmd = {
                        ind,
                        mode: MODE_FLAT,
                        doc: state
                      };
                      if (fits(cmd, cmds, rem, hasLineSuffix, groupModeMap)) {
                        cmds.push(cmd);
                        break;
                      }
                    }
                  }
                }
              } else {
                cmds.push({
                  ind,
                  mode: MODE_BREAK,
                  doc: doc2.contents
                });
              }
            }
            break;
          }
        }
        if (doc2.id) {
          groupModeMap[doc2.id] = at_default(
            /* isOptionalObject*/
            false,
            cmds,
            -1
          ).mode;
        }
        break;
      case DOC_TYPE_FILL: {
        const rem = width - pos;
        const {
          parts
        } = doc2;
        if (parts.length === 0) {
          break;
        }
        const [content, whitespace] = parts;
        const contentFlatCmd = {
          ind,
          mode: MODE_FLAT,
          doc: content
        };
        const contentBreakCmd = {
          ind,
          mode: MODE_BREAK,
          doc: content
        };
        const contentFits = fits(contentFlatCmd, [], rem, lineSuffix22.length > 0, groupModeMap, true);
        if (parts.length === 1) {
          if (contentFits) {
            cmds.push(contentFlatCmd);
          } else {
            cmds.push(contentBreakCmd);
          }
          break;
        }
        const whitespaceFlatCmd = {
          ind,
          mode: MODE_FLAT,
          doc: whitespace
        };
        const whitespaceBreakCmd = {
          ind,
          mode: MODE_BREAK,
          doc: whitespace
        };
        if (parts.length === 2) {
          if (contentFits) {
            cmds.push(whitespaceFlatCmd, contentFlatCmd);
          } else {
            cmds.push(whitespaceBreakCmd, contentBreakCmd);
          }
          break;
        }
        parts.splice(0, 2);
        const remainingCmd = {
          ind,
          mode,
          doc: fill(parts)
        };
        const secondContent = parts[0];
        const firstAndSecondContentFlatCmd = {
          ind,
          mode: MODE_FLAT,
          doc: [content, whitespace, secondContent]
        };
        const firstAndSecondContentFits = fits(firstAndSecondContentFlatCmd, [], rem, lineSuffix22.length > 0, groupModeMap, true);
        if (firstAndSecondContentFits) {
          cmds.push(remainingCmd, whitespaceFlatCmd, contentFlatCmd);
        } else if (contentFits) {
          cmds.push(remainingCmd, whitespaceBreakCmd, contentFlatCmd);
        } else {
          cmds.push(remainingCmd, whitespaceBreakCmd, contentBreakCmd);
        }
        break;
      }
      case DOC_TYPE_IF_BREAK:
      case DOC_TYPE_INDENT_IF_BREAK: {
        const groupMode = doc2.groupId ? groupModeMap[doc2.groupId] : mode;
        if (groupMode === MODE_BREAK) {
          const breakContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.breakContents : doc2.negate ? doc2.contents : indent(doc2.contents);
          if (breakContents) {
            cmds.push({
              ind,
              mode,
              doc: breakContents
            });
          }
        }
        if (groupMode === MODE_FLAT) {
          const flatContents = doc2.type === DOC_TYPE_IF_BREAK ? doc2.flatContents : doc2.negate ? indent(doc2.contents) : doc2.contents;
          if (flatContents) {
            cmds.push({
              ind,
              mode,
              doc: flatContents
            });
          }
        }
        break;
      }
      case DOC_TYPE_LINE_SUFFIX:
        lineSuffix22.push({
          ind,
          mode,
          doc: doc2.contents
        });
        break;
      case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
        if (lineSuffix22.length > 0) {
          cmds.push({
            ind,
            mode,
            doc: hardlineWithoutBreakParent
          });
        }
        break;
      case DOC_TYPE_LINE:
        switch (mode) {
          case MODE_FLAT:
            if (!doc2.hard) {
              if (!doc2.soft) {
                out.push(" ");
                pos += 1;
              }
              break;
            } else {
              shouldRemeasure = true;
            }
          case MODE_BREAK:
            if (lineSuffix22.length > 0) {
              cmds.push({
                ind,
                mode,
                doc: doc2
              }, ...lineSuffix22.reverse());
              lineSuffix22.length = 0;
              break;
            }
            if (doc2.literal) {
              if (ind.root) {
                out.push(newLine, ind.root.value);
                pos = ind.root.length;
              } else {
                out.push(newLine);
                pos = 0;
              }
            } else {
              pos -= trim2(out);
              out.push(newLine + ind.value);
              pos = ind.length;
            }
            break;
        }
        break;
      case DOC_TYPE_LABEL:
        cmds.push({
          ind,
          mode,
          doc: doc2.contents
        });
        break;
      case DOC_TYPE_BREAK_PARENT:
        break;
      default:
        throw new invalid_doc_error_default(doc2);
    }
    if (cmds.length === 0 && lineSuffix22.length > 0) {
      cmds.push(...lineSuffix22.reverse());
      lineSuffix22.length = 0;
    }
  }
  const cursorPlaceholderIndex = out.indexOf(CURSOR_PLACEHOLDER);
  if (cursorPlaceholderIndex !== -1) {
    const otherCursorPlaceholderIndex = out.indexOf(CURSOR_PLACEHOLDER, cursorPlaceholderIndex + 1);
    const beforeCursor = out.slice(0, cursorPlaceholderIndex).join("");
    const aroundCursor = out.slice(cursorPlaceholderIndex + 1, otherCursorPlaceholderIndex).join("");
    const afterCursor = out.slice(otherCursorPlaceholderIndex + 1).join("");
    return {
      formatted: beforeCursor + aroundCursor + afterCursor,
      cursorNodeStart: beforeCursor.length,
      cursorNodeText: aroundCursor
    };
  }
  return {
    formatted: out.join("")
  };
}
var builders = {
  join,
  line,
  softline,
  hardline,
  literalline,
  group,
  conditionalGroup,
  fill,
  lineSuffix,
  lineSuffixBoundary,
  cursor,
  breakParent,
  ifBreak,
  trim,
  indent,
  indentIfBreak,
  align,
  addAlignmentToDoc,
  markAsRoot,
  dedentToRoot,
  dedent,
  hardlineWithoutBreakParent,
  literallineWithoutBreakParent,
  label,
  // TODO: Remove this in v4
  concat: (parts) => parts
};
var printer = { printDocToString };
var utils = {
  willBreak,
  traverseDoc: traverse_doc_default,
  findInDoc,
  mapDoc,
  removeLines,
  stripTrailingHardline,
  replaceEndOfLine,
  canBreak
};

// libs/printer/common.ts
import { printRaw } from "@unified-latex/unified-latex-util-print-raw";
import { match } from "@unified-latex/unified-latex-util-match";
function formatEnvSurround(node) {
  const env = printRaw(node.env);
  return {
    envName: env,
    start: ESCAPE + "begin{" + env + "}",
    end: ESCAPE + "end{" + env + "}"
  };
}
function isLineType(elm) {
  if (elm == null || typeof elm === "string") {
    return false;
  }
  if (Array.isArray(elm)) {
    return isLineType(elm[0]);
  }
  if (elm.type === "concat") {
    return isLineType(elm.parts);
  }
  return elm.type === "line";
}
function joinWithSoftline(arr) {
  if (arr.length === 0 || arr.length === 1) {
    return arr;
  }
  const ret = [arr[0]];
  for (let i = 1; i < arr.length; i++) {
    const prevNode = arr[i - 1];
    const nextNode = arr[i];
    if (!isLineType(prevNode) && !isLineType(nextNode)) {
      ret.push(softline2);
    }
    ret.push(nextNode);
  }
  return ret;
}
function getNodeInfo(node, options) {
  if (!node) {
    return { renderInfo: {} };
  }
  const renderInfo = node._renderInfo || {};
  const previousNode = options.referenceMap && options.referenceMap.getPreviousNode(node);
  const nextNode = options.referenceMap && options.referenceMap.getNextNode(node);
  const renderCache = options.referenceMap && options.referenceMap.getRenderCache(node);
  return {
    renderInfo,
    renderCache,
    previousNode,
    nextNode,
    referenceMap: options.referenceMap
  };
}
var ESCAPE = "\\";
var {
  group: group2,
  fill: fill2,
  ifBreak: ifBreak2,
  line: line2,
  softline: softline2,
  hardline: hardline2,
  lineSuffix: lineSuffix2,
  lineSuffixBoundary: lineSuffixBoundary2,
  breakParent: breakParent2,
  indent: indent2,
  markAsRoot: markAsRoot2,
  join: join2
} = builders;
function formatDocArray(nodes, docArray, options) {
  const ret = [];
  for (let i = 0; i < nodes.length; i++) {
    const rawNode = nodes[i];
    const printedNode = docArray[i];
    const { renderInfo, referenceMap, previousNode, nextNode } = getNodeInfo(rawNode, options);
    const renderCache = referenceMap && referenceMap.getRenderCache(rawNode);
    switch (rawNode.type) {
      case "comment":
        if (!rawNode.sameline && previousNode && !match.comment(previousNode) && !match.parbreak(previousNode)) {
          ret.push(hardline2);
        }
        ret.push(printedNode);
        if (nextNode && !rawNode.suffixParbreak) {
          ret.push(hardline2);
        }
        break;
      case "environment":
      case "displaymath":
      case "mathenv":
        if (previousNode && (previousNode == null ? void 0 : previousNode.type) !== "parbreak") {
          if (ret[ret.length - 1] === line2) {
            ret.pop();
          }
          if (ret[ret.length - 1] !== hardline2) {
            ret.push(hardline2);
          }
        }
        ret.push(printedNode);
        if ((nextNode == null ? void 0 : nextNode.type) === "whitespace") {
          ret.push(hardline2);
          i++;
        }
        break;
      case "macro":
        if (renderInfo.breakBefore || renderInfo.breakAround) {
          if (previousNode) {
            if (ret[ret.length - 1] === line2 || ret[ret.length - 1] === hardline2) {
              ret.pop();
              ret.push(hardline2);
            } else if (!match.comment(previousNode) && !match.parbreak(previousNode)) {
              ret.push(hardline2);
            }
          }
        }
        if (renderInfo.inParMode && !renderInfo.hangingIndent && renderCache) {
          ret.push(
            renderCache.content,
            ...renderCache.rawArgs || []
          );
        } else {
          ret.push(printedNode);
        }
        if (renderInfo.breakAfter || renderInfo.breakAround) {
          if (nextNode) {
            if (match.whitespace(nextNode)) {
              ret.push(hardline2);
              i++;
            } else if (match.parbreak(nextNode)) {
            } else if (!match.comment(nextNode)) {
              ret.push(hardline2);
            }
          }
        }
        break;
      case "parbreak":
        ret.push(hardline2, hardline2);
        break;
      default:
        ret.push(printedNode);
        break;
    }
  }
  return ret;
}

// libs/zip.ts
function zip(array1, array2) {
  const ret = [];
  const len = Math.min(array1.length, array2.length);
  for (let i = 0; i < len; i++) {
    ret.push([array1[i], array2[i]]);
  }
  return ret;
}

// libs/printer/macro.ts
function printMacro(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  const content = (node.escapeToken != null ? node.escapeToken : ESCAPE) + node.content;
  const args = node.args ? path.map(print, "args") : [];
  const rawArgs = [];
  for (const [arg, printedArg] of zip(node.args || [], args)) {
    const renderCache = referenceMap && referenceMap.getRenderCache(arg);
    if (renderInfo.inParMode && renderCache) {
      rawArgs.push(...renderCache);
    } else {
      rawArgs.push(printedArg);
    }
  }
  if (referenceMap) {
    referenceMap.setRenderCache(node, { rawArgs, content });
  }
  if (renderInfo.hangingIndent) {
    return indent2(fill2([content, ...rawArgs]));
  }
  return group2([content, ...rawArgs]);
}

// libs/printer/argument.ts
import { match as match3 } from "@unified-latex/unified-latex-util-match";
import { trim as trim4 } from "@unified-latex/unified-latex-util-trim";

// libs/printer/tikz.ts
import {
  printRaw as printRaw3
} from "@unified-latex/unified-latex-util-print-raw";
import { match as match2 } from "@unified-latex/unified-latex-util-match";
import { trim as trim3 } from "@unified-latex/unified-latex-util-trim";
import {
  parse as parseTikz
} from "@unified-latex/unified-latex-ctan/package/tikz";

// libs/printer/print-argument-pgfkeys.ts
import {
  linebreak,
  printRaw as printRaw2
} from "@unified-latex/unified-latex-util-print-raw";
import { parsePgfkeys } from "@unified-latex/unified-latex-util-pgfkeys";
function printArgumentPgfkeys(nodes, options) {
  const { allowParenGroups = false } = options;
  const parsed = parsePgfkeys(nodes, { allowParenGroups });
  const content = [];
  for (const part of parsed) {
    const isLastItem = part === parsed[parsed.length - 1];
    if (part.itemParts) {
      const parts = part.itemParts.map(
        (node) => printRaw2(node, { asArray: true }).map(
          (token) => token === linebreak ? hardline2 : token
        )
      );
      const row = join2("=", parts);
      content.push(row);
      if (part.trailingComma) {
        content.push(",");
      }
    }
    if (part.trailingComment) {
      const leadingContent = part.itemParts ? [" "] : [];
      if (part.leadingParbreak) {
        leadingContent.push(hardline2);
      }
      content.push(
        ...leadingContent,
        // We're carefully and manually controlling the newlines,
        // so print the comment directly without any newlines
        "%",
        part.trailingComment.content,
        breakParent2
      );
    }
    if (!isLastItem) {
      content.push(line2);
    }
  }
  let leadingComment = [""];
  if (options.leadingComment) {
    if (options.leadingComment.leadingWhitespace) {
      leadingComment.push(" ");
    }
    leadingComment.push("%" + options.leadingComment.content, breakParent2);
  }
  return group2([
    options.openMark,
    ...leadingComment,
    // If there is no content, we don't want to push an extra `softline`.
    // This matters because the braces group could still be broken by `leadingComment`
    content.length > 0 ? indent2([softline2, ...content]) : "",
    softline2,
    options.closeMark
  ]);
}

// libs/printer/tikz.ts
function printTikzArgument(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  const content = [];
  const nodes = [...node.content];
  trim3(nodes);
  try {
    const tikzAst = parseTikz(nodes);
    if (tikzAst.content.length === 0) {
      content.push(";");
      return content;
    }
    const printer2 = new TikzArgumentPrinter(tikzAst, path, print);
    return printer2.toDoc();
  } catch (e) {
    console.warn("Encountered error when trying to parse tikz argument", e);
  }
  content.push(";");
  return content;
}
function printFragment(fragment, path, print) {
  const tmpKey = Symbol();
  const currNode = path.getNode();
  if (!currNode) {
    throw new Error(
      "tried to print a fragment, but the current node is `null`"
    );
  }
  currNode[tmpKey] = fragment;
  const ret = print(tmpKey);
  delete currNode[tmpKey];
  return ret;
}
function printTikzPathSpecNode(node, path, print) {
  switch (node.type) {
    case "comment":
      return printFragment(node, path, print);
    case "unknown":
      return printFragment(node.content, path, print);
    case "coordinate":
      return [printRaw3(node.prefix), "(", printRaw3(node.content), ")"];
    case "line_to":
      return node.command;
    case "square_brace_group":
      return printOptionalArgs(node.content);
    case "operation":
      return node.content.content;
    case "svg_operation": {
      const comments = node.comments.map(
        (n) => printTikzPathSpecNode(n, path, print)
      );
      const options = node.options ? printOptionalArgs(node.options) : [];
      const rest = node.options ? [group2(indent2([line2, printRaw3(node.content)]))] : [" ", printRaw3(node.content)];
      return [...comments, "svg", options, ...rest];
    }
    case "curve_to": {
      const comments = node.comments.map(
        (n) => printTikzPathSpecNode(n, path, print)
      );
      const printedControls = node.controls.length > 1 ? [
        printTikzPathSpecNode(node.controls[0], path, print),
        " ",
        "and",
        line2,
        printTikzPathSpecNode(node.controls[1], path, print)
      ] : [printTikzPathSpecNode(node.controls[0], path, print)];
      return [
        ...comments,
        "..",
        " ",
        group2(
          indent2(["controls", line2, ...printedControls, " ", ".."])
        )
      ];
    }
    case "animation": {
      const comments = node.comments.map(
        (n) => printTikzPathSpecNode(n, path, print)
      );
      return [
        ...comments,
        ":",
        node.attribute,
        " ",
        "=",
        " ",
        group2(
          indent2([
            printArgumentPgfkeys(node.content, {
              openMark: "{",
              closeMark: "}"
            })
          ])
        )
      ];
    }
    case "foreach": {
      const comments = node.comments.map(
        (n) => printTikzPathSpecNode(n, path, print)
      );
      const variables = [...node.variables];
      trim3(variables);
      const list = node.list.type === "macro" ? printFragment(node.list, path, print) : printArgumentPgfkeys(node.list.content, {
        openMark: "{",
        closeMark: "}",
        allowParenGroups: true
      });
      const doc = [
        ...comments,
        printRaw3(node.start),
        " ",
        printRaw3(variables)
      ];
      if (node.options) {
        doc.push(" ", indent2(printOptionalArgs(node.options)));
      }
      doc.push(" ", "in", " ", group2(indent2(list)));
      const commandType = node.command.type;
      switch (commandType) {
        case "foreach":
          doc.push(
            indent2([
              line2,
              printTikzPathSpecNode(node.command, path, print)
            ])
          );
          break;
        case "macro":
          doc.push(
            indent2([line2, printFragment(node.command, path, print)])
          );
          break;
        case "group": {
          const groupContent = [...node.command.content];
          trim3(groupContent);
          doc.push(
            " ",
            indent2(
              group2([
                "{",
                indent2([
                  softline2,
                  ...groupContent.map(
                    (n) => printFragment(n, path, print)
                  )
                ]),
                softline2,
                "}"
              ])
            )
          );
          break;
        }
        default:
          const invalidType = commandType;
          console.warn(
            `Unhandled command type when printing "foreach": ${invalidType}`
          );
      }
      return indent2(doc);
    }
  }
  console.warn(
    `Encountered unknown type when trying to print tikz PathSpec: "${node.type}"`
  );
  return [];
}
function printOptionalArgs(nodes) {
  return printArgumentPgfkeys(nodes, {
    openMark: "[",
    closeMark: "]"
  });
}
var _path, _print;
var TikzArgumentPrinter = class {
  constructor(spec, path, print) {
    __privateAdd(this, _path, void 0);
    __privateAdd(this, _print, void 0);
    __privateSet(this, _path, path);
    __privateSet(this, _print, print);
    this.nodes = [...spec.content];
  }
  nodeToDoc(node) {
    return printTikzPathSpecNode(node, __privateGet(this, _path), __privateGet(this, _print));
  }
  toDoc() {
    const doc = [];
    const startArg = this.eatOptionalArg();
    if (startArg.optionalArg) {
      doc.push(
        ...startArg.comments.map(
          (c) => printFragment(c, __privateGet(this, _path), __privateGet(this, _print))
        )
      );
      doc.push(printOptionalArgs(startArg.optionalArg.content));
    }
    const innerDoc = [];
    doc.push(group2([indent2(innerDoc), ";"]));
    let cycle = -1;
    while (this.nodes.length > 0) {
      cycle++;
      const firstSep = cycle === 0 && !startArg.optionalArg ? " " : line2;
      const comingUp = this.peek();
      switch (comingUp) {
        case "short_path": {
          const [n0, n1, n2] = this.nodes.splice(0, 3);
          innerDoc.push(
            firstSep,
            this.nodeToDoc(n0),
            " ",
            this.nodeToDoc(n1),
            " ",
            this.nodeToDoc(n2)
          );
          continue;
        }
        case "long_path": {
          const [n0, n1] = this.nodes.splice(0, 2);
          if (n1.type === "operation") {
            this.nodes.unshift(n1);
            innerDoc.push(
              firstSep,
              this.nodeToDoc(n0),
              " ",
              this.eatOperation()
            );
          } else {
            innerDoc.push(
              firstSep,
              this.nodeToDoc(n0),
              " ",
              this.nodeToDoc(n1)
            );
          }
          continue;
        }
        case "node":
          {
            const eatenNode = this.eatNode();
            if (eatenNode) {
              innerDoc.push(line2, ...eatenNode);
              continue;
            }
            console.warn(
              "Expected to print a tikz `node` PathSpec but couldn't find the text `node`"
            );
          }
          continue;
        case "operation":
          innerDoc.push(firstSep, this.eatOperation());
          continue;
        case "unknown": {
          const node = this.nodes.shift();
          innerDoc.push(firstSep, this.nodeToDoc(node));
          continue;
        }
      }
      this.nodes.shift();
    }
    return doc;
  }
  /**
   * Look at the current node and the nodes that follow. Return what
   * "type" is recognized.
   */
  peek() {
    const [n0, n1, n2, n3] = [
      this.nodes[0],
      this.nodes[1],
      this.nodes[2],
      this.nodes[3]
    ];
    if ((n0 == null ? void 0 : n0.type) === "coordinate" && isPathJoinOperation(n1)) {
      if ((n2 == null ? void 0 : n2.type) === "coordinate" && !((n3 == null ? void 0 : n3.type) === "coordinate" || isPathJoinOperation(n3))) {
        return "short_path";
      }
      return "long_path";
    }
    if ((n0 == null ? void 0 : n0.type) === "operation") {
      if (n0.content.content === "node") {
        return "node";
      }
      return "operation";
    }
    return "unknown";
  }
  /**
   * Eat comments and an optional arg if present. If no optional
   * arg is present, do nothing.
   */
  eatOptionalArg() {
    let i = 0;
    const comments = [];
    let optionalArg = null;
    for (; i < this.nodes.length; i++) {
      const node = this.nodes[i];
      if (node.type === "square_brace_group") {
        optionalArg = node;
        i++;
        break;
      }
      if (node.type === "comment") {
        comments.push(node);
        continue;
      }
      break;
    }
    if (optionalArg) {
      this.nodes.splice(0, i);
    }
    return { optionalArg, comments };
  }
  /**
   * Eat a `type === "operation"` node whose contents is `"node"`. I.e.,
   * the type of thing that shows up in `\path node at (1,1) {foo};`
   */
  eatNode() {
    const firstNode = this.nodes[0];
    if ((firstNode == null ? void 0 : firstNode.type) === "operation" && firstNode.content.content === "node") {
      this.nodes.shift();
    } else {
      return null;
    }
    const innerDoc = [];
    const commentBlock = [];
    const doc = [commentBlock, "node", group2(indent2(innerDoc))];
    let hasNodeArgument = false;
    let shouldBail = false;
    let i = 0;
    const comments = [];
    const options = [];
    const name = [];
    const atLocations = [];
    const animations = [];
    let content = [];
    for (; i < this.nodes.length && !shouldBail; i++) {
      const node = this.nodes[i];
      switch (node.type) {
        case "animation":
          animations.push(this.nodeToDoc(node));
          continue;
        case "comment": {
          const comment = {
            ...node,
            leadingWhitespace: false
          };
          comments.push(this.nodeToDoc(comment));
          continue;
        }
        case "square_brace_group":
          options.push(printOptionalArgs(node.content));
          continue;
        case "coordinate":
          name.push(this.nodeToDoc(node));
          continue;
        case "operation": {
          if (node.content.content === "at") {
            const nextNode = this.nodes[i + 1];
            if (!nextNode || !(nextNode.type === "coordinate" || nextNode.type === "unknown" && match2.anyMacro(nextNode.content))) {
              shouldBail = true;
              continue;
            }
            atLocations.push(["at", " ", this.nodeToDoc(nextNode)]);
            i++;
            continue;
          }
          shouldBail = true;
          continue;
        }
        case "unknown": {
          if (match2.group(node.content)) {
            hasNodeArgument = true;
            content = this.nodeToDoc(node);
          }
        }
      }
      break;
    }
    if (!hasNodeArgument) {
      return innerDoc;
    }
    this.nodes.splice(0, i + 1);
    let isFirstElement = true;
    let isNamed = !(Array.isArray(name) && name.length === 0);
    for (const comment of comments) {
      commentBlock.push(comment, hardline2);
    }
    if (options.length > 0) {
      innerDoc.push(join2(" ", options));
      isFirstElement = false;
    }
    if (animations.length > 0) {
      innerDoc.push(isFirstElement ? " " : line2);
      innerDoc.push(join2(line2, animations));
      isFirstElement = false;
    }
    if (isNamed) {
      innerDoc.push(isFirstElement ? " " : line2);
      innerDoc.push(name);
      isFirstElement = false;
    }
    if (atLocations.length > 0) {
      innerDoc.push(isFirstElement || isNamed ? " " : line2);
      innerDoc.push(join2(line2, atLocations));
      isFirstElement = false;
    }
    innerDoc.push(line2, content);
    return doc;
  }
  /**
   * Eat a `type === "operation"` node, including its optional arguments.
   */
  eatOperation() {
    const node = this.nodes[0];
    if ((node == null ? void 0 : node.type) === "operation") {
      this.nodes.shift();
    } else {
      return [];
    }
    const doc = [];
    if ((node == null ? void 0 : node.type) !== "operation") {
      throw new Error("Expecting `operation` node.");
    }
    const options = this.eatOptionalArg();
    doc.push(
      ...options.comments.map(
        (c) => printFragment(c, __privateGet(this, _path), __privateGet(this, _print))
      ),
      node.content.content
    );
    if (options.optionalArg) {
      doc.push(indent2(printOptionalArgs(options.optionalArg.content)));
    }
    return doc;
  }
};
_path = new WeakMap();
_print = new WeakMap();
var PATH_JOIN_OPERATIONS = /* @__PURE__ */ new Set(["rectangle", "grid", "sin", "cos", "to"]);
function isPathJoinOperation(node) {
  if (!node) {
    return false;
  }
  switch (node.type) {
    case "line_to":
    case "curve_to":
      return true;
    case "operation":
      return PATH_JOIN_OPERATIONS.has(node.content.content);
  }
  return false;
}

// libs/printer/argument.ts
function printArgument(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  if (node.openMark === "" && node.closeMark === "" && node.content.length === 0) {
    return [];
  }
  const parentNode = path.getParentNode();
  const { renderInfo: parentRenderInfo } = getNodeInfo(parentNode, options);
  if (parentRenderInfo.pgfkeysArgs) {
    const leadingComment = node.content.length > 0 && match3.comment(node.content[0]) && node.content[0].sameline ? node.content[0] : null;
    const content2 = leadingComment ? node.content.slice(1) : node.content;
    trim4(content2);
    return printArgumentPgfkeys(content2, {
      openMark: node.openMark,
      closeMark: node.closeMark,
      leadingComment
    });
  }
  if (parentRenderInfo.tikzPathCommand) {
    return printTikzArgument(path, print, options);
  }
  const openMark = node.openMark;
  const closeMark = node.closeMark;
  let content = path.map(print, "content");
  content = formatDocArray(node.content, content, options);
  if (match3.comment(node.content[node.content.length - 1])) {
    content.push(hardline2);
  }
  let rawRet = [openMark, fill2(content), closeMark];
  if (renderInfo.inParMode) {
    rawRet = [openMark, ...content, closeMark];
  }
  if (referenceMap) {
    referenceMap.setRenderCache(node, rawRet);
  }
  return rawRet;
}

// libs/printer/root.ts
import { match as match4 } from "@unified-latex/unified-latex-util-match";
function hasPreambleCode(nodes) {
  return nodes.some((node) => match4.macro(node, "documentclass"));
}
function printRoot(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  const content = path.map(print, "content");
  const rawContent = formatDocArray(node.content, content, options);
  const concatFunction = hasPreambleCode(node.content) ? (x) => x : fill2;
  return concatFunction(rawContent);
}

// libs/printer/comment.ts
import { printRaw as printRaw4 } from "@unified-latex/unified-latex-util-print-raw";
function printComment(path, _print2, _options) {
  const node = path.getNode();
  let leadingWhitespace = "";
  if (node.leadingWhitespace && node.sameline) {
    leadingWhitespace = " ";
  }
  const content = [leadingWhitespace, "%" + printRaw4(node.content)];
  return content;
}

// libs/printer/math.ts
function printInlineMath(path, print, options) {
  const node = path.getNode();
  if (node.content.length === 0) {
    return ["$", " ", "$"];
  }
  let content = path.map(print, "content");
  content = formatDocArray(node.content, content, options);
  content = joinWithSoftline(content);
  if (node.content[node.content.length - 1].type === "comment") {
    content.push(hardline2);
  }
  return fill2(["$", ...content, "$"]);
}
function printDisplayMath(path, print, options) {
  const node = path.getNode();
  let content = path.map(print, "content");
  content = formatDocArray(node.content, content, options);
  content = joinWithSoftline(content);
  const bodyStartToken = [hardline2];
  if (node.content.length === 0 || node.content[0].type === "comment" && node.content[0].sameline) {
    bodyStartToken.pop();
  }
  return [
    ESCAPE + "[",
    indent2(fill2(bodyStartToken.concat(content))),
    hardline2,
    ESCAPE + "]"
  ];
}

// libs/printer/environment.ts
import { printRaw as printRaw5 } from "@unified-latex/unified-latex-util-print-raw";
import { parseAlignEnvironment } from "@unified-latex/unified-latex-util-align";
import { trim as trim5 } from "@unified-latex/unified-latex-util-trim";
function printVerbatimEnvironment(path, print, options) {
  const node = path.getNode();
  const env = formatEnvSurround(node);
  return [env.start, node.content, env.end];
}
function printEnvironment(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  const args = node.args ? path.map(print, "args") : [];
  const env = formatEnvSurround(node);
  let content = path.map(print, "content");
  content = formatDocArray(node.content, content, options);
  if (renderInfo.inMathMode) {
    content = joinWithSoftline(content);
  }
  let bodyStartToken = [hardline2];
  if (node.content.length === 0 || node.content[0].type === "comment" && node.content[0].sameline) {
    bodyStartToken.pop();
  }
  return [
    env.start,
    ...args,
    indent2(fill2(bodyStartToken.concat(content))),
    hardline2,
    env.end
  ];
}
function printAlignedEnvironment(path, print, options) {
  const node = path.getNode();
  const { renderInfo, previousNode, nextNode, referenceMap } = getNodeInfo(
    node,
    options
  );
  const args = node.args ? path.map(print, "args") : [];
  const env = formatEnvSurround(node);
  const leadingComment = node.content[0] && node.content[0].type === "comment" && node.content[0].sameline ? node.content[0] : null;
  const { rows, rowSeps, trailingComments } = formatAlignedContent(
    leadingComment ? node.content.slice(1) : node.content
  );
  const content = [];
  for (let i = 0; i < rows.length; i++) {
    const row = rows[i];
    const rowSep = rowSeps[i];
    const trailingComment = trailingComments[i];
    content.push(row);
    if (rowSep) {
      content.push(printRaw5(rowSep));
    }
    if (rowSep && trailingComment) {
      content.push(" ");
    }
    if (trailingComment) {
      content.push(["%", printRaw5(trailingComment.content)]);
    }
    if (rowSep || trailingComment) {
      content.push(hardline2);
    }
  }
  if (content[content.length - 1] === hardline2) {
    content.pop();
  }
  if (leadingComment) {
    content.unshift(
      leadingComment.leadingWhitespace ? " " : "",
      "%" + printRaw5(leadingComment.content),
      hardline2
    );
    return [env.start, ...args, indent2(content), hardline2, env.end];
  }
  return [
    env.start,
    ...args,
    indent2([hardline2, ...content]),
    hardline2,
    env.end
  ];
}
function formatAlignedContent(nodes) {
  function getSpace(len = 1) {
    return " ".repeat(len);
  }
  const rows = parseAlignEnvironment(nodes);
  const numCols = Math.max(...rows.map((r) => r.cells.length));
  const rowSeps = rows.map(({ rowSep }) => printRaw5(rowSep || []));
  const trailingComments = rows.map(({ trailingComment }) => trailingComment);
  const renderedRows = rows.map(({ cells, colSeps }) => ({
    cells: cells.map((nodes2) => {
      trim5(nodes2);
      return printRaw5(nodes2);
    }),
    seps: colSeps.map((nodes2) => printRaw5(nodes2))
  }));
  const colWidths = [];
  for (let i = 0; i < numCols; i++) {
    colWidths.push(
      Math.max(
        ...renderedRows.map(
          ({ cells, seps }) => ((cells[i] || "") + (seps[i] || "")).length
        )
      )
    );
  }
  const joinedRows = renderedRows.map(({ cells, seps }) => {
    if (cells.length === 1 && cells[0] === "") {
      return "";
    }
    let ret = "";
    for (let i = 0; i < cells.length; i++) {
      const width = colWidths[i] - (seps[i] || "").length;
      ret += (i === 0 ? "" : " ") + cells[i] + getSpace(width - cells[i].length + 1) + (seps[i] || "");
    }
    return ret;
  });
  return { rows: joinedRows, rowSeps, trailingComments };
}

// libs/printer/printer.ts
import {
  linebreak as linebreak2,
  printRaw as printRaw6
} from "@unified-latex/unified-latex-util-print-raw";

// libs/reference-map.ts
import { visit } from "@unified-latex/unified-latex-util-visit";
var ReferenceMap = class {
  constructor(ast) {
    this.ast = ast;
    this.map = /* @__PURE__ */ new Map();
    visit(
      this.ast,
      (nodeList) => {
        for (let i = 0; i < nodeList.length; i++) {
          this.map.set(nodeList[i], {
            previous: nodeList[i - 1],
            next: nodeList[i + 1]
          });
        }
      },
      { includeArrays: true, test: Array.isArray }
    );
  }
  /**
   * Associate render-specific data with this node. This data
   * will be overwritten if `setRenderCache` is called twice.
   *
   * @param {Ast.Ast} node
   * @param {*} data
   * @memberof ReferenceMap
   */
  setRenderCache(node, data) {
    const currData = this.map.get(node) || {};
    this.map.set(node, { ...currData, renderCache: data });
  }
  /**
   * Retrieve data associated with `node` via `setRenderCache`
   *
   * @param {Ast.Ast} node
   * @returns {(object | undefined)}
   * @memberof ReferenceMap
   */
  getRenderCache(node) {
    var _a;
    return (_a = this.map.get(node)) == null ? void 0 : _a.renderCache;
  }
  getPreviousNode(node) {
    return (this.map.get(node) || {}).previous;
  }
  getNextNode(node) {
    return (this.map.get(node) || {}).next;
  }
};

// libs/printer/printer.ts
function printLatexAst(path, options, print) {
  const node = path.getValue();
  const { renderInfo } = getNodeInfo(node, options);
  if (node == null) {
    return node;
  }
  if (typeof node === "string") {
    return node;
  }
  switch (node.type) {
    case "root":
      if (options.referenceMap) {
        console.warn(
          "Processing root node, but ReferenceMap already exists. Are there multiple nodes of type 'root'?"
        );
      }
      options.referenceMap = new ReferenceMap(node);
      return printRoot(path, print, options);
    case "argument":
      return printArgument(path, print, options);
    case "comment":
      return printComment(path, print, options);
    case "environment":
    case "mathenv":
      if (renderInfo.alignContent) {
        return printAlignedEnvironment(path, print, options);
      }
      return printEnvironment(path, print, options);
    case "displaymath":
      return printDisplayMath(path, print, options);
    case "group":
      const content = printRaw6(node.content, {
        asArray: true
      }).map((token) => token === linebreak2 ? hardline2 : token);
      return ["{", ...content, "}"];
    case "inlinemath":
      return printInlineMath(path, print, options);
    case "macro":
      return printMacro(path, print, options);
    case "parbreak":
      return [hardline2, hardline2];
    case "string":
      return node.content;
    case "verb":
      return [
        ESCAPE,
        node.env,
        node.escape,
        printRaw6(node.content),
        node.escape
      ];
    case "verbatim":
      return printVerbatimEnvironment(path, print, options);
    case "whitespace":
      return line2;
    default:
      console.warn("Printing unknown type", node);
      return printRaw6(node);
  }
}

// libs/prettier-plugin-latex.ts
import { parse } from "@unified-latex/unified-latex-util-parse";
var languages = [
  {
    name: "latex",
    extensions: [".tex"],
    parsers: ["latex-parser"]
  }
];
var parsers = {
  "latex-parser": {
    parse,
    astFormat: "latex-ast",
    locStart: (node) => node.position ? node.position.start.offset : 0,
    locEnd: (node) => node.position ? node.position.end.offset : 1
  }
};
var printers = {
  "latex-ast": {
    print: printLatexAst
  }
};
var prettierPluginLatex = { languages, parsers, printers };
export {
  prettierPluginLatex,
  printLatexAst,
  printLatexAst as printer
};
//# sourceMappingURL=index.js.map
