"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/index.ts
var index_exports = {};
__export(index_exports, {
  default: () => index_default,
  languages: () => languages,
  options: () => options,
  parsers: () => parsers,
  printers: () => printers2
});
module.exports = __toCommonJS(index_exports);

// src/lexer/directives.ts
var DEFAULT_DIRECTIVES = [
  "if",
  "elseif",
  "else",
  "endif",
  "unless",
  "endunless",
  "isset",
  "endisset",
  "empty",
  "endempty",
  "switch",
  "case",
  "break",
  "default",
  "endswitch",
  "foreach",
  "endforeach",
  "for",
  "endfor",
  "while",
  "endwhile",
  "forelse",
  "endforelse",
  "continue",
  "auth",
  "elseauth",
  "endauth",
  "guest",
  "elseguest",
  "endguest",
  "can",
  "elsecan",
  "endcan",
  "canany",
  "elsecanany",
  "endcanany",
  "cannot",
  "elsecannot",
  "endcannot",
  "env",
  "elseenv",
  "endenv",
  "production",
  "elseproduction",
  "endproduction",
  "section",
  "endsection",
  "yield",
  "show",
  "stop",
  "append",
  "overwrite",
  "extends",
  "extendsFirst",
  "parent",
  "hasSection",
  "sectionMissing",
  "include",
  "includeIf",
  "includeWhen",
  "includeUnless",
  "includeFirst",
  "includeIsolated",
  "each",
  "once",
  "endonce",
  "push",
  "endpush",
  "pushOnce",
  "endPushOnce",
  "pushIf",
  "elsePushIf",
  "endPushIf",
  "prepend",
  "endprepend",
  "prependOnce",
  "endPrependOnce",
  "stack",
  "hasstack",
  "component",
  "endcomponent",
  "endComponentClass",
  "componentFirst",
  "endComponentFirst",
  "slot",
  "endslot",
  "props",
  "aware",
  "csrf",
  "method",
  "error",
  "enderror",
  "old",
  "inject",
  "dd",
  "dump",
  "vite",
  "viteReactRefresh",
  "json",
  "js",
  "unset",
  "class",
  "style",
  "checked",
  "selected",
  "disabled",
  "readonly",
  "required",
  "bool",
  "php",
  "endphp",
  "verbatim",
  "endverbatim",
  "fragment",
  "endfragment",
  "session",
  "endsession",
  "context",
  "endcontext",
  "lang",
  "endlang",
  "choice",
  "livewire",
  "livewireStyles",
  "livewireScripts",
  "entangle",
  "this",
  "persist",
  "endpersist",
  "teleport",
  "endteleport",
  "volt",
  // Inertia.js
  "inertia",
  "inertiaHead",
  // Filament
  "filamentStyles",
  "filamentScripts",
  // Blade Icons
  "svg",
  // Spatie Permission
  "role",
  "endrole",
  "hasrole",
  "endhasrole",
  "hasanyrole",
  "endhasanyrole",
  "hasallroles",
  "endhasallroles",
  "unlessrole",
  "endunlessrole",
  // Pennant
  "feature",
  "endfeature",
  "featureany",
  "endfeatureany",
  // Cashier Paddle
  "paddleJS",
  "use"
];
var CANONICAL_DIRECTIVE_CASE = /* @__PURE__ */ new Map();
for (const name of DEFAULT_DIRECTIVES) {
  const lower = name.toLowerCase();
  if (!CANONICAL_DIRECTIVE_CASE.has(lower)) {
    CANONICAL_DIRECTIVE_CASE.set(lower, name);
  }
}
var IF_WRAPPER_DIRECTIVES = /* @__PURE__ */ new Set([
  "if",
  "elseif",
  "unless",
  "isset",
  "once",
  "auth",
  "elseauth",
  "guest",
  "elseguest",
  "can",
  "elsecan",
  "cannot",
  "elsecannot",
  "canany",
  "elsecanany",
  "env",
  "elseenv",
  "production",
  "elseproduction",
  "hassection",
  "sectionmissing",
  "error",
  "role",
  "hasrole",
  "hasanyrole",
  "hasallroles",
  "unlessrole",
  "pushif",
  "elsepushif",
  "hasstack"
]);
var AGGRESSIVE_WRAPPER_ORDER = [
  "if",
  "while",
  "switch",
  "foreach",
  "for",
  "case",
  "call"
];
function getDirectivePhpWrapperKind(directiveName, context = {}) {
  const name = directiveName.toLowerCase();
  const hasDirective = context.hasDirective;
  if (context.isConditionLikeDirective?.(name)) {
    return "if";
  }
  if (name === "for") return "for";
  if (name === "foreach" || name === "forelse") return "foreach";
  if (name === "while") return "while";
  if (name === "switch") return "switch";
  if (name === "case") return "case";
  if (IF_WRAPPER_DIRECTIVES.has(name)) return "if";
  if (hasDirective?.(`else${name}`) && hasDirective(`end${name}`)) {
    return "if";
  }
  if (name.startsWith("else") && name.length > 4) {
    const baseName = name.slice(4);
    if (hasDirective?.(baseName) && hasDirective(`end${baseName}`)) {
      return "if";
    }
  }
  return "call";
}
function getDirectivePhpWrapperKinds(directiveName, mode, context = {}) {
  const first = getDirectivePhpWrapperKind(directiveName, context);
  if (mode === "safe") {
    return first === "call" ? ["call"] : [first, "call"];
  }
  const kinds = [first];
  for (const kind of AGGRESSIVE_WRAPPER_ORDER) {
    if (!kinds.includes(kind)) {
      kinds.push(kind);
    }
  }
  return kinds;
}
function getCanonicalDirectiveName(directiveName) {
  return CANONICAL_DIRECTIVE_CASE.get(directiveName.toLowerCase()) ?? null;
}
var Directives = class _Directives {
  known;
  _acceptAll;
  constructor(known, acceptAll) {
    this.known = known;
    this._acceptAll = acceptAll;
  }
  static acceptAll() {
    return new _Directives(/* @__PURE__ */ new Set(), true);
  }
  static withDefaults(extraNames = []) {
    const set = /* @__PURE__ */ new Set();
    for (const name of DEFAULT_DIRECTIVES) {
      set.add(name.toLowerCase());
    }
    for (const name of extraNames) {
      const normalized = name.trim().toLowerCase().replace(/^@/, "");
      if (normalized) set.add(normalized);
    }
    return new _Directives(set, false);
  }
  static empty() {
    return new _Directives(/* @__PURE__ */ new Set(), false);
  }
  static from(names) {
    const set = /* @__PURE__ */ new Set();
    for (const name of names) {
      set.add(name.toLowerCase());
    }
    return new _Directives(set, false);
  }
  isDirective(name) {
    if (this._acceptAll) return true;
    return this.known.has(name.toLowerCase());
  }
  isDirectiveLower(nameLower) {
    if (this._acceptAll) return true;
    return this.known.has(nameLower);
  }
  acceptsAll() {
    return this._acceptAll;
  }
  register(name) {
    this.known.add(name.toLowerCase());
    return this;
  }
};

// src/frontend-attribute-names.ts
var DOM_EVENT_NAMES = /* @__PURE__ */ new Set([
  "abort",
  "animationend",
  "animationiteration",
  "animationstart",
  "auxclick",
  "beforeinput",
  "beforematch",
  "beforetoggle",
  "beforeunload",
  "blur",
  "cancel",
  "canplay",
  "canplaythrough",
  "change",
  "click",
  "close",
  "contentvisibilityautostatechange",
  "contextlost",
  "contextmenu",
  "contextrestored",
  "copy",
  "cuechange",
  "cut",
  "dblclick",
  "drag",
  "dragend",
  "dragenter",
  "dragleave",
  "dragover",
  "dragstart",
  "drop",
  "durationchange",
  "emptied",
  "ended",
  "error",
  "focus",
  "focusin",
  "focusout",
  "formdata",
  "gotpointercapture",
  "input",
  "invalid",
  "keydown",
  "keypress",
  "keyup",
  "load",
  "loadeddata",
  "loadedmetadata",
  "loadstart",
  "lostpointercapture",
  "mousedown",
  "mouseenter",
  "mouseleave",
  "mousemove",
  "mouseout",
  "mouseover",
  "mouseup",
  "paste",
  "pause",
  "play",
  "playing",
  "pointercancel",
  "pointerdown",
  "pointerenter",
  "pointerleave",
  "pointermove",
  "pointerout",
  "pointerover",
  "pointerrawupdate",
  "pointerup",
  "progress",
  "ratechange",
  "reset",
  "resize",
  "scroll",
  "scrollend",
  "securitypolicyviolation",
  "seeked",
  "seeking",
  "select",
  "selectionchange",
  "selectstart",
  "slotchange",
  "stalled",
  "submit",
  "suspend",
  "timeupdate",
  "toggle",
  "touchcancel",
  "touchend",
  "touchmove",
  "touchstart",
  "transitioncancel",
  "transitionend",
  "transitionrun",
  "transitionstart",
  "unload",
  "volumechange",
  "waiting",
  "webkitanimationend",
  "webkitanimationiteration",
  "webkitanimationstart",
  "webkittransitionend",
  "wheel"
]);
function isFrontendEventStyleAtName(name) {
  return DOM_EVENT_NAMES.has(name.toLowerCase());
}
function isHtmlEventAttribute(name) {
  const lower = name.toLowerCase();
  if (!lower.startsWith("on")) return false;
  return DOM_EVENT_NAMES.has(lower.slice(2));
}

// src/lexer/scan-primitives.ts
function findLineEnding(src, pos, len) {
  for (let i = pos; i < len; i++) {
    const ch = src[i];
    if (ch === "\n" || ch === "\r") return i;
  }
  return -1;
}
function skipLineEnding(src, pos, len) {
  if (pos.value >= len) return;
  const byte = src[pos.value];
  if (byte === "\n") {
    pos.value++;
  } else if (byte === "\r") {
    pos.value++;
    if (pos.value < len && src[pos.value] === "\n") {
      pos.value++;
    }
  }
}
function skipQuotedString(src, pos, len, quote) {
  while (pos.value < len) {
    const quotePos = src.indexOf(quote, pos.value);
    if (quotePos === -1) {
      pos.value = len;
      return;
    }
    pos.value = quotePos;
    let backslashCount = 0;
    let checkPos = pos.value - 1;
    while (checkPos >= 0 && src[checkPos] === "\\") {
      backslashCount++;
      checkPos--;
    }
    pos.value++;
    if (backslashCount % 2 === 0) {
      return;
    }
  }
  pos.value = len;
}
function skipBlockComment(src, pos, len) {
  while (pos.value < len) {
    const starPos = src.indexOf("*", pos.value);
    if (starPos === -1) {
      pos.value = len;
      return;
    }
    pos.value = starPos + 1;
    if (pos.value < len && src[pos.value] === "/") {
      pos.value++;
      return;
    }
  }
  pos.value = len;
}
function skipLineComment(src, pos, len) {
  const lineEndPos = findLineEnding(src, pos.value, len);
  if (lineEndPos === -1) {
    pos.value = len;
  } else {
    pos.value = lineEndPos;
    skipLineEnding(src, pos, len);
  }
}
function skipLineCommentDetecting(src, pos, len, sequences) {
  const detected = [];
  const lineEndPos = findLineEnding(src, pos.value, len);
  const endPos = lineEndPos === -1 ? len : lineEndPos;
  for (const sequence of sequences) {
    const seqLen = sequence.length;
    let searchPos = pos.value;
    while (searchPos + seqLen <= endPos) {
      const foundPos = src.indexOf(sequence, searchPos);
      if (foundPos === -1 || foundPos >= endPos) {
        break;
      }
      detected.push({ sequence, offset: foundPos });
      searchPos = foundPos + seqLen;
    }
  }
  if (lineEndPos === -1) {
    pos.value = len;
  } else {
    pos.value = lineEndPos;
    skipLineEnding(src, pos, len);
  }
  return detected;
}
function skipHeredoc(src, pos, len) {
  if (pos.value >= len) return;
  const isNowdoc = src[pos.value] === "'";
  if (isNowdoc) {
    pos.value++;
  }
  const delimStart = pos.value;
  while (pos.value < len) {
    const ch = src.charCodeAt(pos.value);
    if (ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 48 && ch <= 57 || ch === 95) {
      pos.value++;
    } else {
      break;
    }
  }
  if (pos.value === delimStart) {
    pos.value = len;
    return;
  }
  const delimiter = src.slice(delimStart, pos.value);
  if (isNowdoc && pos.value < len && src[pos.value] === "'") {
    pos.value++;
  }
  const lineEndPos = findLineEnding(src, pos.value, len);
  if (lineEndPos === -1) {
    pos.value = len;
    return;
  }
  pos.value = lineEndPos;
  skipLineEnding(src, pos, len);
  const delimLen = delimiter.length;
  while (pos.value < len) {
    if (pos.value + delimLen <= len) {
      const potentialDelim = src.slice(pos.value, pos.value + delimLen);
      if (potentialDelim === delimiter) {
        const afterPos = pos.value + delimLen;
        if (afterPos >= len || src[afterPos] === "\n" || src[afterPos] === "\r" || src[afterPos] === ";") {
          pos.value = afterPos;
          if (pos.value < len && src[pos.value] === ";") {
            pos.value++;
          }
          skipLineEnding(src, pos, len);
          return;
        }
      }
    }
    const nextLineEnd = findLineEnding(src, pos.value, len);
    if (nextLineEnd === -1) {
      pos.value = len;
      return;
    }
    pos.value = nextLineEnd;
    skipLineEnding(src, pos, len);
  }
  pos.value = len;
}
function skipTemplateLiteral(src, pos, len) {
  while (pos.value < len) {
    const byte = src[pos.value];
    if (byte === "`") {
      pos.value++;
      return;
    } else if (byte === "\\") {
      pos.value += 2;
    } else if (byte === "$" && pos.value + 1 < len && src[pos.value + 1] === "{") {
      pos.value += 2;
      skipTemplateExpression(src, pos, len);
    } else {
      pos.value++;
    }
  }
}
function skipTemplateExpression(src, pos, len) {
  let depth = 1;
  while (depth > 0 && pos.value < len) {
    const byte = src[pos.value];
    if (byte === "{") {
      depth++;
      pos.value++;
    } else if (byte === "}") {
      depth--;
      pos.value++;
    } else if (byte === "'" || byte === '"') {
      pos.value++;
      skipQuotedString(src, pos, len, byte);
    } else if (byte === "`") {
      pos.value++;
      skipTemplateLiteral(src, pos, len);
    } else if (byte === "/" && pos.value + 1 < len) {
      const next = src[pos.value + 1];
      if (next === "/") {
        pos.value += 2;
        skipLineComment(src, pos, len);
      } else if (next === "*") {
        pos.value += 2;
        skipBlockComment(src, pos, len);
      } else {
        pos.value++;
      }
    } else {
      pos.value++;
    }
  }
}
function skipBacktickString(src, pos, len) {
  skipQuotedString(src, pos, len, "`");
}

// src/lexer/lexer.ts
var RAWTEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style"]);
var ATTR_LIKE_AT_NAME_CONTINUATION = /* @__PURE__ */ new Set([".", "-", ":", "[", "]"]);
var Lexer = class {
  src;
  pos = 0;
  len;
  state = 0 /* Data */;
  returnState = 0 /* Data */;
  tokens = [];
  errors = [];
  verbatim = false;
  verbatimReturnState = null;
  phpBlock = false;
  phpTag = false;
  attrPhpDirectiveDepth = 0;
  rawtextTagName = "";
  currentTagName = "";
  currentTagStart = -1;
  ignoreRanges;
  nextIgnoreRangeIndex = 0;
  ignoreRangeCollector;
  pendingHtmlCommentOriginState = null;
  pendingHtmlCommentTagStart = null;
  pendingBladeCommentOriginState = null;
  pendingBladeCommentTagStart = null;
  isAtAttributeCandidate(nameLower, afterNamePos) {
    if (afterNamePos >= this.len) {
      return isFrontendEventStyleAtName(nameLower);
    }
    const immediate = this.src[afterNamePos];
    if (ATTR_LIKE_AT_NAME_CONTINUATION.has(immediate)) {
      return true;
    }
    let pos = afterNamePos;
    while (pos < this.len && isSpace(this.src.charCodeAt(pos))) {
      pos++;
    }
    if (pos < this.len && this.src[pos] === "=") {
      return true;
    }
    if (!isFrontendEventStyleAtName(nameLower)) {
      return false;
    }
    return pos >= this.len || this.src[pos] === ">" || this.src[pos] === "/" || isSpace(immediate.charCodeAt(0));
  }
  isClosingTag = false;
  continuedTagName = false;
  inXmlDeclaration = false;
  _directives;
  verbatimStartDirectives = /* @__PURE__ */ new Set(["verbatim"]);
  verbatimEndDirectives = /* @__PURE__ */ new Set(["endverbatim"]);
  constructor(source, directives, rawBlockConfig) {
    this.src = source;
    this.len = source.length;
    this._directives = directives ?? Directives.acceptAll();
    this.ignoreRanges = rawBlockConfig?.ignoreRanges ?? [];
    this.ignoreRangeCollector = rawBlockConfig?.ignoreRangeCollector ?? null;
    for (const directive of rawBlockConfig?.verbatimStartDirectives ?? []) {
      const normalized = normalizeDirectiveName(directive);
      if (normalized) this.verbatimStartDirectives.add(normalized);
    }
    for (const directive of rawBlockConfig?.verbatimEndDirectives ?? []) {
      const normalized = normalizeDirectiveName(directive);
      if (normalized) this.verbatimEndDirectives.add(normalized);
    }
  }
  directives() {
    return this._directives;
  }
  tokenize() {
    while (this.pos < this.len) {
      if (this.tryEmitIgnoreRange()) {
        continue;
      }
      switch (this.state) {
        case 0 /* Data */:
          this.scanData();
          break;
        case 9 /* RawText */:
          this.scanRawtext();
          break;
        case 11 /* BladeComment */:
          this.scanBladeCommentContent();
          break;
        case 10 /* Comment */:
          this.scanComment();
          break;
        case 2 /* TagName */:
          this.scanTagName();
          break;
        case 3 /* BeforeAttrName */:
          this.scanBeforeAttrName();
          break;
        case 4 /* AttrName */:
          this.scanAttrName();
          break;
        case 5 /* AfterAttrName */:
          this.scanAfterAttrName();
          break;
        case 6 /* BeforeAttrValue */:
          this.scanBeforeAttrValue();
          break;
        case 7 /* AttrValueQuoted */:
          this.scanAttrValueQuoted();
          break;
        case 8 /* AttrValueUnquoted */:
          this.scanAttrValueUnquoted();
          break;
        default:
          break;
      }
    }
    if (this.state === 2 /* TagName */ || this.state === 3 /* BeforeAttrName */ || this.state === 4 /* AttrName */ || this.state === 5 /* AfterAttrName */ || this.state === 6 /* BeforeAttrValue */ || this.state === 7 /* AttrValueQuoted */ || this.state === 8 /* AttrValueUnquoted */) {
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
    }
    this.ignoreRangeCollector?.finish(this.snapshotIgnoreRangeResumeState(), this.len);
    return { tokens: this.tokens, errors: this.errors };
  }
  emit(type, start, end) {
    this.tokens.push({ type, start, end });
  }
  snapshotIgnoreRangeResumeState() {
    return {
      state: this.state,
      returnState: this.returnState,
      rawtextTagName: this.rawtextTagName,
      currentTagName: this.currentTagName,
      isClosingTag: this.isClosingTag,
      continuedTagName: this.continuedTagName,
      inXmlDeclaration: this.inXmlDeclaration,
      verbatim: this.verbatim,
      verbatimReturnState: this.verbatimReturnState,
      phpBlock: this.phpBlock,
      phpTag: this.phpTag,
      attrPhpDirectiveDepth: this.attrPhpDirectiveDepth
    };
  }
  restoreIgnoreRangeResumeState(resume) {
    this.state = resume.state;
    this.returnState = resume.returnState;
    this.rawtextTagName = resume.rawtextTagName;
    this.currentTagName = resume.currentTagName;
    this.isClosingTag = resume.isClosingTag;
    this.continuedTagName = resume.continuedTagName;
    this.inXmlDeclaration = resume.inXmlDeclaration;
    this.verbatim = resume.verbatim;
    this.verbatimReturnState = resume.verbatimReturnState;
    this.phpBlock = resume.phpBlock;
    this.phpTag = resume.phpTag;
    this.attrPhpDirectiveDepth = resume.attrPhpDirectiveDepth;
  }
  tryEmitIgnoreRange() {
    const range = this.ignoreRanges[this.nextIgnoreRangeIndex];
    if (!range || this.pos !== range.start) {
      return false;
    }
    this.emit(51 /* IgnoreRange */, range.start, range.end);
    this.pos = range.end;
    this.restoreIgnoreRangeResumeState(range.resume);
    this.nextIgnoreRangeIndex++;
    return true;
  }
  nextIgnoreRangeStart() {
    const range = this.ignoreRanges[this.nextIgnoreRangeIndex];
    return range ? range.start : null;
  }
  recordBladeComment(start, end, originState, tagStart) {
    this.ignoreRangeCollector?.handleBladeComment(
      start,
      end,
      originState,
      tagStart,
      this.snapshotIgnoreRangeResumeState()
    );
  }
  recordHtmlComment(start, end, originState, tagStart) {
    this.ignoreRangeCollector?.handleHtmlComment(
      start,
      end,
      originState,
      tagStart,
      this.snapshotIgnoreRangeResumeState()
    );
  }
  beginBladeCommentCapture(originState, tagStart) {
    this.pendingBladeCommentOriginState = originState;
    this.pendingBladeCommentTagStart = tagStart;
  }
  beginHtmlCommentCapture(originState, tagStart) {
    this.pendingHtmlCommentOriginState = originState;
    this.pendingHtmlCommentTagStart = tagStart;
  }
  logError(reason, offset) {
    this.errors.push({ reason, offset });
  }
  peek() {
    return this.pos < this.len ? this.src[this.pos] : null;
  }
  peekAhead(n) {
    const p = this.pos + n;
    return p < this.len ? this.src[p] : null;
  }
  skipWhitespace() {
    while (this.pos < this.len && isSpace(this.src.charCodeAt(this.pos))) {
      this.pos++;
    }
  }
  skipAndEmitWhitespace() {
    const start = this.pos;
    while (this.pos < this.len && isSpace(this.src.charCodeAt(this.pos))) {
      this.pos++;
    }
    if (start < this.pos) {
      this.emit(9 /* Whitespace */, start, this.pos);
    }
  }
  scanAttributePhpDirectiveContent() {
    if (this.attrPhpDirectiveDepth <= 0) return false;
    const start = this.pos;
    while (this.pos < this.len) {
      const ch = this.src[this.pos];
      if (ch === '"' || ch === "'") {
        this.pos++;
        this.skipQuotedStringPrim(ch);
        continue;
      }
      if (ch === "`") {
        this.pos++;
        this.skipBacktickStringPrim();
        continue;
      }
      if (ch === "/" && this.pos + 1 < this.len) {
        const next = this.src[this.pos + 1];
        if (next === "/") {
          this.pos += 2;
          while (this.pos < this.len) {
            const c = this.src[this.pos];
            if (c === "\n" || c === "\r") {
              this.pos++;
              break;
            }
            this.pos++;
          }
          continue;
        }
        if (next === "*") {
          this.pos += 2;
          this.skipBlockCommentPrim();
          continue;
        }
      }
      if (ch === "#") {
        this.pos++;
        while (this.pos < this.len) {
          const c = this.src[this.pos];
          if (c === "\n" || c === "\r") {
            this.pos++;
            break;
          }
          this.pos++;
        }
        continue;
      }
      if (ch === "<" && this.pos + 2 < this.len && this.src[this.pos + 1] === "<" && this.src[this.pos + 2] === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
        continue;
      }
      if (ch === "@" && !this.verbatim && !this.phpTag) {
        let nameEnd = this.pos + 1;
        while (nameEnd < this.len) {
          const cc = this.src.charCodeAt(nameEnd);
          if (isAlnum(cc) || cc === 95) {
            nameEnd++;
          } else {
            break;
          }
        }
        if (nameEnd > this.pos + 1) {
          const name = this.src.slice(this.pos + 1, nameEnd).toLowerCase();
          if (name === "php" || name === "endphp") {
            if (start < this.pos) {
              this.emit(0 /* Text */, start, this.pos);
            }
            this.returnState = this.state;
            this.scanDirective();
            return true;
          }
        }
      }
      this.pos++;
    }
    if (start < this.pos) {
      this.emit(0 /* Text */, start, this.pos);
    }
    return true;
  }
  posRef() {
    return { value: this.pos };
  }
  syncPos(ref) {
    this.pos = ref.value;
  }
  skipQuotedStringPrim(quote) {
    const ref = this.posRef();
    skipQuotedString(this.src, ref, this.len, quote);
    this.syncPos(ref);
  }
  skipBlockCommentPrim() {
    const ref = this.posRef();
    skipBlockComment(this.src, ref, this.len);
    this.syncPos(ref);
  }
  skipHeredocPrim() {
    const ref = this.posRef();
    skipHeredoc(this.src, ref, this.len);
    this.syncPos(ref);
  }
  skipBacktickStringPrim() {
    const ref = this.posRef();
    skipBacktickString(this.src, ref, this.len);
    this.syncPos(ref);
  }
  skipTemplateLiteralPrim() {
    const ref = this.posRef();
    skipTemplateLiteral(this.src, ref, this.len);
    this.syncPos(ref);
  }
  /**
   * Skip line comment with warnings about ?> inside comments.
   */
  skipLineCommentWithWarnings() {
    const ref = this.posRef();
    const detected = skipLineCommentDetecting(this.src, ref, this.len, ["?>"]);
    this.syncPos(ref);
    for (const d of detected) {
      this.logError(2 /* PhpCloseTagInComment */, d.offset);
    }
  }
  /**
   * Detect if the current position starts a Blade/PHP construct.
   * Used for construct collision detection inside echos.
   */
  detectConstruct() {
    if (this.pos >= this.len) return false;
    const byte = this.src[this.pos];
    if (byte === "{" && this.peekAhead(1) === "{" && this.peekAhead(2) === "{") {
      return true;
    }
    if (byte === "{" && this.peekAhead(1) === "{" && this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
      return true;
    }
    if (byte === "{" && this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
      return true;
    }
    if (byte === "{" && this.peekAhead(1) === "{") {
      return true;
    }
    if (byte === "@" && this.pos + 1 < this.len) {
      const next = this.src[this.pos + 1];
      if (isAlpha(next.charCodeAt(0))) {
        return true;
      }
    }
    if (byte === "<" && this.peekAhead(1) === "?") {
      if (this.phpTagStartLength(this.pos) > 0) {
        return true;
      }
    }
    return false;
  }
  /**
   * Case-insensitive ASCII word match at a source offset.
   */
  hasAsciiWordAt(pos, word) {
    if (pos + word.length > this.len) return false;
    for (let i = 0; i < word.length; i++) {
      let code = this.src.charCodeAt(pos + i);
      if (code >= 65 && code <= 90) code += 32;
      if (code !== word.charCodeAt(i)) {
        return false;
      }
    }
    return true;
  }
  /**
   * Fast-forward to next character relevant to TSX generic scanning.
   */
  nextInterestingPosForTsxGeneric(fromPos) {
    for (let i = fromPos; i < this.len; i++) {
      switch (this.src.charCodeAt(i)) {
        case 60:
        // <
        case 62:
        // >
        case 34:
        // "
        case 39:
        // '
        case 96:
        // `
        case 64:
        // @
        case 10:
        // \n
        case 13:
          return i;
      }
    }
    return this.len;
  }
  /**
   * Fast-forward to next character relevant to balanced JS-like scanning.
   */
  nextInterestingPosForBalancedJsLike(fromPos) {
    for (let i = fromPos; i < this.len; i++) {
      switch (this.src.charCodeAt(i)) {
        case 123:
        // {
        case 125:
        // }
        case 40:
        // (
        case 41:
        // )
        case 34:
        // "
        case 39:
        // '
        case 96:
        // `
        case 47:
        // /
        case 64:
        // @
        case 10:
        // \n
        case 13:
          return i;
      }
    }
    return this.len;
  }
  scanData() {
    const start = this.pos;
    while (this.pos < this.len) {
      const nextIgnoreRangeStart = this.nextIgnoreRangeStart();
      if (nextIgnoreRangeStart !== null && this.pos === nextIgnoreRangeStart) {
        if (start < this.pos) {
          if (this.phpBlock) {
            this.emit(31 /* PhpBlock */, start, this.pos);
          } else if (this.phpTag) {
            this.emit(41 /* PhpContent */, start, this.pos);
          } else {
            this.emit(0 /* Text */, start, this.pos);
          }
        }
        return;
      }
      const byte = this.src[this.pos];
      if (this.phpBlock) {
        if (byte === "'" || byte === '"') {
          this.pos++;
          this.skipQuotedStringPrim(byte);
          continue;
        }
        if (byte === "`") {
          this.pos++;
          this.skipBacktickStringPrim();
          continue;
        }
        if (byte === "/" && this.pos + 1 < this.len) {
          const next = this.src[this.pos + 1];
          if (next === "/") {
            this.pos += 2;
            while (this.pos < this.len) {
              const ch = this.src[this.pos];
              if (ch === "\n" || ch === "\r") {
                this.pos++;
                break;
              }
              this.pos++;
            }
            continue;
          }
          if (next === "*") {
            this.pos += 2;
            this.skipBlockCommentPrim();
            continue;
          }
        }
        if (byte === "#") {
          this.pos++;
          while (this.pos < this.len) {
            const ch = this.src[this.pos];
            if (ch === "\n" || ch === "\r") {
              this.pos++;
              break;
            }
            this.pos++;
          }
          continue;
        }
        if (byte === "<" && this.pos + 2 < this.len && this.src[this.pos + 1] === "<" && this.src[this.pos + 2] === "<") {
          this.pos += 3;
          this.skipHeredocPrim();
          continue;
        }
        if (byte === "@" && this.isEndphpAt(this.pos)) {
          if (start < this.pos) {
            this.emit(31 /* PhpBlock */, start, this.pos);
          }
          this.scanDirective();
          return;
        }
        this.pos++;
        continue;
      }
      if (byte === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        const prevChar = this.pos > 0 ? this.src[this.pos - 1] : null;
        if (prevChar === "@") {
          this.pos++;
          continue;
        }
        const next1 = this.peekAhead(1);
        if (next1 === "{") {
          const next2 = this.peekAhead(2);
          const next3 = this.peekAhead(3);
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          if (next2 === "-" && next3 === "-") {
            this.beginBladeCommentCapture(0 /* Data */, null);
            this.scanBladeCommentStart();
            return;
          }
          this.scanEcho();
          return;
        } else if (next1 === "!" && this.pos + 2 < this.len && this.src[this.pos + 2] === "!") {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          this.scanRawEcho();
          return;
        } else {
          this.pos++;
        }
      } else if (byte === "@") {
        if (this.verbatim) {
          if (this.isVerbatimTerminatorAt(this.pos)) {
            if (start < this.pos) {
              this.emit(0 /* Text */, start, this.pos);
            }
            this.scanDirective();
            return;
          }
          this.pos++;
          continue;
        }
        if (this.phpTag) {
          this.pos++;
          continue;
        }
        const prevChar = this.pos > 0 ? this.src[this.pos - 1] : null;
        const canStart = this.pos === 0 || prevChar !== null && !isAlnum(prevChar.charCodeAt(0)) && prevChar !== "@";
        if (canStart) {
          const nextPos = this.pos + 1;
          let isEscaped = false;
          if (nextPos < this.len) {
            const nextByte = this.src[nextPos];
            if (nextByte === "@") {
              isEscaped = true;
            } else if (nextByte === "{" && nextPos + 1 < this.len) {
              const afterBrace = this.src[nextPos + 1];
              if (afterBrace === "{" || afterBrace === "!") {
                isEscaped = true;
              }
            }
          }
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          if (isEscaped) {
            this.emit(17 /* AtSign */, this.pos, this.pos + 1);
            this.pos++;
            return;
          }
          this.scanDirective();
          return;
        } else {
          this.pos++;
        }
      } else if (byte === "<" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        if (this.pos + 9 <= this.len && this.src[this.pos + 1] === "!" && this.src.slice(this.pos + 2, this.pos + 9).toLowerCase() === "doctype") {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          this.scanDoctype();
          return;
        }
        if (this.pos + 3 <= this.len && this.src[this.pos + 1] === "!" && this.src[this.pos + 2] === "[") {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          if (this.tryScanCdata()) {
            return;
          }
          this.tryScanConditionalCommentEnd();
          return;
        }
        if (this.pos + 4 <= this.len && this.src[this.pos + 1] === "!" && this.src[this.pos + 2] === "-" && this.src[this.pos + 3] === "-") {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          if (this.tryScanConditionalComment()) {
            return;
          }
          this.state = 10 /* Comment */;
          return;
        }
        if (this.pos + 3 <= this.len && this.src[this.pos + 1] === "!" && this.src[this.pos + 2] === "-" && (this.pos + 3 >= this.len || this.src[this.pos + 3] !== "-")) {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          const bogusStart = this.pos;
          this.pos += 3;
          while (this.pos < this.len) {
            if (this.src[this.pos] === ">") {
              this.pos++;
              this.emit(36 /* BogusComment */, bogusStart, this.pos);
              return;
            }
            if (this.pos + 1 < this.len && this.src[this.pos] === "-" && this.src[this.pos + 1] === ">") {
              this.pos += 2;
              this.emit(36 /* BogusComment */, bogusStart, this.pos);
              return;
            }
            this.pos++;
          }
          this.emit(36 /* BogusComment */, bogusStart, this.pos);
          return;
        }
        if (this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
          const scanStart = this.pos;
          const tokensBefore = this.tokens.length;
          if (this.tryScanDecl() || this.tryScanProcessingInstruction() || this.tryScanBogusComment()) {
            if (start < scanStart) {
              this.tokens.splice(tokensBefore, 0, {
                type: 0 /* Text */,
                start,
                end: scanStart
              });
            }
            return;
          }
          if (this.phpTagStartLength(this.pos) > 0) {
            if (start < this.pos) {
              this.emit(0 /* Text */, start, this.pos);
            }
            this.tryScanPhpTag();
            return;
          }
          this.pos++;
          continue;
        }
        if (this.pos + 1 < this.len && this.src[this.pos + 1] === "-" && (this.pos + 2 >= this.len || this.src[this.pos + 2] !== "-")) {
          const scanStart = this.pos;
          const tokensBefore = this.tokens.length;
          if (this.tryScanBogusComment()) {
            if (start < scanStart) {
              this.tokens.splice(tokensBefore, 0, {
                type: 0 /* Text */,
                start,
                end: scanStart
              });
            }
            return;
          }
          this.pos++;
          continue;
        }
        const nextChar = this.pos + 1 < this.len ? this.src[this.pos + 1] : null;
        const isValidTagStart = nextChar !== null && (isAlpha(nextChar.charCodeAt(0)) || nextChar === "/" || nextChar === "_" || nextChar === ">" || nextChar === "{" || nextChar === "@");
        if (isValidTagStart) {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          this.scanTagOpen();
          return;
        } else {
          this.pos++;
        }
      } else if (byte === "?" && this.phpTag) {
        if (this.isPhpTagEndAt(this.pos)) {
          if (start < this.pos) {
            this.emit(41 /* PhpContent */, start, this.pos);
          }
          this.emit(40 /* PhpTagEnd */, this.pos, this.pos + 2);
          this.pos += 2;
          this.phpTag = false;
          return;
        }
        this.pos++;
      } else {
        this.pos++;
      }
    }
    if (start < this.pos) {
      if (this.phpBlock) {
        this.logError(0 /* UnexpectedEof */, this.pos);
        this.emit(31 /* PhpBlock */, start, this.pos);
      } else if (this.phpTag) {
        this.emit(41 /* PhpContent */, start, this.pos);
      } else if (this.verbatim) {
        this.logError(0 /* UnexpectedEof */, this.pos);
        this.emit(0 /* Text */, start, this.pos);
      } else {
        this.emit(0 /* Text */, start, this.pos);
      }
    }
  }
  scanComment() {
    const start = this.pos;
    const originState = this.pendingHtmlCommentOriginState ?? 0 /* Data */;
    const tagStart = this.pendingHtmlCommentTagStart;
    this.pendingHtmlCommentOriginState = null;
    this.pendingHtmlCommentTagStart = null;
    this.emit(10 /* CommentStart */, start, start + 4);
    this.pos += 4;
    const contentStart = this.pos;
    const closePos = this.src.indexOf("-->", this.pos);
    if (closePos === -1) {
      if (contentStart < this.len) {
        this.emit(0 /* Text */, contentStart, this.len);
      }
      this.logError(0 /* UnexpectedEof */, this.len);
      this.pos = this.len;
      this.state = 0 /* Data */;
      this.recordHtmlComment(start, this.pos, originState, tagStart);
      return;
    }
    if (contentStart < closePos) {
      this.emit(0 /* Text */, contentStart, closePos);
    }
    this.emit(11 /* CommentEnd */, closePos, closePos + 3);
    this.pos = closePos + 3;
    this.state = 0 /* Data */;
    this.recordHtmlComment(start, this.pos, originState, tagStart);
  }
  tryScanBogusComment() {
    if (this.pos + 1 >= this.len) return false;
    const start = this.pos;
    if (this.src[this.pos] === "<" && this.src[this.pos + 1] === "?") {
      const tagLen = this.phpTagStartLength(this.pos);
      if (tagLen > 0) return false;
      this.pos += 2;
      while (this.pos < this.len) {
        if (this.src[this.pos] === ">") {
          this.pos++;
          this.emit(36 /* BogusComment */, start, this.pos);
          return true;
        }
        this.pos++;
      }
      this.pos = start;
      return false;
    }
    if (this.src[this.pos] === "<" && this.src[this.pos + 1] === "-") {
      if (this.pos + 2 < this.len && this.src[this.pos + 2] === "-") {
        return false;
      }
      this.pos += 2;
      while (this.pos + 1 < this.len) {
        if (this.src[this.pos] === "-" && this.src[this.pos + 1] === ">") {
          this.pos += 2;
          this.emit(36 /* BogusComment */, start, this.pos);
          return true;
        }
        this.pos++;
      }
      this.pos = start;
      return false;
    }
    return false;
  }
  scanBladeCommentStart() {
    const start = this.pos;
    this.pos += 4;
    this.emit(12 /* BladeCommentStart */, start, this.pos);
    this.state = 11 /* BladeComment */;
  }
  scanBladeCommentContent() {
    const start = this.pos;
    const commentStart = start - 4;
    const originState = this.pendingBladeCommentOriginState ?? this.returnState;
    const tagStart = this.pendingBladeCommentTagStart;
    this.pendingBladeCommentOriginState = null;
    this.pendingBladeCommentTagStart = null;
    while (this.pos < this.len) {
      const closePos = this.src.indexOf("--}}", this.pos);
      if (closePos === -1) {
        if (start < this.len) {
          this.emit(0 /* Text */, start, this.len);
        }
        this.pos = this.len;
        this.logError(0 /* UnexpectedEof */, this.len);
        this.state = this.returnState;
        this.returnState = 0 /* Data */;
        this.recordBladeComment(commentStart, this.pos, originState, tagStart);
        return;
      }
      if (closePos > start) {
        this.emit(0 /* Text */, start, closePos);
      }
      this.emit(13 /* BladeCommentEnd */, closePos, closePos + 4);
      this.pos = closePos + 4;
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      this.recordBladeComment(commentStart, this.pos, originState, tagStart);
      return;
    }
    this.state = this.returnState;
    this.returnState = 0 /* Data */;
    this.recordBladeComment(commentStart, this.pos, originState, tagStart);
  }
  tryScanConditionalComment() {
    if (this.pos + 5 >= this.len) return false;
    if (this.src.slice(this.pos, this.pos + 5) !== "<!--[") return false;
    const start = this.pos;
    let scanPos = this.pos + 5;
    while (scanPos + 1 < this.len) {
      if (this.src[scanPos] === "]" && this.src[scanPos + 1] === ">") {
        const afterMarker = scanPos + 2;
        if (afterMarker + 5 <= this.len && this.src.slice(afterMarker, afterMarker + 5) === "<!-->") {
          return false;
        }
        this.pos = afterMarker;
        this.emit(37 /* ConditionalCommentStart */, start, this.pos);
        return true;
      }
      scanPos++;
    }
    this.pos = this.len;
    this.emit(37 /* ConditionalCommentStart */, start, this.pos);
    return true;
  }
  tryScanConditionalCommentEnd() {
    if (this.pos + 3 > this.len) return false;
    if (this.src.slice(this.pos, this.pos + 3) !== "<![") return false;
    const start = this.pos;
    this.pos += 3;
    return this.scanConditionalClosing(start);
  }
  scanConditionalClosing(start) {
    while (this.pos + 3 < this.len) {
      if (this.src[this.pos] === "]" && this.src[this.pos + 1] === "-" && this.src[this.pos + 2] === "-" && this.src[this.pos + 3] === ">") {
        this.pos += 4;
        this.emit(38 /* ConditionalCommentEnd */, start, this.pos);
        return true;
      }
      this.pos++;
    }
    this.pos = this.len;
    this.emit(38 /* ConditionalCommentEnd */, start, this.pos);
    return true;
  }
  tryScanCdata() {
    if (this.pos + 9 > this.len) return false;
    if (this.src.slice(this.pos, this.pos + 9) !== "<![CDATA[") return false;
    const start = this.pos;
    this.emit(42 /* CdataStart */, start, start + 9);
    this.pos += 9;
    const contentStart = this.pos;
    const closePos = this.src.indexOf("]]>", this.pos);
    if (closePos === -1) {
      if (contentStart < this.len) {
        this.emit(0 /* Text */, contentStart, this.len);
      }
      this.logError(0 /* UnexpectedEof */, this.len);
      this.pos = this.len;
      return true;
    }
    if (contentStart < closePos) {
      this.emit(0 /* Text */, contentStart, closePos);
    }
    this.emit(43 /* CdataEnd */, closePos, closePos + 3);
    this.pos = closePos + 3;
    return true;
  }
  tryScanProcessingInstruction() {
    if (this.pos + 2 > this.len) return false;
    if (this.src[this.pos] !== "<" || this.src[this.pos + 1] !== "?") {
      return false;
    }
    if (this.pos + 2 >= this.len) return false;
    const thirdChar = this.src[this.pos + 2];
    if (isSpace(thirdChar.charCodeAt(0))) return false;
    if (!isAlpha(thirdChar.charCodeAt(0))) return false;
    if (this.phpTagStartLength(this.pos) > 0) return false;
    const targetStart = this.pos + 2;
    let targetEnd = targetStart;
    while (targetEnd < this.len) {
      const c = this.src[targetEnd];
      const cc = c.charCodeAt(0);
      if (isAlnum(cc) || c === "-" || c === "_" || c === ":") {
        targetEnd++;
      } else {
        break;
      }
    }
    const targetName = this.src.slice(targetStart, targetEnd);
    if (targetName.toLowerCase() === "xml") return false;
    const start = this.pos;
    const piStartEnd = targetEnd;
    this.emit(46 /* PIStart */, start, piStartEnd);
    this.pos = piStartEnd;
    const contentStart = this.pos;
    while (this.pos + 1 < this.len) {
      if (this.src[this.pos] === "?" && this.src[this.pos + 1] === ">") {
        if (contentStart < this.pos) {
          this.emit(0 /* Text */, contentStart, this.pos);
        }
        this.emit(47 /* PIEnd */, this.pos, this.pos + 2);
        this.pos += 2;
        return true;
      }
      this.pos++;
    }
    if (contentStart < this.len) {
      this.emit(0 /* Text */, contentStart, this.len);
    }
    this.pos = this.len;
    this.logError(0 /* UnexpectedEof */, this.len);
    return true;
  }
  tryScanDecl() {
    if (this.pos + 5 > this.len) return false;
    if (this.src[this.pos] !== "<" || this.src[this.pos + 1] !== "?") {
      return false;
    }
    const xmlMatch = this.hasAsciiWordAt(this.pos + 2, "xml");
    if (!xmlMatch) return false;
    if (this.pos + 5 < this.len) {
      const next = this.src[this.pos + 5];
      const cc = next.charCodeAt(0);
      if (isAlnum(cc) || next === "_" || next === "-" || next === ":") {
        return false;
      }
    }
    const start = this.pos;
    this.emit(44 /* DeclStart */, start, start + 5);
    this.pos += 5;
    this.inXmlDeclaration = true;
    this.state = 3 /* BeforeAttrName */;
    return true;
  }
  phpTagStartLength(pos) {
    if (pos + 2 > this.len || this.src[pos] !== "<" || this.src[pos + 1] !== "?") {
      return 0;
    }
    if (pos + 5 <= this.len) {
      const matchesPhp = this.hasAsciiWordAt(pos + 2, "php");
      if (matchesPhp) {
        if (pos + 5 < this.len) {
          const next = this.src[pos + 5];
          const cc = next.charCodeAt(0);
          if (isAlnum(cc) || next === "_") {
            return 0;
          }
        }
        return 5;
      }
    }
    if (pos + 3 <= this.len && this.src[pos + 2] === "=") {
      return 3;
    }
    return 0;
  }
  isPhpTagEndAt(pos) {
    return pos + 2 <= this.len && this.src[pos] === "?" && this.src[pos + 1] === ">";
  }
  tryScanPhpTag() {
    if (this.pos + 1 >= this.len || this.src[this.pos] !== "<" || this.src[this.pos + 1] !== "?") {
      return false;
    }
    const start = this.pos;
    this.pos += 2;
    if (this.pos + 3 <= this.len) {
      const matchesPhp = this.hasAsciiWordAt(this.pos, "php");
      if (matchesPhp) {
        if (this.pos + 3 < this.len) {
          const next = this.src[this.pos + 3];
          const cc = next.charCodeAt(0);
          if (isAlnum(cc) || next === "_") {
            this.pos = start;
            return false;
          }
        }
        this.pos += 3;
      } else if (this.pos < this.len && this.src[this.pos] === "=") {
        this.pos++;
      } else {
        this.pos = start;
        return false;
      }
    } else if (this.pos < this.len && this.src[this.pos] === "=") {
      this.pos++;
    } else {
      this.pos = start;
      return false;
    }
    this.emit(39 /* PhpTagStart */, start, this.pos);
    this.scanPhpContent();
    return true;
  }
  scanPhpContent() {
    const start = this.pos;
    while (true) {
      if (this.pos >= this.len) {
        if (this.pos > start) {
          this.emit(41 /* PhpContent */, start, this.pos);
        }
        return;
      }
      if (this.pos + 1 < this.len && this.src[this.pos] === "?" && this.src[this.pos + 1] === ">") {
        if (this.pos > start) {
          this.emit(41 /* PhpContent */, start, this.pos);
        }
        this.emit(40 /* PhpTagEnd */, this.pos, this.pos + 2);
        this.pos += 2;
        return;
      }
      const byte = this.src[this.pos];
      if (byte === '"' || byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim(byte);
      } else if (byte === "/" && this.pos + 1 < this.len) {
        const next = this.src[this.pos + 1];
        if (next === "/") {
          this.pos += 2;
          while (this.pos < this.len) {
            const ch = this.src[this.pos];
            if (ch === "\n" || ch === "\r") {
              this.pos++;
              break;
            }
            if (this.pos + 2 <= this.len && this.src[this.pos] === "?" && this.src[this.pos + 1] === ">") {
              break;
            }
            this.pos++;
          }
        } else if (next === "*") {
          this.pos += 2;
          this.skipBlockCommentPrim();
        } else {
          this.pos++;
        }
      } else if (byte === "#") {
        this.pos++;
        while (this.pos < this.len) {
          const ch = this.src[this.pos];
          if (ch === "\n" || ch === "\r") {
            this.pos++;
            break;
          }
          if (this.pos + 2 <= this.len && this.src[this.pos] === "?" && this.src[this.pos + 1] === ">") {
            break;
          }
          this.pos++;
        }
      } else if (byte === "<" && this.pos + 2 < this.len && this.src[this.pos + 1] === "<" && this.src[this.pos + 2] === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
      } else {
        this.pos++;
      }
    }
  }
  scanDoctype() {
    this.emit(14 /* DoctypeStart */, this.pos, this.pos + 9);
    this.pos += 9;
    this.skipAndEmitWhitespace();
    const contentStart = this.pos;
    while (this.pos < this.len && this.src[this.pos] !== ">") {
      this.pos++;
    }
    if (contentStart < this.pos) {
      this.emit(15 /* Doctype */, contentStart, this.pos);
    }
    if (this.pos < this.len && this.src[this.pos] === ">") {
      this.emit(16 /* DoctypeEnd */, this.pos, this.pos + 1);
      this.pos++;
    }
  }
  scanTagOpen() {
    const start = this.pos;
    this.currentTagName = "";
    this.currentTagStart = start;
    this.emit(1 /* LessThan */, start, start + 1);
    this.pos++;
    if (this.pos < this.len && this.src[this.pos] === "/") {
      this.emit(3 /* Slash */, this.pos, this.pos + 1);
      this.pos++;
      this.isClosingTag = true;
    } else {
      this.isClosingTag = false;
    }
    this.state = 2 /* TagName */;
  }
  checkRawtextMode() {
    if (this.isClosingTag) return 0 /* Data */;
    const tagNameLower = this.currentTagName.toLowerCase();
    if (RAWTEXT_ELEMENTS.has(tagNameLower)) {
      this.rawtextTagName = tagNameLower;
      return 9 /* RawText */;
    }
    return 0 /* Data */;
  }
  scanTagName() {
    const start = this.pos;
    if (this.continuedTagName && this.pos < this.len && isSpace(this.src.charCodeAt(this.pos))) {
      this.continuedTagName = false;
      this.state = 3 /* BeforeAttrName */;
      return;
    }
    if (!this.continuedTagName) {
      this.skipWhitespace();
    }
    this.continuedTagName = false;
    if (this.pos >= this.len || this.src[this.pos] === ">" || this.src[this.pos] === "/") {
      if (start < this.pos) {
        this.emit(9 /* Whitespace */, start, this.pos);
      }
      if (this.pos < this.len) {
        if (this.src[this.pos] === ">") {
          this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
          this.pos++;
          this.state = this.checkRawtextMode();
        } else if (this.src[this.pos] === "/") {
          this.emit(3 /* Slash */, this.pos, this.pos + 1);
          this.pos++;
          if (this.pos < this.len && this.src[this.pos] === ">") {
            this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
            this.pos++;
            this.state = 0 /* Data */;
          } else {
            this.state = 3 /* BeforeAttrName */;
          }
        }
      } else {
        this.emit(32 /* SyntheticClose */, this.pos, this.pos);
        this.state = 0 /* Data */;
      }
      return;
    }
    const nameStart = this.pos;
    while (this.pos < this.len) {
      const ch2 = this.src[this.pos];
      if (ch2 === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        if (this.pos > nameStart) {
          this.emit(5 /* TagName */, nameStart, this.pos);
        }
        if (this.peekAhead(1) === "{") {
          if (this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
            this.returnState = 2 /* TagName */;
            this.continuedTagName = true;
            this.beginBladeCommentCapture(2 /* TagName */, this.currentTagStart);
            this.scanBladeCommentStart();
            this.scanBladeCommentContent();
            return;
          }
          this.returnState = 2 /* TagName */;
          this.continuedTagName = true;
          this.scanEcho();
          return;
        } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
          this.returnState = 2 /* TagName */;
          this.continuedTagName = true;
          this.scanRawEcho();
          return;
        }
        break;
      }
      const cc = ch2.charCodeAt(0);
      if (isAlnum(cc) || ch2 === "-" || ch2 === ":" || ch2 === "_" || ch2 === "@" || ch2 === "." || ch2 === "[" || ch2 === "]" || ch2 === "$") {
        this.pos++;
      } else {
        break;
      }
    }
    if (nameStart < this.pos) {
      const tagNamePart = this.src.slice(nameStart, this.pos);
      this.currentTagName += tagNamePart;
      this.emit(5 /* TagName */, nameStart, this.pos);
    }
    if (this.pos >= this.len) {
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      this.state = 0 /* Data */;
      return;
    }
    const ch = this.src[this.pos];
    if (ch === "<") {
      if (this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
        if (this.tryScanPhpTag()) {
          this.state = 2 /* TagName */;
          this.continuedTagName = true;
          return;
        }
      }
      if (this.tryScanTsxGenericType()) {
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      this.scanTagOpen();
    } else if (ch === ">") {
      this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = this.checkRawtextMode();
    } else if (ch === "/") {
      this.emit(3 /* Slash */, this.pos, this.pos + 1);
      this.pos++;
      this.skipWhitespace();
      if (this.pos < this.len && this.src[this.pos] === ">") {
        this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
        this.pos++;
        this.state = 0 /* Data */;
      } else {
        this.state = 3 /* BeforeAttrName */;
      }
    } else if (isSpace(ch.charCodeAt(0))) {
      this.state = 3 /* BeforeAttrName */;
    } else {
      this.state = 3 /* BeforeAttrName */;
    }
  }
  scanBeforeAttrName() {
    if (this.scanAttributePhpDirectiveContent()) return;
    const start = this.pos;
    while (this.pos < this.len && isSpace(this.src.charCodeAt(this.pos))) {
      this.pos++;
    }
    if (this.isClosingTag) {
      if (this.pos >= this.len) {
        this.emit(32 /* SyntheticClose */, start, start);
        this.pos = start;
        this.state = 0 /* Data */;
        return;
      }
      const ch2 = this.src[this.pos];
      if (ch2 !== ">" && ch2 !== "/") {
        this.emit(32 /* SyntheticClose */, start, start);
        this.pos = start;
        this.state = 0 /* Data */;
        return;
      }
    }
    if (start < this.pos) {
      this.emit(9 /* Whitespace */, start, this.pos);
    }
    if (this.pos >= this.len) {
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      this.state = 0 /* Data */;
      return;
    }
    const ch = this.src[this.pos];
    if (ch === "@" && !this.verbatim && !this.phpBlock && !this.phpTag) {
      let tempPos = this.pos + 1;
      const nameStart = tempPos;
      while (tempPos < this.len) {
        const b = this.src.charCodeAt(tempPos);
        if (isAlnum(b) || b === 95) {
          tempPos++;
        } else {
          break;
        }
      }
      if (tempPos > nameStart) {
        const nameLower = this.src.slice(nameStart, tempPos).toLowerCase();
        if (this.isAtAttributeCandidate(nameLower, tempPos)) {
        } else if (this._directives.acceptsAll()) {
          this.returnState = 3 /* BeforeAttrName */;
          this.scanDirective();
          return;
        } else if (this._directives.isDirectiveLower(nameLower)) {
          this.returnState = 3 /* BeforeAttrName */;
          this.scanDirective();
          return;
        }
      }
    }
    if (ch === "<" && this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
      if (this.tryScanPhpTag()) {
        this.state = 3 /* BeforeAttrName */;
        return;
      }
    }
    if (ch === "<" && this.pos + 3 < this.len && this.src[this.pos + 1] === "!" && this.src[this.pos + 2] === "-" && this.src[this.pos + 3] === "-") {
      this.beginHtmlCommentCapture(3 /* BeforeAttrName */, this.currentTagStart);
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      this.state = 0 /* Data */;
      return;
    }
    if (ch === "<") {
      if (this.tryScanTsxGenericType()) {
        return;
      }
      this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      this.emit(1 /* LessThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 2 /* TagName */;
      return;
    }
    if (ch === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
      if (this.tryScanJsxShorthandAttribute()) {
        return;
      }
    }
    if (ch === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
      if (this.peekAhead(1) === "{") {
        if (this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
          this.returnState = 3 /* BeforeAttrName */;
          this.beginBladeCommentCapture(3 /* BeforeAttrName */, this.currentTagStart);
          this.scanBladeCommentStart();
          this.scanBladeCommentContent();
          return;
        }
        this.returnState = 3 /* BeforeAttrName */;
        this.scanEcho();
        if (this.pos < this.len) {
          const nextCh = this.src[this.pos];
          if (nextCh !== " " && nextCh !== "	" && nextCh !== "\n" && nextCh !== "\r" && nextCh !== ">" && nextCh !== "/" && nextCh !== "=" && nextCh !== "<") {
            this.state = 4 /* AttrName */;
            return;
          }
        }
        return;
      } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
        this.returnState = 3 /* BeforeAttrName */;
        this.scanRawEcho();
        return;
      }
    }
    if (this.inXmlDeclaration && ch === "?" && this.pos + 1 < this.len && this.src[this.pos + 1] === ">") {
      this.emit(45 /* DeclEnd */, this.pos, this.pos + 2);
      this.pos += 2;
      this.inXmlDeclaration = false;
      this.state = 0 /* Data */;
      return;
    }
    if (ch === ">") {
      this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = this.checkRawtextMode();
    } else if (ch === "/") {
      this.emit(3 /* Slash */, this.pos, this.pos + 1);
      this.pos++;
      const wsStart = this.pos;
      while (this.pos < this.len && isSpace(this.src.charCodeAt(this.pos))) {
        this.pos++;
      }
      if (this.pos < this.len && this.src[this.pos] === ">") {
        this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
        this.pos++;
      } else if (this.pos >= this.len) {
        this.emit(32 /* SyntheticClose */, this.pos, this.pos);
      } else {
        this.emit(32 /* SyntheticClose */, wsStart, wsStart);
        this.pos = wsStart;
      }
      this.state = 0 /* Data */;
    } else {
      this.state = 4 /* AttrName */;
    }
  }
  scanAttrName() {
    if (this.scanAttributePhpDirectiveContent()) return;
    const start = this.pos;
    let tokenType = 6 /* AttributeName */;
    if (this.pos < this.len && this.src[this.pos] === ":") {
      if (this.pos + 1 < this.len && this.src[this.pos + 1] === ":") {
        tokenType = 33 /* EscapedAttribute */;
      } else if (this.pos + 1 < this.len && this.src[this.pos + 1] === "$") {
        tokenType = 35 /* ShorthandAttribute */;
      } else {
        tokenType = 34 /* BoundAttribute */;
      }
    }
    while (true) {
      if (this.pos >= this.len) break;
      const byte = this.src[this.pos];
      if (byte === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        if (this.pos > start) {
          this.emit(tokenType, start, this.pos);
        }
        const savedPos = this.pos;
        if (this.peekAhead(1) === "{") {
          if (this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
            const savedState2 = this.state;
            this.returnState = 0 /* Data */;
            this.beginBladeCommentCapture(4 /* AttrName */, this.currentTagStart);
            this.scanBladeCommentStart();
            this.scanBladeCommentContent();
            this.state = savedState2;
            this.scanAttrName();
            return;
          }
          const savedState = this.state;
          this.returnState = 0 /* Data */;
          this.scanEcho();
          this.state = savedState;
          this.scanAttrName();
          return;
        } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
          const savedState = this.state;
          this.returnState = 0 /* Data */;
          this.scanRawEcho();
          this.state = savedState;
          this.scanAttrName();
          return;
        }
        this.pos = savedPos;
        break;
      }
      if (byte === "<" && this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
        if (this.pos > start) {
          this.emit(tokenType, start, this.pos);
        }
        if (this.tryScanPhpTag()) {
          this.scanAttrName();
          return;
        }
        break;
      }
      if (byte === "@" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        let tempPos = this.pos + 1;
        const nameStart = tempPos;
        while (tempPos < this.len) {
          const b = this.src.charCodeAt(tempPos);
          if (isAlnum(b) || b === 95) tempPos++;
          else break;
        }
        let isKnownDirective = false;
        if (tempPos > nameStart) {
          const nameLower = this.src.slice(nameStart, tempPos).toLowerCase();
          if (this.isAtAttributeCandidate(nameLower, tempPos)) {
            isKnownDirective = false;
          } else if (this._directives.acceptsAll()) {
            isKnownDirective = true;
          } else {
            isKnownDirective = this._directives.isDirectiveLower(nameLower);
          }
        }
        if (isKnownDirective) {
          if (this.pos > start) {
            this.emit(tokenType, start, this.pos);
          }
          const savedState = this.state;
          this.returnState = 0 /* Data */;
          this.scanDirective();
          this.state = savedState;
          this.scanAttrName();
          return;
        }
        this.pos++;
        continue;
      }
      const cc = byte.charCodeAt(0);
      if (isAlnum(cc) || byte === "-" || byte === ":" || byte === "_" || byte === "$" || byte === "@" || byte === "." || byte === "[" || byte === "]" || byte === "(" || byte === ")" || byte === "*" || byte === "#") {
        this.pos++;
      } else {
        break;
      }
    }
    if (start < this.pos) {
      this.emit(tokenType, start, this.pos);
    }
    if (this.pos >= this.len) {
      this.state = 0 /* Data */;
      return;
    }
    const char = this.src[this.pos];
    if (char === "=") {
      this.emit(4 /* Equals */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 6 /* BeforeAttrValue */;
    } else if (this.inXmlDeclaration && char === "?" && this.pos + 1 < this.len && this.src[this.pos + 1] === ">") {
      this.emit(45 /* DeclEnd */, this.pos, this.pos + 2);
      this.pos += 2;
      this.inXmlDeclaration = false;
      this.state = 0 /* Data */;
    } else if (char === ">") {
      this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 0 /* Data */;
    } else if (char === "/") {
      this.emit(3 /* Slash */, this.pos, this.pos + 1);
      this.pos++;
      if (this.pos < this.len && this.src[this.pos] === ">") {
        this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
        this.pos++;
        this.state = 0 /* Data */;
      } else {
        this.state = 3 /* BeforeAttrName */;
      }
    } else if (isSpace(char.charCodeAt(0))) {
      this.state = 5 /* AfterAttrName */;
    } else if (char === "<") {
      this.state = 3 /* BeforeAttrName */;
    } else {
      this.emit(0 /* Text */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 3 /* BeforeAttrName */;
    }
  }
  scanAfterAttrName() {
    if (this.scanAttributePhpDirectiveContent()) return;
    this.skipAndEmitWhitespace();
    if (this.pos >= this.len) {
      this.state = 0 /* Data */;
      return;
    }
    const char = this.src[this.pos];
    if (char === "=") {
      this.emit(4 /* Equals */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 6 /* BeforeAttrValue */;
    } else if (this.inXmlDeclaration && char === "?" && this.pos + 1 < this.len && this.src[this.pos + 1] === ">") {
      this.emit(45 /* DeclEnd */, this.pos, this.pos + 2);
      this.pos += 2;
      this.inXmlDeclaration = false;
      this.state = 0 /* Data */;
    } else if (char === ">") {
      this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 0 /* Data */;
    } else if (char === "/") {
      this.emit(3 /* Slash */, this.pos, this.pos + 1);
      this.pos++;
      if (this.pos < this.len && this.src[this.pos] === ">") {
        this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
        this.pos++;
        this.state = 0 /* Data */;
      } else {
        this.state = 3 /* BeforeAttrName */;
      }
    } else {
      this.state = 3 /* BeforeAttrName */;
    }
  }
  scanBeforeAttrValue() {
    if (this.scanAttributePhpDirectiveContent()) return;
    this.skipAndEmitWhitespace();
    if (this.pos >= this.len) {
      this.state = 0 /* Data */;
      return;
    }
    const char = this.src[this.pos];
    if (char === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
      if (this.peekAhead(1) === "{") {
        this.returnState = 3 /* BeforeAttrName */;
        this.scanEcho();
        this.state = 3 /* BeforeAttrName */;
        return;
      } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
        this.returnState = 3 /* BeforeAttrName */;
        this.scanRawEcho();
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      if (this.scanJsxAttributeValue()) {
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      this.state = 8 /* AttrValueUnquoted */;
      return;
    }
    if (char === "(" && this.pos + 1 < this.len && this.src[this.pos + 1] === "{") {
      if (this.scanJsxAttributeValue()) {
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      this.state = 8 /* AttrValueUnquoted */;
      return;
    }
    if (char === '"' || char === "'") {
      this.state = 7 /* AttrValueQuoted */;
    } else if (this.inXmlDeclaration && char === "?" && this.pos + 1 < this.len && this.src[this.pos + 1] === ">") {
      this.emit(45 /* DeclEnd */, this.pos, this.pos + 2);
      this.pos += 2;
      this.inXmlDeclaration = false;
      this.state = 0 /* Data */;
    } else if (char === ">") {
      this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
      this.pos++;
      this.state = 0 /* Data */;
    } else {
      this.state = 8 /* AttrValueUnquoted */;
    }
  }
  scanAttrValueQuoted() {
    if (this.scanAttributePhpDirectiveContent()) return;
    const quote = this.src[this.pos];
    this.emit(8 /* Quote */, this.pos, this.pos + 1);
    this.pos++;
    let valueStart = this.pos;
    while (true) {
      if (this.pos >= this.len) {
        if (this.pos > valueStart) {
          this.emit(7 /* AttributeValue */, valueStart, this.pos);
        }
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      const quotePos = this.src.indexOf(quote, this.pos);
      const bracePos = this.src.indexOf("{", this.pos);
      const atPos = this.src.indexOf("@", this.pos);
      let nextPos = this.len;
      if (quotePos !== -1 && quotePos < nextPos) nextPos = quotePos;
      if (bracePos !== -1 && bracePos < nextPos) nextPos = bracePos;
      if (atPos !== -1 && atPos < nextPos) nextPos = atPos;
      if (nextPos === this.len) {
        this.pos = this.len;
        if (this.pos > valueStart) {
          this.emit(7 /* AttributeValue */, valueStart, this.pos);
        }
        this.state = 3 /* BeforeAttrName */;
        return;
      }
      this.pos = nextPos;
      const byte = this.src[this.pos];
      if (byte === quote) {
        let backslashCount = 0;
        let checkPos = this.pos - 1;
        while (checkPos >= valueStart && this.src[checkPos] === "\\") {
          backslashCount++;
          checkPos--;
        }
        if (backslashCount % 2 === 1) {
          this.pos++;
          continue;
        }
        if (this.pos > valueStart) {
          this.emit(7 /* AttributeValue */, valueStart, this.pos);
        }
        this.emit(8 /* Quote */, this.pos, this.pos + 1);
        this.pos++;
        this.state = 3 /* BeforeAttrName */;
        return;
      } else if (byte === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        const savedPos = this.pos;
        if (this.peekAhead(1) === "{") {
          if (this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
            if (savedPos > valueStart) {
              this.emit(7 /* AttributeValue */, valueStart, savedPos);
            }
            this.returnState = 7 /* AttrValueQuoted */;
            this.beginBladeCommentCapture(7 /* AttrValueQuoted */, null);
            this.scanBladeCommentStart();
            this.scanBladeCommentContent();
            valueStart = this.pos;
            continue;
          }
          if (savedPos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, savedPos);
          }
          this.returnState = 7 /* AttrValueQuoted */;
          this.scanEcho();
          valueStart = this.pos;
          continue;
        } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
          if (savedPos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, savedPos);
          }
          this.returnState = 7 /* AttrValueQuoted */;
          this.scanRawEcho();
          valueStart = this.pos;
          continue;
        }
        this.pos = savedPos + 1;
      } else if (byte === "@" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        const canStart = this.pos === valueStart || !isAlnum(this.src.charCodeAt(this.pos - 1));
        if (canStart) {
          const savedPos = this.pos;
          if (savedPos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, savedPos);
          }
          this.returnState = 7 /* AttrValueQuoted */;
          this.scanDirective();
          valueStart = this.pos;
          continue;
        }
        this.pos++;
      } else {
        this.pos++;
      }
    }
  }
  scanAttrValueUnquoted() {
    if (this.scanAttributePhpDirectiveContent()) return;
    let valueStart = this.pos;
    while (true) {
      if (this.pos >= this.len) break;
      const byte = this.src[this.pos];
      if (this.inXmlDeclaration && byte === "?" && this.pos + 1 < this.len && this.src[this.pos + 1] === ">") {
        break;
      }
      if (isSpace(byte.charCodeAt(0)) || byte === ">") break;
      if (byte === "<" && this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
        const savedPos = this.pos;
        if (savedPos > valueStart) {
          this.emit(7 /* AttributeValue */, valueStart, savedPos);
        }
        if (this.tryScanPhpTag()) {
          valueStart = this.pos;
          continue;
        }
        break;
      }
      if (byte === "{" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        if (this.peekAhead(1) === "{") {
          if (this.peekAhead(2) === "-" && this.peekAhead(3) === "-") {
            if (this.pos > valueStart) {
              this.emit(7 /* AttributeValue */, valueStart, this.pos);
            }
            this.returnState = 8 /* AttrValueUnquoted */;
            this.beginBladeCommentCapture(8 /* AttrValueUnquoted */, this.currentTagStart);
            this.scanBladeCommentStart();
            this.scanBladeCommentContent();
            valueStart = this.pos;
            continue;
          }
          if (this.pos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, this.pos);
          }
          this.returnState = 8 /* AttrValueUnquoted */;
          this.scanEcho();
          valueStart = this.pos;
          continue;
        } else if (this.peekAhead(1) === "!" && this.peekAhead(2) === "!") {
          if (this.pos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, this.pos);
          }
          this.returnState = 8 /* AttrValueUnquoted */;
          this.scanRawEcho();
          valueStart = this.pos;
          continue;
        }
        this.pos++;
        continue;
      }
      if (byte === "@" && !this.verbatim && !this.phpBlock && !this.phpTag) {
        const canStart = this.pos === valueStart || !isAlnum(this.src.charCodeAt(this.pos - 1));
        if (canStart) {
          if (this.pos > valueStart) {
            this.emit(7 /* AttributeValue */, valueStart, this.pos);
          }
          this.returnState = 8 /* AttrValueUnquoted */;
          this.scanDirective();
          valueStart = this.pos;
          continue;
        }
        this.pos++;
        continue;
      }
      this.pos++;
    }
    if (valueStart < this.pos) {
      this.emit(7 /* AttributeValue */, valueStart, this.pos);
    }
    this.state = 3 /* BeforeAttrName */;
  }
  scanDirective() {
    const start = this.pos;
    this.pos++;
    const nameStart = this.pos;
    let pos = nameStart;
    while (pos < this.len) {
      const cc = this.src.charCodeAt(pos);
      if (isAlnum(cc) || cc === 95) {
        pos++;
      } else {
        break;
      }
    }
    if (pos === nameStart) {
      this.emit(0 /* Text */, start, start + 1);
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      return;
    }
    const nameLower = this.src.slice(nameStart, pos).toLowerCase();
    const isRawBlockDirective = this.verbatimStartDirectives.has(nameLower) || this.verbatimEndDirectives.has(nameLower);
    if (!isRawBlockDirective && !this._directives.isDirectiveLower(nameLower)) {
      this.pos = pos;
      this.emit(0 /* Text */, start, pos);
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      return;
    }
    let argPos = pos;
    while (argPos < this.len && isSpace(this.src.charCodeAt(argPos))) {
      argPos++;
    }
    const hasArgs = argPos < this.len && this.src[argPos] === "(";
    this.pos = pos;
    const inTagAttributeState = this.state === 2 /* TagName */ || this.state === 3 /* BeforeAttrName */ || this.state === 4 /* AttrName */ || this.state === 5 /* AfterAttrName */ || this.state === 6 /* BeforeAttrValue */ || this.state === 7 /* AttrValueQuoted */ || this.state === 8 /* AttrValueUnquoted */;
    if (nameLower === "php" && !hasArgs && !inTagAttributeState) {
      this.emit(29 /* PhpBlockStart */, start, pos);
      this.phpBlock = true;
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      return;
    }
    if (nameLower === "php" && !hasArgs && inTagAttributeState) {
      this.emit(25 /* Directive */, start, pos);
      this.attrPhpDirectiveDepth++;
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      return;
    }
    if (nameLower === "endphp" && !inTagAttributeState) {
      this.emit(30 /* PhpBlockEnd */, start, pos);
      if (this.phpBlock) {
        this.phpBlock = false;
      }
      this.state = this.returnState;
      this.returnState = 0 /* Data */;
      return;
    }
    if (nameLower === "endphp" && inTagAttributeState && this.attrPhpDirectiveDepth > 0) {
      this.attrPhpDirectiveDepth--;
    }
    if (this.verbatimStartDirectives.has(nameLower)) {
      this.emit(27 /* VerbatimStart */, start, pos);
      this.verbatimReturnState = this.state;
      this.verbatim = true;
      this.state = 0 /* Data */;
      this.returnState = 0 /* Data */;
      return;
    }
    if (this.verbatimEndDirectives.has(nameLower)) {
      this.emit(28 /* VerbatimEnd */, start, pos);
      if (this.verbatimReturnState !== null) {
        this.state = this.verbatimReturnState;
        this.verbatimReturnState = null;
      } else {
        this.state = 0 /* Data */;
      }
      this.verbatim = false;
      this.returnState = 0 /* Data */;
      return;
    }
    this.emit(25 /* Directive */, start, pos);
    if (hasArgs && argPos > pos) {
      this.emit(9 /* Whitespace */, pos, argPos);
      this.pos = argPos;
    }
    if (hasArgs) {
      this.scanDirectiveArgs();
    }
    this.state = this.returnState;
    this.returnState = 0 /* Data */;
  }
  scanDirectiveArgs() {
    const start = this.pos;
    if (this.pos >= this.len || this.src[this.pos] !== "(") return;
    this.pos++;
    let depth = 1;
    let firstRecoveryLineBreak = -1;
    while (this.pos < this.len && depth > 0) {
      const byte = this.src[this.pos];
      if (byte === "\n" && depth === 1 && firstRecoveryLineBreak < 0) {
        firstRecoveryLineBreak = this.pos + 1;
      }
      if (byte === "'" || byte === '"') {
        this.pos++;
        this.skipQuotedStringPrim(byte);
      } else if (byte === "`") {
        this.pos++;
        this.skipBacktickStringPrim();
      } else if (byte === "<" && this.peekAhead(1) === "<" && this.peekAhead(2) === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
      } else if (byte === "/" && this.peekAhead(1) === "*") {
        this.pos += 2;
        this.skipBlockCommentPrim();
      } else if (byte === "/" && this.peekAhead(1) === "/") {
        this.pos += 2;
        this.skipLineCommentWithWarnings();
      } else if (byte === "#") {
        this.pos++;
        this.skipLineCommentWithWarnings();
      } else if (byte === "(") {
        depth++;
        this.pos++;
      } else if (byte === ")") {
        depth--;
        this.pos++;
      } else {
        this.pos++;
      }
    }
    if (depth > 0) {
      this.logError(0 /* UnexpectedEof */, this.pos);
      const fallbackEnd = firstRecoveryLineBreak > 0 ? Math.min(firstRecoveryLineBreak, this.len) : this.pos;
      this.pos = fallbackEnd;
      this.emit(26 /* DirectiveArgs */, start, fallbackEnd);
      return;
    }
    this.emit(26 /* DirectiveArgs */, start, this.pos);
  }
  isVerbatimTerminatorAt(pos) {
    const name = this.readDirectiveNameAt(pos);
    if (name === null) {
      return false;
    }
    return this.verbatimEndDirectives.has(name);
  }
  readDirectiveNameAt(pos) {
    if (pos >= this.len || this.src[pos] !== "@") return null;
    const nameStart = pos + 1;
    let end = nameStart;
    while (end < this.len) {
      const cc = this.src.charCodeAt(end);
      if (isAlnum(cc) || cc === 95) {
        end++;
      } else {
        break;
      }
    }
    if (end === nameStart) return null;
    if (end < this.len) {
      const next = this.src.charCodeAt(end);
      if (isAlnum(next) || next === 95) {
        return null;
      }
    }
    return this.src.slice(nameStart, end).toLowerCase();
  }
  isEndphpAt(pos) {
    if (pos + 7 > this.len || this.src[pos] !== "@") return false;
    if (!this.hasAsciiWordAt(pos + 1, "endphp")) return false;
    if (pos + 7 < this.len) {
      const next = this.src.charCodeAt(pos + 7);
      if (isAlnum(next) || next === 95) return false;
    }
    return true;
  }
  scanEcho() {
    if (this.peek() === "{" && this.peekAhead(1) === "{" && this.peekAhead(2) === "{") {
      this.scanTripleEcho();
      return;
    }
    const start = this.pos;
    this.emit(18 /* EchoStart */, start, start + 2);
    this.pos += 2;
    const contentStart = this.pos;
    while (this.pos < this.len) {
      const byte = this.src[this.pos];
      if (byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim("'");
      } else if (byte === '"') {
        this.pos++;
        this.skipQuotedStringPrim('"');
      } else if (byte === "`") {
        this.pos++;
        this.skipBacktickStringPrim();
      } else if (byte === "<" && this.peekAhead(1) === "<" && this.peekAhead(2) === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
      } else if (byte === "/" && this.peekAhead(1) === "*") {
        this.pos += 2;
        this.skipBlockCommentPrim();
      } else if (byte === "/" && this.peekAhead(1) === "/") {
        this.pos += 2;
        this.skipLineCommentWithWarnings();
      } else if (byte === "#") {
        this.pos++;
        this.skipLineCommentWithWarnings();
      } else if (byte === "{" || byte === "@" || byte === "<") {
        if (this.detectConstruct()) {
          this.logError(1 /* ConstructCollision */, this.pos);
          if (contentStart < this.pos) {
            this.emit(20 /* EchoContent */, contentStart, this.pos);
          }
          this.state = this.returnState;
          this.returnState = 0 /* Data */;
          return;
        }
        this.pos++;
      } else if (byte === "}" && this.peekAhead(1) === "}") {
        if (contentStart < this.pos) {
          this.emit(20 /* EchoContent */, contentStart, this.pos);
        }
        this.emit(19 /* EchoEnd */, this.pos, this.pos + 2);
        this.pos += 2;
        this.state = this.returnState;
        this.returnState = 0 /* Data */;
        return;
      } else {
        this.pos++;
      }
    }
    this.logError(0 /* UnexpectedEof */, this.len);
    if (contentStart < this.pos) {
      this.emit(20 /* EchoContent */, contentStart, this.pos);
    }
    this.pos = this.len;
    this.state = this.returnState;
    this.returnState = 0 /* Data */;
  }
  scanRawEcho() {
    const start = this.pos;
    this.emit(21 /* RawEchoStart */, start, start + 3);
    this.pos += 3;
    const contentStart = this.pos;
    while (this.pos < this.len) {
      const byte = this.src[this.pos];
      if (byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim("'");
      } else if (byte === '"') {
        this.pos++;
        this.skipQuotedStringPrim('"');
      } else if (byte === "`") {
        this.pos++;
        this.skipBacktickStringPrim();
      } else if (byte === "<" && this.peekAhead(1) === "<" && this.peekAhead(2) === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
      } else if (byte === "/" && this.peekAhead(1) === "*") {
        this.pos += 2;
        this.skipBlockCommentPrim();
      } else if (byte === "/" && this.peekAhead(1) === "/") {
        this.pos += 2;
        this.skipLineCommentWithWarnings();
      } else if (byte === "#") {
        this.pos++;
        this.skipLineCommentWithWarnings();
      } else if (byte === "{" || byte === "@" || byte === "<") {
        if (this.detectConstruct()) {
          this.logError(1 /* ConstructCollision */, this.pos);
          if (contentStart < this.pos) {
            this.emit(20 /* EchoContent */, contentStart, this.pos);
          }
          this.state = this.returnState;
          this.returnState = 0 /* Data */;
          return;
        }
        this.pos++;
      } else if (byte === "!" && this.peekAhead(1) === "!" && this.peekAhead(2) === "}") {
        if (contentStart < this.pos) {
          this.emit(20 /* EchoContent */, contentStart, this.pos);
        }
        this.emit(22 /* RawEchoEnd */, this.pos, this.pos + 3);
        this.pos += 3;
        this.state = this.returnState;
        this.returnState = 0 /* Data */;
        return;
      } else {
        this.pos++;
      }
    }
    this.logError(0 /* UnexpectedEof */, this.len);
    if (contentStart < this.pos) {
      this.emit(20 /* EchoContent */, contentStart, this.pos);
    }
    this.pos = this.len;
    this.state = this.returnState;
    this.returnState = 0 /* Data */;
  }
  scanTripleEcho() {
    const start = this.pos;
    this.emit(23 /* TripleEchoStart */, start, start + 3);
    this.pos += 3;
    const contentStart = this.pos;
    while (this.pos < this.len) {
      const byte = this.src[this.pos];
      if (byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim("'");
      } else if (byte === '"') {
        this.pos++;
        this.skipQuotedStringPrim('"');
      } else if (byte === "`") {
        this.pos++;
        this.skipBacktickStringPrim();
      } else if (byte === "<" && this.peekAhead(1) === "<" && this.peekAhead(2) === "<") {
        this.pos += 3;
        this.skipHeredocPrim();
      } else if (byte === "/" && this.peekAhead(1) === "*") {
        this.pos += 2;
        this.skipBlockCommentPrim();
      } else if (byte === "/" && this.peekAhead(1) === "/") {
        this.pos += 2;
        this.skipLineCommentWithWarnings();
      } else if (byte === "#") {
        this.pos++;
        this.skipLineCommentWithWarnings();
      } else if (byte === "{" || byte === "@" || byte === "<") {
        if (this.detectConstruct()) {
          this.logError(1 /* ConstructCollision */, this.pos);
          if (contentStart < this.pos) {
            this.emit(20 /* EchoContent */, contentStart, this.pos);
          }
          this.state = this.returnState;
          this.returnState = 0 /* Data */;
          return;
        }
        this.pos++;
      } else if (byte === "}" && this.peekAhead(1) === "}" && this.peekAhead(2) === "}") {
        if (contentStart < this.pos) {
          this.emit(20 /* EchoContent */, contentStart, this.pos);
        }
        this.emit(24 /* TripleEchoEnd */, this.pos, this.pos + 3);
        this.pos += 3;
        this.state = this.returnState;
        this.returnState = 0 /* Data */;
        return;
      } else {
        this.pos++;
      }
    }
    this.logError(0 /* UnexpectedEof */, this.len);
    if (contentStart < this.pos) {
      this.emit(20 /* EchoContent */, contentStart, this.pos);
    }
    this.pos = this.len;
    this.state = this.returnState;
    this.returnState = 0 /* Data */;
  }
  tryScanJsxShorthandAttribute() {
    if (this.pos >= this.len || this.src[this.pos] !== "{") return false;
    if (this.pos + 1 < this.len) {
      const next = this.src[this.pos + 1];
      if (next === "{" || next === "!") return false;
    }
    const start = this.pos;
    const originalPos = this.pos;
    this.pos++;
    let fastScanPos = this.pos;
    while (fastScanPos < this.len) {
      const byte = this.src[fastScanPos];
      if (byte === "}") {
        this.pos = fastScanPos + 1;
        this.emit(49 /* JsxShorthandAttribute */, start, this.pos);
        this.state = 3 /* BeforeAttrName */;
        return true;
      }
      if (byte === "{" || byte === "'" || byte === '"' || byte === "`" || byte === "/") {
        break;
      }
      if (byte === "\n" || byte === "\r" || byte === "@") {
        this.pos = originalPos;
        return false;
      }
      fastScanPos++;
    }
    return this.scanBalancedJsLike(
      start,
      49 /* JsxShorthandAttribute */,
      originalPos,
      1,
      // braceDepth
      0,
      // parenDepth
      false,
      // trackParens
      true,
      // allowComments
      true,
      // abortOnDirective
      true
      // abortOnNewline
    );
  }
  scanJsxAttributeValue() {
    const start = this.pos;
    const originalPos = this.pos;
    const startsWithParen = this.src[this.pos] === "(";
    this.pos++;
    const braceDepth = startsWithParen ? 0 : 1;
    const parenDepth = startsWithParen ? 1 : 0;
    if (braceDepth === 1 && parenDepth === 0) {
      let fastScanPos = this.pos;
      while (fastScanPos < this.len) {
        const byte = this.src[fastScanPos];
        if (byte === "}") {
          this.pos = fastScanPos + 1;
          this.emit(48 /* JsxAttributeValue */, start, this.pos);
          return true;
        }
        if (byte === "{" || byte === "(" || byte === "'" || byte === '"' || byte === "`" || byte === "/") {
          break;
        }
        if (byte === "\n" || byte === "\r" || byte === "@") {
          this.pos = originalPos;
          return false;
        }
        fastScanPos++;
      }
    }
    return this.scanBalancedJsLike(
      start,
      48 /* JsxAttributeValue */,
      originalPos,
      braceDepth,
      parenDepth,
      true,
      // trackParens
      true,
      // allowComments
      true,
      // abortOnDirective
      false
      // abortOnNewline
    );
  }
  tryScanTsxGenericType() {
    if (this.pos >= this.len || this.src[this.pos] !== "<") return false;
    if (this.pos + 1 < this.len && this.src[this.pos + 1] === "?") {
      return false;
    }
    const start = this.pos;
    const originalPos = this.pos;
    this.pos++;
    if (this.pos < this.len) {
      const nextByte = this.src[this.pos];
      const isPascalCaseTag = this.currentTagName !== "" && this.currentTagName[0] >= "A" && this.currentTagName[0] <= "Z";
      let looksLikeGeneric = nextByte === "{" || nextByte >= "A" && nextByte <= "Z" || nextByte === "_";
      if (isPascalCaseTag) {
        looksLikeGeneric = looksLikeGeneric || nextByte >= "a" && nextByte <= "z" || nextByte >= "0" && nextByte <= "9" || nextByte === "[" || nextByte === '"' || nextByte === "'" || nextByte === "(" || nextByte === " " || nextByte === "	";
      }
      if (!looksLikeGeneric) {
        this.pos = originalPos;
        return false;
      }
    }
    let depth = 1;
    while (true) {
      if (this.pos >= this.len) {
        this.pos = originalPos;
        return false;
      }
      const nextPos = this.nextInterestingPosForTsxGeneric(this.pos);
      if (nextPos >= this.len) {
        this.pos = originalPos;
        return false;
      }
      this.pos = nextPos;
      const byte = this.src[this.pos];
      if (byte === "<") {
        depth++;
        this.pos++;
        continue;
      }
      if (byte === ">") {
        if (this.pos > 0 && this.src[this.pos - 1] === "=") {
          this.pos++;
          continue;
        }
        depth--;
        this.pos++;
        if (depth === 0) {
          this.emit(50 /* TsxGenericType */, start, this.pos);
          return true;
        }
        continue;
      }
      if (byte === "\n" || byte === "\r" || byte === "@") {
        this.pos = originalPos;
        return false;
      }
      if (byte === '"' || byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim(byte);
        continue;
      }
      if (byte === "`") {
        this.pos++;
        this.skipTemplateLiteralPrim();
        continue;
      }
      this.pos++;
    }
  }
  /**
   * Balanced scanner for JSX-ish content.
   */
  scanBalancedJsLike(start, tokenType, originalPos, braceDepth, parenDepth, trackParens, allowComments, abortOnDirective, abortOnNewline) {
    while (true) {
      if (this.pos >= this.len) {
        this.emit(tokenType, start, this.pos);
        return true;
      }
      const nextPos = this.nextInterestingPosForBalancedJsLike(this.pos);
      if (nextPos >= this.len) {
        this.pos = this.len;
        this.emit(tokenType, start, this.pos);
        return true;
      }
      this.pos = nextPos;
      const byte = this.src[this.pos];
      if (byte === "{") {
        braceDepth++;
        this.pos++;
        continue;
      }
      if (byte === "}") {
        braceDepth--;
        this.pos++;
        if (braceDepth === 0 && (!trackParens || parenDepth === 0)) {
          this.emit(tokenType, start, this.pos);
          return true;
        }
        continue;
      }
      if (trackParens && byte === "(") {
        parenDepth++;
        this.pos++;
        continue;
      }
      if (trackParens && byte === ")") {
        parenDepth--;
        this.pos++;
        if (braceDepth === 0 && parenDepth === 0) {
          this.emit(tokenType, start, this.pos);
          return true;
        }
        continue;
      }
      if (byte === '"' || byte === "'") {
        this.pos++;
        this.skipQuotedStringPrim(byte);
        continue;
      }
      if (byte === "`") {
        this.pos++;
        this.skipTemplateLiteralPrim();
        continue;
      }
      if (byte === "/") {
        if (!allowComments) {
          this.pos++;
          continue;
        }
        if (this.pos + 1 < this.len) {
          const next = this.src[this.pos + 1];
          if (next === "/") {
            this.pos += 2;
            while (this.pos < this.len) {
              const ch = this.src[this.pos];
              if (ch === "\n" || ch === "\r") {
                this.pos++;
                if (ch === "\r" && this.pos < this.len && this.src[this.pos] === "\n") {
                  this.pos++;
                }
                break;
              }
              this.pos++;
            }
            continue;
          }
          if (next === "*") {
            this.pos += 2;
            this.skipBlockCommentPrim();
            continue;
          }
        }
        this.pos++;
        continue;
      }
      if (abortOnDirective && byte === "@") {
        this.pos = originalPos;
        return false;
      }
      if (abortOnNewline && (byte === "\n" || byte === "\r")) {
        this.pos = originalPos;
        return false;
      }
      this.pos++;
    }
  }
  scanRawtext() {
    const start = this.pos;
    const tagName = this.rawtextTagName;
    const tagNameLen = tagName.length;
    while (this.pos < this.len) {
      const nextIgnoreRangeStart = this.nextIgnoreRangeStart();
      if (nextIgnoreRangeStart !== null && this.pos === nextIgnoreRangeStart) {
        if (start < this.pos) {
          this.emit(0 /* Text */, start, this.pos);
        }
        return;
      }
      const byte = this.src[this.pos];
      if (byte === "{" && !this.verbatim && !this.phpBlock) {
        const next1 = this.peekAhead(1);
        if (next1 === "{") {
          const next2 = this.peekAhead(2);
          const next3 = this.peekAhead(3);
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          this.returnState = 9 /* RawText */;
          if (next2 === "-" && next3 === "-") {
            this.beginBladeCommentCapture(9 /* RawText */, null);
            this.scanBladeCommentStart();
            return;
          }
          this.scanEcho();
          return;
        } else if (next1 === "!" && this.pos + 2 < this.len && this.src[this.pos + 2] === "!") {
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          this.returnState = 9 /* RawText */;
          this.scanRawEcho();
          return;
        }
        this.pos++;
        continue;
      }
      if (byte === "@" && !this.verbatim && !this.phpBlock) {
        const prevChar = this.pos > 0 ? this.src[this.pos - 1] : null;
        const canStart = this.pos === 0 || prevChar !== null && !isAlnum(prevChar.charCodeAt(0)) && prevChar !== "@";
        if (canStart) {
          const nextPos = this.pos + 1;
          let isEscaped = false;
          if (nextPos < this.len) {
            const nextByte = this.src[nextPos];
            if (nextByte === "@") {
              isEscaped = true;
            } else if (nextByte === "{" && nextPos + 1 < this.len) {
              const afterBrace = this.src[nextPos + 1];
              if (afterBrace === "{" || afterBrace === "!") {
                isEscaped = true;
              }
            }
          }
          if (start < this.pos) {
            this.emit(0 /* Text */, start, this.pos);
          }
          if (isEscaped) {
            this.emit(17 /* AtSign */, this.pos, this.pos + 1);
            this.pos++;
            return;
          }
          this.returnState = 9 /* RawText */;
          this.scanDirective();
          return;
        }
        this.pos++;
        continue;
      }
      if (byte === "<") {
        if (this.pos + 2 + tagNameLen <= this.len && this.src[this.pos + 1] === "/") {
          const potentialTagName = this.src.slice(this.pos + 2, this.pos + 2 + tagNameLen);
          if (potentialTagName.toLowerCase() === tagName) {
            const afterTagPos = this.pos + 2 + tagNameLen;
            if (afterTagPos < this.len) {
              const afterTagChar = this.src[afterTagPos];
              if (afterTagChar === ">" || isSpace(afterTagChar.charCodeAt(0))) {
                if (start < this.pos) {
                  this.emit(0 /* Text */, start, this.pos);
                }
                this.rawtextTagName = "";
                this.emit(1 /* LessThan */, this.pos, this.pos + 1);
                this.pos++;
                this.emit(3 /* Slash */, this.pos, this.pos + 1);
                this.pos++;
                this.emit(5 /* TagName */, this.pos, this.pos + tagNameLen);
                this.currentTagName = potentialTagName;
                this.isClosingTag = true;
                this.pos += tagNameLen;
                let peekPos = this.pos;
                while (peekPos < this.len && isSpace(this.src.charCodeAt(peekPos))) {
                  peekPos++;
                }
                if (peekPos < this.len && this.src[peekPos] === ">") {
                  if (this.pos < peekPos) {
                    this.emit(9 /* Whitespace */, this.pos, peekPos);
                    this.pos = peekPos;
                  }
                  this.emit(2 /* GreaterThan */, this.pos, this.pos + 1);
                  this.pos++;
                } else {
                  this.emit(32 /* SyntheticClose */, this.pos, this.pos);
                }
                this.state = 0 /* Data */;
                return;
              }
            } else if (afterTagPos === this.len) {
              if (start < this.pos) {
                this.emit(0 /* Text */, start, this.pos);
              }
              this.rawtextTagName = "";
              this.emit(1 /* LessThan */, this.pos, this.pos + 1);
              this.pos++;
              this.emit(3 /* Slash */, this.pos, this.pos + 1);
              this.pos++;
              this.emit(5 /* TagName */, this.pos, this.pos + tagNameLen);
              this.pos += tagNameLen;
              this.state = 0 /* Data */;
              return;
            }
          }
        }
        this.pos++;
        continue;
      }
      this.pos++;
    }
    if (start < this.pos) {
      this.emit(0 /* Text */, start, this.pos);
    }
    this.rawtextTagName = "";
  }
};
function isAlpha(ch) {
  return ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122;
}
function isAlnum(ch) {
  return isAlpha(ch) || ch >= 48 && ch <= 57;
}
function isSpace(ch) {
  return ch === 32 || ch === 9 || ch === 10 || ch === 13;
}
function normalizeDirectiveName(name) {
  return name.trim().toLowerCase().replace(/^@/, "");
}
function tokenize(source, directives, rawBlockConfig) {
  return new Lexer(source, directives, rawBlockConfig).tokenize();
}

// src/ignore-markers.ts
function getIgnoreCommentKindFromPayload(payload) {
  switch (payload.trim().toLowerCase()) {
    case "format-ignore":
    case "prettier-ignore":
      return "ignore";
    case "format-ignore-start":
    case "prettier-ignore-start":
      return "ignore-start";
    case "format-ignore-end":
    case "prettier-ignore-end":
      return "ignore-end";
    default:
      return null;
  }
}
function getIgnoreCommentKindFromCommentText(text, wrapper) {
  const payload = wrapper === "blade" ? text.match(/^\{\{--\s*([\s\S]*?)\s*--\}\}$/s)?.[1] ?? null : text.match(/^<!--\s*([\s\S]*?)\s*-->$/s)?.[1] ?? null;
  if (payload === null) {
    return null;
  }
  return getIgnoreCommentKindFromPayload(payload);
}

// src/lexer/ignore-ranges.ts
function isTagIgnoreState(state) {
  switch (state) {
    case 2 /* TagName */:
    case 3 /* BeforeAttrName */:
    case 4 /* AttrName */:
    case 5 /* AfterAttrName */:
    case 6 /* BeforeAttrValue */:
    case 8 /* AttrValueUnquoted */:
      return true;
    default:
      return false;
  }
}
function isIgnoreMarkerAllowed(wrapper, originState) {
  if (originState === 7 /* AttrValueQuoted */) {
    return false;
  }
  if (wrapper === "html") {
    return originState !== 9 /* RawText */;
  }
  return true;
}
var IgnoreRangeCollectorImpl = class {
  constructor(source) {
    this.source = source;
  }
  ranges = [];
  depth = 0;
  outerStart = -1;
  handleBladeComment(start, end, originState, tagStart, resume) {
    this.handleComment("blade", start, end, originState, tagStart, resume);
  }
  handleHtmlComment(start, end, originState, tagStart, resume) {
    this.handleComment("html", start, end, originState, tagStart, resume);
  }
  finish(resume, eof) {
    if (this.depth > 0 && this.outerStart >= 0) {
      this.ranges.push({
        start: this.outerStart,
        end: eof,
        resume
      });
      this.depth = 0;
      this.outerStart = -1;
    }
    return this.ranges;
  }
  handleComment(wrapper, start, end, originState, tagStart, resume) {
    if (!isIgnoreMarkerAllowed(wrapper, originState)) {
      return;
    }
    const kind = getIgnoreCommentKindFromCommentText(this.source.slice(start, end), wrapper);
    if (!kind) {
      return;
    }
    if (kind === "ignore-start") {
      if (this.depth === 0) {
        this.outerStart = isTagIgnoreState(originState) && tagStart !== null && tagStart >= 0 ? tagStart : start;
      }
      this.depth++;
      return;
    }
    if (this.depth === 0) {
      return;
    }
    this.depth--;
    if (this.depth !== 0) {
      return;
    }
    this.ranges.push({
      start: this.outerStart >= 0 ? this.outerStart : start,
      end,
      resume
    });
    this.outerStart = -1;
  }
};
function collectIgnoreRanges(source, directives, rawBlockConfig) {
  const collector = new IgnoreRangeCollectorImpl(source);
  new Lexer(source, directives, {
    ...rawBlockConfig,
    ignoreRangeCollector: collector
  }).tokenize();
  return collector.finish(
    {
      state: 0 /* Data */,
      returnState: 0 /* Data */,
      rawtextTagName: "",
      currentTagName: "",
      isClosingTag: false,
      continuedTagName: false,
      inXmlDeclaration: false,
      verbatim: false,
      verbatimReturnState: null,
      phpBlock: false,
      phpTag: false,
      attrPhpDirectiveDepth: 0
    },
    source.length
  );
}

// src/tree/types.ts
var NODE_KIND_LABELS = {
  [0 /* Root */]: "Root",
  [1 /* Element */]: "Element",
  [2 /* Text */]: "Text",
  [3 /* Fragment */]: "Fragment",
  [4 /* Echo */]: "Echo",
  [5 /* RawEcho */]: "RawEcho",
  [6 /* TripleEcho */]: "TripleEcho",
  [7 /* Directive */]: "Directive",
  [8 /* DirectiveBlock */]: "DirectiveBlock",
  [9 /* Verbatim */]: "Verbatim",
  [10 /* PhpBlock */]: "PhpBlock",
  [11 /* PhpTag */]: "PhpTag",
  [12 /* Comment */]: "Comment",
  [13 /* BogusComment */]: "BogusComment",
  [14 /* ConditionalComment */]: "ConditionalComment",
  [15 /* BladeComment */]: "BladeComment",
  [16 /* Doctype */]: "Doctype",
  [17 /* Cdata */]: "Cdata",
  [18 /* Decl */]: "Decl",
  [19 /* Attribute */]: "Attribute",
  [20 /* JsxAttribute */]: "JsxAttribute",
  [21 /* UnpairedClosingTag */]: "UnpairedClosingTag",
  [22 /* NonOutput */]: "NonOutput",
  [23 /* ElementName */]: "ElementName",
  [24 /* ClosingElementName */]: "ClosingElementName",
  [25 /* AttributeWhitespace */]: "AttributeWhitespace",
  [26 /* AttributeName */]: "AttributeName",
  [27 /* AttributeValue */]: "AttributeValue",
  [28 /* ProcessingInstruction */]: "ProcessingInstruction",
  [29 /* IgnoreRange */]: "IgnoreRange"
};
function nodeKindLabel(kind) {
  return NODE_KIND_LABELS[kind] ?? `Unknown(${kind})`;
}
var NONE = -1;
function createFlatNode(kind, parent, tokenStart, tokenCount = 0, genericOffset = 0, data = 0) {
  return {
    kind,
    parent,
    firstChild: NONE,
    lastChild: NONE,
    nextSibling: NONE,
    tokenStart,
    tokenCount,
    genericOffset,
    data
  };
}

// src/tree/void-elements.ts
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
  "area",
  "base",
  "br",
  "col",
  "embed",
  "hr",
  "img",
  "input",
  "link",
  "meta",
  "param",
  "source",
  "track",
  "wbr"
]);

// src/tree/optional-tags.ts
var RULES = {
  li: {
    autoCloseWhenSibling: ["li"],
    autoCloseAtParentEnd: ["ul", "ol", "menu"]
  },
  dt: {
    autoCloseWhenSibling: ["dt", "dd"],
    autoCloseAtParentEnd: ["dl"]
  },
  dd: {
    autoCloseWhenSibling: ["dt", "dd"],
    autoCloseAtParentEnd: ["dl"]
  },
  p: {
    autoCloseWhenSibling: [
      "address",
      "article",
      "aside",
      "blockquote",
      "div",
      "dl",
      "fieldset",
      "footer",
      "form",
      "h1",
      "h2",
      "h3",
      "h4",
      "h5",
      "h6",
      "header",
      "hr",
      "main",
      "nav",
      "ol",
      "p",
      "pre",
      "section",
      "table",
      "ul"
    ]
  },
  option: {
    autoCloseWhenSibling: ["option", "optgroup"],
    autoCloseAtParentEnd: ["select", "datalist", "optgroup"]
  },
  optgroup: {
    autoCloseWhenSibling: ["optgroup"],
    autoCloseAtParentEnd: ["select"]
  },
  rt: {
    autoCloseWhenSibling: ["rt", "rp"],
    autoCloseAtParentEnd: ["ruby", "rtc"]
  },
  rp: {
    autoCloseWhenSibling: ["rt", "rp"],
    autoCloseAtParentEnd: ["ruby", "rtc"]
  },
  rb: {
    autoCloseWhenSibling: ["rb", "rt", "rp", "rtc"],
    autoCloseAtParentEnd: ["ruby"]
  },
  caption: {
    autoCloseWhenSibling: ["colgroup", "thead", "tbody", "tfoot", "tr"],
    autoCloseAtParentEnd: ["table"]
  },
  colgroup: {
    autoCloseWhenSibling: ["colgroup", "thead", "tbody", "tfoot", "tr"],
    autoCloseAtParentEnd: ["table"]
  },
  thead: {
    autoCloseWhenSibling: ["tbody", "tfoot"],
    autoCloseAtParentEnd: ["table"]
  },
  tbody: {
    autoCloseWhenSibling: ["tbody", "tfoot"],
    autoCloseAtParentEnd: ["table"]
  },
  tfoot: {
    autoCloseAtParentEnd: ["table"]
  },
  tr: {
    autoCloseWhenSibling: ["tr"],
    autoCloseAtParentEnd: ["table", "thead", "tbody", "tfoot"]
  },
  td: {
    autoCloseWhenSibling: ["td", "th"],
    autoCloseAtParentEnd: ["tr"]
  },
  th: {
    autoCloseWhenSibling: ["td", "th"],
    autoCloseAtParentEnd: ["tr"]
  }
};
function canOmitClosingTag(element) {
  return element in RULES;
}
function getClosingConditions(element) {
  return RULES[element] ?? null;
}
function shouldAutoCloseOnSibling(element, sibling) {
  const rules = RULES[element];
  if (!rules?.autoCloseWhenSibling) return false;
  return rules.autoCloseWhenSibling.includes(sibling);
}
function shouldAutoCloseAtParentEnd(element, parent) {
  const rules = RULES[element];
  if (!rules?.autoCloseAtParentEnd || parent === null) return false;
  return rules.autoCloseAtParentEnd.includes(parent);
}
function isInValidParentContext(element, parent) {
  const conditions = RULES[element];
  if (!conditions) return false;
  const hasParentRules = conditions.autoCloseAtParentEnd !== void 0;
  const hasSiblingRules = conditions.autoCloseWhenSibling !== void 0;
  if (parent === element || parent === null) {
    if (hasParentRules || parent === element) return false;
  }
  if (hasParentRules) {
    return conditions.autoCloseAtParentEnd.includes(parent);
  }
  if (hasSiblingRules) {
    return true;
  }
  return false;
}
function shouldAutoCloseElement(element, nextElement, parent, atParentEnd) {
  if (!canOmitClosingTag(element)) return false;
  if (nextElement !== null && shouldAutoCloseOnSibling(element, nextElement)) {
    return true;
  }
  if (atParentEnd && shouldAutoCloseAtParentEnd(element, parent)) {
    return true;
  }
  return false;
}

// src/tree/construct-scanner.ts
var CONSTRUCT_PAIRS = {
  [18 /* EchoStart */]: 19 /* EchoEnd */,
  [21 /* RawEchoStart */]: 22 /* RawEchoEnd */,
  [23 /* TripleEchoStart */]: 24 /* TripleEchoEnd */,
  [39 /* PhpTagStart */]: 40 /* PhpTagEnd */,
  [29 /* PhpBlockStart */]: 30 /* PhpBlockEnd */
};
var CONSTRUCT_KINDS = {
  [18 /* EchoStart */]: 4 /* Echo */,
  [21 /* RawEchoStart */]: 5 /* RawEcho */,
  [23 /* TripleEchoStart */]: 6 /* TripleEcho */,
  [39 /* PhpTagStart */]: 11 /* PhpTag */,
  [29 /* PhpBlockStart */]: 10 /* PhpBlock */
};
function isConstructStart(tokenType) {
  return tokenType in CONSTRUCT_PAIRS;
}
function getEndType(startType) {
  return CONSTRUCT_PAIRS[startType] ?? null;
}
function getNodeKind(startType) {
  return CONSTRUCT_KINDS[startType] ?? null;
}
function scanConstruct(tokens, pos, end) {
  if (pos >= end) return [pos, 0];
  const endType = getEndType(tokens[pos].type);
  if (endType === null) return [pos + 1, 1];
  let count = 1;
  pos++;
  while (pos < end && tokens[pos].type !== endType) {
    count++;
    pos++;
  }
  if (pos < end && tokens[pos].type === endType) {
    count++;
    pos++;
  }
  return [pos, count];
}
function countConstructTokens(tokens, pos, end) {
  return scanConstruct(tokens, pos, end)[1];
}
function advancePast(tokens, pos, end) {
  if (pos >= end) return pos;
  if (isConstructStart(tokens[pos].type)) {
    return scanConstruct(tokens, pos, end)[0];
  }
  return pos + 1;
}

// src/tree/directives.ts
function createDirective(overrides) {
  return {
    args: 0 /* Optional */,
    role: 0 /* None */,
    isCondition: false,
    terminators: [],
    conditionLikeBranches: [],
    hasConditionLikeBranches: false,
    terminator: null,
    isSwitch: false,
    switchParent: null,
    isSwitchBranch: false,
    isSwitchTerminator: false,
    isConditionalPair: false,
    pairingStrategy: null,
    isConditionalClose: false,
    ...overrides
  };
}
var Directives3 = class _Directives {
  static defaultTemplate = null;
  directives = /* @__PURE__ */ new Map();
  conditions = /* @__PURE__ */ new Set();
  finalTerminators = /* @__PURE__ */ new Set();
  seenDirectives = /* @__PURE__ */ new Set();
  advisoryPairs = /* @__PURE__ */ new Set();
  advisoryConditions = /* @__PURE__ */ new Set();
  conditionBranchesCache = null;
  conditionTerminatorsCache = null;
  switchBranchesCache = /* @__PURE__ */ new Map();
  shared = false;
  static withDefaults(extraDirectives = []) {
    if (_Directives.defaultTemplate === null) {
      const template = new _Directives();
      for (const json of BUNDLED_DIRECTIVES) {
        template.loadJson(json);
      }
      _Directives.defaultTemplate = template;
    }
    const directives = _Directives.defaultTemplate.forkShared();
    if (extraDirectives.length > 0) {
      directives.loadJson([...extraDirectives]);
    }
    return directives;
  }
  isDirective(name) {
    return this.directives.has(name.toLowerCase());
  }
  isCondition(name) {
    return this.conditions.has(name.toLowerCase());
  }
  isPaired(name) {
    const d = this.directives.get(name.toLowerCase());
    if (!d) return false;
    return d.role === 1 /* Opening */ && d.terminators.length > 0 && d.terminator !== null;
  }
  isSwitch(name) {
    return this.getDirective(name)?.isSwitch ?? false;
  }
  isSwitchBranch(name) {
    return this.getDirective(name)?.isSwitchBranch ?? false;
  }
  isSwitchTerminator(name) {
    return this.getDirective(name)?.isSwitchTerminator ?? false;
  }
  isConditionalPair(name) {
    return this.getDirective(name)?.isConditionalPair ?? false;
  }
  isConditionalClose(name) {
    return this.getDirective(name)?.isConditionalClose ?? false;
  }
  isFinalTerminator(name) {
    return this.finalTerminators.has(name.toLowerCase());
  }
  getDirective(name) {
    return this.directives.get(name.toLowerCase()) ?? null;
  }
  getTerminator(name) {
    const lower = name.toLowerCase();
    if (this.isFinalTerminator(lower)) return lower;
    const d = this.directives.get(lower);
    if (d?.terminator) return d.terminator;
    return "end" + lower;
  }
  getTerminators(name) {
    const d = this.directives.get(name.toLowerCase());
    if (!d) return [];
    return d.terminators;
  }
  getBranches(name) {
    const d = this.directives.get(name.toLowerCase());
    if (!d || !d.isCondition) return [];
    if (this.conditionBranchesCache === null) {
      this.conditionBranchesCache = this.computeAllConditionBranches();
    }
    return this.conditionBranchesCache;
  }
  getSwitchBranches(switchName) {
    const lower = switchName.toLowerCase();
    const cached = this.switchBranchesCache.get(lower);
    if (cached) return cached;
    const branches = [];
    for (const d of this.directives.values()) {
      if (d.switchParent === lower) {
        branches.push(d.name);
      }
    }
    this.switchBranchesCache.set(lower, branches);
    return branches;
  }
  getConditionTerminators() {
    if (this.conditionTerminatorsCache === null) {
      const terminators = [];
      for (const d of this.directives.values()) {
        if (d.isCondition && d.role === 2 /* Closing */) {
          terminators.push(d.name.toLowerCase());
        }
      }
      this.conditionTerminatorsCache = terminators;
    }
    return this.conditionTerminatorsCache;
  }
  getPairingStrategy(name) {
    return this.getDirective(name)?.pairingStrategy ?? null;
  }
  /** @internal */
  hasSeenDirective(name) {
    return this.seenDirectives.has(name.toLowerCase());
  }
  /** @internal */
  hasAdvisoryPair(name) {
    return this.advisoryPairs.has(name.toLowerCase());
  }
  /** @internal */
  hasAdvisoryCondition(name) {
    return this.advisoryConditions.has(name.toLowerCase());
  }
  registerDirective(name) {
    const lower = name.toLowerCase();
    if (this.directives.has(lower)) return;
    this.ensureMutable();
    this.invalidateCaches();
    this.directives.set(lower, createDirective({ name: lower }));
  }
  /**
   * Discover custom paired directives from a token stream.
   */
  train(tokens, source) {
    this.ensureMutable();
    const found = /* @__PURE__ */ new Map();
    for (const token of tokens) {
      if (token.type !== 25 /* Directive */) continue;
      let name = source.slice(token.start, token.end).toLowerCase();
      if (name.startsWith("@")) name = name.slice(1);
      this.seenDirectives.add(name);
      found.set(name, true);
    }
    for (const directiveName of found.keys()) {
      if (this.directives.has(directiveName)) continue;
      const endName = "end" + directiveName;
      const elseName = "else" + directiveName;
      if (found.has(endName)) {
        this.advisoryPairs.add(directiveName);
      }
      if (found.has(elseName)) {
        this.advisoryConditions.add(directiveName);
      }
    }
  }
  loadJson(data) {
    this.ensureMutable();
    for (const meta of data) {
      if (!meta || typeof meta !== "object") continue;
      const m = meta;
      const argReq = this.parseArgumentRequirement(m.args);
      const namesRaw = typeof m.name === "string" ? m.name : "";
      const names = namesRaw.split(",").map((s) => s.trim()).filter(Boolean);
      const structure = typeof m.structure === "object" && m.structure !== null ? m.structure : null;
      let role = 0 /* None */;
      let isCondition = false;
      let terminators = [];
      let conditionLikeBranches = [];
      let hasConditionLikeBranches = false;
      let terminator = null;
      let isSwitch = false;
      let switchParent = null;
      let isSwitchBranch = false;
      let isSwitchTerminator = false;
      let isConditionalPair = false;
      let pairingStrategy = null;
      let isConditionalClose = false;
      if (structure) {
        const roleVal = typeof structure.role === "string" ? structure.role : "";
        role = this.parseStructureRole(roleVal);
        isCondition = Boolean(structure.condition);
        const termsVal = typeof structure.terminators === "string" ? structure.terminators : "";
        const branchesVal = typeof structure.branches === "string" ? structure.branches : "";
        terminators = this.parseTerminators(termsVal);
        conditionLikeBranches = this.parseTerminators(branchesVal);
        hasConditionLikeBranches = conditionLikeBranches.length > 0;
        if (terminators.length > 0) {
          terminator = terminators[terminators.length - 1];
        }
        if (structure.type === "switch") isSwitch = true;
        if (typeof structure.parent === "string") {
          switchParent = structure.parent.toLowerCase();
        }
        if (roleVal === "branch" && switchParent === "switch") {
          isSwitchBranch = true;
        }
        if (roleVal === "branch_terminator" && switchParent === "switch") {
          isSwitchTerminator = true;
        }
        if (roleVal === "conditional_pair") {
          isConditionalPair = true;
          if (typeof structure.pairing_strategy === "string") {
            pairingStrategy = structure.pairing_strategy;
          }
        }
        if (roleVal === "conditional_close") {
          isConditionalClose = true;
        }
      }
      for (const name of names) {
        const directive = createDirective({
          name,
          args: argReq,
          role,
          isCondition,
          terminators,
          conditionLikeBranches,
          hasConditionLikeBranches,
          terminator,
          isSwitch,
          switchParent,
          isSwitchBranch,
          isSwitchTerminator,
          isConditionalPair,
          pairingStrategy,
          isConditionalClose
        });
        this.addDirective(directive);
      }
    }
  }
  addDirective(directive) {
    this.ensureMutable();
    this.invalidateCaches();
    const name = directive.name.toLowerCase();
    if (directive.role === 2 /* Closing */ && directive.terminators.length === 0) {
      this.finalTerminators.add(name);
    }
    this.directives.set(name, directive);
    if (directive.isCondition) {
      this.conditions.add(name);
    }
  }
  addPairedDirective(openName, closeName) {
    this.ensureMutable();
    this.invalidateCaches();
    const open = createDirective({
      name: openName,
      role: 1 /* Opening */,
      terminators: [closeName],
      terminator: closeName
    });
    const close = createDirective({
      name: closeName,
      args: 2 /* NotAllowed */,
      role: 2 /* Closing */
    });
    this.directives.set(openName, open);
    this.directives.set(closeName, close);
  }
  addConditionDirective(condition) {
    this.ensureMutable();
    this.invalidateCaches();
    condition = condition.toLowerCase();
    const elseCond = "else" + condition;
    const endCond = "end" + condition;
    this.conditions.add(condition);
    this.directives.set(
      condition,
      createDirective({
        name: condition,
        args: 1 /* Required */,
        role: 1 /* Opening */,
        isCondition: true,
        terminators: [elseCond, endCond]
      })
    );
    this.directives.set(
      elseCond,
      createDirective({
        name: elseCond,
        args: 1 /* Required */,
        role: 4 /* Mixed */,
        isCondition: true,
        terminators: [elseCond, endCond]
      })
    );
    this.directives.set(
      endCond,
      createDirective({
        name: endCond,
        args: 2 /* NotAllowed */,
        role: 2 /* Closing */,
        isCondition: true
      })
    );
  }
  computeAllConditionBranches() {
    const branches = ["else"];
    for (const d of this.directives.values()) {
      if (d.isCondition && d.role === 1 /* Opening */) {
        branches.push(...d.terminators);
      }
    }
    return branches;
  }
  parseTerminators(value) {
    return value.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
  }
  parseStructureRole(role) {
    switch (role) {
      case "open":
      case "conditional_pair":
        return 1 /* Opening */;
      case "close":
      case "conditional_close":
        return 2 /* Closing */;
      case "mixed":
        return 4 /* Mixed */;
      default:
        return 0 /* None */;
    }
  }
  parseArgumentRequirement(args) {
    if (args === null || args === void 0) return 0 /* Optional */;
    if (args === true) return 1 /* Required */;
    if (args === false) return 2 /* NotAllowed */;
    if (typeof args === "object") {
      const a = args;
      if (!a.allowed) return 2 /* NotAllowed */;
      if (a.required) return 1 /* Required */;
    }
    return 0 /* Optional */;
  }
  invalidateCaches() {
    this.conditionBranchesCache = null;
    this.conditionTerminatorsCache = null;
    this.switchBranchesCache.clear();
  }
  forkShared() {
    const copy = new _Directives();
    copy.directives = this.directives;
    copy.conditions = this.conditions;
    copy.finalTerminators = this.finalTerminators;
    copy.seenDirectives = this.seenDirectives;
    copy.advisoryPairs = this.advisoryPairs;
    copy.advisoryConditions = this.advisoryConditions;
    copy.conditionBranchesCache = this.conditionBranchesCache;
    copy.conditionTerminatorsCache = this.conditionTerminatorsCache;
    copy.switchBranchesCache = this.switchBranchesCache;
    copy.shared = true;
    return copy;
  }
  ensureMutable() {
    if (!this.shared) return;
    this.directives = new Map(this.directives);
    this.conditions = new Set(this.conditions);
    this.finalTerminators = new Set(this.finalTerminators);
    this.seenDirectives = new Set(this.seenDirectives);
    this.advisoryPairs = new Set(this.advisoryPairs);
    this.advisoryConditions = new Set(this.advisoryConditions);
    this.conditionBranchesCache = this.conditionBranchesCache ? [...this.conditionBranchesCache] : null;
    this.conditionTerminatorsCache = this.conditionTerminatorsCache ? [...this.conditionTerminatorsCache] : null;
    this.switchBranchesCache = new Map(
      [...this.switchBranchesCache.entries()].map(([key, value]) => [key, [...value]])
    );
    this.shared = false;
  }
};
var BUNDLED_DIRECTIVES = [
  // conditions.json
  [
    {
      name: "if",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseif,endif" }
    },
    { name: "elseif", args: true, structure: { role: "mixed", terminators: "elseif,endif" } },
    { name: "else", args: false, structure: { role: "mixed", terminators: "endif" } },
    { name: "endif", args: false, structure: { role: "close", condition: true } },
    {
      name: "unless",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseif,endunless" }
    },
    { name: "endunless", args: false, structure: { role: "close", condition: true } },
    {
      name: "isset",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseif,endIsset" }
    },
    { name: "endIsset", args: false, structure: { role: "close", condition: true } },
    {
      name: "once",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseif,endOnce" }
    },
    { name: "endOnce", args: false, structure: { role: "close", condition: true } },
    {
      name: "pushIf",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsePushIf,elseif,endPushIf" }
    },
    {
      name: "elsePushIf",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elsePushIf,elseif,endPushIf" }
    },
    { name: "endPushIf", args: false, structure: { role: "close", condition: true } },
    {
      name: "hasstack",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseif,endif" }
    }
    // Note: @empty/@endempty as standalone condition is intentionally NOT bundled here.
    // @empty is primarily used as a branch marker inside @forelse (via forelse.branches).
    // Standalone @empty($var)...@endempty can be discovered via training.
  ],
  // auth.json
  [
    {
      name: "auth",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseauth,endauth" }
    },
    {
      name: "elseauth",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elseauth,endauth" }
    },
    { name: "endauth", args: false, structure: { role: "close", condition: true } }
  ],
  // guest.json
  [
    {
      name: "guest",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseguest,endguest" }
    },
    {
      name: "elseguest",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elseguest,endguest" }
    },
    { name: "endguest", args: false, structure: { role: "close", condition: true } }
  ],
  // authorizations.json
  [
    {
      name: "can",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsecan,endcan" }
    },
    {
      name: "elsecan",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elsecan,endcan" }
    },
    { name: "endcan", args: false, structure: { role: "close", condition: true } },
    {
      name: "cannot",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsecannot,endcannot" }
    },
    {
      name: "elsecannot",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elsecannot,endcannot" }
    },
    { name: "endcannot", args: false, structure: { role: "close", condition: true } },
    {
      name: "canany",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsecanany,endcanany" }
    },
    {
      name: "elsecanany",
      args: true,
      structure: { role: "mixed", condition: true, terminators: "elsecanany,endcanany" }
    },
    { name: "endcanany", args: false, structure: { role: "close", condition: true } }
  ],
  // env.json
  [
    {
      name: "env",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseenv,endenv" }
    },
    { name: "elseenv", args: true, structure: { role: "mixed", condition: true } },
    { name: "endenv", args: false, structure: { role: "close", condition: true } },
    {
      name: "production",
      args: false,
      structure: { role: "open", condition: true, terminators: "elseproduction,endproduction" }
    },
    { name: "elseproduction", args: false, structure: { role: "mixed", condition: true } },
    { name: "endproduction", args: false, structure: { role: "close", condition: true } }
  ],
  // for.json
  [
    { name: "for", args: true, structure: { role: "open", terminators: "endfor" } },
    { name: "endfor", args: false, structure: { role: "close" } }
  ],
  // foreach.json
  [
    { name: "foreach", args: true, structure: { role: "open", terminators: "endforeach" } },
    { name: "endforeach", args: false, structure: { role: "close" } }
  ],
  // forelse.json
  [
    {
      name: "forelse",
      args: true,
      structure: { role: "open", terminators: "endforelse", branches: "empty" }
    },
    { name: "endforelse", args: false, structure: { role: "close" } }
  ],
  // while.json
  [
    { name: "while", args: true, structure: { role: "open", terminators: "endwhile" } },
    { name: "endwhile", args: false, structure: { role: "close" } }
  ],
  // switch.json
  [
    { name: "switch", args: true, structure: { role: "open", type: "switch" } },
    { name: "case", args: true, structure: { role: "branch", parent: "switch" } },
    { name: "default", args: false, structure: { role: "branch", parent: "switch" } },
    {
      name: "break",
      args: false,
      structure: { role: "branch_terminator", parent: "switch", optional: true }
    },
    { name: "endSwitch", args: false, structure: { role: "close" } }
  ],
  // error.json
  [
    {
      name: "error",
      args: true,
      structure: { role: "open", terminators: "enderror", branches: "else" }
    },
    { name: "enderror", args: false, structure: { role: "close" } }
  ],
  // components.json
  [
    { name: "props,aware", args: true },
    {
      name: "component",
      args: true,
      structure: { role: "open", terminators: "endComponent,endComponentClass" }
    },
    {
      name: "endComponent,endComponentClass,endSlot,endComponentFirst",
      args: false,
      structure: { role: "close" }
    },
    { name: "slot", args: true, structure: { role: "open", terminators: "endSlot" } },
    {
      name: "componentFirst",
      args: true,
      structure: { role: "open", terminators: "endComponentFirst" }
    }
  ],
  // layouts.json
  [
    { name: "extends,extendsFirst,parent,yield", args: true },
    {
      name: "section",
      args: true,
      structure: {
        role: "conditional_pair",
        terminators: "show,append,overwrite,stop,endsection",
        pairing_strategy: "section_style"
      }
    },
    {
      name: "show,append,overwrite,stop,endsection",
      args: false,
      structure: { role: "conditional_close" }
    },
    {
      name: "hasSection,sectionMissing",
      args: true,
      structure: {
        role: "open",
        condition: true,
        terminators: "elseif,else,endif,endhasSection,endsectionMissing"
      }
    },
    {
      name: "endhasSection,endsectionMissing",
      args: false,
      structure: { role: "close", condition: true }
    }
  ],
  // stacks.json
  [
    { name: "stack", args: true },
    { name: "push", args: true, structure: { role: "open", terminators: "endpush,endpushOnce" } },
    {
      name: "endpush,endpushOnce,endprepend,endprependOnce",
      args: false,
      structure: { role: "close" }
    },
    {
      name: "pushOnce",
      args: true,
      structure: { role: "open", terminators: "endpush,endpushOnce" }
    },
    {
      name: "prepend",
      args: true,
      structure: { role: "open", terminators: "endprepend,endprependOnce" }
    },
    {
      name: "prependOnce",
      args: true,
      structure: { role: "open", terminators: "endprepend,endprependOnce" }
    }
  ],
  // fragments.json
  [
    { name: "fragment", args: true, structure: { role: "open", terminators: "endfragment" } },
    { name: "endfragment", args: false, structure: { role: "close" } }
  ],
  // sessions.json
  [
    { name: "session", args: true, structure: { role: "open", terminators: "endsession" } },
    { name: "endsession", args: false, structure: { role: "close" } }
  ],
  // contexts.json
  [
    { name: "context", args: true, structure: { role: "open", terminators: "endcontext" } },
    { name: "endcontext", args: false, structure: { role: "close" } }
  ],
  // livewire.json
  [
    { name: "persist", args: true, structure: { role: "open", terminators: "endpersist" } },
    { name: "endpersist", args: false, structure: { role: "close" } },
    { name: "teleport", args: true, structure: { role: "open", terminators: "endteleport" } },
    { name: "endteleport", args: false, structure: { role: "close" } },
    { name: "livewire", args: true },
    { name: "livewireStyles,livewireScripts", args: false },
    { name: "entangle", args: true },
    { name: "this" },
    { name: "volt" }
  ],
  // spatie-permission.json
  [
    {
      name: "role",
      args: true,
      structure: { role: "open", condition: true, terminators: "elserole,endrole" }
    },
    { name: "endrole", args: false, structure: { role: "close", condition: true } },
    {
      name: "hasrole",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsehasrole,endhasrole" }
    },
    { name: "endhasrole", args: false, structure: { role: "close", condition: true } },
    {
      name: "hasanyrole",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsehasanyrole,endhasanyrole" }
    },
    { name: "endhasanyrole", args: false, structure: { role: "close", condition: true } },
    {
      name: "hasallroles",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsehasallroles,endhasallroles" }
    },
    { name: "endhasallroles", args: false, structure: { role: "close", condition: true } },
    {
      name: "unlessrole",
      args: true,
      structure: { role: "open", condition: true, terminators: "elseunlessrole,endunlessrole" }
    },
    { name: "endunlessrole", args: false, structure: { role: "close", condition: true } }
  ],
  // pennant.json (Feature Flags)
  [
    {
      name: "feature",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsefeature,endfeature" }
    },
    { name: "endfeature", args: false, structure: { role: "close", condition: true } },
    {
      name: "featureany",
      args: true,
      structure: { role: "open", condition: true, terminators: "elsefeatureany,endfeatureany" }
    },
    { name: "endfeatureany", args: false, structure: { role: "close", condition: true } }
  ],
  // translations.json
  [
    {
      name: "lang",
      structure: {
        role: "conditional_pair",
        terminators: "endlang",
        pairing_strategy: "lang_style"
      }
    },
    { name: "choice", args: true },
    { name: "endlang", args: false, structure: { role: "conditional_close" } }
  ],
  // verbatim.json
  [
    { name: "verbatim", args: false, structure: { role: "open", terminators: "endverbatim" } },
    { name: "endverbatim", args: false, structure: { role: "close" } }
  ],
  // includes.json
  [
    { name: "each", args: true },
    { name: "include", args: true },
    { name: "includeIf", args: true },
    { name: "includeWhen", args: true },
    { name: "includeUnless", args: true },
    { name: "includeFirst", args: true },
    { name: "includeIsolated", args: true }
  ],
  // basic.json
  [
    { name: "csrf", args: false },
    { name: "method", args: true },
    { name: "inject", args: true },
    { name: "dd", args: true },
    { name: "dump", args: true },
    { name: "js", args: true },
    { name: "json", args: true },
    { name: "vite", args: true },
    { name: "viteReactRefresh", args: false },
    { name: "bool", args: true },
    { name: "class", args: true },
    { name: "style", args: true },
    { name: "selected", args: true },
    { name: "checked", args: true },
    { name: "disabled", args: true },
    { name: "required", args: true },
    { name: "readonly", args: true },
    { name: "old", args: true },
    { name: "use" },
    { name: "unset", args: true },
    { name: "inertia", args: true },
    { name: "inertiaHead" },
    { name: "filamentStyles,filamentScripts", args: false },
    { name: "svg", args: true },
    { name: "paddleJS", args: false },
    { name: "continue" },
    { name: "php", args: false, structure: { role: "open", terminators: "endphp" } },
    { name: "endphp", args: false, structure: { role: "close" } }
  ]
];

// src/tree/directive-helper.ts
function extractDirectiveName(token, source) {
  let text = source.slice(token.start, token.end);
  if (text.startsWith("@")) text = text.slice(1);
  return text.toLowerCase();
}
function checkDirectiveArgsFast(tokens, startIdx, endIdx) {
  let consumed = 0;
  let checkIdx = startIdx;
  if (checkIdx < endIdx && tokens[checkIdx].type === 9 /* Whitespace */) {
    if (checkIdx + 1 < endIdx && tokens[checkIdx + 1].type === 26 /* DirectiveArgs */) {
      consumed++;
      checkIdx++;
    }
  }
  if (checkIdx < endIdx && tokens[checkIdx].type === 26 /* DirectiveArgs */) {
    consumed++;
    return { hasArgs: true, argsTokenIndex: checkIdx, consumed };
  }
  return { hasArgs: false, argsTokenIndex: -1, consumed };
}

// src/tree/directive-token-index.ts
var DirectiveTokenIndex = class {
  byName = /* @__PURE__ */ new Map();
  allPositions = [];
  allNames = [];
  nameSetCache = /* @__PURE__ */ new Map();
  constructor(tokens, source) {
    for (let i = 0; i < tokens.length; i++) {
      if (tokens[i].type !== 25 /* Directive */) continue;
      const name = this.extractName(tokens[i], source);
      this.allPositions.push(i);
      this.allNames.push(name);
      let positions = this.byName.get(name);
      if (!positions) {
        positions = [];
        this.byName.set(name, positions);
      }
      positions.push(i);
    }
  }
  getPositionsAfter(name, minIdx) {
    name = name.toLowerCase();
    const positions = this.byName.get(name);
    if (!positions) return [];
    const firstIdx = this.binarySearchGte(positions, minIdx);
    if (firstIdx === null) return [];
    return positions.slice(firstIdx);
  }
  existsAfter(name, minIdx) {
    name = name.toLowerCase();
    const positions = this.byName.get(name);
    if (!positions || positions.length === 0) return false;
    if (positions[positions.length - 1] < minIdx) return false;
    return this.binarySearchGte(positions, minIdx) !== null;
  }
  existsBetween(name, minIdx, maxIdxExclusive) {
    name = name.toLowerCase();
    const positions = this.byName.get(name);
    if (!positions || positions.length === 0) return false;
    if (positions[positions.length - 1] < minIdx) return false;
    const firstIdx = this.binarySearchGte(positions, minIdx);
    if (firstIdx === null) return false;
    return positions[firstIdx] < maxIdxExclusive;
  }
  findMatchingTerminator(directiveName, startIdx, terminators, maxIdxExclusive = null, initialNesting = 0) {
    return this.findMatchingTerminatorForOpeners(
      [directiveName],
      startIdx,
      terminators,
      maxIdxExclusive,
      initialNesting
    );
  }
  findMatchingTerminatorForOpeners(openerNames, startIdx, terminators, maxIdxExclusive = null, initialNesting = 0) {
    const firstIdx = this.binarySearchGte(this.allPositions, startIdx);
    if (firstIdx === null) return null;
    const openerSet = this.getNameSet(openerNames);
    const terminatorSet = this.getNameSet(terminators);
    let nesting = initialNesting;
    for (let i = firstIdx; i < this.allPositions.length; i++) {
      if (maxIdxExclusive !== null && this.allPositions[i] >= maxIdxExclusive) {
        return null;
      }
      const name = this.allNames[i];
      if (openerSet.has(name)) {
        nesting++;
        continue;
      }
      if (!terminatorSet.has(name)) continue;
      if (nesting === 0) return this.allPositions[i];
      nesting--;
    }
    return null;
  }
  hasTerminator(directiveName, startIdx, terminators, maxIdxExclusive = null) {
    return this.findMatchingTerminator(directiveName, startIdx, terminators, maxIdxExclusive) !== null;
  }
  findMatchingBoundary(directiveName, startIdx, terminatorNames, branchNames = [], maxIdxExclusive = null, initialNesting = 0) {
    return this.findMatchingBoundaryForOpeners(
      [directiveName],
      startIdx,
      terminatorNames,
      branchNames,
      maxIdxExclusive,
      initialNesting
    );
  }
  findMatchingBoundaryForOpeners(openerNames, startIdx, terminatorNames, branchNames = [], maxIdxExclusive = null, initialNesting = 0) {
    const firstIdx = this.binarySearchGte(this.allPositions, startIdx);
    if (firstIdx === null) return null;
    const openerSet = this.getNameSet(openerNames);
    const terminatorSet = this.getNameSet(terminatorNames);
    const branchSet = this.getNameSet(branchNames);
    let nesting = initialNesting;
    for (let i = firstIdx; i < this.allPositions.length; i++) {
      if (maxIdxExclusive !== null && this.allPositions[i] >= maxIdxExclusive) {
        return null;
      }
      const name = this.allNames[i];
      if (openerSet.has(name)) {
        nesting++;
        continue;
      }
      if (branchSet.has(name)) {
        if (nesting === 0) {
          return this.allPositions[i];
        }
        continue;
      }
      if (!terminatorSet.has(name)) continue;
      if (nesting === 0) {
        return this.allPositions[i];
      }
      nesting--;
    }
    return null;
  }
  analyzeUnknownDirective(directiveName, startIdx, terminatorNames, branchNames = [], maxIdxExclusive = null) {
    return this.analyzeUnknownDirectiveFamily(
      [directiveName],
      startIdx,
      terminatorNames,
      branchNames,
      maxIdxExclusive
    );
  }
  analyzeUnknownDirectiveFamily(openerNames, startIdx, terminatorNames, branchNames = [], maxIdxExclusive = null) {
    const openerSet = this.getNameSet(openerNames);
    const terminatorSet = this.getNameSet(terminatorNames);
    const branchSet = this.getNameSet(branchNames);
    const firstIdx = this.binarySearchGte(this.allPositions, startIdx);
    if (firstIdx === null) {
      return { terminatorIdx: null, terminatorName: null, branchIdx: null };
    }
    let nesting = 0;
    let branchIdx = null;
    for (let i = firstIdx; i < this.allPositions.length; i++) {
      if (maxIdxExclusive !== null && this.allPositions[i] >= maxIdxExclusive) {
        return { terminatorIdx: null, terminatorName: null, branchIdx: null };
      }
      const name = this.allNames[i];
      if (openerSet.has(name)) {
        nesting++;
        continue;
      }
      if (terminatorSet.has(name)) {
        if (nesting === 0) {
          return {
            terminatorIdx: this.allPositions[i],
            terminatorName: name,
            branchIdx
          };
        }
        nesting--;
        continue;
      }
      if (branchSet.has(name) && nesting === 0 && branchIdx === null) {
        branchIdx = this.allPositions[i];
      }
    }
    return { terminatorIdx: null, terminatorName: null, branchIdx: null };
  }
  extractName(token, source) {
    let text = source.slice(token.start, token.end);
    if (text.startsWith("@")) text = text.slice(1);
    return text.toLowerCase();
  }
  getNameSet(names) {
    const key = names.join("|").toLowerCase();
    const cached = this.nameSetCache.get(key);
    if (cached) return cached;
    const set = /* @__PURE__ */ new Set();
    for (const name of names) {
      set.add(name.toLowerCase());
    }
    this.nameSetCache.set(key, set);
    return set;
  }
  binarySearchGte(arr, target) {
    let lo = 0;
    let hi = arr.length - 1;
    let result = null;
    while (lo <= hi) {
      const mid = lo + hi >>> 1;
      if (arr[mid] >= target) {
        result = mid;
        hi = mid - 1;
      } else {
        lo = mid + 1;
      }
    }
    return result;
  }
};

// src/tree/argument-scanner.ts
function isWhitespace(ch) {
  return ch === " " || ch === "	" || ch === "\n" || ch === "\r";
}
function skipWhitespace(str, pos) {
  while (pos < str.length && isWhitespace(str[pos])) pos++;
  return pos;
}
function skipQuotedString2(str, pos, quote) {
  while (pos < str.length) {
    if (str[pos] === "\\") {
      pos += 2;
      continue;
    }
    if (str[pos] === quote) {
      pos++;
      return pos;
    }
    pos++;
  }
  return pos;
}
function isHeredocStart(str, pos) {
  return pos + 2 < str.length && str[pos] === "<" && str[pos + 1] === "<" && str[pos + 2] === "<";
}
function skipHeredoc2(str, pos) {
  let identStart = pos;
  while (identStart < str.length && isWhitespace(str[identStart])) identStart++;
  const isNowdoc = identStart < str.length && str[identStart] === "'";
  if (isNowdoc) identStart++;
  let identEnd = identStart;
  while (identEnd < str.length && /[a-zA-Z0-9_]/.test(str[identEnd])) identEnd++;
  const ident = str.slice(identStart, identEnd);
  if (ident.length === 0) return pos;
  pos = identEnd;
  if (isNowdoc && pos < str.length && str[pos] === "'") pos++;
  while (pos < str.length && str[pos] !== "\n") pos++;
  if (pos < str.length) pos++;
  while (pos < str.length) {
    const lineStart = pos;
    let checkPos = lineStart;
    while (checkPos < str.length && (str[checkPos] === " " || str[checkPos] === "	")) checkPos++;
    if (str.startsWith(ident, checkPos)) {
      const afterIdent = checkPos + ident.length;
      if (afterIdent >= str.length || str[afterIdent] === ";" || str[afterIdent] === "\n") {
        return afterIdent < str.length ? afterIdent + 1 : afterIdent;
      }
    }
    while (pos < str.length && str[pos] !== "\n") pos++;
    if (pos < str.length) pos++;
  }
  return pos;
}
function countArguments(args) {
  const len = args.length;
  if (len === 0) return 0;
  let pos = skipWhitespace(args, 0);
  if (pos >= len) return 0;
  let count = 1;
  let depth = 0;
  while (pos < len) {
    const ch = args[pos];
    if (ch === '"' || ch === "'") {
      pos = skipQuotedString2(args, pos + 1, ch);
      continue;
    }
    if (isHeredocStart(args, pos)) {
      pos = skipHeredoc2(args, pos + 3);
      continue;
    }
    if (ch === "(" || ch === "[" || ch === "{") {
      depth++;
      pos++;
      continue;
    }
    if (ch === ")" || ch === "]" || ch === "}") {
      depth--;
      pos++;
      continue;
    }
    if (ch === "," && depth === 0) {
      count++;
    }
    pos++;
  }
  return count;
}
function startsWithArray(args) {
  const pos = skipWhitespace(args, 0);
  return pos < args.length && args[pos] === "[";
}
function unwrapParentheses(args) {
  const trimmed = args.trim();
  if (trimmed.startsWith("(") && trimmed.endsWith(")")) {
    return trimmed.slice(1, -1);
  }
  return trimmed;
}

// src/tree/tree-builder.ts
function classifyPhpTagShorthand(source) {
  const phpTagMatch = source.match(/^<\?(php)\s*([\s\S]*?)\s*\?>$/i);
  if (!phpTagMatch) return null;
  const body = phpTagMatch[2]?.trim() ?? "";
  if (body.length === 0) return null;
  if (/^if\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "if", context: "if" };
  }
  if (/^elseif\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "branch", name: "elseif", context: "if" };
  }
  if (/^else\s*:\s*$/iu.test(body)) {
    return { role: "branch", name: "else", context: "if" };
  }
  if (/^endif\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "endif", context: "if" };
  }
  if (/^switch\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "switch", context: "switch" };
  }
  if (/^case\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "branch", name: "case", context: "switch" };
  }
  if (/^default\s*:\s*$/iu.test(body)) {
    return { role: "branch", name: "default", context: "switch" };
  }
  if (/^endswitch\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "endswitch", context: "switch" };
  }
  if (/^for\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "for", context: "for" };
  }
  if (/^endfor\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "endfor", context: "for" };
  }
  if (/^foreach\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "foreach", context: "foreach" };
  }
  if (/^endforeach\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "endforeach", context: "foreach" };
  }
  if (/^while\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "while", context: "while" };
  }
  if (/^endwhile\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "endwhile", context: "while" };
  }
  if (/^declare\b[\s\S]*:\s*$/iu.test(body)) {
    return { role: "open", name: "declare", context: "declare" };
  }
  if (/^enddeclare\s*;?\s*$/iu.test(body)) {
    return { role: "close", name: "enddeclare", context: "declare" };
  }
  return null;
}
var TreeBuilder = class {
  constructor(tokens, source, directives = Directives3.withDefaults()) {
    this.tokens = tokens;
    this.source = source;
    this.directives = directives;
  }
  nodes = [];
  nodeCount = 0;
  openElements = [];
  openDirectives = [];
  openConditions = [];
  openSwitches = [];
  openPhpTagConditions = [];
  pos = 0;
  tagNames = /* @__PURE__ */ new Map();
  rawTagNames = /* @__PURE__ */ new Map();
  dynamicTagNames = /* @__PURE__ */ new Set();
  tagNameStacks = /* @__PURE__ */ new Map();
  directiveIndex = null;
  attributeRegionEnd = null;
  discoveredDirectiveFamilyCache = /* @__PURE__ */ new Map();
  maxElementDepth = 512;
  maxDirectiveDepth = 256;
  maxConditionDepth = 256;
  build() {
    this.nodes.push(createFlatNode(0 /* Root */, NONE, 0, 0));
    this.nodeCount = 1;
    this.openElements.push(0);
    const total = this.tokens.length;
    while (this.pos < total) {
      this.processToken();
    }
    this.closeRemainingDirectives();
    this.closeRemainingElements();
    return {
      nodes: this.nodes,
      source: this.source,
      tokens: this.tokens,
      directives: this.directives
    };
  }
  processToken() {
    const type = this.tokens[this.pos].type;
    switch (type) {
      case 1 /* LessThan */:
        this.processElementStart();
        break;
      case 0 /* Text */:
      case 5 /* TagName */:
        this.processText();
        break;
      case 9 /* Whitespace */:
        this.processText();
        break;
      case 17 /* AtSign */:
        this.processAtSign();
        break;
      case 18 /* EchoStart */:
        this.processEcho();
        break;
      case 21 /* RawEchoStart */:
        this.processRawEcho();
        break;
      case 23 /* TripleEchoStart */:
        this.processTripleEcho();
        break;
      case 25 /* Directive */:
        this.processDirective();
        break;
      case 27 /* VerbatimStart */:
        this.createBlockNode(this.pos, 28 /* VerbatimEnd */, 9 /* Verbatim */);
        break;
      case 12 /* BladeCommentStart */:
        this.createBlockNode(this.pos, 13 /* BladeCommentEnd */, 15 /* BladeComment */);
        break;
      case 10 /* CommentStart */:
        this.createBlockNode(this.pos, 11 /* CommentEnd */, 12 /* Comment */);
        break;
      case 36 /* BogusComment */:
        this.addChild(createFlatNode(13 /* BogusComment */, 0, this.pos, 1, 0, 1));
        this.pos++;
        break;
      case 14 /* DoctypeStart */:
        this.createBlockNode(this.pos, 16 /* DoctypeEnd */, 16 /* Doctype */);
        break;
      case 51 /* IgnoreRange */:
        this.addChild(createFlatNode(29 /* IgnoreRange */, 0, this.pos, 1));
        this.pos++;
        break;
      case 29 /* PhpBlockStart */:
        this.createBlockNode(this.pos, 30 /* PhpBlockEnd */, 10 /* PhpBlock */);
        break;
      case 39 /* PhpTagStart */:
        this.processPhpTag();
        break;
      case 30 /* PhpBlockEnd */:
        this.processOrphanPhpBlockEnd();
        break;
      case 37 /* ConditionalCommentStart */:
        this.createConditionalComment();
        break;
      case 42 /* CdataStart */:
        this.createBlockNode(this.pos, 43 /* CdataEnd */, 17 /* Cdata */);
        break;
      case 44 /* DeclStart */:
        this.createDecl();
        break;
      case 46 /* PIStart */:
        this.createBlockNode(this.pos, 47 /* PIEnd */, 28 /* ProcessingInstruction */);
        break;
      case 38 /* ConditionalCommentEnd */:
      case 2 /* GreaterThan */:
        this.emitSingleTokenText();
        break;
      default:
        this.pos++;
        break;
    }
  }
  addChild(node) {
    this.implicitlyCloseVoidElements();
    const parentIdx = this.getCurrentParent();
    node.parent = parentIdx;
    const nodeIdx = this.nodeCount++;
    this.nodes[nodeIdx] = node;
    const parent = this.nodes[parentIdx];
    if (parent.firstChild === NONE) {
      parent.firstChild = nodeIdx;
    } else {
      this.nodes[parent.lastChild].nextSibling = nodeIdx;
    }
    parent.lastChild = nodeIdx;
    return nodeIdx;
  }
  getCurrentParent() {
    const last = this.openElements[this.openElements.length - 1];
    return last !== void 0 ? last : 0;
  }
  createFirstChild(parentIdx, kind, tokenStart, tokenCount) {
    const childIdx = this.nodeCount++;
    this.nodes[childIdx] = createFlatNode(kind, parentIdx, tokenStart, tokenCount);
    this.nodes[parentIdx].firstChild = childIdx;
    this.nodes[parentIdx].lastChild = childIdx;
    return childIdx;
  }
  createSiblingChild(prevSiblingIdx, parentIdx, kind, tokenStart, tokenCount) {
    const childIdx = this.nodeCount++;
    this.nodes[childIdx] = createFlatNode(kind, parentIdx, tokenStart, tokenCount);
    this.nodes[prevSiblingIdx].nextSibling = childIdx;
    this.nodes[parentIdx].lastChild = childIdx;
    return childIdx;
  }
  popIfTop(idx) {
    if (this.openElements[this.openElements.length - 1] === idx) {
      const popped = this.openElements.pop();
      this.cleanupTagNameStack(popped);
    }
  }
  popElementsToDepth(targetDepth) {
    while (this.openElements.length > targetDepth) {
      const popped = this.openElements.pop();
      this.cleanupTagNameStack(popped);
    }
  }
  cleanupTagNameStack(elementIdx) {
    const tagName = this.tagNames.get(elementIdx);
    this.tagNames.delete(elementIdx);
    this.rawTagNames.delete(elementIdx);
    this.dynamicTagNames.delete(elementIdx);
    if (tagName === void 0) return;
    const stack = this.tagNameStacks.get(tagName);
    if (stack && stack.length > 0) {
      stack.pop();
      if (stack.length === 0) {
        this.tagNameStacks.delete(tagName);
      }
    }
  }
  checkElementDepth() {
    if (this.openElements.length >= this.maxElementDepth) {
      throw new Error(`Maximum element nesting depth (${this.maxElementDepth}) exceeded.`);
    }
  }
  checkDirectiveDepth() {
    if (this.openDirectives.length >= this.maxDirectiveDepth) {
      throw new Error(`Maximum directive nesting depth (${this.maxDirectiveDepth}) exceeded.`);
    }
  }
  checkConditionDepth() {
    if (this.openConditions.length + this.openPhpTagConditions.length >= this.maxConditionDepth) {
      throw new Error(`Maximum condition nesting depth (${this.maxConditionDepth}) exceeded.`);
    }
  }
  implicitlyCloseVoidElements() {
    while (this.openElements.length > 1) {
      const topIdx = this.openElements[this.openElements.length - 1];
      const tagName = this.tagNames.get(topIdx);
      if (tagName === void 0 || !VOID_ELEMENTS.has(tagName)) break;
      this.openElements.pop();
      const stack = this.tagNameStacks.get(tagName);
      if (stack) {
        stack.pop();
        if (stack.length === 0) this.tagNameStacks.delete(tagName);
      }
    }
  }
  autoCloseElementsForSibling(newTag) {
    if (newTag === "") return;
    const conditions = getClosingConditions(newTag);
    if (conditions?.autoCloseAtParentEnd) {
      const containerIndex = this.findNearestValidContainer(
        conditions.autoCloseAtParentEnd
      );
      if (containerIndex >= 0) {
        this.autoCloseElementsBetween(containerIndex, newTag);
        return;
      }
      return;
    }
    this.autoCloseImmediateParent(newTag);
  }
  autoCloseElementsBetween(containerIndex, newTag) {
    let closeUpToIndex = -1;
    for (let i = this.openElements.length - 1; i > containerIndex; i--) {
      const elementIdx = this.openElements[i];
      if (this.nodes[elementIdx].kind !== 1 /* Element */) continue;
      const tagName = this.tagNames.get(elementIdx) ?? "";
      if (tagName === "") continue;
      const parentTagName = this.parentTagNameOf(elementIdx);
      if (shouldAutoCloseElement(tagName, newTag, parentTagName, false)) {
        closeUpToIndex = i;
      }
    }
    if (closeUpToIndex >= 0) {
      while (this.openElements.length > closeUpToIndex) {
        const popped = this.openElements.pop();
        this.cleanupTagNameStack(popped);
      }
    }
  }
  autoCloseImmediateParent(newTag) {
    if (this.openElements.length <= 1) return;
    const currentIdx = this.openElements[this.openElements.length - 1];
    if (this.nodes[currentIdx].kind !== 1 /* Element */) return;
    const currentTagName = this.tagNames.get(currentIdx) ?? "";
    if (currentTagName === "") return;
    const parentTagName = this.parentTagNameOf(currentIdx);
    if (!isInValidParentContext(currentTagName, parentTagName)) return;
    if (shouldAutoCloseElement(currentTagName, newTag, parentTagName, false)) {
      this.openElements.pop();
      this.cleanupTagNameStack(currentIdx);
    }
  }
  findNearestValidContainer(validParents) {
    for (let i = this.openElements.length - 1; i > 0; i--) {
      const elementIdx = this.openElements[i];
      if (this.nodes[elementIdx].kind !== 1 /* Element */) continue;
      const tagName = this.tagNames.get(elementIdx) ?? "";
      if (tagName === "") continue;
      if (validParents.includes(tagName)) return i;
    }
    return -1;
  }
  parentTagNameOf(idx) {
    const parentIdx = this.nodes[idx].parent;
    if (parentIdx <= 0 || !this.nodes[parentIdx]) return null;
    if (this.nodes[parentIdx].kind !== 1 /* Element */) return null;
    return this.tagNames.get(parentIdx) ?? null;
  }
  closeRemainingElements() {
    const totalTokens = this.tokens.length;
    for (const elementIdx of this.openElements) {
      if (elementIdx === 0) continue;
      this.nodes[elementIdx].tokenCount = totalTokens - this.nodes[elementIdx].tokenStart;
    }
  }
  processText() {
    const parentIdx = this.getCurrentParent();
    const parent = this.nodes[parentIdx];
    if (parent.lastChild !== NONE) {
      const lastChild = this.nodes[parent.lastChild];
      if (lastChild.kind === 2 /* Text */) {
        lastChild.tokenCount++;
        this.pos++;
        return;
      }
    }
    const startPos = this.pos;
    this.pos++;
    this.addChild(createFlatNode(2 /* Text */, 0, startPos, 1));
  }
  processAtSign() {
    const startPos = this.pos;
    this.pos++;
    this.addChild(createFlatNode(22 /* NonOutput */, 0, startPos, 1));
  }
  emitSingleTokenText() {
    const startPos = this.pos;
    this.pos++;
    this.addChild(createFlatNode(2 /* Text */, 0, startPos, 1));
  }
  processEcho() {
    this.processEchoSpan(19 /* EchoEnd */, 4 /* Echo */);
  }
  processRawEcho() {
    this.processEchoSpan(22 /* RawEchoEnd */, 5 /* RawEcho */);
  }
  processTripleEcho() {
    this.processEchoSpan(24 /* TripleEchoEnd */, 6 /* TripleEcho */);
  }
  processEchoSpan(endType, nodeKind) {
    const startPos = this.pos;
    this.pos++;
    const total = this.tokens.length;
    while (this.pos < total) {
      const type = this.tokens[this.pos].type;
      if (type === endType) {
        this.pos++;
        break;
      }
      if (type === 18 /* EchoStart */ || type === 21 /* RawEchoStart */ || type === 23 /* TripleEchoStart */ || type === 12 /* BladeCommentStart */) {
        this.addChild(createFlatNode(2 /* Text */, 0, startPos, this.pos - startPos));
        return;
      }
      this.pos++;
    }
    this.addChild(createFlatNode(nodeKind, 0, startPos, this.pos - startPos));
  }
  createBlockNode(startPos, endTokenType, nodeKind) {
    let endPos = this.pos;
    let hasClosing = false;
    const total = this.tokens.length;
    while (endPos < total) {
      if (this.tokens[endPos].type === endTokenType) {
        hasClosing = true;
        endPos++;
        break;
      }
      endPos++;
    }
    this.addChild(createFlatNode(nodeKind, 0, startPos, endPos - startPos, 0, hasClosing ? 1 : 0));
    this.pos = endPos;
  }
  getPhpTagTokenCount(startPos) {
    let endPos = startPos;
    let hasClosing = false;
    const total = this.tokens.length;
    while (endPos < total) {
      if (this.tokens[endPos].type === 40 /* PhpTagEnd */) {
        hasClosing = true;
        endPos++;
        break;
      }
      endPos++;
    }
    return { tokenCount: endPos - startPos, hasClosing };
  }
  addStandalonePhpTag(startPos, tokenCount, hasClosing) {
    this.addChild(createFlatNode(11 /* PhpTag */, 0, startPos, tokenCount, 0, hasClosing ? 1 : 0));
    this.pos += tokenCount;
  }
  processPhpTag() {
    const startPos = this.pos;
    const { tokenCount, hasClosing } = this.getPhpTagTokenCount(startPos);
    if (tokenCount <= 0) {
      this.pos++;
      return;
    }
    const startToken = this.tokens[startPos];
    const endToken = this.tokens[startPos + tokenCount - 1];
    const rawTag = this.source.slice(startToken.start, endToken.end);
    const shorthand = classifyPhpTagShorthand(rawTag);
    if (!shorthand) {
      this.addStandalonePhpTag(startPos, tokenCount, hasClosing);
      return;
    }
    if (shorthand.role === "open") {
      this.openPhpTagCondition(shorthand, startPos, tokenCount, hasClosing);
      return;
    }
    if (shorthand.role === "branch") {
      this.openPhpTagConditionBranch(shorthand, startPos, tokenCount, hasClosing);
      return;
    }
    this.closePhpTagCondition(shorthand, startPos, tokenCount, hasClosing);
  }
  openPhpTagCondition(shorthand, startPos, tokenCount, hasClosing) {
    const blockIdx = this.addChild(
      createFlatNode(8 /* DirectiveBlock */, 0, startPos, tokenCount)
    );
    const elementStackBase = this.openElements.length;
    this.checkElementDepth();
    this.openElements.push(blockIdx);
    const branchIdx = this.addChild(
      createFlatNode(11 /* PhpTag */, 0, startPos, tokenCount, 0, hasClosing ? 1 : 0)
    );
    this.checkElementDepth();
    this.openElements.push(branchIdx);
    this.checkConditionDepth();
    this.openPhpTagConditions.push({
      blockIdx,
      currentBranchIdx: branchIdx,
      name: shorthand.context,
      elementStackBase
    });
    this.pos += tokenCount;
  }
  openPhpTagConditionBranch(shorthand, startPos, tokenCount, hasClosing) {
    if (this.openPhpTagConditions.length === 0) {
      this.addStandalonePhpTag(startPos, tokenCount, hasClosing);
      return;
    }
    const frame = this.openPhpTagConditions[this.openPhpTagConditions.length - 1];
    const isMatchingBranch = frame.name === "if" && (shorthand.name === "elseif" || shorthand.name === "else") || frame.name === "switch" && (shorthand.name === "case" || shorthand.name === "default");
    if (!isMatchingBranch) {
      this.addStandalonePhpTag(startPos, tokenCount, hasClosing);
      return;
    }
    this.popIfTop(frame.currentBranchIdx);
    this.popElementsToDepth(frame.elementStackBase + 1);
    const branchIdx = this.addChild(
      createFlatNode(11 /* PhpTag */, 0, startPos, tokenCount, 0, hasClosing ? 1 : 0)
    );
    this.checkElementDepth();
    this.openElements.push(branchIdx);
    frame.currentBranchIdx = branchIdx;
    this.pos += tokenCount;
  }
  closePhpTagCondition(shorthand, startPos, tokenCount, hasClosing) {
    if (this.openPhpTagConditions.length === 0) {
      this.addStandalonePhpTag(startPos, tokenCount, hasClosing);
      return;
    }
    const frame = this.openPhpTagConditions[this.openPhpTagConditions.length - 1];
    const expectedCloser = frame.name === "if" ? "endif" : frame.name === "switch" ? "endswitch" : frame.name === "for" ? "endfor" : frame.name === "foreach" ? "endforeach" : frame.name === "while" ? "endwhile" : "enddeclare";
    if (shorthand.name !== expectedCloser) {
      this.addStandalonePhpTag(startPos, tokenCount, hasClosing);
      return;
    }
    this.openPhpTagConditions.pop();
    this.popElementsToDepth(frame.elementStackBase + 1);
    this.popIfTop(frame.currentBranchIdx);
    this.addChild(createFlatNode(11 /* PhpTag */, 0, startPos, tokenCount, 0, hasClosing ? 1 : 0));
    this.popIfTop(frame.blockIdx);
    const endPos = startPos + tokenCount;
    this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    this.pos += tokenCount;
  }
  processOrphanPhpBlockEnd() {
    const startPos = this.pos;
    this.pos++;
    const node = createFlatNode(7 /* Directive */, 0, startPos, 1);
    this.addChild(node);
  }
  createConditionalComment() {
    const startPos = this.pos;
    const total = this.tokens.length;
    let endPos = startPos + 1;
    let hasClosing = false;
    while (endPos < total) {
      if (this.tokens[endPos].type === 38 /* ConditionalCommentEnd */) {
        hasClosing = true;
        break;
      }
      endPos++;
    }
    const fullEndPos = hasClosing ? endPos + 1 : endPos;
    const node = createFlatNode(
      14 /* ConditionalComment */,
      0,
      startPos,
      fullEndPos - startPos,
      0,
      hasClosing ? 1 : 0
    );
    const nodeIdx = this.addChild(node);
    const elementStackDepth = this.openElements.length;
    this.checkElementDepth();
    this.openElements.push(nodeIdx);
    this.pos = startPos + 1;
    while (this.pos < endPos) {
      this.processToken();
    }
    while (this.openElements.length > elementStackDepth + 1) {
      const popped2 = this.openElements.pop();
      this.cleanupTagNameStack(popped2);
    }
    const popped = this.openElements.pop();
    this.cleanupTagNameStack(popped);
    this.pos = fullEndPos;
  }
  createDecl() {
    const tokens = this.tokens;
    const total = tokens.length;
    const startPos = this.pos;
    let endPos = this.pos;
    let hasClosing = false;
    while (endPos < total) {
      if (tokens[endPos].type === 45 /* DeclEnd */) {
        hasClosing = true;
        break;
      }
      endPos++;
    }
    const declTokenCount = hasClosing ? endPos + 1 - startPos : endPos - startPos;
    const declIdx = this.addChild(
      createFlatNode(18 /* Decl */, 0, startPos, declTokenCount, 0, hasClosing ? 1 : 0)
    );
    this.checkElementDepth();
    this.openElements.push(declIdx);
    this.pos++;
    while (this.pos < total) {
      const type = tokens[this.pos].type;
      if (type === 45 /* DeclEnd */) {
        this.pos++;
        break;
      }
      if (type === 9 /* Whitespace */) {
        this.addChild(createFlatNode(25 /* AttributeWhitespace */, 0, this.pos, 1));
        this.pos++;
        continue;
      }
      if (type === 18 /* EchoStart */ || type === 21 /* RawEchoStart */ || type === 23 /* TripleEchoStart */) {
        this.processDeclEcho();
        continue;
      }
      if (type === 6 /* AttributeName */ || type === 34 /* BoundAttribute */ || type === 33 /* EscapedAttribute */ || type === 35 /* ShorthandAttribute */) {
        this.buildDeclAttribute(endPos);
        continue;
      }
      this.pos++;
    }
    this.openElements.pop();
  }
  processDeclEcho() {
    const startPos = this.pos;
    const total = this.tokens.length;
    const startType = this.tokens[startPos].type;
    const nodeKind = getNodeKind(startType) ?? 4 /* Echo */;
    const constructTokenCount = countConstructTokens(this.tokens, startPos, total);
    this.pos += constructTokenCount;
    this.addChild(createFlatNode(nodeKind, 0, startPos, constructTokenCount));
  }
  buildDeclAttribute(attrEnd) {
    const tokens = this.tokens;
    const total = tokens.length;
    const attrStart = this.pos;
    let nameCount = 0;
    while (this.pos < total && this.pos < attrEnd) {
      const type = tokens[this.pos].type;
      if (type === 6 /* AttributeName */ || type === 18 /* EchoStart */ || type === 21 /* RawEchoStart */ || type === 23 /* TripleEchoStart */) {
        nameCount++;
        this.pos++;
        continue;
      }
      break;
    }
    if (nameCount === 0) {
      this.pos++;
      return;
    }
    const [hasValue, valueStart, valueCount] = this.scanDeclEqualsAndValue(attrEnd, total);
    const attrTokenCount = this.pos - attrStart;
    const attrIdx = this.addChild(createFlatNode(19 /* Attribute */, 0, attrStart, attrTokenCount));
    const nameIdx = this.createFirstChild(attrIdx, 26 /* AttributeName */, attrStart, nameCount);
    this.buildDeclAttributeParts(attrStart, nameCount, nameIdx, false);
    if (hasValue && valueCount > 0) {
      const valueIdx = this.createSiblingChild(
        nameIdx,
        attrIdx,
        27 /* AttributeValue */,
        valueStart,
        valueCount
      );
      this.buildDeclAttributeParts(valueStart, valueCount, valueIdx, true);
    }
  }
  scanDeclEqualsAndValue(attrEnd, total) {
    let hasValue = false;
    let valueStart = 0;
    let valueCount = 0;
    let checkPos = this.pos;
    if (checkPos < total && this.tokens[checkPos].type === 9 /* Whitespace */) {
      checkPos++;
    }
    if (checkPos < total && this.tokens[checkPos].type === 4 /* Equals */) {
      this.pos = checkPos + 1;
      if (this.pos < total && this.tokens[this.pos].type === 9 /* Whitespace */) {
        this.pos++;
      }
      if (this.pos < total) {
        valueStart = this.pos;
        valueCount = this.scanDeclAttributeValue(attrEnd);
        hasValue = valueCount > 0;
      }
    }
    return [hasValue, valueStart, valueCount];
  }
  scanDeclAttributeValue(attrEnd) {
    const total = this.tokens.length;
    if (this.pos >= total || this.tokens[this.pos].type !== 8 /* Quote */) {
      return 0;
    }
    let count = 1;
    this.pos++;
    while (this.pos < total && this.pos < attrEnd) {
      const type = this.tokens[this.pos].type;
      if (type === 8 /* Quote */) {
        count++;
        this.pos++;
        break;
      }
      if (type === 45 /* DeclEnd */) {
        break;
      }
      count++;
      this.pos++;
    }
    return count;
  }
  buildDeclAttributeParts(start, count, parentIdx, isValue) {
    let lastChildIdx = NONE;
    for (let i = 0; i < count; i++) {
      const tokenPos = start + i;
      const type = this.tokens[tokenPos].type;
      if (isValue) {
        if (type === 8 /* Quote */ || type === 19 /* EchoEnd */ || type === 22 /* RawEchoEnd */ || type === 24 /* TripleEchoEnd */) {
          continue;
        }
      }
      const nodeKind = this.declPartNodeKind(type);
      const partIdx = this.nodeCount++;
      this.nodes[partIdx] = createFlatNode(nodeKind, parentIdx, tokenPos, 1);
      if (lastChildIdx === NONE) {
        this.nodes[parentIdx].firstChild = partIdx;
      } else {
        this.nodes[lastChildIdx].nextSibling = partIdx;
      }
      this.nodes[parentIdx].lastChild = partIdx;
      lastChildIdx = partIdx;
    }
  }
  declPartNodeKind(type) {
    switch (type) {
      case 18 /* EchoStart */:
        return 4 /* Echo */;
      case 21 /* RawEchoStart */:
        return 5 /* RawEcho */;
      case 23 /* TripleEchoStart */:
        return 6 /* TripleEcho */;
      default:
        return 2 /* Text */;
    }
  }
  processElementStart() {
    const tokens = this.tokens;
    const total = tokens.length;
    const startPos = this.pos;
    this.pos++;
    if (startPos >= total || tokens[startPos].type !== 1 /* LessThan */) return;
    if (this.pos < total && tokens[this.pos].type === 3 /* Slash */) {
      this.processElementEnd();
      return;
    }
    const tagNameStart = this.pos;
    const [tagNameCount, genericOffset] = this.scanElementName();
    const rawTagName = this.getRawNameText(tagNameStart, tagNameCount);
    const isDynamicTagName = this.isDynamicTagName(tagNameStart, tagNameCount);
    if (this.pos < total && tokens[this.pos].type === 50 /* TsxGenericType */) {
      this.pos++;
    }
    if (tagNameCount === 0) {
      this.addChild(createFlatNode(2 /* Text */, 0, startPos, 1));
      return;
    }
    const staticTagName = this.getTagNameText(tagNameStart, tagNameCount);
    const lowerNewTag = staticTagName.toLowerCase();
    if (!isDynamicTagName) {
      this.autoCloseElementsForSibling(lowerNewTag);
    }
    const elementIdx = this.addChild(createFlatNode(1 /* Element */, 0, startPos, 0));
    const elementNameIdx = this.createFirstChild(
      elementIdx,
      23 /* ElementName */,
      tagNameStart,
      tagNameCount
    );
    this.buildElementNameParts(tagNameStart, tagNameCount, elementNameIdx);
    this.buildAttributes(elementIdx, elementNameIdx);
    let selfClosing = false;
    let syntheticClose = false;
    if (this.pos < total && tokens[this.pos].type === 3 /* Slash */) {
      this.pos++;
      selfClosing = true;
    }
    if (this.pos < total) {
      const type = tokens[this.pos].type;
      if (type === 2 /* GreaterThan */) {
        this.pos++;
      } else if (type === 32 /* SyntheticClose */) {
        this.pos++;
        syntheticClose = true;
      }
    }
    this.nodes[elementIdx].tokenCount = this.pos - startPos;
    this.nodes[elementIdx].genericOffset = genericOffset > 0 ? genericOffset + 1 : 0;
    this.nodes[elementIdx].data = selfClosing ? 1 : 0;
    let shouldStayOpen = !selfClosing;
    if (syntheticClose && shouldStayOpen) {
      const nextType = this.pos < total ? tokens[this.pos].type : null;
      if (this.pos >= total || nextType === 1 /* LessThan */) {
        shouldStayOpen = false;
      }
    }
    if (!shouldStayOpen) return;
    this.checkElementDepth();
    this.openElements.push(elementIdx);
    this.tagNames.set(elementIdx, lowerNewTag);
    this.rawTagNames.set(elementIdx, rawTagName);
    if (isDynamicTagName) {
      this.dynamicTagNames.add(elementIdx);
    }
    if (lowerNewTag !== "" && !isDynamicTagName) {
      let stack = this.tagNameStacks.get(lowerNewTag);
      if (!stack) {
        stack = [];
        this.tagNameStacks.set(lowerNewTag, stack);
      }
      stack.push(this.openElements.length - 1);
    }
  }
  processElementEnd() {
    const tokens = this.tokens;
    const total = tokens.length;
    const startPos = this.pos - 1;
    this.pos++;
    const tagNameStartPos = this.pos;
    const [tagNameCount] = this.scanElementName();
    const closingTagName = tagNameCount > 0 ? this.getTagNameText(tagNameStartPos, tagNameCount) : "";
    const closingRawTagName = tagNameCount > 0 ? this.getRawNameText(tagNameStartPos, tagNameCount) : "";
    const closingIsDynamicTagName = tagNameCount > 0 ? this.isDynamicTagName(tagNameStartPos, tagNameCount) : false;
    while (this.pos < total && tokens[this.pos].type !== 2 /* GreaterThan */ && tokens[this.pos].type !== 32 /* SyntheticClose */) {
      this.pos++;
    }
    if (this.pos < total) this.pos++;
    let searchLimit = 1;
    if (this.openDirectives.length > 0) {
      const currentDirective = this.openDirectives[this.openDirectives.length - 1];
      searchLimit = currentDirective.elementStackBase + 1;
    }
    const lowerClosingTag = closingTagName.toLowerCase();
    let foundMatch = false;
    let matchDepth = 0;
    let matchedOpenElementsIndex = -1;
    const stack = !closingIsDynamicTagName ? this.tagNameStacks.get(lowerClosingTag) : null;
    if (stack && stack.length > 0) {
      const openElementsCount = this.openElements.length;
      for (let i = stack.length - 1; i >= 0; i--) {
        const openElementsIndex = stack[i];
        if (openElementsIndex >= searchLimit && openElementsIndex < openElementsCount) {
          const elementIdx = this.openElements[openElementsIndex];
          if ((this.tagNames.get(elementIdx) ?? "") === lowerClosingTag) {
            matchedOpenElementsIndex = openElementsIndex;
            foundMatch = true;
            matchDepth = openElementsCount - openElementsIndex;
            break;
          }
        }
      }
    }
    if (!foundMatch) {
      for (let i = this.openElements.length - 1; i >= searchLimit; i--) {
        const elementIdx = this.openElements[i];
        if (this.nodes[elementIdx].kind === 8 /* DirectiveBlock */) continue;
        const openTagName = this.tagNames.get(elementIdx) ?? "";
        const openRawTagName = this.rawTagNames.get(elementIdx) ?? "";
        const openIsDynamicTagName = this.dynamicTagNames.has(elementIdx);
        if (openIsDynamicTagName || closingIsDynamicTagName) {
          if (openRawTagName === closingRawTagName) {
            foundMatch = true;
            matchDepth = this.openElements.length - i;
            matchedOpenElementsIndex = i;
            break;
          }
          continue;
        }
        if (openTagName.toLowerCase() === lowerClosingTag || this.isSlotClosingMatch(openRawTagName, closingRawTagName)) {
          foundMatch = true;
          matchDepth = this.openElements.length - i;
          matchedOpenElementsIndex = i;
          break;
        }
      }
    }
    if (foundMatch) {
      const elementIdx = this.openElements[matchedOpenElementsIndex];
      this.nodes[elementIdx].tokenCount = this.pos - this.nodes[elementIdx].tokenStart;
      const closingNameIdx = this.createAndLinkClosingNameNode(
        elementIdx,
        tagNameStartPos,
        tagNameCount
      );
      this.buildElementNameParts(tagNameStartPos, tagNameCount, closingNameIdx);
      for (let i = 0; i < matchDepth; i++) {
        if (this.openElements.length > 1) {
          const popped = this.openElements.pop();
          this.cleanupTagNameStack(popped);
        }
      }
      return;
    }
    this.addChild(
      createFlatNode(
        21 /* UnpairedClosingTag */,
        0,
        startPos,
        this.pos - startPos,
        0,
        tagNameCount
      )
    );
  }
  createAndLinkClosingNameNode(parentIdx, tokenStart, tokenCount) {
    const idx = this.nodeCount++;
    this.nodes[idx] = createFlatNode(
      24 /* ClosingElementName */,
      parentIdx,
      tokenStart,
      tokenCount
    );
    const lastChild = this.nodes[parentIdx].lastChild;
    if (lastChild !== NONE) {
      this.nodes[lastChild].nextSibling = idx;
    } else {
      this.nodes[parentIdx].firstChild = idx;
    }
    this.nodes[parentIdx].lastChild = idx;
    return idx;
  }
  isSlotClosingMatch(openTagName, closingTagName) {
    const lowerClose = closingTagName.toLowerCase();
    if (lowerClose !== "x-slot") return false;
    const lowerOpen = openTagName.toLowerCase();
    return lowerOpen.startsWith("x-slot:") || lowerOpen.startsWith("x-slot[");
  }
  scanElementName() {
    const tokens = this.tokens;
    const limit = tokens.length;
    let count = 0;
    let genericOffset = 0;
    while (this.pos < limit) {
      const type = tokens[this.pos].type;
      if (this.isElementNameTerminator(type)) {
        if (type === 50 /* TsxGenericType */) {
          genericOffset = count + 1;
        }
        break;
      }
      if (type === 5 /* TagName */) {
        count++;
        this.pos++;
        continue;
      }
      if (isConstructStart(type)) {
        const [newPos, constructCount] = scanConstruct(tokens, this.pos, limit);
        count += constructCount;
        this.pos = newPos;
        continue;
      }
      break;
    }
    return [count, genericOffset];
  }
  isElementNameTerminator(type) {
    return type === 9 /* Whitespace */ || type === 2 /* GreaterThan */ || type === 3 /* Slash */ || type === 25 /* Directive */ || type === 50 /* TsxGenericType */ || type === 32 /* SyntheticClose */;
  }
  buildElementNameParts(startPos, tokenCount, parentIdx) {
    const tokens = this.tokens;
    const endPos = startPos + tokenCount;
    let i = startPos;
    let lastChildIdx = null;
    while (i < endPos) {
      const type = tokens[i].type;
      let childTokenCount = 1;
      let childNode = null;
      if (type === 5 /* TagName */) {
        childNode = createFlatNode(2 /* Text */, parentIdx, i, 1);
      } else if (isConstructStart(type)) {
        const nodeKind = getNodeKind(type) ?? 4 /* Echo */;
        childTokenCount = countConstructTokens(tokens, i, endPos);
        childNode = createFlatNode(nodeKind, parentIdx, i, childTokenCount);
      }
      if (childNode !== null) {
        const childIdx = this.nodeCount++;
        this.nodes[childIdx] = childNode;
        if (lastChildIdx === null) {
          this.nodes[parentIdx].firstChild = childIdx;
        } else {
          this.nodes[lastChildIdx].nextSibling = childIdx;
        }
        this.nodes[parentIdx].lastChild = childIdx;
        lastChildIdx = childIdx;
      }
      i += childTokenCount;
    }
  }
  getTagNameText(startPos, tokenCount) {
    let text = "";
    const total = this.tokens.length;
    for (let i = 0; i < tokenCount; i++) {
      const idx = startPos + i;
      if (idx >= total) break;
      if (this.tokens[idx].type === 5 /* TagName */) {
        text += this.source.slice(this.tokens[idx].start, this.tokens[idx].end);
      }
    }
    return text;
  }
  getRawNameText(startPos, tokenCount) {
    let text = "";
    const total = this.tokens.length;
    for (let i = 0; i < tokenCount; i++) {
      const idx = startPos + i;
      if (idx >= total) break;
      const token = this.tokens[idx];
      text += this.source.slice(token.start, token.end);
    }
    return text;
  }
  isDynamicTagName(startPos, tokenCount) {
    const total = this.tokens.length;
    for (let i = 0; i < tokenCount; i++) {
      const idx = startPos + i;
      if (idx >= total) break;
      if (this.tokens[idx].type !== 5 /* TagName */) return true;
    }
    return false;
  }
  // Attributes
  buildAttributes(elementIdx, _lastChildIdx) {
    const attrEnd = this.findAttributeRegionEnd();
    this.openElements.push(elementIdx);
    const savedDirectives = this.openDirectives;
    const savedConditions = this.openConditions;
    const savedAttributeRegionEnd = this.attributeRegionEnd;
    this.openDirectives = [];
    this.openConditions = [];
    this.attributeRegionEnd = attrEnd;
    try {
      while (this.pos < attrEnd) {
        const type = this.tokens[this.pos].type;
        if (this.isInsideAttributePhpDirective()) {
          if (type === 25 /* Directive */) {
            const directiveName = extractDirectiveName(this.tokens[this.pos], this.source);
            if (directiveName === "endphp") {
              this.processDirective();
              continue;
            }
          }
          if (isConstructStart(type)) {
            this.processConstructInAttributes(4 /* Echo */);
          } else {
            this.processText();
          }
          continue;
        }
        if (type === 9 /* Whitespace */) {
          this.addChild(createFlatNode(25 /* AttributeWhitespace */, 0, this.pos, 1));
          this.pos++;
          continue;
        }
        if (type === 25 /* Directive */) {
          this.processDirective();
          continue;
        }
        if (type === 49 /* JsxShorthandAttribute */) {
          this.addChild(createFlatNode(20 /* JsxAttribute */, 0, this.pos, 1));
          this.pos++;
          continue;
        }
        this.buildUnifiedAttribute(attrEnd);
      }
      this.closeRemainingAttributeDirectives();
    } finally {
      this.openDirectives = savedDirectives;
      this.openConditions = savedConditions;
      this.attributeRegionEnd = savedAttributeRegionEnd;
      this.openElements.pop();
    }
  }
  isInsideAttributePhpDirective() {
    if (this.openDirectives.length === 0) return false;
    const top = this.openDirectives[this.openDirectives.length - 1];
    return top.name === "php";
  }
  findAttributeRegionEnd() {
    let attrEnd = this.pos;
    const total = this.tokens.length;
    while (attrEnd < total) {
      const type = this.tokens[attrEnd].type;
      if (type === 2 /* GreaterThan */ || type === 32 /* SyntheticClose */) break;
      if (type === 3 /* Slash */ && attrEnd + 1 < total) {
        const next = this.tokens[attrEnd + 1].type;
        if (next === 2 /* GreaterThan */ || next === 32 /* SyntheticClose */) break;
      }
      attrEnd++;
    }
    return attrEnd;
  }
  buildUnifiedAttribute(attrEnd) {
    const attrStart = this.pos;
    const bounds = this.scanAttributeBounds(attrEnd);
    if (bounds.length === 0) {
      this.pos++;
      return;
    }
    this.pos = bounds.end;
    const firstType = this.tokens[attrStart].type;
    if (isConstructStart(firstType)) {
      const constructCount = countConstructTokens(this.tokens, attrStart, attrEnd);
      if (constructCount === bounds.length) {
        this.pos = attrStart;
        this.processConstructInAttributes(4 /* Echo */);
        return;
      }
    }
    if (bounds.isNameValue) {
      const attrIdx2 = this.addChild(
        createFlatNode(19 /* Attribute */, 0, attrStart, bounds.length)
      );
      const nameIdx2 = this.createFirstChild(
        attrIdx2,
        26 /* AttributeName */,
        attrStart,
        bounds.nameCount
      );
      this.buildAttributeNameParts(attrStart, bounds.nameCount, nameIdx2);
      if (bounds.valueCount > 0) {
        const valueIdx = this.createSiblingChild(
          nameIdx2,
          attrIdx2,
          27 /* AttributeValue */,
          bounds.valueStart,
          bounds.valueCount
        );
        this.buildAttributeValueParts(bounds.valueStart, bounds.valueCount, valueIdx);
      }
      return;
    }
    const attrIdx = this.addChild(createFlatNode(19 /* Attribute */, 0, attrStart, bounds.length));
    const nameIdx = this.createFirstChild(
      attrIdx,
      26 /* AttributeName */,
      attrStart,
      bounds.length
    );
    this.buildAttributeNameParts(attrStart, bounds.length, nameIdx);
  }
  scanAttributeBounds(attrEnd) {
    const attrStart = this.pos;
    let equalsPos = -1;
    let nameEnd = -1;
    let scanPos = this.pos;
    let lastNonWhitespace = this.pos;
    while (scanPos < attrEnd) {
      const type = this.tokens[scanPos].type;
      if (type === 9 /* Whitespace */) {
        let lookAhead = scanPos + 1;
        while (lookAhead < attrEnd && this.tokens[lookAhead].type === 9 /* Whitespace */) {
          lookAhead++;
        }
        if (lookAhead < attrEnd && this.tokens[lookAhead].type === 4 /* Equals */) {
          scanPos = lookAhead;
          continue;
        }
        break;
      }
      if (type === 4 /* Equals */) {
        equalsPos = scanPos;
        nameEnd = lastNonWhitespace;
        scanPos++;
        while (scanPos < attrEnd && this.tokens[scanPos].type === 9 /* Whitespace */) {
          scanPos++;
        }
        if (scanPos < attrEnd) {
          if (this.tokens[scanPos].type === 8 /* Quote */) {
            scanPos++;
            while (scanPos < attrEnd && this.tokens[scanPos].type !== 8 /* Quote */) {
              scanPos = advancePast(this.tokens, scanPos, attrEnd);
            }
            if (scanPos < attrEnd) scanPos++;
          } else {
            while (scanPos < attrEnd && this.tokens[scanPos].type !== 9 /* Whitespace */) {
              scanPos = advancePast(this.tokens, scanPos, attrEnd);
            }
          }
        }
        break;
      }
      scanPos = advancePast(this.tokens, scanPos, attrEnd);
      lastNonWhitespace = scanPos;
    }
    const length = scanPos - attrStart;
    if (length === 0) {
      return {
        length: 0,
        end: scanPos,
        isNameValue: false,
        nameCount: 0,
        valueStart: 0,
        valueCount: 0
      };
    }
    if (equalsPos !== -1 && nameEnd !== -1) {
      const nameCount = nameEnd - attrStart;
      let valueStart = equalsPos + 1;
      while (valueStart < scanPos && this.tokens[valueStart].type === 9 /* Whitespace */) {
        valueStart++;
      }
      const valueCount = scanPos - valueStart;
      return { length, end: scanPos, isNameValue: true, nameCount, valueStart, valueCount };
    }
    return { length, end: scanPos, isNameValue: false, nameCount: 0, valueStart: 0, valueCount: 0 };
  }
  buildAttributeNameParts(startPos, tokenCount, parentIdx) {
    this.buildParts(startPos, startPos + tokenCount, parentIdx, false);
  }
  buildAttributeValueParts(startPos, tokenCount, parentIdx) {
    let i = startPos;
    const endPos = startPos + tokenCount;
    if (i < endPos && this.tokens[i].type === 8 /* Quote */) i++;
    let effectiveEnd = endPos;
    if (effectiveEnd > startPos && this.tokens[effectiveEnd - 1].type === 8 /* Quote */) {
      effectiveEnd--;
    }
    this.buildParts(i, effectiveEnd, parentIdx, true);
  }
  buildParts(startPos, endPos, parentIdx, asValue) {
    let i = startPos;
    let lastChildIdx = null;
    while (i < endPos) {
      const type = this.tokens[i].type;
      let childTokenCount = 1;
      let childNode;
      if (this.isTextLike(type, asValue)) {
        childNode = createFlatNode(2 /* Text */, parentIdx, i, 1);
      } else if (isConstructStart(type)) {
        const nodeKind = getNodeKind(type) ?? 4 /* Echo */;
        childTokenCount = countConstructTokens(this.tokens, i, endPos);
        childNode = createFlatNode(nodeKind, parentIdx, i, childTokenCount);
      } else if (asValue && type === 25 /* Directive */) {
        let dirEnd = i + 1;
        if (dirEnd < endPos && this.tokens[dirEnd].type === 26 /* DirectiveArgs */) {
          dirEnd++;
        }
        childTokenCount = dirEnd - i;
        childNode = createFlatNode(7 /* Directive */, parentIdx, i, childTokenCount);
      } else {
        childNode = createFlatNode(2 /* Text */, parentIdx, i, 1);
      }
      const childIdx = this.nodeCount++;
      this.nodes[childIdx] = childNode;
      if (lastChildIdx === null) {
        this.nodes[parentIdx].firstChild = childIdx;
      } else {
        this.nodes[lastChildIdx].nextSibling = childIdx;
      }
      this.nodes[parentIdx].lastChild = childIdx;
      lastChildIdx = childIdx;
      i += childTokenCount;
    }
  }
  isTextLike(type, asValue) {
    if (asValue) {
      return type === 7 /* AttributeValue */ || type === 0 /* Text */;
    }
    return type === 6 /* AttributeName */ || type === 34 /* BoundAttribute */ || type === 33 /* EscapedAttribute */ || type === 35 /* ShorthandAttribute */ || type === 0 /* Text */;
  }
  processConstructInAttributes(defaultKind) {
    const startPos = this.pos;
    const startType = this.tokens[startPos].type;
    const nodeKind = getNodeKind(startType) ?? defaultKind;
    const constructTokenCount = countConstructTokens(
      this.tokens,
      startPos,
      this.tokens.length
    );
    this.pos += constructTokenCount;
    this.addChild(createFlatNode(nodeKind, 0, startPos, constructTokenCount));
  }
  closeRemainingAttributeDirectives() {
    while (this.openConditions.length > 0) {
      const frame = this.openConditions.pop();
      this.popIfTop(frame.currentBranchIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = this.pos - this.nodes[frame.blockIdx].tokenStart;
    }
    while (this.openDirectives.length > 0) {
      const frame = this.openDirectives.pop();
      this.popIfTop(frame.startDirectiveIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = this.pos - this.nodes[frame.blockIdx].tokenStart;
    }
  }
  processDirective() {
    const startPos = this.pos;
    const directiveToken = this.tokens[this.pos];
    const directiveName = extractDirectiveName(directiveToken, this.source);
    let tokenCount = 1;
    const argsInfo = checkDirectiveArgsFast(this.tokens, this.pos + 1, this.tokens.length);
    tokenCount += argsInfo.consumed;
    if (this.isSwitchRelatedDirective(directiveName)) {
      this.processSwitchDirective(directiveName, startPos, tokenCount, null);
      return;
    }
    if (this.directives.isConditionalPair(directiveName)) {
      const argsContent = argsInfo.argsTokenIndex >= 0 ? this.source.slice(
        this.tokens[argsInfo.argsTokenIndex].start,
        this.tokens[argsInfo.argsTokenIndex].end
      ) : null;
      this.processConditionalPairingDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    if (this.isConditionRelatedDirective(directiveName)) {
      this.processConditionDirective(directiveName, startPos, tokenCount, null);
      return;
    }
    if (this.isBranchOfOpenDirective(directiveName)) {
      this.openDirectiveBranch(directiveName, startPos, tokenCount, null);
      return;
    }
    if (this.isClosingDirective(directiveName)) {
      this.closeDirective(directiveName, startPos, tokenCount, null);
      return;
    }
    if (directiveName === "php" && argsInfo.hasArgs) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, null);
      return;
    }
    if (this.directives.isPaired(directiveName)) {
      this.openPairedDirective(directiveName, startPos, tokenCount);
      return;
    }
    if (this.tryOpenDiscoveredDirective(directiveName, startPos, tokenCount)) {
      return;
    }
    this.createStandaloneDirective(directiveName, startPos, tokenCount, null);
  }
  tryOpenDiscoveredDirective(directiveName, startPos, tokenCount) {
    const family = this.resolveDiscoveredDirectiveFamily(directiveName);
    if (family === null) {
      return false;
    }
    const { hasAdvisoryCondition, elseName, endName, openers } = family;
    const directiveIndex = this.getDirectiveIndex();
    const directiveStart = startPos + tokenCount;
    const searchEnd = this.getDiscoveredDirectiveSearchEnd(openers, directiveStart);
    if (!hasAdvisoryCondition) {
      if (!this.hasDirectiveInSearchRange(directiveIndex, endName, directiveStart, searchEnd)) {
        return false;
      }
      const terminatorIdx = directiveIndex.findMatchingTerminatorForOpeners(
        openers,
        directiveStart,
        [endName],
        searchEnd
      );
      if (terminatorIdx === null) {
        return false;
      }
      this.openPairedDirective(directiveName, startPos, tokenCount, {
        terminators: [endName],
        branches: [],
        openers
      });
      return true;
    }
    const genericConditionTerminators = this.directives.getConditionTerminators();
    const terminators = genericConditionTerminators.includes(endName) ? genericConditionTerminators : [endName, ...genericConditionTerminators];
    const branches = [elseName, "else", "elseif"];
    if (!this.hasDirectiveInSearchRange(directiveIndex, endName, directiveStart, searchEnd) && !this.hasDirectiveInSearchRange(directiveIndex, elseName, directiveStart, searchEnd) && !genericConditionTerminators.some(
      (name) => this.hasDirectiveInSearchRange(directiveIndex, name, directiveStart, searchEnd)
    )) {
      return false;
    }
    const analysis = directiveIndex.analyzeUnknownDirectiveFamily(
      openers,
      directiveStart,
      terminators,
      branches,
      searchEnd
    );
    if (analysis.terminatorIdx === null || analysis.terminatorName === null) {
      return false;
    }
    const opensAsConditionLike = hasAdvisoryCondition && (analysis.branchIdx !== null || analysis.terminatorName !== endName);
    this.openPairedDirective(directiveName, startPos, tokenCount, {
      terminators: opensAsConditionLike ? terminators : [endName],
      branches: opensAsConditionLike ? branches : [],
      openers
    });
    return true;
  }
  resolveDiscoveredDirectiveFamily(directiveName) {
    directiveName = directiveName.toLowerCase();
    if (this.discoveredDirectiveFamilyCache.has(directiveName)) {
      return this.discoveredDirectiveFamilyCache.get(directiveName) ?? null;
    }
    if (this.directives.isDirective(directiveName)) {
      this.discoveredDirectiveFamilyCache.set(directiveName, null);
      return null;
    }
    let baseName = directiveName;
    let unlessName = `unless${directiveName}`;
    let isUnlessVariant = false;
    if (directiveName.startsWith("unless") && directiveName.length > "unless".length) {
      const candidateBase = directiveName.slice("unless".length);
      if (candidateBase.length === 0 || this.directives.isDirective(candidateBase)) {
        this.discoveredDirectiveFamilyCache.set(directiveName, null);
        return null;
      }
      baseName = candidateBase;
      unlessName = directiveName;
      isUnlessVariant = true;
    }
    const elseName = `else${baseName}`;
    const endName = `end${baseName}`;
    const hasAdvisoryPair = this.directives.hasAdvisoryPair(baseName) || this.directives.hasSeenDirective(endName);
    const hasAdvisoryCondition = this.directives.hasAdvisoryCondition(baseName) || this.directives.hasSeenDirective(elseName);
    if (!hasAdvisoryPair && !hasAdvisoryCondition) {
      this.discoveredDirectiveFamilyCache.set(directiveName, null);
      return null;
    }
    const openers = isUnlessVariant || this.directives.hasSeenDirective(unlessName) ? [baseName, unlessName] : [directiveName];
    const family = { elseName, endName, openers, hasAdvisoryPair, hasAdvisoryCondition };
    this.discoveredDirectiveFamilyCache.set(directiveName, family);
    return family;
  }
  hasDirectiveInSearchRange(index, directiveName, minIdx, maxIdxExclusive) {
    return maxIdxExclusive === null ? index.existsAfter(directiveName, minIdx) : index.existsBetween(directiveName, minIdx, maxIdxExclusive);
  }
  getDiscoveredDirectiveSearchEnd(openerNames, startIdx) {
    let searchEnd = this.attributeRegionEnd;
    searchEnd = this.takeEarlierBoundary(searchEnd, this.findOpenElementBoundary(startIdx));
    searchEnd = this.takeEarlierBoundary(
      searchEnd,
      this.findOpenDirectiveBoundary(openerNames, startIdx)
    );
    searchEnd = this.takeEarlierBoundary(searchEnd, this.findOpenSwitchBoundary(startIdx));
    return searchEnd;
  }
  takeEarlierBoundary(current, candidate) {
    if (candidate === null) {
      return current;
    }
    if (current === null || candidate < current) {
      return candidate;
    }
    return current;
  }
  findOpenElementBoundary(startIdx) {
    let containingTagName = null;
    for (let i = this.openElements.length - 1; i >= 0; i--) {
      const elementIdx = this.openElements[i];
      if (this.nodes[elementIdx]?.kind !== 1 /* Element */) continue;
      containingTagName = this.tagNames.get(elementIdx) ?? null;
      if (containingTagName !== null) {
        break;
      }
    }
    if (containingTagName === null) {
      return null;
    }
    let containingTagDepth = 0;
    for (let i = startIdx; i < this.tokens.length; i++) {
      if (this.tokens[i].type !== 1 /* LessThan */) continue;
      if (i + 2 >= this.tokens.length) continue;
      if (this.tokens[i + 1].type === 3 /* Slash */) {
        if (this.tokens[i + 2].type !== 5 /* TagName */) continue;
        const closingTagName = this.source.slice(this.tokens[i + 2].start, this.tokens[i + 2].end).toLowerCase();
        if (closingTagName !== containingTagName) continue;
        if (containingTagDepth === 0) {
          return i;
        }
        containingTagDepth--;
        continue;
      }
      if (this.tokens[i + 1].type !== 5 /* TagName */) continue;
      const openingTagName = this.source.slice(this.tokens[i + 1].start, this.tokens[i + 1].end).toLowerCase();
      if (openingTagName !== containingTagName) continue;
      if (!this.isSelfClosingElementAt(i, this.tokens.length)) {
        containingTagDepth++;
      }
    }
    return null;
  }
  isSelfClosingElementAt(startIdx, limitIdx) {
    for (let i = startIdx + 1; i < limitIdx; i++) {
      const type = this.tokens[i].type;
      if (type === 2 /* GreaterThan */ || type === 32 /* SyntheticClose */) {
        return this.tokens[i - 1]?.type === 3 /* Slash */;
      }
      if (type === 1 /* LessThan */) {
        return false;
      }
    }
    return false;
  }
  findOpenDirectiveBoundary(openerNames, startIdx) {
    if (this.openDirectives.length === 0) {
      return null;
    }
    const index = this.getDirectiveIndex();
    let boundary = null;
    for (const frame of this.openDirectives) {
      if (frame.terminators.length === 0 && frame.branches.length === 0) continue;
      const initialNesting = this.directiveFamiliesIntersect(frame.openers, openerNames) ? 1 : 0;
      const boundaryIdx = frame.branches.length > 0 ? index.findMatchingBoundaryForOpeners(
        frame.openers,
        startIdx,
        frame.terminators,
        frame.branches,
        null,
        initialNesting
      ) : index.findMatchingTerminatorForOpeners(
        frame.openers,
        startIdx,
        frame.terminators,
        null,
        initialNesting
      );
      if (boundaryIdx !== null) {
        boundary = this.takeEarlierBoundary(boundary, boundaryIdx);
      }
    }
    return boundary;
  }
  directiveFamiliesIntersect(left, right) {
    if (left[0] === right[0]) {
      return true;
    }
    const leftSecond = left[1];
    const rightSecond = right[1];
    return leftSecond === right[0] || rightSecond === left[0] || leftSecond !== void 0 && leftSecond === rightSecond;
  }
  findOpenSwitchBoundary(startIdx) {
    if (this.openSwitches.length === 0) {
      return null;
    }
    const index = this.getDirectiveIndex();
    let boundary = null;
    for (const frame of this.openSwitches) {
      const boundaries = [...this.directives.getSwitchBranches(frame.name), "endswitch"];
      const boundaryIdx = index.findMatchingTerminator(frame.name, startIdx, boundaries);
      if (boundaryIdx !== null) {
        boundary = this.takeEarlierBoundary(boundary, boundaryIdx);
      }
    }
    return boundary;
  }
  isClosingDirective(directiveName) {
    if (this.openDirectives.length === 0) return false;
    for (let i = this.openDirectives.length - 1; i >= 0; i--) {
      const frame = this.openDirectives[i];
      if (frame.terminators.includes(directiveName)) return true;
    }
    return false;
  }
  isBranchOfOpenDirective(directiveName) {
    if (this.openDirectives.length === 0) return false;
    for (let i = this.openDirectives.length - 1; i >= 0; i--) {
      const frame = this.openDirectives[i];
      if (frame.branches.includes(directiveName)) return true;
    }
    return false;
  }
  openPairedDirective(directiveName, startPos, tokenCount, frameMeta) {
    const blockIdx = this.addChild(
      createFlatNode(8 /* DirectiveBlock */, 0, startPos, tokenCount)
    );
    const elementStackBase = this.openElements.length;
    this.checkElementDepth();
    this.openElements.push(blockIdx);
    const startDirectiveIdx = this.addChild(
      createFlatNode(7 /* Directive */, 0, startPos, tokenCount)
    );
    this.checkDirectiveDepth();
    const directive = this.directives.getDirective(directiveName);
    const terminators = frameMeta?.terminators ?? directive?.terminators ?? [];
    const branches = frameMeta?.branches ?? directive?.conditionLikeBranches ?? [];
    const openers = frameMeta?.openers ?? [directiveName];
    this.openDirectives.push({
      blockIdx,
      startDirectiveIdx,
      name: directiveName,
      elementStackBase,
      terminators,
      branches,
      openers
    });
    this.checkElementDepth();
    this.openElements.push(startDirectiveIdx);
    this.pos += tokenCount;
  }
  openDirectiveBranch(directiveName, startPos, tokenCount, argsContent) {
    if (this.openDirectives.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    let matchedIdx = -1;
    for (let i = this.openDirectives.length - 1; i >= 0; i--) {
      const frame2 = this.openDirectives[i];
      if (frame2.branches.includes(directiveName)) {
        matchedIdx = i;
        break;
      }
    }
    if (matchedIdx === -1) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    const frame = this.openDirectives[matchedIdx];
    this.popIfTop(frame.startDirectiveIdx);
    this.popElementsToDepth(frame.elementStackBase + 1);
    const branchIdx = this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.checkElementDepth();
    this.openElements.push(branchIdx);
    frame.startDirectiveIdx = branchIdx;
    this.pos += tokenCount;
  }
  closeDirective(directiveName, startPos, tokenCount, argsContent) {
    let matchedIdx = -1;
    for (let i = this.openDirectives.length - 1; i >= 0; i--) {
      const frame = this.openDirectives[i];
      if (frame.terminators.includes(directiveName)) {
        matchedIdx = i;
        break;
      }
    }
    if (matchedIdx === -1) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    for (let i = this.openDirectives.length - 1; i >= matchedIdx; i--) {
      const frame = this.openDirectives.pop();
      const blockIdx = frame.blockIdx;
      this.popElementsToDepth(frame.elementStackBase + 2);
      this.popIfTop(frame.startDirectiveIdx);
      this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
      this.popIfTop(blockIdx);
      const endPos = startPos + tokenCount;
      this.nodes[blockIdx].tokenCount = endPos - this.nodes[blockIdx].tokenStart;
    }
    this.pos += tokenCount;
  }
  createStandaloneDirective(_directiveName, startPos, tokenCount, _argsContent) {
    this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.pos += tokenCount;
  }
  isConditionRelatedDirective(directiveName) {
    if (this.directives.isCondition(directiveName)) return true;
    if (this.openConditions.length > 0) {
      const currentCondition = this.openConditions[this.openConditions.length - 1];
      const branches = this.directives.getBranches(currentCondition.name);
      for (const branch of branches) {
        if (branch.toLowerCase() === directiveName) return true;
      }
    }
    const terminators = this.directives.getConditionTerminators();
    return terminators.includes(directiveName);
  }
  processConditionDirective(directiveName, startPos, tokenCount, argsContent) {
    if (this.tryHandleConditionDirectiveWithOpenDirective(
      directiveName,
      startPos,
      tokenCount,
      argsContent
    )) {
      return;
    }
    const terminators = this.directives.getConditionTerminators();
    const isFinalTerminator = terminators.includes(directiveName);
    if (isFinalTerminator && this.openConditions.length > 0) {
      this.closeCondition(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    if (this.openConditions.length > 0) {
      const currentCondition = this.openConditions[this.openConditions.length - 1];
      const branches = this.directives.getBranches(currentCondition.name);
      for (const branch of branches) {
        if (branch.toLowerCase() === directiveName) {
          this.openConditionBranch(directiveName, startPos, tokenCount, argsContent);
          return;
        }
      }
    }
    const directive = this.directives.getDirective(directiveName);
    if (this.directives.isCondition(directiveName) && directive !== null && directive.role === 1 /* Opening */) {
      this.openCondition(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
  }
  tryHandleConditionDirectiveWithOpenDirective(directiveName, startPos, tokenCount, argsContent) {
    const directiveMatch = this.getMatchingOpenDirectiveFrame(directiveName);
    if (directiveMatch === null) {
      return false;
    }
    const conditionMatch = this.getMatchingOpenConditionFrame(directiveName);
    if (conditionMatch !== null && this.getConditionFrameTokenStart(conditionMatch.frame) >= this.getDirectiveFrameTokenStart(directiveMatch.frame)) {
      return false;
    }
    if (directiveMatch.kind === "branch") {
      this.openDirectiveBranch(directiveName, startPos, tokenCount, argsContent);
      return true;
    }
    this.closeDirective(directiveName, startPos, tokenCount, argsContent);
    return true;
  }
  getMatchingOpenDirectiveFrame(directiveName) {
    if (this.openDirectives.length === 0) {
      return null;
    }
    for (let i = this.openDirectives.length - 1; i >= 0; i--) {
      const frame = this.openDirectives[i];
      if (frame.branches.includes(directiveName)) {
        return { frame, kind: "branch" };
      }
      if (frame.terminators.includes(directiveName)) {
        return { frame, kind: "close" };
      }
    }
    return null;
  }
  getMatchingOpenConditionFrame(directiveName) {
    if (this.openConditions.length === 0) {
      return null;
    }
    const frame = this.openConditions[this.openConditions.length - 1];
    const terminators = this.directives.getConditionTerminators();
    if (terminators.includes(directiveName)) {
      return { frame, kind: "close" };
    }
    const branches = this.directives.getBranches(frame.name);
    if (branches.includes(directiveName)) {
      return { frame, kind: "branch" };
    }
    return null;
  }
  getDirectiveFrameTokenStart(frame) {
    return this.nodes[frame.startDirectiveIdx]?.tokenStart ?? -1;
  }
  getConditionFrameTokenStart(frame) {
    return this.nodes[frame.currentBranchIdx]?.tokenStart ?? -1;
  }
  openCondition(directiveName, startPos, tokenCount, _argsContent) {
    const blockIdx = this.addChild(
      createFlatNode(8 /* DirectiveBlock */, 0, startPos, tokenCount)
    );
    const elementStackBase = this.openElements.length;
    this.checkElementDepth();
    this.openElements.push(blockIdx);
    const branchIdx = this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.checkElementDepth();
    this.openElements.push(branchIdx);
    this.checkConditionDepth();
    this.openConditions.push({
      blockIdx,
      currentBranchIdx: branchIdx,
      name: directiveName,
      elementStackBase
    });
    this.pos += tokenCount;
  }
  openConditionBranch(directiveName, startPos, tokenCount, _argsContent) {
    if (this.openConditions.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, _argsContent);
      return;
    }
    const frame = this.openConditions[this.openConditions.length - 1];
    this.popIfTop(frame.currentBranchIdx);
    this.popElementsToDepth(frame.elementStackBase + 1);
    const branchIdx = this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.checkElementDepth();
    this.openElements.push(branchIdx);
    frame.currentBranchIdx = branchIdx;
    this.pos += tokenCount;
  }
  closeCondition(directiveName, startPos, tokenCount, _argsContent) {
    if (this.openConditions.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, _argsContent);
      return;
    }
    const frame = this.openConditions.pop();
    this.popElementsToDepth(frame.elementStackBase + 1);
    this.popIfTop(frame.currentBranchIdx);
    this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.popIfTop(frame.blockIdx);
    const endPos = startPos + tokenCount;
    this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    this.pos += tokenCount;
  }
  isSwitchRelatedDirective(directiveName) {
    if (this.directives.isSwitch(directiveName)) return true;
    if (directiveName === "endswitch") return true;
    if (this.openSwitches.length > 0) {
      if (this.directives.isSwitchBranch(directiveName)) return true;
      if (this.directives.isSwitchTerminator(directiveName)) return true;
    }
    return false;
  }
  processSwitchDirective(directiveName, startPos, tokenCount, argsContent) {
    if (directiveName === "endswitch" && this.openSwitches.length > 0) {
      this.closeSwitch(directiveName, startPos, tokenCount, argsContent);
    } else if (this.directives.isSwitchTerminator(directiveName) && this.openSwitches.length > 0) {
      this.processSwitchBreak(directiveName, startPos, tokenCount, argsContent);
    } else if (this.openSwitches.length > 0 && this.directives.isSwitchBranch(directiveName)) {
      this.openSwitchCase(directiveName, startPos, tokenCount, argsContent);
    } else if (this.directives.isSwitch(directiveName)) {
      this.openSwitch(directiveName, startPos, tokenCount, argsContent);
    } else {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
    }
  }
  openSwitch(directiveName, startPos, tokenCount, _argsContent) {
    const blockIdx = this.addChild(
      createFlatNode(8 /* DirectiveBlock */, 0, startPos, tokenCount)
    );
    const elementStackBase = this.openElements.length;
    this.checkElementDepth();
    this.openElements.push(blockIdx);
    const switchDirectiveIdx = this.addChild(
      createFlatNode(7 /* Directive */, 0, startPos, tokenCount)
    );
    this.checkDirectiveDepth();
    this.openSwitches.push({
      blockIdx,
      switchDirectiveIdx,
      currentCaseIdx: null,
      name: directiveName,
      elementStackBase
    });
    this.checkElementDepth();
    this.openElements.push(switchDirectiveIdx);
    this.pos += tokenCount;
  }
  openSwitchCase(directiveName, startPos, tokenCount, argsContent) {
    if (this.openSwitches.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    const frame = this.openSwitches[this.openSwitches.length - 1];
    this.popElementsToDepth(frame.elementStackBase + 2);
    if (frame.currentCaseIdx !== null) {
      this.popIfTop(frame.currentCaseIdx);
    }
    const caseIdx = this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    frame.currentCaseIdx = caseIdx;
    this.checkElementDepth();
    this.openElements.push(caseIdx);
    this.pos += tokenCount;
  }
  processSwitchBreak(directiveName, startPos, tokenCount, argsContent) {
    if (this.openSwitches.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    const frame = this.openSwitches[this.openSwitches.length - 1];
    if (frame.currentCaseIdx === null) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.pos += tokenCount;
  }
  closeSwitch(directiveName, startPos, tokenCount, argsContent) {
    if (this.openSwitches.length === 0) {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
      return;
    }
    const frame = this.openSwitches.pop();
    this.popElementsToDepth(frame.elementStackBase + 2);
    if (frame.currentCaseIdx !== null) {
      this.popIfTop(frame.currentCaseIdx);
    }
    this.popIfTop(frame.switchDirectiveIdx);
    this.addChild(createFlatNode(7 /* Directive */, 0, startPos, tokenCount));
    this.popIfTop(frame.blockIdx);
    const endPos = startPos + tokenCount;
    this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    this.pos += tokenCount;
  }
  processConditionalPairingDirective(directiveName, startPos, tokenCount, argsContent) {
    if (this.shouldPairDirective(directiveName, startPos, tokenCount, argsContent)) {
      if (this.directives.isCondition(directiveName)) {
        this.openCondition(directiveName, startPos, tokenCount, argsContent);
      } else {
        this.openPairedDirective(directiveName, startPos, tokenCount);
      }
    } else {
      this.createStandaloneDirective(directiveName, startPos, tokenCount, argsContent);
    }
  }
  shouldPairDirective(directiveName, startPos, tokenCount, argsContent) {
    const strategy = this.directives.getPairingStrategy(directiveName);
    if (strategy === null) return false;
    switch (strategy) {
      case "lang_style":
        return this.shouldPairLangStyle(directiveName, startPos, tokenCount, argsContent);
      case "no_arguments_block":
        return this.shouldPairNoArgumentsBlock(directiveName, startPos, tokenCount, argsContent);
      case "section_style":
        return this.shouldPairSectionStyle(directiveName, startPos, tokenCount, argsContent);
      case "single_argument_block":
        return this.shouldPairSingleArgumentBlock(directiveName, startPos, tokenCount, argsContent);
      default:
        return false;
    }
  }
  shouldPairLangStyle(directiveName, startPos, tokenCount, argsContent) {
    if (argsContent === null || startsWithArray(unwrapParentheses(argsContent))) {
      return this.hasMatchingTerminator(directiveName, startPos + tokenCount);
    }
    return false;
  }
  shouldPairSectionStyle(directiveName, startPos, tokenCount, argsContent) {
    if (argsContent !== null) {
      const argCount = countArguments(unwrapParentheses(argsContent));
      if (argCount >= 2) return false;
    }
    return this.hasMatchingTerminator(directiveName, startPos + tokenCount);
  }
  shouldPairNoArgumentsBlock(directiveName, startPos, tokenCount, argsContent) {
    if (getDirectiveArgumentCount(argsContent) !== 0) {
      return false;
    }
    return this.hasMatchingTerminator(directiveName, startPos + tokenCount);
  }
  shouldPairSingleArgumentBlock(directiveName, startPos, tokenCount, argsContent) {
    if (getDirectiveArgumentCount(argsContent) !== 1) {
      return false;
    }
    return this.hasMatchingTerminator(directiveName, startPos + tokenCount);
  }
  hasMatchingTerminator(directiveName, afterPos) {
    const directiveIndex = this.getDirectiveIndex();
    const terminators = this.directives.getTerminators(directiveName);
    if (terminators.length === 0) {
      terminators.push("end" + directiveName);
    }
    return directiveIndex.findMatchingTerminator(directiveName, afterPos, terminators) !== null;
  }
  closeRemainingDirectives() {
    const endPos = this.tokens.length;
    while (this.openSwitches.length > 0) {
      const frame = this.openSwitches.pop();
      if (frame.currentCaseIdx !== null) this.popIfTop(frame.currentCaseIdx);
      this.popIfTop(frame.switchDirectiveIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    }
    while (this.openConditions.length > 0) {
      const frame = this.openConditions.pop();
      this.popIfTop(frame.currentBranchIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    }
    while (this.openPhpTagConditions.length > 0) {
      const frame = this.openPhpTagConditions.pop();
      this.popIfTop(frame.currentBranchIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    }
    while (this.openDirectives.length > 0) {
      const frame = this.openDirectives.pop();
      this.popIfTop(frame.startDirectiveIdx);
      this.popIfTop(frame.blockIdx);
      this.nodes[frame.blockIdx].tokenCount = endPos - this.nodes[frame.blockIdx].tokenStart;
    }
  }
  getDirectiveIndex() {
    if (this.directiveIndex === null) {
      this.directiveIndex = new DirectiveTokenIndex(this.tokens, this.source);
    }
    return this.directiveIndex;
  }
};
function buildTree(tokens, source, directives) {
  return new TreeBuilder(tokens, source, directives).build();
}
function getDirectiveArgumentCount(argsContent) {
  if (argsContent === null) return 0;
  return countArguments(unwrapParentheses(argsContent));
}

// src/pragma.ts
var HTML_PRAGMA_RE = /^\s*<!--\s*@(?:format|prettier)\s*-->/;
var BLADE_PRAGMA_RE = /^\s*\{\{--\s*@(?:format|prettier)\s*--\}\}/;
function hasPragma(text) {
  return HTML_PRAGMA_RE.test(text) || BLADE_PRAGMA_RE.test(text);
}
function insertPragma(text) {
  return `<!-- @format -->

${text}`;
}

// src/plugins/sage/metadata.ts
var SAGE_ACF_DIRECTIVES = [
  { name: "fields", args: true, structure: { role: "open", terminators: "endfields" } },
  { name: "endfields", args: false, structure: { role: "close" } },
  {
    name: "hasfields",
    args: true,
    structure: { role: "open", condition: true, terminators: "endhasfields" }
  },
  { name: "endhasfields", args: false, structure: { role: "close", condition: true } },
  { name: "field", args: true },
  {
    name: "hasfield,isfield",
    args: true,
    structure: { role: "open", condition: true, terminators: "endfield" }
  },
  { name: "endfield", args: false, structure: { role: "close", condition: true } },
  { name: "sub", args: true },
  {
    name: "hassub,issub",
    args: true,
    structure: { role: "open", condition: true, terminators: "endsub" }
  },
  { name: "endsub", args: false, structure: { role: "close", condition: true } },
  { name: "layouts", args: true, structure: { role: "open", terminators: "endlayouts" } },
  { name: "endlayouts", args: false, structure: { role: "close" } },
  {
    name: "layout",
    args: true,
    structure: { role: "open", condition: true, terminators: "endlayout" }
  },
  { name: "endlayout", args: false, structure: { role: "close", condition: true } },
  { name: "group", args: true, structure: { role: "open", terminators: "endgroup" } },
  { name: "endgroup", args: false, structure: { role: "close" } },
  { name: "options", args: true, structure: { role: "open", terminators: "endoptions" } },
  { name: "endoptions", args: false, structure: { role: "close" } },
  {
    name: "hasoptions",
    args: true,
    structure: { role: "open", condition: true, terminators: "endhasoptions" }
  },
  { name: "endhasoptions", args: false, structure: { role: "close", condition: true } },
  { name: "option", args: true },
  {
    name: "hasoption,isoption",
    args: true,
    structure: { role: "open", condition: true, terminators: "endoption" }
  },
  { name: "endoption", args: false, structure: { role: "close", condition: true } }
];
var SAGE_HELPER_DIRECTIVES = [
  {
    name: "istrue",
    args: true,
    structure: {
      role: "conditional_pair",
      condition: true,
      terminators: "endistrue",
      pairing_strategy: "single_argument_block"
    }
  },
  {
    name: "isfalse",
    args: true,
    structure: {
      role: "conditional_pair",
      condition: true,
      terminators: "endisfalse",
      pairing_strategy: "single_argument_block"
    }
  },
  {
    name: "isnull",
    args: true,
    structure: {
      role: "conditional_pair",
      condition: true,
      terminators: "endisnull",
      pairing_strategy: "single_argument_block"
    }
  },
  {
    name: "isnotnull",
    args: true,
    structure: {
      role: "conditional_pair",
      condition: true,
      terminators: "endisnotnull",
      pairing_strategy: "single_argument_block"
    }
  },
  {
    name: "notempty",
    args: true,
    structure: {
      role: "conditional_pair",
      condition: true,
      terminators: "endnotempty",
      pairing_strategy: "single_argument_block"
    }
  },
  {
    name: "endistrue,endisfalse,endisnull,endisnotnull,endnotempty",
    args: false,
    structure: { role: "close", condition: true }
  },
  {
    name: "instanceof",
    args: true,
    structure: { role: "open", condition: true, terminators: "endinstanceof" }
  },
  { name: "endinstanceof", args: false, structure: { role: "close", condition: true } },
  {
    name: "typeof",
    args: true,
    structure: { role: "open", condition: true, terminators: "endtypeof" }
  },
  { name: "endtypeof", args: false, structure: { role: "close", condition: true } },
  { name: "global", args: true },
  { name: "set", args: true },
  { name: "unset", args: true },
  { name: "extract", args: true },
  { name: "implode", args: true },
  { name: "repeat", args: true, structure: { role: "open", terminators: "endrepeat" } },
  { name: "endrepeat", args: false, structure: { role: "close" } },
  {
    name: "stylesheet",
    structure: {
      role: "conditional_pair",
      terminators: "endstylesheet",
      pairing_strategy: "no_arguments_block"
    }
  },
  {
    name: "script",
    structure: {
      role: "conditional_pair",
      terminators: "endscript",
      pairing_strategy: "no_arguments_block"
    }
  },
  { name: "endstylesheet,endscript", args: false, structure: { role: "conditional_close" } },
  { name: "js", args: true },
  { name: "inline", args: true }
];
var SAGE_WORDPRESS_DIRECTIVES = [
  { name: "query", args: true },
  { name: "posts", args: true, structure: { role: "open", terminators: "endposts" } },
  { name: "endposts", args: false, structure: { role: "close" } },
  {
    name: "hasposts",
    args: true,
    structure: { role: "open", condition: true, terminators: "endhasposts" }
  },
  {
    name: "noposts",
    args: true,
    structure: { role: "open", condition: true, terminators: "endnoposts" }
  },
  {
    name: "endhasposts,endnoposts",
    args: false,
    structure: { role: "close", condition: true }
  },
  { name: "postmeta,title,permalink,thumbnail,author,authorurl,published,modified", args: true },
  { name: "content,excerpt,wphead,wpfooter,wpbodyopen", args: false },
  { name: "category,categories,term,terms,image,shortcode,wpautop,wpautokp", args: true },
  { name: "action,filter,bodyclass,postclass,sidebar,thememod,menu", args: true },
  {
    name: "role",
    args: true,
    structure: { role: "open", condition: true, terminators: "endrole" }
  },
  { name: "endrole", args: false, structure: { role: "close", condition: true } },
  {
    name: "user",
    args: false,
    structure: { role: "open", condition: true, terminators: "enduser" }
  },
  { name: "enduser", args: false, structure: { role: "close", condition: true } },
  {
    name: "guest",
    args: false,
    structure: { role: "open", condition: true, terminators: "endguest" }
  },
  { name: "endguest", args: false, structure: { role: "close", condition: true } },
  {
    name: "hassidebar",
    args: true,
    structure: { role: "open", condition: true, terminators: "endhassidebar" }
  },
  {
    name: "hasmenu",
    args: true,
    structure: { role: "open", condition: true, terminators: "endhasmenu" }
  },
  {
    name: "endhassidebar,endhasmenu",
    args: false,
    structure: { role: "close", condition: true }
  },
  { name: "__", args: true }
];
var SAGE_TREE_DIRECTIVES = [
  ...SAGE_ACF_DIRECTIVES,
  ...SAGE_HELPER_DIRECTIVES,
  ...SAGE_WORDPRESS_DIRECTIVES
];
function splitDirectiveNames(value) {
  return value.split(",").map((name) => name.trim().toLowerCase()).filter(Boolean);
}
function allowsDirectiveArguments(args) {
  if (args === false) {
    return false;
  }
  if (typeof args === "object" && args !== null && args.allowed === false) {
    return false;
  }
  return true;
}
function isConditionDirective(definition) {
  if (!definition.structure?.condition) {
    return false;
  }
  return definition.structure.role === "open" || definition.structure.role === "conditional_pair";
}
var SAGE_DIRECTIVE_METADATA = /* @__PURE__ */ new Map();
for (const definition of SAGE_TREE_DIRECTIVES) {
  const directiveMetadata = {
    allowsArguments: allowsDirectiveArguments(definition.args),
    isConditionDirective: isConditionDirective(definition)
  };
  for (const name of splitDirectiveNames(definition.name)) {
    SAGE_DIRECTIVE_METADATA.set(name, {
      name,
      ...directiveMetadata
    });
  }
}
var SAGE_DECLARED_DIRECTIVE_NAMES = Object.freeze([...SAGE_DIRECTIVE_METADATA.keys()]);
var SAGE_ARGUMENT_DIRECTIVE_NAMES = Object.freeze(
  SAGE_DECLARED_DIRECTIVE_NAMES.filter(
    (name) => SAGE_DIRECTIVE_METADATA.get(name)?.allowsArguments === true
  )
);
function getSageDirectiveMetadata(name) {
  return SAGE_DIRECTIVE_METADATA.get(name.trim().toLowerCase()) ?? null;
}

// src/plugins/types.ts
var DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER = "__BLADE_DIRECTIVE_ARGS__";

// src/plugins/sage/print.ts
var DIRECTIVE_CALL_TEMPLATE = `<?php __b(${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER});`;
var DIRECTIVE_GLOBAL_TEMPLATE = `<?php global ${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER};`;
var DIRECTIVE_IF_TEMPLATE = `<?php if (${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER}) {}`;
var DIRECTIVE_QUERY_TEMPLATE = `<?php $__blade_sage_query__ = new WP_Query(${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER});`;
var DIRECTIVE_REPEAT_TEMPLATE = `<?php $__currentLoopData = range(1, ${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER}); foreach ($__currentLoopData as $__i) : endforeach; ?>`;
var DIRECTIVE_POSTS_TEMPLATE = `<?php $__blade_sage_query__ = ${DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER}; if ($__blade_sage_query__) : while (true) : endwhile; endif; ?>`;
function withCallFallback(key, template, directiveName) {
  return [
    { key, template },
    { key: `sage-call:${directiveName}`, template: DIRECTIVE_CALL_TEMPLATE }
  ];
}
var SAGE_DIRECTIVE_TEMPLATES = /* @__PURE__ */ new Map([
  ["global", withCallFallback("sage-global", DIRECTIVE_GLOBAL_TEMPLATE, "global")],
  ["posts", withCallFallback("sage-posts", DIRECTIVE_POSTS_TEMPLATE, "posts")],
  ["query", withCallFallback("sage-query", DIRECTIVE_QUERY_TEMPLATE, "query")],
  ["repeat", withCallFallback("sage-repeat", DIRECTIVE_REPEAT_TEMPLATE, "repeat")]
]);
function getSageDirectivePhpFormatTemplates(directiveName, context) {
  const normalizedDirectiveName = directiveName.trim().toLowerCase();
  const direct = SAGE_DIRECTIVE_TEMPLATES.get(normalizedDirectiveName);
  if (direct) return direct;
  const metadata = getSageDirectiveMetadata(normalizedDirectiveName);
  if (metadata === null || !metadata.allowsArguments) {
    return [];
  }
  if (metadata.isConditionDirective || context.isConditionLikeDirective?.(normalizedDirectiveName)) {
    return withCallFallback(
      `sage-if:${normalizedDirectiveName}`,
      DIRECTIVE_IF_TEMPLATE,
      normalizedDirectiveName
    );
  }
  return [{ key: `sage-call:${normalizedDirectiveName}`, template: DIRECTIVE_CALL_TEMPLATE }];
}

// src/plugins/sage/index.ts
var SAGE_PLUGIN_NAME = "log1x/sage-directives";
var sagePlugin = {
  name: SAGE_PLUGIN_NAME,
  // The parser tokenizes directives permissively, so Sage only needs tree metadata.
  lexerDirectives: [],
  treeDirectives: SAGE_TREE_DIRECTIVES,
  verbatimStartDirectives: [],
  verbatimEndDirectives: [],
  getDirectivePhpFormatTemplates: getSageDirectivePhpFormatTemplates
};

// src/plugins/statamic.ts
var STATAMIC_VERBATIM_START_DIRECTIVES = ["antlers"];
var STATAMIC_VERBATIM_END_DIRECTIVES = ["endantlers"];
var statamicPlugin = {
  name: "statamic",
  lexerDirectives: [...STATAMIC_VERBATIM_START_DIRECTIVES, ...STATAMIC_VERBATIM_END_DIRECTIVES],
  treeDirectives: [
    {
      name: "antlers",
      args: false,
      structure: { role: "open", terminators: "endantlers" }
    },
    {
      name: "endantlers",
      args: false,
      structure: { role: "close" }
    }
  ],
  verbatimStartDirectives: STATAMIC_VERBATIM_START_DIRECTIVES,
  verbatimEndDirectives: STATAMIC_VERBATIM_END_DIRECTIVES
};

// src/plugins/runtime.ts
var BUILTIN_BLADE_SYNTAX_PLUGINS = /* @__PURE__ */ new Map([
  [SAGE_PLUGIN_NAME, sagePlugin],
  ["statamic", statamicPlugin]
]);
var resolvedBladeSyntaxPluginsCache = /* @__PURE__ */ new WeakMap();
function isRecord(value) {
  return typeof value === "object" && value !== null;
}
function isStringArray(value) {
  return Array.isArray(value) && value.every((item) => typeof item === "string");
}
function isBladeSyntaxPlugin(value) {
  if (!isRecord(value)) return false;
  if (typeof value.name !== "string") return false;
  if (!isStringArray(value.lexerDirectives)) return false;
  if (!Array.isArray(value.treeDirectives)) return false;
  if (!isStringArray(value.verbatimStartDirectives)) return false;
  if (!isStringArray(value.verbatimEndDirectives)) return false;
  return true;
}
function normalizeDirectiveName2(name) {
  return name.trim().toLowerCase().replace(/^@/, "");
}
function parseBladeSyntaxPluginTokens(value) {
  if (!Array.isArray(value)) return [];
  const out = [];
  for (const entry of value) {
    if (typeof entry === "string") {
      for (const token of entry.split(",")) {
        const trimmed = token.trim();
        if (trimmed) out.push(trimmed);
      }
      continue;
    }
    out.push(entry);
  }
  return out;
}
function resolveBladeSyntaxPluginEntry(value) {
  if (typeof value === "string") {
    return BUILTIN_BLADE_SYNTAX_PLUGINS.get(normalizeDirectiveName2(value)) ?? null;
  }
  if (isBladeSyntaxPlugin(value)) {
    return value;
  }
  return null;
}
function resolveBladeSyntaxProfile(options2) {
  const resolvedPlugins = resolveBladeSyntaxPlugins(options2);
  const lexerDirectives = /* @__PURE__ */ new Set();
  const verbatimStartDirectives = /* @__PURE__ */ new Set();
  const verbatimEndDirectives = /* @__PURE__ */ new Set();
  const treeDirectives = [];
  for (const plugin2 of resolvedPlugins) {
    for (const directive of plugin2.lexerDirectives) {
      const normalized = normalizeDirectiveName2(directive);
      if (normalized) lexerDirectives.add(normalized);
    }
    for (const directive of plugin2.verbatimStartDirectives) {
      const normalized = normalizeDirectiveName2(directive);
      if (normalized) verbatimStartDirectives.add(normalized);
    }
    for (const directive of plugin2.verbatimEndDirectives) {
      const normalized = normalizeDirectiveName2(directive);
      if (normalized) verbatimEndDirectives.add(normalized);
    }
    for (const directive of plugin2.treeDirectives) {
      treeDirectives.push(directive);
    }
  }
  return {
    lexerDirectives: [...lexerDirectives],
    treeDirectives,
    verbatimStartDirectives: [...verbatimStartDirectives],
    verbatimEndDirectives: [...verbatimEndDirectives]
  };
}
function resolveBladeSyntaxPlugins(options2) {
  const optionRecord = isRecord(options2) ? options2 : {};
  const cached = resolvedBladeSyntaxPluginsCache.get(optionRecord);
  if (cached) {
    return cached;
  }
  const rawPlugins = parseBladeSyntaxPluginTokens(optionRecord.bladeSyntaxPlugins);
  const seenPluginNames = /* @__PURE__ */ new Set();
  const resolvedPlugins = [];
  for (const entry of rawPlugins) {
    const plugin2 = resolveBladeSyntaxPluginEntry(entry);
    if (!plugin2) continue;
    const key = plugin2.name.toLowerCase();
    if (seenPluginNames.has(key)) continue;
    seenPluginNames.add(key);
    resolvedPlugins.push(plugin2);
  }
  resolvedBladeSyntaxPluginsCache.set(optionRecord, resolvedPlugins);
  return resolvedPlugins;
}

// src/front-matter.ts
var DELIMITER_LENGTH = 3;
var FRONT_MATTER_MARK = /* @__PURE__ */ Symbol.for("PRETTIER_IS_FRONT_MATTER");
function markFrontMatter(value) {
  value[FRONT_MATTER_MARK] = true;
}
function hasFrontMatterMark(value) {
  if (!value || typeof value !== "object") return false;
  return value[FRONT_MATTER_MARK] === true;
}
function replaceNonLineBreaksWithSpace(text) {
  return text.replaceAll(/[^\r\n]/g, " ");
}
function findLineBreakIndex(text, start) {
  for (let i = start; i < text.length; i++) {
    const ch = text[i];
    if (ch === "\n" || ch === "\r") {
      return i;
    }
  }
  return -1;
}
function skipLineBreak(text, index) {
  if (index < 0 || index >= text.length) return index;
  if (text[index] === "\r" && index + 1 < text.length && text[index + 1] === "\n") {
    return index + 2;
  }
  return index + 1;
}
function getLineAndColumnAtEnd(text) {
  let line6 = 1;
  let column = 0;
  for (let i = 0; i < text.length; i++) {
    const ch = text[i];
    if (ch === "\n") {
      line6++;
      column = 0;
      continue;
    }
    if (ch === "\r") {
      if (i + 1 < text.length && text[i + 1] === "\n") {
        i++;
      }
      line6++;
      column = 0;
      continue;
    }
    column++;
  }
  return { line: line6, column };
}
function getFrontMatter(text) {
  const startDelimiter = text.slice(0, DELIMITER_LENGTH);
  if (startDelimiter !== "---" && startDelimiter !== "+++") {
    return;
  }
  const firstLineBreakIndex = findLineBreakIndex(text, DELIMITER_LENGTH);
  if (firstLineBreakIndex === -1) {
    return;
  }
  const contentStartIndex = skipLineBreak(text, firstLineBreakIndex);
  const explicitLanguage = text.slice(DELIMITER_LENGTH, firstLineBreakIndex).trim();
  let language = explicitLanguage;
  if (!language) {
    language = startDelimiter === "+++" ? "toml" : "yaml";
  }
  const allowYamlAltDelimiter = startDelimiter === "---" && language === "yaml";
  let endDelimiterStartIndex = -1;
  let endDelimiterEndIndex = -1;
  let cursor = contentStartIndex;
  while (cursor <= text.length) {
    const lineBreakIndex = findLineBreakIndex(text, cursor);
    const lineEnd = lineBreakIndex === -1 ? text.length : lineBreakIndex;
    const line6 = text.slice(cursor, lineEnd);
    if (line6 === startDelimiter || allowYamlAltDelimiter && line6 === "...") {
      endDelimiterStartIndex = cursor;
      endDelimiterEndIndex = lineEnd;
      break;
    }
    if (lineBreakIndex === -1) {
      break;
    }
    cursor = skipLineBreak(text, lineBreakIndex);
  }
  if (endDelimiterStartIndex === -1 || endDelimiterEndIndex === -1) {
    return;
  }
  const frontMatterEndIndex = endDelimiterEndIndex;
  const raw = text.slice(0, frontMatterEndIndex);
  const endPosition = getLineAndColumnAtEnd(raw);
  const endDelimiter = text.slice(endDelimiterStartIndex, endDelimiterEndIndex);
  return {
    language,
    explicitLanguage: explicitLanguage || null,
    value: text.slice(contentStartIndex, endDelimiterStartIndex),
    startDelimiter,
    endDelimiter,
    raw,
    start: { line: 1, column: 0, index: 0 },
    end: {
      index: raw.length,
      line: endPosition.line,
      column: endPosition.column
    },
    [FRONT_MATTER_MARK]: true
  };
}
function parseFrontMatter(text) {
  const frontMatter = getFrontMatter(text);
  if (!frontMatter) {
    return { content: text };
  }
  return {
    frontMatter,
    content: replaceNonLineBreaksWithSpace(frontMatter.raw) + text.slice(frontMatter.raw.length)
  };
}

// src/line-offsets.ts
function buildLineOffsets(source) {
  const offsets = [0];
  for (let i = 0; i < source.length; i++) {
    if (source[i] === "\n") {
      offsets.push(i + 1);
      continue;
    }
    if (source[i] === "\r") {
      if (i + 1 < source.length && source[i + 1] === "\n") {
        i++;
      }
      offsets.push(i + 1);
    }
  }
  return offsets;
}
function getLine(offset, lineOffsets) {
  let lo = 0;
  let hi = lineOffsets.length - 1;
  while (lo < hi) {
    const mid = lo + hi + 1 >> 1;
    if (lineOffsets[mid] <= offset) {
      lo = mid;
    } else {
      hi = mid - 1;
    }
  }
  return lo;
}

// src/parser.ts
var INTERNAL_KINDS = /* @__PURE__ */ new Set([
  23 /* ElementName */,
  24 /* ClosingElementName */,
  19 /* Attribute */,
  20 /* JsxAttribute */,
  26 /* AttributeName */,
  27 /* AttributeValue */,
  25 /* AttributeWhitespace */
]);
var IGNORE_RANGES_OPTION = "__bladeIgnoreRanges";
function buildTokenLineNumbers(tokens, lineOffsets) {
  const startLines = [];
  const endLines = [];
  startLines.length = tokens.length;
  endLines.length = tokens.length;
  let line6 = 0;
  for (let i = 0; i < tokens.length; i++) {
    const token = tokens[i];
    while (line6 + 1 < lineOffsets.length && lineOffsets[line6 + 1] <= token.start) {
      line6++;
    }
    startLines[i] = line6;
    const endOffset = token.end > token.start ? token.end - 1 : token.end;
    while (line6 + 1 < lineOffsets.length && lineOffsets[line6 + 1] <= endOffset) {
      line6++;
    }
    endLines[i] = line6;
  }
  return { startLines, endLines };
}
function wrapTree(result) {
  const { nodes, tokens, source } = result;
  const wrapped = [];
  wrapped.length = nodes.length;
  const lineOffsets = buildLineOffsets(source);
  const tokenLines = buildTokenLineNumbers(tokens, lineOffsets);
  for (let i = 0; i < nodes.length; i++) {
    const flat = nodes[i];
    const [start, end] = nodeSourceRange(flat, tokens);
    let startLine = 0;
    let endLine = 0;
    if (flat.tokenCount > 0) {
      const firstTokenIdx = flat.tokenStart;
      const lastTokenIdx = flat.tokenStart + flat.tokenCount - 1;
      startLine = tokenLines.startLines[firstTokenIdx];
      endLine = tokenLines.endLines[lastTokenIdx];
    }
    wrapped[i] = {
      kind: flat.kind,
      flatIndex: i,
      flat,
      parent: null,
      children: [],
      source,
      start,
      end,
      rawText: shouldMaterializeRawText(flat.kind) ? ownTokenText(flat, tokens, source) : "",
      buildResult: result,
      attrs: [],
      tagName: "",
      rawTagName: "",
      rawClosingTagName: "",
      fullName: "",
      name: "",
      namespace: "",
      hasClosingTag: false,
      openTagEndOffset: 0,
      closingTagStartOffset: 0,
      startLine,
      endLine,
      prev: null,
      next: null,
      isSelfClosing: false,
      hasHtmComponentClosingTag: false,
      condition: "",
      complete: true,
      conditionalStartIsRevealed: false,
      conditionalEndIsHidden: false,
      isIeConditionalStartComment: false,
      ieConditionalStartCondition: "",
      cssDisplay: "inline",
      isWhitespaceSensitive: false,
      isIndentationSensitive: false,
      isLeadingSpaceSensitive: false,
      isTrailingSpaceSensitive: false,
      isDanglingSpaceSensitive: false,
      hasLeadingSpaces: false,
      hasTrailingSpaces: false,
      hasDanglingSpaces: false
    };
  }
  for (let i = 0; i < nodes.length; i++) {
    const flat = nodes[i];
    let childIdx = flat.firstChild;
    while (childIdx !== NONE) {
      const child = wrapped[childIdx];
      child.parent = wrapped[i];
      if (child.kind !== "frontMatter" && INTERNAL_KINDS.has(child.kind)) {
        if (child.kind === 19 /* Attribute */ || child.kind === 20 /* JsxAttribute */) {
          if (wrapped[i].kind !== 1 /* Element */) {
            wrapped[i].children.push(child);
            childIdx = nodes[childIdx].nextSibling;
            continue;
          }
          wrapped[i].attrs.push(child);
        }
        if (child.kind === 23 /* ElementName */) {
          const raw = child.rawText;
          wrapped[i].rawTagName = raw;
          wrapped[i].fullName = raw;
          const colonIdx = raw.indexOf(":");
          if (colonIdx >= 0) {
            wrapped[i].namespace = raw.slice(0, colonIdx);
            wrapped[i].name = raw.slice(colonIdx + 1);
            wrapped[i].tagName = raw.slice(colonIdx + 1).toLowerCase();
          } else {
            wrapped[i].namespace = "";
            wrapped[i].name = raw;
            wrapped[i].tagName = raw.toLowerCase();
          }
        }
        if (child.kind === 24 /* ClosingElementName */) {
          wrapped[i].hasClosingTag = true;
          wrapped[i].rawClosingTagName = child.rawText;
        }
      } else {
        wrapped[i].children.push(child);
      }
      childIdx = nodes[childIdx].nextSibling;
    }
    if (flat.kind === 1 /* Element */ && flat.tokenCount > 0) {
      const tokenEnd = flat.tokenStart + flat.tokenCount;
      for (let j = flat.tokenStart; j < tokenEnd; j++) {
        if (tokens[j].type === 2 /* GreaterThan */) {
          wrapped[i].openTagEndOffset = tokens[j].end;
          break;
        }
      }
      if (wrapped[i].hasClosingTag) {
        for (let j = tokenEnd - 1; j > flat.tokenStart; j--) {
          if (tokens[j].type === 3 /* Slash */ && tokens[j - 1].type === 1 /* LessThan */) {
            wrapped[i].closingTagStartOffset = tokens[j - 1].start;
            break;
          }
        }
      }
    }
    if (flat.kind === 14 /* ConditionalComment */ && flat.tokenCount > 0) {
      const firstToken = tokens[flat.tokenStart];
      if (firstToken.type === 37 /* ConditionalCommentStart */) {
        const text = source.slice(firstToken.start, firstToken.end);
        wrapped[i].conditionalStartIsRevealed = text.endsWith("]><!-->");
        const match = text.match(/^<!--\[if\s*([^\]]*)\]>/);
        if (match) {
          wrapped[i].condition = match[1].trim().replace(/\s+/g, " ");
        }
        wrapped[i].openTagEndOffset = firstToken.end;
      }
      const lastToken = tokens[flat.tokenStart + flat.tokenCount - 1];
      const isComplete = lastToken.type === 38 /* ConditionalCommentEnd */;
      wrapped[i].complete = isComplete;
      if (isComplete) {
        const endText = source.slice(lastToken.start, lastToken.end);
        wrapped[i].conditionalEndIsHidden = endText.startsWith("<!--<![");
        wrapped[i].hasClosingTag = true;
        wrapped[i].closingTagStartOffset = lastToken.start;
      }
    }
    if (flat.kind === 12 /* Comment */) {
      const condition = parseIeConditionalStartCommentCondition(wrapped[i].rawText);
      if (condition !== null) {
        wrapped[i].isIeConditionalStartComment = true;
        wrapped[i].ieConditionalStartCondition = condition;
      }
    }
  }
  return wrapped[0];
}
function nodeSourceRange(node, tokens) {
  if (node.tokenCount === 0) return [0, 0];
  const first = tokens[node.tokenStart];
  const last = tokens[node.tokenStart + node.tokenCount - 1];
  return [first.start, last.end];
}
function ownTokenText(node, tokens, source) {
  if (node.tokenCount === 0) return "";
  const s = tokens[node.tokenStart];
  const e = tokens[node.tokenStart + node.tokenCount - 1];
  return source.slice(s.start, e.end);
}
function shouldMaterializeRawText(kind) {
  switch (kind) {
    case 2 /* Text */:
    case 12 /* Comment */:
    case 13 /* BogusComment */:
    case 15 /* BladeComment */:
    case 29 /* IgnoreRange */:
    case 16 /* Doctype */:
    case 23 /* ElementName */:
    case 24 /* ClosingElementName */:
      return true;
    default:
      return false;
  }
}
function parseCommentValue(rawText) {
  const match = rawText.match(/^<!--([\s\S]*?)-->$/);
  return match ? match[1] : null;
}
function parseIeConditionalStartCommentCondition(rawText) {
  const value = parseCommentValue(rawText);
  if (value === null) return null;
  const match = value.match(/^\[if([^\]]*)\]><!$/s);
  if (!match) return null;
  return match[1].trim().replace(/\s+/g, " ");
}
function prependFrontMatterNode(root, source, frontMatter) {
  const lineOffsets = buildLineOffsets(source);
  const endLine = getLine(Math.max(frontMatter.end.index - 1, 0), lineOffsets);
  const frontMatterNode = {
    kind: "frontMatter",
    flatIndex: -1,
    flat: root.flat,
    parent: root,
    children: [],
    source,
    start: frontMatter.start.index,
    end: frontMatter.end.index,
    rawText: frontMatter.raw,
    raw: frontMatter.raw,
    value: frontMatter.value,
    language: frontMatter.language,
    explicitLanguage: frontMatter.explicitLanguage,
    startDelimiter: frontMatter.startDelimiter,
    endDelimiter: frontMatter.endDelimiter,
    buildResult: root.buildResult,
    attrs: [],
    tagName: "",
    rawTagName: "",
    rawClosingTagName: "",
    fullName: "",
    name: "",
    namespace: "",
    hasClosingTag: false,
    openTagEndOffset: 0,
    closingTagStartOffset: 0,
    startLine: 0,
    endLine,
    prev: null,
    next: null,
    isSelfClosing: true,
    hasHtmComponentClosingTag: false,
    condition: "",
    complete: true,
    conditionalStartIsRevealed: false,
    conditionalEndIsHidden: false,
    isIeConditionalStartComment: false,
    ieConditionalStartCondition: "",
    cssDisplay: "inline",
    isWhitespaceSensitive: false,
    isIndentationSensitive: false,
    isLeadingSpaceSensitive: false,
    isTrailingSpaceSensitive: false,
    isDanglingSpaceSensitive: false,
    hasLeadingSpaces: false,
    hasTrailingSpaces: false,
    hasDanglingSpaces: false
  };
  markFrontMatter(frontMatterNode);
  root.children.unshift(frontMatterNode);
}
function parse(text, options2) {
  const { frontMatter, content } = parseFrontMatter(text);
  const syntaxProfile = resolveBladeSyntaxProfile(options2);
  const lexerDirectives = Directives.acceptAll();
  const parserOptions = options2 ?? {};
  const ignoreRanges = parserOptions[IGNORE_RANGES_OPTION] ?? collectIgnoreRanges(content, lexerDirectives, {
    verbatimStartDirectives: syntaxProfile.verbatimStartDirectives,
    verbatimEndDirectives: syntaxProfile.verbatimEndDirectives
  });
  const { tokens } = tokenize(content, lexerDirectives, {
    verbatimStartDirectives: syntaxProfile.verbatimStartDirectives,
    verbatimEndDirectives: syntaxProfile.verbatimEndDirectives,
    ignoreRanges
  });
  const directives = Directives3.withDefaults(syntaxProfile.treeDirectives);
  directives.train(tokens, content);
  const result = buildTree(tokens, content, directives);
  result.ignoreRanges = ignoreRanges;
  const root = wrapTree(result);
  if (frontMatter) {
    prependFrontMatterNode(root, text, frontMatter);
  }
  return root;
}
function preprocess(text, options2) {
  const { content } = parseFrontMatter(text);
  const syntaxProfile = resolveBladeSyntaxProfile(options2);
  const lexerDirectives = Directives.acceptAll();
  const parserOptions = options2 ?? {};
  parserOptions[IGNORE_RANGES_OPTION] = collectIgnoreRanges(content, lexerDirectives, {
    verbatimStartDirectives: syntaxProfile.verbatimStartDirectives,
    verbatimEndDirectives: syntaxProfile.verbatimEndDirectives
  });
  return text;
}
var bladeParser = {
  parse,
  preprocess,
  hasPragma,
  astFormat: "blade-ast",
  locStart: (node) => node.start,
  locEnd: (node) => node.end
};

// src/print/index.ts
var import_prettier16 = require("prettier");

// src/html-whitespace.ts
var HTML_WS_BOTH = /^[\t\n\f\r ]+|[\t\n\f\r ]+$/g;
var HTML_WS_START = /^[\t\n\f\r ]+/;
var HTML_WS_END = /[\t\n\f\r ]+$/;
var HTML_WS_CHAR = /[\t\n\f\r ]/;
function htmlTrim(s) {
  return s.replace(HTML_WS_BOTH, "");
}
function htmlTrimStart(s) {
  return s.replace(HTML_WS_START, "");
}
function htmlTrimEnd(s) {
  return s.replace(HTML_WS_END, "");
}
function hasHtmlWhitespaceCharacter(s) {
  return HTML_WS_CHAR.test(s);
}

// src/preprocess/pipeline.ts
function getNodeKindName(node) {
  return typeof node.kind === "number" ? nodeKindLabel(node.kind) : node.kind;
}
function assertParentLinks(node) {
  for (const child of node.children) {
    if (child.parent !== node) {
      throw new Error(
        `Invalid parent link: child ${getNodeKindName(child)} does not point to parent ${getNodeKindName(node)}`
      );
    }
    assertParentLinks(child);
  }
}
function assertSiblingLinks(node) {
  for (let i = 0; i < node.children.length; i++) {
    const child = node.children[i];
    const expectedPrev = i > 0 ? node.children[i - 1] : null;
    const expectedNext = i < node.children.length - 1 ? node.children[i + 1] : null;
    if (child.prev !== expectedPrev || child.next !== expectedNext) {
      throw new Error(
        `Invalid sibling links on ${getNodeKindName(child)} under ${getNodeKindName(node)}`
      );
    }
    assertSiblingLinks(child);
  }
}
function runPreprocessStage(ast, stage, options2) {
  stage.run();
  if (!options2.validateStages) {
    return;
  }
  try {
    if (stage.validateParents) {
      assertParentLinks(ast);
    }
    if (stage.validateSiblings) {
      assertSiblingLinks(ast);
    }
  } catch (error) {
    const message = error instanceof Error ? error.message : "unknown preprocess failure";
    throw new Error(`[preprocess:${stage.name}] ${message}`);
  }
}
function executePreprocessStages(ast, stages, { validateStages = false } = {}) {
  for (const stage of stages) {
    runPreprocessStage(ast, stage, { validateStages });
  }
}

// src/preprocess/whitespace-model.ts
function isBlockLikeCssDisplay(display) {
  return display === "block" || display === "list-item" || display.startsWith("table");
}
function isFirstChildLeadingSpaceSensitiveCssDisplay(display) {
  return !isBlockLikeCssDisplay(display) && display !== "inline-block";
}
function isLastChildTrailingSpaceSensitiveCssDisplay(display) {
  return !isBlockLikeCssDisplay(display) && display !== "inline-block";
}
function isNextLeadingSpaceSensitiveCssDisplay(display) {
  return !isBlockLikeCssDisplay(display);
}
function isPrevTrailingSpaceSensitiveCssDisplay(display) {
  return !isBlockLikeCssDisplay(display);
}

// src/constants.ts
var CSS_DISPLAY_TAGS = {
  // hidden
  area: "none",
  base: "none",
  basefont: "none",
  datalist: "none",
  head: "none",
  link: "none",
  meta: "none",
  noembed: "none",
  noframes: "none",
  param: "block",
  rp: "none",
  title: "none",
  // block-like but need visibility
  script: "block",
  style: "block",
  // explicit inline
  template: "inline",
  // block
  address: "block",
  article: "block",
  aside: "block",
  blockquote: "block",
  body: "block",
  center: "block",
  dd: "block",
  details: "block",
  dialog: "block",
  dir: "block",
  div: "block",
  dl: "block",
  dt: "block",
  fieldset: "block",
  figcaption: "block",
  figure: "block",
  footer: "block",
  form: "block",
  h1: "block",
  h2: "block",
  h3: "block",
  h4: "block",
  h5: "block",
  h6: "block",
  header: "block",
  hgroup: "block",
  hr: "block",
  html: "block",
  legend: "block",
  li: "block",
  listing: "block",
  main: "block",
  marquee: "inline-block",
  menu: "block",
  nav: "block",
  ol: "block",
  optgroup: "block",
  option: "block",
  p: "block",
  plaintext: "block",
  pre: "block",
  search: "block",
  section: "block",
  source: "block",
  summary: "block",
  table: "table",
  track: "block",
  ul: "block",
  xmp: "block",
  // table
  caption: "table-caption",
  tr: "table-row",
  td: "table-cell",
  th: "table-cell",
  thead: "table-header-group",
  tbody: "table-row-group",
  tfoot: "table-footer-group",
  col: "table-column",
  colgroup: "table-column-group",
  // inline-block
  button: "inline-block",
  meter: "inline-block",
  progress: "inline-block",
  select: "inline-block",
  textarea: "inline-block",
  video: "inline-block",
  audio: "inline-block",
  object: "inline-block",
  // ruby
  ruby: "ruby",
  rt: "ruby-text",
  svg: "inline-block"
};
var CSS_DISPLAY_DEFAULT = "inline";
var CSS_WHITE_SPACE_TAGS = {
  listing: "pre",
  plaintext: "pre",
  pre: "pre",
  xmp: "pre",
  nobr: "nowrap",
  table: "initial",
  textarea: "pre-wrap",
  td: "normal",
  th: "normal"
};
var CSS_WHITE_SPACE_DEFAULT = "normal";

// src/node-predicates.ts
var VUE_ROOT_ELEMENTS = /* @__PURE__ */ new Set(["template", "style", "script"]);
function hasParent(node, predicate) {
  let current = node;
  while (current) {
    if (predicate(current)) return true;
    current = current.parent;
  }
  return false;
}
function isUnknownNamespace(node) {
  const namespace = node.namespace.toLowerCase();
  const hasExplicitNamespace = node.fullName.includes(":");
  return node.kind === 1 /* Element */ && !hasExplicitNamespace && namespace !== "" && !["html", "svg"].includes(namespace);
}
function isEchoLike(node) {
  return node.kind === 4 /* Echo */ || node.kind === 5 /* RawEcho */ || node.kind === 6 /* TripleEcho */;
}
function isTextLikeNode(node) {
  if (node.kind === 12 /* Comment */) {
    return !node.isIeConditionalStartComment;
  }
  return node.kind === 2 /* Text */ || node.kind === 17 /* Cdata */ || node.kind === 13 /* BogusComment */ || node.kind === 21 /* UnpairedClosingTag */ || isEchoLike(node);
}
function isWhitespaceTextLikeNode(node) {
  return node.kind === 2 /* Text */ || isEchoLike(node);
}
function isVueSfcBlock(node, options2) {
  return options2.parser === "vue" && node.kind === 1 /* Element */ && node.parent?.kind === 0 /* Root */ && node.fullName.toLowerCase() !== "html";
}
function isVueCustomBlock(node, options2) {
  return isVueSfcBlock(node, options2) && !VUE_ROOT_ELEMENTS.has(node.fullName);
}
function isVueNonHtmlBlock(node, options2) {
  return isVueSfcBlock(node, options2) && isVueCustomBlock(node, options2);
}
function isScriptLikeTag(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  const full = node.fullName.toLowerCase();
  return full === "script" || full === "style" || full === "svg:style" || full === "svg:script" || (node.namespace === "svg" || node.parent?.namespace === "svg") && (node.tagName === "script" || node.tagName === "style") || full === "mj-style" && options2?.parser === "mjml" || isUnknownNamespace(node) && (node.tagName === "script" || node.tagName === "style");
}

// src/preprocess.ts
function isWhitespaceOnlyText(node) {
  return node.kind === 2 /* Text */ && /^[\t\n\f\r ]*$/.test(node.rawText);
}
function getPrevNonWhitespaceSibling(node) {
  let sibling = node.prev;
  while (sibling) {
    if (!isWhitespaceOnlyText(sibling)) return sibling;
    sibling = sibling.prev;
  }
  return null;
}
function isBladeSlotElement(node) {
  if (node.kind !== 1 /* Element */) return false;
  return /^x-slot(?::|\[|$)/iu.test(node.fullName);
}
function getCssDisplay(node, options2) {
  if (isVueSfcBlock(node, options2)) return "block";
  if (isBladeSlotElement(node)) return "block";
  const prevSibling = getPrevNonWhitespaceSibling(node);
  if (prevSibling?.kind === 12 /* Comment */) {
    const match = prevSibling.rawText.match(/^<!--\s*display:\s*([a-z]+)\s*-->$/);
    if (match) return match[1];
  }
  if (node.kind === 1 /* Element */ && node.namespace === "svg") {
    if (hasParent(
      node,
      (parent) => parent.kind === 1 /* Element */ && parent.namespace === "svg" && parent.tagName === "foreignobject"
    )) {
    } else {
      return node.tagName === "svg" ? "inline-block" : "block";
    }
  }
  const wsSensitivity = options2.htmlWhitespaceSensitivity;
  const lowerName = node.tagName;
  switch (wsSensitivity) {
    case "strict":
      return "inline";
    case "ignore":
      return "block";
    default:
      if (node.kind === 1 /* Element */ && (!node.namespace || hasParent(
        node,
        (parent) => parent.kind === 1 /* Element */ && parent.namespace === "svg" && parent.tagName === "foreignobject"
      ) || isUnknownNamespace(node)) && lowerName in CSS_DISPLAY_TAGS) {
        return CSS_DISPLAY_TAGS[lowerName];
      }
  }
  if (node.kind === 8 /* DirectiveBlock */) return "block";
  if (node.kind === 0 /* Root */) return "block";
  return CSS_DISPLAY_DEFAULT;
}
function getCssWhiteSpace(node) {
  if (node.kind === 1 /* Element */ && (!node.namespace || isUnknownNamespace(node))) {
    const lowerName = node.tagName;
    if (lowerName in CSS_WHITE_SPACE_TAGS) {
      return CSS_WHITE_SPACE_TAGS[lowerName];
    }
  }
  return CSS_WHITE_SPACE_DEFAULT;
}
function isPreLikeNode(node) {
  return getCssWhiteSpace(node).startsWith("pre");
}
function isFrontMatterNode(node) {
  return hasFrontMatterMark(node);
}
function addImplicitNamespaces(node, inheritedNamespace = "") {
  let childNamespace = inheritedNamespace;
  if (node.kind === 1 /* Element */) {
    if (!node.fullName.includes(":")) {
      if (node.tagName === "svg") {
        node.namespace = "svg";
      } else if (inheritedNamespace === "svg" && node.parent?.kind === 1 /* Element */ && node.parent.tagName !== "foreignobject") {
        node.namespace = "svg";
      } else if (inheritedNamespace === "svg" && node.parent?.kind === 1 /* Element */ && node.parent.tagName === "foreignobject") {
        node.namespace = "";
      }
    }
    childNamespace = node.namespace;
    if (node.namespace === "svg" && node.tagName === "foreignobject") {
      childNamespace = "";
    }
  }
  for (const child of node.children) {
    addImplicitNamespaces(child, childNamespace);
  }
}
var isTextLikeNode2 = isWhitespaceTextLikeNode;
var IGNORE_FIRST_LF_TAGS = /* @__PURE__ */ new Set(["pre", "textarea", "listing"]);
function removeIgnorableFirstLf(node) {
  if (node.kind === 1 /* Element */ && IGNORE_FIRST_LF_TAGS.has(node.fullName.toLowerCase()) && node.children.length > 0 && node.children[0].kind === 2 /* Text */ && node.children[0].rawText[0] === "\n") {
    const text = node.children[0];
    if (text.rawText.length === 1) {
      node.children.splice(0, 1);
    } else {
      text.rawText = text.rawText.slice(1);
      text.start += 1;
    }
  }
  for (const child of node.children) {
    removeIgnorableFirstLf(child);
  }
}
function addCssDisplay(node, options2) {
  node.cssDisplay = getCssDisplay(node, options2);
  for (const child of node.children) {
    addCssDisplay(child, options2);
  }
}
function addWhitespaceFlags(node, options2) {
  node.isWhitespaceSensitive = isScriptLikeTag(node, options2) || isEchoLike(node) || isPreLikeNode(node);
  node.isIndentationSensitive = isPreLikeNode(node);
  for (const child of node.children) {
    addWhitespaceFlags(child, options2);
  }
}
function addSiblings(node) {
  for (let i = 0; i < node.children.length; i++) {
    node.children[i].prev = i > 0 ? node.children[i - 1] : null;
    node.children[i].next = i < node.children.length - 1 ? node.children[i + 1] : null;
  }
  for (const child of node.children) {
    addSiblings(child);
  }
}
function extractWhitespace(node, lineOffsets) {
  const children = node.children;
  if (children.length === 0) {
    return;
  }
  if (children.length === 1 && children[0].kind === 2 /* Text */ && htmlTrim(children[0].rawText).length === 0) {
    node.hasDanglingSpaces = children[0].rawText.length > 0;
    children.splice(0, 1);
    return;
  }
  if (node.isWhitespaceSensitive) return;
  for (let i = children.length - 1; i >= 0; i--) {
    const child = children[i];
    if (child.kind !== 2 /* Text */) continue;
    const text = child.rawText;
    const trimmed = htmlTrim(text);
    if (!trimmed) {
      const prev = children[i - 1];
      const next = children[i + 1];
      if (prev) prev.hasTrailingSpaces = true;
      if (next) next.hasLeadingSpaces = true;
      if (!prev && !next) {
        node.hasDanglingSpaces = true;
      }
      children.splice(i, 1);
      continue;
    }
    const leadingLen = text.length - htmlTrimStart(text).length;
    const trailingLen = text.length - htmlTrimEnd(text).length;
    if (leadingLen > 0) {
      child.hasLeadingSpaces = true;
      const prev = children[i - 1];
      if (prev) prev.hasTrailingSpaces = true;
    }
    if (trailingLen > 0) {
      child.hasTrailingSpaces = true;
      const next = children[i + 1];
      if (next) next.hasLeadingSpaces = true;
    }
    child.rawText = trimmed;
    const contentStart = child.start + leadingLen;
    const contentEnd = child.end - trailingLen;
    child.startLine = getLine(contentStart, lineOffsets);
    child.endLine = getLine(contentEnd > 0 ? contentEnd - 1 : 0, lineOffsets);
  }
  for (const child of children) {
    extractWhitespace(child, lineOffsets);
  }
}
function addSpaceSensitivity(node, options2) {
  const children = node.children;
  if (children.length === 0) {
    node.isDanglingSpaceSensitive = isDanglingSpaceSensitive(node);
    return;
  }
  for (const child of children) {
    child.isLeadingSpaceSensitive = isLeadingSpaceSensitive(child, options2);
    child.isTrailingSpaceSensitive = isTrailingSpaceSensitive(child, options2);
  }
  for (let i = 0; i < children.length; i++) {
    const child = children[i];
    if (i > 0) {
      child.isLeadingSpaceSensitive = children[i - 1].isTrailingSpaceSensitive && child.isLeadingSpaceSensitive;
    }
    if (i < children.length - 1) {
      child.isTrailingSpaceSensitive = children[i + 1].isLeadingSpaceSensitive && child.isTrailingSpaceSensitive;
    }
  }
  for (const child of children) {
    addSpaceSensitivity(child, options2);
  }
}
function isLeadingSpaceSensitive(node, options2) {
  const result = _isLeadingSpaceSensitive(node, options2);
  if (result && !node.prev && node.parent && IGNORE_FIRST_LF_TAGS.has(node.parent.fullName.toLowerCase())) {
    return isEchoLike(node);
  }
  return result;
}
function _isLeadingSpaceSensitive(node, options2) {
  if (isFrontMatterNode(node)) return false;
  if (node.kind === 8 /* DirectiveBlock */) return false;
  const parent = node.parent;
  const prev = node.prev;
  if ((isTextLikeNode2(node) || isEchoLike(node)) && prev && (isTextLikeNode2(prev) || isEchoLike(prev))) {
    return true;
  }
  if (!parent || parent.cssDisplay === "none") return false;
  if (isPreLikeNode(parent)) return true;
  if (!prev) {
    if (parent.kind === 0 /* Root */ || isPreLikeNode(node) && parent || isScriptLikeTag(parent, options2) || isVueCustomBlock(parent, options2) || !isFirstChildLeadingSpaceSensitiveCssDisplay(parent.cssDisplay)) {
      return false;
    }
    return true;
  }
  if (!isNextLeadingSpaceSensitiveCssDisplay(prev.cssDisplay)) {
    return false;
  }
  return true;
}
function isTrailingSpaceSensitive(node, options2) {
  if (isFrontMatterNode(node)) return false;
  if (node.kind === 8 /* DirectiveBlock */) return false;
  const parent = node.parent;
  const next = node.next;
  if ((isTextLikeNode2(node) || isEchoLike(node)) && next && (isTextLikeNode2(next) || isEchoLike(next))) {
    return true;
  }
  if (!parent || parent.cssDisplay === "none") return false;
  if (isPreLikeNode(parent)) return true;
  if (!next) {
    if (parent.kind === 0 /* Root */ || isPreLikeNode(node) && parent || isScriptLikeTag(parent, options2) || isVueCustomBlock(parent, options2) || !isLastChildTrailingSpaceSensitiveCssDisplay(parent.cssDisplay)) {
      return false;
    }
    return true;
  }
  if (!isPrevTrailingSpaceSensitiveCssDisplay(next.cssDisplay)) {
    return false;
  }
  return true;
}
function isDanglingSpaceSensitive(node) {
  return !isBlockLikeCssDisplay(node.cssDisplay) && node.cssDisplay !== "inline-block" && !isScriptLikeTag(node);
}
function addIsSelfClosing(node) {
  if (node.kind === 1 /* Element */) {
    node.isSelfClosing = // HTML void element (br, img, input, etc.)
    VOID_ELEMENTS.has(node.fullName.toLowerCase()) || // Self-closing slash (stored in flat.data)
    node.flat.data === 1;
  } else {
    node.isSelfClosing = node.children.length === 0;
  }
  for (const child of node.children) {
    addIsSelfClosing(child);
  }
}
function addHasHtmComponentClosingTag(node) {
  if (node.kind === 1 /* Element */ && node.hasClosingTag) {
    const closingStart = node.source.lastIndexOf("</", node.end);
    if (closingStart >= 0) {
      const closingText = node.source.slice(closingStart, node.end);
      node.hasHtmComponentClosingTag = /^<\s*\/\s*\/\s*>$/.test(closingText);
    }
  }
  for (const child of node.children) {
    addHasHtmComponentClosingTag(child);
  }
}
function mergeSimpleElementIntoText(node) {
  const children = node.children;
  for (let i = 0; i < children.length; i++) {
    const child = children[i];
    if (child.kind !== 1 /* Element */) {
      mergeSimpleElementIntoText(child);
      continue;
    }
    const prev = i > 0 ? children[i - 1] : null;
    const next = i < children.length - 1 ? children[i + 1] : null;
    const firstChild = child.children[0];
    const isSimpleElement = child.attrs.length === 0 && child.children.length === 1 && firstChild.kind === 2 /* Text */ && !hasHtmlWhitespaceCharacter(firstChild.rawText) && !firstChild.hasLeadingSpaces && !firstChild.hasTrailingSpaces && child.isLeadingSpaceSensitive && !child.hasLeadingSpaces && child.isTrailingSpaceSensitive && !child.hasTrailingSpaces && prev?.kind === 2 /* Text */ && next?.kind === 2 /* Text */;
    if (!isSimpleElement) {
      mergeSimpleElementIntoText(child);
      continue;
    }
    prev.rawText += `<${child.rawTagName}>` + firstChild.rawText + `</${child.rawTagName}>` + next.rawText;
    prev.end = next.end;
    prev.endLine = next.endLine;
    prev.isTrailingSpaceSensitive = next.isTrailingSpaceSensitive;
    prev.hasTrailingSpaces = next.hasTrailingSpaces;
    children.splice(i, 2);
    i--;
  }
}
var VALIDATE_PREPROCESS_STAGES = typeof process !== "undefined" && process.env.FORTE_VALIDATE_PREPROCESS === "1";
function preprocess2(ast, options2) {
  const lineOffsets = buildLineOffsets(ast.source);
  const stages = [
    {
      name: "removeIgnorableFirstLf",
      run: () => removeIgnorableFirstLf(ast),
      validateParents: true
    },
    {
      name: "mergeIfConditionalStartEndCommentIntoElementOpeningTag",
      run: () => mergeIfConditionalStartEndCommentIntoElementOpeningTag(ast),
      validateParents: true
    },
    {
      name: "addImplicitNamespaces",
      run: () => addImplicitNamespaces(ast),
      validateParents: true
    },
    {
      name: "addSiblings:initial",
      run: () => addSiblings(ast),
      validateSiblings: true
    },
    {
      name: "addCssDisplay",
      run: () => addCssDisplay(ast, options2)
    },
    {
      name: "addIsSelfClosing",
      run: () => addIsSelfClosing(ast)
    },
    {
      name: "addHasHtmComponentClosingTag",
      run: () => addHasHtmComponentClosingTag(ast)
    },
    {
      name: "addWhitespaceFlags",
      run: () => addWhitespaceFlags(ast, options2)
    },
    {
      name: "extractWhitespace",
      run: () => extractWhitespace(ast, lineOffsets),
      validateParents: true
    },
    {
      name: "addSiblings:postExtractWhitespace",
      run: () => addSiblings(ast),
      validateSiblings: true
    },
    {
      name: "addSpaceSensitivity",
      run: () => addSpaceSensitivity(ast, options2)
    },
    {
      name: "mergeSimpleElementIntoText",
      run: () => mergeSimpleElementIntoText(ast),
      validateParents: true
    },
    {
      name: "addSiblings:postMergeSimpleElementIntoText",
      run: () => addSiblings(ast),
      validateSiblings: true
    },
    {
      name: "promoteOpeningTagChildrenToAttrs",
      run: () => promoteOpeningTagChildrenToAttrs(ast),
      validateParents: true
    },
    {
      name: "addSiblings:postPromoteOpeningTagChildrenToAttrs",
      run: () => addSiblings(ast),
      validateSiblings: true
    }
  ];
  executePreprocessStages(ast, stages, {
    validateStages: VALIDATE_PREPROCESS_STAGES
  });
  return ast;
}
function isOpeningTagContextChild(parent, child) {
  if (parent.kind !== 1 /* Element */) return false;
  if (parent.openTagEndOffset <= 0) return false;
  return child.start >= parent.start && child.start < parent.openTagEndOffset && child.end <= parent.openTagEndOffset;
}
function promoteOpeningTagChildrenToAttrs(node) {
  for (const child of node.children) {
    promoteOpeningTagChildrenToAttrs(child);
  }
  if (node.kind !== 1 /* Element */) {
    return;
  }
  if (node.children.length === 0) {
    return;
  }
  const moved = [];
  const retained = [];
  for (const child of node.children) {
    if (isOpeningTagContextChild(node, child)) {
      child.prev = null;
      child.next = null;
      child.isLeadingSpaceSensitive = false;
      child.isTrailingSpaceSensitive = false;
      child.hasLeadingSpaces = false;
      child.hasTrailingSpaces = false;
      moved.push(child);
    } else {
      retained.push(child);
    }
  }
  if (moved.length === 0) {
    return;
  }
  node.children = retained;
  node.attrs = [...node.attrs, ...moved].sort(
    (a, b) => a.start === b.start ? a.end - b.end : a.start - b.start
  );
}
function mergeIfConditionalStartEndCommentIntoElementOpeningTag(node) {
  if (node.children.length === 0) {
    return;
  }
  for (let i = 0; i < node.children.length; i++) {
    const child = node.children[i];
    if (child.kind !== 1 /* Element */) {
      mergeIfConditionalStartEndCommentIntoElementOpeningTag(child);
      continue;
    }
    const prev = i > 0 ? node.children[i - 1] : null;
    const firstChild = child.children[0];
    const condition = prev ? parseIeConditionalStartComment(prev) : null;
    const canMerge = !!condition && prev !== null && prev.end === child.start && !!firstChild && firstChild.kind === 12 /* Comment */ && firstChild.start === child.openTagEndOffset && isIeConditionalEndComment(firstChild);
    if (!canMerge) {
      mergeIfConditionalStartEndCommentIntoElementOpeningTag(child);
      continue;
    }
    child.condition = condition;
    child.start = prev.start;
    child.startLine = prev.startLine;
    child.openTagEndOffset = firstChild.end;
    node.children.splice(i - 1, 1);
    i--;
    child.children.splice(0, 1);
    mergeIfConditionalStartEndCommentIntoElementOpeningTag(child);
  }
}
function parseCommentValue2(node) {
  if (node.kind !== 12 /* Comment */) return null;
  const match = node.rawText.match(/^<!--([\s\S]*?)-->$/);
  return match ? match[1] : null;
}
function parseIeConditionalStartComment(node) {
  const value = parseCommentValue2(node);
  if (!value) return null;
  const match = value.match(/^\[if([^\]]*)\]><!$/s);
  if (!match) return null;
  return match[1].trim().replace(/\s+/g, " ");
}
function isIeConditionalEndComment(node) {
  const value = parseCommentValue2(node);
  return !!value && /^<!\s*\[endif\]$/s.test(value);
}

// src/html-data.ts
var import_html_tags = require("@prettier/html-tags");
var import_html_element_attributes = require("html-element-attributes");
var HTML_TAGS = new Set(import_html_tags.htmlTags);
var HTML_ELEMENT_ATTRIBUTES = new Map(
  Object.entries(import_html_element_attributes.htmlElementAttributes).map(([tagName, attributes]) => [
    tagName,
    new Set(attributes)
  ])
);

// src/print/blade-syntax.ts
var CSS_AT_RULES = /* @__PURE__ */ new Set([
  "charset",
  "import",
  "namespace",
  "media",
  "supports",
  "layer",
  "container",
  "scope",
  "font-face",
  "font-feature-values",
  "font-palette-values",
  "property",
  "counter-style",
  "keyframes",
  "-webkit-keyframes",
  "-moz-keyframes",
  "-o-keyframes",
  "page",
  "starting-style",
  "view-transition",
  "document",
  "custom-media",
  "tailwind",
  "apply",
  "screen",
  "responsive",
  "variants",
  "utility",
  "theme",
  "plugin",
  "config",
  "use",
  "forward",
  "mixin",
  "include",
  "function",
  "return",
  "if",
  "else",
  "for",
  "each",
  "while",
  "at-root",
  "extend",
  "debug",
  "warn",
  "error"
]);
function extractDirectiveName2(text) {
  const trimmed = text.trimStart();
  if (!trimmed.startsWith("@")) return null;
  let i = 1;
  if (i >= trimmed.length) return null;
  const first = trimmed.charCodeAt(i);
  const startsWithAlphaOrUnderscore = first >= 65 && first <= 90 || first >= 97 && first <= 122 || first === 95;
  if (!startsWithAlphaOrUnderscore) return null;
  while (i < trimmed.length) {
    const code = trimmed.charCodeAt(i);
    const isAlphaNum = code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 95;
    if (!isAlphaNum) break;
    i++;
  }
  return trimmed.slice(1, i).toLowerCase();
}
function hasPhpLikeMarkers(text) {
  const hasCallWithLiteralArgs = /@[A-Za-z_][A-Za-z0-9_]*\s*\(\s*['"`[]/u.test(text);
  let hasNamedArgs = false;
  const openParen = text.indexOf("(");
  const closeParen = text.lastIndexOf(")");
  if (openParen >= 0 && closeParen > openParen) {
    const args = text.slice(openParen + 1, closeParen);
    hasNamedArgs = /(^|,)\s*[A-Za-z_][A-Za-z0-9_]*\s*:/u.test(args);
  }
  return text.includes("$") || text.includes("->") || text.includes("::") || text.includes("=>") || hasCallWithLiteralArgs || hasNamedArgs;
}
function isDirectiveNodeBladeLike(node, context) {
  const text = node.source.slice(node.start, node.end);
  const name = extractDirectiveName2(text);
  if (!name) return false;
  if (context === "style") {
    if (CSS_AT_RULES.has(name) || isFrontendEventStyleAtName(name)) {
      return hasPhpLikeMarkers(text);
    }
  } else if (isFrontendEventStyleAtName(name)) {
    return hasPhpLikeMarkers(text);
  }
  const trainedDirectives = node.buildResult.directives;
  if (trainedDirectives?.isDirective(name)) {
    return true;
  }
  return hasPhpLikeMarkers(text);
}
function isBladeConstructChild(node, context = "generic") {
  switch (node.kind) {
    case 4 /* Echo */:
    case 5 /* RawEcho */:
    case 6 /* TripleEcho */:
    case 11 /* PhpTag */:
    case 10 /* PhpBlock */:
    case 8 /* DirectiveBlock */:
    case 29 /* IgnoreRange */:
      return true;
    case 7 /* Directive */:
      return isDirectiveNodeBladeLike(node, context);
    default:
      return false;
  }
}
function elementContent(node) {
  if (node.openTagEndOffset > 0 && node.closingTagStartOffset > node.openTagEndOffset) {
    return node.source.slice(node.openTagEndOffset, node.closingTagStartOffset);
  }
  if (node.children.length === 0) return "";
  const start = node.children[0].start;
  const end = node.children[node.children.length - 1].end;
  if (end <= start) return "";
  return node.source.slice(start, end);
}
function parentContainsBladeSyntax(node, context = "generic") {
  if (node.kind !== 1 /* Element */) return false;
  if (node.children.some((child) => isBladeConstructChild(child, context))) {
    return true;
  }
  const content = elementContent(node);
  return content.includes("{{") || content.includes("{!!") || content.includes("{{{") || content.includes("<?php");
}

// src/print/utils.ts
var VALUE_CONSTRUCT_END = {
  [18 /* EchoStart */]: 19 /* EchoEnd */,
  [21 /* RawEchoStart */]: 22 /* RawEchoEnd */,
  [23 /* TripleEchoStart */]: 24 /* TripleEchoEnd */,
  [39 /* PhpTagStart */]: 40 /* PhpTagEnd */,
  [29 /* PhpBlockStart */]: 30 /* PhpBlockEnd */
};
function fullText(node) {
  return node.source.slice(node.start, node.end);
}
function isFrontMatterNode2(node) {
  return hasFrontMatterMark(node);
}
function isIeConditionalStartComment(node) {
  return node.kind === 12 /* Comment */ && node.isIeConditionalStartComment;
}
function isPreLikeNode2(node) {
  return node.isIndentationSensitive;
}
function getLastDescendant(node) {
  let current = node;
  while (current.children.length > 0) {
    current = current.children[current.children.length - 1];
  }
  return current;
}
function hasLeadingLineBreak(node) {
  if (!node.hasLeadingSpaces) return false;
  if (node.prev) return node.prev.endLine < node.startLine;
  if (!node.parent) return false;
  return node.parent.kind === 0 /* Root */ || node.parent.startLine < node.startLine;
}
function hasTrailingLineBreak(node) {
  if (!node.hasTrailingSpaces) return false;
  if (node.next) return node.next.startLine > node.endLine;
  if (!node.parent) return false;
  return node.parent.kind === 0 /* Root */ || node.parent.endLine > node.endLine;
}
function hasSurroundingLineBreak(node) {
  return hasLeadingLineBreak(node) && hasTrailingLineBreak(node);
}
function hasNonTextChild(node) {
  return node.children?.some((child) => child.kind !== 2 /* Text */ && !isEchoLike(child)) ?? false;
}
function forceBreakChildren(node) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.children.length === 0) return false;
  return ["html", "head", "ul", "ol", "select"].includes(node.tagName) || node.cssDisplay.startsWith("table") && node.cssDisplay !== "table-cell";
}
function forceBreakContent(node) {
  if (forceBreakChildren(node)) return true;
  if (node.kind !== 1 /* Element */) return false;
  if (node.children.length === 0) return false;
  if (isBladeSlotElement2(node)) return true;
  const firstChild = node.children[0];
  const lastChild = node.children[node.children.length - 1];
  return ["body", "script", "style"].includes(node.tagName) || node.children.some((child) => hasNonTextChild(child)) || // Single non-text/non-interpolation child with surrounding line breaks forces break.
  firstChild === lastChild && firstChild.kind !== 2 /* Text */ && !isEchoLike(firstChild) && hasLeadingLineBreak(firstChild) && (!lastChild.isTrailingSpaceSensitive || hasTrailingLineBreak(lastChild));
}
function isBladeSlotElement2(node) {
  if (node.kind !== 1 /* Element */) return false;
  const fullName = node.fullName.toLowerCase();
  return fullName === "x-slot" || fullName.startsWith("x-slot:") || fullName.startsWith("x-slot[") || fullName.startsWith("x-slot:[");
}
function preferHardlineAsSurroundingSpaces(node) {
  switch (node.kind) {
    case 12 /* Comment */:
    case 13 /* BogusComment */:
    case 15 /* BladeComment */:
    case 14 /* ConditionalComment */:
    case 7 /* Directive */:
    case 8 /* DirectiveBlock */:
      return true;
    case 1 /* Element */:
      return node.tagName === "script" || node.tagName === "select";
    default:
      return false;
  }
}
function preferHardlineAsLeadingSpaces(node) {
  return preferHardlineAsSurroundingSpaces(node) || !!node.prev && preferHardlineAsTrailingSpaces(node.prev) || hasSurroundingLineBreak(node);
}
function preferHardlineAsTrailingSpaces(node) {
  return preferHardlineAsSurroundingSpaces(node) || node.kind === 1 /* Element */ && node.tagName === "br" || hasSurroundingLineBreak(node);
}
function shouldPreserveContent(node, options2) {
  if (node.kind === 14 /* ConditionalComment */ && node.children.length > 0) {
    const lastChild = node.children[node.children.length - 1];
    if (!lastChild.isSelfClosing && !lastChild.hasClosingTag) {
      return true;
    }
  }
  if (node.kind === 14 /* ConditionalComment */ && !node.complete) {
    return true;
  }
  if (node.kind === 14 /* ConditionalComment */ && node.children.some((child) => child.kind === 21 /* UnpairedClosingTag */)) {
    return true;
  }
  if (isPreLikeNode2(node) && node.children.some((child) => child.kind !== 2 /* Text */ && !isEchoLike(child))) {
    return true;
  }
  if (node.kind === 1 /* Element */ && node.tagName === "style" && hasBladeLikeSyntaxInElementContent(node)) {
    return true;
  }
  if (options2 && isVueNonHtmlBlock(node, options2) && !isScriptLikeTag(node, options2) && !isEchoLike(node)) {
    return true;
  }
  return false;
}
function hasBladeLikeSyntaxInElementContent(node) {
  return parentContainsBladeSyntax(node, "style");
}
function htmlTrimLeadingBlankLines(s) {
  return s.replaceAll(/^[\t\f\r ]*\n/g, "");
}
function htmlTrimPreserveIndentation(s) {
  return htmlTrimLeadingBlankLines(s.replace(/[\t\n\f\r ]+$/, ""));
}
function dedentString(s) {
  const lines = s.split("\n");
  let minIndent = Infinity;
  for (const line6 of lines) {
    if (line6.trim().length === 0) continue;
    const indent7 = line6.match(/^[\t ]*/)?.[0].length ?? 0;
    if (indent7 < minIndent) minIndent = indent7;
  }
  if (minIndent === 0 || minIndent === Infinity) return s;
  return lines.map((line6) => line6.slice(minIndent)).join("\n");
}
function forceNextEmptyLine(node) {
  if (isFrontMatterNode2(node)) return true;
  return !!node.next && node.endLine + 1 < node.next.startLine;
}
var ignoredChildrenCache = /* @__PURE__ */ new WeakMap();
function hasPrettierIgnore(node) {
  if (node.kind === 19 /* Attribute */) return false;
  if (!node.parent) return false;
  const ignoredChildren = getIgnoredChildren(node.parent);
  return ignoredChildren.has(node);
}
function getPrettierIgnoreMode(node) {
  if (node.kind === 19 /* Attribute */) return null;
  if (!node.parent) return null;
  const ignoredChildren = getIgnoredChildren(node.parent);
  return ignoredChildren.get(node) ?? null;
}
function getIgnoredChildren(parent) {
  const cached = ignoredChildrenCache.get(parent);
  if (cached) return cached;
  const ignored = /* @__PURE__ */ new Map();
  let ignoreNextCount = 0;
  for (const child of parent.children) {
    const ignoreKind = getIgnoreCommentKind(child);
    if (ignoreNextCount > 0 && ignoreKind !== "ignore") {
      ignored.set(child, "single");
      ignoreNextCount--;
    }
    if (ignoreKind === "ignore") {
      ignoreNextCount = Math.max(ignoreNextCount, 1);
    }
  }
  ignoredChildrenCache.set(parent, ignored);
  return ignored;
}
function getIgnoreCommentKind(node) {
  if (node.kind === 12 /* Comment */) {
    return getIgnoreCommentKindFromCommentText(fullText(node), "html");
  }
  if (node.kind === 15 /* BladeComment */) {
    return getIgnoreCommentKindFromCommentText(fullText(node), "blade");
  }
  return null;
}
function getPrintableSubtreeEnd(node) {
  let end = node.end;
  const subtreeChildren = node.attrs.length === 0 ? node.children : node.children.length === 0 ? node.attrs : [...node.attrs, ...node.children].sort(
    (left, right) => left.start !== right.start ? left.start - right.start : left.end - right.end
  );
  for (const child of subtreeChildren) {
    end = Math.max(end, getPrintableSubtreeEnd(child));
  }
  return end;
}
function getChildPrintSegments(children) {
  return children.map((child, index) => ({
    startIndex: index,
    endIndex: index,
    first: child,
    last: child,
    sourceStart: child.start,
    sourceEnd: getPrintableSubtreeEnd(child)
  }));
}
function getAttributeNameRaw(node) {
  const br = node.buildResult;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  let start = -1;
  let end = -1;
  for (let i = tokenStart; i < tokenEnd; i++) {
    const token = br.tokens[i];
    if (token.type === 4 /* Equals */) break;
    if (start === -1) start = token.start;
    if (token.type !== 9 /* Whitespace */) end = token.end;
  }
  if (start === -1 || end === -1 || end < start) return "";
  return br.source.slice(start, end);
}
function isStaticAttributeName(node) {
  const br = node.buildResult;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  for (let i = tokenStart; i < tokenEnd; i++) {
    const tokenType = br.tokens[i].type;
    if (tokenType === 4 /* Equals */) break;
    if (tokenType === 18 /* EchoStart */ || tokenType === 21 /* RawEchoStart */ || tokenType === 23 /* TripleEchoStart */ || tokenType === 25 /* Directive */ || tokenType === 39 /* PhpTagStart */) {
      return false;
    }
  }
  return true;
}
function getStaticAttributeNameLower(node) {
  if (!isStaticAttributeName(node)) return null;
  const raw = getAttributeNameRaw(node);
  if (!raw) return null;
  return raw.toLowerCase();
}
function getAttributeNameParts(node) {
  const br = node.buildResult;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  const parts = [];
  for (let i = tokenStart; i < tokenEnd; i++) {
    const token = br.tokens[i];
    if (token.type === 18 /* EchoStart */ || token.type === 21 /* RawEchoStart */ || token.type === 23 /* TripleEchoStart */ || token.type === 39 /* PhpTagStart */ || token.type === 29 /* PhpBlockStart */) {
      const endType = token.type === 18 /* EchoStart */ ? 19 /* EchoEnd */ : token.type === 21 /* RawEchoStart */ ? 22 /* RawEchoEnd */ : token.type === 23 /* TripleEchoStart */ ? 24 /* TripleEchoEnd */ : token.type === 39 /* PhpTagStart */ ? 40 /* PhpTagEnd */ : 30 /* PhpBlockEnd */;
      const start = token.start;
      let end = token.end;
      i++;
      while (i < tokenEnd) {
        const current = br.tokens[i];
        end = current.end;
        if (current.type === endType) {
          break;
        }
        i++;
      }
      parts.push({
        kind: token.type === 18 /* EchoStart */ ? "echo" : token.type === 21 /* RawEchoStart */ ? "raw_echo" : token.type === 23 /* TripleEchoStart */ ? "triple_echo" : token.type === 39 /* PhpTagStart */ ? "php_tag" : "php_block",
        text: br.source.slice(start, end)
      });
      continue;
    }
    if (token.type === 4 /* Equals */) break;
    if (token.type === 9 /* Whitespace */) continue;
    if (token.type === 6 /* AttributeName */ || token.type === 34 /* BoundAttribute */ || token.type === 33 /* EscapedAttribute */ || token.type === 35 /* ShorthandAttribute */ || token.type === 0 /* Text */) {
      parts.push({
        kind: "text",
        text: br.source.slice(token.start, token.end)
      });
      continue;
    }
    if (token.type === 25 /* Directive */) {
      const start = token.start;
      let end = token.end;
      if (i + 1 < tokenEnd && br.tokens[i + 1].type === 26 /* DirectiveArgs */) {
        i++;
        end = br.tokens[i].end;
      }
      parts.push({ kind: "directive", text: br.source.slice(start, end) });
      continue;
    }
    parts.push({ kind: "text", text: br.source.slice(token.start, token.end) });
  }
  return parts;
}
function getAttributeValueRange(node) {
  const br = node.buildResult;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  let equalsIndex = -1;
  for (let i = tokenStart; i < tokenEnd; i++) {
    if (br.tokens[i].type === 4 /* Equals */) {
      equalsIndex = i;
      break;
    }
  }
  if (equalsIndex === -1) return null;
  let valueStart = equalsIndex + 1;
  while (valueStart < tokenEnd && br.tokens[valueStart].type === 9 /* Whitespace */) {
    valueStart++;
  }
  if (valueStart >= tokenEnd) {
    return {
      hasValue: true,
      start: valueStart,
      end: valueStart,
      quoted: false,
      quote: null
    };
  }
  const isQuoted = br.tokens[valueStart].type === 8 /* Quote */;
  if (!isQuoted) {
    return {
      hasValue: true,
      start: valueStart,
      end: tokenEnd,
      quoted: false,
      quote: null
    };
  }
  const quote = br.source.slice(br.tokens[valueStart].start, br.tokens[valueStart].end);
  let end = tokenEnd;
  if (end > valueStart + 1 && br.tokens[end - 1].type === 8 /* Quote */) {
    end--;
  }
  return {
    hasValue: true,
    start: valueStart + 1,
    end,
    quoted: true,
    quote
  };
}
function getAttributeRawValue(node) {
  const br = node.buildResult;
  const range = getAttributeValueRange(node);
  if (!range?.hasValue) return null;
  const { start: valueStart, end: valueEnd, quoted } = range;
  if (valueStart >= valueEnd) return "";
  let value = "";
  for (let i = valueStart; i < valueEnd; i++) {
    const token = br.tokens[i];
    if (quoted && token.type === 8 /* Quote */) {
      continue;
    }
    value += br.source.slice(token.start, token.end);
  }
  return value;
}
function getAttributeValueQuote(node) {
  const range = getAttributeValueRange(node);
  if (!range?.hasValue || !range.quoted) return null;
  return range.quote;
}
function getAttributeValueKind(node) {
  const br = node.buildResult;
  const range = getAttributeValueRange(node);
  if (!range?.hasValue) return "none";
  if (range.start >= range.end) return "static_text";
  let hasDynamic = false;
  let hasText = false;
  for (let i = range.start; i < range.end; i++) {
    const token = br.tokens[i];
    if (token.type === 48 /* JsxAttributeValue */) {
      hasDynamic = true;
      continue;
    }
    const endType = VALUE_CONSTRUCT_END[token.type];
    if (endType !== void 0) {
      hasDynamic = true;
      i++;
      while (i < range.end && br.tokens[i].type !== endType) {
        i++;
      }
      continue;
    }
    if (token.type === 25 /* Directive */) {
      hasDynamic = true;
      if (i + 1 < range.end && br.tokens[i + 1].type === 26 /* DirectiveArgs */) {
        i++;
      }
      continue;
    }
    const text = br.source.slice(token.start, token.end);
    if (text.includes("<?")) {
      hasDynamic = true;
      continue;
    }
    hasText = true;
  }
  if (!hasDynamic) return "static_text";
  return hasText ? "mixed_structured" : "pure_construct";
}
function isStaticAttributeValue(node) {
  return getAttributeValueKind(node) === "static_text";
}
function unescapeQuoteEntities(text) {
  return text.replaceAll("&apos;", "'").replaceAll("&quot;", '"');
}
function getUnescapedAttributeValue(node) {
  const raw = getAttributeRawValue(node);
  return raw ? unescapeQuoteEntities(raw) : "";
}
function getAttrMap(node) {
  const map = {};
  for (const attr of node.attrs) {
    if (!isStaticAttributeName(attr)) continue;
    const name = getAttributeNameRaw(attr);
    const value = getAttributeRawValue(attr);
    if (name) map[name.toLowerCase()] = value ?? "";
  }
  return map;
}
function inferElementParser(node, options2) {
  return inferScriptParser(node, options2) ?? inferStyleParser(node, options2);
}
function inferScriptParser(node, options2) {
  if (node.fullName.toLowerCase() !== "script") return;
  const attrMap = getAttrMap(node);
  if ("src" in attrMap) return;
  const { type, lang } = attrMap;
  if (!lang && !type) return "babel";
  return inferParserByLanguage(options2, lang) ?? inferParserByTypeAttribute(type);
}
function inferStyleParser(node, options2) {
  if (node.fullName.toLowerCase() !== "style") return;
  const { lang } = getAttrMap(node);
  if (lang) {
    return inferParserByLanguage(options2, lang);
  }
  return "css";
}
function inferParserByLanguage(options2, language) {
  if (!language) return;
  const plugins = options2.plugins ?? [];
  const languages2 = plugins.slice().reverse().flatMap((plugin2) => {
    const p = plugin2;
    return Array.isArray(p.languages) ? p.languages : [];
  });
  const matchedLanguage = languages2.find(({ name }) => typeof name === "string" && name.toLowerCase() === language) ?? languages2.find(({ aliases }) => Array.isArray(aliases) && aliases.includes(language)) ?? languages2.find(
    ({ extensions }) => Array.isArray(extensions) && extensions.includes(`.${language}`)
  );
  return matchedLanguage?.parsers?.[0];
}
var SCRIPT_TYPE_ATTRIBUTE_PARSER_MAP = {
  module: "babel",
  "text/javascript": "babel",
  "text/babel": "babel",
  "text/jsx": "babel",
  "application/javascript": "babel",
  "application/x-typescript": "typescript",
  "text/markdown": "markdown",
  "text/html": "html",
  "text/x-handlebars-template": "glimmer"
};
function inferParserByTypeAttribute(type) {
  if (!type) return;
  const explicitParser = SCRIPT_TYPE_ATTRIBUTE_PARSER_MAP[type];
  if (explicitParser) {
    return explicitParser;
  }
  if (type.endsWith("json") || type.endsWith("importmap") || type === "speculationrules") {
    return "json";
  }
  return;
}
function normalizeAttributeName(name, parentNode) {
  if (!parentNode || parentNode.kind !== 1 /* Element */) return name;
  if (name.includes(":")) return name;
  const lowerName = name.toLowerCase();
  const elementName = parentNode.tagName;
  if (HTML_ELEMENT_ATTRIBUTES.has(elementName) && (HTML_ELEMENT_ATTRIBUTES.get("*").has(lowerName) || HTML_ELEMENT_ATTRIBUTES.get(elementName).has(lowerName))) {
    return lowerName;
  }
  return name;
}

// src/print/element.ts
var import_prettier5 = require("prettier");

// src/print/blade-options.ts
var directiveCaseMapCache = /* @__PURE__ */ new WeakMap();
var directiveArgSpacingOverridesCache = /* @__PURE__ */ new WeakMap();
var inlineIntentElementsCache = /* @__PURE__ */ new WeakMap();
var bladeComponentPrefixesCache = /* @__PURE__ */ new WeakMap();
var DEFAULT_INLINE_INTENT_ELEMENTS = ["p", "svg", "svg:*"];
var DEFAULT_BLADE_COMPONENT_PREFIXES = [
  "x",
  "s",
  "statamic",
  "flux",
  "livewire",
  "native"
];
var DEFAULT_DIRECTIVE_ARG_SPACING_OVERRIDE_TOKENS = Object.freeze([
  "if",
  "elseif",
  "unless",
  "while",
  "for",
  "foreach",
  "forelse",
  "switch",
  "case"
]);
var DEFAULT_DIRECTIVE_ARG_SPACING_OVERRIDES = Object.freeze({
  if: "space",
  elseif: "space",
  unless: "space",
  while: "space",
  for: "space",
  foreach: "space",
  forelse: "space",
  switch: "space",
  case: "space"
});
function normalizeDirectiveName3(name) {
  return name.startsWith("@") ? name.slice(1) : name;
}
function normalizeDirectiveLookupName(name) {
  return normalizeDirectiveName3(name.trim()).toLowerCase();
}
function dedupStrings(items) {
  const seen = /* @__PURE__ */ new Set();
  const result = [];
  for (const item of items) {
    if (seen.has(item)) continue;
    seen.add(item);
    result.push(item);
  }
  return result;
}
function sanitizeDirectiveCaseValue(value) {
  const trimmed = value.trim();
  if (!trimmed) return trimmed;
  return normalizeDirectiveName3(trimmed);
}
function parseDirectiveCaseMapValue(value) {
  const out = /* @__PURE__ */ new Map();
  if (!value) return out;
  if (typeof value === "string") {
    const trimmed = value.trim();
    if (!trimmed) return out;
    try {
      const parsed = JSON.parse(trimmed);
      return parseDirectiveCaseMapValue(parsed);
    } catch {
      return out;
    }
  }
  if (typeof value !== "object") return out;
  for (const [rawKey, rawValue] of Object.entries(value)) {
    if (typeof rawValue !== "string") continue;
    const key = normalizeDirectiveName3(rawKey).toLowerCase();
    const directiveName = sanitizeDirectiveCaseValue(rawValue);
    if (!key || !directiveName) continue;
    out.set(key, directiveName);
  }
  return out;
}
function parseLowercaseStringArray(value) {
  if (!Array.isArray(value)) {
    return [];
  }
  const normalized = value.filter((item) => typeof item === "string").flatMap((item) => item.split(/[,\s]+/u).map((token) => token.trim().toLowerCase())).filter(Boolean);
  return dedupStrings(normalized);
}
function expandBladeComponentPrefixToken(token) {
  if (token.endsWith("-") || token.endsWith(":")) {
    return [token];
  }
  if (/^[a-z0-9_]+$/u.test(token)) {
    return [`${token}-`, `${token}:`];
  }
  return [token];
}
function normalizeBladeComponentPrefixes(tokens) {
  return dedupStrings(tokens.flatMap(expandBladeComponentPrefixToken));
}
function getDirectiveCaseMap(options2) {
  const key = options2;
  const cached = directiveCaseMapCache.get(key);
  if (cached) return cached;
  const parsed = parseDirectiveCaseMapValue(
    options2.bladeDirectiveCaseMap
  );
  directiveCaseMapCache.set(key, parsed);
  return parsed;
}
function getDirectiveCaseMode(options2) {
  const value = options2.bladeDirectiveCase;
  return value === "canonical" || value === "lower" ? value : "preserve";
}
function getDirectiveArgSpacingMode(options2) {
  const value = options2.bladeDirectiveArgSpacing;
  if (value === "preserve" || value === "none" || value === "space") {
    return value;
  }
  return "space";
}
function parseDirectiveArgSpacingRule(value) {
  if (typeof value !== "string") {
    return null;
  }
  const normalized = value.trim().toLowerCase();
  if (/^\d+$/u.test(normalized)) {
    return Number.parseInt(normalized, 10);
  }
  if (normalized === "preserve" || normalized === "none" || normalized === "space") {
    return normalized;
  }
  return null;
}
function parseDirectiveArgSpacingOverrideToken(token) {
  const trimmed = token.trim();
  if (!trimmed) return null;
  const separatorIndex = trimmed.indexOf("=");
  if (separatorIndex === -1) {
    const key2 = normalizeDirectiveLookupName(trimmed);
    return key2 ? [key2, "space"] : null;
  }
  const key = normalizeDirectiveLookupName(trimmed.slice(0, separatorIndex));
  const rule = parseDirectiveArgSpacingRule(trimmed.slice(separatorIndex + 1));
  if (!key || rule === null) return null;
  return [key, rule];
}
function parseDirectiveArgSpacingOverridesValue(value) {
  const out = /* @__PURE__ */ new Map();
  if (!Array.isArray(value)) {
    return out;
  }
  for (const item of value) {
    if (typeof item !== "string") continue;
    const parsed = parseDirectiveArgSpacingOverrideToken(item);
    if (!parsed) continue;
    const [key, rule] = parsed;
    out.set(key, rule);
  }
  return out;
}
function getDirectiveArgSpacingOverrides(options2) {
  const key = options2;
  const cached = directiveArgSpacingOverridesCache.get(key);
  if (cached) return cached;
  const rawValue = options2.bladeDirectiveArgSpacingOverrides;
  const result = rawValue === void 0 || rawValue === null ? parseDirectiveArgSpacingOverridesValue(DEFAULT_DIRECTIVE_ARG_SPACING_OVERRIDE_TOKENS) : parseDirectiveArgSpacingOverridesValue(rawValue);
  directiveArgSpacingOverridesCache.set(key, result);
  return result;
}
function getDirectiveArgSpacingText(authoredSpacing, rule) {
  if (rule === "preserve") {
    return authoredSpacing;
  }
  if (rule === "none") {
    return "";
  }
  if (rule === "space") {
    return " ";
  }
  return " ".repeat(rule);
}
function resolveDirectiveArgSpacingRule(directiveName, options2, inBladeComponentAttribute = false) {
  if (inBladeComponentAttribute) {
    return 0;
  }
  const normalized = normalizeDirectiveLookupName(directiveName);
  if (normalized) {
    const override = getDirectiveArgSpacingOverrides(options2).get(normalized);
    if (override !== void 0) {
      return override;
    }
  }
  return getDirectiveArgSpacingMode(options2);
}
function getDirectiveBlockStyle(options2) {
  const value = options2.bladeDirectiveBlockStyle;
  if (value === "inline-if-short" || value === "multiline") return value;
  return "preserve";
}
function getBladeBlankLinesMode(options2) {
  const value = options2.bladeBlankLinesAroundDirectives;
  if (value === "always") return value;
  return "preserve";
}
function getEchoSpacingMode(options2) {
  const value = options2.bladeEchoSpacing;
  if (value === "space" || value === "tight") return value;
  return "preserve";
}
function getSlotClosingTagMode(options2) {
  const value = options2.bladeSlotClosingTag;
  if (value === "preserve") return "preserve";
  return "canonical";
}
function shouldInsertOptionalClosingTags(options2) {
  const value = options2.bladeInsertOptionalClosingTags;
  return value === true;
}
function shouldKeepHeadAndBodyAtRoot(options2) {
  const value = options2.bladeKeepHeadAndBodyAtRoot;
  return value === true;
}
function getInlineIntentElements(options2) {
  const key = options2;
  const cached = inlineIntentElementsCache.get(key);
  if (cached) return cached;
  const rawValue = options2.bladeInlineIntentElements;
  const parsed = parseLowercaseStringArray(rawValue);
  const values = rawValue === void 0 || rawValue === null ? [...DEFAULT_INLINE_INTENT_ELEMENTS] : parsed;
  const result = new Set(values);
  inlineIntentElementsCache.set(key, result);
  return result;
}
function shouldPreserveInlineIntentElement(options2, tagName, namespace = "") {
  const normalizedTagName = tagName.toLowerCase();
  const normalizedNamespace = namespace.toLowerCase();
  const set = getInlineIntentElements(options2);
  if (set.has(normalizedTagName)) {
    return true;
  }
  if (normalizedNamespace) {
    return set.has(`${normalizedNamespace}:${normalizedTagName}`);
  }
  return false;
}
function shouldPreserveInlineIntentAttributes(options2, tagName, namespace = "") {
  if (shouldPreserveInlineIntentElement(options2, tagName, namespace)) {
    return true;
  }
  const normalizedTagName = tagName.toLowerCase();
  const normalizedNamespace = namespace.toLowerCase();
  if (!normalizedNamespace) {
    return false;
  }
  if (normalizedNamespace === "svg" && normalizedTagName === "foreignobject") {
    return false;
  }
  return shouldPreserveInlineIntentNamespace(options2, normalizedNamespace);
}
function shouldPreserveInlineIntentNamespace(options2, namespace) {
  const normalizedNamespace = namespace.toLowerCase();
  return getInlineIntentElements(options2).has(`${normalizedNamespace}:*`);
}
function getBladeComponentPrefixes(options2) {
  const key = options2;
  const cached = bladeComponentPrefixesCache.get(key);
  if (cached) return cached;
  const rawValue = options2.bladeComponentPrefixes;
  const parsed = parseLowercaseStringArray(rawValue);
  const values = normalizeBladeComponentPrefixes(
    rawValue === void 0 || rawValue === null ? [...DEFAULT_BLADE_COMPONENT_PREFIXES] : parsed
  );
  bladeComponentPrefixesCache.set(key, values);
  return values;
}
function isBladeComponentTagName(fullName, options2) {
  const normalized = fullName.trim().toLowerCase();
  if (!normalized) return false;
  return getBladeComponentPrefixes(options2).some((prefix) => normalized.startsWith(prefix));
}
function formatDirectiveNameToken(rawDirectiveToken, options2) {
  if (!rawDirectiveToken.startsWith("@")) {
    return rawDirectiveToken;
  }
  const name = rawDirectiveToken.slice(1);
  const lowerName = name.toLowerCase();
  const mode = getDirectiveCaseMode(options2);
  if (mode === "preserve") {
    return rawDirectiveToken;
  }
  if (mode === "lower") {
    return `@${lowerName}`;
  }
  const map = getDirectiveCaseMap(options2);
  const mapped = map.get(lowerName);
  if (mapped) {
    return `@${mapped}`;
  }
  const canonical = getCanonicalDirectiveName(name);
  if (!canonical) {
    return rawDirectiveToken;
  }
  return `@${canonical}`;
}

// src/print/tag.ts
var import_prettier2 = require("prettier");

// src/print/attribute-name.ts
function getEchoDelimiters(part) {
  switch (part.kind) {
    case "echo":
      return { open: "{{", close: "}}" };
    case "raw_echo":
      return { open: "{!!", close: "!!}" };
    case "triple_echo":
      return { open: "{{{", close: "}}}" };
    default:
      return null;
  }
}
function formatEchoPart(part, options2) {
  const spacing = getEchoSpacingMode(options2);
  if (spacing === "preserve") return part.text;
  const delimiters = getEchoDelimiters(part);
  if (!delimiters) return part.text;
  const { open, close } = delimiters;
  if (!part.text.startsWith(open) || !part.text.endsWith(close)) {
    return part.text;
  }
  const content = part.text.slice(open.length, part.text.length - close.length);
  const trimmed = content.trim();
  if (trimmed.length === 0) {
    return spacing === "tight" ? `${open}${close}` : `${open} ${close}`;
  }
  if (trimmed.includes("\n")) {
    return `${open}
${trimmed}
${close}`;
  }
  if (spacing === "tight") {
    return `${open}${trimmed}${close}`;
  }
  return `${open} ${trimmed} ${close}`;
}
function isComponentAttributeName(node, options2) {
  return node.parent?.kind === 1 /* Element */ && isBladeComponentTagName(node.parent.fullName, options2);
}
function formatDirectivePart(part, node, options2) {
  if (!part.text.startsWith("@")) return part.text;
  const argsStart = part.text.indexOf("(");
  if (argsStart === -1) {
    return formatDirectiveNameToken(part.text, options2);
  }
  const beforeArgs = part.text.slice(0, argsStart);
  const trimmedName = beforeArgs.trimEnd();
  const spacing = beforeArgs.slice(trimmedName.length);
  const args = part.text.slice(argsStart);
  const formattedName = formatDirectiveNameToken(trimmedName, options2);
  const spacingRule = resolveDirectiveArgSpacingRule(
    trimmedName,
    options2,
    isComponentAttributeName(node, options2)
  );
  if (spacingRule === "preserve") {
    return `${formattedName}${spacing}${args}`;
  }
  const normalizedArgs = args.trimStart();
  return `${formattedName}${getDirectiveArgSpacingText("", spacingRule)}${normalizedArgs}`;
}
function formatAttributeNamePart(part, node, options2) {
  switch (part.kind) {
    case "echo":
    case "raw_echo":
    case "triple_echo":
      return formatEchoPart(part, options2);
    case "directive":
      return formatDirectivePart(part, node, options2);
    case "php_tag":
    case "php_block":
    case "text":
    default:
      return part.text;
  }
}
function formatAttributeNameForPrint(node, options2) {
  if (isStaticAttributeName(node)) {
    return getAttributeNameRaw(node);
  }
  const parts = getAttributeNameParts(node);
  if (parts.length === 0) {
    return getAttributeNameRaw(node);
  }
  return parts.map((part) => formatAttributeNamePart(part, node, options2)).join("");
}

// src/print/doctype-utils.ts
var DOCTYPE_START = "<!DOCTYPE";
var DOCTYPE_START_LOWER = "<!doctype";
function parseDoctype(rawText) {
  const valueMatch = rawText.match(/^<!DOCTYPE\s+(.*?)\s*>$/is);
  if (!valueMatch) return null;
  const value = valueMatch[1];
  const normalizedValue = value.replace(/^html\b/i, "html").replace(/\s+/g, " ");
  const isSimpleHtml5 = /^html$/i.test(normalizedValue);
  return { normalizedValue, isSimpleHtml5 };
}
function getDoctypeStartMarker(rawText, options2) {
  const parsed = parseDoctype(rawText);
  const filepath = options2?.filepath;
  const hasFilepath = typeof filepath === "string" && filepath.length > 0;
  const isHtmlFilepath = hasFilepath && /\.html?$/i.test(filepath);
  if (!parsed) {
    return rawText.slice(0, DOCTYPE_START.length);
  }
  if (hasFilepath && !isHtmlFilepath) {
    return rawText.slice(0, DOCTYPE_START.length);
  }
  if (parsed.isSimpleHtml5) {
    return DOCTYPE_START_LOWER;
  }
  return DOCTYPE_START;
}
function formatDoctype(rawText, options2) {
  const parsed = parseDoctype(rawText);
  if (!parsed) {
    if (/^<!doctype\b/i.test(rawText) && !rawText.includes(">")) {
      return rawText.trimEnd();
    }
    return rawText;
  }
  return `${getDoctypeStartMarker(rawText, options2)} ${parsed.normalizedValue}>`;
}

// src/print/doc-utils.ts
var import_prettier = require("prettier");
function replaceEndOfLine(text, replacement = import_prettier.doc.builders.literalline) {
  const parts = [];
  const lines = text.split("\n");
  for (let i = 0; i < lines.length; i++) {
    if (i > 0) parts.push(replacement);
    if (lines[i]) parts.push(lines[i]);
  }
  return parts;
}
function htmlTrimStart2(s) {
  return htmlTrimStart(s);
}
function htmlTrimEnd2(s) {
  return htmlTrimEnd(s);
}

// src/print/tag.ts
var { indent, line, softline, hardline, join } = import_prettier2.doc.builders;
var unpairedClosingTagIndexCache = /* @__PURE__ */ new WeakMap();
function canBorrowParentTagMarkers(node) {
  return node.kind === 1 /* Element */ || node.kind === 14 /* ConditionalComment */;
}
function getDisplayTagName(node) {
  const trimMalformedEofName = (name) => shouldTrimMalformedEofTagName(node) ? name.replace(/\s+$/u, "") : name;
  if (node.namespace === "svg") {
    return trimMalformedEofName(node.rawTagName);
  }
  if (node.kind === 1 /* Element */ && node.flat.genericOffset > 0) {
    return trimMalformedEofName(node.rawTagName);
  }
  const fullLower = node.rawTagName.toLowerCase();
  if (HTML_TAGS.has(fullLower)) {
    return trimMalformedEofName(fullLower);
  }
  return trimMalformedEofName(node.rawTagName);
}
function shouldTrimMalformedEofTagName(node) {
  return node.kind === 1 /* Element */ && node.end === node.source.length && node.openTagEndOffset <= node.start && !node.hasClosingTag;
}
function getElementGenericSuffix(node) {
  if (node.kind !== 1 /* Element */) return "";
  const tokens = node.buildResult.tokens;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  for (let i = tokenStart + 1; i < tokenEnd; i++) {
    const token = tokens[i];
    if (token.type === 50 /* TsxGenericType */) {
      return node.buildResult.source.slice(token.start, token.end);
    }
    if (token.type === 9 /* Whitespace */ || token.type === 2 /* GreaterThan */ || token.type === 3 /* Slash */ || token.type === 32 /* SyntheticClose */) {
      break;
    }
  }
  return "";
}
function isDynamicTagNameText(name) {
  return name.includes("{{") || name.includes("{!!") || name.includes("<?") || name.includes("@");
}
function hasShorthandSlotClosingTag(node) {
  if (!node.rawClosingTagName) return false;
  const openTagName = node.rawTagName.toLowerCase();
  if (!openTagName.startsWith("x-slot:") && !openTagName.startsWith("x-slot[")) {
    return false;
  }
  return node.rawClosingTagName.toLowerCase() === "x-slot";
}
function getDisplayClosingTagName(node, options2) {
  if (options2 && getSlotClosingTagMode(options2) === "preserve" && hasShorthandSlotClosingTag(node)) {
    return node.rawClosingTagName;
  }
  if (node.rawClosingTagName && (isDynamicTagNameText(node.rawTagName) || isDynamicTagNameText(node.rawClosingTagName))) {
    return node.rawClosingTagName;
  }
  return getDisplayTagName(node);
}
function isBorrowableMarkerNode(node) {
  return node.kind === 1 /* Element */ || node.kind === 14 /* ConditionalComment */ || node.kind === 12 /* Comment */ || node.kind === 13 /* BogusComment */;
}
function canBorrowPrevClosingTagEndMarker(node) {
  return node.kind === 1 /* Element */ || node.kind === 14 /* ConditionalComment */ || node.kind === 2 /* Text */ || node.kind === 12 /* Comment */ || node.kind === 13 /* BogusComment */ || node.kind === 4 /* Echo */ || node.kind === 5 /* RawEcho */ || node.kind === 6 /* TripleEcho */ || node.kind === 16 /* Doctype */ || node.kind === 17 /* Cdata */ || node.kind === 18 /* Decl */ || node.kind === 28 /* ProcessingInstruction */;
}
function getRoot(node) {
  let current = node;
  while (current.parent) {
    current = current.parent;
  }
  return current;
}
function getUnpairedClosingTagName(node) {
  if (node.kind !== 21 /* UnpairedClosingTag */) return null;
  const raw = node.source.slice(node.start, node.end).trim();
  const match = raw.match(/^<\s*\/\s*([^\s>/]+)\s*>?$/);
  return match?.[1]?.toLowerCase() ?? null;
}
function buildUnpairedClosingTagIndex(root) {
  const index = /* @__PURE__ */ new Map();
  const stack = [root];
  while (stack.length > 0) {
    const node = stack.pop();
    const name = getUnpairedClosingTagName(node);
    if (name) {
      const list = index.get(name);
      if (list) {
        list.push(node.start);
      } else {
        index.set(name, [node.start]);
      }
    }
    for (let i = node.children.length - 1; i >= 0; i--) {
      stack.push(node.children[i]);
    }
  }
  for (const positions of index.values()) {
    positions.sort((a, b) => a - b);
  }
  return index;
}
function getUnpairedClosingTagIndex(root) {
  const cached = unpairedClosingTagIndexCache.get(root);
  if (cached) return cached;
  const built = buildUnpairedClosingTagIndex(root);
  unpairedClosingTagIndexCache.set(root, built);
  return built;
}
function hasFutureMatchingUnpairedClosingTag(node) {
  if (node.kind !== 1 /* Element */) return false;
  if (!node.tagName) return false;
  const root = getRoot(node);
  const index = getUnpairedClosingTagIndex(root);
  const openTagName = node.tagName.toLowerCase();
  const candidateClosingNames = /* @__PURE__ */ new Set([openTagName]);
  if (openTagName.startsWith("x-slot:") || openTagName.startsWith("x-slot[")) {
    candidateClosingNames.add("x-slot");
  }
  for (const candidate of candidateClosingNames) {
    const positions = index.get(candidate) ?? [];
    let lo = 0;
    let hi = positions.length - 1;
    while (lo <= hi) {
      const mid = lo + hi >> 1;
      if (positions[mid] <= node.end) {
        lo = mid + 1;
      } else {
        return true;
      }
    }
  }
  return false;
}
function needsToBorrowPrevClosingTagEndMarker(node) {
  return canBorrowPrevClosingTagEndMarker(node) && !!node.prev && isBorrowableMarkerNode(node.prev) && node.prev.kind !== 16 /* Doctype */ && node.kind !== 8 /* DirectiveBlock */ && !isTextLikeNode(node.prev) && node.isLeadingSpaceSensitive && !node.hasLeadingSpaces;
}
function needsToBorrowLastChildClosingTagEndMarker(node) {
  if (!canBorrowParentTagMarkers(node)) {
    return false;
  }
  const last = node.children[node.children.length - 1];
  return !!last && isBorrowableMarkerNode(last) && last.isTrailingSpaceSensitive && !last.hasTrailingSpaces && !isTextLikeNode(getLastDescendant(last)) && !isPreLikeNode2(node);
}
function needsToBorrowParentClosingTagStartMarker(node) {
  return !node.next && !node.hasTrailingSpaces && node.isTrailingSpaceSensitive && isTextLikeNode(getLastDescendant(node));
}
function needsToBorrowNextOpeningTagStartMarker(node) {
  return !!node.next && isBorrowableMarkerNode(node.next) && !isTextLikeNode(node.next) && isTextLikeNode(node) && node.isTrailingSpaceSensitive && !node.hasTrailingSpaces;
}
function needsToBorrowParentOpeningTagEndMarker(node) {
  const canBorrow = node.kind === 2 /* Text */ || node.kind === 12 /* Comment */ || node.kind === 13 /* BogusComment */ || node.kind === 4 /* Echo */ || node.kind === 5 /* RawEcho */ || node.kind === 6 /* TripleEcho */ || node.kind === 16 /* Doctype */ || node.kind === 17 /* Cdata */ || node.kind === 18 /* Decl */ || node.kind === 28 /* ProcessingInstruction */ || node.kind === 1 /* Element */ || node.kind === 14 /* ConditionalComment */;
  if (node.parent?.kind === 1 /* Element */ && node.parent.rawTagName.includes(".")) {
    return false;
  }
  return canBorrow && !node.prev && node.isLeadingSpaceSensitive && !node.hasLeadingSpaces;
}
function shouldNotPrintClosingTag(node, options2) {
  if (node.kind === 1 /* Element */ && !node.isSelfClosing && !node.hasClosingTag && !shouldInsertOptionalClosingTags(options2)) {
    return true;
  }
  const hasClosingTagLikeTextInBody = node.kind === 1 /* Element */ && !node.isSelfClosing && !node.hasClosingTag && node.rawTagName.length > 0 && node.openTagEndOffset > 0 && node.source.slice(node.openTagEndOffset, node.end).toLowerCase().includes(`</${node.rawTagName.toLowerCase()}`);
  if (node.kind === 1 /* Element */ && !node.isSelfClosing && !node.hasClosingTag && hasFutureMatchingUnpairedClosingTag(node)) {
    return true;
  }
  const hasUnpairedClosingChild = node.kind === 1 /* Element */ && node.children.some((child) => child.kind === 21 /* UnpairedClosingTag */);
  return !node.isSelfClosing && !node.hasClosingTag && (hasClosingTagLikeTextInBody || hasPrettierIgnore(node) || shouldPreserveContent(node.parent, options2) || hasUnpairedClosingChild);
}
function printOpeningTagStartMarker(node, options2) {
  switch (node.kind) {
    case 14 /* ConditionalComment */:
      return `<!--[if ${node.condition}`;
    case 12 /* Comment */:
      if (isIeConditionalStartComment(node)) {
        return `<!--[if ${node.ieConditionalStartCondition}`;
      }
      return "<!--";
    case 13 /* BogusComment */:
      return "<!--";
    case 4 /* Echo */:
      return "{{";
    case 5 /* RawEcho */:
      return "{!!";
    case 6 /* TripleEcho */:
      return "{{{";
    case 16 /* Doctype */:
      return getDoctypeStartMarker(node.rawText, options2);
    case 1 /* Element */:
      if (node.condition) {
        return `<!--[if ${node.condition}]><!--><${getDisplayTagName(node)}${getElementGenericSuffix(node)}`;
      }
      return `<${getDisplayTagName(node)}${getElementGenericSuffix(node)}`;
    default:
      return `<${getDisplayTagName(node)}`;
  }
}
function printOpeningTagEndMarker(node, options2) {
  switch (node.kind) {
    case 14 /* ConditionalComment */:
      return node.conditionalStartIsRevealed ? "]><!-->" : "]>";
    case 1 /* Element */:
      const hasFutureMatchingCloser = hasFutureMatchingUnpairedClosingTag(node);
      if (node.openTagEndOffset <= node.start && !node.hasClosingTag && !(options2 && shouldInsertOptionalClosingTags(options2)) && !hasFutureMatchingCloser) {
        return "";
      }
      if (node.condition) {
        return "><!--<![endif]-->";
      }
      return ">";
    default:
      return ">";
  }
}
function printClosingTagStartMarker(node, options2) {
  if (options2 && shouldNotPrintClosingTag(node, options2)) {
    return "";
  }
  switch (node.kind) {
    case 14 /* ConditionalComment */:
      return node.conditionalEndIsHidden ? "<!--<!" : "<!";
    case 1 /* Element */:
      if (node.hasHtmComponentClosingTag) {
        return "<//";
      }
      return `</${getDisplayClosingTagName(node, options2)}`;
    default:
      return `</${getDisplayTagName(node)}`;
  }
}
function printClosingTagEndMarker(node, options2) {
  if (options2 && shouldNotPrintClosingTag(node, options2)) {
    return "";
  }
  switch (node.kind) {
    case 14 /* ConditionalComment */:
      return "[endif]-->";
    case 12 /* Comment */:
      return isIeConditionalStartComment(node) ? "]><!-->" : ">";
    case 4 /* Echo */:
      return "}}";
    case 5 /* RawEcho */:
      return "!!}";
    case 6 /* TripleEcho */:
      return "}}}";
    case 1 /* Element */:
      if (node.isSelfClosing) {
        return "/>";
      }
      return ">";
    default:
      return ">";
  }
}
function printOpeningTagPrefix(node, options2) {
  return needsToBorrowParentOpeningTagEndMarker(node) ? node.parent && canBorrowParentTagMarkers(node.parent) ? printOpeningTagEndMarker(node.parent, options2) : "" : needsToBorrowPrevClosingTagEndMarker(node) ? printClosingTagEndMarker(node.prev, options2) : "";
}
function printOpeningTagStart(node, options2) {
  return node.prev && needsToBorrowNextOpeningTagStartMarker(node.prev) ? "" : [printOpeningTagPrefix(node, options2), printOpeningTagStartMarker(node, options2)];
}
function printOpeningTagEnd(node, options2) {
  const firstChild = node.children[0];
  return firstChild && needsToBorrowParentOpeningTagEndMarker(firstChild) ? "" : printOpeningTagEndMarker(node, options2);
}
function printClosingTagSuffix(node, options2) {
  if (needsToBorrowParentClosingTagStartMarker(node)) {
    if (node.parent && canBorrowParentTagMarkers(node.parent) && canBorrowParentClosingMarkerStart(node.parent, options2)) {
      return printClosingTagStartMarker(node.parent, options2);
    }
    return "";
  }
  return needsToBorrowNextOpeningTagStartMarker(node) ? printOpeningTagStartMarker(node.next, options2) : "";
}
function canBorrowParentClosingMarkerStart(parent, options2) {
  if (parent.kind !== 1 /* Element */) {
    return true;
  }
  if (parent.hasClosingTag) {
    return true;
  }
  return options2 ? shouldInsertOptionalClosingTags(options2) : false;
}
function printClosingTagPrefix(node, options2) {
  return needsToBorrowLastChildClosingTagEndMarker(node) ? printClosingTagEndMarker(node.children[node.children.length - 1], options2) : "";
}
function printClosingTagStart(node, options2) {
  const lastChild = node.children[node.children.length - 1];
  return lastChild && needsToBorrowParentClosingTagStartMarker(lastChild) ? "" : [printClosingTagPrefix(node, options2), printClosingTagStartMarker(node, options2)];
}
function printClosingTagEnd(node, options2) {
  return (node.next ? needsToBorrowPrevClosingTagEndMarker(node.next) : needsToBorrowLastChildClosingTagEndMarker(node.parent)) ? "" : [printClosingTagEndMarker(node, options2), printClosingTagSuffix(node, options2)];
}
function getPrettierIgnoreAttributeCommentData(value) {
  const match = value.trim().match(/^prettier-ignore-attribute(?:\s+(.+))?$/s);
  if (!match) return false;
  if (!match[1]) return true;
  return match[1].split(/\s+/);
}
function printOpeningTag(path, options2, print) {
  const node = path.node;
  return [
    printOpeningTagStart(node, options2),
    printAttributes(path, options2, print),
    node.isSelfClosing ? "" : printOpeningTagEnd(node, options2)
  ];
}
function printClosingTag(node, options2) {
  return [
    node.isSelfClosing ? "" : printClosingTagStart(node, options2),
    printClosingTagEnd(node, options2)
  ];
}
function printAttributes(path, options2, print) {
  const node = path.node;
  const bracketSameLine = options2.bracketSameLine;
  if (node.attrs.length === 0) {
    return node.isSelfClosing ? " " : "";
  }
  const ignoreAttributeData = node.prev?.kind === 12 /* Comment */ && getPrettierIgnoreAttributeCommentData(
    node.prev.rawText.replace(/^<!--\s*/, "").replace(/\s*-->$/, "")
  );
  const hasPrettierIgnoreAttribute = typeof ignoreAttributeData === "boolean" ? () => ignoreAttributeData : Array.isArray(ignoreAttributeData) ? (attribute) => {
    if (attribute.kind !== 19 /* Attribute */ && attribute.kind !== 20 /* JsxAttribute */) {
      return false;
    }
    const attrName = getAttributeNameRaw(attribute);
    return ignoreAttributeData.includes(attrName);
  } : () => false;
  const printedAttrs = path.map((attrPath) => {
    const attribute = attrPath.node;
    if (hasPrettierIgnoreAttribute(attribute)) {
      return replaceEndOfLine(node.source.slice(attribute.start, attribute.end));
    }
    return print(attrPath);
  }, "attrs");
  const forceNotToBreakAttrContent = node.kind === 1 /* Element */ && node.fullName.toLowerCase() === "script" && node.attrs.length === 1 && getStaticAttributeNameLower(node.attrs[0]) === "src" && node.children.length === 0;
  const forceInlineIntentAttributeLayout = shouldKeepInlineIntentAttributeLayout(node, options2);
  const forceMultilineSvgAttributeLayout = shouldForceMultilineSvgAttributeLayout(node, options2);
  const shouldPrintAttributePerLine = !forceInlineIntentAttributeLayout && !forceMultilineSvgAttributeLayout && options2.singleAttributePerLine && node.attrs.length > 1 && !isVueSfcBlock(node, options2);
  const attrLine = shouldPrintAttributePerLine ? hardline : line;
  const parts = [
    indent([
      forceNotToBreakAttrContent || forceInlineIntentAttributeLayout ? " " : forceMultilineSvgAttributeLayout ? hardline : line,
      join(
        forceInlineIntentAttributeLayout ? " " : forceMultilineSvgAttributeLayout ? hardline : attrLine,
        printedAttrs
      )
    ])
  ];
  const firstChild = node.children[0];
  const forceFlat = firstChild && needsToBorrowParentOpeningTagEndMarker(firstChild) || node.isSelfClosing && node.parent !== null && needsToBorrowLastChildClosingTagEndMarker(node.parent) || forceInlineIntentAttributeLayout || forceNotToBreakAttrContent;
  if (forceMultilineSvgAttributeLayout) {
    parts.push(hardline);
  } else if (forceFlat) {
    parts.push(node.isSelfClosing ? " " : "");
  } else if (bracketSameLine) {
    parts.push(node.isSelfClosing ? " " : "");
  } else {
    parts.push(node.isSelfClosing ? line : softline);
  }
  return parts;
}
function shouldKeepInlineIntentAttributeLayout(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.attrs.length === 0) return false;
  if (node.openTagEndOffset <= node.start) return false;
  if (!shouldPreserveInlineIntentAttributes(options2, node.tagName, node.namespace)) {
    return false;
  }
  const openingSource = node.source.slice(node.start, node.openTagEndOffset);
  if (openingSource.includes("{{") || openingSource.includes("{!!") || openingSource.includes("{{{")) {
    return false;
  }
  return !/[\r\n]/u.test(openingSource);
}
function shouldForceMultilineSvgAttributeLayout(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.namespace !== "svg") return false;
  if (node.attrs.length === 0) return false;
  return !hasInlineIntentAttributeConfig(node, options2);
}
function hasInlineIntentAttributeConfig(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  return shouldPreserveInlineIntentElement(options2, node.tagName, node.namespace) || shouldPreserveInlineIntentNamespace(options2, node.namespace);
}
function getPreferredQuote(value, preferred) {
  const alt = preferred === '"' ? "'" : '"';
  let prefCount = 0;
  let altCount = 0;
  for (const ch of value) {
    if (ch === preferred) prefCount++;
    else if (ch === alt) altCount++;
  }
  return prefCount > altCount ? alt : preferred;
}
function getAttributeValueTokenRange(node) {
  const br = node.buildResult;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  let equalsIndex = -1;
  for (let i = tokenStart; i < tokenEnd; i++) {
    if (br.tokens[i].type === 4 /* Equals */) {
      equalsIndex = i;
      break;
    }
  }
  if (equalsIndex === -1) return null;
  let valueStart = equalsIndex + 1;
  while (valueStart < tokenEnd && br.tokens[valueStart].type === 9 /* Whitespace */) {
    valueStart++;
  }
  if (valueStart >= tokenEnd) {
    return { start: valueStart, end: valueStart };
  }
  if (br.tokens[valueStart].type !== 8 /* Quote */) {
    return { start: valueStart, end: tokenEnd };
  }
  let valueEnd = tokenEnd;
  if (valueEnd > valueStart + 1 && br.tokens[valueEnd - 1].type === 8 /* Quote */) {
    valueEnd--;
  }
  return { start: valueStart + 1, end: valueEnd };
}
function getEchoConstructInfo(tokenType) {
  if (tokenType === 18 /* EchoStart */) {
    return { open: "{{", close: "}}", endType: 19 /* EchoEnd */ };
  }
  if (tokenType === 21 /* RawEchoStart */) {
    return { open: "{!!", close: "!!}", endType: 22 /* RawEchoEnd */ };
  }
  if (tokenType === 23 /* TripleEchoStart */) {
    return { open: "{{{", close: "}}}", endType: 24 /* TripleEchoEnd */ };
  }
  return null;
}
function formatEchoConstruct(raw, open, close, spacing) {
  if (spacing === "preserve") {
    return raw;
  }
  if (!raw.startsWith(open) || !raw.endsWith(close)) {
    return raw;
  }
  const content = raw.slice(open.length, raw.length - close.length);
  const trimmed = content.trim();
  if (trimmed.length === 0) {
    return spacing === "tight" ? `${open}${close}` : `${open} ${close}`;
  }
  if (trimmed.includes("\n")) {
    return `${open}
${trimmed}
${close}`;
  }
  return spacing === "tight" ? `${open}${trimmed}${close}` : `${open} ${trimmed} ${close}`;
}
function formatDynamicAttributeValue(node, originalValue, options2) {
  const spacing = getEchoSpacingMode(options2);
  if (spacing === "preserve") {
    return originalValue;
  }
  const range = getAttributeValueTokenRange(node);
  if (!range || range.start >= range.end) {
    return originalValue;
  }
  const br = node.buildResult;
  let output = "";
  for (let i = range.start; i < range.end; i++) {
    const token = br.tokens[i];
    const echoInfo = getEchoConstructInfo(token.type);
    if (!echoInfo) {
      output += br.source.slice(token.start, token.end);
      continue;
    }
    const segmentStart = token.start;
    let segmentEnd = token.end;
    i++;
    while (i < range.end) {
      const current = br.tokens[i];
      segmentEnd = current.end;
      if (current.type === echoInfo.endType) {
        break;
      }
      i++;
    }
    output += formatEchoConstruct(
      br.source.slice(segmentStart, segmentEnd),
      echoInfo.open,
      echoInfo.close,
      spacing
    );
  }
  return output;
}
function printAttribute(node, options2) {
  const br = node.buildResult;
  const tc = node.flat.tokenCount;
  let isBound = false;
  let isShorthand = false;
  let isEscaped = false;
  for (let i = 0; i < tc; i++) {
    const t = br.tokens[node.flat.tokenStart + i];
    if (t.type === 34 /* BoundAttribute */) isBound = true;
    if (t.type === 35 /* ShorthandAttribute */) isShorthand = true;
    if (t.type === 33 /* EscapedAttribute */) isEscaped = true;
  }
  const rawName = formatAttributeNameForPrint(node, options2);
  const name = isBound || isShorthand || isEscaped || !isStaticAttributeName(node) ? rawName : normalizeAttributeName(rawName, node.parent);
  const value = getAttributeRawValue(node);
  const valueKind = getAttributeValueKind(node);
  if (value === null) {
    return name;
  }
  if (valueKind !== "static_text") {
    const formattedDynamicValue = formatDynamicAttributeValue(node, value, options2);
    const quote2 = getAttributeValueQuote(node);
    return quote2 ? [name, "=", quote2, replaceEndOfLine(formattedDynamicValue), quote2] : [name, "=", replaceEndOfLine(formattedDynamicValue)];
  }
  const unescaped = unescapeQuoteEntities(value);
  const quote = getPreferredQuote(unescaped, '"');
  const escaped = quote === '"' ? unescaped.replaceAll('"', "&quot;") : unescaped.replaceAll("'", "&apos;");
  return [name, "=", quote, replaceEndOfLine(escaped), quote];
}

// src/print/children.ts
var import_prettier4 = require("prettier");

// src/print/if-break-chain.ts
var import_prettier3 = require("prettier");
var { ifBreak } = import_prettier3.doc.builders;
function ifBreakChain(flatDoc, groupIds, breakDoc = "") {
  let chained = flatDoc;
  for (let i = groupIds.length - 1; i >= 0; i--) {
    const groupId = groupIds[i];
    if (!groupId) {
      continue;
    }
    chained = ifBreak(breakDoc, chained, { groupId });
  }
  return chained;
}

// src/print/children.ts
var { breakParent, group, hardline: hardline2, softline: softline2, line: line2 } = import_prettier4.doc.builders;
function getSourceBetween(prev, next) {
  if (prev.source !== next.source) {
    return "";
  }
  return prev.source.slice(prev.end, next.start);
}
function isIgnoreRangeNode(node) {
  return node.kind === 29 /* IgnoreRange */;
}
function printChild(childPath, options2, print) {
  const child = childPath.node;
  const ignoreMode = getPrettierIgnoreMode(child);
  if (hasPrettierIgnore(child) && ignoreMode === "single") {
    const endLocation = getPrintableSubtreeEnd(child);
    let preservedText = htmlTrimEnd2(
      child.source.slice(
        child.start + (child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev) ? printOpeningTagStartMarker(child).length : 0),
        endLocation - (child.next && needsToBorrowPrevClosingTagEndMarker(child.next) ? printClosingTagEndMarker(child, options2).length : 0)
      )
    );
    if (child.kind === 2 /* Text */ && ignoreMode === "single") {
      preservedText = htmlTrimStart2(preservedText);
    }
    return [
      printOpeningTagPrefix(child, options2),
      replaceEndOfLine(preservedText),
      printClosingTagSuffix(child, options2)
    ];
  }
  return print(childPath);
}
function getSourceBetweenSegments(prev, next) {
  if (prev.first.source !== next.first.source) {
    return "";
  }
  return prev.first.source.slice(prev.sourceEnd, next.sourceStart);
}
function hasEmptyLineBetweenSegments(prev, next) {
  if (!isIgnoreRangeNode(prev.last) && !isIgnoreRangeNode(next.first)) {
    return forceNextEmptyLine(prev.last);
  }
  const sourceBetween = getSourceBetweenSegments(prev, next);
  return /(?:\r\n|\r|\n)[^\S\r\n]*(?:\r\n|\r|\n)/u.test(sourceBetween);
}
function printBetweenSegments(prev, next) {
  if (isIgnoreRangeNode(prev.last) || isIgnoreRangeNode(next.first)) {
    const sourceBetween = getSourceBetweenSegments(prev, next);
    if (sourceBetween.length === 0) {
      return "";
    }
    if (/(?:\r\n|\r|\n)[^\S\r\n]*(?:\r\n|\r|\n)/u.test(sourceBetween)) {
      return [hardline2, hardline2];
    }
    if (/[\r\n]/u.test(sourceBetween)) {
      return hardline2;
    }
    return sourceBetween;
  }
  return printBetweenLine(prev.last, next.first);
}
function printBetweenLine(prev, next) {
  const sourceBetween = getSourceBetween(prev, next);
  if (isIgnoreRangeNode(prev) || isIgnoreRangeNode(next)) {
    if (sourceBetween.length === 0) {
      return "";
    }
    if (/(?:\r\n|\r|\n)[^\S\r\n]*(?:\r\n|\r|\n)/u.test(sourceBetween)) {
      return [hardline2, hardline2];
    }
    if (/[\r\n]/u.test(sourceBetween)) {
      return hardline2;
    }
    return sourceBetween;
  }
  if (prev.kind === 22 /* NonOutput */ || next.kind === 22 /* NonOutput */) {
    return "";
  }
  if (isTextLikeNode(prev) && isTextLikeNode(next)) {
    if (prev.isTrailingSpaceSensitive) {
      if (prev.hasTrailingSpaces) {
        if (isEchoLike(prev) || isEchoLike(next)) {
          return " ";
        }
        return preferHardlineAsLeadingSpaces(next) ? hardline2 : line2;
      }
      return "";
    }
    if (isEchoLike(prev) || isEchoLike(next)) {
      return "";
    }
    return preferHardlineAsLeadingSpaces(next) ? hardline2 : softline2;
  }
  if (needsToBorrowNextOpeningTagStartMarker(prev) && (hasPrettierIgnore(next) || next.children.length > 0 || next.isSelfClosing || next.kind === 1 /* Element */ && next.attrs.length > 0) || prev.kind === 1 /* Element */ && prev.isSelfClosing && needsToBorrowPrevClosingTagEndMarker(next)) {
    return "";
  }
  if (!next.isLeadingSpaceSensitive || preferHardlineAsLeadingSpaces(next) || needsToBorrowPrevClosingTagEndMarker(next) && prev.children.length > 0 && needsToBorrowParentClosingTagStartMarker(prev.children[prev.children.length - 1]) && prev.children[prev.children.length - 1].children.length > 0 && needsToBorrowParentClosingTagStartMarker(
    prev.children[prev.children.length - 1].children[prev.children[prev.children.length - 1].children.length - 1]
  )) {
    return hardline2;
  }
  if (next.hasLeadingSpaces) {
    return line2;
  }
  return softline2;
}
function printChildren(path, print, options2) {
  const node = path.node;
  const segments = getChildPrintSegments(node.children);
  const printedChildren = path.map(
    (childPath) => printChild(childPath, options2, print),
    "children"
  );
  if (forceBreakChildren(node)) {
    return [
      breakParent,
      ...segments.map((segment, segmentIndex) => {
        const prevSegment = segmentIndex > 0 ? segments[segmentIndex - 1] : null;
        const prevBetweenLine = !prevSegment ? "" : printBetweenSegments(prevSegment, segment);
        return [
          !prevBetweenLine ? "" : [prevBetweenLine, hasEmptyLineBetweenSegments(prevSegment, segment) ? hardline2 : ""],
          printedChildren[segment.startIndex]
        ];
      })
    ];
  }
  const needsGroupIds = segments.some((segment) => !isTextLikeNode(segment.first));
  const groupIds = needsGroupIds ? segments.map(() => /* @__PURE__ */ Symbol("")) : [];
  return segments.map((segment, childIndex) => {
    const childNode = segment.first;
    const segmentDoc = printedChildren[segment.startIndex];
    if (isTextLikeNode(childNode)) {
      const prevSegment2 = childIndex > 0 ? segments[childIndex - 1] : null;
      if (prevSegment2 && isTextLikeNode(prevSegment2.last)) {
        const prevBetweenLine2 = printBetweenSegments(prevSegment2, segment);
        if (prevBetweenLine2) {
          if (hasEmptyLineBetweenSegments(prevSegment2, segment)) {
            return [hardline2, hardline2, segmentDoc];
          }
          return [prevBetweenLine2, segmentDoc];
        }
      }
      return segmentDoc;
    }
    const prevParts = [];
    const leadingParts = [];
    const trailingParts = [];
    const nextParts = [];
    const prevSegment = childIndex > 0 ? segments[childIndex - 1] : null;
    const prevBetweenLine = prevSegment ? printBetweenSegments(prevSegment, segment) : "";
    const nextSegment = childIndex + 1 < segments.length ? segments[childIndex + 1] : null;
    const nextBetweenLine = nextSegment ? printBetweenSegments(segment, nextSegment) : "";
    if (prevBetweenLine) {
      if (hasEmptyLineBetweenSegments(prevSegment, segment)) {
        prevParts.push(hardline2, hardline2);
      } else if (prevBetweenLine === hardline2) {
        prevParts.push(hardline2);
      } else if (prevSegment && isTextLikeNode(prevSegment.last)) {
        leadingParts.push(prevBetweenLine);
      } else {
        leadingParts.push(ifBreakChain(softline2, [groupIds[childIndex - 1]]));
      }
    }
    if (nextBetweenLine) {
      if (nextSegment && hasEmptyLineBetweenSegments(segment, nextSegment)) {
        if (isTextLikeNode(nextSegment.first)) {
          nextParts.push(hardline2, hardline2);
        }
      } else if (nextBetweenLine === hardline2) {
        if (nextSegment && isTextLikeNode(nextSegment.first)) {
          nextParts.push(hardline2);
        }
      } else {
        trailingParts.push(nextBetweenLine);
      }
    }
    return [
      ...prevParts,
      group([
        ...leadingParts,
        group([segmentDoc, ...trailingParts], {
          id: groupIds[childIndex]
        })
      ]),
      ...nextParts
    ];
  });
}

// src/print/element.ts
var {
  group: group2,
  indent: indent2,
  indentIfBreak,
  ifBreak: ifBreak2,
  breakParent: breakParent2,
  dedentToRoot,
  softline: softline3,
  line: line3,
  hardline: hardline3
} = import_prettier5.doc.builders;
function printElement(path, options2, print) {
  const node = path.node;
  if (shouldPreserveMalformedOpeningTag(node, options2)) {
    return printMalformedOpeningTag(node);
  }
  const forceInlineIntentLayout = shouldKeepInlineIntentLayout(node, options2);
  const forceMultilineSvgChildren = shouldForceMultilineSvgChildren(node);
  const keepHeadBodyAtRoot = shouldKeepHtmlHeadBodyAtRoot(node, options2);
  if (shouldPreserveContent(node, options2)) {
    return [
      printOpeningTagPrefix(node, options2),
      group2(printOpeningTag(path, options2, print)),
      replaceEndOfLine(getNodeContent(node, options2)),
      ...printClosingTag(node, options2),
      printClosingTagSuffix(node, options2)
    ];
  }
  const shouldHugContent = node.children.length === 1 && isEchoLike(node.children[0]) && node.children[0].isLeadingSpaceSensitive && !node.children[0].hasLeadingSpaces && node.children[0].isTrailingSpaceSensitive && !node.children[0].hasTrailingSpaces;
  const attrGroupId = /* @__PURE__ */ Symbol("element-attr-group-id");
  const printTag = (content) => group2([
    group2(printOpeningTag(path, options2, print), { id: attrGroupId }),
    content,
    printClosingTag(node, options2)
  ]);
  const printChildrenDoc = (childrenDoc) => {
    if (forceInlineIntentLayout) {
      return flattenInlineIntentChildren(childrenDoc);
    }
    if (keepHeadBodyAtRoot) {
      return childrenDoc;
    }
    if (shouldHugContent) {
      return indentIfBreak(childrenDoc, { groupId: attrGroupId });
    }
    if ((isScriptLikeTag(node, options2) || isVueCustomBlock(node, options2)) && node.parent?.kind === 0 /* Root */ && options2.parser === "vue" && !options2.vueIndentScriptAndStyle) {
      return childrenDoc;
    }
    return indent2(childrenDoc);
  };
  const printLineBeforeChildren = () => {
    const firstChild = node.children[0];
    if (forceInlineIntentLayout) {
      return "";
    }
    if (forceMultilineSvgChildren) {
      return hardline3;
    }
    if (shouldHugContent) {
      return ifBreak2(softline3, "", { groupId: attrGroupId });
    }
    if (firstChild.hasLeadingSpaces && firstChild.isLeadingSpaceSensitive) {
      return line3;
    }
    if (firstChild.kind === 2 /* Text */ && node.isWhitespaceSensitive && node.isIndentationSensitive) {
      return dedentToRoot(softline3);
    }
    return softline3;
  };
  const printLineAfterChildren = () => {
    const lastChild = node.children[node.children.length - 1];
    if (forceInlineIntentLayout) {
      return "";
    }
    if (forceMultilineSvgChildren) {
      return hardline3;
    }
    if (!node.hasClosingTag && !node.isSelfClosing && !shouldInsertOptionalClosingTags(options2)) {
      return "";
    }
    if (isRecoveryUnclosedElementWithClosingText(node)) {
      return "";
    }
    const needsToBorrow = node.next ? needsToBorrowPrevClosingTagEndMarker(node.next) : needsToBorrowLastChildClosingTagEndMarker(node.parent);
    if (needsToBorrow) {
      if (lastChild.hasTrailingSpaces && lastChild.isTrailingSpaceSensitive) {
        return " ";
      }
      return "";
    }
    if (shouldHugContent) {
      return ifBreak2(softline3, "", { groupId: attrGroupId });
    }
    if (lastChild.hasTrailingSpaces && lastChild.isTrailingSpaceSensitive) {
      return line3;
    }
    const lastChildTrailingValue = lastChild.kind === 12 /* Comment */ ? getCommentValue(lastChild.rawText) : lastChild.rawText;
    if ((lastChild.kind === 12 /* Comment */ || lastChild.kind === 13 /* BogusComment */ || lastChild.kind === 2 /* Text */ && node.isWhitespaceSensitive && node.isIndentationSensitive) && endsWithIndentedNewline(
      lastChildTrailingValue,
      (options2.tabWidth ?? 2) * countAncestors(path)
    )) {
      return "";
    }
    return softline3;
  };
  if (node.children.length === 0) {
    const shouldPrintDanglingSpaceLine = node.hasDanglingSpaces && node.isDanglingSpaceSensitive && !shouldSuppressDanglingSpaceAtEof(node);
    return printTag(shouldPrintDanglingSpaceLine ? line3 : "");
  }
  return printTag([
    forceBreakContent(node) ? breakParent2 : "",
    printChildrenDoc([printLineBeforeChildren(), printChildren(path, print, options2)]),
    printLineAfterChildren()
  ]);
}
function shouldPreserveMalformedOpeningTag(node, options2) {
  if (node.kind !== 1 /* Element */ || node.openTagEndOffset > node.start || node.hasClosingTag || node.isSelfClosing) {
    return false;
  }
  if (isRecoverableUnterminatedOpeningEcho(node)) {
    return false;
  }
  if (!shouldInsertOptionalClosingTags(options2)) {
    return true;
  }
  return hasComplexMalformedOpeningSyntax(node);
}
function isRecoverableUnterminatedOpeningEcho(node) {
  if (node.kind !== 1 /* Element */) {
    return false;
  }
  if (node.attrs.length > 0 || node.children.length !== 1) {
    return false;
  }
  const onlyChild = node.children[0];
  return (onlyChild.kind === 4 /* Echo */ || onlyChild.kind === 5 /* RawEcho */ || onlyChild.kind === 6 /* TripleEcho */) && onlyChild.start >= node.start && onlyChild.end === node.end;
}
function hasComplexMalformedOpeningSyntax(node) {
  const tokens = node.buildResult.tokens;
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  for (let i = start; i < end; i++) {
    switch (tokens[i].type) {
      case 50 /* TsxGenericType */:
      case 25 /* Directive */:
      case 26 /* DirectiveArgs */:
      case 18 /* EchoStart */:
      case 21 /* RawEchoStart */:
      case 23 /* TripleEchoStart */:
      case 39 /* PhpTagStart */:
      case 29 /* PhpBlockStart */:
        return true;
      default:
        break;
    }
  }
  return node.attrs.length > 1 || node.children.length > 0 || node.source.slice(node.start + 1, node.end).includes("<");
}
function printMalformedOpeningTag(node) {
  return node.source.slice(node.start, node.end).replace(/\s+$/u, "");
}
function flattenInlineIntentChildren(childrenDoc) {
  return import_prettier5.doc.utils.mapDoc(childrenDoc, (current) => {
    if (current === softline3) {
      return "";
    }
    if (current === line3 || current === hardline3) {
      return " ";
    }
    if (current === breakParent2) {
      return "";
    }
    return current;
  });
}
function isRecoveryUnclosedElementWithClosingText(node) {
  return node.kind === 1 /* Element */ && !node.hasClosingTag && !node.isSelfClosing && node.rawTagName.length > 0 && node.openTagEndOffset > 0 && node.source.slice(node.openTagEndOffset, node.end).toLowerCase().includes(`</${node.rawTagName.toLowerCase()}`);
}
function shouldKeepInlineIntentLayout(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.children.length === 0) return false;
  if (!node.hasClosingTag) return false;
  if (node.openTagEndOffset <= node.start) return false;
  if (node.closingTagStartOffset <= node.openTagEndOffset) return false;
  if (!shouldPreserveInlineIntentElement(options2, node.tagName, node.namespace)) {
    return false;
  }
  if (containsBlockDirectiveDescendant(node)) {
    return false;
  }
  if (node.tagName === "svg") {
    let elementChildCount = 0;
    for (const child of node.children) {
      if (child.kind === 1 /* Element */) {
        elementChildCount++;
        if (elementChildCount > 1) {
          return false;
        }
      }
    }
  }
  return hasInlineIntentShellSource(node);
}
function shouldSuppressDanglingSpaceAtEof(node) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.end !== node.source.length) return false;
  return !node.hasClosingTag && !node.isSelfClosing;
}
function hasInlineIntentShellSource(node) {
  const source = node.source.slice(node.start, node.end);
  if (!/[\r\n]/u.test(source)) {
    return true;
  }
  const firstChild = node.children[0];
  const lastChild = node.children[node.children.length - 1];
  if (!firstChild || !lastChild) {
    return false;
  }
  const openingGap = node.source.slice(node.openTagEndOffset, firstChild.start);
  if (/[\r\n]/u.test(openingGap)) {
    return false;
  }
  const closingGap = node.source.slice(lastChild.end, node.closingTagStartOffset);
  return !/[\r\n]/u.test(closingGap);
}
function shouldForceMultilineSvgChildren(node) {
  if (node.kind !== 1 /* Element */) return false;
  if (node.tagName === "clippath") {
    for (const child of node.children) {
      if (child.kind === 1 /* Element */) {
        return true;
      }
    }
    return false;
  }
  if (node.tagName !== "svg") return false;
  let elementChildCount = 0;
  for (const child of node.children) {
    if (child.kind === 1 /* Element */) {
      elementChildCount++;
      if (elementChildCount > 1) {
        return true;
      }
    }
  }
  return false;
}
function containsBlockDirectiveDescendant(node) {
  const stack = [...node.children];
  while (stack.length > 0) {
    const current = stack.pop();
    if (current.kind === 8 /* DirectiveBlock */ || current.kind === 7 /* Directive */ && current.children.length > 0) {
      return true;
    }
    for (let i = 0; i < current.children.length; i++) {
      stack.push(current.children[i]);
    }
  }
  return false;
}
function shouldKeepHtmlHeadBodyAtRoot(node, options2) {
  if (!shouldKeepHeadAndBodyAtRoot(options2)) return false;
  if (node.kind !== 1 /* Element */) return false;
  if (node.namespace.length > 0) return false;
  if (node.tagName !== "html") return false;
  if (node.parent?.kind !== 0 /* Root */) return false;
  const directElementChildren = node.children.filter(
    (child) => child.kind === 1 /* Element */
  );
  if (directElementChildren.length === 0) return false;
  return directElementChildren.every(
    (child) => child.namespace.length === 0 && (child.tagName === "head" || child.tagName === "body")
  );
}
function countAncestors(path) {
  if ("ancestors" in path && Array.isArray(path.ancestors)) {
    return Math.max(path.ancestors.length - 1, 0);
  }
  return 0;
}
function getNodeContent(node, options2) {
  if (!node.hasClosingTag) return "";
  if (!node.openTagEndOffset && !node.closingTagStartOffset) return "";
  let start = node.openTagEndOffset;
  if (node.children.length > 0 && needsToBorrowParentOpeningTagEndMarker(node.children[0])) {
    start -= printOpeningTagEndMarker(node).length;
  }
  let end = node.closingTagStartOffset;
  const last = node.children.length > 0 ? node.children[node.children.length - 1] : null;
  if (last && needsToBorrowParentClosingTagStartMarker(last)) {
    end += printClosingTagStartMarker(node, options2).length;
  } else if (needsToBorrowLastChildClosingTagEndMarker(node)) {
    end -= printClosingTagEndMarker(last, options2).length;
  }
  return node.source.slice(start, end);
}
function getCommentValue(rawText) {
  const match = rawText.match(/^<!--([\s\S]*?)-->$/);
  return match ? match[1] : rawText;
}
function endsWithIndentedNewline(value, indentWidth) {
  let index = value.length - 1;
  let wsCount = 0;
  while (index >= 0) {
    const ch = value.charCodeAt(index);
    if (ch !== 32 && ch !== 9) break;
    wsCount++;
    index--;
  }
  return wsCount === indentWidth && index >= 0 && value.charCodeAt(index) === 10;
}

// src/print/text.ts
var import_prettier6 = require("prettier");
var { line: line4, hardline: hardline4, fill, join: join2 } = import_prettier6.doc.builders;
function printText(node, options2) {
  const text = node.rawText;
  if (node.parent && isEchoLike(node.parent)) {
    const trailingNewlineRegex = /\n[^\S\n]*$/;
    const hasTrailingNewline = trailingNewlineRegex.test(text);
    const value = hasTrailingNewline ? text.replace(trailingNewlineRegex, "") : text;
    return [replaceEndOfLine(value), hasTrailingNewline ? hardline4 : ""];
  }
  const prefix = printOpeningTagPrefix(node);
  const suffix = printClosingTagSuffix(node, options2);
  const printed = getTextValueParts(node);
  if (Array.isArray(printed) && printed.length > 0) {
    printed[0] = [prefix, printed[0]];
    printed.push([printed.pop(), suffix]);
    return fill(printed);
  }
  return [prefix, printed, suffix];
}
function getTextValueParts(node) {
  const value = node.rawText;
  if (node.parent?.isWhitespaceSensitive) {
    if (node.parent.isIndentationSensitive) {
      return replaceEndOfLine(value);
    }
    return replaceEndOfLine(dedentString(htmlTrimPreserveIndentation(value)), hardline4);
  }
  return join2(line4, value.split(/[\t\n\f\r ]+/));
}

// src/print/directive.ts
var import_prettier7 = require("prettier");

// src/print/directive-spacing-context.ts
function getDirectiveName(node) {
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  for (let i = start; i < end; i++) {
    const token = tokens[i];
    if (token.type !== 25 /* Directive */) continue;
    const raw = node.source.slice(token.start, token.end);
    return raw.startsWith("@") ? raw.slice(1).toLowerCase() : raw.toLowerCase();
  }
  return null;
}
function getDirectiveAttributeContextElement(node) {
  let current = node;
  while (current.parent?.kind === 8 /* DirectiveBlock */) {
    current = current.parent;
  }
  const parent = current.parent;
  if (!parent || parent.kind !== 1 /* Element */) {
    return null;
  }
  return current.end <= parent.openTagEndOffset ? parent : null;
}
function isDirectiveInElementOpenTag(node) {
  return getDirectiveAttributeContextElement(node) !== null;
}
function isDirectiveInBladeComponentAttributeContext(node, options2) {
  const element = getDirectiveAttributeContextElement(node);
  if (!element) {
    return false;
  }
  return isBladeComponentTagName(element.fullName, options2);
}
function getEffectiveDirectiveArgSpacingRule(node, options2) {
  return resolveDirectiveArgSpacingRule(
    getDirectiveName(node) ?? "",
    options2,
    isDirectiveInBladeComponentAttributeContext(node, options2)
  );
}

// src/string-utils.ts
function trimFinalLineBreak(text) {
  if (text.endsWith("\r\n")) return text.slice(0, -2);
  if (text.endsWith("\n")) return text.slice(0, -1);
  return text;
}
function normalizeLineEndingsToLf(text) {
  return text.replace(/\r\n?/gu, "\n");
}
function safeSerialize(value) {
  try {
    return JSON.stringify(value) ?? "";
  } catch {
    return String(value);
  }
}
function trimTrailingHorizontalWhitespace(value) {
  return value.replace(/[ \t]+(?=\r?\n|$)/gu, "");
}

// src/print/directive.ts
var { indent: indent3, hardline: hardline5 } = import_prettier7.doc.builders;
function isBranchNode(node) {
  return node.kind === 7 /* Directive */ || node.kind === 11 /* PhpTag */;
}
var BODY_BLANK_LINE_LAYOUT_DIRECTIVES = /* @__PURE__ */ new Set([
  "include",
  "includeif",
  "includewhen",
  "includeunless",
  "includefirst",
  "each"
]);
function isIgnoreRangeNode2(node) {
  return node.kind === 29 /* IgnoreRange */;
}
function printIgnoredDirectiveBodyChild(childPath, options2) {
  const child = childPath.node;
  const ignoreMode = getPrettierIgnoreMode(child);
  if (!(hasPrettierIgnore(child) && ignoreMode === "single")) {
    return null;
  }
  const endLocation = getPrintableSubtreeEnd(child);
  let preservedText = htmlTrimEnd2(
    child.source.slice(
      child.start + (child.prev && needsToBorrowNextOpeningTagStartMarker(child.prev) ? printOpeningTagStartMarker(child).length : 0),
      endLocation - (child.next && needsToBorrowPrevClosingTagEndMarker(child.next) ? printClosingTagEndMarker(child, options2).length : 0)
    )
  );
  if (child.kind === 2 /* Text */ && ignoreMode === "single") {
    preservedText = htmlTrimStart2(preservedText);
  }
  return [
    printOpeningTagPrefix(child, options2),
    replaceEndOfLine(preservedText),
    printClosingTagSuffix(child, options2)
  ];
}
function getSourceBetweenSegments2(prev, next) {
  if (prev.first.source !== next.first.source) {
    return "";
  }
  return getSourceBetweenBounds(prev.first.source, prev.sourceEnd, next.sourceStart);
}
function printBetweenSegments2(prev, next) {
  if (isIgnoreRangeNode2(prev.last) || isIgnoreRangeNode2(next.first)) {
    const sourceBetween = getSourceBetweenSegments2(prev, next);
    if (sourceBetween.length === 0) {
      return "";
    }
    if (!/[\r\n]/u.test(sourceBetween)) {
      return sourceBetween;
    }
    if (hasBlankLineBetween(sourceBetween) && shouldPreserveBodyBlankLine(prev.last, next.first)) {
      return [hardline5, hardline5];
    }
    return hardline5;
  }
  return printBetweenLine2(prev.last, next.first);
}
function printDirective(node, options2) {
  return renderDirectiveTokens(node, options2);
}
function renderDirectiveTokens(node, options2) {
  const br = node.buildResult;
  const tc = node.flat.tokenCount;
  let result = "";
  const argSpacingRule = getEffectiveDirectiveArgSpacingRule(node, options2);
  const start = node.flat.tokenStart;
  let sawDirectiveToken = false;
  let sawArgsToken = false;
  for (let i = 0; i < tc; i++) {
    const tokenIndex = start + i;
    const t = br.tokens[tokenIndex];
    const prev = tokenIndex > start ? br.tokens[tokenIndex - 1] : null;
    const next = tokenIndex + 1 < start + tc ? br.tokens[tokenIndex + 1] : null;
    const tokenText = br.source.slice(t.start, t.end);
    if (t.type === 25 /* Directive */) {
      result += formatDirectiveNameToken(tokenText, options2);
      sawDirectiveToken = true;
      if (next?.type === 26 /* DirectiveArgs */) {
        result += getDirectiveArgSpacingText("", argSpacingRule);
      }
      continue;
    }
    if (!sawDirectiveToken) {
      continue;
    }
    if (t.type === 9 /* Whitespace */ && prev?.type === 25 /* Directive */ && next?.type === 26 /* DirectiveArgs */) {
      result += getDirectiveArgSpacingText(tokenText, argSpacingRule);
      continue;
    }
    if (t.type === 26 /* DirectiveArgs */ && !sawArgsToken) {
      result += trimTrailingHorizontalWhitespace(tokenText);
      sawArgsToken = true;
      continue;
    }
    break;
  }
  if (!sawDirectiveToken) {
    return "";
  }
  if (hasUnterminatedDirectiveArgsAtEof(node)) {
    return result.replace(/\s+$/u, "");
  }
  return result;
}
function hasUnterminatedDirectiveArgsAtEof(node) {
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  for (let i = start; i < end; i++) {
    const token = tokens[i];
    if (token.type !== 26 /* DirectiveArgs */) continue;
    if (token.end < node.source.length) return false;
    const text = node.source.slice(token.start, token.end);
    if (!text.startsWith("(")) return false;
    return !text.trimEnd().endsWith(")");
  }
  return false;
}
function printDirectiveBlock(node, path, print, options2) {
  if (shouldFallbackMalformedDirectiveBlock(node)) {
    return fullText(node).replace(/\s+$/u, "");
  }
  if (shouldFallbackUnterminatedRootDirectiveBlock(node)) {
    return fullText(node).replace(/\s+$/u, "");
  }
  const children = node.children;
  if (children.length === 0) return "";
  const style = getDirectiveBlockStyle(options2);
  if (style !== "multiline" && shouldPreserveInlineBlock(node, style)) {
    return printDirectiveBlockInline(path, print, options2);
  }
  return printDirectiveBlockMultiline(node, path, print, options2);
}
function shouldFallbackMalformedDirectiveBlock(node) {
  return node.children.some((child) => !isBranchNode(child));
}
function shouldFallbackUnterminatedRootDirectiveBlock(node) {
  if (node.parent?.kind !== 0 /* Root */) {
    return false;
  }
  if (/\S/u.test(node.source.slice(node.end))) {
    return false;
  }
  const branches = node.children.filter((child) => isBranchNode(child));
  if (branches.length === 0) {
    return false;
  }
  const lastBranch = branches[branches.length - 1];
  if (lastBranch.children.length === 0) {
    return false;
  }
  if (branches.some((branch) => branch.kind === 11 /* PhpTag */)) {
    return true;
  }
  if (isSimpleUnterminatedDirectiveBody(lastBranch)) {
    return false;
  }
  return true;
}
function isSimpleUnterminatedDirectiveBody(branch) {
  const meaningfulChildren = branch.children.filter(
    (child) => !(child.kind === 2 /* Text */ && child.rawText.trim().length === 0)
  );
  if (meaningfulChildren.length !== 1) {
    return false;
  }
  return isSimpleLeafBodyNode(meaningfulChildren[0]);
}
function isSimpleLeafBodyNode(node) {
  if (node.kind === 2 /* Text */ || node.kind === 4 /* Echo */ || node.kind === 5 /* RawEcho */ || node.kind === 6 /* TripleEcho */) {
    return true;
  }
  if (node.kind !== 1 /* Element */) {
    return false;
  }
  if (node.attrs.length > 0) {
    return false;
  }
  let hasAttribute = false;
  let hasNestedElement = false;
  const stack = [...node.children];
  while (stack.length > 0) {
    const current = stack.pop();
    if (current.kind === 19 /* Attribute */ || current.kind === 20 /* JsxAttribute */) {
      hasAttribute = true;
      continue;
    }
    if (current.kind === 1 /* Element */) {
      hasNestedElement = true;
      break;
    }
    if (current.children.length > 0) {
      stack.push(...current.children);
    }
  }
  return !hasAttribute && !hasNestedElement;
}
function printDirectiveBody(branchPath, print, options2) {
  const docs = [];
  const branch = branchPath.node;
  const segments = getChildPrintSegments(branch.children);
  const renderedChildren = branchPath.map((childPath) => {
    const child = childPath.node;
    if (isBranchNode(child) && child.children.length > 0) {
      return {
        branchDoc: child.kind === 7 /* Directive */ ? renderDirectiveTokens(child, options2) : print(childPath),
        nestedDocs: printDirectiveBody(childPath, print, options2)
      };
    }
    return {
      branchDoc: printDirectiveBodyChild(childPath, print, options2),
      nestedDocs: []
    };
  }, "children");
  for (const [segmentIndex, segment] of segments.entries()) {
    const child = segment.first;
    if (docs.length > 0) {
      const prev = segments[segmentIndex - 1];
      if (prev) {
        docs.push(printBetweenSegments2(prev, segment));
      }
    }
    const rendered = renderedChildren[segment.startIndex];
    if (!rendered) {
      continue;
    }
    if (isBranchNode(child) && child.children.length > 0) {
      docs.push(rendered.branchDoc);
      const nestedDocs = rendered.nestedDocs;
      if (nestedDocs.length > 0) {
        docs.push(indent3([hardline5, nestedDocs]));
      }
    } else {
      docs.push(rendered.branchDoc);
    }
  }
  return docs;
}
function printDirectiveBodyInline(branchPath, print, options2) {
  const docs = [];
  const segments = getChildPrintSegments(branchPath.node.children);
  const printedChildren = branchPath.map(
    (childPath) => printDirectiveBodyChild(childPath, print, options2),
    "children"
  );
  for (const [segmentIndex, segment] of segments.entries()) {
    const prev = segmentIndex > 0 ? segments[segmentIndex - 1] : null;
    if (prev !== null) {
      const between = isIgnoreRangeNode2(prev.last) || isIgnoreRangeNode2(segment.first) ? getSourceBetweenSegments2(prev, segment) : getSourceBetween2(prev.last, segment.first);
      if (isIgnoreRangeNode2(prev.last) || isIgnoreRangeNode2(segment.first)) {
        if (between.length > 0) {
          docs.push(
            hasBlankLineBetween(between) ? [hardline5, hardline5] : /[\r\n]/u.test(between) ? hardline5 : between
          );
        }
      } else if (/\s/.test(between)) {
        docs.push(" ");
      }
    }
    const printed = printedChildren[segment.startIndex];
    if (printed !== "") {
      docs.push(printed);
    }
  }
  return docs;
}
function printDirectiveBlockInline(path, print, options2) {
  const segments = [];
  let previousDirective = null;
  path.each((childPath) => {
    const child = childPath.node;
    if (!isBranchNode(child)) {
      segments.push(print(childPath));
      return;
    }
    if (segments.length > 0) {
      const separator = getInlineDirectiveSeparator(previousDirective, child);
      if (separator.length > 0) {
        segments.push(separator);
      }
    }
    segments.push(print(childPath));
    if (child.children.length > 0) {
      const body = printDirectiveBodyInline(childPath, print, options2);
      if (body.length > 0) {
        segments.push(" ", body);
      }
    }
    previousDirective = child;
  }, "children");
  return segments;
}
function printDirectiveBlockMultiline(node, path, print, options2) {
  const branches = node.children.filter((child) => isBranchNode(child));
  if (branches.length === 0) {
    return path.map((childPath) => print(childPath), "children");
  }
  const segments = [];
  const separators = [];
  const blankMode = getBladeBlankLinesMode(options2);
  let directiveIndex = 0;
  path.each((childPath) => {
    const child = childPath.node;
    if (!isBranchNode(child)) return;
    const segment = [print(childPath)];
    if (child.children.length > 0) {
      const bodyDocs = printDirectiveBody(childPath, print, options2);
      if (bodyDocs.length > 0) {
        segment.push(indent3([hardline5, bodyDocs]));
      }
    }
    segments.push(segment);
    const nextDirective = branches[directiveIndex + 1];
    if (!nextDirective) return;
    separators.push(getDirectiveSeparator(child, nextDirective, blankMode));
    directiveIndex++;
  }, "children");
  if (segments.length === 1) return segments[0];
  const output = [segments[0]];
  for (let i = 0; i < separators.length; i++) {
    output.push(separators[i], segments[i + 1]);
  }
  return output;
}
function printDirectiveBodyChild(childPath, print, options2) {
  const child = childPath.node;
  const ignored = printIgnoredDirectiveBodyChild(childPath, options2);
  if (ignored !== null) {
    return ignored;
  }
  if (child.kind === 2 /* Text */ && (child.prev !== null && isEchoLike(child.prev) || child.next !== null && isEchoLike(child.next))) {
    return replaceEndOfLine(child.rawText);
  }
  return print(childPath);
}
function shouldPreserveInlineBlock(node, style) {
  const inlineAtTopLevel = isInlineDirectiveBlock(node);
  if (inlineAtTopLevel) return true;
  if (style !== "inline-if-short") {
    return false;
  }
  const directives = node.children.filter((child) => isBranchNode(child));
  if (directives.length !== 2) return false;
  const opener = directives[0];
  if (opener.children.length !== 1) return false;
  const onlyBody = opener.children[0];
  if (onlyBody.kind !== 2 /* Text */ && onlyBody.kind !== 4 /* Echo */ && onlyBody.kind !== 5 /* RawEcho */ && onlyBody.kind !== 6 /* TripleEcho */) {
    return false;
  }
  return fullText(node).trim().length <= 60;
}
function getDirectiveSeparator(prev, next, mode) {
  if (shouldSuppressDirectiveSeparator(prev, next)) {
    return "";
  }
  const between = getDirectiveSourceBetweenBranches(prev, next);
  if (mode === "always") {
    return [hardline5, hardline5];
  }
  return hasBlankLineBetween(between) ? [hardline5, hardline5] : hardline5;
}
function getInlineDirectiveSeparator(prev, next) {
  if (!prev) return "";
  if (shouldSuppressDirectiveSeparator(prev, next)) {
    return "";
  }
  const between = getSourceBetween2(prev, next);
  if (between.length === 0) {
    return "";
  }
  return /\s$/.test(between) ? " " : "";
}
function hasBlankLineBetween(between) {
  return /\r?\n\s*\r?\n/.test(between);
}
function getPhpTagKeyword(node) {
  if (node.kind !== 11 /* PhpTag */) {
    return null;
  }
  const match = fullText(node).trim().match(/^<\?(?:php)?\s*([a-z_][a-z0-9_]*)/iu);
  return match?.[1]?.toLowerCase() ?? null;
}
function shouldSuppressDirectiveSeparator(prev, next) {
  return prev.children.length === 0 && getPhpTagKeyword(prev) === "switch" && (getPhpTagKeyword(next) === "case" || getPhpTagKeyword(next) === "default");
}
function isInlineDirectiveBlock(node) {
  const directives = node.children.filter((child) => isBranchNode(child));
  if (directives.length === 0) return false;
  for (let i = 0; i < directives.length; i++) {
    const directive = directives[i];
    if (directive.children.length > 0) {
      const firstBodyChild = directive.children[0];
      if (firstBodyChild.startLine > directive.endLine) {
        return false;
      }
      for (const child of directive.children) {
        if (child.endLine > child.startLine) {
          return false;
        }
        if (!isDirectiveInElementOpenTag(directive) && child.kind === 1 /* Element */) {
          return false;
        }
      }
      for (let j = 1; j < directive.children.length; j++) {
        if (directive.children[j].startLine > directive.children[j - 1].endLine) {
          return false;
        }
      }
    }
    const nextDirective = directives[i + 1];
    const branchEndLine = directive.children.length > 0 ? directive.children[directive.children.length - 1].endLine : directive.endLine;
    if (nextDirective && nextDirective.startLine > branchEndLine) {
      return false;
    }
  }
  return true;
}
function getSourceBetween2(prev, next) {
  if (prev.source !== next.source) {
    return "";
  }
  return getSourceBetweenBounds(prev.source, prev.end, next.start);
}
function getSourceBetweenBounds(source, start, end) {
  if (start > end) {
    return "";
  }
  return source.slice(start, end);
}
function getDirectiveSourceBetweenBranches(prevDirective, nextDirective) {
  if (prevDirective.source !== nextDirective.source) {
    return "";
  }
  const prevBranchEnd = getDirectiveBranchEnd(prevDirective);
  return getSourceBetweenBounds(prevDirective.source, prevBranchEnd, nextDirective.start);
}
function getDirectiveBranchEnd(directive) {
  if (directive.children.length === 0) {
    return directive.end;
  }
  return directive.children[directive.children.length - 1].end;
}
function printBetweenLine2(prev, next) {
  if (prev.kind === 22 /* NonOutput */ || next.kind === 22 /* NonOutput */) {
    return "";
  }
  const sourceBetween = getSourceBetween2(prev, next);
  const hasLineBreakBetweenNodes = /[\r\n]/.test(sourceBetween) || next.startLine > prev.endLine;
  if (isIgnoreRangeNode2(prev) || isIgnoreRangeNode2(next)) {
    if (sourceBetween.length === 0) {
      return "";
    }
    if (hasBlankLineBetween(sourceBetween)) {
      return [hardline5, hardline5];
    }
    if (hasLineBreakBetweenNodes) {
      return hardline5;
    }
    return sourceBetween;
  }
  if (hasBlankLineBetween(sourceBetween) && shouldPreserveBodyBlankLine(prev, next)) {
    return [hardline5, hardline5];
  }
  if (isTextLikeNode(prev) && isTextLikeNode(next)) {
    if (prev.isTrailingSpaceSensitive) {
      if (prev.hasTrailingSpaces) {
        if (isEchoLike(prev) || isEchoLike(next)) {
          return hasLineBreakBetweenNodes ? hardline5 : " ";
        }
        return preferHardlineAsLeadingSpaces(next) ? hardline5 : import_prettier7.doc.builders.line;
      }
      return "";
    }
    if (isEchoLike(prev) || isEchoLike(next)) {
      return hasLineBreakBetweenNodes ? hardline5 : "";
    }
    return preferHardlineAsLeadingSpaces(next) ? hardline5 : import_prettier7.doc.builders.softline;
  }
  if (!next.isLeadingSpaceSensitive || preferHardlineAsLeadingSpaces(next)) {
    return hardline5;
  }
  if (next.hasLeadingSpaces) {
    return import_prettier7.doc.builders.line;
  }
  return import_prettier7.doc.builders.softline;
}
function shouldPreserveBodyBlankLine(prev, next) {
  if (isBranchNode(next) && next.children.length > 0) {
    return false;
  }
  return isBodyLayoutDirective(prev) && isContainerLikeBodySibling(next) || isBodyLayoutDirective(next) && isContainerLikeBodySibling(prev);
}
function isBodyLayoutDirective(node) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  const name = getDirectiveName(node);
  if (name === null) {
    return false;
  }
  return BODY_BLANK_LINE_LAYOUT_DIRECTIVES.has(name);
}
function isContainerLikeBodySibling(node) {
  if (isTextLikeNode(node)) {
    return false;
  }
  if (node.kind === 1 /* Element */) {
    return node.children.length > 0 && isComponentLikeElement(node);
  }
  return node.children.length > 0;
}
function isComponentLikeElement(node) {
  return node.tagName.includes("-") || node.fullName.includes(":");
}

// src/print/echo.ts
function printEcho(node, options2) {
  const spacing = getEchoSpacingMode(options2);
  if (spacing === "preserve") {
    if (isUnterminatedEchoAtEof(node)) {
      return trimTrailingWhitespace(fullText(node));
    }
    return fullText(node);
  }
  const content = getEchoContent(node);
  if (content === null) {
    return fullText(node);
  }
  const trimmed = content.trim();
  const { open, close } = getEchoDelimiters2(node);
  if (trimmed.length === 0) {
    return spacing === "tight" ? `${open}${close}` : `${open} ${close}`;
  }
  if (trimmed.includes("\n")) {
    return `${open}
${trimmed}
${close}`;
  }
  if (spacing === "tight") {
    return `${open}${trimmed}${close}`;
  }
  return `${open} ${trimmed} ${close}`;
}
function getEchoContent(node) {
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  const parts = [];
  for (let i = start; i < end; i++) {
    const token = tokens[i];
    if (token.type === 20 /* EchoContent */) {
      parts.push(node.source.slice(token.start, token.end));
    }
  }
  if (parts.length === 0) return null;
  return parts.join("");
}
function getEchoDelimiters2(node) {
  switch (node.kind) {
    case 5 /* RawEcho */:
      return { open: "{!!", close: "!!}" };
    case 6 /* TripleEcho */:
      return { open: "{{{", close: "}}}" };
    case 4 /* Echo */:
    default:
      return { open: "{{", close: "}}" };
  }
}
function isUnterminatedEchoAtEof(node) {
  if (node.end !== node.source.length) {
    return false;
  }
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  const endType = node.kind === 5 /* RawEcho */ ? 22 /* RawEchoEnd */ : node.kind === 6 /* TripleEcho */ ? 24 /* TripleEchoEnd */ : 19 /* EchoEnd */;
  for (let i = start; i < end; i++) {
    if (tokens[i].type === endType) {
      return false;
    }
  }
  return true;
}
function trimTrailingWhitespace(value) {
  return value.replace(/\s+$/u, "");
}

// src/print/comment.ts
function printComment(node, options2) {
  if (isIeConditionalStartComment(node)) {
    return [printOpeningTagStart(node, options2), printClosingTagEnd(node, options2)];
  }
  return [
    printOpeningTagPrefix(node, options2),
    replaceEndOfLine(fullText(node)),
    printClosingTagSuffix(node, options2)
  ];
}
function printBladeComment(node) {
  return fullText(node);
}

// src/print/doctype.ts
function printDoctype(node, options2) {
  return [
    printOpeningTagPrefix(node, options2),
    formatDoctype(node.rawText, options2),
    printClosingTagSuffix(node, options2)
  ];
}

// src/print/embed.ts
var import_prettier14 = require("prettier");
var import_prettier15 = require("prettier");

// src/print/embed/attribute.ts
var import_prettier10 = require("prettier");
var import_prettier11 = require("prettier");
var import_parse_srcset = __toESM(require("@prettier/parse-srcset"), 1);

// src/print/embed/utilities.ts
var import_prettier8 = require("prettier");
var { group: group3, indent: indent4, softline: softline4 } = import_prettier8.doc.builders;
function printExpand(content, canHaveTrailingWhitespace = true) {
  return [indent4([softline4, content]), canHaveTrailingWhitespace ? softline4 : ""];
}
function shouldHugJsExpression(ast, options2) {
  const rootNode = ast.type === "NGRoot" ? ast.node?.type === "NGMicrosyntax" && Array.isArray(ast.node?.body) && ast.node.body.length === 1 && ast.node.body[0]?.type === "NGMicrosyntaxExpression" ? ast.node.body[0].expression : ast.node : ast.type === "JsExpressionRoot" ? ast.node : ast;
  if (!rootNode || typeof rootNode !== "object") return false;
  const root = rootNode;
  return root.type === "ObjectExpression" || root.type === "ArrayExpression" || (options2.parser === "__vue_expression" || options2.parser === "__vue_ts_expression" || options2.parser === "__ng_binding" || options2.parser === "__ng_directive") && (root.type === "TemplateLiteral" || root.type === "StringLiteral");
}
async function formatAttributeValue(code, textToDoc, options2, shouldHugFn) {
  const textToDocOptions = {
    __isInHtmlAttribute: true,
    __embeddedInHtml: true,
    ...options2
  };
  let shouldHug = true;
  if (shouldHugFn) {
    textToDocOptions.__onHtmlBindingRoot = (ast, opts) => {
      shouldHug = shouldHugFn(ast, opts);
    };
  }
  const result = await textToDoc(code, textToDocOptions);
  return shouldHug ? group3(result) : printExpand(result);
}

// src/print/embed/alpine-attributes.ts
function getLineIndent(line6) {
  return line6.match(/^[\t ]*/u)?.[0].length ?? 0;
}
function isBracketPair(open, close) {
  return open === "[" && close === "]" || open === "{" && close === "}" || open === "(" && close === ")";
}
function normalizeMultilineFallbackValueIndentation(value) {
  if (!value.includes("\n")) return value;
  const lines = value.replace(/\r\n/g, "\n").split("\n");
  let firstNonEmpty = -1;
  let lastNonEmpty = -1;
  for (let i = 0; i < lines.length; i++) {
    if (lines[i].trim().length === 0) continue;
    if (firstNonEmpty === -1) firstNonEmpty = i;
    lastNonEmpty = i;
  }
  if (firstNonEmpty === -1 || lastNonEmpty === -1 || firstNonEmpty >= lastNonEmpty) {
    return value;
  }
  const firstTrimmed = lines[firstNonEmpty].trim();
  const lastTrimmed = lines[lastNonEmpty].trim();
  if (firstTrimmed.length === 0 || lastTrimmed.length === 0) {
    return value;
  }
  const open = firstTrimmed[0];
  const close = lastTrimmed[0];
  if (!isBracketPair(open, close)) {
    return value;
  }
  const closeIndent = getLineIndent(lines[lastNonEmpty]);
  let minMiddleIndent = Number.POSITIVE_INFINITY;
  for (let i = firstNonEmpty + 1; i < lastNonEmpty; i++) {
    if (lines[i].trim().length === 0) continue;
    const indent7 = getLineIndent(lines[i]);
    if (indent7 < minMiddleIndent) minMiddleIndent = indent7;
  }
  if (!Number.isFinite(minMiddleIndent)) {
    return value;
  }
  const targetMiddleIndent = closeIndent + 2;
  const shiftLeft = minMiddleIndent - targetMiddleIndent;
  if (shiftLeft <= 0) {
    return value;
  }
  const output = [...lines];
  for (let i = firstNonEmpty + 1; i < lastNonEmpty; i++) {
    const line6 = output[i];
    if (line6.trim().length === 0) {
      continue;
    }
    output[i] = line6.slice(Math.min(shiftLeft, line6.length));
  }
  return output.join("\n");
}
function hasBladeValueSyntax(node) {
  const value = getUnescapedAttributeValue(node);
  return value.includes("{{") || value.includes("{!!");
}
var ALPINE_DIRECTIVES = /* @__PURE__ */ new Map([
  // Core directives
  ["x-data", "expression"],
  ["x-model", "expression"],
  ["x-modelable", "expression"],
  ["x-show", "expression"],
  ["x-if", "expression"],
  ["x-for", "expression"],
  ["x-text", "expression"],
  ["x-html", "expression"],
  ["x-effect", "expression"],
  ["x-id", "expression"],
  ["x-teleport", "expression"],
  ["x-init", "statement"],
  // Plugin directives
  ["x-intersect", "expression"],
  ["x-trap", "expression"],
  ["x-mask", "expression"],
  ["x-sort", "expression"],
  ["x-anchor", "expression"],
  ["x-persist", "expression"],
  ["x-resize", "statement"]
]);
function getAlpineDirectiveInfo(name) {
  const lower = name.toLowerCase();
  if (lower.startsWith("@") || lower.startsWith("x-on:")) {
    return { kind: "statement", name };
  }
  if (lower.startsWith(":") || lower.startsWith("x-bind:")) {
    return { kind: "expression", name };
  }
  for (const [directive, kind] of ALPINE_DIRECTIVES) {
    if (lower === directive || lower.startsWith(`${directive}.`) || lower.startsWith(`${directive}:`)) {
      return { kind, name };
    }
  }
  return null;
}
function isSyntaxError(error) {
  return typeof error === "object" && error !== null && "cause" in error && typeof error.cause === "object" && error.cause?.code === "BABEL_PARSER_SYNTAX_ERROR";
}
async function formatAsExpression(value, textToDoc) {
  return formatAttributeValue(
    value,
    textToDoc,
    { parser: "__js_expression" },
    shouldHugJsExpression
  );
}
async function formatAsStatement(value, textToDoc) {
  return formatAttributeValue(
    value,
    textToDoc,
    { parser: "babel", __isHtmlInlineEventHandler: true },
    () => false
  );
}
async function printAlpineDirective(info, value, textToDoc) {
  const strategies = info.kind === "statement" ? [formatAsStatement, formatAsExpression] : [formatAsExpression, formatAsStatement];
  let lastError;
  for (const strategy of strategies) {
    try {
      return await strategy(value, textToDoc);
    } catch (error) {
      if (!isSyntaxError(error)) {
        throw error;
      }
      lastError = error;
    }
  }
  if (lastError) {
    return normalizeMultilineFallbackValueIndentation(value);
  }
  return value;
}
var isAlpineAttribute = (path, options2) => {
  if (options2.parentParser) {
    return false;
  }
  const node = path.node;
  if (hasBladeValueSyntax(node)) {
    return false;
  }
  if (!isStaticAttributeValue(node)) {
    return false;
  }
  if (!isStaticAttributeName(node)) {
    return false;
  }
  const name = getAttributeNameRaw(node);
  if (!name) {
    return false;
  }
  return getAlpineDirectiveInfo(name) !== null;
};
var printAlpineAttribute = async (textToDoc, _print, path) => {
  const node = path.node;
  if (!isStaticAttributeName(node)) {
    return void 0;
  }
  const name = getAttributeNameRaw(node);
  const info = getAlpineDirectiveInfo(name);
  if (!info) {
    return void 0;
  }
  const value = getUnescapedAttributeValue(node);
  if (!value) {
    return void 0;
  }
  if (!isStaticAttributeValue(node)) {
    return void 0;
  }
  return printAlpineDirective(info, value, textToDoc);
};
var alpineAttributePrinters = [
  {
    test: isAlpineAttribute,
    print: printAlpineAttribute
  }
];

// src/print/embed/tailwind.ts
var MAX_CLASS_SORT_CACHE_SIZE = 500;
var parserIds = /* @__PURE__ */ new WeakMap();
var classSortCache = /* @__PURE__ */ new Map();
var nextParserId = 1;
var importedTailwindParserPromise = null;
function getPlugins(options2) {
  const plugins = options2.plugins;
  return Array.isArray(plugins) ? plugins : [];
}
function hasTailwindOptionShape(plugin2) {
  const options2 = plugin2.options;
  if (!options2 || typeof options2 !== "object") return false;
  const optionRecord = options2;
  return "tailwindConfig" in optionRecord || "tailwindStylesheet" in optionRecord || "tailwindAttributes" in optionRecord || "tailwindFunctions" in optionRecord;
}
function getHtmlParserFromPlugin(plugin2) {
  const parsers2 = plugin2.parsers;
  if (!parsers2 || typeof parsers2 !== "object") return null;
  const htmlParser = parsers2.html;
  if (!htmlParser || typeof htmlParser !== "object") return null;
  return typeof htmlParser.parse === "function" ? htmlParser : null;
}
function isTailwindPlugin(plugin2) {
  return plugin2.name === "prettier-plugin-tailwindcss" || hasTailwindOptionShape(plugin2);
}
function findTailwindParserInLoadedPlugins(options2) {
  for (const plugin2 of getPlugins(options2)) {
    if (!plugin2 || typeof plugin2 !== "object") continue;
    const pluginRecord = plugin2;
    if (!isTailwindPlugin(pluginRecord)) continue;
    const htmlParser = getHtmlParserFromPlugin(pluginRecord);
    if (htmlParser) return htmlParser;
  }
  return null;
}
function hasTailwindPluginReference(options2) {
  for (const plugin2 of getPlugins(options2)) {
    if (typeof plugin2 === "string") {
      if (plugin2.includes("prettier-plugin-tailwindcss")) {
        return true;
      }
      continue;
    }
    if (plugin2 instanceof URL) {
      if (plugin2.href.includes("prettier-plugin-tailwindcss")) {
        return true;
      }
    }
  }
  return false;
}
async function loadTailwindParserFromModule() {
  if (!importedTailwindParserPromise) {
    importedTailwindParserPromise = (async () => {
      try {
        const tailwindModuleId = "prettier-plugin-tailwindcss";
        const mod = await import(tailwindModuleId);
        const moduleRecord = mod;
        const directParser = getHtmlParserFromPlugin(moduleRecord);
        if (directParser) return directParser;
        const defaultExport = moduleRecord.default;
        if (!defaultExport || typeof defaultExport !== "object") return null;
        return getHtmlParserFromPlugin(defaultExport);
      } catch {
        return null;
      }
    })();
  }
  return importedTailwindParserPromise;
}
async function resolveTailwindParser(options2) {
  const loadedParser = findTailwindParserInLoadedPlugins(options2);
  if (loadedParser) return loadedParser;
  if (!hasTailwindPluginReference(options2)) return null;
  return loadTailwindParserFromModule();
}
function encodeSyntheticHtmlAttributeValue(value) {
  return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;");
}
function decodeSyntheticHtmlAttributeValue(value) {
  return value.replaceAll("&quot;", '"').replaceAll("&lt;", "<").replaceAll("&amp;", "&");
}
function extractClassAttributeValue(ast) {
  const stack = [ast];
  const visited = /* @__PURE__ */ new Set();
  while (stack.length > 0) {
    const current = stack.pop();
    if (!current || typeof current !== "object") continue;
    if (visited.has(current)) continue;
    visited.add(current);
    const record = current;
    if (record.name === "class" && typeof record.value === "string") {
      return record.value;
    }
    for (const value of Object.values(record)) {
      if (!value || typeof value !== "object") continue;
      if (Array.isArray(value)) {
        for (let i = value.length - 1; i >= 0; i--) {
          stack.push(value[i]);
        }
      } else {
        stack.push(value);
      }
    }
  }
  return null;
}
function getParserId(parser) {
  const key = parser;
  let parserId = parserIds.get(key);
  if (!parserId) {
    parserId = nextParserId++;
    parserIds.set(key, parserId);
  }
  return parserId;
}
function getSortCacheKey(parser, value, options2) {
  const opts = options2;
  const parserId = getParserId(parser);
  const optionsKey = safeSerialize({
    filepath: opts.filepath,
    tailwindConfig: opts.tailwindConfig,
    tailwindEntryPoint: opts.tailwindEntryPoint,
    tailwindStylesheet: opts.tailwindStylesheet,
    tailwindPackageName: opts.tailwindPackageName,
    tailwindAttributes: opts.tailwindAttributes,
    tailwindFunctions: opts.tailwindFunctions,
    tailwindPreserveWhitespace: opts.tailwindPreserveWhitespace,
    tailwindPreserveDuplicates: opts.tailwindPreserveDuplicates
  });
  return `${parserId}|${optionsKey}|${value}`;
}
function setCachedSortResult(key, value) {
  if (classSortCache.size >= MAX_CLASS_SORT_CACHE_SIZE) {
    classSortCache.clear();
  }
  classSortCache.set(key, value);
}
function createTailwindParseOptions(options2) {
  return {
    ...options2,
    parser: "html"
  };
}
async function sortClassNamesWithTailwind(value, options2) {
  if (value.trim().length === 0) {
    return "";
  }
  const tailwindParser = await resolveTailwindParser(options2);
  if (!tailwindParser) return null;
  const cacheKey = getSortCacheKey(tailwindParser, value, options2);
  const cached = classSortCache.get(cacheKey);
  if (cached !== void 0) return cached;
  try {
    const encodedValue = encodeSyntheticHtmlAttributeValue(value);
    const ast = await tailwindParser.parse(
      `<div class="${encodedValue}"></div>`,
      createTailwindParseOptions(options2)
    );
    const sortedClassValue = extractClassAttributeValue(ast);
    if (typeof sortedClassValue !== "string") return null;
    const decodedValue = decodeSyntheticHtmlAttributeValue(sortedClassValue);
    setCachedSortResult(cacheKey, decodedValue);
    return decodedValue;
  } catch {
    return null;
  }
}

// src/print/embed/embedded-parser-plugins.ts
var EMBEDDED_PARSER_PLUGIN_MODULES = {
  babel: ["prettier/plugins/babel", "prettier/plugins/estree"],
  "babel-ts": ["prettier/plugins/babel", "prettier/plugins/estree"],
  flow: ["prettier/plugins/babel", "prettier/plugins/estree"],
  typescript: ["prettier/plugins/typescript", "prettier/plugins/estree"],
  css: ["prettier/plugins/postcss"],
  scss: ["prettier/plugins/postcss"],
  less: ["prettier/plugins/postcss"],
  markdown: ["prettier/plugins/markdown"],
  mdx: ["prettier/plugins/markdown"]
};
var importedPluginPromises = /* @__PURE__ */ new Map();
function getPlugins2(options2) {
  const plugins = options2.plugins;
  return Array.isArray(plugins) ? plugins : [];
}
function hasParser(plugin2, parser) {
  if (!plugin2 || typeof plugin2 !== "object") return false;
  const parsers2 = plugin2.parsers;
  if (!parsers2 || typeof parsers2 !== "object") return false;
  return parser in parsers2;
}
function getDefaultExportCandidate(plugin2) {
  if (!plugin2 || typeof plugin2 !== "object") return null;
  const defaultExport = plugin2.default;
  return defaultExport && typeof defaultExport === "object" ? defaultExport : null;
}
function normalizePlugin(plugin2) {
  const defaultExport = getDefaultExportCandidate(plugin2);
  if (defaultExport) {
    const defaultRecord = defaultExport;
    if (typeof defaultRecord.parsers === "object" || typeof defaultRecord.printers === "object" || Array.isArray(defaultRecord.languages)) {
      return defaultExport;
    }
  }
  return plugin2;
}
function hasParserInPlugins(plugins, parser) {
  return plugins.some((plugin2) => hasParser(plugin2, parser));
}
async function loadPluginModule(moduleId) {
  let promise = importedPluginPromises.get(moduleId);
  if (!promise) {
    promise = (async () => {
      try {
        const mod = await import(moduleId);
        return normalizePlugin(mod);
      } catch {
        return null;
      }
    })();
    importedPluginPromises.set(moduleId, promise);
  }
  return promise;
}
async function resolveEmbeddedParserPlugins(options2, parser) {
  const plugins = getPlugins2(options2).map(normalizePlugin);
  if (hasParserInPlugins(plugins, parser)) {
    return plugins;
  }
  const moduleIds = EMBEDDED_PARSER_PLUGIN_MODULES[parser] ?? [];
  if (moduleIds.length === 0) {
    return plugins;
  }
  const resolved = [...plugins];
  for (const moduleId of moduleIds) {
    const plugin2 = await loadPluginModule(moduleId);
    if (!plugin2) continue;
    if (resolved.includes(plugin2)) continue;
    resolved.push(plugin2);
  }
  return resolved;
}

// src/print/embed/php-plugin.ts
var importedPhpPluginPromise = null;
var PHP_PLUGIN_MODULE_IDS = ["@prettier/plugin-php", "@prettier/plugin-php/standalone"];
var moduleImporter = (moduleId) => import(moduleId);
function getPlugins3(options2) {
  const plugins = options2.plugins;
  return Array.isArray(plugins) ? plugins : [];
}
function getDefaultExportCandidate2(plugin2) {
  if (!plugin2 || typeof plugin2 !== "object") return null;
  const defaultExport = plugin2.default;
  return defaultExport && typeof defaultExport === "object" ? defaultExport : null;
}
function isPhpParser(value) {
  return !!value && typeof value === "object" && typeof value.parse === "function";
}
function isPhpParserFunction(value) {
  return typeof value === "function";
}
function hasPhpParser(plugin2) {
  if (!plugin2 || typeof plugin2 !== "object") return false;
  const phpEntry = plugin2.parsers?.php;
  return isPhpParser(phpEntry) || isPhpParserFunction(phpEntry);
}
function normalizePlugin2(plugin2) {
  if (hasPhpParser(plugin2)) {
    return plugin2;
  }
  const defaultExport = getDefaultExportCandidate2(plugin2);
  if (defaultExport && hasPhpParser(defaultExport)) {
    return defaultExport;
  }
  return plugin2;
}
async function loadPhpPluginFromModule() {
  if (!importedPhpPluginPromise) {
    importedPhpPluginPromise = (async () => {
      for (const phpModuleId of PHP_PLUGIN_MODULE_IDS) {
        try {
          const mod = await moduleImporter(phpModuleId);
          const moduleRecord = mod;
          if (hasPhpParser(moduleRecord)) {
            return moduleRecord;
          }
          const defaultExport = moduleRecord.default;
          if (hasPhpParser(defaultExport)) {
            return defaultExport;
          }
        } catch {
        }
      }
      return null;
    })();
  }
  return importedPhpPluginPromise;
}
async function resolvePhpPlugins(options2) {
  const plugins = getPlugins3(options2).map(normalizePlugin2);
  if (plugins.some(hasPhpParser)) {
    return plugins;
  }
  const phpPlugin = await loadPhpPluginFromModule();
  if (!phpPlugin) {
    return null;
  }
  return [...plugins, phpPlugin];
}

// src/print/embed/php.ts
var import_prettier9 = require("prettier");
var MAX_PHP_FORMAT_CACHE_SIZE = 500;
var START_MARKER_COMMENT = "/*__BLADE_PHP_FMT_START__*/";
var END_MARKER_COMMENT = "/*__BLADE_PHP_FMT_END__*/";
var DIRECTIVE_START_MARKER_COMMENT = "/*__BDS__*/";
var DIRECTIVE_END_MARKER_COMMENT = "/*__BDE__*/";
var phpFormatCache = /* @__PURE__ */ new Map();
var BROWSER_DEFAULT_PHP_VERSION = "8.4";
var PHP_INLINE_WRAPPER_PRINT_WIDTH_MARGIN = 8;
var FORCED_DIRECTIVE_ARG_TRAILING_COMMA = false;
function getMode(options2) {
  const rawOptions = options2;
  const mode = rawOptions.bladePhpFormatting;
  if (mode === "safe" || mode === "aggressive") {
    return mode;
  }
  return "off";
}
function parsePhpFormattingTargets(options2) {
  const raw = options2.bladePhpFormattingTargets;
  const allTargets = ["directiveArgs", "echo", "phpBlock", "phpTag"];
  if (raw === void 0 || raw === null) {
    return new Set(allTargets);
  }
  if (!Array.isArray(raw)) {
    return new Set(allTargets);
  }
  if (raw.length === 0) {
    return /* @__PURE__ */ new Set();
  }
  const normalized = raw.filter((item) => typeof item === "string").flatMap((item) => item.split(/[,\s]+/u)).map((token) => token.trim().toLowerCase()).filter(Boolean);
  const out = /* @__PURE__ */ new Set();
  for (const token of normalized) {
    if (token === "all") {
      return new Set(allTargets);
    }
    if (token === "none") {
      continue;
    }
    if (token === "echo" || token === "echoes") {
      out.add("echo");
      continue;
    }
    if (token === "directiveargs" || token === "directive-args" || token === "directive_args") {
      out.add("directiveArgs");
      continue;
    }
    if (token === "phpblock" || token === "php-block" || token === "php_block") {
      out.add("phpBlock");
      continue;
    }
    if (token === "phptag" || token === "php-tag" || token === "php_tag") {
      out.add("phpTag");
      continue;
    }
  }
  return out;
}
function isPhpTargetEnabled(options2, target) {
  return parsePhpFormattingTargets(options2).has(target);
}
function isPhpFormattingEnabled(options2) {
  return getMode(options2) !== "off";
}
function isPhpTagNode(node) {
  return node.kind === 11 /* PhpTag */;
}
function isPhpBlockNode(node) {
  return node.kind === 10 /* PhpBlock */;
}
var isEchoNode = isEchoLike;
function isInBladeComponentOpenTag(node, options2) {
  const parent = node.parent;
  if (!parent || parent.kind !== 1 /* Element */) return false;
  if (parent.openTagEndOffset === 0) return false;
  if (node.end > parent.openTagEndOffset) return false;
  return isBladeComponentTagName(parent.fullName, options2);
}
function isDirectiveWithArgsNode(node) {
  if (node.kind !== 7 /* Directive */) return false;
  return findFirstToken(node, 26 /* DirectiveArgs */) !== null;
}
function nodeTokens(node) {
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  return node.buildResult.tokens.slice(start, end);
}
function findFirstToken(node, type) {
  for (const token of nodeTokens(node)) {
    if (token.type === type) return token;
  }
  return null;
}
function getTextBetweenMarkers(formatted, startMarker = START_MARKER_COMMENT, endMarker = END_MARKER_COMMENT) {
  const startMarkerIndex = formatted.indexOf(startMarker);
  if (startMarkerIndex < 0) return null;
  const contentStart = startMarkerIndex + startMarker.length;
  const endMarkerIndex = formatted.indexOf(endMarker, contentStart);
  if (endMarkerIndex < 0) return null;
  return formatted.slice(contentStart, endMarkerIndex);
}
function dedentMultiline(text) {
  const normalized = normalizeLineEndingsToLf(text);
  if (!normalized.includes("\n")) return normalized.trim();
  const trimmed = normalized.trim();
  if (!trimmed) return "";
  const lines = trimmed.split("\n");
  function getLineIndent2(line6) {
    return line6.match(/^[\t ]*/)?.[0].length ?? 0;
  }
  function getMinIndent(input) {
    let minIndent = Number.POSITIVE_INFINITY;
    for (const line6 of input) {
      if (line6.trim().length === 0) continue;
      const indent7 = getLineIndent2(line6);
      if (indent7 < minIndent) {
        minIndent = indent7;
      }
    }
    return minIndent;
  }
  function stripIndent(input, amount) {
    if (!Number.isFinite(amount) || amount <= 0) {
      return input;
    }
    return input.map(
      (line6) => line6.trim().length === 0 ? "" : line6.slice(Math.min(amount, line6.length))
    );
  }
  function normalizeBracketWrappedContinuationIndent(input) {
    if (input.length < 2) return input;
    const first = input[0].trim();
    const expectedClose = first === "[" ? "]" : first === "{" ? "}" : first === "(" ? ")" : null;
    if (!expectedClose) return input;
    let lastNonEmpty = -1;
    for (let i = input.length - 1; i >= 0; i--) {
      if (input[i].trim().length > 0) {
        lastNonEmpty = i;
        break;
      }
    }
    if (lastNonEmpty <= 0) return input;
    if (input[lastNonEmpty].trim() !== expectedClose) return input;
    const closingIndent = getLineIndent2(input[lastNonEmpty]);
    if (closingIndent <= 0) return input;
    const out = [...input];
    for (let i = 1; i <= lastNonEmpty; i++) {
      const line6 = out[i];
      if (line6.trim().length === 0) {
        out[i] = "";
        continue;
      }
      out[i] = line6.slice(Math.min(closingIndent, line6.length));
    }
    return out;
  }
  const dedented = stripIndent(lines, getMinIndent(lines));
  return normalizeBracketWrappedContinuationIndent(dedented).join("\n");
}
function normalizePayload(text) {
  return dedentMultiline(text);
}
function normalizePhpDocBlockIndentation(payload) {
  if (!payload.includes("/**")) return payload;
  const lines = payload.split("\n");
  const out = [...lines];
  for (let i = 0; i < lines.length; i++) {
    const openMatch = lines[i].match(/^(\s*)\/\*\*/u);
    if (!openMatch) continue;
    const baseIndent = openMatch[1];
    for (let j = i + 1; j < lines.length; j++) {
      const trimmed = lines[j].trim();
      if (trimmed.length === 0) {
        out[j] = "";
        continue;
      }
      if (trimmed.startsWith("*/")) {
        out[j] = `${baseIndent} ${trimmed}`;
        i = j;
        break;
      }
      if (trimmed.startsWith("*")) {
        out[j] = `${baseIndent} ${trimmed}`;
      }
    }
  }
  return out.join("\n");
}
function getIndentUnit(options2) {
  const raw = options2.tabWidth;
  const tabWidth = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : 2;
  return options2.useTabs === true ? "	" : " ".repeat(tabWidth);
}
function indentMultilinePayload(payload, options2) {
  const indentUnit = getIndentUnit(options2);
  const lines = payload.split("\n");
  return lines.map((line6) => line6.trim().length === 0 ? "" : `${indentUnit}${line6}`).join("\n");
}
function getHeredocOrNowdocLabel(line6) {
  const match = line6.match(/<<<[ \t]*(['"]?)([A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*)\1/u);
  return match?.[2] ?? null;
}
function isHeredocOrNowdocTerminator(line6, label) {
  const trimmed = line6.trim();
  return trimmed === label || trimmed === `${label};`;
}
function indentPhpBlockBody(payload, options2) {
  const indentUnit = getIndentUnit(options2);
  const lines = payload.split("\n");
  let heredocLabel = null;
  return lines.map((line6) => {
    if (heredocLabel !== null) {
      const out2 = line6;
      if (isHeredocOrNowdocTerminator(line6, heredocLabel)) {
        heredocLabel = null;
      }
      return out2;
    }
    if (line6.trim().length === 0) {
      return "";
    }
    const startLabel = getHeredocOrNowdocLabel(line6);
    const out = `${indentUnit}${line6}`;
    if (startLabel) {
      heredocLabel = startLabel;
    }
    return out;
  }).join("\n");
}
function stripTrailingSemicolon(text) {
  return text.replace(/;\s*$/u, "");
}
function hasTrailingComma(text) {
  return /,\s*$/u.test(text);
}
function normalizeTrailingComma(text, shouldHaveTrailingComma) {
  const trimmedEnd = text.replace(/\s+$/u, "");
  const suffix = text.slice(trimmedEnd.length);
  if (shouldHaveTrailingComma) {
    if (hasTrailingComma(trimmedEnd)) {
      return `${trimmedEnd}${suffix}`;
    }
    return `${trimmedEnd},${suffix}`;
  }
  return `${trimmedEnd.replace(/,\s*$/u, "")}${suffix}`;
}
function hasWrappedMultilineDirectiveArgs(rawArgs) {
  if (!/[\r\n]/u.test(rawArgs)) return false;
  return /^\(\s*\r?\n/u.test(rawArgs);
}
function normalizeWrappedDirectiveArgsPayload(payload) {
  const lines = payload.split("\n");
  if (lines.length <= 1) {
    return payload.trim();
  }
  let minIndent = Number.POSITIVE_INFINITY;
  for (let i = 1; i < lines.length; i++) {
    const line6 = lines[i];
    if (line6.trim().length === 0) continue;
    const indent7 = line6.match(/^[\t ]*/u)?.[0].length ?? 0;
    if (indent7 < minIndent) {
      minIndent = indent7;
    }
  }
  if (!Number.isFinite(minIndent) || minIndent <= 0) {
    return payload;
  }
  return lines.map((line6, index) => {
    if (index === 0 || line6.trim().length === 0) {
      return line6;
    }
    return line6.slice(Math.min(minIndent, line6.length));
  }).join("\n");
}
function tryCollapseDirectivePayloadSingleLine(payload) {
  if (!/[\r\n]/u.test(payload)) {
    const single = payload.trim();
    return single.length > 0 ? single : null;
  }
  if (/\/\*/u.test(payload) || /(^|[^:])\/\/+/u.test(payload) || /(^|\s)#[^\n]*/u.test(payload) || /<<<[ \t]*[A-Za-z_'"]/u.test(payload)) {
    return null;
  }
  const collapsed = payload.replace(/\s+/gu, " ").trim();
  return collapsed.length > 0 ? collapsed : null;
}
function getPrintWidth(options2) {
  const raw = options2.printWidth;
  if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) {
    return Math.floor(raw);
  }
  return 80;
}
function getInlineWrapperSyntaxOverhead(snippet) {
  let maxOverhead = 0;
  for (const line6 of snippet.split(/\r\n?|\n/u)) {
    const startMarkerIndex = line6.indexOf(START_MARKER_COMMENT);
    if (startMarkerIndex < 0) continue;
    const endMarkerIndex = line6.indexOf(
      END_MARKER_COMMENT,
      startMarkerIndex + START_MARKER_COMMENT.length
    );
    if (endMarkerIndex < 0) continue;
    const prefixLength = startMarkerIndex;
    const suffixLength = line6.length - (endMarkerIndex + END_MARKER_COMMENT.length);
    maxOverhead = Math.max(maxOverhead, prefixLength + suffixLength);
  }
  return maxOverhead;
}
function getCompensatedDelegatedPhpPrintWidth(snippet, options2) {
  const basePrintWidth = getPrintWidth(options2);
  const inlineWrapperOverhead = getInlineWrapperSyntaxOverhead(snippet);
  if (inlineWrapperOverhead === 0) {
    return basePrintWidth;
  }
  return basePrintWidth + inlineWrapperOverhead + PHP_INLINE_WRAPPER_PRINT_WIDTH_MARGIN;
}
function shouldPreferInlineDirectiveArgs(node, directiveName, payload, options2) {
  if (directiveName === "php") {
    return true;
  }
  const printWidth = getPrintWidth(options2);
  const spacing = getDirectiveArgSpacingText(
    "",
    getEffectiveDirectiveArgSpacingRule(node, options2)
  );
  const preview = `@${directiveName}${spacing}(${payload})`;
  return preview.length <= printWidth;
}
function getPhpFormatCacheKey(snippet, mode, options2, trailingCommaPHPOverride, singleQuoteOverride) {
  const opts = options2;
  const optionsKey = safeSerialize({
    mode,
    printWidth: opts.printWidth,
    tabWidth: opts.tabWidth,
    useTabs: opts.useTabs,
    singleQuote: singleQuoteOverride === void 0 ? opts.singleQuote : singleQuoteOverride,
    semi: opts.semi,
    trailingComma: opts.trailingComma,
    bracketSpacing: opts.bracketSpacing,
    jsxSingleQuote: opts.jsxSingleQuote,
    quoteProps: opts.quoteProps,
    endOfLine: opts.endOfLine,
    phpVersion: opts.phpVersion,
    trailingCommaPHP: trailingCommaPHPOverride === void 0 ? opts.trailingCommaPHP : trailingCommaPHPOverride,
    braceStyle: opts.braceStyle
  });
  return `${optionsKey}|${snippet}`;
}
function setCachedPhpFormatResult(key, value) {
  if (phpFormatCache.size >= MAX_PHP_FORMAT_CACHE_SIZE) {
    phpFormatCache.clear();
  }
  phpFormatCache.set(key, value);
}
function createPhpFormatOptions(options2, plugins, trailingCommaPHPOverride, singleQuoteOverride) {
  const baseOptions = {
    ...options2
  };
  delete baseOptions.parser;
  delete baseOptions.parentParser;
  delete baseOptions.plugins;
  delete baseOptions.rangeStart;
  delete baseOptions.rangeEnd;
  delete baseOptions.cursorOffset;
  const runtime = globalThis;
  const isBrowserRuntime = typeof runtime.window === "object";
  const phpVersion = baseOptions.phpVersion;
  const needsBrowserPhpVersionFallback = phpVersion === void 0 || phpVersion === null || phpVersion === "auto" || phpVersion === "composer";
  if (isBrowserRuntime && needsBrowserPhpVersionFallback) {
    baseOptions.phpVersion = BROWSER_DEFAULT_PHP_VERSION;
  }
  if (trailingCommaPHPOverride !== void 0) {
    baseOptions.trailingCommaPHP = trailingCommaPHPOverride;
  }
  if (singleQuoteOverride !== void 0) {
    baseOptions.singleQuote = singleQuoteOverride;
  }
  return {
    ...baseOptions,
    parser: "php",
    plugins
  };
}
async function formatPhpSnippet(snippet, options2, mode, trailingCommaPHPOverride, singleQuoteOverride) {
  const plugins = await resolvePhpPlugins(options2);
  if (!plugins) return null;
  const cacheKey = getPhpFormatCacheKey(
    snippet,
    mode,
    options2,
    trailingCommaPHPOverride,
    singleQuoteOverride
  );
  if (phpFormatCache.has(cacheKey)) {
    return phpFormatCache.get(cacheKey) ?? null;
  }
  try {
    const formatted = await (0, import_prettier9.format)(
      snippet,
      createPhpFormatOptions(options2, plugins, trailingCommaPHPOverride, singleQuoteOverride)
    );
    const normalized = normalizeLineEndingsToLf(trimFinalLineBreak(formatted));
    setCachedPhpFormatResult(cacheKey, normalized);
    return normalized;
  } catch {
    setCachedPhpFormatResult(cacheKey, null);
    return null;
  }
}
function getDirectiveWrapperContext(node) {
  const trainedDirectives = node.buildResult.directives;
  if (!trainedDirectives) return {};
  return {
    hasDirective: (name) => trainedDirectives.isDirective(name) || trainedDirectives.hasSeenDirective(name),
    isConditionLikeDirective: (name) => trainedDirectives.isCondition(name) || trainedDirectives.hasAdvisoryCondition(name)
  };
}
function createDirectiveArgsMarkerPayload(args) {
  return `${DIRECTIVE_START_MARKER_COMMENT}${args}${DIRECTIVE_END_MARKER_COMMENT}`;
}
function wrapDirectiveArgs(args, kind) {
  const payload = createDirectiveArgsMarkerPayload(args);
  switch (kind) {
    case "for":
      return `<?php for (${payload}) {}`;
    case "foreach":
      return `<?php foreach (${payload}) {}`;
    case "while":
      return `<?php while (${payload}) {}`;
    case "switch":
      return `<?php switch (${payload}) {}`;
    case "case":
      return `<?php switch (true) { case (${payload}): break; }`;
    case "if":
      return `<?php if (${payload}) {}`;
    case "call":
    default:
      return `<?php __b(${payload});`;
  }
}
function wrapDirectiveArgsWithTemplate(args, template) {
  if (!template.includes(DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER)) {
    return null;
  }
  const payload = createDirectiveArgsMarkerPayload(args);
  return template.replaceAll(DIRECTIVE_PHP_FORMAT_ARGS_PLACEHOLDER, payload);
}
function getDirectivePhpFormatAttempts(directiveName, args, mode, options2, context) {
  const attempts = [];
  const seenDedupeKeys = /* @__PURE__ */ new Set();
  const pluginContext = { ...context, mode };
  for (const plugin2 of resolveBladeSyntaxPlugins(options2)) {
    const templates = plugin2.getDirectivePhpFormatTemplates?.(directiveName, pluginContext) ?? [];
    for (const template of templates) {
      const dedupeKey = template.key.trim();
      if (!dedupeKey || seenDedupeKeys.has(dedupeKey)) {
        continue;
      }
      const wrapped = wrapDirectiveArgsWithTemplate(args, template.template);
      if (wrapped === null) {
        continue;
      }
      seenDedupeKeys.add(dedupeKey);
      attempts.push({
        preserveWrappedMultilineArgs: true,
        wrapped
      });
    }
  }
  for (const wrapperKind of getDirectivePhpWrapperKinds(directiveName, mode, context)) {
    const dedupeKey = `builtin:${wrapperKind}`;
    if (seenDedupeKeys.has(dedupeKey)) {
      continue;
    }
    seenDedupeKeys.add(dedupeKey);
    attempts.push({
      preserveWrappedMultilineArgs: wrapperKind !== "call",
      wrapped: wrapDirectiveArgs(args, wrapperKind)
    });
  }
  return attempts;
}
function wrapEchoExpression(expression) {
  return `<?php ${START_MARKER_COMMENT} echo ${expression}; ${END_MARKER_COMMENT}`;
}
function stripLeadingEchoKeyword(text) {
  return text.replace(/^\s*echo\b\s*/u, "");
}
function rebuildDirectiveWithFormattedArgs(node, formattedArgs, options2) {
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  const argSpacingRule = getEffectiveDirectiveArgSpacingRule(node, options2);
  let result = "";
  let sawDirectiveToken = false;
  let sawArgsToken = false;
  for (let i = start; i < end; i++) {
    const token = tokens[i];
    const prev = i > start ? tokens[i - 1] : null;
    const next = i + 1 < end ? tokens[i + 1] : null;
    const tokenText = node.source.slice(token.start, token.end);
    if (token.type === 25 /* Directive */) {
      result += tokenText;
      sawDirectiveToken = true;
      if (next?.type === 26 /* DirectiveArgs */) {
        result += getDirectiveArgSpacingText("", argSpacingRule);
      }
      continue;
    }
    if (!sawDirectiveToken) {
      continue;
    }
    if (token.type === 9 /* Whitespace */ && prev?.type === 25 /* Directive */ && next?.type === 26 /* DirectiveArgs */) {
      result += getDirectiveArgSpacingText(tokenText, argSpacingRule);
      continue;
    }
    if (token.type === 26 /* DirectiveArgs */ && !sawArgsToken) {
      result += formattedArgs;
      sawArgsToken = true;
      continue;
    }
    break;
  }
  return sawDirectiveToken ? result : "";
}
function getEchoDelimiters3(node) {
  switch (node.kind) {
    case 5 /* RawEcho */:
      return { open: "{!!", close: "!!}" };
    case 6 /* TripleEcho */:
      return { open: "{{{", close: "}}}" };
    case 4 /* Echo */:
    default:
      return { open: "{{", close: "}}" };
  }
}
function getEchoContent2(node) {
  const tokens = nodeTokens(node);
  const parts = [];
  for (const token of tokens) {
    if (token.type === 20 /* EchoContent */) {
      parts.push(node.source.slice(token.start, token.end));
    }
  }
  if (parts.length === 0) return null;
  return parts.join("");
}
function isWhitespaceTextNode(node) {
  return node?.kind === 2 /* Text */ && node.rawText.trim().length === 0;
}
function isNonWhitespaceTextNode(node) {
  return node?.kind === 2 /* Text */ && node.rawText.trim().length > 0;
}
function isEchoInAttributeLikeTextRun(node) {
  if (node.prev?.kind !== 2 /* Text */ || node.next?.kind !== 2 /* Text */) {
    return false;
  }
  const prevTrimmed = node.prev.rawText.trimEnd();
  const nextTrimmed = node.next.rawText.trimStart();
  return /=\s*["']$/.test(prevTrimmed) && /^["']/.test(nextTrimmed);
}
function shouldCompensateInlineEchoPrintWidth(node) {
  const parent = node.parent;
  if (!parent || parent.kind !== 1 /* Element */) {
    return false;
  }
  if (parent.tagName === "style" || parent.tagName === "script") {
    return false;
  }
  if (node.start < parent.openTagEndOffset) {
    return false;
  }
  if (parent.fullName === "title") {
    return (node.prev === null || isWhitespaceTextNode(node.prev)) && (node.next === null || isWhitespaceTextNode(node.next));
  }
  return isNonWhitespaceTextNode(node.prev) || isNonWhitespaceTextNode(node.next);
}
function withCompensatedInlineEchoPrintWidth(wrappedSnippet, options2) {
  return {
    ...options2,
    printWidth: getCompensatedDelegatedPhpPrintWidth(wrappedSnippet, options2)
  };
}
async function formatDirectiveNodeArgs(node, options2) {
  const mode = getMode(options2);
  if (mode === "off") return null;
  if (!isPhpTargetEnabled(options2, "directiveArgs")) return null;
  if (!isDirectiveWithArgsNode(node)) return null;
  const activeMode = mode;
  const argsToken = findFirstToken(node, 26 /* DirectiveArgs */);
  if (!argsToken) return null;
  const rawArgs = node.source.slice(argsToken.start, argsToken.end);
  if (!rawArgs.startsWith("(") || !rawArgs.endsWith(")")) return null;
  const argsInner = rawArgs.slice(1, -1);
  if (argsInner.trim().length === 0) return null;
  const hasWrappedMultilineArgs = hasWrappedMultilineDirectiveArgs(rawArgs);
  const originalWasSingleLine = !/[\r\n]/u.test(argsInner);
  const originalHadTrailingComma = hasTrailingComma(argsInner.trimEnd());
  const directiveName = getDirectiveName(node) ?? "";
  const directiveWrapperContext = getDirectiveWrapperContext(node);
  const formatAttempts = getDirectivePhpFormatAttempts(
    directiveName,
    argsInner,
    activeMode,
    options2,
    directiveWrapperContext
  );
  for (const attempt of formatAttempts) {
    const wrapped = attempt.wrapped;
    const formatted = await formatPhpSnippet(
      wrapped,
      options2,
      activeMode,
      FORCED_DIRECTIVE_ARG_TRAILING_COMMA
    );
    if (!formatted) continue;
    const extracted = getTextBetweenMarkers(
      formatted,
      DIRECTIVE_START_MARKER_COMMENT,
      DIRECTIVE_END_MARKER_COMMENT
    );
    if (extracted === null) continue;
    const normalizedPayload = normalizePayload(extracted);
    const payload = normalizeTrailingComma(
      normalizedPayload,
      originalHadTrailingComma || hasTrailingComma(normalizedPayload.trimEnd())
    );
    const collapsedInlinePayload = originalWasSingleLine ? tryCollapseDirectivePayloadSingleLine(payload) : null;
    const finalPayload = collapsedInlinePayload && shouldPreferInlineDirectiveArgs(node, directiveName, collapsedInlinePayload, options2) ? collapsedInlinePayload : payload;
    const shouldPreserveWrappedMultilineArgs = hasWrappedMultilineArgs && attempt.preserveWrappedMultilineArgs;
    const formattedArgs = shouldPreserveWrappedMultilineArgs ? `(
${indentMultilinePayload(
      normalizeWrappedDirectiveArgsPayload(dedentMultiline(finalPayload)),
      options2
    )}
)` : `(${finalPayload})`;
    return rebuildDirectiveWithFormattedArgs(node, formattedArgs, options2);
  }
  return null;
}
async function formatEchoNode(node, options2) {
  const mode = getMode(options2);
  if (mode === "off") return null;
  if (!isPhpTargetEnabled(options2, "echo")) return null;
  if (!isEchoNode(node)) return null;
  if (isEchoInAttributeLikeTextRun(node)) return null;
  const content = getEchoContent2(node);
  if (content === null || content.trim().length === 0) return null;
  const trimmedContent = content.trim();
  const wrapped = wrapEchoExpression(trimmedContent);
  const delegatedOptions = shouldCompensateInlineEchoPrintWidth(node) ? withCompensatedInlineEchoPrintWidth(wrapped, options2) : options2;
  const singleQuoteOverride = isInBladeComponentOpenTag(node, options2) ? true : void 0;
  const formatted = await formatPhpSnippet(
    wrapped,
    delegatedOptions,
    mode,
    void 0,
    singleQuoteOverride
  );
  if (!formatted) return null;
  const extracted = getTextBetweenMarkers(formatted);
  if (extracted === null) return null;
  const expression = normalizePayload(stripLeadingEchoKeyword(extracted));
  const normalizedExpression = normalizePayload(stripTrailingSemicolon(expression));
  if (!normalizedExpression) return null;
  const delimiters = getEchoDelimiters3(node);
  if (normalizedExpression.includes("\n")) {
    const indentedExpression = indentMultilinePayload(normalizedExpression, options2);
    return `${delimiters.open}
${indentedExpression}
${delimiters.close}`;
  }
  const spacing = getEchoSpacingMode(options2);
  if (spacing === "tight") {
    return `${delimiters.open}${normalizedExpression}${delimiters.close}`;
  }
  return `${delimiters.open} ${normalizedExpression} ${delimiters.close}`;
}
async function formatPhpTagNode(node, options2) {
  const mode = getMode(options2);
  if (mode === "off") return null;
  if (!isPhpTargetEnabled(options2, "phpTag")) return null;
  if (!isPhpTagNode(node)) return null;
  const raw = fullText(node);
  if (raw.trim().length === 0) return null;
  return formatPhpSnippet(raw, options2, mode);
}
async function formatPhpBlockNode(node, options2) {
  const mode = getMode(options2);
  if (mode === "off") return null;
  if (!isPhpTargetEnabled(options2, "phpBlock")) return null;
  if (!isPhpBlockNode(node)) return null;
  const startToken = findFirstToken(node, 29 /* PhpBlockStart */);
  const endToken = findFirstToken(node, 30 /* PhpBlockEnd */);
  if (!startToken || !endToken) return null;
  const opener = node.source.slice(startToken.start, startToken.end);
  const closer = node.source.slice(endToken.start, endToken.end);
  const body = node.source.slice(startToken.end, endToken.start);
  const wrapped = `<?php
${START_MARKER_COMMENT}
${body}
${END_MARKER_COMMENT}
`;
  const formatted = await formatPhpSnippet(wrapped, options2, mode);
  if (!formatted) return null;
  const extracted = getTextBetweenMarkers(formatted);
  if (extracted === null) return null;
  const formattedBody = normalizePhpDocBlockIndentation(dedentMultiline(extracted));
  const originalBlockText = node.source.slice(startToken.start, endToken.end);
  const originallyInline = !/[\r\n]/.test(originalBlockText);
  if (originallyInline && !formattedBody.includes("\n")) {
    if (formattedBody.length === 0) {
      return `${opener} ${closer}`;
    }
    return `${opener} ${formattedBody} ${closer}`;
  }
  if (formattedBody.length === 0) {
    return `${opener}
${closer}`;
  }
  const indentedBody = indentPhpBlockBody(formattedBody, options2);
  return `${opener}
${indentedBody}
${closer}`;
}

// src/print/embed/attribute.ts
var { group: group4, join: join3, line: line5, ifBreak: ifBreak3 } = import_prettier10.doc.builders;
function hasBladeValueSyntax2(node) {
  const text = fullText(node);
  return text.includes("{{") || text.includes("{!!");
}
function isSyntaxError2(error) {
  return typeof error === "object" && error !== null && "cause" in error && typeof error.cause === "object" && error.cause?.code === "BABEL_PARSER_SYNTAX_ERROR";
}
var VUE_BIND_PREFIX = "v-bind:";
function isColonBoundAttributeName(name) {
  const trimmed = name.trimStart();
  return trimmed.startsWith(":") || trimmed.toLowerCase().startsWith(VUE_BIND_PREFIX);
}
function isBladeComponentElement(node, options2) {
  if (!node || node.kind !== 1 /* Element */) return false;
  return isBladeComponentTagName(node.fullName, options2);
}
function createPhpAttributeOptions(options2, plugins) {
  const baseOptions = {
    ...options2
  };
  delete baseOptions.parser;
  delete baseOptions.parentParser;
  delete baseOptions.plugins;
  delete baseOptions.rangeStart;
  delete baseOptions.rangeEnd;
  delete baseOptions.cursorOffset;
  const runtime = globalThis;
  const isBrowserRuntime = typeof runtime.window === "object";
  const phpVersion = baseOptions.phpVersion;
  if (isBrowserRuntime && (phpVersion === void 0 || phpVersion === null || phpVersion === "auto" || phpVersion === "composer")) {
    baseOptions.phpVersion = "8.4";
  }
  baseOptions.singleQuote = true;
  return {
    ...baseOptions,
    parser: "php",
    plugins
  };
}
function wrapBoundAttributeExpression(value) {
  return `<?php __blade_bound_attr__(${value});`;
}
function extractWrapperCallArgument(formatted) {
  const wrapperIndex = formatted.indexOf("__blade_bound_attr__");
  if (wrapperIndex < 0) return null;
  const openIndex = formatted.indexOf("(", wrapperIndex);
  if (openIndex < 0) return null;
  let depth = 0;
  let inSingle = false;
  let inDouble = false;
  let inLineComment = false;
  let inBlockComment = false;
  let escape = false;
  for (let i = openIndex; i < formatted.length; i++) {
    const char = formatted[i];
    const next = formatted[i + 1] ?? "";
    if (inLineComment) {
      if (char === "\n") {
        inLineComment = false;
      }
      continue;
    }
    if (inBlockComment) {
      if (char === "*" && next === "/") {
        inBlockComment = false;
        i += 1;
      }
      continue;
    }
    if (inSingle) {
      if (escape) {
        escape = false;
        continue;
      }
      if (char === "\\") {
        escape = true;
        continue;
      }
      if (char === "'") {
        inSingle = false;
      }
      continue;
    }
    if (inDouble) {
      if (escape) {
        escape = false;
        continue;
      }
      if (char === "\\") {
        escape = true;
        continue;
      }
      if (char === '"') {
        inDouble = false;
      }
      continue;
    }
    if (char === "/" && next === "/") {
      inLineComment = true;
      i += 1;
      continue;
    }
    if (char === "#") {
      inLineComment = true;
      continue;
    }
    if (char === "/" && next === "*") {
      inBlockComment = true;
      i += 1;
      continue;
    }
    if (char === "'") {
      inSingle = true;
      continue;
    }
    if (char === '"') {
      inDouble = true;
      continue;
    }
    if (char === "(") {
      depth += 1;
      continue;
    }
    if (char === ")") {
      depth -= 1;
      if (depth === 0) {
        return formatted.slice(openIndex + 1, i);
      }
    }
  }
  return null;
}
function dedentMultiline2(text) {
  const normalized = normalizeLineEndingsToLf(text);
  if (!normalized.includes("\n")) return normalized.trim();
  const lines = normalized.trim().split("\n");
  let minIndent = Number.POSITIVE_INFINITY;
  for (const line6 of lines) {
    if (line6.trim().length === 0) continue;
    const indent7 = line6.match(/^[\t ]*/u)?.[0].length ?? 0;
    if (indent7 < minIndent) {
      minIndent = indent7;
    }
  }
  if (!Number.isFinite(minIndent) || minIndent <= 0) {
    return lines.join("\n");
  }
  return lines.map((line6) => line6.trim().length === 0 ? "" : line6.slice(Math.min(minIndent, line6.length))).join("\n");
}
function indentMultilineRelativeToAttributeName(value, attributeName) {
  if (!value.includes("\n")) return value;
  const lines = value.split("\n");
  const nonEmpty = lines.map((line6) => line6.trim()).filter(Boolean);
  const first = nonEmpty[0] ?? "";
  const last = nonEmpty[nonEmpty.length - 1] ?? "";
  const isWrappedMethodCall = first.includes("->") && first.endsWith("(") && last === ")";
  const isBracketWrapped = first === "[" && last === "]";
  const shouldApplyRelativeIndent = isWrappedMethodCall || isBracketWrapped;
  if (!shouldApplyRelativeIndent) {
    return value;
  }
  const continuationLines = lines.slice(1).filter((line6) => line6.trim().length > 0);
  if (continuationLines.length > 0) {
    const minContinuationIndent = Math.min(
      ...continuationLines.map((line6) => line6.match(/^[\t ]*/u)?.[0].length ?? 0)
    );
    if (minContinuationIndent > 0) {
      for (let i = 1; i < lines.length; i++) {
        const line6 = lines[i];
        if (line6.trim().length === 0) continue;
        lines[i] = line6.slice(Math.min(minContinuationIndent, line6.length));
      }
    }
  }
  const continuationIndentSize = isBracketWrapped ? Math.max(2, Math.floor(attributeName.length / 2)) : attributeName.length;
  const continuationIndent = " ".repeat(continuationIndentSize);
  const bracketClosingIndent = isBracketWrapped ? " ".repeat(Math.max(4, Math.floor(attributeName.length / 3))) : continuationIndent;
  return lines.map((line6, index) => {
    if (index === 0) return line6;
    if (line6.trim().length === 0) return "";
    if (isBracketWrapped && line6.trim() === "]") {
      return `${bracketClosingIndent}${line6.trimStart()}`;
    }
    return `${continuationIndent}${line6}`;
  }).join("\n");
}
async function formatAsPhpBoundAttributeValue(value, options2) {
  const plugins = await resolvePhpPlugins(options2);
  if (!plugins) return void 0;
  try {
    const formatted = await (0, import_prettier11.format)(
      wrapBoundAttributeExpression(value),
      createPhpAttributeOptions(options2, plugins)
    );
    const extracted = extractWrapperCallArgument(normalizeLineEndingsToLf(formatted));
    if (extracted === null) return void 0;
    const normalized = dedentMultiline2(extracted).replace(/,\s*$/u, "").replace(/;\s*$/u, "");
    return normalized || void 0;
  } catch {
    return void 0;
  }
}
var isSrcset = (path) => {
  const node = path.node;
  const name = getStaticAttributeNameLower(node);
  if (name === null) return false;
  if (!isStaticAttributeValue(node)) return false;
  return name === "srcset" && node.parent !== null && (node.parent.fullName.toLowerCase() === "img" || node.parent.fullName.toLowerCase() === "source");
};
var SRCSET_UNITS = {
  width: "w",
  height: "h",
  density: "x"
};
var printSrcset = (_textToDoc, _print, path) => {
  const value = getUnescapedAttributeValue(path.node);
  const srcset = (0, import_parse_srcset.default)(value);
  if (srcset.length === 0) return value;
  const srcsetTypes = Object.keys(SRCSET_UNITS);
  const types = srcsetTypes.filter(
    (type) => srcset.some((candidate) => Object.hasOwn(candidate, type))
  );
  if (types.length > 1) {
    throw new Error("Mixed descriptor in srcset is not supported");
  }
  const [key] = types;
  const unit = key ? SRCSET_UNITS[key] : "";
  const urls = srcset.map((candidate) => candidate.source.value);
  const maxUrlLength = Math.max(...urls.map((u) => u.length));
  const descriptors = srcset.map(
    (candidate) => key && candidate[key] ? String(candidate[key].value) : ""
  );
  const descriptorLeftLengths = descriptors.map((d) => {
    const idx = d.indexOf(".");
    return idx === -1 ? d.length : idx;
  });
  const maxDescriptorLeftLength = Math.max(...descriptorLeftLengths);
  return printExpand(
    join3(
      [",", line5],
      urls.map((url, index) => {
        const parts = [url];
        const descriptor = descriptors[index];
        if (descriptor) {
          const urlPadding = maxUrlLength - url.length + 1;
          const descriptorPadding = maxDescriptorLeftLength - descriptorLeftLengths[index];
          const alignment = " ".repeat(urlPadding + descriptorPadding);
          parts.push(ifBreak3(alignment, " "), descriptor + unit);
        }
        return parts;
      })
    )
  );
};
var isStyle = (path, options2) => {
  const node = path.node;
  const name = getStaticAttributeNameLower(node);
  if (!isStaticAttributeValue(node)) return false;
  return name === "style" && !options2.parentParser && !hasBladeValueSyntax2(node);
};
function shouldPreserveInlineSvgStyleAttribute(path, options2) {
  const node = path.node;
  const parent = node.parent;
  if (!parent || parent.kind !== 1 /* Element */) return false;
  if (parent.namespace !== "svg") return false;
  if (!shouldPreserveInlineIntentAttributes(options2, parent.tagName, parent.namespace)) {
    return false;
  }
  if (fullText(parent).includes("\n") || fullText(parent).includes("\r")) return false;
  if (fullText(node).includes("\n") || fullText(node).includes("\r")) return false;
  return true;
}
var printStyle = async (textToDoc, _print, path, options2) => {
  const value = getUnescapedAttributeValue(path.node);
  if (shouldPreserveInlineSvgStyleAttribute(path, options2)) {
    return value;
  }
  const plugins = await resolveEmbeddedParserPlugins(options2, "css");
  return printExpand(
    await textToDoc(value, {
      parser: "css",
      __isHTMLStyleAttribute: true,
      plugins
    })
  );
};
var isEventHandler = (path, options2) => {
  const node = path.node;
  const name = getStaticAttributeNameLower(node);
  if (!name) return false;
  if (!isStaticAttributeValue(node)) return false;
  return isHtmlEventAttribute(name) && !options2.parentParser && !hasBladeValueSyntax2(node);
};
var printEventHandler = async (textToDoc, _print, path, options2) => {
  const value = getUnescapedAttributeValue(path.node);
  const plugins = await resolveEmbeddedParserPlugins(options2, "babel");
  return formatAttributeValue(
    value,
    textToDoc,
    {
      parser: "babel",
      __isHtmlInlineEventHandler: true,
      plugins
    },
    () => false
  );
};
var isColonBoundAttribute = (path, options2) => {
  if (options2.parentParser) return false;
  const node = path.node;
  if (!isStaticAttributeName(node)) return false;
  if (!isStaticAttributeValue(node)) return false;
  if (hasBladeValueSyntax2(node)) return false;
  const name = getAttributeNameRaw(node);
  if (!name) return false;
  return isColonBoundAttributeName(name);
};
var printColonBoundAttribute = async (textToDoc, _print, path, options2) => {
  const node = path.node;
  if (!isStaticAttributeName(node) || !isStaticAttributeValue(node)) {
    return void 0;
  }
  const name = getAttributeNameRaw(node);
  if (!name || !isColonBoundAttributeName(name)) {
    return void 0;
  }
  const value = getUnescapedAttributeValue(node);
  if (!value) return void 0;
  if (isBladeComponentElement(node.parent, options2)) {
    if (!isPhpFormattingEnabled(options2)) {
      return void 0;
    }
    const formattedValue = await formatAsPhpBoundAttributeValue(value, options2);
    if (!formattedValue) return void 0;
    const normalizedName = normalizeAttributeName(name, node.parent);
    const indentedValue = indentMultilineRelativeToAttributeName(formattedValue, normalizedName);
    return indentedValue.includes("\n") ? printExpand(indentedValue) : indentedValue;
  }
  try {
    return await formatAttributeValue(value, textToDoc, { parser: "__js_expression" });
  } catch (error) {
    if (!isSyntaxError2(error)) {
      throw error;
    }
    try {
      return await formatAttributeValue(value, textToDoc, {
        parser: "babel",
        __isHtmlInlineEventHandler: true
      });
    } catch (fallbackError) {
      if (!isSyntaxError2(fallbackError)) {
        throw fallbackError;
      }
      return void 0;
    }
  }
};
var isClassNames = (path, options2) => {
  const node = path.node;
  const name = getStaticAttributeNameLower(node);
  if (!isStaticAttributeValue(node)) return false;
  return (name === "class" || name === "classname") && !options2.parentParser && !hasBladeValueSyntax2(node);
};
var printClassNames = async (_textToDoc, _print, path, options2) => {
  const value = getUnescapedAttributeValue(path.node);
  const tailwindSortedValue = await sortClassNamesWithTailwind(value, options2);
  if (tailwindSortedValue !== null) {
    return tailwindSortedValue;
  }
  return value.trim().split(/\s+/).join(" ");
};
var isPermissionsPolicy = (path, options2) => {
  const node = path.node;
  const name = getStaticAttributeNameLower(node);
  if (!isStaticAttributeValue(node)) return false;
  return name === "allow" && !options2.parentParser && node.parent !== null && node.parent.fullName.toLowerCase() === "iframe" && !hasBladeValueSyntax2(node);
};
function parsePermissionsPolicy(value) {
  return value.split(";").map((s) => s.trim()).filter(Boolean).map((directive) => {
    const parts = directive.split(/\s+/);
    return { name: parts[0], value: parts.slice(1) };
  });
}
var printPermissionsPolicy = (_textToDoc, _print, path) => {
  const value = getUnescapedAttributeValue(path.node);
  const directives = parsePermissionsPolicy(value);
  if (directives.length === 0) return [""];
  return printExpand(
    directives.map(({ name, value: vals }, index) => [
      [name, ...vals].join(" "),
      index === directives.length - 1 ? ifBreak3(";") : [";", line5]
    ])
  );
};
var rawPrinters = [
  { test: isSrcset, print: printSrcset },
  { test: isStyle, print: printStyle },
  { test: isEventHandler, print: printEventHandler },
  {
    test: isColonBoundAttribute,
    print: printColonBoundAttribute,
    allowSingleQuoteWrapper: true
  },
  { test: isClassNames, print: printClassNames },
  { test: isPermissionsPolicy, print: printPermissionsPolicy },
  ...alpineAttributePrinters
];
function collectDocStringContent(d) {
  let result = "";
  import_prettier10.doc.utils.mapDoc(d, (sub) => {
    if (typeof sub === "string") {
      result += sub;
    }
    return sub;
  });
  return result;
}
function createAttributePrinter(printValue, { allowSingleQuoteWrapper = false } = {}) {
  return async (textToDoc, print, path, options2) => {
    let valueDoc = await printValue(textToDoc, print, path, options2);
    if (!valueDoc) return void 0;
    const rawName = formatAttributeNameForPrint(path.node, options2);
    const name = isStaticAttributeName(path.node) ? normalizeAttributeName(rawName, path.node.parent) : rawName;
    if (allowSingleQuoteWrapper) {
      const content = collectDocStringContent(valueDoc);
      if (content.includes('"') && !content.includes("'")) {
        return [name, "='", group4(valueDoc), "'"];
      }
    }
    valueDoc = import_prettier10.doc.utils.mapDoc(
      valueDoc,
      (d) => typeof d === "string" ? d.replaceAll('"', "&quot;") : d
    );
    return [name, '="', group4(valueDoc), '"'];
  };
}
var printers = rawPrinters.map(({ test, print: p, allowSingleQuoteWrapper }) => ({
  test,
  print: createAttributePrinter(p, { allowSingleQuoteWrapper })
}));
function printEmbedAttribute(path, options2) {
  const node = path.node;
  const value = getUnescapedAttributeValue(node);
  if (!value) return null;
  const match = printers.find(({ test }) => test(path, options2));
  if (!match) return null;
  return (textToDoc, print, cbPath, cbOptions) => match.print(textToDoc, print, cbPath, cbOptions);
}

// src/print/embed/raw-content.ts
var import_prettier12 = require("prettier");
var import_prettier13 = require("prettier");
var { group: group5, hardline: hardline6, indent: indent5 } = import_prettier12.doc.builders;
var EXPRESSION_DIRECTIVES = /* @__PURE__ */ new Set(["json", "js", "entangle", "this"]);
function isLeafConstructNode(node) {
  switch (node.kind) {
    case 7 /* Directive */:
    case 4 /* Echo */:
    case 5 /* RawEcho */:
    case 6 /* TripleEcho */:
    case 10 /* PhpBlock */:
    case 11 /* PhpTag */:
    case 15 /* BladeComment */:
    case 12 /* Comment */:
    case 13 /* BogusComment */:
    case 22 /* NonOutput */:
      return true;
    default:
      return false;
  }
}
function extractDirectiveName3(node) {
  if (node.kind !== 7 /* Directive */) return null;
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  for (let i = tokenStart; i < tokenEnd; i++) {
    const token = tokens[i];
    if (token.type !== 25 /* Directive */) continue;
    const raw = node.source.slice(token.start, token.end);
    if (!raw.startsWith("@")) return null;
    return raw.slice(1).toLowerCase();
  }
  return null;
}
function isKnownBladeDirective(node) {
  const name = extractDirectiveName3(node);
  if (!name) {
    return false;
  }
  return node.buildResult.directives?.getDirective(name) !== void 0;
}
function getPlaceholderKind(node) {
  switch (node.kind) {
    case 4 /* Echo */:
    case 5 /* RawEcho */:
    case 6 /* TripleEcho */:
      return "expr";
    case 11 /* PhpTag */:
    case 10 /* PhpBlock */:
      return "expr";
    case 7 /* Directive */: {
      const name = extractDirectiveName3(node);
      return name && EXPRESSION_DIRECTIVES.has(name) ? "expr" : "stmt";
    }
    default:
      return "stmt";
  }
}
function isStyleParser(parser) {
  return parser === "css" || parser === "scss" || parser === "less";
}
function getPlaceholderMarker(markerSessionKey, kind, index, parser, inStyleValueContext = false) {
  if (isStyleParser(parser)) {
    if (inStyleValueContext) {
      return `__blade_value_slot_${markerSessionKey}_${index}__`;
    }
    return kind === "expr" ? `/*__blade_expr_slot_${markerSessionKey}_${index}__*/` : `@__blade_stmt_slot_${markerSessionKey}_${index};`;
  }
  if (kind === "expr") {
    return `__blade_expr_slot_${markerSessionKey}_${index}__`;
  }
  return `/*__blade_stmt_slot_${markerSessionKey}_${index}__*/`;
}
function createMarkerSessionKey(source, start, end) {
  const base = `${source.length.toString(36)}_${start.toString(36)}_${end.toString(36)}`;
  for (let attempt = 0; ; attempt++) {
    const candidate = attempt === 0 ? base : `${base}_${attempt.toString(36)}`;
    if (!source.includes(`__blade_expr_slot_${candidate}_`) && !source.includes(`__blade_stmt_slot_${candidate}_`) && !source.includes(`__blade_value_slot_${candidate}_`)) {
      return candidate;
    }
  }
}
function isInCssValueContext(source, slotStart, contentStart) {
  for (let i = slotStart - 1; i >= contentStart; i--) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      continue;
    }
    if (ch === ":") {
      return true;
    }
    if (ch === "}") {
      if (i - 1 >= contentStart && source[i - 1] === "}" || i + 1 < slotStart && source[i + 1] === "}" || i - 1 >= contentStart && source[i - 1] === "!") {
        continue;
      }
      return false;
    }
    if (ch === "{") {
      if (i - 1 >= contentStart && source[i - 1] === "{" || i + 1 < slotStart && source[i + 1] === "{" || i + 1 < slotStart && source[i + 1] === "!") {
        continue;
      }
      return false;
    }
    if (ch === ";") {
      return false;
    }
  }
  return false;
}
function getElementContentRange(node) {
  if (node.openTagEndOffset > 0 && node.closingTagStartOffset > node.openTagEndOffset) {
    return { start: node.openTagEndOffset, end: node.closingTagStartOffset };
  }
  if (node.children.length === 0) {
    return { start: node.start, end: node.start };
  }
  return {
    start: node.children[0].start,
    end: node.children[node.children.length - 1].end
  };
}
function collectLeafConstructs(node, start, end) {
  const out = [];
  const stack = [...node.children];
  while (stack.length > 0) {
    const current = stack.pop();
    if (current.end <= start || current.start >= end) {
      continue;
    }
    if (isLeafConstructNode(current)) {
      if (current.start >= start && current.end <= end) {
        out.push(current);
      }
      if (current.kind !== 7 /* Directive */ || current.children.length === 0) {
        continue;
      }
    }
    for (let i = current.children.length - 1; i >= 0; i--) {
      stack.push(current.children[i]);
    }
  }
  out.sort((a, b) => a.start - b.start || a.end - b.end);
  return out;
}
function getReplacementRange(node) {
  if (node.kind !== 7 /* Directive */) {
    return { start: node.start, end: node.end };
  }
  const tokenStart = node.flat.tokenStart;
  const tokenEnd = tokenStart + node.flat.tokenCount;
  if (node.flat.tokenCount <= 0) {
    return { start: node.start, end: node.end };
  }
  const first = node.buildResult.tokens[tokenStart];
  const last = node.buildResult.tokens[tokenEnd - 1];
  if (!first || !last) {
    return { start: node.start, end: node.end };
  }
  return { start: first.start, end: last.end };
}
function docToFlatString(value) {
  if (typeof value === "string") return value;
  if (!Array.isArray(value)) return null;
  let out = "";
  for (const part of value) {
    const rendered = docToFlatString(part);
    if (rendered === null) return null;
    out += rendered;
  }
  return out;
}
async function getConstructReplacementText(node, options2) {
  switch (node.kind) {
    case 4 /* Echo */:
    case 5 /* RawEcho */:
    case 6 /* TripleEcho */: {
      const formatted = await formatEchoNode(node, options2);
      if (formatted !== null) return formatted;
      const rendered = docToFlatString(printEcho(node, options2));
      return rendered ?? fullText(node);
    }
    case 7 /* Directive */: {
      const formatted = await formatDirectiveNodeArgs(node, options2);
      if (formatted !== null) return formatted;
      const rendered = docToFlatString(printDirective(node, options2));
      return rendered ?? fullText(node);
    }
    case 11 /* PhpTag */: {
      const formatted = await formatPhpTagNode(node, options2);
      return formatted ?? fullText(node);
    }
    case 10 /* PhpBlock */: {
      const formatted = await formatPhpBlockNode(node, options2);
      return formatted ?? fullText(node);
    }
    default:
      return fullText(node);
  }
}
function buildMaskedSource(source, start, end, slots) {
  let cursor = start;
  let out = "";
  for (const slot of slots) {
    out += source.slice(cursor, slot.start);
    out += slot.marker;
    cursor = slot.end;
  }
  out += source.slice(cursor, end);
  return out;
}
function normalizeStyleValueReplacementText(value) {
  const lines = normalizeLineEndingsToLf(value).split("\n");
  if (lines.length <= 1) {
    return value;
  }
  let minIndent = Number.POSITIVE_INFINITY;
  for (let i = 1; i < lines.length; i++) {
    const line6 = lines[i];
    if (!line6 || line6.trim().length === 0) {
      continue;
    }
    const indent7 = line6.match(/^[ \t]*/u)?.[0].length ?? 0;
    if (indent7 < minIndent) {
      minIndent = indent7;
    }
  }
  if (!Number.isFinite(minIndent) || minIndent <= 0) {
    return lines.join("\n");
  }
  for (let i = 1; i < lines.length; i++) {
    const line6 = lines[i];
    if (!line6 || line6.trim().length === 0) {
      continue;
    }
    lines[i] = line6.slice(Math.min(minIndent, line6.length));
  }
  return lines.join("\n");
}
function applyMarkerReplacements(value, slots) {
  let out = value;
  let allFound = true;
  for (const slot of slots) {
    const start = out.indexOf(slot.marker);
    if (start < 0) {
      allFound = false;
      continue;
    }
    const duplicate = out.indexOf(slot.marker, start + slot.marker.length) >= 0;
    if (duplicate) {
      allFound = false;
      continue;
    }
    out = `${out.slice(0, start)}${slot.replacementText}${out.slice(start + slot.marker.length)}`;
  }
  return { text: out, allFound };
}
function maskStyleDirectiveLikeComments(value, markerSessionKey) {
  const slots = [];
  let index = 0;
  const masked = value.replace(/\/\*[^]*?\*\//gu, (match) => {
    if (!match.includes("@")) {
      return match;
    }
    const marker = `/*__blade_comment_slot_${markerSessionKey}_${index}__*/`;
    slots.push({ marker, text: match });
    index++;
    return marker;
  });
  return { text: masked, slots };
}
function applyStyleCommentReplacements(value, slots) {
  let out = value;
  let allFound = true;
  for (const slot of slots) {
    const start = out.indexOf(slot.marker);
    if (start < 0) {
      allFound = false;
      continue;
    }
    const duplicate = out.indexOf(slot.marker, start + slot.marker.length) >= 0;
    if (duplicate) {
      allFound = false;
      continue;
    }
    out = `${out.slice(0, start)}${slot.text}${out.slice(start + slot.marker.length)}`;
  }
  return { text: out, allFound };
}
function getEmbeddedTextToDocOptions(node, parser) {
  const textToDocOptions = {
    parser,
    __embeddedInHtml: true
  };
  if (parser === "babel") {
    let sourceType = "script";
    const attrMap = getAttrMap(node);
    if (attrMap.type === "module" || (attrMap.type === "text/babel" || attrMap.type === "text/jsx") && attrMap["data-type"] === "module") {
      sourceType = "module";
    }
    textToDocOptions.__babelSourceType = sourceType;
  }
  return textToDocOptions;
}
async function createSubformatOptions(options2, parser, node) {
  const base = { ...options2 };
  delete base.parser;
  delete base.parentParser;
  delete base.plugins;
  delete base.rangeStart;
  delete base.rangeEnd;
  delete base.cursorOffset;
  const plugins = await resolveEmbeddedParserPlugins(options2, parser);
  return {
    ...base,
    ...getEmbeddedTextToDocOptions(node, parser),
    plugins
  };
}
function buildScriptLikeElementDoc(path, node, options2, print, content, rawValue, contentAlreadyIndented = false) {
  const isEmpty = /^\s*$/.test(rawValue);
  return [
    printOpeningTagPrefix(node, options2),
    group5(printOpeningTag(path, options2, print)),
    isEmpty ? "" : contentAlreadyIndented ? [hardline6, content] : indent5([hardline6, content]),
    isEmpty ? "" : hardline6,
    printClosingTag(node, options2),
    printClosingTagSuffix(node, options2)
  ];
}
function stripBoundaryLineBreaks(value) {
  let next = value;
  if (next.startsWith("\r\n")) {
    next = next.slice(2);
  } else if (next.startsWith("\n")) {
    next = next.slice(1);
  }
  if (next.endsWith("\r\n")) {
    next = next.slice(0, -2);
  } else if (next.endsWith("\n")) {
    next = next.slice(0, -1);
  }
  return next;
}
function trimTrailingWhitespaceOnlyLine(value) {
  return value.replace(/\r?\n[^\S\r\n]*$/u, "");
}
function applyTextTransforms(value, transforms) {
  let next = value;
  for (const transform of transforms) {
    next = transform(next);
  }
  return next;
}
function normalizeEmbeddedRawContentFallback(value) {
  return applyTextTransforms(value, [
    stripBoundaryLineBreaks,
    trimTrailingWhitespaceOnlyLine,
    dedentString,
    normalizeLineEndingsToLf
  ]);
}
function normalizeStyleEmbeddedOutput(value) {
  return applyTextTransforms(value, [
    normalizeStyleDirectiveBoundaries,
    normalizeStyleBladeValueIndentation,
    normalizeStyleStructuralDirectiveSemicolons,
    normalizeStyleDirectiveCommentChains,
    normalizeStyleDirectiveCommentSelectorLines,
    normalizeStyleDirectiveChainBlankLines,
    normalizeStyleBlankLineRuns,
    normalizeStyleStandaloneSemicolonLines,
    repairStyleBrokenCommentClosers,
    normalizeStyleCommentRunLines,
    normalizeStyleDirectiveSelectorAlignment,
    trimTrailingHorizontalWhitespace
  ]);
}
function normalizeEmbeddedOutput(value, tagName) {
  const normalized = tagName === "style" ? normalizeStyleEmbeddedOutput(value) : value;
  return applyTextTransforms(normalized, [
    normalizeLineEndingsToLf,
    trimTrailingWhitespaceOnlyLine,
    trimFinalLineBreak
  ]);
}
function normalizeStyleDirectiveBoundaries(value) {
  const directivePattern = /^@[A-Za-z_][A-Za-z0-9_]*(?:\s*\([^)]*\))?/u;
  let state = "code";
  let out = "";
  for (let i = 0; i < value.length; i++) {
    const ch = value[i];
    const next = i + 1 < value.length ? value[i + 1] : "";
    if (state === "lineComment") {
      out += ch;
      if (ch === "\n") {
        state = "code";
      }
      continue;
    }
    if (state === "blockComment") {
      out += ch;
      if (ch === "*" && next === "/") {
        out += "/";
        i++;
        state = "code";
      }
      continue;
    }
    if (state === "single") {
      out += ch;
      if (ch === "\\") {
        if (i + 1 < value.length) {
          out += value[i + 1];
          i++;
        }
        continue;
      }
      if (ch === "'") {
        state = "code";
      }
      continue;
    }
    if (state === "double") {
      out += ch;
      if (ch === "\\") {
        if (i + 1 < value.length) {
          out += value[i + 1];
          i++;
        }
        continue;
      }
      if (ch === '"') {
        state = "code";
      }
      continue;
    }
    if (ch === "/" && next === "*") {
      out += "/*";
      i++;
      state = "blockComment";
      continue;
    }
    if (ch === "/" && next === "/" && shouldTreatAsStyleLineComment(value, 0, i)) {
      out += "//";
      i++;
      state = "lineComment";
      continue;
    }
    if (ch === "'") {
      out += ch;
      state = "single";
      continue;
    }
    if (ch === '"') {
      out += ch;
      state = "double";
      continue;
    }
    if (ch === "}" && value[i - 1] !== "{" && next !== "}") {
      let j = i + 1;
      while (j < value.length) {
        const ws = value[j];
        if (ws === " " || ws === "	" || ws === "\r" || ws === "\n") {
          j++;
          continue;
        }
        break;
      }
      if (j > i + 1 && directivePattern.test(value.slice(j))) {
        out += "}\n";
        i = j - 1;
        continue;
      }
    }
    out += ch;
  }
  return out;
}
var STYLE_DIRECTIVE_BLOCK_OPENERS = /* @__PURE__ */ new Set([
  "if",
  "unless",
  "isset",
  "empty",
  "for",
  "foreach",
  "forelse",
  "while",
  "switch",
  "php",
  "verbatim"
]);
var STYLE_DIRECTIVE_BLOCK_CLOSERS = /* @__PURE__ */ new Set([
  "endif",
  "endunless",
  "endisset",
  "endempty",
  "endfor",
  "endforeach",
  "endforelse",
  "endwhile",
  "endswitch",
  "endphp",
  "endverbatim"
]);
var STYLE_DIRECTIVE_BRANCHES = /* @__PURE__ */ new Set(["else", "elseif", "empty", "case", "default"]);
var STYLE_RAW_BLADE_FALLBACK_RE = /(?:\{\{|\{!!|@(?:elseif|endif|endunless|endisset|endempty|endfor|endforeach|endforelse|endwhile|endswitch|endphp|endverbatim|foreach|forelse|case|default)\b)/u;
var LARGE_STYLE_EMBED_CHAR_THRESHOLD = 2e4;
var LARGE_STYLE_EMBED_LINE_THRESHOLD = 300;
var UNSTABLE_STYLE_ESCAPED_SLASH_LITERAL = /\/[^\r\n;{}]*\\\s*\/\s*\//u;
function getDirectiveNameFromLine(trimmedLine) {
  const match = trimmedLine.match(/^@([A-Za-z_][A-Za-z0-9_]*)/u);
  return match ? match[1].toLowerCase() : null;
}
function isStyleCommentLine(trimmedLine) {
  return trimmedLine.startsWith("/*") && trimmedLine.endsWith("*/") || trimmedLine.startsWith("//");
}
function normalizeStyleDirectiveLineArgSpacing(line6) {
  const match = line6.match(/^([ \t]*)@([A-Za-z_][A-Za-z0-9_]*)\s*\(/u);
  if (!match) {
    return line6;
  }
  const indent7 = match[1];
  const name = match[2].toLowerCase();
  if (!STYLE_DIRECTIVE_BLOCK_OPENERS.has(name) && !STYLE_DIRECTIVE_BRANCHES.has(name) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(name) && !EXPRESSION_DIRECTIVES.has(name)) {
    return line6;
  }
  return line6.replace(/^([ \t]*)@([A-Za-z_][A-Za-z0-9_]*)\s*\(/u, `${indent7}@$2 (`);
}
function isBladeValueLine(trimmedLine) {
  return trimmedLine.startsWith("@") || trimmedLine.startsWith("{{") || trimmedLine.startsWith("{!!") || trimmedLine.startsWith("<?php");
}
function splitStyleBladeValueChunks(trimmedLine) {
  const directivePattern = /(?:^|\s)(@[A-Za-z_][A-Za-z0-9_]*(?:\s*\([^)]*\))?)(?=\s|$)/gu;
  const chunks = [];
  let cursor = 0;
  for (const match of trimmedLine.matchAll(directivePattern)) {
    const directive = match[1];
    if (!directive) {
      continue;
    }
    const fullMatch = match[0];
    const fullStart = match.index ?? 0;
    const directiveStart = fullStart + fullMatch.lastIndexOf(directive);
    const before = trimmedLine.slice(cursor, directiveStart).trim();
    if (before.length > 0) {
      chunks.push(before);
    }
    chunks.push(directive);
    cursor = directiveStart + directive.length;
  }
  const tail = trimmedLine.slice(cursor).trim();
  if (tail.length > 0) {
    chunks.push(tail);
  }
  if (chunks.length === 0 && trimmedLine.length > 0) {
    chunks.push(trimmedLine);
  }
  return chunks;
}
function normalizeStyleBladeValueIndentation(value) {
  const lines = value.split(/\r?\n/u);
  for (let i = 0; i < lines.length; i++) {
    const current = lines[i];
    if (!/:\s*$/u.test(current)) continue;
    const baseIndent = current.match(/^\s*/u)?.[0] ?? "";
    const firstContent = i + 1;
    if (firstContent >= lines.length) continue;
    let semicolonIndex = -1;
    let sawBladeValueContent = false;
    const valueChunks = [];
    for (let j = firstContent; j < lines.length; j++) {
      const trimmed = lines[j].trim();
      if (trimmed.length === 0) continue;
      let lineBody = trimmed;
      let sawTrailingSemicolon = false;
      if (lineBody === ";") {
        semicolonIndex = j;
        break;
      }
      if (lineBody.endsWith(";")) {
        sawTrailingSemicolon = true;
        semicolonIndex = j;
        lineBody = lineBody.slice(0, -1).trimEnd();
      }
      if (lineBody.length > 0) {
        const chunks = splitStyleBladeValueChunks(lineBody);
        valueChunks.push(...chunks);
        if (chunks.some((chunk) => isBladeValueLine(chunk))) {
          sawBladeValueContent = true;
        }
      }
      if (sawTrailingSemicolon) {
        break;
      }
    }
    if (!sawBladeValueContent || semicolonIndex < 0 || valueChunks.length === 0) continue;
    let depth = 0;
    const replacementLines = [];
    for (const chunk of valueChunks) {
      const trimmed = chunk.trim();
      if (trimmed.length === 0) continue;
      const directiveName = getDirectiveNameFromLine(trimmed);
      if (directiveName && (STYLE_DIRECTIVE_BLOCK_CLOSERS.has(directiveName) || STYLE_DIRECTIVE_BRANCHES.has(directiveName))) {
        depth = Math.max(0, depth - 1);
      }
      const lineIndent = `${baseIndent}  ${"  ".repeat(depth)}`;
      replacementLines.push(`${lineIndent}${trimmed}`);
      if (directiveName && (STYLE_DIRECTIVE_BLOCK_OPENERS.has(directiveName) || STYLE_DIRECTIVE_BRANCHES.has(directiveName))) {
        depth++;
      }
    }
    replacementLines.push(`${baseIndent}  ;`);
    lines.splice(firstContent, semicolonIndex - firstContent + 1, ...replacementLines);
    i = firstContent + replacementLines.length - 1;
  }
  return lines.join("\n");
}
function normalizeStyleStructuralDirectiveSemicolons(value) {
  let state = "code";
  let out = "";
  let lineCode = "";
  for (let i = 0; i < value.length; i++) {
    const ch = value[i];
    const next = i + 1 < value.length ? value[i + 1] : "";
    if (state === "lineComment") {
      out += ch;
      if (ch === "\n") {
        state = "code";
        lineCode = "";
      }
      continue;
    }
    if (state === "blockComment") {
      out += ch;
      if (ch === "\n") {
        lineCode = "";
      }
      if (ch === "*" && next === "/") {
        out += "/";
        i++;
        state = "code";
      }
      continue;
    }
    if (state === "single") {
      out += ch;
      if (ch === "\\") {
        if (i + 1 < value.length) {
          out += value[i + 1];
          i++;
        }
        continue;
      }
      if (ch === "'") {
        state = "code";
      }
      if (ch === "\n") {
        lineCode = "";
      }
      continue;
    }
    if (state === "double") {
      out += ch;
      if (ch === "\\") {
        if (i + 1 < value.length) {
          out += value[i + 1];
          i++;
        }
        continue;
      }
      if (ch === '"') {
        state = "code";
      }
      if (ch === "\n") {
        lineCode = "";
      }
      continue;
    }
    if (ch === "/" && next === "*") {
      out += "/*";
      i++;
      state = "blockComment";
      continue;
    }
    if (ch === "/" && next === "/" && shouldTreatAsStyleLineComment(value, 0, i)) {
      out += "//";
      i++;
      state = "lineComment";
      continue;
    }
    if (ch === "'") {
      out += ch;
      lineCode += ch;
      state = "single";
      continue;
    }
    if (ch === '"') {
      out += ch;
      lineCode += ch;
      state = "double";
      continue;
    }
    if (ch === ";") {
      const directiveMatch = lineCode.match(/@([A-Za-z_][A-Za-z0-9_]*)(?:\s*\([^)]*\))?\s*$/u);
      if (directiveMatch) {
        const name = directiveMatch[1].toLowerCase();
        if (STYLE_DIRECTIVE_BLOCK_OPENERS.has(name) || STYLE_DIRECTIVE_BRANCHES.has(name) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(name)) {
          let j = i + 1;
          while (j < value.length) {
            const ws = value[j];
            if (ws === " " || ws === "	" || ws === "\r") {
              j++;
              continue;
            }
            break;
          }
          const nextCh = j < value.length ? value[j] : "";
          const nextNextCh = j + 1 < value.length ? value[j + 1] : "";
          if (nextCh === "" || nextCh === "\n" || nextCh === "/" && nextNextCh === "*" || nextCh === "/" && nextNextCh === "/") {
            continue;
          }
        }
      }
    }
    out += ch;
    if (ch === "\n") {
      lineCode = "";
    } else {
      lineCode += ch;
    }
  }
  return out;
}
function normalizeStyleDirectiveCommentChains(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  for (const line6 of lines) {
    const trimmed = line6.trim();
    if (trimmed.length === 0 || !trimmed.includes("@")) {
      out.push(line6);
      continue;
    }
    const indent7 = line6.match(/^\s*/u)?.[0] ?? "";
    const tokenRe = /@[A-Za-z_][A-Za-z0-9_]*(?:\s*\([^)]*\))?|\/\*[^]*?\*\//gu;
    const tokens = Array.from(trimmed.matchAll(tokenRe), (match) => match[0].trim());
    if (tokens.length <= 1) {
      out.push(line6);
      continue;
    }
    const remainder = trimmed.replace(/@[A-Za-z_][A-Za-z0-9_]*(?:\s*\([^)]*\))?|\/\*[^]*?\*\//gu, "").trim();
    if (remainder.length > 0) {
      out.push(line6);
      continue;
    }
    if (!tokens.some((token) => token.startsWith("@")) || !tokens.every((token) => token.startsWith("@") || token.startsWith("/*"))) {
      out.push(line6);
      continue;
    }
    for (const token of tokens) {
      if (token.startsWith("@")) {
        out.push(normalizeStyleDirectiveLineArgSpacing(`${indent7}${token}`));
      } else {
        out.push(`${indent7}${token}`);
      }
    }
  }
  return out.join("\n");
}
function normalizeStyleDirectiveCommentSelectorLines(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  const selectorLikeStartRe = /^([.#:[*]|[A-Za-z_]).*\{/u;
  for (const line6 of lines) {
    const indent7 = line6.match(/^\s*/u)?.[0] ?? "";
    const trimmed = line6.trim();
    const directiveMatch = trimmed.match(/^@[A-Za-z_][A-Za-z0-9_]*(?:\s*\([^)]*\))?/u);
    if (!directiveMatch) {
      out.push(line6);
      continue;
    }
    const directiveName = getDirectiveNameFromLine(directiveMatch[0]);
    if (!directiveName || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(directiveName) && !STYLE_DIRECTIVE_BRANCHES.has(directiveName) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(directiveName)) {
      out.push(line6);
      continue;
    }
    let cursor = directiveMatch[0].length;
    const comments = [];
    for (; ; ) {
      const rest = trimmed.slice(cursor).trimStart();
      if (!rest.startsWith("/*")) {
        break;
      }
      const commentEnd = rest.indexOf("*/");
      if (commentEnd < 0) {
        break;
      }
      comments.push(rest.slice(0, commentEnd + 2));
      cursor = trimmed.length - rest.length + commentEnd + 2;
    }
    const tail = trimmed.slice(cursor).trimStart();
    if (comments.length === 0 || tail.length === 0 || !selectorLikeStartRe.test(tail)) {
      out.push(line6);
      continue;
    }
    out.push(normalizeStyleDirectiveLineArgSpacing(`${indent7}${directiveMatch[0]}`));
    for (const comment of comments) {
      out.push(`${indent7}${comment}`);
    }
    out.push(`${indent7}${tail}`);
  }
  return out.join("\n");
}
function classifyStyleDirectiveChainLine(line6) {
  const trimmed = line6.trim();
  if (trimmed.length === 0) {
    return "other";
  }
  const directiveName = getDirectiveNameFromLine(trimmed);
  if (directiveName && (STYLE_DIRECTIVE_BLOCK_OPENERS.has(directiveName) || STYLE_DIRECTIVE_BRANCHES.has(directiveName) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(directiveName))) {
    return "structuralDirective";
  }
  if (isStyleCommentLine(trimmed)) {
    if (/^\/\*\s*@/u.test(trimmed) || /^\/\/\s*@/u.test(trimmed)) {
      return "directiveComment";
    }
    return "genericComment";
  }
  return "other";
}
function normalizeStyleDirectiveChainBlankLines(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  for (let i = 0; i < lines.length; i++) {
    const current = lines[i];
    if (current.trim().length > 0) {
      out.push(current);
      continue;
    }
    let prevIndex = out.length - 1;
    while (prevIndex >= 0 && out[prevIndex].trim().length === 0) {
      prevIndex--;
    }
    let nextIndex = i + 1;
    while (nextIndex < lines.length && lines[nextIndex].trim().length === 0) {
      nextIndex++;
    }
    if (prevIndex < 0 || nextIndex >= lines.length) {
      out.push(current);
      continue;
    }
    const prevKind = classifyStyleDirectiveChainLine(out[prevIndex]);
    const nextKind = classifyStyleDirectiveChainLine(lines[nextIndex]);
    const shouldDrop = prevKind === "structuralDirective" && nextKind === "structuralDirective" || prevKind === "structuralDirective" && nextKind === "genericComment" || prevKind === "genericComment" && nextKind === "structuralDirective" || prevKind === "directiveComment" && nextKind === "structuralDirective" || prevKind === "structuralDirective" && nextKind === "directiveComment" || prevKind === "directiveComment" && nextKind === "genericComment" || prevKind === "genericComment" && nextKind === "directiveComment";
    if (!shouldDrop) {
      out.push(current);
    }
  }
  return out.join("\n");
}
function normalizeStyleBlankLineRuns(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  let blankRun = 0;
  for (const line6 of lines) {
    if (line6.trim().length === 0) {
      blankRun++;
      if (blankRun <= 1) {
        out.push("");
      }
      continue;
    }
    blankRun = 0;
    out.push(line6);
  }
  return out.join("\n");
}
function normalizeStyleStandaloneSemicolonLines(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  for (let i = 0; i < lines.length; i++) {
    const trimmed = lines[i].trim();
    if (trimmed !== ";") {
      out.push(lines[i]);
      continue;
    }
    let prevIndex = out.length - 1;
    while (prevIndex >= 0 && out[prevIndex].trim().length === 0) {
      prevIndex--;
    }
    if (prevIndex < 0) {
      out.push(lines[i]);
      continue;
    }
    const previousDirective = getDirectiveNameFromLine(out[prevIndex].trim());
    const isStructuralDirective = previousDirective !== null && (STYLE_DIRECTIVE_BLOCK_OPENERS.has(previousDirective) || STYLE_DIRECTIVE_BRANCHES.has(previousDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(previousDirective));
    if (isStructuralDirective) {
      let inValueContext = false;
      for (let j = prevIndex - 1; j >= 0; j--) {
        const candidate = out[j].trim();
        if (candidate.length === 0) {
          continue;
        }
        if (getDirectiveNameFromLine(candidate) !== null || isStyleCommentLine(candidate) || isBladeValueLine(candidate)) {
          continue;
        }
        if (candidate.endsWith(":")) {
          inValueContext = true;
        }
        break;
      }
      if (inValueContext) {
        out.push(lines[i]);
        continue;
      }
    }
    if (!isStructuralDirective) {
      out.push(lines[i]);
    }
  }
  return out.join("\n");
}
function repairStyleBrokenCommentClosers(value) {
  const lines = value.split(/\r?\n/u);
  const out = lines.map((line6) => {
    const trimmedStart = line6.trimStart();
    if (!trimmedStart.startsWith("/*")) {
      return line6;
    }
    const trimmedEnd = line6.trimEnd();
    if (trimmedEnd.endsWith("*/")) {
      return line6;
    }
    if (trimmedEnd.endsWith("*;")) {
      return line6.replace(/\*;$/u, "*/");
    }
    if (trimmedEnd.endsWith("*")) {
      return `${line6}/`;
    }
    return line6;
  });
  return out.join("\n");
}
function normalizeStyleCommentRunLines(value) {
  const lines = value.split(/\r?\n/u);
  const out = [];
  const selectorLikeStartRe = /^([.#:[*]|[A-Za-z_]).*\{/u;
  for (const line6 of lines) {
    const indent7 = line6.match(/^\s*/u)?.[0] ?? "";
    const trimmed = line6.trim();
    if (!trimmed.startsWith("/*")) {
      out.push(line6);
      continue;
    }
    const comments = [];
    let cursor = 0;
    let parseFailed = false;
    for (; ; ) {
      const rest = trimmed.slice(cursor).trimStart();
      if (!rest.startsWith("/*")) {
        break;
      }
      const commentEnd = rest.indexOf("*/");
      if (commentEnd < 0) {
        parseFailed = true;
        break;
      }
      comments.push(rest.slice(0, commentEnd + 2));
      cursor = trimmed.length - rest.length + commentEnd + 2;
    }
    if (parseFailed || comments.length === 0) {
      out.push(line6);
      continue;
    }
    const tail = trimmed.slice(cursor).trimStart();
    const shouldSplit = comments.length >= 2 || tail.length > 0 && (selectorLikeStartRe.test(tail) || tail.startsWith("@") || tail.startsWith("/*"));
    if (!shouldSplit) {
      out.push(line6);
      continue;
    }
    for (const comment of comments) {
      out.push(`${indent7}${comment}`);
    }
    if (tail.length > 0) {
      out.push(`${indent7}${tail}`);
    }
  }
  return out.join("\n");
}
function normalizeStyleDirectiveSelectorAlignment(value) {
  const lines = value.split(/\r?\n/u);
  const selectorLikeStartRe = /^([.#:[*]|[A-Za-z_]).*\{\s*$/u;
  for (let iteration = 0; iteration < 4; iteration++) {
    let changed = false;
    for (let i = 0; i < lines.length; i++) {
      const normalized = normalizeStyleDirectiveLineArgSpacing(lines[i]);
      if (normalized !== lines[i]) {
        lines[i] = normalized;
        changed = true;
      }
    }
    for (let i = 0; i < lines.length; i++) {
      const currentTrimmed = lines[i].trim();
      if (currentTrimmed.length === 0) {
        continue;
      }
      let prevIndex = i - 1;
      while (prevIndex >= 0 && lines[prevIndex].trim().length === 0) {
        prevIndex--;
      }
      if (prevIndex < 0) {
        continue;
      }
      const previousTrimmed = lines[prevIndex].trim();
      const directiveName = getDirectiveNameFromLine(previousTrimmed);
      if (!directiveName || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(directiveName) && !STYLE_DIRECTIVE_BRANCHES.has(directiveName) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(directiveName)) {
        continue;
      }
      if (!currentTrimmed.endsWith("{") || getDirectiveNameFromLine(currentTrimmed) !== null) {
        continue;
      }
      const previousIndent = lines[prevIndex].match(/^\s*/u)?.[0] ?? "";
      const currentIndent = lines[i].match(/^\s*/u)?.[0] ?? "";
      if (currentIndent.length <= previousIndent.length) {
        continue;
      }
      const nextLine = `${previousIndent}${currentTrimmed}`;
      if (nextLine !== lines[i]) {
        lines[i] = nextLine;
        changed = true;
      }
    }
    for (let i = 0; i < lines.length; i++) {
      const currentTrimmed = lines[i].trim();
      if (!isStyleCommentLine(currentTrimmed) || !/^\/\*\s*@/u.test(currentTrimmed) && !/^\/\/\s*@/u.test(currentTrimmed)) {
        continue;
      }
      let prevIndex = i - 1;
      while (prevIndex >= 0 && lines[prevIndex].trim().length === 0) {
        prevIndex--;
      }
      if (prevIndex < 0) {
        continue;
      }
      const previousTrimmed = lines[prevIndex].trim();
      let previousIndent = lines[prevIndex].match(/^\s*/u)?.[0] ?? "";
      let previousDirective = getDirectiveNameFromLine(previousTrimmed);
      if (!previousDirective || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(previousDirective) && !STYLE_DIRECTIVE_BRANCHES.has(previousDirective) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(previousDirective)) {
        let anchorIndex = prevIndex - 1;
        while (anchorIndex >= 0) {
          const anchorTrimmed = lines[anchorIndex].trim();
          if (anchorTrimmed.length === 0 || isStyleCommentLine(anchorTrimmed)) {
            anchorIndex--;
            continue;
          }
          const anchorDirective = getDirectiveNameFromLine(anchorTrimmed);
          if (anchorDirective && (STYLE_DIRECTIVE_BLOCK_OPENERS.has(anchorDirective) || STYLE_DIRECTIVE_BRANCHES.has(anchorDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(anchorDirective))) {
            previousDirective = anchorDirective;
            previousIndent = lines[anchorIndex].match(/^\s*/u)?.[0] ?? "";
          }
          break;
        }
      }
      if (!previousDirective || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(previousDirective) && !STYLE_DIRECTIVE_BRANCHES.has(previousDirective) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(previousDirective)) {
        continue;
      }
      const currentIndent = lines[i].match(/^\s*/u)?.[0] ?? "";
      if (currentIndent.length <= previousIndent.length) {
        continue;
      }
      const nextLine = `${previousIndent}${currentTrimmed}`;
      if (nextLine !== lines[i]) {
        lines[i] = nextLine;
        changed = true;
      }
    }
    for (let i = 0; i < lines.length; i++) {
      const currentTrimmed = lines[i].trim();
      const currentDirective = getDirectiveNameFromLine(currentTrimmed);
      if (!currentDirective || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(currentDirective) && !STYLE_DIRECTIVE_BRANCHES.has(currentDirective) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(currentDirective)) {
        continue;
      }
      let prevIndex = i - 1;
      while (prevIndex >= 0 && lines[prevIndex].trim().length === 0) {
        prevIndex--;
      }
      if (prevIndex < 0) {
        continue;
      }
      const previousTrimmed = lines[prevIndex].trim();
      const previousIndent = lines[prevIndex].match(/^\s*/u)?.[0] ?? "";
      const currentIndent = lines[i].match(/^\s*/u)?.[0] ?? "";
      if ((STYLE_DIRECTIVE_BRANCHES.has(currentDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(currentDirective) || STYLE_DIRECTIVE_BLOCK_OPENERS.has(currentDirective)) && isStyleCommentLine(previousTrimmed) && currentIndent.length > previousIndent.length) {
        const nextLine = `${previousIndent}${currentTrimmed}`;
        if (nextLine !== lines[i]) {
          lines[i] = nextLine;
          changed = true;
        }
        continue;
      }
      const previousDirective = getDirectiveNameFromLine(previousTrimmed);
      if (!previousDirective || !STYLE_DIRECTIVE_BLOCK_OPENERS.has(previousDirective) && !STYLE_DIRECTIVE_BRANCHES.has(previousDirective) && !STYLE_DIRECTIVE_BLOCK_CLOSERS.has(previousDirective)) {
        continue;
      }
      if (currentIndent.length <= previousIndent.length) {
        continue;
      }
      const shouldAlign = STYLE_DIRECTIVE_BRANCHES.has(currentDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(currentDirective) || STYLE_DIRECTIVE_BRANCHES.has(previousDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(previousDirective);
      if (shouldAlign) {
        const nextLine = `${previousIndent}${currentTrimmed}`;
        if (nextLine !== lines[i]) {
          lines[i] = nextLine;
          changed = true;
        }
        continue;
      }
      if (STYLE_DIRECTIVE_BLOCK_OPENERS.has(currentDirective) && STYLE_DIRECTIVE_BLOCK_OPENERS.has(previousDirective)) {
        let nextIndex = i + 1;
        let chainLeadsToSelector = false;
        while (nextIndex < lines.length) {
          const nextTrimmed = lines[nextIndex].trim();
          if (nextTrimmed.length === 0) {
            nextIndex++;
            continue;
          }
          if (nextTrimmed === currentTrimmed) {
            nextIndex++;
            continue;
          }
          if (isStyleCommentLine(nextTrimmed)) {
            nextIndex++;
            continue;
          }
          const nextDirective = getDirectiveNameFromLine(nextTrimmed);
          if (nextDirective && STYLE_DIRECTIVE_BLOCK_OPENERS.has(nextDirective)) {
            nextIndex++;
            continue;
          }
          if (nextDirective && (STYLE_DIRECTIVE_BRANCHES.has(nextDirective) || STYLE_DIRECTIVE_BLOCK_CLOSERS.has(nextDirective))) {
            nextIndex++;
            continue;
          }
          if (selectorLikeStartRe.test(nextTrimmed)) {
            chainLeadsToSelector = true;
          }
          break;
        }
        if (chainLeadsToSelector) {
          const nextLine = `${previousIndent}${currentTrimmed}`;
          if (nextLine !== lines[i]) {
            lines[i] = nextLine;
            changed = true;
          }
        }
      }
    }
    if (!changed) {
      break;
    }
  }
  const lineAdjusted = lines.join("\n");
  const directiveAligned = lineAdjusted.replace(
    /((?:^|\n)([ \t]*)@(?:else|elseif|case|default|endif|endunless|endisset|endempty|endfor|endforeach|endforelse|endwhile|endswitch|endphp|endverbatim)[^\n]*\n)[ \t]+(@(?:if|unless|isset|empty|for|foreach|forelse|while|switch|php|verbatim|else|elseif|case|default|endif|endunless|endisset|endempty|endfor|endforeach|endforelse|endwhile|endswitch|endphp|endverbatim)[^\n]*)(?=\n|$)/gu,
    (_match, prefix, indent7, directiveLine) => `${prefix}${indent7}${directiveLine.trimStart()}`
  );
  return directiveAligned.replace(
    /((?:^|\n)([ \t]*)@(?:if|unless|isset|empty|for|foreach|forelse|while|switch|php|verbatim|else|elseif|case|default|endif|endunless|endisset|endempty|endfor|endforeach|endforelse|endwhile|endswitch|endphp|endverbatim)[^\n]*\n)[ \t]+(([.#:[*]|[A-Za-z_])[^\n]*\{[ \t]*)(?=\n|$)/gu,
    (_match, prefix, indent7, selectorStart) => `${prefix}${indent7}${selectorStart}`
  );
}
function shouldUseMixedRawContentEmbedding(node, options2) {
  if (shouldBypassStyleParserEmbedding(node, options2)) {
    return false;
  }
  const parser = inferElementParser(node, options2);
  if (!parser) return false;
  if (!isPhpFormattingEnabled(options2) && node.tagName === "script") {
    const range2 = getElementContentRange(node);
    const constructs2 = collectLeafConstructs(node, range2.start, range2.end);
    if (constructs2.length === 0) {
      return false;
    }
    if (constructs2.some(
      (child) => child.kind === 10 /* PhpBlock */ || child.kind === 11 /* PhpTag */ || child.kind === 7 /* Directive */ && !isDirectiveInsideScriptLiteralOrComment(child, node.source, range2.start, range2.end) && (isStructuralScriptDirective(child) || isExpressionScriptDirective(child) || isInlineScriptDirectiveExpression(child, node.source, range2.start, range2.end) || isStandaloneScriptDirective(child, node.source, range2.start, range2.end))
    )) {
      return true;
    }
    return constructs2.some(
      (child) => child.kind === 7 /* Directive */ && isKnownBladeDirective(child) && isDirectiveInsideScriptLiteralOrComment(child, node.source, range2.start, range2.end)
    );
  }
  if (node.tagName === "script") {
    const range2 = getElementContentRange(node);
    const constructs2 = collectLeafConstructs(node, range2.start, range2.end);
    if (constructs2.length === 0) {
      return false;
    }
    if (constructs2.some((child) => {
      if (child.kind === 7 /* Directive */ && isDirectiveInsideScriptLiteralOrComment(child, node.source, range2.start, range2.end)) {
        return false;
      }
      return isBladeConstructChild(child, "script");
    })) {
      return true;
    }
    if (constructs2.some(
      (child) => child.kind === 7 /* Directive */ && isKnownBladeDirective(child) && isDirectiveInsideScriptLiteralOrComment(child, node.source, range2.start, range2.end)
    )) {
      return true;
    }
    return parentContainsBladeSyntax(node, "script");
  }
  if (node.children.length > 0) {
    if (node.children.some((child) => isBladeConstructChild(child, "style"))) {
      return true;
    }
  }
  const range = getElementContentRange(node);
  const constructs = collectLeafConstructs(node, range.start, range.end);
  if (constructs.some(
    (child) => child.kind === 7 /* Directive */ && isKnownBladeDirective(child) && isDirectiveInsideStyleLiteralOrComment(child, node.source, range.start, range.end)
  )) {
    return true;
  }
  const rawValue = node.source.slice(range.start, range.end);
  if (STYLE_RAW_BLADE_FALLBACK_RE.test(rawValue)) {
    return true;
  }
  return parentContainsBladeSyntax(node, "style");
}
function isStructuralScriptDirective(node) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  if (node.children.length > 0) {
    return true;
  }
  const name = extractDirectiveName3(node);
  if (!name) {
    return false;
  }
  const directive = node.buildResult.directives?.getDirective(name);
  if (!directive) {
    return false;
  }
  return directive.role !== 0 /* None */ || directive.isCondition || directive.isSwitch || directive.isSwitchBranch || directive.isSwitchTerminator || directive.isConditionalPair || directive.isConditionalClose || directive.hasConditionLikeBranches || directive.terminators.length > 0;
}
function isExpressionScriptDirective(node) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  const name = extractDirectiveName3(node);
  return name !== null && EXPRESSION_DIRECTIVES.has(name);
}
function isStandaloneScriptDirective(node, source, contentStart, contentEnd) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  const replacementRange = getReplacementRange(node);
  if (replacementRange.start < contentStart || replacementRange.end > contentEnd) {
    return false;
  }
  if (isLikelyInsideScriptLiteralOrComment(source, contentStart, replacementRange.start)) {
    return false;
  }
  const lineStart = Math.max(
    contentStart,
    source.lastIndexOf("\n", Math.max(contentStart, replacementRange.start) - 1) + 1
  );
  let lineEnd = source.indexOf("\n", replacementRange.end);
  if (lineEnd < 0 || lineEnd > contentEnd) {
    lineEnd = contentEnd;
  }
  const before = source.slice(lineStart, replacementRange.start);
  const after = source.slice(replacementRange.end, lineEnd);
  return before.trim().length === 0 && after.trim().length === 0;
}
function isDirectiveInsideScriptLiteralOrComment(node, source, contentStart, contentEnd) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  const replacementRange = getReplacementRange(node);
  if (replacementRange.start < contentStart || replacementRange.end > contentEnd) {
    return false;
  }
  return isLikelyInsideScriptLiteralOrComment(source, contentStart, replacementRange.start);
}
function isDirectiveInsideStyleLiteralOrComment(node, source, contentStart, contentEnd) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  const replacementRange = getReplacementRange(node);
  if (replacementRange.start < contentStart || replacementRange.end > contentEnd) {
    return false;
  }
  if (isInsideStyleCommentByLineHeuristic(source, contentStart, replacementRange.start)) {
    return true;
  }
  if (isLikelySlashDelimitedStyleLiteralToken(
    source,
    replacementRange.start,
    replacementRange.end,
    contentStart,
    contentEnd
  )) {
    return true;
  }
  return isLikelyInsideStyleLiteralOrComment(source, contentStart, replacementRange.start);
}
function isInsideStyleCommentByLineHeuristic(source, contentStart, offset) {
  const lineStart = Math.max(
    contentStart,
    source.lastIndexOf("\n", Math.max(contentStart, offset) - 1) + 1
  );
  const prefix = source.slice(lineStart, offset);
  const blockOpen = prefix.lastIndexOf("/*");
  const blockClose = prefix.lastIndexOf("*/");
  if (blockOpen > blockClose) {
    return true;
  }
  const lineComment = prefix.lastIndexOf("//");
  if (lineComment >= 0 && shouldTreatAsStyleLineComment(source, contentStart, lineStart + lineComment)) {
    return true;
  }
  return false;
}
function previousNonWhitespaceChar(source, startExclusive, contentStart) {
  for (let i = startExclusive - 1; i >= contentStart; i--) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      continue;
    }
    return ch;
  }
  return null;
}
function isLikelySlashDelimitedStyleLiteralToken(source, tokenStart, tokenEnd, contentStart, contentEnd) {
  const prev = previousNonWhitespaceChar(source, tokenStart, contentStart);
  if (prev !== "/") {
    return false;
  }
  for (let i = tokenEnd; i < contentEnd; i++) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      continue;
    }
    if (ch === "\\") {
      i++;
      continue;
    }
    if (ch === "/") {
      return true;
    }
    if (ch === ";" || ch === "{" || ch === "}") {
      return false;
    }
  }
  return false;
}
function isInlineScriptDirectiveExpression(node, source, contentStart, contentEnd) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  if (node.children.length > 0 || isStructuralScriptDirective(node)) {
    return false;
  }
  if (isDirectiveInsideScriptLiteralOrComment(node, source, contentStart, contentEnd)) {
    return false;
  }
  const replacementRange = getReplacementRange(node);
  const lineStart = Math.max(
    contentStart,
    source.lastIndexOf("\n", Math.max(contentStart, replacementRange.start) - 1) + 1
  );
  let lineEnd = source.indexOf("\n", replacementRange.end);
  if (lineEnd < 0 || lineEnd > contentEnd) {
    lineEnd = contentEnd;
  }
  const before = source.slice(lineStart, replacementRange.start);
  const after = source.slice(replacementRange.end, lineEnd);
  return before.trim().length > 0 || after.trim().length > 0;
}
function isInlineStyleDirectiveExpression(node, source, contentStart, contentEnd) {
  if (node.kind !== 7 /* Directive */) {
    return false;
  }
  if (node.children.length > 0 || isStructuralScriptDirective(node)) {
    return false;
  }
  if (isDirectiveInsideStyleLiteralOrComment(node, source, contentStart, contentEnd)) {
    return false;
  }
  const replacementRange = getReplacementRange(node);
  const lineStart = Math.max(
    contentStart,
    source.lastIndexOf("\n", Math.max(contentStart, replacementRange.start) - 1) + 1
  );
  let lineEnd = source.indexOf("\n", replacementRange.end);
  if (lineEnd < 0 || lineEnd > contentEnd) {
    lineEnd = contentEnd;
  }
  const before = source.slice(lineStart, replacementRange.start);
  const after = source.slice(replacementRange.end, lineEnd);
  return before.trim().length > 0 || after.trim().length > 0;
}
function isLikelyInsideScriptLiteralOrComment(source, contentStart, offset) {
  let state = "code";
  const templateExpressionDepthStack = [];
  for (let i = contentStart; i < offset; i++) {
    const ch = source[i];
    const next = i + 1 < offset ? source[i + 1] : "";
    if (state === "lineComment") {
      if (ch === "\n") {
        state = "code";
      }
      continue;
    }
    if (state === "blockComment") {
      if (ch === "*" && next === "/") {
        state = "code";
        i++;
      }
      continue;
    }
    if (state === "single") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === "'") {
        state = "code";
      }
      continue;
    }
    if (state === "double") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === '"') {
        state = "code";
      }
      continue;
    }
    if (state === "template") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === "$" && next === "{") {
        templateExpressionDepthStack.push(1);
        state = "code";
        i++;
        continue;
      }
      if (ch === "`") {
        state = "code";
      }
      continue;
    }
    if (state === "regex") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === "[") {
        state = "regexClass";
        continue;
      }
      if (ch === "/") {
        state = "code";
      }
      continue;
    }
    if (state === "regexClass") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === "]") {
        state = "regex";
      }
      continue;
    }
    if (templateExpressionDepthStack.length > 0) {
      if (ch === "{") {
        templateExpressionDepthStack[templateExpressionDepthStack.length - 1]++;
        continue;
      }
      if (ch === "}") {
        templateExpressionDepthStack[templateExpressionDepthStack.length - 1]--;
        if (templateExpressionDepthStack[templateExpressionDepthStack.length - 1] === 0) {
          templateExpressionDepthStack.pop();
          state = "template";
        }
        continue;
      }
    }
    if (ch === "/" && next === "/") {
      state = "lineComment";
      i++;
      continue;
    }
    if (ch === "/" && next === "*") {
      state = "blockComment";
      i++;
      continue;
    }
    if (ch === "/" && next !== "/" && next !== "*" && isLikelyRegexLiteralStart(source, contentStart, i)) {
      state = "regex";
      continue;
    }
    if (ch === "'") {
      state = "single";
      continue;
    }
    if (ch === '"') {
      state = "double";
      continue;
    }
    if (ch === "`") {
      state = "template";
    }
  }
  return state !== "code";
}
function isLikelyInsideStyleLiteralOrComment(source, contentStart, offset) {
  let state = "code";
  for (let i = contentStart; i < offset; i++) {
    const ch = source[i];
    const next = i + 1 < offset ? source[i + 1] : "";
    if (state === "lineComment") {
      if (ch === "\n") {
        state = "code";
      }
      continue;
    }
    if (state === "blockComment") {
      if (ch === "*" && next === "/") {
        state = "code";
        i++;
      }
      continue;
    }
    if (state === "single") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === "'") {
        state = "code";
      }
      continue;
    }
    if (state === "double") {
      if (ch === "\\") {
        i++;
        continue;
      }
      if (ch === '"') {
        state = "code";
      }
      continue;
    }
    if (ch === "/" && next === "*") {
      state = "blockComment";
      i++;
      continue;
    }
    if (ch === "/" && next === "/" && shouldTreatAsStyleLineComment(source, contentStart, i)) {
      state = "lineComment";
      i++;
      continue;
    }
    if (ch === "'") {
      state = "single";
      continue;
    }
    if (ch === '"') {
      state = "double";
    }
  }
  return state !== "code";
}
function shouldTreatAsStyleLineComment(source, contentStart, slashIndex) {
  for (let i = slashIndex - 1; i >= contentStart; i--) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r") {
      continue;
    }
    return ch === "\n" || ch === ";" || ch === "{" || ch === "}";
  }
  return true;
}
var REGEX_PREFIX_KEYWORDS = /* @__PURE__ */ new Set([
  "return",
  "throw",
  "do",
  "case",
  "delete",
  "void",
  "typeof",
  "instanceof",
  "in",
  "of",
  "yield",
  "await",
  "else"
]);
var REGEX_AFTER_PAREN_KEYWORDS = /* @__PURE__ */ new Set(["if", "while", "for", "with", "catch"]);
var IDENTIFIER_PART_RE = /^[$_\p{ID_Continue}]$/u;
function isIdentifierPart(ch) {
  return IDENTIFIER_PART_RE.test(ch);
}
function previousNonWhitespaceIndex(source, contentStart, startExclusive) {
  for (let i = startExclusive - 1; i >= contentStart; i--) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      continue;
    }
    return i;
  }
  return -1;
}
function getPreviousIdentifierToken(source, contentStart, index) {
  if (index < contentStart || !isIdentifierPart(source[index])) {
    return null;
  }
  let tokenStart = index;
  while (tokenStart - 1 >= contentStart && isIdentifierPart(source[tokenStart - 1])) {
    tokenStart--;
  }
  return {
    token: source.slice(tokenStart, index + 1),
    start: tokenStart
  };
}
function isRegexAfterConditionParen(source, contentStart, closeParenIndex) {
  let depth = 0;
  let openParenIndex = -1;
  for (let i2 = closeParenIndex; i2 >= contentStart; i2--) {
    const ch = source[i2];
    if (ch === ")") {
      depth++;
      continue;
    }
    if (ch === "(") {
      depth--;
      if (depth === 0) {
        openParenIndex = i2;
        break;
      }
    }
  }
  if (openParenIndex < 0) {
    return false;
  }
  let i = openParenIndex - 1;
  while (i >= contentStart) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      i--;
      continue;
    }
    const tokenInfo = getPreviousIdentifierToken(source, contentStart, i);
    if (!tokenInfo) {
      return false;
    }
    return REGEX_AFTER_PAREN_KEYWORDS.has(tokenInfo.token);
  }
  return false;
}
function isLikelyRegexLiteralStart(source, contentStart, slashIndex) {
  for (let i = slashIndex - 1; i >= contentStart; i--) {
    const ch = source[i];
    if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
      continue;
    }
    if (ch === "'" || ch === '"' || ch === "`") {
      return false;
    }
    if (isIdentifierPart(ch)) {
      const tokenInfo = getPreviousIdentifierToken(source, contentStart, i);
      return tokenInfo !== null && REGEX_PREFIX_KEYWORDS.has(tokenInfo.token);
    }
    if (ch === ")") {
      return isRegexAfterConditionParen(source, contentStart, i);
    }
    if (ch === "+" || ch === "-") {
      const beforeIndex = previousNonWhitespaceIndex(source, contentStart, i);
      if (beforeIndex >= contentStart && source[beforeIndex] === ch) {
        return false;
      }
      return true;
    }
    if (ch === "]" || ch === "}") {
      return false;
    }
    return true;
  }
  return true;
}
function shouldBypassStyleParserEmbedding(node, options2) {
  if (node.kind !== 1 /* Element */ || node.tagName !== "style") {
    return false;
  }
  const parser = inferElementParser(node, options2);
  if (!parser || !isStyleParser(parser)) {
    return false;
  }
  const range = getElementContentRange(node);
  if (range.end <= range.start) {
    return false;
  }
  const rawValue = node.source.slice(range.start, range.end);
  if (UNSTABLE_STYLE_ESCAPED_SLASH_LITERAL.test(rawValue)) {
    return true;
  }
  if (rawValue.length >= LARGE_STYLE_EMBED_CHAR_THRESHOLD) {
    return true;
  }
  let lineCount = 1;
  for (let i = 0; i < rawValue.length; i++) {
    if (rawValue[i] === "\n") {
      lineCount++;
      if (lineCount > LARGE_STYLE_EMBED_LINE_THRESHOLD) {
        return true;
      }
    }
  }
  return false;
}
async function embedMixedRawContentElement(path, options2, _textToDoc, print) {
  const node = path.node;
  const parser = inferElementParser(node, options2);
  if (!parser) return null;
  const range = getElementContentRange(node);
  const rawValue = node.source.slice(range.start, range.end);
  const rawConstructs = collectLeafConstructs(node, range.start, range.end);
  const constructs = rawConstructs.filter((child) => {
    if (child.kind !== 7 /* Directive */) {
      return true;
    }
    if (node.tagName === "script" && isDirectiveInsideScriptLiteralOrComment(child, node.source, range.start, range.end)) {
      return false;
    }
    if (node.tagName === "style" && isDirectiveInsideStyleLiteralOrComment(child, node.source, range.start, range.end)) {
      return false;
    }
    return true;
  });
  const markerSessionKey = createMarkerSessionKey(node.source, range.start, range.end);
  const replacements = await Promise.all(
    constructs.map((child) => getConstructReplacementText(child, options2))
  );
  const candidates = constructs.map((child, index) => {
    const replacementRange = getReplacementRange(child);
    let kind = getPlaceholderKind(child);
    if (node.tagName === "script" && kind === "stmt" && child.kind === 7 /* Directive */ && isInlineScriptDirectiveExpression(child, node.source, range.start, range.end)) {
      kind = "expr";
    }
    if (node.tagName === "style" && kind === "stmt" && child.kind === 7 /* Directive */ && isInlineStyleDirectiveExpression(child, node.source, range.start, range.end)) {
      kind = "expr";
    }
    const inStyleValueContext = isStyleParser(parser) && isInCssValueContext(node.source, replacementRange.start, range.start);
    const replacementText = isStyleParser(parser) && inStyleValueContext ? normalizeStyleValueReplacementText(replacements[index]) : replacements[index];
    return {
      node: child,
      start: replacementRange.start,
      end: replacementRange.end,
      kind,
      inStyleValueContext,
      replacementText
    };
  });
  const slots = [];
  for (let i = 0; i < candidates.length; ) {
    const candidate = candidates[i];
    if (isStyleParser(parser) && candidate.inStyleValueContext) {
      let groupedStart = candidate.start;
      let groupedEnd = candidate.end;
      let groupedReplacement = candidate.replacementText;
      let groupedNode = candidate.node;
      let groupHasStatement = candidate.kind === "stmt";
      let j = i + 1;
      while (j < candidates.length) {
        const nextCandidate = candidates[j];
        if (!nextCandidate.inStyleValueContext) break;
        const between = node.source.slice(groupedEnd, nextCandidate.start);
        if (between.trim().length > 0) break;
        groupedReplacement += `
${nextCandidate.replacementText}`;
        groupedEnd = nextCandidate.end;
        groupHasStatement = groupHasStatement || nextCandidate.kind === "stmt";
        j++;
      }
      if (groupHasStatement) {
        const lines = groupedReplacement.split(/\r?\n/u).map((line6) => line6.trim()).filter((line6) => line6.length > 0);
        groupedReplacement = `
${lines.map((line6) => `  ${line6}`).join("\n")}
  `;
      }
      slots.push({
        node: groupedNode,
        start: groupedStart,
        end: groupedEnd,
        marker: getPlaceholderMarker(markerSessionKey, "expr", slots.length, parser, true),
        replacementText: groupedReplacement
      });
      i = j;
      continue;
    }
    slots.push({
      node: candidate.node,
      start: candidate.start,
      end: candidate.end,
      marker: getPlaceholderMarker(
        markerSessionKey,
        candidate.kind,
        slots.length,
        parser,
        candidate.inStyleValueContext
      ),
      replacementText: candidate.replacementText
    });
    i++;
  }
  const maskedRaw = buildMaskedSource(node.source, range.start, range.end, slots);
  const styleCommentMask = node.tagName === "style" ? maskStyleDirectiveLikeComments(maskedRaw, markerSessionKey) : null;
  const maskedForFormatting = styleCommentMask ? styleCommentMask.text : maskedRaw;
  const normalizedMasked = dedentString(stripBoundaryLineBreaks(maskedForFormatting));
  const maskedValue = parser === "markdown" ? dedentString(normalizedMasked.replace(/^[^\S\n]*\n/, "")) : normalizedMasked;
  let formattedMasked;
  try {
    formattedMasked = await (0, import_prettier13.format)(
      maskedValue,
      await createSubformatOptions(options2, parser, node)
    );
  } catch {
    const fallback = normalizeEmbeddedRawContentFallback(rawValue);
    return buildScriptLikeElementDoc(
      path,
      node,
      options2,
      print,
      replaceEndOfLine(fallback, hardline6),
      rawValue
    );
  }
  const unmasked = applyMarkerReplacements(formattedMasked, slots);
  if (!unmasked.allFound) {
    const fallback = normalizeEmbeddedRawContentFallback(rawValue);
    return buildScriptLikeElementDoc(
      path,
      node,
      options2,
      print,
      replaceEndOfLine(fallback, hardline6),
      rawValue
    );
  }
  let restoredText = unmasked.text;
  if (styleCommentMask && styleCommentMask.slots.length > 0) {
    const restored = applyStyleCommentReplacements(restoredText, styleCommentMask.slots);
    if (!restored.allFound) {
      const fallback = normalizeEmbeddedRawContentFallback(rawValue);
      return buildScriptLikeElementDoc(
        path,
        node,
        options2,
        print,
        replaceEndOfLine(fallback, hardline6),
        rawValue
      );
    }
    restoredText = restored.text;
  }
  const normalizedOutput = normalizeEmbeddedOutput(restoredText, node.tagName);
  return buildScriptLikeElementDoc(
    path,
    node,
    options2,
    print,
    replaceEndOfLine(normalizedOutput, hardline6),
    rawValue
  );
}

// src/print/embed.ts
var { breakParent: breakParent3, group: group6, hardline: hardline7, indent: indent6 } = import_prettier14.doc.builders;
var INLINE_INTENT_EMBED_TAGS = /* @__PURE__ */ new Set(["p", "svg"]);
var INLINE_INTENT_MIN_LENGTH = 160;
var INLINE_INTENT_TRIGGER_WIDTH_MULTIPLIER = 2;
var INLINE_INTENT_SUBFORMAT_WIDTH_MULTIPLIER = 8;
var INLINE_INTENT_GUARD_FLAG = "__bladeInlineIntentDelegated";
function handleElementEmbed(path, options2) {
  const node = path.node;
  if (shouldUseInlineIntentElementEmbed(node, options2)) {
    return async (_textToDoc, _print) => {
      try {
        const delegated = await (0, import_prettier15.format)(
          fullText(node),
          createInlineIntentSubformatOptions(options2)
        );
        return replaceEndOfLine(trimFinalLineBreak(delegated), hardline7);
      } catch {
        return fullText(node);
      }
    };
  }
  if (isScriptLikeTag(node, options2)) {
    if (shouldBypassStyleParserEmbedding(node, options2)) {
      return null;
    }
    if (shouldUseMixedRawContentEmbedding(node, options2)) {
      return async (textToDoc, print) => {
        return await embedMixedRawContentElement(
          path,
          options2,
          textToDoc,
          print
        ) ?? fullText(node);
      };
    }
    const parser = inferElementParser(node, options2);
    if (parser && node.tagName === "style" && node.children.some((child) => child.kind !== 2 /* Text */)) {
      if (node.children.some((child) => isBladeConstructChild(child, "style"))) {
        return null;
      }
      return async (textToDoc, print) => {
        const rawValue = getRawElementContent(node);
        const value = parser === "markdown" ? dedentString(rawValue.replace(/^[^\S\n]*\n/, "")) : rawValue;
        const plugins = await resolveEmbeddedParserPlugins(options2, parser);
        const textToDocOptions = {
          parser,
          __embeddedInHtml: true,
          plugins
        };
        const docContent = await textToDoc(value, textToDocOptions);
        const isEmpty = /^\s*$/.test(rawValue) || docContent === "";
        return [
          printOpeningTagPrefix(node, options2),
          group6(
            printOpeningTag(
              path,
              options2,
              print
            )
          ),
          isEmpty ? "" : indent6([hardline7, docContent]),
          isEmpty ? "" : hardline7,
          printClosingTag(node, options2),
          printClosingTagSuffix(node, options2)
        ];
      };
    }
    return null;
  }
  return null;
}
function handleTextEmbed(path, options2) {
  const node = path.node;
  if (node.parent && isScriptLikeTag(node.parent, options2)) {
    if (shouldBypassStyleParserEmbedding(node.parent, options2)) {
      return null;
    }
    const parser = inferElementParser(node.parent, options2);
    if (parser) {
      if (parser === "css" && parentContainsBladeSyntax(node.parent, "style")) {
        return null;
      }
      return async (textToDoc, _print) => {
        const rawValue = node.rawText;
        const value = parser === "markdown" ? dedentString(rawValue.replace(/^[^\S\n]*\n/, "")) : rawValue;
        const plugins = await resolveEmbeddedParserPlugins(options2, parser);
        const textToDocOptions = {
          parser,
          __embeddedInHtml: true,
          plugins
        };
        if (parser === "babel") {
          let sourceType = "script";
          const attrMap = getAttrMap(node.parent);
          if (attrMap.type === "module" || (attrMap.type === "text/babel" || attrMap.type === "text/jsx") && attrMap["data-type"] === "module") {
            sourceType = "module";
          }
          textToDocOptions.__babelSourceType = sourceType;
        }
        return [
          breakParent3,
          printOpeningTagPrefix(node, options2),
          await textToDoc(value, textToDocOptions),
          printClosingTagSuffix(node, options2)
        ];
      };
    }
  }
  return null;
}
function handleAttributeEmbed(path, options2) {
  return printEmbedAttribute(path, options2);
}
function handleEchoEmbed(path, options2) {
  if (!isPhpFormattingEnabled(options2)) return null;
  const node = path.node;
  return async (_textToDoc, print) => {
    const formatted = await formatEchoNode(node, options2);
    if (formatted === null) {
      return print(path);
    }
    const rendered = replaceEndOfLine(formatted, hardline7);
    return [printOpeningTagPrefix(node, options2), rendered, printClosingTagSuffix(node, options2)];
  };
}
function handleDirectiveEmbed(path, options2) {
  if (!isPhpFormattingEnabled(options2)) return null;
  const node = path.node;
  return async (_textToDoc, print) => {
    const phpPlugins = await resolvePhpPlugins(options2);
    if (!phpPlugins) {
      return print(path);
    }
    const formatted = await formatDirectiveNodeArgs(node, options2);
    if (formatted === null) {
      return print(path);
    }
    return replaceEndOfLine(formatted, hardline7);
  };
}
function handlePhpBlockEmbed(path, options2) {
  if (!isPhpFormattingEnabled(options2)) return null;
  const node = path.node;
  return async (_textToDoc, print) => {
    const formatted = await formatPhpBlockNode(node, options2);
    if (formatted === null) {
      return print(path);
    }
    const rendered = replaceEndOfLine(formatted, hardline7);
    return [printOpeningTagPrefix(node, options2), rendered, printClosingTagSuffix(node, options2)];
  };
}
function handlePhpTagEmbed(path, options2) {
  if (!isPhpFormattingEnabled(options2)) return null;
  const node = path.node;
  return async (_textToDoc, print) => {
    const formatted = await formatPhpTagNode(node, options2);
    if (formatted === null) {
      return print(path);
    }
    const rendered = replaceEndOfLine(formatted, hardline7);
    return [printOpeningTagPrefix(node, options2), rendered, printClosingTagSuffix(node, options2)];
  };
}
var EMBED_HANDLERS = {
  [1 /* Element */]: handleElementEmbed,
  [2 /* Text */]: handleTextEmbed,
  [19 /* Attribute */]: handleAttributeEmbed,
  [20 /* JsxAttribute */]: handleAttributeEmbed,
  [4 /* Echo */]: handleEchoEmbed,
  [5 /* RawEcho */]: handleEchoEmbed,
  [6 /* TripleEcho */]: handleEchoEmbed,
  [7 /* Directive */]: handleDirectiveEmbed,
  [10 /* PhpBlock */]: handlePhpBlockEmbed,
  [11 /* PhpTag */]: handlePhpTagEmbed
};
function embed(path, options2) {
  const node = path.node;
  const handler = EMBED_HANDLERS[node.kind];
  if (!handler) return null;
  return handler(path, options2);
}
function getRawElementContent(node) {
  if (!node.hasClosingTag) return "";
  if (node.openTagEndOffset > 0 && node.closingTagStartOffset > node.openTagEndOffset) {
    return node.source.slice(node.openTagEndOffset, node.closingTagStartOffset);
  }
  if (node.children.length === 0) return "";
  const start = node.children[0].start;
  const end = node.children[node.children.length - 1].end;
  return node.source.slice(start, end);
}
function shouldUseInlineIntentElementEmbed(node, options2) {
  if (node.kind !== 1 /* Element */) return false;
  if (!node.hasClosingTag) return false;
  if (options2[INLINE_INTENT_GUARD_FLAG]) {
    return false;
  }
  if (!INLINE_INTENT_EMBED_TAGS.has(node.tagName)) return false;
  if (!shouldPreserveInlineIntentElement(options2, node.tagName, node.namespace)) {
    return false;
  }
  const source = fullText(node).trimEnd();
  if (source.length < getInlineIntentLengthThreshold(options2)) return false;
  if (source.includes("\n") || source.includes("\r")) return false;
  return true;
}
function getInlineIntentLengthThreshold(options2) {
  const candidate = Number(options2.printWidth);
  if (!Number.isFinite(candidate) || candidate <= 0) {
    return INLINE_INTENT_MIN_LENGTH;
  }
  return Math.max(
    INLINE_INTENT_MIN_LENGTH,
    Math.floor(candidate * INLINE_INTENT_TRIGGER_WIDTH_MULTIPLIER)
  );
}
function createInlineIntentSubformatOptions(options2) {
  const base = { ...options2 };
  const printWidth = Number(options2.printWidth);
  const computedPrintWidth = Number.isFinite(printWidth) && printWidth > 0 ? Math.max(200, Math.floor(printWidth * INLINE_INTENT_SUBFORMAT_WIDTH_MULTIPLIER)) : 200;
  return {
    ...base,
    parser: "blade",
    printWidth: computedPrintWidth,
    [INLINE_INTENT_GUARD_FLAG]: true
  };
}

// src/print/index.ts
var { group: group7, hardline: hardline8 } = import_prettier16.doc.builders;
function assertNever(x) {
  throw new Error(`Unhandled node kind in printer: ${String(x)}`);
}
function genericPrint(path, options2, print) {
  const node = path.node;
  switch (node.kind) {
    case "frontMatter":
      return fullText(node);
    case 0 /* Root */: {
      const children = printChildren(path, print, options2);
      if (children.length === 0) return "";
      return shouldPreserveIgnoreRangeEof(node) ? group7(children) : [group7(children), hardline8];
    }
    case 1 /* Element */:
    case 14 /* ConditionalComment */:
      return printElement(path, options2, print);
    case 2 /* Text */:
      return printText(node, options2);
    case 29 /* IgnoreRange */:
      return printIgnoreRange(node);
    case 4 /* Echo */:
    case 5 /* RawEcho */:
    case 6 /* TripleEcho */:
      return [
        printOpeningTagPrefix(node, options2),
        printEcho(node, options2),
        printClosingTagSuffix(node, options2)
      ];
    case 7 /* Directive */:
      return printDirective(node, options2);
    case 8 /* DirectiveBlock */:
      return printDirectiveBlock(node, path, print, options2);
    case 12 /* Comment */:
    case 13 /* BogusComment */:
      return printComment(node, options2);
    case 15 /* BladeComment */:
      return printBladeComment(node);
    case 19 /* Attribute */:
    case 20 /* JsxAttribute */:
      return printAttribute(node, options2);
    case 16 /* Doctype */:
      return printDoctype(node, options2);
    case 9 /* Verbatim */:
    case 10 /* PhpBlock */:
    case 11 /* PhpTag */:
      return printRawBlockNode(node);
    case 17 /* Cdata */:
    case 18 /* Decl */:
    case 28 /* ProcessingInstruction */:
      return [
        printOpeningTagPrefix(node, options2),
        printRawDelimitedNode(node),
        printClosingTagSuffix(node, options2)
      ];
    case 3 /* Fragment */:
      return printChildren(path, print, options2);
    case 22 /* NonOutput */:
      return fullText(node);
    case 21 /* UnpairedClosingTag */:
      return trimTrailingWhitespaceAtEof(node);
    case 23 /* ElementName */:
    case 25 /* AttributeWhitespace */:
    case 26 /* AttributeName */:
    case 27 /* AttributeValue */:
      return fullText(node);
    case 24 /* ClosingElementName */:
      return trimTrailingWhitespaceAtEof(node);
    default:
      return assertNever(node.kind);
  }
}
var bladePrinter = {
  features: {
    experimental_frontMatterSupport: {
      massageAstNode: true,
      embed: true,
      print: true
    }
  },
  preprocess: preprocess2,
  print: genericPrint,
  embed,
  insertPragma,
  getVisitorKeys(_node) {
    return ["children", "attrs"];
  }
};
function printRawBlockNode(node) {
  return trimUnterminatedNodeAtEof(node);
}
function printIgnoreRange(node) {
  return fullText(node);
}
function printRawDelimitedNode(node) {
  return trimUnterminatedNodeAtEof(node);
}
function trimUnterminatedNodeAtEof(node) {
  const text = fullText(node);
  if (!isUnterminatedDelimitedNodeAtEof(node)) {
    return text;
  }
  return text.replace(/\s+$/u, "");
}
function isUnterminatedDelimitedNodeAtEof(node) {
  if (node.end !== node.source.length) {
    return false;
  }
  const closingToken = getClosingTokenForDelimitedNode(node.kind);
  if (closingToken === null) {
    return false;
  }
  const start = node.flat.tokenStart;
  const end = start + node.flat.tokenCount;
  const tokens = node.buildResult.tokens;
  for (let i = start; i < end; i++) {
    if (tokens[i].type === closingToken) {
      return false;
    }
  }
  return true;
}
function getClosingTokenForDelimitedNode(kind) {
  switch (kind) {
    case 9 /* Verbatim */:
      return 28 /* VerbatimEnd */;
    case 10 /* PhpBlock */:
      return 30 /* PhpBlockEnd */;
    case 11 /* PhpTag */:
      return 40 /* PhpTagEnd */;
    case 17 /* Cdata */:
      return 43 /* CdataEnd */;
    case 18 /* Decl */:
      return 45 /* DeclEnd */;
    case 28 /* ProcessingInstruction */:
      return 47 /* PIEnd */;
    default:
      return null;
  }
}
function trimTrailingWhitespaceAtEof(node) {
  const text = fullText(node);
  if (node.end !== node.source.length) {
    return text;
  }
  return text.replace(/\s+$/u, "");
}
function shouldPreserveIgnoreRangeEof(node) {
  if (node.kind !== 0 /* Root */ || node.children.length === 0) {
    return false;
  }
  const lastChild = node.children[node.children.length - 1];
  return lastChild.kind === 29 /* IgnoreRange */ && lastChild.end === lastChild.source.length;
}

// src/index.ts
var languages = [
  {
    name: "blade",
    parsers: ["blade"],
    extensions: [".blade.php"],
    vscodeLanguageIds: ["blade"]
  }
];
var parsers = {
  blade: bladeParser
};
var printers2 = {
  "blade-ast": bladePrinter
};
var options = {
  htmlWhitespaceSensitivity: {
    category: "HTML",
    type: "choice",
    default: "css",
    description: "How to handle whitespaces in HTML.",
    choices: [
      {
        value: "css",
        description: "Respect the default value of CSS display property."
      },
      {
        value: "strict",
        description: "Whitespaces are considered sensitive."
      },
      {
        value: "ignore",
        description: "Whitespaces are considered insensitive."
      }
    ]
  },
  bladePhpFormatting: {
    category: "Blade",
    type: "choice",
    default: "safe",
    description: "Format Blade PHP fragments (directive args, echoes, and PHP blocks/tags).",
    choices: [
      {
        value: "off",
        description: "Disable Blade PHP fragment formatting."
      },
      {
        value: "safe",
        description: "Format known-safe Blade PHP fragments with conservative wrappers."
      },
      {
        value: "aggressive",
        description: "Try additional wrapper strategies before falling back to original text."
      }
    ]
  },
  bladePhpFormattingTargets: {
    category: "Blade",
    type: "string",
    array: true,
    default: [{ value: ["directiveArgs", "echo", "phpBlock", "phpTag"] }],
    description: "PHP embedding targets: echo, directiveArgs, phpBlock, phpTag. Use [] (or CLI value 'none') to disable all targets."
  },
  bladeSyntaxPlugins: {
    category: "Blade",
    type: "string",
    array: true,
    default: [{ value: ["statamic"] }],
    description: "List of Blade syntax plugins, e.g. statamic or log1x/sage-directives."
  },
  bladeDirectiveCase: {
    category: "Blade",
    type: "choice",
    default: "preserve",
    description: "Normalize Blade directive casing.",
    choices: [
      {
        value: "preserve",
        description: "Keep directive case as written."
      },
      {
        value: "canonical",
        description: "Use canonical directive casing for known directives."
      },
      {
        value: "lower",
        description: "Lowercase all directive names."
      }
    ]
  },
  bladeDirectiveCaseMap: {
    category: "Blade",
    type: "string",
    default: "",
    description: 'JSON object mapping directive names to canonical case, e.g. {"disk":"Disk"}.'
  },
  bladeDirectiveArgSpacing: {
    category: "Blade",
    type: "choice",
    default: "space",
    description: "Spacing between directive name and argument list.",
    choices: [
      {
        value: "preserve",
        description: "Preserve original spacing."
      },
      {
        value: "none",
        description: "Print without a space, e.g. @if($x)."
      },
      {
        value: "space",
        description: "Print with one space, e.g. @if ($x)."
      }
    ]
  },
  bladeDirectiveArgSpacingOverrides: {
    category: "Blade",
    type: "string",
    array: true,
    default: [{ value: [...DEFAULT_DIRECTIVE_ARG_SPACING_OVERRIDE_TOKENS] }],
    description: "Directive spacing overrides in directive[=rule] form; bare directive names imply space."
  },
  bladeDirectiveBlockStyle: {
    category: "Blade",
    type: "choice",
    default: "preserve",
    description: "Formatting style for directive blocks.",
    choices: [
      {
        value: "preserve",
        description: "Preserve inline block intent when written on one line."
      },
      {
        value: "inline-if-short",
        description: "Allow short blocks to print inline when possible."
      },
      {
        value: "multiline",
        description: "Always print directive blocks in multiline style."
      }
    ]
  },
  bladeBlankLinesAroundDirectives: {
    category: "Blade",
    type: "choice",
    default: "preserve",
    description: "Blank line policy between directives inside a block.",
    choices: [
      {
        value: "preserve",
        description: "Preserve existing blank line intent."
      },
      {
        value: "always",
        description: "Insert a blank line between directive segments."
      }
    ]
  },
  bladeEchoSpacing: {
    category: "Blade",
    type: "choice",
    default: "preserve",
    description: "Spacing style for Blade echo delimiters.",
    choices: [
      {
        value: "preserve",
        description: "Preserve current echo spacing."
      },
      {
        value: "space",
        description: "Use spaced delimiters, e.g. {{ $x }}."
      },
      {
        value: "tight",
        description: "Use tight delimiters, e.g. {{$x}}."
      }
    ]
  },
  bladeSlotClosingTag: {
    category: "Blade",
    type: "choice",
    default: "canonical",
    description: "How to print Blade slot closing tags for shorthand pairs.",
    choices: [
      {
        value: "canonical",
        description: "Use canonical closing tag names based on the opening slot tag."
      },
      {
        value: "preserve",
        description: "Preserve shorthand closing tags such as </x-slot> when present."
      }
    ]
  },
  bladeInlineIntentElements: {
    category: "Blade",
    type: "string",
    array: true,
    default: [{ value: ["p", "svg", "svg:*"] }],
    description: "Element names that should preserve single-line inline intent and ignore printWidth-driven wrapping when source is inline. Supports namespace wildcards like svg:*."
  },
  bladeComponentPrefixes: {
    category: "Blade",
    type: "string",
    array: true,
    default: [{ value: ["x", "s", "statamic", "flux", "livewire", "native"] }],
    description: "Component prefixes used to detect Blade components for :bound attribute PHP formatting."
  },
  bladeInsertOptionalClosingTags: {
    category: "Blade",
    type: "boolean",
    default: false,
    description: "Insert explicit closing tags when elements are implicitly closed in source (optional-end-tag and parser-recovered missing closing tags)."
  },
  bladeKeepHeadAndBodyAtRoot: {
    category: "Blade",
    type: "boolean",
    default: true,
    description: "Keep root-level <head> and <body> tags flush with <html> for canonical HTML documents."
  }
};
var plugin = { languages, parsers, printers: printers2, options };
var index_default = plugin;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  languages,
  options,
  parsers,
  printers
});
//# sourceMappingURL=index.cjs.map