{"version":3,"file":"parse-CdeXr0T3.mjs","names":["#text","#lineStarts","#lineIndexAt","#lineStartAt","#lineEndAt","#stack","#tokenizer","#sourceFile","#builder","#diagnostics","#offset","#depth","#advance"],"sources":["../src/source-file.ts","../src/syntax/green.ts","../src/syntax/green-builder.ts","../src/parse.ts"],"sourcesContent":["const CARRIAGE_RETURN = 13;\nconst LINE_FEED = 10;\n\nexport interface Position {\n  readonly line: number;\n  readonly character: number;\n}\n\nexport interface Range {\n  readonly start: Position;\n  readonly end: Position;\n}\n\nexport class SourceFile {\n  readonly #text: string;\n  readonly #lineStarts: readonly number[];\n\n  constructor(text: string) {\n    this.#text = text;\n    const lineStarts: number[] = [0];\n    for (let offset = 0; offset < text.length; offset++) {\n      if (text.charCodeAt(offset) === LINE_FEED) {\n        lineStarts.push(offset + 1);\n      }\n    }\n    this.#lineStarts = lineStarts;\n  }\n\n  get text(): string {\n    return this.#text;\n  }\n\n  get length(): number {\n    return this.#text.length;\n  }\n\n  get lineCount(): number {\n    return this.#lineStarts.length;\n  }\n\n  lineStartOffsets(): readonly number[] {\n    return this.#lineStarts;\n  }\n\n  lineStartOffset(line: number): number {\n    if (line <= 0) {\n      return 0;\n    }\n    return this.#lineStarts[line] ?? this.#text.length;\n  }\n\n  lineEndOffset(line: number): number {\n    if (line < 0) {\n      return 0;\n    }\n\n    const nextLineStart = this.#lineStarts[line + 1];\n    if (nextLineStart === undefined) {\n      return this.#text.length;\n    }\n\n    const lineFeedOffset = nextLineStart - 1;\n    const carriageReturnOffset = lineFeedOffset - 1;\n    return this.#text.charCodeAt(carriageReturnOffset) === CARRIAGE_RETURN\n      ? carriageReturnOffset\n      : lineFeedOffset;\n  }\n\n  positionAt(offset: number): Position {\n    const clamped = clamp(offset, 0, this.#text.length);\n    const line = this.#lineIndexAt(clamped);\n    return { line, character: clamped - this.#lineStartAt(line) };\n  }\n\n  offsetAt(position: Position): number {\n    const line = clamp(position.line, 0, this.#lineStarts.length - 1);\n    const lineStart = this.#lineStartAt(line);\n    const lineEnd = this.#lineEndAt(line);\n    return clamp(lineStart + position.character, lineStart, lineEnd);\n  }\n\n  #lineStartAt(line: number): number {\n    return this.#lineStarts[line] ?? 0;\n  }\n\n  #lineEndAt(line: number): number {\n    return line + 1 < this.#lineStarts.length ? this.#lineStartAt(line + 1) - 1 : this.#text.length;\n  }\n\n  #lineIndexAt(offset: number): number {\n    const lineStarts = this.#lineStarts;\n    let low = 0;\n    let high = lineStarts.length - 1;\n    while (low < high) {\n      const mid = (low + high + 1) >>> 1;\n      if ((lineStarts[mid] ?? 0) <= offset) {\n        low = mid;\n      } else {\n        high = mid - 1;\n      }\n    }\n    return low;\n  }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n  if (value < min) {\n    return min;\n  }\n  if (value > max) {\n    return max;\n  }\n  return value;\n}\n","import type { TokenKind } from '../tokenizer';\nimport type { SyntaxKind } from './syntax-kind';\n\nexport interface GreenToken {\n  readonly type: 'token';\n  readonly kind: TokenKind;\n  readonly text: string;\n}\n\nexport interface GreenNode {\n  readonly type: 'node';\n  readonly kind: SyntaxKind;\n  readonly children: ReadonlyArray<GreenElement>;\n  readonly textLength: number;\n}\n\nexport type GreenElement = GreenNode | GreenToken;\n\nexport function greenToken(kind: TokenKind, text: string): GreenToken {\n  return { type: 'token', kind, text };\n}\n\nexport function greenNode(kind: SyntaxKind, children: ReadonlyArray<GreenElement>): GreenNode {\n  let textLength = 0;\n  for (const child of children) {\n    textLength += child.type === 'token' ? child.text.length : child.textLength;\n  }\n  return { type: 'node', kind, children, textLength };\n}\n","import type { TokenKind } from '../tokenizer';\nimport type { GreenElement, GreenNode } from './green';\nimport { greenNode, greenToken } from './green';\nimport type { SyntaxKind } from './syntax-kind';\n\nexport class GreenNodeBuilder {\n  readonly #stack: Array<{ kind: SyntaxKind; children: GreenElement[] }> = [];\n\n  startNode(kind: SyntaxKind): void {\n    this.#stack.push({ kind, children: [] });\n  }\n\n  token(kind: TokenKind, text: string): void {\n    const current = this.#stack.at(-1);\n    if (!current) {\n      throw new Error('GreenNodeBuilder: token() called with no open node');\n    }\n    current.children.push(greenToken(kind, text));\n  }\n\n  finishNode(): GreenNode {\n    const completed = this.#stack.pop();\n    if (!completed) {\n      throw new Error('GreenNodeBuilder: finishNode() called with no open node');\n    }\n    const node = greenNode(completed.kind, completed.children);\n    const parent = this.#stack.at(-1);\n    if (parent) {\n      parent.children.push(node);\n    }\n    return node;\n  }\n}\n","import type { PslDiagnosticCode } from '@prisma-next/framework-components/psl-ast';\nimport { UNSPECIFIED_PSL_NAMESPACE_ID } from '@prisma-next/framework-components/psl-ast';\nimport { type Range, SourceFile } from './source-file';\nimport { DocumentAst } from './syntax/ast/declarations';\nimport type { GreenNode } from './syntax/green';\nimport { GreenNodeBuilder } from './syntax/green-builder';\nimport { createSyntaxTree } from './syntax/red';\nimport type { SyntaxKind } from './syntax/syntax-kind';\nimport { isTerminatedStringLiteral, type Token, Tokenizer, type TokenKind } from './tokenizer';\n\nexport interface ParseDiagnostic {\n  readonly code: PslDiagnosticCode;\n  readonly message: string;\n  readonly range: Range;\n}\n\nexport interface ParseResult {\n  readonly document: DocumentAst;\n  readonly diagnostics: readonly ParseDiagnostic[];\n  readonly sourceFile: SourceFile;\n}\n\nconst TRIVIA_KINDS: ReadonlySet<TokenKind> = new Set<TokenKind>([\n  'Whitespace',\n  'Newline',\n  'Comment',\n]);\n\n/**\n * The source span of a token, captured eagerly so it stays valid after the\n * cursor advances past the token it points at.\n */\nexport interface DiagnosticMark {\n  readonly offset: number;\n  readonly length: number;\n}\n\n/**\n * The fault-tolerant parser substrate the grammars drive. Trivia is flushed\n * into the enclosing open node, so every child node spans exactly its first\n * through last significant token.\n */\nexport class Cursor {\n  readonly #tokenizer: Tokenizer;\n  readonly #sourceFile: SourceFile;\n  readonly #builder = new GreenNodeBuilder();\n  readonly #diagnostics: ParseDiagnostic[] = [];\n  #offset = 0;\n  #depth = 0;\n\n  constructor(source: string) {\n    this.#tokenizer = new Tokenizer(source);\n    this.#sourceFile = new SourceFile(source);\n  }\n\n  get diagnostics(): readonly ParseDiagnostic[] {\n    return this.#diagnostics;\n  }\n\n  get sourceFile(): SourceFile {\n    return this.#sourceFile;\n  }\n\n  peekKind(ahead = 0): TokenKind {\n    return this.peekToken(ahead).kind;\n  }\n\n  peekToken(ahead = 0): Token {\n    let rawIndex = 0;\n    let remaining = ahead;\n    for (;;) {\n      const token = this.#tokenizer.peek(rawIndex);\n      if (token.kind === 'Eof') return token;\n      if (TRIVIA_KINDS.has(token.kind)) {\n        rawIndex++;\n        continue;\n      }\n      if (remaining === 0) return token;\n      remaining--;\n      rawIndex++;\n    }\n  }\n\n  /** Span of the significant token `lookahead` positions ahead (`mark(0)` = the next). */\n  mark(lookahead = 0): DiagnosticMark {\n    let rawIndex = 0;\n    let offset = this.#offset;\n    let remaining = lookahead;\n    for (;;) {\n      const token = this.#tokenizer.peek(rawIndex);\n      if (token.kind === 'Eof') {\n        return { offset, length: token.text.length };\n      }\n      if (!TRIVIA_KINDS.has(token.kind) && remaining === 0) {\n        return { offset, length: token.text.length };\n      }\n      if (!TRIVIA_KINDS.has(token.kind)) {\n        remaining--;\n      }\n      offset += token.text.length;\n      rawIndex++;\n    }\n  }\n\n  /**\n   * Zero-width mark just past the last consumed significant token — anchors an\n   * \"expected here\" diagnostic, e.g. the `{` missing after a declaration's name.\n   */\n  markAfterLastToken(): DiagnosticMark {\n    return { offset: this.#offset, length: 0 };\n  }\n\n  startNode(kind: SyntaxKind): void {\n    if (this.#depth > 0) {\n      this.flushTrivia();\n    }\n    this.#builder.startNode(kind);\n    this.#depth++;\n  }\n\n  finishNode(): GreenNode {\n    this.#depth--;\n    return this.#builder.finishNode();\n  }\n\n  bump(): Token {\n    this.flushTrivia();\n    const token = this.#tokenizer.peek();\n    if (token.kind === 'Eof') return token;\n    this.#builder.token(token.kind, token.text);\n    this.#advance();\n    return token;\n  }\n\n  recoverToSyncPoint(): void {\n    for (;;) {\n      const token = this.#tokenizer.peek();\n      if (token.kind === 'Eof' || token.kind === 'Newline' || token.kind === 'RBrace') {\n        return;\n      }\n      this.#builder.token(token.kind, token.text);\n      this.#advance();\n    }\n  }\n\n  flushTrivia(): void {\n    for (;;) {\n      const token = this.#tokenizer.peek();\n      if (!TRIVIA_KINDS.has(token.kind)) return;\n      this.#builder.token(token.kind, token.text);\n      this.#advance();\n    }\n  }\n\n  diagnostic(code: PslDiagnosticCode, message: string, mark: DiagnosticMark): void {\n    const start = mark.offset;\n    const end = start + mark.length;\n    this.#diagnostics.push({\n      code,\n      message,\n      range: {\n        start: this.#sourceFile.positionAt(start),\n        end: this.#sourceFile.positionAt(end),\n      },\n    });\n  }\n\n  #advance(): void {\n    this.#offset += this.#tokenizer.next().text.length;\n  }\n}\n\nfunction parseIdentifier(cursor: Cursor): void {\n  cursor.startNode('Identifier');\n  cursor.bump();\n  cursor.finishNode();\n}\n\n/**\n * Returns `undefined` when the next significant token does not start a\n * recognised expression, leaving recovery to the caller.\n */\nexport function parseExpression(cursor: Cursor): GreenNode | undefined {\n  return (\n    parseStringLiteralExpr(cursor) ??\n    parseNumberLiteralExpr(cursor) ??\n    parseArrayLiteral(cursor) ??\n    parseObjectLiteralExpr(cursor) ??\n    parseFunctionCall(cursor) ??\n    parseBooleanLiteralExpr(cursor) ??\n    parseIdentifierExpr(cursor)\n  );\n}\n\nexport function parseStringLiteralExpr(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'StringLiteral') return undefined;\n  const stringMark = cursor.mark();\n  const text = cursor.peekToken().text;\n  cursor.startNode('StringLiteralExpr');\n  cursor.bump();\n  if (!isTerminatedStringLiteral(text)) {\n    cursor.diagnostic('PSL_UNTERMINATED_STRING', 'Unterminated string literal', stringMark);\n  }\n  return cursor.finishNode();\n}\n\nexport function parseNumberLiteralExpr(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'NumberLiteral') return undefined;\n  cursor.startNode('NumberLiteralExpr');\n  cursor.bump();\n  return cursor.finishNode();\n}\n\n/**\n * Parses a namespace-qualified name `[space ':']? Ident ('.' Ident)*`. The\n * caller guarantees a leading `Ident`.\n *\n * Parsing the whole chain up front lets a position decide\n * constructor-vs-reference by peeking exactly one token for `(`, with no scan of\n * the dotted chain's length.\n */\nexport function parseQualifiedName(cursor: Cursor): void {\n  cursor.startNode('QualifiedName');\n  parseIdentifier(cursor); // first segment: the space, namespace, or bare name\n  parseQualifiedSegments(cursor, 'Colon');\n  parseQualifiedSegments(cursor, 'Dot');\n  cursor.finishNode();\n}\n\n/**\n * A well-formed name carries at most one colon space and one dot namespace, so\n * each separator past the first of its kind reports `PSL_INVALID_QUALIFIED_NAME`.\n * The separator is consumed regardless, keeping the lossless round-trip intact.\n */\nfunction parseQualifiedSegments(cursor: Cursor, separator: 'Colon' | 'Dot'): void {\n  let seen = 0;\n  while (cursor.peekKind() === separator) {\n    seen++;\n    const separatorMark = cursor.mark();\n    cursor.bump();\n    if (seen > 1) {\n      cursor.diagnostic(\n        'PSL_INVALID_QUALIFIED_NAME',\n        'Qualified name has too many segments',\n        separatorMark,\n      );\n    }\n    if (cursor.peekKind() === 'Ident') {\n      parseIdentifier(cursor);\n    } else {\n      cursor.diagnostic(\n        'PSL_INVALID_QUALIFIED_NAME',\n        'Qualified name is missing a name after the separator',\n        cursor.mark(),\n      );\n    }\n  }\n}\n\n// Ordering among the `Ident`-leading alternatives is load-bearing: the\n// `LParen`/`Dot` lookahead of `parseCall` must win before the boolean check, so\n// `true(` stays a function call named `true` rather than a boolean literal.\nexport function parseBooleanLiteralExpr(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  const text = cursor.peekToken().text;\n  if (text !== 'true' && text !== 'false') return undefined;\n  cursor.startNode('BooleanLiteralExpr');\n  cursor.bump();\n  return cursor.finishNode();\n}\n\nexport function parseIdentifierExpr(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  cursor.startNode('Identifier');\n  cursor.bump();\n  return cursor.finishNode();\n}\n\nexport function parseArrayLiteral(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'LBracket') return undefined;\n  cursor.startNode('ArrayLiteral');\n  cursor.bump();\n  while (cursor.peekKind() !== 'RBracket' && cursor.peekKind() !== 'Eof') {\n    const element = parseExpression(cursor);\n    if (!element) break;\n    if (cursor.peekKind() === 'Comma') {\n      cursor.bump();\n    } else {\n      break;\n    }\n  }\n  if (cursor.peekKind() === 'RBracket') {\n    cursor.bump();\n  }\n  return cursor.finishNode();\n}\n\nexport function parseObjectLiteralExpr(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'LBrace') return undefined;\n  const braceMark = cursor.mark();\n  cursor.startNode('ObjectLiteralExpr');\n  cursor.bump();\n  while (cursor.peekKind() !== 'RBrace' && cursor.peekKind() !== 'Eof') {\n    parseObjectField(cursor);\n    if (cursor.peekKind() === 'Comma') {\n      cursor.bump();\n    } else if (cursor.peekKind() === 'Ident') {\n      // A following identifier key with no comma re-enters the loop; the next\n      // parseObjectField consumes ≥1 token, so progress is guaranteed.\n      cursor.diagnostic(\n        'PSL_INVALID_OBJECT_LITERAL',\n        'Expected \",\" between object-literal fields',\n        cursor.markAfterLastToken(),\n      );\n    } else {\n      break;\n    }\n  }\n  if (cursor.peekKind() === 'RBrace') {\n    cursor.bump();\n  } else {\n    cursor.diagnostic('PSL_INVALID_OBJECT_LITERAL', 'Unterminated object literal', braceMark);\n  }\n  return cursor.finishNode();\n}\n\nexport function parseObjectField(cursor: Cursor): GreenNode {\n  cursor.startNode('ObjectField');\n  const keyMark = cursor.mark();\n  const keyText = cursor.peekToken().text;\n  if (cursor.peekKind() === 'Ident') {\n    parseIdentifier(cursor);\n  } else if (cursor.peekKind() === 'StringLiteral') {\n    // A string-literal key (e.g. `{ \"length\": 35 }`) is accepted; its logical\n    // name is the unquoted string.\n    parseStringLiteralExpr(cursor);\n  }\n  if (cursor.peekKind() === 'Colon') {\n    cursor.bump(); // Colon\n    const value = parseExpression(cursor);\n    if (!value) {\n      cursor.diagnostic('PSL_INVALID_OBJECT_LITERAL', 'Expected a value after \":\"', cursor.mark());\n    }\n  } else {\n    cursor.diagnostic('PSL_INVALID_OBJECT_LITERAL', `Expected \":\" after \"${keyText}\"`, keyMark);\n    const followsWithKey = cursor.peekKind() === 'Ident' && cursor.peekKind(1) === 'Colon';\n    if (!followsWithKey) {\n      parseExpression(cursor); // best-effort: consume a value if one follows\n    }\n  }\n  return cursor.finishNode();\n}\n\n/**\n * Whether the next tokens open a call: a bare `Ident(` or a namespace-qualified\n * `Ident.Ident(`. The lookahead is deliberately bounded so a bare dotted\n * reference like `a.b` is not mistaken for a call, rather than scanning an\n * unbounded dotted chain ahead to find the paren.\n */\nfunction isCallAhead(cursor: Cursor): boolean {\n  if (cursor.peekKind() !== 'Ident') return false;\n  if (cursor.peekKind(1) === 'LParen') return true;\n  return (\n    cursor.peekKind(1) === 'Dot' &&\n    cursor.peekKind(2) === 'Ident' &&\n    cursor.peekKind(3) === 'LParen'\n  );\n}\n\n/**\n * Parses a function/constructor call — bare `autoincrement()` or qualified\n * `temporal.updatedAt()`. Returns `undefined` unless {@link isCallAhead}\n * confirms a trailing `(`, so the `parseExpression` chain falls through to the\n * boolean and bare-identifier forms.\n */\nexport function parseFunctionCall(cursor: Cursor): GreenNode | undefined {\n  if (!isCallAhead(cursor)) return undefined;\n  cursor.startNode('FunctionCall');\n  parseQualifiedName(cursor);\n  if (cursor.peekKind() === 'LParen') {\n    parseParenArgs(cursor);\n  }\n  return cursor.finishNode();\n}\n\n/** Parses a parenthesised, comma-separated `AttributeArg` list into the currently open node. */\nfunction parseParenArgs(cursor: Cursor): void {\n  cursor.bump();\n  while (cursor.peekKind() !== 'RParen' && cursor.peekKind() !== 'Eof') {\n    parseAttributeArg(cursor);\n    if (cursor.peekKind() === 'Comma') {\n      cursor.bump();\n    } else {\n      break;\n    }\n  }\n  if (cursor.peekKind() === 'RParen') {\n    cursor.bump();\n  }\n}\n\nexport function parseAttributeArg(cursor: Cursor): void {\n  const kind = cursor.peekKind();\n  if (\n    kind !== 'Ident' &&\n    kind !== 'StringLiteral' &&\n    kind !== 'NumberLiteral' &&\n    kind !== 'LBracket' &&\n    kind !== 'LBrace'\n  ) {\n    return;\n  }\n  cursor.startNode('AttributeArg');\n  if (cursor.peekKind() === 'Ident' && cursor.peekKind(1) === 'Colon') {\n    parseIdentifier(cursor);\n    cursor.bump();\n  }\n  parseArgValue(cursor);\n  cursor.finishNode();\n}\n\nfunction parseArgValue(cursor: Cursor): void {\n  parseExpression(cursor);\n}\n\nexport function parseAttributeArgList(cursor: Cursor): GreenNode {\n  cursor.startNode('AttributeArgList');\n  parseParenArgs(cursor);\n  return cursor.finishNode();\n}\n\nexport function parseAttribute(cursor: Cursor): GreenNode {\n  const isBlockAttribute = cursor.peekKind() === 'DoubleAt';\n  const attributeMark = cursor.mark();\n  cursor.startNode(isBlockAttribute ? 'ModelAttribute' : 'FieldAttribute');\n  cursor.bump();\n  if (cursor.peekKind() === 'Ident') {\n    parseQualifiedName(cursor);\n  } else {\n    cursor.diagnostic('PSL_INVALID_ATTRIBUTE_SYNTAX', 'Attribute name expected', attributeMark);\n  }\n  if (cursor.peekKind() === 'LParen') {\n    parseAttributeArgList(cursor);\n  }\n  return cursor.finishNode();\n}\n\n/**\n * A type annotation: `QualifiedName (argList)? ([])? (?)?`, e.g.\n * `pgvector.Vector(1536)[]?`. When the field has no type, no node is emitted —\n * a missing type is the absence of a `TypeAnnotation`, not a zero-width one.\n */\nexport function parseTypeAnnotation(cursor: Cursor): void {\n  const kind = cursor.peekKind();\n  if (kind !== 'Ident' && kind !== 'LBracket' && kind !== 'Question') {\n    return;\n  }\n  cursor.startNode('TypeAnnotation');\n  if (cursor.peekKind() === 'Ident') {\n    parseQualifiedName(cursor);\n    if (cursor.peekKind() === 'LParen') {\n      parseAttributeArgList(cursor);\n    }\n  }\n  if (cursor.peekKind() === 'LBracket') {\n    cursor.bump();\n    if (cursor.peekKind() === 'RBracket') {\n      cursor.bump();\n    }\n  }\n  if (cursor.peekKind() === 'Question') {\n    cursor.bump();\n  }\n  cursor.finishNode();\n}\n\ntype MemberParser = (cursor: Cursor) => void;\n\n/**\n * Parses a full PSL document. Never throws — malformed input yields diagnostics\n * and a recovered tree, not an exception.\n */\nexport function parse(source: string): ParseResult {\n  const cursor = new Cursor(source);\n  const green = parseDocument(cursor);\n  const root = createSyntaxTree(green);\n  const document = DocumentAst.cast(root) ?? new DocumentAst(root);\n  return { document, diagnostics: cursor.diagnostics, sourceFile: cursor.sourceFile };\n}\n\nfunction parseDocument(cursor: Cursor): GreenNode {\n  cursor.startNode('Document');\n  while (cursor.peekKind() !== 'Eof') {\n    parseDeclaration(cursor, false);\n  }\n  cursor.flushTrivia(); // attach trailing trivia so the round-trip stays lossless\n  return cursor.finishNode();\n}\n\nconst RESERVED_BLOCK_KEYWORDS: ReadonlySet<string> = new Set([\n  'model',\n  'namespace',\n  'type',\n  'types',\n]);\n\nfunction keywordIs(cursor: Cursor, keyword: string): boolean {\n  return cursor.peekKind() === 'Ident' && cursor.peekToken().text === keyword;\n}\n\n/**\n * Each alternative is a no-op on non-match, consuming nothing, so the\n * forward-only cursor is never left half-consumed by a rejected alternative.\n * Recovery runs via the `if (!node)` tail rather than as a `??` arm, because it\n * appends raw tokens to the open parent instead of returning a child node.\n */\nfunction parseDeclaration(cursor: Cursor, insideNamespace: boolean): void {\n  const name = cursor.peekKind(1) === 'Ident' ? cursor.peekToken(1).text : '';\n  if (insideNamespace && keywordIs(cursor, 'namespace')) {\n    cursor.diagnostic(\n      'PSL_INVALID_NAMESPACE_BLOCK',\n      `Recursive \"namespace ${name}\" block is not allowed; namespace blocks may not nest`,\n      cursor.mark(),\n    );\n  } else if (insideNamespace && keywordIs(cursor, 'types')) {\n    cursor.diagnostic(\n      'PSL_INVALID_NAMESPACE_BLOCK',\n      '`types` blocks must be declared at the document top level, not inside a namespace block',\n      cursor.mark(),\n    );\n  } else if (keywordIs(cursor, 'namespace') && name === UNSPECIFIED_PSL_NAMESPACE_ID) {\n    cursor.diagnostic(\n      'PSL_INVALID_NAMESPACE_BLOCK',\n      `Namespace name \"${UNSPECIFIED_PSL_NAMESPACE_ID}\" is reserved for the parser-synthesised bucket for top-level declarations`,\n      cursor.mark(1),\n    );\n  }\n\n  const node =\n    parseModel(cursor) ??\n    parseNamespace(cursor) ??\n    parseCompositeType(cursor) ??\n    parseTypesBlock(cursor) ??\n    parseGenericBlock(cursor);\n  if (!node) {\n    parseUnsupportedTopLevel(cursor);\n  }\n}\n\n/**\n * Reports only the first missing piece — a missing name suppresses the\n * missing-brace diagnostic. `nameRequired` is false only for the `types` block.\n */\nfunction parseBlock(\n  cursor: Cursor,\n  kind: SyntaxKind,\n  nameRequired: boolean,\n  parseMember: MemberParser,\n): GreenNode {\n  const keyword = cursor.peekToken().text;\n  const keywordMark = cursor.mark();\n  cursor.startNode(kind);\n  cursor.bump();\n  const hasName = nameRequired && cursor.peekKind() === 'Ident';\n  if (hasName) {\n    parseIdentifier(cursor);\n  }\n  if (nameRequired && !hasName) {\n    cursor.diagnostic('PSL_INVALID_DECLARATION', `Expected a name after \"${keyword}\"`, keywordMark);\n  } else if (cursor.peekKind() !== 'LBrace') {\n    cursor.diagnostic(\n      'PSL_INVALID_DECLARATION',\n      `Expected \"{\" to open the \"${keyword}\" block`,\n      cursor.markAfterLastToken(),\n    );\n  }\n  if (cursor.peekKind() === 'LBrace') {\n    parseBlockBody(cursor, parseMember);\n  } else {\n    cursor.recoverToSyncPoint();\n  }\n  return cursor.finishNode();\n}\n\nexport function parseModel(cursor: Cursor): GreenNode | undefined {\n  if (!keywordIs(cursor, 'model')) return undefined;\n  return parseBlock(cursor, 'ModelDeclaration', true, parseModelMember);\n}\n\n/**\n * Excluding the reserved keywords keeps a malformed reserved block (e.g. `model\n * {` with no name) routed to its dedicated parser. The generic keyword set is\n * open, so a bare identifier with no brace (e.g. `oops`) is read as an unfinished\n * custom declaration rather than unsupported content.\n */\nexport function parseGenericBlock(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  const keyword = cursor.peekToken().text;\n  if (RESERVED_BLOCK_KEYWORDS.has(keyword)) return undefined;\n  const hasName = cursor.peekKind(1) === 'Ident' && cursor.peekKind(2) === 'LBrace';\n  cursor.startNode('GenericBlockDeclaration');\n  cursor.bump();\n  if (hasName) {\n    parseIdentifier(cursor);\n  }\n  if (cursor.peekKind() === 'LBrace') {\n    parseBlockBody(cursor, parseKeyValueMember);\n  } else {\n    cursor.diagnostic(\n      'PSL_INVALID_DECLARATION',\n      `Expected \"{\" to open the \"${keyword}\" block`,\n      cursor.markAfterLastToken(),\n    );\n    cursor.recoverToSyncPoint();\n  }\n  return cursor.finishNode();\n}\n\nexport function parseNamespace(cursor: Cursor): GreenNode | undefined {\n  if (!keywordIs(cursor, 'namespace')) return undefined;\n  return parseBlock(cursor, 'Namespace', true, (inner) => parseDeclaration(inner, true));\n}\n\nexport function parseCompositeType(cursor: Cursor): GreenNode | undefined {\n  if (!keywordIs(cursor, 'type')) return undefined;\n  return parseBlock(cursor, 'CompositeTypeDeclaration', true, parseModelMember);\n}\n\n/** `types` (plural) is the no-name types block; the singular `type` is the composite type above. */\nexport function parseTypesBlock(cursor: Cursor): GreenNode | undefined {\n  if (!keywordIs(cursor, 'types')) return undefined;\n  return parseBlock(cursor, 'TypesBlock', false, parseNamedTypeMember);\n}\n\n/** Every `parseMember` consumes at least one significant token, so the loop always terminates. */\nfunction parseBlockBody(cursor: Cursor, parseMember: MemberParser): void {\n  const braceMark = cursor.mark();\n  cursor.bump();\n  for (;;) {\n    const kind = cursor.peekKind();\n    if (kind === 'RBrace' || kind === 'Eof') break;\n    parseMember(cursor);\n  }\n  if (cursor.peekKind() === 'RBrace') {\n    cursor.bump();\n  } else {\n    cursor.diagnostic('PSL_UNTERMINATED_BLOCK', 'Unterminated block declaration', braceMark);\n  }\n}\n\nfunction parseUnsupportedTopLevel(cursor: Cursor): void {\n  const offending = cursor.peekToken().text;\n  const message =\n    cursor.peekKind(1) === 'LBrace'\n      ? `Unsupported top-level block \"${offending}\"`\n      : `Unsupported top-level declaration \"${offending}\"`;\n  cursor.diagnostic('PSL_UNSUPPORTED_TOP_LEVEL_BLOCK', message, cursor.mark());\n  cursor.bump();\n  cursor.recoverToSyncPoint();\n}\n\n/**\n * Matches a leading `@@` block attribute, a no-op otherwise. Single-`@`\n * attributes belong to fields and are parsed inside `parseField`.\n */\nexport function parseBlockAttribute(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'DoubleAt') return undefined;\n  return parseAttribute(cursor);\n}\n\nfunction parseModelMember(cursor: Cursor): void {\n  const node = parseBlockAttribute(cursor) ?? parseField(cursor);\n  if (!node) {\n    invalidMember(\n      cursor,\n      'PSL_INVALID_MODEL_MEMBER',\n      `Invalid model member declaration \"${cursor.peekToken().text}\"`,\n    );\n  }\n}\n\nfunction parseNamedTypeMember(cursor: Cursor): void {\n  const node = parseNamedType(cursor);\n  if (!node) {\n    invalidMember(\n      cursor,\n      'PSL_INVALID_TYPES_MEMBER',\n      `Invalid types declaration \"${cursor.peekToken().text}\"`,\n    );\n  }\n}\n\n/**\n * A generic-block member is either a `@@`-block attribute or a `key = value`\n * entry. The block-attribute alternative is purely syntactic — it does not judge\n * whether the attribute is valid for the block's kind.\n */\nfunction parseKeyValueMember(cursor: Cursor): void {\n  const node = parseBlockAttribute(cursor) ?? parseKeyValue(cursor);\n  if (!node) {\n    invalidMember(cursor, 'PSL_INVALID_EXTENSION_BLOCK_MEMBER', 'Invalid block entry');\n  }\n}\n\nfunction invalidMember(cursor: Cursor, code: PslDiagnosticCode, message: string): void {\n  cursor.diagnostic(code, message, cursor.mark());\n  cursor.bump(); // consume the offending token so the member loop makes progress\n  cursor.recoverToSyncPoint();\n}\n\nexport function parseField(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  cursor.startNode('FieldDeclaration');\n  const nameMark = cursor.mark();\n  const nameText = cursor.peekToken().text;\n  parseIdentifier(cursor);\n  if (cursor.peekKind() !== 'Ident') {\n    cursor.diagnostic(\n      'PSL_INVALID_MODEL_MEMBER',\n      `Expected a type after field \"${nameText}\"`,\n      nameMark,\n    );\n  }\n  parseTypeAnnotation(cursor);\n  while (cursor.peekKind() === 'At') {\n    parseAttribute(cursor);\n  }\n  return cursor.finishNode();\n}\n\nexport function parseNamedType(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  cursor.startNode('NamedTypeDeclaration');\n  const nameMark = cursor.mark();\n  const nameText = cursor.peekToken().text;\n  parseIdentifier(cursor);\n  if (cursor.peekKind() === 'Equals') {\n    cursor.bump();\n  } else {\n    cursor.diagnostic('PSL_INVALID_TYPES_MEMBER', `Expected \"=\" after \"${nameText}\"`, nameMark);\n  }\n  parseTypeAnnotation(cursor);\n  while (cursor.peekKind() === 'At') {\n    parseAttribute(cursor);\n  }\n  return cursor.finishNode();\n}\n\n/**\n * A generic-block entry is either `key = value` or a bare `key` (committing a\n * `KeyValuePair` carrying only the key). A `key =` with no following expression\n * is flagged.\n */\nexport function parseKeyValue(cursor: Cursor): GreenNode | undefined {\n  if (cursor.peekKind() !== 'Ident') return undefined;\n  cursor.startNode('KeyValuePair');\n  parseIdentifier(cursor);\n  if (cursor.peekKind() === 'Equals') {\n    cursor.bump();\n    if (!parseExpression(cursor)) {\n      cursor.diagnostic(\n        'PSL_INVALID_EXTENSION_BLOCK_MEMBER',\n        'Expected a value after \"=\"',\n        cursor.mark(),\n      );\n    }\n  }\n  return cursor.finishNode();\n}\n"],"mappings":";;;;AAAA,MAAM,kBAAkB;AACxB,MAAM,YAAY;AAYlB,IAAa,aAAb,MAAwB;CACtB;CACA;CAEA,YAAY,MAAc;EACxB,KAAKA,QAAQ;EACb,MAAM,aAAuB,CAAC,CAAC;EAC/B,KAAK,IAAI,SAAS,GAAG,SAAS,KAAK,QAAQ,UACzC,IAAI,KAAK,WAAW,MAAM,MAAM,WAC9B,WAAW,KAAK,SAAS,CAAC;EAG9B,KAAKC,cAAc;CACrB;CAEA,IAAI,OAAe;EACjB,OAAO,KAAKD;CACd;CAEA,IAAI,SAAiB;EACnB,OAAO,KAAKA,MAAM;CACpB;CAEA,IAAI,YAAoB;EACtB,OAAO,KAAKC,YAAY;CAC1B;CAEA,mBAAsC;EACpC,OAAO,KAAKA;CACd;CAEA,gBAAgB,MAAsB;EACpC,IAAI,QAAQ,GACV,OAAO;EAET,OAAO,KAAKA,YAAY,SAAS,KAAKD,MAAM;CAC9C;CAEA,cAAc,MAAsB;EAClC,IAAI,OAAO,GACT,OAAO;EAGT,MAAM,gBAAgB,KAAKC,YAAY,OAAO;EAC9C,IAAI,kBAAkB,KAAA,GACpB,OAAO,KAAKD,MAAM;EAGpB,MAAM,iBAAiB,gBAAgB;EACvC,MAAM,uBAAuB,iBAAiB;EAC9C,OAAO,KAAKA,MAAM,WAAW,oBAAoB,MAAM,kBACnD,uBACA;CACN;CAEA,WAAW,QAA0B;EACnC,MAAM,UAAU,MAAM,QAAQ,GAAG,KAAKA,MAAM,MAAM;EAClD,MAAM,OAAO,KAAKE,aAAa,OAAO;EACtC,OAAO;GAAE;GAAM,WAAW,UAAU,KAAKC,aAAa,IAAI;EAAE;CAC9D;CAEA,SAAS,UAA4B;EACnC,MAAM,OAAO,MAAM,SAAS,MAAM,GAAG,KAAKF,YAAY,SAAS,CAAC;EAChE,MAAM,YAAY,KAAKE,aAAa,IAAI;EACxC,MAAM,UAAU,KAAKC,WAAW,IAAI;EACpC,OAAO,MAAM,YAAY,SAAS,WAAW,WAAW,OAAO;CACjE;CAEA,aAAa,MAAsB;EACjC,OAAO,KAAKH,YAAY,SAAS;CACnC;CAEA,WAAW,MAAsB;EAC/B,OAAO,OAAO,IAAI,KAAKA,YAAY,SAAS,KAAKE,aAAa,OAAO,CAAC,IAAI,IAAI,KAAKH,MAAM;CAC3F;CAEA,aAAa,QAAwB;EACnC,MAAM,aAAa,KAAKC;EACxB,IAAI,MAAM;EACV,IAAI,OAAO,WAAW,SAAS;EAC/B,OAAO,MAAM,MAAM;GACjB,MAAM,MAAO,MAAM,OAAO,MAAO;GACjC,KAAK,WAAW,QAAQ,MAAM,QAC5B,MAAM;QAEN,OAAO,MAAM;EAEjB;EACA,OAAO;CACT;AACF;AAEA,SAAS,MAAM,OAAe,KAAa,KAAqB;CAC9D,IAAI,QAAQ,KACV,OAAO;CAET,IAAI,QAAQ,KACV,OAAO;CAET,OAAO;AACT;;;AC/FA,SAAgB,WAAW,MAAiB,MAA0B;CACpE,OAAO;EAAE,MAAM;EAAS;EAAM;CAAK;AACrC;AAEA,SAAgB,UAAU,MAAkB,UAAkD;CAC5F,IAAI,aAAa;CACjB,KAAK,MAAM,SAAS,UAClB,cAAc,MAAM,SAAS,UAAU,MAAM,KAAK,SAAS,MAAM;CAEnE,OAAO;EAAE,MAAM;EAAQ;EAAM;EAAU;CAAW;AACpD;;;ACvBA,IAAa,mBAAb,MAA8B;CAC5B,SAAyE,CAAC;CAE1E,UAAU,MAAwB;EAChC,KAAKI,OAAO,KAAK;GAAE;GAAM,UAAU,CAAC;EAAE,CAAC;CACzC;CAEA,MAAM,MAAiB,MAAoB;EACzC,MAAM,UAAU,KAAKA,OAAO,GAAG,EAAE;EACjC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oDAAoD;EAEtE,QAAQ,SAAS,KAAK,WAAW,MAAM,IAAI,CAAC;CAC9C;CAEA,aAAwB;EACtB,MAAM,YAAY,KAAKA,OAAO,IAAI;EAClC,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,yDAAyD;EAE3E,MAAM,OAAO,UAAU,UAAU,MAAM,UAAU,QAAQ;EACzD,MAAM,SAAS,KAAKA,OAAO,GAAG,EAAE;EAChC,IAAI,QACF,OAAO,SAAS,KAAK,IAAI;EAE3B,OAAO;CACT;AACF;;;ACVA,MAAM,+BAAuC,IAAI,IAAe;CAC9D;CACA;CACA;AACF,CAAC;;;;;;AAgBD,IAAa,SAAb,MAAoB;CAClB;CACA;CACA,WAAoB,IAAI,iBAAiB;CACzC,eAA2C,CAAC;CAC5C,UAAU;CACV,SAAS;CAET,YAAY,QAAgB;EAC1B,KAAKC,aAAa,IAAI,UAAU,MAAM;EACtC,KAAKC,cAAc,IAAI,WAAW,MAAM;CAC1C;CAEA,IAAI,cAA0C;EAC5C,OAAO,KAAKE;CACd;CAEA,IAAI,aAAyB;EAC3B,OAAO,KAAKF;CACd;CAEA,SAAS,QAAQ,GAAc;EAC7B,OAAO,KAAK,UAAU,KAAK,CAAC,CAAC;CAC/B;CAEA,UAAU,QAAQ,GAAU;EAC1B,IAAI,WAAW;EACf,IAAI,YAAY;EAChB,SAAS;GACP,MAAM,QAAQ,KAAKD,WAAW,KAAK,QAAQ;GAC3C,IAAI,MAAM,SAAS,OAAO,OAAO;GACjC,IAAI,aAAa,IAAI,MAAM,IAAI,GAAG;IAChC;IACA;GACF;GACA,IAAI,cAAc,GAAG,OAAO;GAC5B;GACA;EACF;CACF;;CAGA,KAAK,YAAY,GAAmB;EAClC,IAAI,WAAW;EACf,IAAI,SAAS,KAAKI;EAClB,IAAI,YAAY;EAChB,SAAS;GACP,MAAM,QAAQ,KAAKJ,WAAW,KAAK,QAAQ;GAC3C,IAAI,MAAM,SAAS,OACjB,OAAO;IAAE;IAAQ,QAAQ,MAAM,KAAK;GAAO;GAE7C,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,KAAK,cAAc,GACjD,OAAO;IAAE;IAAQ,QAAQ,MAAM,KAAK;GAAO;GAE7C,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,GAC9B;GAEF,UAAU,MAAM,KAAK;GACrB;EACF;CACF;;;;;CAMA,qBAAqC;EACnC,OAAO;GAAE,QAAQ,KAAKI;GAAS,QAAQ;EAAE;CAC3C;CAEA,UAAU,MAAwB;EAChC,IAAI,KAAKC,SAAS,GAChB,KAAK,YAAY;EAEnB,KAAKH,SAAS,UAAU,IAAI;EAC5B,KAAKG;CACP;CAEA,aAAwB;EACtB,KAAKA;EACL,OAAO,KAAKH,SAAS,WAAW;CAClC;CAEA,OAAc;EACZ,KAAK,YAAY;EACjB,MAAM,QAAQ,KAAKF,WAAW,KAAK;EACnC,IAAI,MAAM,SAAS,OAAO,OAAO;EACjC,KAAKE,SAAS,MAAM,MAAM,MAAM,MAAM,IAAI;EAC1C,KAAKI,SAAS;EACd,OAAO;CACT;CAEA,qBAA2B;EACzB,SAAS;GACP,MAAM,QAAQ,KAAKN,WAAW,KAAK;GACnC,IAAI,MAAM,SAAS,SAAS,MAAM,SAAS,aAAa,MAAM,SAAS,UACrE;GAEF,KAAKE,SAAS,MAAM,MAAM,MAAM,MAAM,IAAI;GAC1C,KAAKI,SAAS;EAChB;CACF;CAEA,cAAoB;EAClB,SAAS;GACP,MAAM,QAAQ,KAAKN,WAAW,KAAK;GACnC,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,GAAG;GACnC,KAAKE,SAAS,MAAM,MAAM,MAAM,MAAM,IAAI;GAC1C,KAAKI,SAAS;EAChB;CACF;CAEA,WAAW,MAAyB,SAAiB,MAA4B;EAC/E,MAAM,QAAQ,KAAK;EACnB,MAAM,MAAM,QAAQ,KAAK;EACzB,KAAKH,aAAa,KAAK;GACrB;GACA;GACA,OAAO;IACL,OAAO,KAAKF,YAAY,WAAW,KAAK;IACxC,KAAK,KAAKA,YAAY,WAAW,GAAG;GACtC;EACF,CAAC;CACH;CAEA,WAAiB;EACf,KAAKG,WAAW,KAAKJ,WAAW,KAAK,CAAC,CAAC,KAAK;CAC9C;AACF;AAEA,SAAS,gBAAgB,QAAsB;CAC7C,OAAO,UAAU,YAAY;CAC7B,OAAO,KAAK;CACZ,OAAO,WAAW;AACpB;;;;;AAMA,SAAgB,gBAAgB,QAAuC;CACrE,OACE,uBAAuB,MAAM,KAC7B,uBAAuB,MAAM,KAC7B,kBAAkB,MAAM,KACxB,uBAAuB,MAAM,KAC7B,kBAAkB,MAAM,KACxB,wBAAwB,MAAM,KAC9B,oBAAoB,MAAM;AAE9B;AAEA,SAAgB,uBAAuB,QAAuC;CAC5E,IAAI,OAAO,SAAS,MAAM,iBAAiB,OAAO,KAAA;CAClD,MAAM,aAAa,OAAO,KAAK;CAC/B,MAAM,OAAO,OAAO,UAAU,CAAC,CAAC;CAChC,OAAO,UAAU,mBAAmB;CACpC,OAAO,KAAK;CACZ,IAAI,CAAC,0BAA0B,IAAI,GACjC,OAAO,WAAW,2BAA2B,+BAA+B,UAAU;CAExF,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,uBAAuB,QAAuC;CAC5E,IAAI,OAAO,SAAS,MAAM,iBAAiB,OAAO,KAAA;CAClD,OAAO,UAAU,mBAAmB;CACpC,OAAO,KAAK;CACZ,OAAO,OAAO,WAAW;AAC3B;;;;;;;;;AAUA,SAAgB,mBAAmB,QAAsB;CACvD,OAAO,UAAU,eAAe;CAChC,gBAAgB,MAAM;CACtB,uBAAuB,QAAQ,OAAO;CACtC,uBAAuB,QAAQ,KAAK;CACpC,OAAO,WAAW;AACpB;;;;;;AAOA,SAAS,uBAAuB,QAAgB,WAAkC;CAChF,IAAI,OAAO;CACX,OAAO,OAAO,SAAS,MAAM,WAAW;EACtC;EACA,MAAM,gBAAgB,OAAO,KAAK;EAClC,OAAO,KAAK;EACZ,IAAI,OAAO,GACT,OAAO,WACL,8BACA,wCACA,aACF;EAEF,IAAI,OAAO,SAAS,MAAM,SACxB,gBAAgB,MAAM;OAEtB,OAAO,WACL,8BACA,wDACA,OAAO,KAAK,CACd;CAEJ;AACF;AAKA,SAAgB,wBAAwB,QAAuC;CAC7E,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,MAAM,OAAO,OAAO,UAAU,CAAC,CAAC;CAChC,IAAI,SAAS,UAAU,SAAS,SAAS,OAAO,KAAA;CAChD,OAAO,UAAU,oBAAoB;CACrC,OAAO,KAAK;CACZ,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,oBAAoB,QAAuC;CACzE,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,OAAO,UAAU,YAAY;CAC7B,OAAO,KAAK;CACZ,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,kBAAkB,QAAuC;CACvE,IAAI,OAAO,SAAS,MAAM,YAAY,OAAO,KAAA;CAC7C,OAAO,UAAU,cAAc;CAC/B,OAAO,KAAK;CACZ,OAAO,OAAO,SAAS,MAAM,cAAc,OAAO,SAAS,MAAM,OAAO;EAEtE,IAAI,CADY,gBAAgB,MACrB,GAAG;EACd,IAAI,OAAO,SAAS,MAAM,SACxB,OAAO,KAAK;OAEZ;CAEJ;CACA,IAAI,OAAO,SAAS,MAAM,YACxB,OAAO,KAAK;CAEd,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,uBAAuB,QAAuC;CAC5E,IAAI,OAAO,SAAS,MAAM,UAAU,OAAO,KAAA;CAC3C,MAAM,YAAY,OAAO,KAAK;CAC9B,OAAO,UAAU,mBAAmB;CACpC,OAAO,KAAK;CACZ,OAAO,OAAO,SAAS,MAAM,YAAY,OAAO,SAAS,MAAM,OAAO;EACpE,iBAAiB,MAAM;EACvB,IAAI,OAAO,SAAS,MAAM,SACxB,OAAO,KAAK;OACP,IAAI,OAAO,SAAS,MAAM,SAG/B,OAAO,WACL,8BACA,gDACA,OAAO,mBAAmB,CAC5B;OAEA;CAEJ;CACA,IAAI,OAAO,SAAS,MAAM,UACxB,OAAO,KAAK;MAEZ,OAAO,WAAW,8BAA8B,+BAA+B,SAAS;CAE1F,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,iBAAiB,QAA2B;CAC1D,OAAO,UAAU,aAAa;CAC9B,MAAM,UAAU,OAAO,KAAK;CAC5B,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC;CACnC,IAAI,OAAO,SAAS,MAAM,SACxB,gBAAgB,MAAM;MACjB,IAAI,OAAO,SAAS,MAAM,iBAG/B,uBAAuB,MAAM;CAE/B,IAAI,OAAO,SAAS,MAAM,SAAS;EACjC,OAAO,KAAK;EAEZ,IAAI,CADU,gBAAgB,MACrB,GACP,OAAO,WAAW,8BAA8B,gCAA8B,OAAO,KAAK,CAAC;CAE/F,OAAO;EACL,OAAO,WAAW,8BAA8B,uBAAuB,QAAQ,IAAI,OAAO;EAE1F,IAAI,EADmB,OAAO,SAAS,MAAM,WAAW,OAAO,SAAS,CAAC,MAAM,UAE7E,gBAAgB,MAAM;CAE1B;CACA,OAAO,OAAO,WAAW;AAC3B;;;;;;;AAQA,SAAS,YAAY,QAAyB;CAC5C,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO;CAC1C,IAAI,OAAO,SAAS,CAAC,MAAM,UAAU,OAAO;CAC5C,OACE,OAAO,SAAS,CAAC,MAAM,SACvB,OAAO,SAAS,CAAC,MAAM,WACvB,OAAO,SAAS,CAAC,MAAM;AAE3B;;;;;;;AAQA,SAAgB,kBAAkB,QAAuC;CACvE,IAAI,CAAC,YAAY,MAAM,GAAG,OAAO,KAAA;CACjC,OAAO,UAAU,cAAc;CAC/B,mBAAmB,MAAM;CACzB,IAAI,OAAO,SAAS,MAAM,UACxB,eAAe,MAAM;CAEvB,OAAO,OAAO,WAAW;AAC3B;;AAGA,SAAS,eAAe,QAAsB;CAC5C,OAAO,KAAK;CACZ,OAAO,OAAO,SAAS,MAAM,YAAY,OAAO,SAAS,MAAM,OAAO;EACpE,kBAAkB,MAAM;EACxB,IAAI,OAAO,SAAS,MAAM,SACxB,OAAO,KAAK;OAEZ;CAEJ;CACA,IAAI,OAAO,SAAS,MAAM,UACxB,OAAO,KAAK;AAEhB;AAEA,SAAgB,kBAAkB,QAAsB;CACtD,MAAM,OAAO,OAAO,SAAS;CAC7B,IACE,SAAS,WACT,SAAS,mBACT,SAAS,mBACT,SAAS,cACT,SAAS,UAET;CAEF,OAAO,UAAU,cAAc;CAC/B,IAAI,OAAO,SAAS,MAAM,WAAW,OAAO,SAAS,CAAC,MAAM,SAAS;EACnE,gBAAgB,MAAM;EACtB,OAAO,KAAK;CACd;CACA,cAAc,MAAM;CACpB,OAAO,WAAW;AACpB;AAEA,SAAS,cAAc,QAAsB;CAC3C,gBAAgB,MAAM;AACxB;AAEA,SAAgB,sBAAsB,QAA2B;CAC/D,OAAO,UAAU,kBAAkB;CACnC,eAAe,MAAM;CACrB,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,eAAe,QAA2B;CACxD,MAAM,mBAAmB,OAAO,SAAS,MAAM;CAC/C,MAAM,gBAAgB,OAAO,KAAK;CAClC,OAAO,UAAU,mBAAmB,mBAAmB,gBAAgB;CACvE,OAAO,KAAK;CACZ,IAAI,OAAO,SAAS,MAAM,SACxB,mBAAmB,MAAM;MAEzB,OAAO,WAAW,gCAAgC,2BAA2B,aAAa;CAE5F,IAAI,OAAO,SAAS,MAAM,UACxB,sBAAsB,MAAM;CAE9B,OAAO,OAAO,WAAW;AAC3B;;;;;;AAOA,SAAgB,oBAAoB,QAAsB;CACxD,MAAM,OAAO,OAAO,SAAS;CAC7B,IAAI,SAAS,WAAW,SAAS,cAAc,SAAS,YACtD;CAEF,OAAO,UAAU,gBAAgB;CACjC,IAAI,OAAO,SAAS,MAAM,SAAS;EACjC,mBAAmB,MAAM;EACzB,IAAI,OAAO,SAAS,MAAM,UACxB,sBAAsB,MAAM;CAEhC;CACA,IAAI,OAAO,SAAS,MAAM,YAAY;EACpC,OAAO,KAAK;EACZ,IAAI,OAAO,SAAS,MAAM,YACxB,OAAO,KAAK;CAEhB;CACA,IAAI,OAAO,SAAS,MAAM,YACxB,OAAO,KAAK;CAEd,OAAO,WAAW;AACpB;;;;;AAQA,SAAgB,MAAM,QAA6B;CACjD,MAAM,SAAS,IAAI,OAAO,MAAM;CAEhC,MAAM,OAAO,iBADC,cAAc,MACM,CAAC;CAEnC,OAAO;EAAE,UADQ,YAAY,KAAK,IAAI,KAAK,IAAI,YAAY,IAAI;EAC5C,aAAa,OAAO;EAAa,YAAY,OAAO;CAAW;AACpF;AAEA,SAAS,cAAc,QAA2B;CAChD,OAAO,UAAU,UAAU;CAC3B,OAAO,OAAO,SAAS,MAAM,OAC3B,iBAAiB,QAAQ,KAAK;CAEhC,OAAO,YAAY;CACnB,OAAO,OAAO,WAAW;AAC3B;AAEA,MAAM,0CAA+C,IAAI,IAAI;CAC3D;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,UAAU,QAAgB,SAA0B;CAC3D,OAAO,OAAO,SAAS,MAAM,WAAW,OAAO,UAAU,CAAC,CAAC,SAAS;AACtE;;;;;;;AAQA,SAAS,iBAAiB,QAAgB,iBAAgC;CACxE,MAAM,OAAO,OAAO,SAAS,CAAC,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC,CAAC,OAAO;CACzE,IAAI,mBAAmB,UAAU,QAAQ,WAAW,GAClD,OAAO,WACL,+BACA,wBAAwB,KAAK,wDAC7B,OAAO,KAAK,CACd;MACK,IAAI,mBAAmB,UAAU,QAAQ,OAAO,GACrD,OAAO,WACL,+BACA,2FACA,OAAO,KAAK,CACd;MACK,IAAI,UAAU,QAAQ,WAAW,KAAK,SAAS,8BACpD,OAAO,WACL,+BACA,mBAAmB,6BAA6B,6EAChD,OAAO,KAAK,CAAC,CACf;CASF,IAAI,EALF,WAAW,MAAM,KACjB,eAAe,MAAM,KACrB,mBAAmB,MAAM,KACzB,gBAAgB,MAAM,KACtB,kBAAkB,MAAM,IAExB,yBAAyB,MAAM;AAEnC;;;;;AAMA,SAAS,WACP,QACA,MACA,cACA,aACW;CACX,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC;CACnC,MAAM,cAAc,OAAO,KAAK;CAChC,OAAO,UAAU,IAAI;CACrB,OAAO,KAAK;CACZ,MAAM,UAAU,gBAAgB,OAAO,SAAS,MAAM;CACtD,IAAI,SACF,gBAAgB,MAAM;CAExB,IAAI,gBAAgB,CAAC,SACnB,OAAO,WAAW,2BAA2B,0BAA0B,QAAQ,IAAI,WAAW;MACzF,IAAI,OAAO,SAAS,MAAM,UAC/B,OAAO,WACL,2BACA,6BAA6B,QAAQ,UACrC,OAAO,mBAAmB,CAC5B;CAEF,IAAI,OAAO,SAAS,MAAM,UACxB,eAAe,QAAQ,WAAW;MAElC,OAAO,mBAAmB;CAE5B,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,WAAW,QAAuC;CAChE,IAAI,CAAC,UAAU,QAAQ,OAAO,GAAG,OAAO,KAAA;CACxC,OAAO,WAAW,QAAQ,oBAAoB,MAAM,gBAAgB;AACtE;;;;;;;AAQA,SAAgB,kBAAkB,QAAuC;CACvE,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,MAAM,UAAU,OAAO,UAAU,CAAC,CAAC;CACnC,IAAI,wBAAwB,IAAI,OAAO,GAAG,OAAO,KAAA;CACjD,MAAM,UAAU,OAAO,SAAS,CAAC,MAAM,WAAW,OAAO,SAAS,CAAC,MAAM;CACzE,OAAO,UAAU,yBAAyB;CAC1C,OAAO,KAAK;CACZ,IAAI,SACF,gBAAgB,MAAM;CAExB,IAAI,OAAO,SAAS,MAAM,UACxB,eAAe,QAAQ,mBAAmB;MACrC;EACL,OAAO,WACL,2BACA,6BAA6B,QAAQ,UACrC,OAAO,mBAAmB,CAC5B;EACA,OAAO,mBAAmB;CAC5B;CACA,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,eAAe,QAAuC;CACpE,IAAI,CAAC,UAAU,QAAQ,WAAW,GAAG,OAAO,KAAA;CAC5C,OAAO,WAAW,QAAQ,aAAa,OAAO,UAAU,iBAAiB,OAAO,IAAI,CAAC;AACvF;AAEA,SAAgB,mBAAmB,QAAuC;CACxE,IAAI,CAAC,UAAU,QAAQ,MAAM,GAAG,OAAO,KAAA;CACvC,OAAO,WAAW,QAAQ,4BAA4B,MAAM,gBAAgB;AAC9E;;AAGA,SAAgB,gBAAgB,QAAuC;CACrE,IAAI,CAAC,UAAU,QAAQ,OAAO,GAAG,OAAO,KAAA;CACxC,OAAO,WAAW,QAAQ,cAAc,OAAO,oBAAoB;AACrE;;AAGA,SAAS,eAAe,QAAgB,aAAiC;CACvE,MAAM,YAAY,OAAO,KAAK;CAC9B,OAAO,KAAK;CACZ,SAAS;EACP,MAAM,OAAO,OAAO,SAAS;EAC7B,IAAI,SAAS,YAAY,SAAS,OAAO;EACzC,YAAY,MAAM;CACpB;CACA,IAAI,OAAO,SAAS,MAAM,UACxB,OAAO,KAAK;MAEZ,OAAO,WAAW,0BAA0B,kCAAkC,SAAS;AAE3F;AAEA,SAAS,yBAAyB,QAAsB;CACtD,MAAM,YAAY,OAAO,UAAU,CAAC,CAAC;CACrC,MAAM,UACJ,OAAO,SAAS,CAAC,MAAM,WACnB,gCAAgC,UAAU,KAC1C,sCAAsC,UAAU;CACtD,OAAO,WAAW,mCAAmC,SAAS,OAAO,KAAK,CAAC;CAC3E,OAAO,KAAK;CACZ,OAAO,mBAAmB;AAC5B;;;;;AAMA,SAAgB,oBAAoB,QAAuC;CACzE,IAAI,OAAO,SAAS,MAAM,YAAY,OAAO,KAAA;CAC7C,OAAO,eAAe,MAAM;AAC9B;AAEA,SAAS,iBAAiB,QAAsB;CAE9C,IAAI,EADS,oBAAoB,MAAM,KAAK,WAAW,MAAM,IAE3D,cACE,QACA,4BACA,qCAAqC,OAAO,UAAU,CAAC,CAAC,KAAK,EAC/D;AAEJ;AAEA,SAAS,qBAAqB,QAAsB;CAElD,IAAI,CADS,eAAe,MACpB,GACN,cACE,QACA,4BACA,8BAA8B,OAAO,UAAU,CAAC,CAAC,KAAK,EACxD;AAEJ;;;;;;AAOA,SAAS,oBAAoB,QAAsB;CAEjD,IAAI,EADS,oBAAoB,MAAM,KAAK,cAAc,MAAM,IAE9D,cAAc,QAAQ,sCAAsC,qBAAqB;AAErF;AAEA,SAAS,cAAc,QAAgB,MAAyB,SAAuB;CACrF,OAAO,WAAW,MAAM,SAAS,OAAO,KAAK,CAAC;CAC9C,OAAO,KAAK;CACZ,OAAO,mBAAmB;AAC5B;AAEA,SAAgB,WAAW,QAAuC;CAChE,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,OAAO,UAAU,kBAAkB;CACnC,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,WAAW,OAAO,UAAU,CAAC,CAAC;CACpC,gBAAgB,MAAM;CACtB,IAAI,OAAO,SAAS,MAAM,SACxB,OAAO,WACL,4BACA,gCAAgC,SAAS,IACzC,QACF;CAEF,oBAAoB,MAAM;CAC1B,OAAO,OAAO,SAAS,MAAM,MAC3B,eAAe,MAAM;CAEvB,OAAO,OAAO,WAAW;AAC3B;AAEA,SAAgB,eAAe,QAAuC;CACpE,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,OAAO,UAAU,sBAAsB;CACvC,MAAM,WAAW,OAAO,KAAK;CAC7B,MAAM,WAAW,OAAO,UAAU,CAAC,CAAC;CACpC,gBAAgB,MAAM;CACtB,IAAI,OAAO,SAAS,MAAM,UACxB,OAAO,KAAK;MAEZ,OAAO,WAAW,4BAA4B,uBAAuB,SAAS,IAAI,QAAQ;CAE5F,oBAAoB,MAAM;CAC1B,OAAO,OAAO,SAAS,MAAM,MAC3B,eAAe,MAAM;CAEvB,OAAO,OAAO,WAAW;AAC3B;;;;;;AAOA,SAAgB,cAAc,QAAuC;CACnE,IAAI,OAAO,SAAS,MAAM,SAAS,OAAO,KAAA;CAC1C,OAAO,UAAU,cAAc;CAC/B,gBAAgB,MAAM;CACtB,IAAI,OAAO,SAAS,MAAM,UAAU;EAClC,OAAO,KAAK;EACZ,IAAI,CAAC,gBAAgB,MAAM,GACzB,OAAO,WACL,sCACA,gCACA,OAAO,KAAK,CACd;CAEJ;CACA,OAAO,OAAO,WAAW;AAC3B"}