{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/config.ts","../src/tokenize.ts","../src/utils.ts","../src/walk.ts","../src/parse.ts","../src/stringify.ts"],"sourcesContent":["/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-19 01:09:54\n */\n\nexport { SyntaxKind } from './types';\nexport type { IBaseNode, IAttributeValue, IAttribute, ITag, IText, INode } from './types';\nexport { TokenKind, tokenize } from './tokenize';\nexport type { IToken, TokenizeOptions } from './tokenize';\nexport { parse } from './parse';\nexport type { ParseOptions } from './parse';\nexport { removeAttribute, setAttribute, stringify } from './stringify';\nexport { walk } from './walk';\nexport type { WalkOptions } from './walk';\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-18 15:17:51\n */\n\n/**\n * Node kinds returned by the parser.\n */\nexport enum SyntaxKind {\n  /**\n   * Plain text content.\n   */\n  Text = 'Text',\n  /**\n   * HTML tag node.\n   */\n  Tag = 'Tag',\n}\n\n/**\n * Common source range shared by every AST node.\n */\nexport interface IBaseNode {\n  /**\n   * Zero-based start offset in the source string.\n   */\n  start: number;\n  /**\n   * Zero-based end offset in the source string.\n   */\n  end: number;\n}\n\n/**\n * Text node in the parsed AST.\n */\nexport interface IText extends IBaseNode {\n  /**\n   * Discriminator for text nodes.\n   */\n  type: SyntaxKind.Text;\n  /**\n   * Original text content.\n   */\n  value: string;\n}\n\n/**\n * Parsed attribute value, with quote information preserved.\n */\nexport interface IAttributeValue extends IBaseNode {\n  /**\n   * Attribute value without surrounding quotes.\n   */\n  value: string;\n  /**\n   * Quote character used by the source value, or undefined for unquoted values.\n   */\n  quote: \"'\" | '\"' | undefined;\n}\n\n/**\n * Parsed tag attribute.\n */\nexport interface IAttribute extends IBaseNode {\n  /**\n   * Attribute name token.\n   */\n  name: IText;\n  /**\n   * Attribute value, if the source provided one.\n   */\n  value: IAttributeValue | undefined;\n}\n\n/**\n * Tag node in the parsed AST.\n */\nexport interface ITag extends IBaseNode {\n  /**\n   * Discriminator for tag nodes.\n   */\n  type: SyntaxKind.Tag;\n  /**\n   * Original opening tag text, such as <Div id=\"id\">.\n   */\n  open: IText;\n  /**\n   * Lowercase tag name, such as div.\n   */\n  name: string;\n  /**\n   * Tag name with original casing, such as Div.\n   */\n  rawName: string;\n  /**\n   * Attributes in source order.\n   */\n  attributes: IAttribute[];\n  /**\n   * Attribute lookup map when ParseOptions.setAttributeMap is true.\n   */\n  attributeMap: Record<string, IAttribute> | undefined;\n  /**\n   * Child nodes for paired tags, undefined for self-closed tags, or null when the opening tag is incomplete.\n   */\n  body: Array<ITag | IText> | undefined | null;\n  /**\n   * Original closing tag text, undefined for self-closed tags, or null when missing.\n   */\n  close: IText | undefined | null;\n}\n\n/**\n * Any node returned by parse.\n */\nexport type INode = IText | ITag;\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-19 15:56:14\n */\n\n/**\n * HTML tags that do not require closing tags.\n */\nexport const selfCloseTags = new Set([\n  'area',\n  'base',\n  'basefont',\n  'bgsound',\n  'br',\n  'col',\n  'command',\n  'embed',\n  'frame',\n  'hr',\n  'image',\n  'img',\n  'input',\n  'keygen',\n  'link',\n  'meta',\n  'param',\n  'source',\n  'track',\n  'wbr',\n  '!doctype',\n  '',\n  '!',\n  '!--',\n]);\n\n/**\n * Tags that implicitly close a previous tag of the same name.\n */\nexport const noNestedTags = new Set(['li', 'option', 'select', 'textarea']);\n\n/**\n * Tags whose content is parsed as RCDATA.\n */\nexport const rcDataTags = new Set(['title', 'textarea']);\n\n/**\n * Tags whose content is parsed as RAWTEXT.\n */\nexport const rawTextTags = new Set(['style', 'xmp', 'iframe', 'noembed', 'noframes']);\n\n/**\n * Tags whose content is parsed as script data.\n */\nexport const scriptDataTags = new Set(['script']);\n\n/**\n * Tags whose content is parsed as RAWTEXT when scripting is enabled.\n */\nexport const scriptingRawTextTags = new Set(['noscript']);\n\n/**\n * Tags whose content is parsed as plain text until EOF.\n */\nexport const plainTextTags = new Set(['plaintext']);\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-19 00:54:29\n */\n\nimport {\n  plainTextTags,\n  rawTextTags,\n  rcDataTags,\n  scriptDataTags,\n  scriptingRawTextTags,\n} from './config';\n\nconst enum State {\n  Literal,\n  BeforeOpenTag,\n  OpeningTag,\n  AfterOpenTag,\n  InValueNq,\n  InValueSq,\n  InValueDq,\n  ClosingOpenTag,\n  OpeningSpecial,\n  OpeningDoctype,\n  OpeningNormalComment,\n  InNormalComment,\n  InShortComment,\n  ClosingNormalComment,\n  ClosingTag,\n}\n\nconst enum TextMode {\n  Data,\n  RcData,\n  RawText,\n  ScriptData,\n  PlainText,\n}\n\n/**\n * Token kinds emitted by tokenize.\n */\nexport const enum TokenKind {\n  /**\n   * Raw text outside tag syntax.\n   */\n  Literal,\n  /**\n   * Opening tag name without the leading <.\n   */\n  OpenTag,\n  /**\n   * Opening tag end marker without the trailing >; value is / or empty.\n   */\n  OpenTagEnd,\n  /**\n   * Closing tag name without the leading </ or trailing >.\n   */\n  CloseTag,\n  /**\n   * Whitespace between attributes.\n   */\n  Whitespace,\n  /**\n   * Attribute value assignment marker.\n   */\n  AttrValueEq,\n  /**\n   * Unquoted attribute value.\n   */\n  AttrValueNq,\n  /**\n   * Single-quoted attribute value.\n   */\n  AttrValueSq,\n  /**\n   * Double-quoted attribute value.\n   */\n  AttrValueDq,\n}\n\n/**\n * Token emitted by the HTML tokenizer.\n */\nexport interface IToken {\n  /**\n   * Zero-based start offset in the source string.\n   */\n  start: number;\n  /**\n   * Zero-based end offset in the source string.\n   */\n  end: number;\n  /**\n   * Raw token value after token-specific trimming.\n   */\n  value: string;\n  /**\n   * Token category.\n   */\n  type: TokenKind;\n}\n\n/**\n * Options that control tokenization.\n */\nexport interface TokenizeOptions {\n  /**\n   * Treat noscript content as RAWTEXT when true, matching HTML parsers with scripting enabled.\n   */\n  scriptingEnabled?: boolean;\n}\n\ninterface ICodePoints {\n  lower: number[];\n  upper: number[];\n  length: number;\n}\n\nlet state: State;\nlet buffer: string;\nlet bufSize: number;\nlet sectionStart: number;\nlet index: number;\nlet tokens: IToken[];\nlet char: number;\nlet offset: number;\nlet textMode: TextMode;\nlet textEndTag: ICodePoints | undefined;\nlet pendingTextMode: TextMode;\nlet pendingTextTag: string;\nlet tokenizeOptions: Required<TokenizeOptions>;\n\nfunction makeCodePoints(input: string): ICodePoints {\n  return {\n    lower: input\n      .toLowerCase()\n      .split('')\n      .map((c) => c.charCodeAt(0)),\n    upper: input\n      .toUpperCase()\n      .split('')\n      .map((c) => c.charCodeAt(0)),\n    length: input.length,\n  };\n}\n\nconst doctype = makeCodePoints('!doctype');\n\nconst enum Chars {\n  _S = 32, // ' '\n  _N = 10, // \\n\n  _T = 9, // \\t\n  _R = 13, // \\r\n  _F = 12, // \\f\n  Lt = 60, // <\n  Ep = 33, // !\n  Cl = 45, // -\n  Sl = 47, // /\n  Gt = 62, // >\n  Qm = 63, // ?\n  La = 97, // a\n  Lz = 122, // z\n  Ua = 65, // A\n  Uz = 90, // Z\n  Eq = 61, // =\n  Sq = 39, // '\n  Dq = 34, // \"\n  Ld = 100, // d\n  Ud = 68, //D\n}\n\nfunction isWhiteSpace() {\n  return (\n    char === Chars._S ||\n    char === Chars._N ||\n    char === Chars._T ||\n    char === Chars._T ||\n    char === Chars._R ||\n    char === Chars._F\n  );\n}\n\nfunction init(input: string, options: Required<TokenizeOptions>) {\n  state = State.Literal;\n  buffer = input;\n  bufSize = input.length;\n  sectionStart = 0;\n  index = 0;\n  tokens = [];\n  offset = 0;\n  textMode = TextMode.Data;\n  textEndTag = void 0;\n  pendingTextMode = TextMode.Data;\n  pendingTextTag = '';\n  tokenizeOptions = options;\n}\n\nfunction getTextMode(tagName: string): TextMode {\n  if (rcDataTags.has(tagName)) {\n    return TextMode.RcData;\n  }\n  if (rawTextTags.has(tagName)) {\n    return TextMode.RawText;\n  }\n  if (scriptDataTags.has(tagName)) {\n    return TextMode.ScriptData;\n  }\n  if (plainTextTags.has(tagName)) {\n    return TextMode.PlainText;\n  }\n  if (tokenizeOptions.scriptingEnabled && scriptingRawTextTags.has(tagName)) {\n    return TextMode.RawText;\n  }\n  return TextMode.Data;\n}\n\nfunction setPendingTextMode(tagName: string) {\n  pendingTextTag = tagName;\n  pendingTextMode = getTextMode(tagName);\n}\n\nfunction activatePendingTextMode(openTagEnd: string) {\n  if (openTagEnd !== '/' && pendingTextMode !== TextMode.Data) {\n    textMode = pendingTextMode;\n    textEndTag = makeCodePoints(pendingTextTag);\n    if (pendingTextTag === 'textarea' && buffer.charCodeAt(sectionStart) === Chars._N) {\n      sectionStart++;\n      index++;\n    }\n  }\n  pendingTextMode = TextMode.Data;\n  pendingTextTag = '';\n}\n\nfunction resetTextMode() {\n  textMode = TextMode.Data;\n  textEndTag = void 0;\n}\n\nfunction resetTextClosingTag() {\n  sectionStart -= 2;\n  state = State.Literal;\n}\n\n/**\n * Convert an HTML string into a flat token stream.\n */\nexport function tokenize(input: string, options: TokenizeOptions = {}): IToken[] {\n  init(input, {\n    scriptingEnabled: options.scriptingEnabled !== false,\n  });\n  while (index < bufSize) {\n    char = buffer.charCodeAt(index);\n    switch (state) {\n      case State.Literal:\n        parseLiteral();\n        break;\n      case State.BeforeOpenTag:\n        parseBeforeOpenTag();\n        break;\n      case State.OpeningTag:\n        parseOpeningTag();\n        break;\n      case State.AfterOpenTag:\n        parseAfterOpenTag();\n        break;\n      case State.InValueNq:\n        parseInValueNq();\n        break;\n      case State.InValueSq:\n        parseInValueSq();\n        break;\n      case State.InValueDq:\n        parseInValueDq();\n        break;\n      case State.ClosingOpenTag:\n        parseClosingOpenTag();\n        break;\n      case State.OpeningSpecial:\n        parseOpeningSpecial();\n        break;\n      case State.OpeningDoctype:\n        parseOpeningDoctype();\n        break;\n      case State.OpeningNormalComment:\n        parseOpeningNormalComment();\n        break;\n      case State.InNormalComment:\n        parseNormalComment();\n        break;\n      case State.InShortComment:\n        parseShortComment();\n        break;\n      case State.ClosingNormalComment:\n        parseClosingNormalComment();\n        break;\n      case State.ClosingTag:\n        parseClosingTag();\n        break;\n      default:\n        unexpected();\n    }\n    index++;\n  }\n  switch (state) {\n    case State.Literal:\n    case State.BeforeOpenTag:\n    case State.InValueNq:\n    case State.InValueSq:\n    case State.InValueDq:\n    case State.ClosingOpenTag:\n    case State.InNormalComment:\n    case State.InShortComment:\n    case State.ClosingNormalComment:\n      emitToken(TokenKind.Literal);\n      break;\n    case State.OpeningTag:\n      emitToken(TokenKind.OpenTag);\n      break;\n    case State.AfterOpenTag:\n      break;\n    case State.OpeningSpecial:\n      emitToken(TokenKind.OpenTag, State.InShortComment);\n      break;\n    case State.OpeningDoctype:\n      if (index - sectionStart === doctype.length) {\n        emitToken(TokenKind.OpenTag);\n      } else {\n        emitToken(TokenKind.OpenTag, void 0, sectionStart + 1);\n        emitToken(TokenKind.Literal);\n      }\n      break;\n    case State.OpeningNormalComment:\n      if (index - sectionStart === 2) {\n        emitToken(TokenKind.OpenTag);\n      } else {\n        emitToken(TokenKind.OpenTag, void 0, sectionStart + 1);\n        emitToken(TokenKind.Literal);\n      }\n      break;\n    case State.ClosingTag:\n      emitToken(TokenKind.CloseTag);\n      break;\n    default:\n      break;\n  }\n  const _tokens = tokens;\n  init('', tokenizeOptions);\n  return _tokens;\n}\n\nfunction emitToken(kind: TokenKind, newState = state, end = index) {\n  let value = buffer.substring(sectionStart, end);\n  if (kind === TokenKind.OpenTag || kind === TokenKind.CloseTag) {\n    value = value.toLowerCase();\n  }\n  if (kind === TokenKind.OpenTag) {\n    setPendingTextMode(value);\n  }\n  if (kind === TokenKind.CloseTag) {\n    resetTextMode();\n  }\n  if (!((kind === TokenKind.Literal || kind === TokenKind.Whitespace) && end === sectionStart)) {\n    // empty literal should be ignored\n    tokens.push({ type: kind, start: sectionStart, end, value });\n  }\n  if (kind === TokenKind.OpenTagEnd || kind === TokenKind.CloseTag) {\n    sectionStart = end + 1;\n    state = State.Literal;\n    if (kind === TokenKind.OpenTagEnd) {\n      activatePendingTextMode(value);\n    }\n  } else {\n    sectionStart = end;\n    state = newState;\n  }\n}\n\nfunction parseLiteral() {\n  if (textMode === TextMode.PlainText) {\n    return;\n  }\n  if (char === Chars.Lt) {\n    // <\n    emitToken(TokenKind.Literal, State.BeforeOpenTag);\n  }\n}\n\nfunction parseBeforeOpenTag() {\n  if (textMode !== TextMode.Data) {\n    if (char === Chars.Sl) {\n      state = State.ClosingTag;\n      sectionStart = index + 1;\n    } else {\n      state = State.Literal;\n    }\n    return;\n  }\n  if ((char >= Chars.La && char <= Chars.Lz) || (char >= Chars.Ua && char <= Chars.Uz)) {\n    // <d\n    state = State.OpeningTag;\n    sectionStart = index;\n  } else if (char === Chars.Sl) {\n    // </\n    state = State.ClosingTag;\n    sectionStart = index + 1;\n  } else if (char === Chars.Lt) {\n    // <<\n    emitToken(TokenKind.Literal);\n  } else if (char === Chars.Ep) {\n    // <!\n    state = State.OpeningSpecial;\n    sectionStart = index;\n  } else if (char === Chars.Qm) {\n    // <?\n    // treat as short comment\n    sectionStart = index;\n    emitToken(TokenKind.OpenTag, State.InShortComment);\n  } else {\n    // <>\n    // any other chars covert to normal state\n    state = State.Literal;\n  }\n}\n\nfunction parseOpeningTag() {\n  if (isWhiteSpace()) {\n    // <div ...\n    emitToken(TokenKind.OpenTag, State.AfterOpenTag);\n  } else if (char === Chars.Gt) {\n    // <div>\n    emitToken(TokenKind.OpenTag);\n    emitToken(TokenKind.OpenTagEnd);\n  } else if (char === Chars.Sl) {\n    // <div/\n    emitToken(TokenKind.OpenTag, State.ClosingOpenTag);\n  }\n}\n\nfunction parseAfterOpenTag() {\n  if (char === Chars.Gt) {\n    // <div >\n    emitToken(TokenKind.Whitespace);\n    emitToken(TokenKind.OpenTagEnd);\n  } else if (char === Chars.Sl) {\n    // <div /\n    emitToken(TokenKind.Whitespace, State.ClosingOpenTag);\n  } else if (char === Chars.Eq) {\n    // <div ...=...\n    emitToken(TokenKind.Whitespace);\n    emitToken(TokenKind.AttrValueEq, void 0, index + 1);\n  } else if (char === Chars.Sq) {\n    // <div ...'...\n    emitToken(TokenKind.Whitespace, State.InValueSq);\n  } else if (char === Chars.Dq) {\n    // <div ...\"...\n    emitToken(TokenKind.Whitespace, State.InValueDq);\n  } else if (!isWhiteSpace()) {\n    // <div ...name...\n    emitToken(TokenKind.Whitespace, State.InValueNq);\n  }\n}\n\nfunction parseInValueNq() {\n  if (char === Chars.Gt) {\n    // <div xxx>\n    emitToken(TokenKind.AttrValueNq);\n    emitToken(TokenKind.OpenTagEnd);\n  } else if (char === Chars.Sl) {\n    // <div xxx/\n    emitToken(TokenKind.AttrValueNq, State.ClosingOpenTag);\n  } else if (char === Chars.Eq) {\n    // <div xxx=\n    emitToken(TokenKind.AttrValueNq);\n    emitToken(TokenKind.AttrValueEq, State.AfterOpenTag, index + 1);\n  } else if (isWhiteSpace()) {\n    // <div xxx ...\n    emitToken(TokenKind.AttrValueNq, State.AfterOpenTag);\n  }\n}\n\nfunction parseInValueSq() {\n  if (char === Chars.Sq) {\n    // <div 'xxx'\n    emitToken(TokenKind.AttrValueSq, State.AfterOpenTag, index + 1);\n  }\n}\n\nfunction parseInValueDq() {\n  if (char === Chars.Dq) {\n    // <div \"xxx\", problem same to Sq\n    emitToken(TokenKind.AttrValueDq, State.AfterOpenTag, index + 1);\n  }\n}\n\nfunction parseClosingOpenTag() {\n  if (char === Chars.Gt) {\n    // <div />\n    emitToken(TokenKind.OpenTagEnd);\n  } else {\n    // <div /...>\n    emitToken(TokenKind.AttrValueNq, State.AfterOpenTag);\n    parseAfterOpenTag();\n  }\n}\n\nfunction parseOpeningSpecial() {\n  switch (char) {\n    case Chars.Cl: // <!-\n      state = State.OpeningNormalComment;\n      break;\n    case Chars.Ld: // <!d\n    case Chars.Ud: // <!D\n      state = State.OpeningDoctype;\n      break;\n    default:\n      emitToken(TokenKind.OpenTag, State.InShortComment);\n      break;\n  }\n}\n\nfunction parseOpeningDoctype() {\n  offset = index - sectionStart;\n  if (offset === doctype.length) {\n    // <!d, <!d , start: 0, index: 2\n    if (isWhiteSpace()) {\n      emitToken(TokenKind.OpenTag, State.AfterOpenTag);\n    } else {\n      unexpected();\n    }\n  } else if (char === Chars.Gt) {\n    // <!DOCT>\n    emitToken(TokenKind.OpenTag, void 0, sectionStart + 1);\n    emitToken(TokenKind.Literal);\n    emitToken(TokenKind.OpenTagEnd);\n  } else if (doctype.lower[offset] !== char && doctype.upper[offset] !== char) {\n    // <!DOCX...\n    emitToken(TokenKind.OpenTag, State.InShortComment, sectionStart + 1);\n  }\n}\n\nfunction parseOpeningNormalComment() {\n  if (char === Chars.Cl) {\n    // <!--\n    emitToken(TokenKind.OpenTag, State.InNormalComment, index + 1);\n  } else {\n    emitToken(TokenKind.OpenTag, State.InShortComment, sectionStart + 1);\n  }\n}\n\nfunction parseNormalComment() {\n  if (char === Chars.Cl) {\n    // <!-- ... -\n    emitToken(TokenKind.Literal, State.ClosingNormalComment);\n  }\n}\n\nfunction parseShortComment() {\n  if (char === Chars.Gt) {\n    // <! ... >\n    emitToken(TokenKind.Literal);\n    emitToken(TokenKind.OpenTagEnd);\n  }\n}\n\nfunction parseClosingNormalComment() {\n  offset = index - sectionStart;\n  if (offset === 2) {\n    if (char === Chars.Gt) {\n      // <!-- xxx -->\n      emitToken(TokenKind.OpenTagEnd);\n    } else if (char === Chars.Cl) {\n      // <!-- xxx ---\n      emitToken(TokenKind.Literal, void 0, sectionStart + 1);\n    } else {\n      // <!-- xxx --x\n      state = State.InNormalComment;\n    }\n  } else if (char !== Chars.Cl) {\n    // <!-- xxx - ...\n    state = State.InNormalComment;\n  }\n}\n\nfunction parseClosingTag() {\n  offset = index - sectionStart;\n  if (textMode !== TextMode.Data) {\n    const endTag = textEndTag;\n    if (!endTag) {\n      unexpected();\n    }\n    if (char === Chars.Lt) {\n      resetTextClosingTag();\n      emitToken(TokenKind.Literal, State.BeforeOpenTag);\n    } else if (offset < endTag.length) {\n      if (endTag.lower[offset] !== char && endTag.upper[offset] !== char) {\n        resetTextClosingTag();\n      }\n    } else if (char === Chars.Gt) {\n      emitToken(TokenKind.CloseTag);\n    } else if (!isWhiteSpace()) {\n      resetTextClosingTag();\n    }\n  } else if (char === Chars.Gt) {\n    // </ xxx >\n    emitToken(TokenKind.CloseTag);\n  }\n}\n\nfunction unexpected(): never {\n  throw new SyntaxError(\n    `Unexpected token \"${buffer.charAt(index)}\" at ${index} when parse ${state}`,\n  );\n}\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-20 21:41:39\n */\n\n/**\n * Build cumulative line ending offsets for source position lookup.\n */\nexport function getLineRanges(input: string) {\n  return input.split('\\n').reduce(\n    (arr, line) => {\n      arr.push(line.length + 1 + arr[arr.length - 1]);\n      return arr;\n    },\n    [0],\n  );\n}\n\n/**\n * Convert a source offset to one-based line and column coordinates.\n */\nexport function getPosition(ranges: number[], offset: number): [number, number] {\n  let line = NaN;\n  let column = NaN;\n  for (let i = 1; i < ranges.length; i++) {\n    if (ranges[i] > offset) {\n      line = i;\n      column = offset - ranges[i - 1] + 1;\n      break;\n    }\n  }\n  return [line, column];\n}\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-19 00:54:46\n */\n\nimport { SyntaxKind } from './types';\nimport type { INode } from './types';\n\n/**\n * Visitor callbacks used while walking an AST.\n */\nexport interface WalkOptions {\n  /**\n   * Called before visiting a node's children.\n   */\n  enter?(node: INode, parent: INode | undefined, index: number): void;\n  /**\n   * Called after visiting a node's children.\n   */\n  leave?(node: INode, parent: INode | undefined, index: number): void;\n}\n\nfunction visit(node: INode, parent: INode | undefined, index: number, options: WalkOptions) {\n  options.enter && options.enter(node, parent, index);\n  if (node.type === SyntaxKind.Tag && Array.isArray(node.body)) {\n    for (let i = 0; i < node.body.length; i++) {\n      visit(node.body[i], node, i, options);\n    }\n  }\n  options.leave && options.leave(node, parent, index);\n}\n\n/**\n * Traverse an AST depth-first.\n */\nexport function walk(ast: INode[], options: WalkOptions) {\n  for (let i = 0; i < ast.length; i++) {\n    visit(ast[i], void 0, i, options);\n  }\n}\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2017-08-19 00:54:46\n */\n\nimport { noNestedTags, selfCloseTags } from './config';\nimport { tokenize, TokenKind } from './tokenize';\nimport type { IToken } from './tokenize';\nimport { SyntaxKind } from './types';\nimport type { IAttribute, IAttributeValue, INode, ITag, IText } from './types';\nimport { getLineRanges, getPosition } from './utils';\nimport { walk } from './walk';\n\ninterface IContext {\n  parent: IContext | undefined;\n  tag: ITag;\n}\n\n/**\n * Options that control AST construction.\n */\nexport interface ParseOptions {\n  /**\n   * Populate each tag node with an attribute lookup map.\n   */\n  setAttributeMap?: boolean;\n  /**\n   * Treat noscript content as RAWTEXT when true, matching HTML parsers with scripting enabled.\n   */\n  scriptingEnabled?: boolean;\n}\n\nlet index: number;\nlet count: number;\nlet tokens: IToken[];\nlet tagChain: IContext | undefined;\nlet nodes: INode[];\nlet token: IToken;\nlet node: IText | undefined;\nlet buffer: string;\nlet lines: number[] | undefined;\nlet parseOptions: ParseOptions | undefined;\n\nfunction init(input?: string, options?: ParseOptions) {\n  if (input === void 0) {\n    count = 0;\n    tokens.length = 0;\n    buffer = '';\n  } else {\n    tokens = tokenize(input, {\n      scriptingEnabled: options?.scriptingEnabled,\n    });\n    count = tokens.length;\n    buffer = input;\n  }\n  index = 0;\n  tagChain = void 0;\n  nodes = [];\n  token = void 0 as any;\n  node = void 0;\n  lines = void 0;\n  parseOptions = options;\n}\n\nfunction pushNode(_node: ITag | IText) {\n  if (!tagChain) {\n    nodes.push(_node);\n  } else if (\n    _node.type === SyntaxKind.Tag &&\n    _node.name === tagChain.tag.name &&\n    noNestedTags.has(_node.name)\n  ) {\n    tagChain = tagChain.parent;\n    pushNode(_node);\n  } else if (tagChain.tag.body) {\n    tagChain.tag.end = _node.end;\n    tagChain.tag.body.push(_node);\n  }\n}\n\nfunction pushTagChain(tag: ITag) {\n  tagChain = { parent: tagChain, tag: tag };\n  node = void 0;\n}\n\nfunction createLiteral(start = token.start, end = token.end, value = token.value): IText {\n  return { start, end, value, type: SyntaxKind.Text };\n}\n\nfunction createTag(): ITag {\n  return {\n    start: token.start - 1, // include <\n    end: token.end,\n    type: SyntaxKind.Tag,\n    open: createLiteral(token.start - 1), // not finished\n    name: token.value,\n    rawName: buffer.substring(token.start, token.end),\n    attributes: [],\n    attributeMap: void 0,\n    body: null,\n    close: null,\n  };\n}\n\nfunction createAttribute(): IAttribute {\n  return {\n    start: token.start,\n    end: token.end,\n    name: createLiteral(),\n    value: void 0,\n  };\n}\n\nfunction createAttributeValue(): IAttributeValue {\n  return {\n    start: token.start,\n    end: token.end,\n    value:\n      token.type === TokenKind.AttrValueNq\n        ? token.value\n        : token.value.substr(1, token.value.length - 2),\n    quote:\n      token.type === TokenKind.AttrValueNq\n        ? void 0\n        : token.type === TokenKind.AttrValueSq\n          ? \"'\"\n          : '\"',\n  };\n}\n\nfunction appendLiteral(_node: IText | IAttributeValue = node as IText) {\n  _node.value += token.value;\n  _node.end = token.end;\n}\n\nfunction unexpected() {\n  if (lines === void 0) {\n    lines = getLineRanges(buffer);\n  }\n  const [line, column] = getPosition(lines, token.start);\n  throw new Error(\n    `Unexpected token \"${token.value}(${token.type})\" at [${line},${column}]` +\n      (tagChain ? ` when parsing tag: ${JSON.stringify(tagChain.tag.name)}.` : ''),\n  );\n}\n\nfunction buildAttributeMap(tag: ITag) {\n  tag.attributeMap = {};\n  for (const attr of tag.attributes) {\n    tag.attributeMap[attr.name.value] = attr;\n  }\n}\n\nconst enum OpenTagState {\n  BeforeAttr,\n  InName,\n  AfterName,\n  AfterEqual,\n  InValue,\n}\n\nfunction parseOpenTag() {\n  let state = OpenTagState.BeforeAttr;\n\n  let attr: IAttribute = void 0 as any;\n\n  const tag = createTag();\n  pushNode(tag);\n  if (tag.name === '' || tag.name === '!' || tag.name === '!--') {\n    tag.open.value = '<' + tag.open.value;\n    if (index === count) {\n      return;\n    } else {\n      token = tokens[++index];\n      if (token.type !== TokenKind.OpenTagEnd) {\n        node = createLiteral();\n        tag.body = [node];\n        while (++index < count) {\n          token = tokens[index];\n          if (token.type === TokenKind.OpenTagEnd) {\n            node = void 0;\n            break;\n          }\n          appendLiteral();\n        }\n      }\n      tag.close = createLiteral(token.start, token.end + 1, `${token.value}>`);\n      tag.end = tag.close.end;\n    }\n    return;\n  }\n  while (++index < count) {\n    token = tokens[index];\n    if (token.type === TokenKind.OpenTagEnd) {\n      tag.end = tag.open.end = token.end + 1;\n      tag.open.value = buffer.substring(tag.open.start, tag.open.end);\n      if (token.value === '' && !selfCloseTags.has(tag.name)) {\n        tag.body = [];\n        pushTagChain(tag);\n      } else {\n        tag.body = void 0;\n      }\n      break;\n    } else if (state === OpenTagState.BeforeAttr) {\n      if (token.type !== TokenKind.Whitespace) {\n        attr = createAttribute();\n        state = OpenTagState.InName;\n        tag.attributes.push(attr);\n      }\n    } else if (state === OpenTagState.InName) {\n      if (token.type === TokenKind.Whitespace) {\n        state = OpenTagState.AfterName;\n      } else if (token.type === TokenKind.AttrValueEq) {\n        state = OpenTagState.AfterEqual;\n      } else {\n        appendLiteral(attr.name);\n      }\n    } else if (state === OpenTagState.AfterName) {\n      if (token.type !== TokenKind.Whitespace) {\n        if (token.type === TokenKind.AttrValueEq) {\n          state = OpenTagState.AfterEqual;\n        } else {\n          attr = createAttribute();\n          state = OpenTagState.InName;\n          tag.attributes.push(attr);\n        }\n      }\n    } else if (state === OpenTagState.AfterEqual) {\n      if (token.type !== TokenKind.Whitespace) {\n        attr.value = createAttributeValue();\n        if (token.type === TokenKind.AttrValueNq) {\n          state = OpenTagState.InValue;\n        } else {\n          attr.end = attr.value.end;\n          state = OpenTagState.BeforeAttr;\n        }\n      }\n    } else {\n      if (token.type === TokenKind.Whitespace) {\n        attr.end = attr.value!.end;\n        state = OpenTagState.BeforeAttr;\n      } else {\n        appendLiteral(attr.value);\n      }\n    }\n  }\n}\n\nfunction parseCloseTag() {\n  let _context = tagChain;\n  while (true) {\n    if (!_context || token.value.trim() === _context.tag.name) {\n      break;\n    }\n    _context = _context.parent;\n  }\n  if (!_context) {\n    return;\n  }\n  _context.tag.close = createLiteral(\n    token.start - 2,\n    token.end + 1,\n    buffer.substring(token.start - 2, token.end + 1),\n  );\n  _context.tag.end = _context.tag.close.end;\n  _context = _context.parent;\n  tagChain = _context;\n}\n\n/**\n * Parse an HTML string into an AST.\n */\nexport function parse(input: string, options?: ParseOptions): INode[] {\n  init(input, {\n    setAttributeMap: false,\n    scriptingEnabled: true,\n    ...options,\n  });\n  while (index < count) {\n    token = tokens[index];\n    switch (token.type) {\n      case TokenKind.Literal:\n        if (!node) {\n          node = createLiteral();\n          pushNode(node);\n        } else {\n          appendLiteral(node);\n        }\n        break;\n      case TokenKind.OpenTag:\n        node = void 0;\n        parseOpenTag();\n        break;\n      case TokenKind.CloseTag:\n        node = void 0;\n        parseCloseTag();\n        break;\n      default:\n        unexpected();\n        break;\n    }\n    index++;\n  }\n  const _nodes = nodes;\n  if (parseOptions?.setAttributeMap) {\n    walk(_nodes, {\n      enter(node: IText | ITag): void {\n        if (node.type === SyntaxKind.Tag) {\n          buildAttributeMap(node);\n        }\n      },\n    });\n  }\n  init();\n  return _nodes;\n}\n","/*\n * @author acrazing joking.young@gmail.com\n * @since 2026-05-15 15:16:00\n */\n\nimport { SyntaxKind } from './types';\nimport type { IAttribute, INode, ITag } from './types';\n\n/**\n * Set a tag attribute and keep attributeMap in sync when it exists.\n */\nexport function setAttribute(tag: ITag, name: string, value?: string): void {\n  const attr = findAttribute(tag, name);\n  if (attr) {\n    attr.name.value = name;\n    attr.value =\n      value === void 0\n        ? void 0\n        : {\n            start: attr.value?.start ?? attr.end,\n            end: attr.value?.end ?? attr.end,\n            value,\n            quote: attr.value?.quote ?? '\"',\n          };\n    attr.end = attr.value?.end ?? attr.name.end;\n  } else {\n    tag.attributes.push(createAttribute(name, value));\n  }\n  if (tag.attributeMap) {\n    tag.attributeMap[name] = findAttribute(tag, name) as IAttribute;\n  }\n}\n\n/**\n * Remove all tag attributes with the provided name and keep attributeMap in sync when it exists.\n */\nexport function removeAttribute(tag: ITag, name: string): void {\n  for (let index = tag.attributes.length - 1; index >= 0; index--) {\n    if (tag.attributes[index].name.value === name) {\n      tag.attributes.splice(index, 1);\n    }\n  }\n  if (tag.attributeMap) {\n    delete tag.attributeMap[name];\n  }\n}\n\n/**\n * Serialize parsed AST nodes back to HTML.\n */\nexport function stringify(ast: INode | INode[]): string {\n  if (Array.isArray(ast)) {\n    return ast.map(stringifyNode).join('');\n  }\n  return stringifyNode(ast);\n}\n\nfunction stringifyNode(node: INode): string {\n  if (node.type === SyntaxKind.Text) {\n    return node.value;\n  }\n  return stringifyTag(node);\n}\n\nfunction stringifyTag(tag: ITag): string {\n  if (tag.body === null) {\n    return stringifyOpenTag(tag, false);\n  }\n  if (tag.name === '!--' || tag.name === '!' || tag.name === '') {\n    return stringifySpecialTag(tag);\n  }\n\n  const open = stringifyOpenTag(tag);\n  if (tag.body === void 0) {\n    return open;\n  }\n  const close = tag.close === null ? '' : `</${tag.rawName}>`;\n  return open + stringify(tag.body) + close;\n}\n\nfunction stringifySpecialTag(tag: ITag): string {\n  const body = tag.body ? stringify(tag.body) : '';\n  if (tag.name === '!--') {\n    return `<!--${body}${tag.close === null ? '' : '-->'}`;\n  }\n  if (tag.name === '!') {\n    return `<!${body}${tag.close === null ? '' : '>'}`;\n  }\n  return `<${body}${tag.close === null ? '' : '>'}`;\n}\n\nfunction stringifyOpenTag(tag: ITag, close = true): string {\n  const attrs = tag.attributes.map(stringifyAttribute).join(' ');\n  return `<${tag.rawName}${attrs ? ` ${attrs}` : ''}${close ? '>' : ''}`;\n}\n\nfunction stringifyAttribute(attr: IAttribute): string {\n  if (!attr.value) {\n    return attr.name.value;\n  }\n  if (attr.value.quote === void 0) {\n    return `${attr.name.value}=${attr.value.value}`;\n  }\n  return `${attr.name.value}=${attr.value.quote}${attr.value.value}${attr.value.quote}`;\n}\n\nfunction findAttribute(tag: ITag, name: string): IAttribute | undefined {\n  return tag.attributes.find((attr) => attr.name.value === name);\n}\n\nfunction createAttribute(name: string, value?: string): IAttribute {\n  return {\n    start: 0,\n    end: 0,\n    name: {\n      start: 0,\n      end: 0,\n      type: SyntaxKind.Text,\n      value: name,\n    },\n    value:\n      value === void 0\n        ? void 0\n        : {\n            start: 0,\n            end: 0,\n            value,\n            quote: '\"',\n          },\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACQO,IAAK,aAAL,kBAAKA,gBAAL;AAIL,EAAAA,YAAA,UAAO;AAIP,EAAAA,YAAA,SAAM;AARI,SAAAA;AAAA,GAAA;;;ACAL,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAKM,IAAM,eAAe,oBAAI,IAAI,CAAC,MAAM,UAAU,UAAU,UAAU,CAAC;AAKnE,IAAM,aAAa,oBAAI,IAAI,CAAC,SAAS,UAAU,CAAC;AAKhD,IAAM,cAAc,oBAAI,IAAI,CAAC,SAAS,OAAO,UAAU,WAAW,UAAU,CAAC;AAK7E,IAAM,iBAAiB,oBAAI,IAAI,CAAC,QAAQ,CAAC;AAKzC,IAAM,uBAAuB,oBAAI,IAAI,CAAC,UAAU,CAAC;AAKjD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,WAAW,CAAC;;;ACrB3C,IAAW,YAAX,kBAAWC,eAAX;AAIL,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AAIA,EAAAA,sBAAA;AApCgB,SAAAA;AAAA,GAAA;AA6ElB,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEJ,SAAS,eAAe,OAA4B;AAClD,SAAO;AAAA,IACL,OAAO,MACJ,YAAY,EACZ,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAAA,IAC7B,OAAO,MACJ,YAAY,EACZ,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAAA,IAC7B,QAAQ,MAAM;AAAA,EAChB;AACF;AAEA,IAAM,UAAU,eAAe,UAAU;AAyBzC,SAAS,eAAe;AACtB,SACE,SAAS,eACT,SAAS,eACT,SAAS,cACT,SAAS,cACT,SAAS,eACT,SAAS;AAEb;AAEA,SAAS,KAAK,OAAe,SAAoC;AAC/D,UAAQ;AACR,WAAS;AACT,YAAU,MAAM;AAChB,iBAAe;AACf,UAAQ;AACR,WAAS,CAAC;AACV,WAAS;AACT,aAAW;AACX,eAAa;AACb,oBAAkB;AAClB,mBAAiB;AACjB,oBAAkB;AACpB;AAEA,SAAS,YAAY,SAA2B;AAC9C,MAAI,WAAW,IAAI,OAAO,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,YAAY,IAAI,OAAO,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,eAAe,IAAI,OAAO,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,cAAc,IAAI,OAAO,GAAG;AAC9B,WAAO;AAAA,EACT;AACA,MAAI,gBAAgB,oBAAoB,qBAAqB,IAAI,OAAO,GAAG;AACzE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,SAAiB;AAC3C,mBAAiB;AACjB,oBAAkB,YAAY,OAAO;AACvC;AAEA,SAAS,wBAAwB,YAAoB;AACnD,MAAI,eAAe,OAAO,oBAAoB,cAAe;AAC3D,eAAW;AACX,iBAAa,eAAe,cAAc;AAC1C,QAAI,mBAAmB,cAAc,OAAO,WAAW,YAAY,MAAM,aAAU;AACjF;AACA;AAAA,IACF;AAAA,EACF;AACA,oBAAkB;AAClB,mBAAiB;AACnB;AAEA,SAAS,gBAAgB;AACvB,aAAW;AACX,eAAa;AACf;AAEA,SAAS,sBAAsB;AAC7B,kBAAgB;AAChB,UAAQ;AACV;AAKO,SAAS,SAAS,OAAe,UAA2B,CAAC,GAAa;AAC/E,OAAK,OAAO;AAAA,IACV,kBAAkB,QAAQ,qBAAqB;AAAA,EACjD,CAAC;AACD,SAAO,QAAQ,SAAS;AACtB,WAAO,OAAO,WAAW,KAAK;AAC9B,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,qBAAa;AACb;AAAA,MACF,KAAK;AACH,2BAAmB;AACnB;AAAA,MACF,KAAK;AACH,wBAAgB;AAChB;AAAA,MACF,KAAK;AACH,0BAAkB;AAClB;AAAA,MACF,KAAK;AACH,uBAAe;AACf;AAAA,MACF,KAAK;AACH,uBAAe;AACf;AAAA,MACF,KAAK;AACH,uBAAe;AACf;AAAA,MACF,KAAK;AACH,4BAAoB;AACpB;AAAA,MACF,KAAK;AACH,4BAAoB;AACpB;AAAA,MACF,KAAK;AACH,4BAAoB;AACpB;AAAA,MACF,KAAK;AACH,kCAA0B;AAC1B;AAAA,MACF,KAAK;AACH,2BAAmB;AACnB;AAAA,MACF,KAAK;AACH,0BAAkB;AAClB;AAAA,MACF,KAAK;AACH,kCAA0B;AAC1B;AAAA,MACF,KAAK;AACH,wBAAgB;AAChB;AAAA,MACF;AACE,mBAAW;AAAA,IACf;AACA;AAAA,EACF;AACA,UAAQ,OAAO;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,gBAAU,eAAiB;AAC3B;AAAA,IACF,KAAK;AACH,gBAAU,eAAiB;AAC3B;AAAA,IACF,KAAK;AACH;AAAA,IACF,KAAK;AACH,gBAAU,iBAAmB,uBAAoB;AACjD;AAAA,IACF,KAAK;AACH,UAAI,QAAQ,iBAAiB,QAAQ,QAAQ;AAC3C,kBAAU,eAAiB;AAAA,MAC7B,OAAO;AACL,kBAAU,iBAAmB,QAAQ,eAAe,CAAC;AACrD,kBAAU,eAAiB;AAAA,MAC7B;AACA;AAAA,IACF,KAAK;AACH,UAAI,QAAQ,iBAAiB,GAAG;AAC9B,kBAAU,eAAiB;AAAA,MAC7B,OAAO;AACL,kBAAU,iBAAmB,QAAQ,eAAe,CAAC;AACrD,kBAAU,eAAiB;AAAA,MAC7B;AACA;AAAA,IACF,KAAK;AACH,gBAAU,gBAAkB;AAC5B;AAAA,IACF;AACE;AAAA,EACJ;AACA,QAAM,UAAU;AAChB,OAAK,IAAI,eAAe;AACxB,SAAO;AACT;AAEA,SAAS,UAAU,MAAiB,WAAW,OAAO,MAAM,OAAO;AACjE,MAAI,QAAQ,OAAO,UAAU,cAAc,GAAG;AAC9C,MAAI,SAAS,mBAAqB,SAAS,kBAAoB;AAC7D,YAAQ,MAAM,YAAY;AAAA,EAC5B;AACA,MAAI,SAAS,iBAAmB;AAC9B,uBAAmB,KAAK;AAAA,EAC1B;AACA,MAAI,SAAS,kBAAoB;AAC/B,kBAAc;AAAA,EAChB;AACA,MAAI,GAAG,SAAS,mBAAqB,SAAS,uBAAyB,QAAQ,eAAe;AAE5F,WAAO,KAAK,EAAE,MAAM,MAAM,OAAO,cAAc,KAAK,MAAM,CAAC;AAAA,EAC7D;AACA,MAAI,SAAS,sBAAwB,SAAS,kBAAoB;AAChE,mBAAe,MAAM;AACrB,YAAQ;AACR,QAAI,SAAS,oBAAsB;AACjC,8BAAwB,KAAK;AAAA,IAC/B;AAAA,EACF,OAAO;AACL,mBAAe;AACf,YAAQ;AAAA,EACV;AACF;AAEA,SAAS,eAAe;AACtB,MAAI,aAAa,mBAAoB;AACnC;AAAA,EACF;AACA,MAAI,SAAS,aAAU;AAErB,cAAU,iBAAmB,qBAAmB;AAAA,EAClD;AACF;AAEA,SAAS,qBAAqB;AAC5B,MAAI,aAAa,cAAe;AAC9B,QAAI,SAAS,aAAU;AACrB,cAAQ;AACR,qBAAe,QAAQ;AAAA,IACzB,OAAO;AACL,cAAQ;AAAA,IACV;AACA;AAAA,EACF;AACA,MAAK,QAAQ,eAAY,QAAQ,gBAAc,QAAQ,eAAY,QAAQ,aAAW;AAEpF,YAAQ;AACR,mBAAe;AAAA,EACjB,WAAW,SAAS,aAAU;AAE5B,YAAQ;AACR,mBAAe,QAAQ;AAAA,EACzB,WAAW,SAAS,aAAU;AAE5B,cAAU,eAAiB;AAAA,EAC7B,WAAW,SAAS,aAAU;AAE5B,YAAQ;AACR,mBAAe;AAAA,EACjB,WAAW,SAAS,aAAU;AAG5B,mBAAe;AACf,cAAU,iBAAmB,uBAAoB;AAAA,EACnD,OAAO;AAGL,YAAQ;AAAA,EACV;AACF;AAEA,SAAS,kBAAkB;AACzB,MAAI,aAAa,GAAG;AAElB,cAAU,iBAAmB,oBAAkB;AAAA,EACjD,WAAW,SAAS,aAAU;AAE5B,cAAU,eAAiB;AAC3B,cAAU,kBAAoB;AAAA,EAChC,WAAW,SAAS,aAAU;AAE5B,cAAU,iBAAmB,sBAAoB;AAAA,EACnD;AACF;AAEA,SAAS,oBAAoB;AAC3B,MAAI,SAAS,aAAU;AAErB,cAAU,kBAAoB;AAC9B,cAAU,kBAAoB;AAAA,EAChC,WAAW,SAAS,aAAU;AAE5B,cAAU,oBAAsB,sBAAoB;AAAA,EACtD,WAAW,SAAS,aAAU;AAE5B,cAAU,kBAAoB;AAC9B,cAAU,qBAAuB,QAAQ,QAAQ,CAAC;AAAA,EACpD,WAAW,SAAS,aAAU;AAE5B,cAAU,oBAAsB,iBAAe;AAAA,EACjD,WAAW,SAAS,aAAU;AAE5B,cAAU,oBAAsB,iBAAe;AAAA,EACjD,WAAW,CAAC,aAAa,GAAG;AAE1B,cAAU,oBAAsB,iBAAe;AAAA,EACjD;AACF;AAEA,SAAS,iBAAiB;AACxB,MAAI,SAAS,aAAU;AAErB,cAAU,mBAAqB;AAC/B,cAAU,kBAAoB;AAAA,EAChC,WAAW,SAAS,aAAU;AAE5B,cAAU,qBAAuB,sBAAoB;AAAA,EACvD,WAAW,SAAS,aAAU;AAE5B,cAAU,mBAAqB;AAC/B,cAAU,qBAAuB,sBAAoB,QAAQ,CAAC;AAAA,EAChE,WAAW,aAAa,GAAG;AAEzB,cAAU,qBAAuB,oBAAkB;AAAA,EACrD;AACF;AAEA,SAAS,iBAAiB;AACxB,MAAI,SAAS,aAAU;AAErB,cAAU,qBAAuB,sBAAoB,QAAQ,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,iBAAiB;AACxB,MAAI,SAAS,aAAU;AAErB,cAAU,qBAAuB,sBAAoB,QAAQ,CAAC;AAAA,EAChE;AACF;AAEA,SAAS,sBAAsB;AAC7B,MAAI,SAAS,aAAU;AAErB,cAAU,kBAAoB;AAAA,EAChC,OAAO;AAEL,cAAU,qBAAuB,oBAAkB;AACnD,sBAAkB;AAAA,EACpB;AACF;AAEA,SAAS,sBAAsB;AAC7B,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,cAAQ;AACR;AAAA,IACF,KAAK;AAAA;AAAA,IACL,KAAK;AACH,cAAQ;AACR;AAAA,IACF;AACE,gBAAU,iBAAmB,uBAAoB;AACjD;AAAA,EACJ;AACF;AAEA,SAAS,sBAAsB;AAC7B,WAAS,QAAQ;AACjB,MAAI,WAAW,QAAQ,QAAQ;AAE7B,QAAI,aAAa,GAAG;AAClB,gBAAU,iBAAmB,oBAAkB;AAAA,IACjD,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF,WAAW,SAAS,aAAU;AAE5B,cAAU,iBAAmB,QAAQ,eAAe,CAAC;AACrD,cAAU,eAAiB;AAC3B,cAAU,kBAAoB;AAAA,EAChC,WAAW,QAAQ,MAAM,MAAM,MAAM,QAAQ,QAAQ,MAAM,MAAM,MAAM,MAAM;AAE3E,cAAU,iBAAmB,yBAAsB,eAAe,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,4BAA4B;AACnC,MAAI,SAAS,aAAU;AAErB,cAAU,iBAAmB,0BAAuB,QAAQ,CAAC;AAAA,EAC/D,OAAO;AACL,cAAU,iBAAmB,yBAAsB,eAAe,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,qBAAqB;AAC5B,MAAI,SAAS,aAAU;AAErB,cAAU,iBAAmB,6BAA0B;AAAA,EACzD;AACF;AAEA,SAAS,oBAAoB;AAC3B,MAAI,SAAS,aAAU;AAErB,cAAU,eAAiB;AAC3B,cAAU,kBAAoB;AAAA,EAChC;AACF;AAEA,SAAS,4BAA4B;AACnC,WAAS,QAAQ;AACjB,MAAI,WAAW,GAAG;AAChB,QAAI,SAAS,aAAU;AAErB,gBAAU,kBAAoB;AAAA,IAChC,WAAW,SAAS,aAAU;AAE5B,gBAAU,iBAAmB,QAAQ,eAAe,CAAC;AAAA,IACvD,OAAO;AAEL,cAAQ;AAAA,IACV;AAAA,EACF,WAAW,SAAS,aAAU;AAE5B,YAAQ;AAAA,EACV;AACF;AAEA,SAAS,kBAAkB;AACzB,WAAS,QAAQ;AACjB,MAAI,aAAa,cAAe;AAC9B,UAAM,SAAS;AACf,QAAI,CAAC,QAAQ;AACX,iBAAW;AAAA,IACb;AACA,QAAI,SAAS,aAAU;AACrB,0BAAoB;AACpB,gBAAU,iBAAmB,qBAAmB;AAAA,IAClD,WAAW,SAAS,OAAO,QAAQ;AACjC,UAAI,OAAO,MAAM,MAAM,MAAM,QAAQ,OAAO,MAAM,MAAM,MAAM,MAAM;AAClE,4BAAoB;AAAA,MACtB;AAAA,IACF,WAAW,SAAS,aAAU;AAC5B,gBAAU,gBAAkB;AAAA,IAC9B,WAAW,CAAC,aAAa,GAAG;AAC1B,0BAAoB;AAAA,IACtB;AAAA,EACF,WAAW,SAAS,aAAU;AAE5B,cAAU,gBAAkB;AAAA,EAC9B;AACF;AAEA,SAAS,aAAoB;AAC3B,QAAM,IAAI;AAAA,IACR,qBAAqB,OAAO,OAAO,KAAK,CAAC,QAAQ,KAAK,eAAe,KAAK;AAAA,EAC5E;AACF;;;AC9lBO,SAAS,cAAc,OAAe;AAC3C,SAAO,MAAM,MAAM,IAAI,EAAE;AAAA,IACvB,CAAC,KAAK,SAAS;AACb,UAAI,KAAK,KAAK,SAAS,IAAI,IAAI,IAAI,SAAS,CAAC,CAAC;AAC9C,aAAO;AAAA,IACT;AAAA,IACA,CAAC,CAAC;AAAA,EACJ;AACF;AAKO,SAAS,YAAY,QAAkBC,SAAkC;AAC9E,MAAI,OAAO;AACX,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,QAAI,OAAO,CAAC,IAAIA,SAAQ;AACtB,aAAO;AACP,eAASA,UAAS,OAAO,IAAI,CAAC,IAAI;AAClC;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,MAAM,MAAM;AACtB;;;ACVA,SAAS,MAAMC,OAAa,QAA2BC,QAAe,SAAsB;AAC1F,UAAQ,SAAS,QAAQ,MAAMD,OAAM,QAAQC,MAAK;AAClD,MAAID,MAAK,4BAA2B,MAAM,QAAQA,MAAK,IAAI,GAAG;AAC5D,aAAS,IAAI,GAAG,IAAIA,MAAK,KAAK,QAAQ,KAAK;AACzC,YAAMA,MAAK,KAAK,CAAC,GAAGA,OAAM,GAAG,OAAO;AAAA,IACtC;AAAA,EACF;AACA,UAAQ,SAAS,QAAQ,MAAMA,OAAM,QAAQC,MAAK;AACpD;AAKO,SAAS,KAAK,KAAc,SAAsB;AACvD,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,UAAM,IAAI,CAAC,GAAG,QAAQ,GAAG,OAAO;AAAA,EAClC;AACF;;;ACPA,IAAIC;AACJ,IAAI;AACJ,IAAIC;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAI;AACJ,IAAIC;AACJ,IAAI;AACJ,IAAI;AAEJ,SAASC,MAAK,OAAgB,SAAwB;AACpD,MAAI,UAAU,QAAQ;AACpB,YAAQ;AACR,IAAAF,QAAO,SAAS;AAChB,IAAAC,UAAS;AAAA,EACX,OAAO;AACL,IAAAD,UAAS,SAAS,OAAO;AAAA,MACvB,kBAAkB,SAAS;AAAA,IAC7B,CAAC;AACD,YAAQA,QAAO;AACf,IAAAC,UAAS;AAAA,EACX;AACA,EAAAF,SAAQ;AACR,aAAW;AACX,UAAQ,CAAC;AACT,UAAQ;AACR,SAAO;AACP,UAAQ;AACR,iBAAe;AACjB;AAEA,SAAS,SAAS,OAAqB;AACrC,MAAI,CAAC,UAAU;AACb,UAAM,KAAK,KAAK;AAAA,EAClB,WACE,MAAM,4BACN,MAAM,SAAS,SAAS,IAAI,QAC5B,aAAa,IAAI,MAAM,IAAI,GAC3B;AACA,eAAW,SAAS;AACpB,aAAS,KAAK;AAAA,EAChB,WAAW,SAAS,IAAI,MAAM;AAC5B,aAAS,IAAI,MAAM,MAAM;AACzB,aAAS,IAAI,KAAK,KAAK,KAAK;AAAA,EAC9B;AACF;AAEA,SAAS,aAAa,KAAW;AAC/B,aAAW,EAAE,QAAQ,UAAU,IAAS;AACxC,SAAO;AACT;AAEA,SAAS,cAAc,QAAQ,MAAM,OAAO,MAAM,MAAM,KAAK,QAAQ,MAAM,OAAc;AACvF,SAAO,EAAE,OAAO,KAAK,OAAO,wBAAsB;AACpD;AAEA,SAAS,YAAkB;AACzB,SAAO;AAAA,IACL,OAAO,MAAM,QAAQ;AAAA;AAAA,IACrB,KAAK,MAAM;AAAA,IACX;AAAA,IACA,MAAM,cAAc,MAAM,QAAQ,CAAC;AAAA;AAAA,IACnC,MAAM,MAAM;AAAA,IACZ,SAASE,QAAO,UAAU,MAAM,OAAO,MAAM,GAAG;AAAA,IAChD,YAAY,CAAC;AAAA,IACb,cAAc;AAAA,IACd,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAA8B;AACrC,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,KAAK,MAAM;AAAA,IACX,MAAM,cAAc;AAAA,IACpB,OAAO;AAAA,EACT;AACF;AAEA,SAAS,uBAAwC;AAC/C,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,KAAK,MAAM;AAAA,IACX,OACE,MAAM,+BACF,MAAM,QACN,MAAM,MAAM,OAAO,GAAG,MAAM,MAAM,SAAS,CAAC;AAAA,IAClD,OACE,MAAM,+BACF,SACA,MAAM,+BACJ,MACA;AAAA,EACV;AACF;AAEA,SAAS,cAAc,QAAiC,MAAe;AACrE,QAAM,SAAS,MAAM;AACrB,QAAM,MAAM,MAAM;AACpB;AAEA,SAASE,cAAa;AACpB,MAAI,UAAU,QAAQ;AACpB,YAAQ,cAAcF,OAAM;AAAA,EAC9B;AACA,QAAM,CAAC,MAAM,MAAM,IAAI,YAAY,OAAO,MAAM,KAAK;AACrD,QAAM,IAAI;AAAA,IACR,qBAAqB,MAAM,KAAK,IAAI,MAAM,IAAI,UAAU,IAAI,IAAI,MAAM,OACnE,WAAW,sBAAsB,KAAK,UAAU,SAAS,IAAI,IAAI,CAAC,MAAM;AAAA,EAC7E;AACF;AAEA,SAAS,kBAAkB,KAAW;AACpC,MAAI,eAAe,CAAC;AACpB,aAAW,QAAQ,IAAI,YAAY;AACjC,QAAI,aAAa,KAAK,KAAK,KAAK,IAAI;AAAA,EACtC;AACF;AAUA,SAAS,eAAe;AACtB,MAAIG,SAAQ;AAEZ,MAAI,OAAmB;AAEvB,QAAM,MAAM,UAAU;AACtB,WAAS,GAAG;AACZ,MAAI,IAAI,SAAS,MAAM,IAAI,SAAS,OAAO,IAAI,SAAS,OAAO;AAC7D,QAAI,KAAK,QAAQ,MAAM,IAAI,KAAK;AAChC,QAAIC,WAAU,OAAO;AACnB;AAAA,IACF,OAAO;AACL,cAAQC,QAAO,EAAED,MAAK;AACtB,UAAI,MAAM,6BAA+B;AACvC,eAAO,cAAc;AACrB,YAAI,OAAO,CAAC,IAAI;AAChB,eAAO,EAAEA,SAAQ,OAAO;AACtB,kBAAQC,QAAOD,MAAK;AACpB,cAAI,MAAM,6BAA+B;AACvC,mBAAO;AACP;AAAA,UACF;AACA,wBAAc;AAAA,QAChB;AAAA,MACF;AACA,UAAI,QAAQ,cAAc,MAAM,OAAO,MAAM,MAAM,GAAG,GAAG,MAAM,KAAK,GAAG;AACvE,UAAI,MAAM,IAAI,MAAM;AAAA,IACtB;AACA;AAAA,EACF;AACA,SAAO,EAAEA,SAAQ,OAAO;AACtB,YAAQC,QAAOD,MAAK;AACpB,QAAI,MAAM,6BAA+B;AACvC,UAAI,MAAM,IAAI,KAAK,MAAM,MAAM,MAAM;AACrC,UAAI,KAAK,QAAQE,QAAO,UAAU,IAAI,KAAK,OAAO,IAAI,KAAK,GAAG;AAC9D,UAAI,MAAM,UAAU,MAAM,CAAC,cAAc,IAAI,IAAI,IAAI,GAAG;AACtD,YAAI,OAAO,CAAC;AACZ,qBAAa,GAAG;AAAA,MAClB,OAAO;AACL,YAAI,OAAO;AAAA,MACb;AACA;AAAA,IACF,WAAWH,WAAU,oBAAyB;AAC5C,UAAI,MAAM,6BAA+B;AACvC,eAAO,gBAAgB;AACvB,QAAAA,SAAQ;AACR,YAAI,WAAW,KAAK,IAAI;AAAA,MAC1B;AAAA,IACF,WAAWA,WAAU,gBAAqB;AACxC,UAAI,MAAM,6BAA+B;AACvC,QAAAA,SAAQ;AAAA,MACV,WAAW,MAAM,8BAAgC;AAC/C,QAAAA,SAAQ;AAAA,MACV,OAAO;AACL,sBAAc,KAAK,IAAI;AAAA,MACzB;AAAA,IACF,WAAWA,WAAU,mBAAwB;AAC3C,UAAI,MAAM,6BAA+B;AACvC,YAAI,MAAM,8BAAgC;AACxC,UAAAA,SAAQ;AAAA,QACV,OAAO;AACL,iBAAO,gBAAgB;AACvB,UAAAA,SAAQ;AACR,cAAI,WAAW,KAAK,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IACF,WAAWA,WAAU,oBAAyB;AAC5C,UAAI,MAAM,6BAA+B;AACvC,aAAK,QAAQ,qBAAqB;AAClC,YAAI,MAAM,8BAAgC;AACxC,UAAAA,SAAQ;AAAA,QACV,OAAO;AACL,eAAK,MAAM,KAAK,MAAM;AACtB,UAAAA,SAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,MAAM,6BAA+B;AACvC,aAAK,MAAM,KAAK,MAAO;AACvB,QAAAA,SAAQ;AAAA,MACV,OAAO;AACL,sBAAc,KAAK,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB;AACvB,MAAI,WAAW;AACf,SAAO,MAAM;AACX,QAAI,CAAC,YAAY,MAAM,MAAM,KAAK,MAAM,SAAS,IAAI,MAAM;AACzD;AAAA,IACF;AACA,eAAW,SAAS;AAAA,EACtB;AACA,MAAI,CAAC,UAAU;AACb;AAAA,EACF;AACA,WAAS,IAAI,QAAQ;AAAA,IACnB,MAAM,QAAQ;AAAA,IACd,MAAM,MAAM;AAAA,IACZG,QAAO,UAAU,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;AAAA,EACjD;AACA,WAAS,IAAI,MAAM,SAAS,IAAI,MAAM;AACtC,aAAW,SAAS;AACpB,aAAW;AACb;AAKO,SAAS,MAAM,OAAe,SAAiC;AACpE,EAAAC,MAAK,OAAO;AAAA,IACV,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,GAAG;AAAA,EACL,CAAC;AACD,SAAOH,SAAQ,OAAO;AACpB,YAAQC,QAAOD,MAAK;AACpB,YAAQ,MAAM,MAAM;AAAA,MAClB;AACE,YAAI,CAAC,MAAM;AACT,iBAAO,cAAc;AACrB,mBAAS,IAAI;AAAA,QACf,OAAO;AACL,wBAAc,IAAI;AAAA,QACpB;AACA;AAAA,MACF;AACE,eAAO;AACP,qBAAa;AACb;AAAA,MACF;AACE,eAAO;AACP,sBAAc;AACd;AAAA,MACF;AACE,QAAAI,YAAW;AACX;AAAA,IACJ;AACA,IAAAJ;AAAA,EACF;AACA,QAAM,SAAS;AACf,MAAI,cAAc,iBAAiB;AACjC,SAAK,QAAQ;AAAA,MACX,MAAMK,OAA0B;AAC9B,YAAIA,MAAK,0BAAyB;AAChC,4BAAkBA,KAAI;AAAA,QACxB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACA,EAAAF,MAAK;AACL,SAAO;AACT;;;AChTO,SAAS,aAAa,KAAW,MAAc,OAAsB;AAC1E,QAAM,OAAO,cAAc,KAAK,IAAI;AACpC,MAAI,MAAM;AACR,SAAK,KAAK,QAAQ;AAClB,SAAK,QACH,UAAU,SACN,SACA;AAAA,MACE,OAAO,KAAK,OAAO,SAAS,KAAK;AAAA,MACjC,KAAK,KAAK,OAAO,OAAO,KAAK;AAAA,MAC7B;AAAA,MACA,OAAO,KAAK,OAAO,SAAS;AAAA,IAC9B;AACN,SAAK,MAAM,KAAK,OAAO,OAAO,KAAK,KAAK;AAAA,EAC1C,OAAO;AACL,QAAI,WAAW,KAAKG,iBAAgB,MAAM,KAAK,CAAC;AAAA,EAClD;AACA,MAAI,IAAI,cAAc;AACpB,QAAI,aAAa,IAAI,IAAI,cAAc,KAAK,IAAI;AAAA,EAClD;AACF;AAKO,SAAS,gBAAgB,KAAW,MAAoB;AAC7D,WAASC,SAAQ,IAAI,WAAW,SAAS,GAAGA,UAAS,GAAGA,UAAS;AAC/D,QAAI,IAAI,WAAWA,MAAK,EAAE,KAAK,UAAU,MAAM;AAC7C,UAAI,WAAW,OAAOA,QAAO,CAAC;AAAA,IAChC;AAAA,EACF;AACA,MAAI,IAAI,cAAc;AACpB,WAAO,IAAI,aAAa,IAAI;AAAA,EAC9B;AACF;AAKO,SAAS,UAAU,KAA8B;AACtD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO,IAAI,IAAI,aAAa,EAAE,KAAK,EAAE;AAAA,EACvC;AACA,SAAO,cAAc,GAAG;AAC1B;AAEA,SAAS,cAAcC,OAAqB;AAC1C,MAAIA,MAAK,4BAA0B;AACjC,WAAOA,MAAK;AAAA,EACd;AACA,SAAO,aAAaA,KAAI;AAC1B;AAEA,SAAS,aAAa,KAAmB;AACvC,MAAI,IAAI,SAAS,MAAM;AACrB,WAAO,iBAAiB,KAAK,KAAK;AAAA,EACpC;AACA,MAAI,IAAI,SAAS,SAAS,IAAI,SAAS,OAAO,IAAI,SAAS,IAAI;AAC7D,WAAO,oBAAoB,GAAG;AAAA,EAChC;AAEA,QAAM,OAAO,iBAAiB,GAAG;AACjC,MAAI,IAAI,SAAS,QAAQ;AACvB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,IAAI,UAAU,OAAO,KAAK,KAAK,IAAI,OAAO;AACxD,SAAO,OAAO,UAAU,IAAI,IAAI,IAAI;AACtC;AAEA,SAAS,oBAAoB,KAAmB;AAC9C,QAAM,OAAO,IAAI,OAAO,UAAU,IAAI,IAAI,IAAI;AAC9C,MAAI,IAAI,SAAS,OAAO;AACtB,WAAO,OAAO,IAAI,GAAG,IAAI,UAAU,OAAO,KAAK,KAAK;AAAA,EACtD;AACA,MAAI,IAAI,SAAS,KAAK;AACpB,WAAO,KAAK,IAAI,GAAG,IAAI,UAAU,OAAO,KAAK,GAAG;AAAA,EAClD;AACA,SAAO,IAAI,IAAI,GAAG,IAAI,UAAU,OAAO,KAAK,GAAG;AACjD;AAEA,SAAS,iBAAiB,KAAW,QAAQ,MAAc;AACzD,QAAM,QAAQ,IAAI,WAAW,IAAI,kBAAkB,EAAE,KAAK,GAAG;AAC7D,SAAO,IAAI,IAAI,OAAO,GAAG,QAAQ,IAAI,KAAK,KAAK,EAAE,GAAG,QAAQ,MAAM,EAAE;AACtE;AAEA,SAAS,mBAAmB,MAA0B;AACpD,MAAI,CAAC,KAAK,OAAO;AACf,WAAO,KAAK,KAAK;AAAA,EACnB;AACA,MAAI,KAAK,MAAM,UAAU,QAAQ;AAC/B,WAAO,GAAG,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK;AAAA,EAC/C;AACA,SAAO,GAAG,KAAK,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,KAAK,GAAG,KAAK,MAAM,KAAK;AACrF;AAEA,SAAS,cAAc,KAAW,MAAsC;AACtE,SAAO,IAAI,WAAW,KAAK,CAAC,SAAS,KAAK,KAAK,UAAU,IAAI;AAC/D;AAEA,SAASF,iBAAgB,MAAc,OAA4B;AACjE,SAAO;AAAA,IACL,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,KAAK;AAAA,MACL;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IACA,OACE,UAAU,SACN,SACA;AAAA,MACE,OAAO;AAAA,MACP,KAAK;AAAA,MACL;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACR;AACF;","names":["SyntaxKind","TokenKind","offset","node","index","index","tokens","buffer","init","unexpected","state","index","tokens","buffer","init","unexpected","node","createAttribute","index","node"]}