@lucidkiln/core 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/ast-DDhHuwaY.d.ts +350 -0
- package/dist/ast-DDhHuwaY.d.ts.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{environment-BlQ8V4tX.d.ts → environment-DBvRrOn0.d.ts} +51 -80
- package/dist/environment-DBvRrOn0.d.ts.map +1 -0
- package/dist/{format-CJoqhehX.js → format-Di6-GUtH.js} +4 -3
- package/dist/{format-CJoqhehX.js.map → format-Di6-GUtH.js.map} +1 -1
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -158
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/parser-isboTef0.js +2627 -0
- package/dist/parser-isboTef0.js.map +1 -0
- package/dist/{source-BQxJGo5Y.js → source-BbikGqIb.js} +40 -2765
- package/dist/source-BbikGqIb.js.map +1 -0
- package/dist/syntax.d.ts +22 -0
- package/dist/syntax.d.ts.map +1 -0
- package/dist/syntax.js +1 -0
- package/package.json +5 -1
- package/dist/environment-BlQ8V4tX.d.ts.map +0 -1
- package/dist/source-BQxJGo5Y.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser-isboTef0.js","names":[],"sources":["../src/parser/ast.ts","../src/lexer/lexer.ts","../src/parser/indent.ts","../src/parser/parser.ts"],"sourcesContent":["import type { Span } from \"../source.js\";\n\nexport type EscapeStrategy = \"html\" | \"attr\" | \"js\" | \"css\" | \"url\";\n\nexport type BinaryOperator =\n\t| \"or\"\n\t| \"and\"\n\t| \"??\"\n\t| \"?:\"\n\t| \"==\"\n\t| \"!=\"\n\t| \"<\"\n\t| \">\"\n\t| \"<=\"\n\t| \">=\"\n\t| \"in\"\n\t| \"not in\"\n\t| \"starts with\"\n\t| \"ends with\"\n\t| \"..\"\n\t| \"~\"\n\t| \"+\"\n\t| \"-\"\n\t| \"*\"\n\t| \"/\"\n\t| \"//\"\n\t| \"%\"\n\t| \"**\";\n\nexport type Spread = { type: \"Spread\"; value: Expression; span: Span };\n\nexport type Argument =\n\t| { type: \"Positional\"; value: Expression; span: Span }\n\t| { type: \"Named\"; name: string; value: Expression; span: Span }\n\t| Spread;\n\nexport type HashEntry =\n\t| { type: \"Property\"; key: Expression; value: Expression; span: Span }\n\t| Spread;\n\nexport type Expression =\n\t| {\n\t\t\ttype: \"Literal\";\n\t\t\tvalue: null | boolean | number | string;\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Name\"; name: string; span: Span }\n\t/** A double-quoted string with `#{}` interpolation. */\n\t| { type: \"Interpolation\"; parts: Expression[]; span: Span }\n\t| { type: \"Array\"; elements: (Expression | Spread)[]; span: Span }\n\t| { type: \"Hash\"; entries: HashEntry[]; span: Span }\n\t| {\n\t\t\ttype: \"Unary\";\n\t\t\toperator: \"-\" | \"+\" | \"not\";\n\t\t\toperand: Expression;\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Binary\";\n\t\t\toperator: BinaryOperator;\n\t\t\tleft: Expression;\n\t\t\tright: Expression;\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Conditional\";\n\t\t\ttest: Expression;\n\t\t\tconsequent: Expression;\n\t\t\talternate: Expression | null;\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Member\";\n\t\t\tobject: Expression;\n\t\t\tproperty: Expression;\n\t\t\t/** True for `a?.b` and `a?.[b]`. */\n\t\t\toptional: boolean;\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Call\"; callee: Expression; args: Argument[]; span: Span }\n\t| {\n\t\t\ttype: \"Filter\";\n\t\t\tname: string;\n\t\t\tnameSpan: Span;\n\t\t\tinput: Expression;\n\t\t\targs: Argument[];\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Test\";\n\t\t\tname: string;\n\t\t\tnameSpan: Span;\n\t\t\tinput: Expression;\n\t\t\targs: Argument[];\n\t\t\tnegated: boolean;\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Arrow\"; params: string[]; body: Expression; span: Span }\n\t/** Wraps a member and call chain that contains `?.`, so null short-circuits the whole chain. */\n\t| { type: \"OptionalChain\"; expression: Expression; span: Span }\n\t/** Stands in for an expression that failed to parse. */\n\t| { type: \"Invalid\"; span: Span };\n\nexport type Param = { name: string; default: Expression | null; span: Span };\n\n/** Type names a prop can declare. See `TYPE_NAMES`. */\nexport type TypeName = (typeof TYPE_NAMES)[number];\n\n/**\n * One member of a prop's type. A full type is a list of members, read as a union.\n *\n * - A built-in type name, such as `string`.\n * - `{ literal }`: one exact string or number, such as `\"primary\"`.\n * - `{ list }`: `T[]`, an array of the inner type.\n * - `{ shape }`: `{ name: string }`, a hash or object with these keys.\n * - `{ named }`: a type the host registers, such as `Post`.\n */\nexport type PropType =\n\t| TypeName\n\t| { literal: string | number }\n\t| { list: PropType[] }\n\t| { shape: ShapeKey[] }\n\t| { named: string };\n\n/** One key of a shape type, such as `url?: string`. */\nexport type ShapeKey = { name: string; optional: boolean; type: PropType[] };\n\n/** A `props` entry. `type` is null when the prop is untyped. */\nexport type PropParam = Param & { type: PropType[] | null };\n\nexport type FilterCall = {\n\tname: string;\n\targs: Argument[];\n\tspan: Span;\n};\n\nexport type Statement =\n\t| { type: \"Text\"; value: string; span: Span }\n\t| { type: \"Output\"; expression: Expression; span: Span }\n\t| {\n\t\t\ttype: \"If\";\n\t\t\tbranches: { test: Expression; body: Statement[] }[];\n\t\t\talternate: Statement[] | null;\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"For\";\n\t\t\tkeyName: string | null;\n\t\t\tvalueName: string;\n\t\t\titerable: Expression;\n\t\t\tbody: Statement[];\n\t\t\talternate: Statement[] | null;\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Set\"; name: string; value: Expression; span: Span }\n\t| { type: \"SetBlock\"; name: string; body: Statement[]; span: Span }\n\t/** `rest` names the hash that collects undeclared variables, as in `...attributes`, or is null. */\n\t| { type: \"Props\"; props: PropParam[]; rest: string | null; span: Span }\n\t| { type: \"Extends\"; template: Expression; span: Span }\n\t| { type: \"Block\"; name: string; body: Statement[]; span: Span }\n\t| {\n\t\t\ttype: \"Include\";\n\t\t\ttemplate: Expression;\n\t\t\twith: Expression | null;\n\t\t\tignoreMissing: boolean;\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Component\";\n\t\t\ttemplate: Expression;\n\t\t\twith: Expression | null;\n\t\t\tfills: { name: string; body: Statement[]; span: Span }[];\n\t\t\t/** Content outside any `fill`, which fills the default slot. */\n\t\t\tbody: Statement[];\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Slot\"; name: string; body: Statement[]; span: Span }\n\t/**\n\t * A component that can load after the page. `body` is the fallback, shown until a deferred island loads. A deferred\n\t * island writes its tags back as `<kiln-island>` lines where they stand on lines of their own. `indent` is set when\n\t * the `island` tag does: its line's indentation. `closing` is set when `endisland` does: its indentation, or null\n\t * when it shares that line with the `island` tag, and whether a line break followed it.\n\t */\n\t| {\n\t\t\ttype: \"Island\";\n\t\t\ttemplate: Expression;\n\t\t\twith: Expression | null;\n\t\t\tbody: Statement[];\n\t\t\tindent?: string;\n\t\t\tclosing?: { indent: string | null; newline: boolean };\n\t\t\tspan: Span;\n\t }\n\t| {\n\t\t\ttype: \"Macro\";\n\t\t\tname: string;\n\t\t\tparams: Param[];\n\t\t\tbody: Statement[];\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Import\"; template: string; alias: string; span: Span }\n\t| {\n\t\t\ttype: \"FromImport\";\n\t\t\ttemplate: string;\n\t\t\tnames: { name: string; alias: string; span: Span }[];\n\t\t\tspan: Span;\n\t }\n\t| { type: \"With\"; value: Expression; body: Statement[]; span: Span }\n\t/** A place other templates add content to with `add to`, filled when the render ends. */\n\t| { type: \"Outlet\"; name: string; span: Span }\n\t/** Closes the outlets reached so far, so a streamed render can send its output up to here. */\n\t| { type: \"Flush\"; span: Span }\n\t/** Content for the outlet named `outlet`. `once` adds it only the first time the tag runs in a render. */\n\t| {\n\t\t\ttype: \"Add\";\n\t\t\toutlet: string;\n\t\t\tonce: boolean;\n\t\t\tbody: Statement[];\n\t\t\tspan: Span;\n\t }\n\t/** `seconds` is the `for` value, or null. */\n\t| {\n\t\t\ttype: \"Cache\";\n\t\t\tkey: Expression;\n\t\t\tseconds: Expression | null;\n\t\t\tbody: Statement[];\n\t\t\tspan: Span;\n\t }\n\t| { type: \"Apply\"; filters: FilterCall[]; body: Statement[]; span: Span }\n\t| {\n\t\t\ttype: \"Autoescape\";\n\t\t\tstrategy: EscapeStrategy | false;\n\t\t\tbody: Statement[];\n\t\t\tspan: Span;\n\t };\n\nexport type TemplateNode = { type: \"Template\"; body: Statement[]; span: Span };\n\nexport type IslandStatement = Extract<Statement, { type: \"Island\" }>;\n\n/** The name of the default slot, filled by content outside any `fill`. */\nexport const DEFAULT_SLOT = \"default\";\n\nexport const ESCAPE_STRATEGIES: readonly EscapeStrategy[] = [\n\t\"html\",\n\t\"attr\",\n\t\"js\",\n\t\"css\",\n\t\"url\",\n];\n\n/** The value types a prop can declare, named as in the docs' table of types. */\nexport const TYPE_NAMES = [\n\t\"null\",\n\t\"boolean\",\n\t\"number\",\n\t\"string\",\n\t\"array\",\n\t\"hash\",\n\t\"set\",\n\t\"date\",\n\t\"markup\",\n\t\"object\",\n] as const;\n","import type { Span } from \"../source.js\";\n\nexport type TokenType =\n\t| \"text\"\n\t| \"outputOpen\"\n\t| \"outputClose\"\n\t| \"tagOpen\"\n\t| \"tagClose\"\n\t| \"name\"\n\t| \"number\"\n\t| \"string\"\n\t| \"punct\"\n\t| \"stringStart\"\n\t| \"stringEnd\"\n\t| \"interpOpen\"\n\t| \"interpClose\"\n\t| \"eof\";\n\n/**\n * One token. `value` is the decoded string for `string` and `text`, the digits without `_` for `number`, and the raw text otherwise.\n */\nexport type Token = {\n\ttype: TokenType;\n\tvalue: string;\n\tstart: number;\n\tend: number;\n};\n\nexport type LexProblem = { code: string; message: string; span: Span };\n\nexport type LexResult = {\n\ttokens: Token[];\n\tproblems: LexProblem[];\n\t/** Tags and comments on lines that hold nothing else, which the lexer removed, as start offset to end offset. */\n\tstandalone: Map<number, number>;\n\t/** Lines of template text that hold content, in source order. See `TextLine`. */\n\tlines: TextLine[];\n};\n\n/**\n * A line of template text that holds content, from its start to the end of its spaces and tabs. Leaves out blank lines, lines the lexer removed, lines whose start a `-` marker trimmed, and lines inside tags, outputs and comments.\n */\nexport type TextLine = { start: number; indentEnd: number };\n\nexport type TextPart = {\n\tkind: \"text\";\n\tstart: number;\n\tend: number;\n\t/** Output range after whitespace control. Starts equal to `start` and `end`. */\n\tfrom: number;\n\tto: number;\n};\n\nexport type DelimitedPart = {\n\tkind: \"output\" | \"tag\" | \"comment\";\n\tstart: number;\n\tend: number;\n\ttrimBefore: boolean;\n\ttrimAfter: boolean;\n\ttokens: Token[];\n};\n\nexport type Part = TextPart | DelimitedPart;\n\ntype ExpressionMode = \"output\" | \"tag\" | \"interp\";\n\n/** Deepest nesting of tags, expressions and string interpolations the lexer and parser accept. */\nexport const MAX_NESTING = 200;\n\n// Longest first, so `...` wins over `..` and `.`.\nconst PUNCTUATORS = [\n\t\"...\",\n\t\"?.\",\n\t\"??\",\n\t\"?:\",\n\t\"**\",\n\t\"//\",\n\t\"==\",\n\t\"!=\",\n\t\"<=\",\n\t\">=\",\n\t\"=>\",\n\t\"..\",\n\t\"+\",\n\t\"-\",\n\t\"*\",\n\t\"/\",\n\t\"%\",\n\t\"~\",\n\t\"<\",\n\t\">\",\n\t\"=\",\n\t\"(\",\n\t\")\",\n\t\"[\",\n\t\"]\",\n\t\"{\",\n\t\"}\",\n\t\",\",\n\t\":\",\n\t\".\",\n\t\"|\",\n\t\"?\",\n];\n\n/** Punctuators by their first character's code, longest first as in `PUNCTUATORS`, so lexing tries only a few. */\nconst PUNCTUATORS_BY_CHARACTER = new Map<number, string[]>();\nfor (const punct of PUNCTUATORS) {\n\tconst code = punct.charCodeAt(0);\n\tconst list = PUNCTUATORS_BY_CHARACTER.get(code);\n\tif (list) list.push(punct);\n\telse PUNCTUATORS_BY_CHARACTER.set(code, [punct]);\n}\n\n/**\n * The punctuator at `pos`, whose first two character codes are `code` and `next`, or null. Longest first, so `...` wins\n * over `..` and `.`, as in `PUNCTUATORS`.\n */\nconst punctuatorAt = (\n\ttext: string,\n\tpos: number,\n\tcode: number,\n\tnext: number,\n): string | null => {\n\tswitch (code) {\n\t\tcase 46: // .\n\t\t\tif (next === 46) return text.charCodeAt(pos + 2) === 46 ? \"...\" : \"..\";\n\t\t\treturn \".\";\n\t\tcase 63: // ?\n\t\t\treturn next === 46 ? \"?.\" : next === 63 ? \"??\" : next === 58 ? \"?:\" : \"?\";\n\t\tcase 42: // *\n\t\t\treturn next === 42 ? \"**\" : \"*\";\n\t\tcase 47: // /\n\t\t\treturn next === 47 ? \"//\" : \"/\";\n\t\tcase 61: // =\n\t\t\treturn next === 61 ? \"==\" : next === 62 ? \"=>\" : \"=\";\n\t\tcase 33: // !\n\t\t\treturn next === 61 ? \"!=\" : null;\n\t\tcase 60: // <\n\t\t\treturn next === 61 ? \"<=\" : \"<\";\n\t\tcase 62: // >\n\t\t\treturn next === 61 ? \">=\" : \">\";\n\t\tdefault: {\n\t\t\tconst single = SINGLE_PUNCTUATORS[code];\n\t\t\treturn single === undefined ? null : single;\n\t\t}\n\t}\n};\n\n/** Punctuators of one character that start no longer one, by character code. */\nconst SINGLE_PUNCTUATORS: (string | undefined)[] = [];\nfor (const punct of PUNCTUATORS) {\n\tconst code = punct.charCodeAt(0);\n\tif ((PUNCTUATORS_BY_CHARACTER.get(code) as string[]).length === 1) {\n\t\tSINGLE_PUNCTUATORS[code] = punct;\n\t}\n}\n\nconst CLOSED = { closed: true, trim: false } as const;\nconst CLOSED_TRIM = { closed: true, trim: true } as const;\nconst NOT_CLOSED = { closed: false, trim: false } as const;\n\nconst ESCAPES: Record<string, string> = {\n\tn: \"\\n\",\n\tr: \"\\r\",\n\tt: \"\\t\",\n\t\"\\\\\": \"\\\\\",\n\t\"'\": \"'\",\n\t'\"': '\"',\n};\n\nconst VERBATIM_END = /\\{%(-?)\\s*endverbatim\\s*(-?)%\\}/g;\n\nconst isInlineSpace = (code: number) =>\n\tcode === 32 || code === 9 || code === 13 || code === 11 || code === 12;\nconst isSpace = (code: number) => code === 10 || isInlineSpace(code);\nconst isNameStart = (code: number) =>\n\t(code >= 97 && code <= 122) || (code >= 65 && code <= 90) || code === 95;\nconst isDigit = (code: number) => code >= 48 && code <= 57;\nconst isNamePart = (code: number) => isNameStart(code) || isDigit(code);\n\n/**\n * Turns template source into tokens in one pass, then applies whitespace control.\n *\n * Text outside delimiters becomes `text` tokens. Comments produce no tokens. Lines holding only block tags and comments are removed, and `-` markers trim neighbouring whitespace.\n */\nexport const lex = (text: string): LexResult => new Lexer(text).run();\n\n/**\n * Splits source into text, outputs, tags and comments as written, before whitespace control. Tools such as the formatter use it. Comments have no tokens.\n */\nexport const scanParts = (\n\ttext: string,\n): { parts: Part[]; problems: LexProblem[] } => new Lexer(text).scan();\n\n/** Where a template's content starts: after a byte order mark, which is never content. */\nexport const contentStart = (text: string): number =>\n\ttext.charCodeAt(0) === 0xfeff ? 1 : 0;\n\nclass Lexer {\n\treadonly #text: string;\n\t#pos: number;\n\t/** How many string interpolations the lexer is inside. */\n\t#interpolations = 0;\n\t#tokens: Token[] = [];\n\treadonly #problems: LexProblem[] = [];\n\n\tconstructor(text: string) {\n\t\tthis.#text = text;\n\t\tthis.#pos = contentStart(text);\n\t}\n\n\tscan(): { parts: Part[]; problems: LexProblem[] } {\n\t\treturn { parts: this.#scanParts(), problems: this.#problems };\n\t}\n\n\trun(): LexResult {\n\t\tconst parts = this.#scanParts();\n\t\tapplyTrimMarkers(this.#text, parts);\n\t\tconst standalone = applyStandaloneLines(this.#text, parts);\n\t\tconst lines = textLines(this.#text, parts, standalone);\n\n\t\tconst tokens: Token[] = [];\n\t\tfor (const part of parts) {\n\t\t\tif (part.kind === \"text\") {\n\t\t\t\tif (part.from < part.to) {\n\t\t\t\t\ttokens.push({\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\tvalue: this.#text.slice(part.from, part.to),\n\t\t\t\t\t\tstart: part.from,\n\t\t\t\t\t\tend: part.to,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else if (part.kind !== \"comment\") {\n\t\t\t\tfor (const token of part.tokens) tokens.push(token);\n\t\t\t}\n\t\t}\n\t\ttokens.push({\n\t\t\ttype: \"eof\",\n\t\t\tvalue: \"\",\n\t\t\tstart: this.#text.length,\n\t\t\tend: this.#text.length,\n\t\t});\n\t\treturn { tokens, problems: this.#problems, standalone, lines };\n\t}\n\n\t#scanParts(): Part[] {\n\t\tconst text = this.#text;\n\t\tconst parts: Part[] = [];\n\t\tconst pushText = (start: number, end: number) => {\n\t\t\tif (end > start) {\n\t\t\t\tparts.push({ kind: \"text\", start, end, from: start, to: end });\n\t\t\t}\n\t\t};\n\n\t\twhile (this.#pos < text.length) {\n\t\t\tconst open = this.#findOpen(this.#pos);\n\t\t\tif (open === -1) {\n\t\t\t\tpushText(this.#pos, text.length);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tpushText(this.#pos, open);\n\n\t\t\tconst kind = text[open + 1];\n\t\t\tif (kind === \"#\") {\n\t\t\t\tparts.push(this.#scanComment(open));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst part = this.#scanDelimited(open, kind === \"{\" ? \"output\" : \"tag\");\n\t\t\tparts.push(part);\n\n\t\t\tconst inner = part.tokens;\n\t\t\tif (\n\t\t\t\tpart.kind === \"tag\" &&\n\t\t\t\tinner.length === 3 &&\n\t\t\t\tinner[1]?.type === \"name\" &&\n\t\t\t\tinner[1].value === \"verbatim\"\n\t\t\t) {\n\t\t\t\tthis.#scanVerbatim(part, parts);\n\t\t\t}\n\t\t}\n\t\treturn parts;\n\t}\n\n\t#findOpen(from: number): number {\n\t\tconst text = this.#text;\n\t\tlet index = text.indexOf(\"{\", from);\n\t\twhile (index !== -1) {\n\t\t\tconst next = text.charCodeAt(index + 1);\n\t\t\t// {{ {% {#\n\t\t\tif (next === 123 || next === 37 || next === 35) return index;\n\t\t\tindex = text.indexOf(\"{\", index + 1);\n\t\t}\n\t\treturn -1;\n\t}\n\n\t#scanComment(open: number): DelimitedPart {\n\t\tconst text = this.#text;\n\t\tconst close = text.indexOf(\"#}\", open + 2);\n\t\tconst trimBefore = text[open + 2] === \"-\";\n\t\tif (close === -1) {\n\t\t\tthis.#problem(\n\t\t\t\t\"unclosed-comment\",\n\t\t\t\t'Comment is missing its closing \"#}\"',\n\t\t\t\topen,\n\t\t\t\topen + 2,\n\t\t\t);\n\t\t\tthis.#pos = text.length;\n\t\t\treturn {\n\t\t\t\tkind: \"comment\",\n\t\t\t\tstart: open,\n\t\t\t\tend: text.length,\n\t\t\t\ttrimBefore,\n\t\t\t\ttrimAfter: false,\n\t\t\t\ttokens: [],\n\t\t\t};\n\t\t}\n\t\tthis.#pos = close + 2;\n\t\treturn {\n\t\t\tkind: \"comment\",\n\t\t\tstart: open,\n\t\t\tend: close + 2,\n\t\t\ttrimBefore,\n\t\t\ttrimAfter: close > open + 2 && text[close - 1] === \"-\",\n\t\t\ttokens: [],\n\t\t};\n\t}\n\n\t#scanDelimited(open: number, kind: \"output\" | \"tag\"): DelimitedPart {\n\t\tconst text = this.#text;\n\t\tconst trimBefore = text[open + 2] === \"-\";\n\t\tthis.#tokens = [\n\t\t\t{\n\t\t\t\ttype: kind === \"output\" ? \"outputOpen\" : \"tagOpen\",\n\t\t\t\tvalue: text.slice(open, open + (trimBefore ? 3 : 2)),\n\t\t\t\tstart: open,\n\t\t\t\tend: open + 2,\n\t\t\t},\n\t\t];\n\t\tthis.#pos = open + (trimBefore ? 3 : 2);\n\n\t\tconst closeStart = this.#pos;\n\t\tconst { trim, closed } = this.#lexExpression(kind);\n\t\tconst end = this.#pos;\n\t\tif (!closed) {\n\t\t\tthis.#problem(\n\t\t\t\t\"unclosed-tag\",\n\t\t\t\tkind === \"output\"\n\t\t\t\t\t? 'Output is missing its closing \"}}\"'\n\t\t\t\t\t: 'Tag is missing its closing \"%}\"',\n\t\t\t\topen,\n\t\t\t\topen + 2,\n\t\t\t);\n\t\t}\n\t\tthis.#tokens.push({\n\t\t\ttype: kind === \"output\" ? \"outputClose\" : \"tagClose\",\n\t\t\tvalue: closed ? text.slice(trim ? end - 3 : end - 2, end) : \"\",\n\t\t\tstart: closed ? end - 2 : Math.max(closeStart, end),\n\t\t\tend,\n\t\t});\n\t\treturn {\n\t\t\tkind,\n\t\t\tstart: open,\n\t\t\tend,\n\t\t\ttrimBefore,\n\t\t\ttrimAfter: trim,\n\t\t\ttokens: this.#tokens,\n\t\t};\n\t}\n\n\t/** Treats everything up to `{% endverbatim %}` as text. */\n\t#scanVerbatim(tag: DelimitedPart, parts: Part[]): void {\n\t\tconst text = this.#text;\n\t\tVERBATIM_END.lastIndex = this.#pos;\n\t\tconst match = VERBATIM_END.exec(text);\n\t\tif (!match) {\n\t\t\tthis.#problem(\n\t\t\t\t\"unclosed-block\",\n\t\t\t\t'\"verbatim\" is missing its \"endverbatim\" tag',\n\t\t\t\ttag.start,\n\t\t\t\ttag.end,\n\t\t\t);\n\t\t\tparts.push({\n\t\t\t\tkind: \"text\",\n\t\t\t\tstart: this.#pos,\n\t\t\t\tend: text.length,\n\t\t\t\tfrom: this.#pos,\n\t\t\t\tto: text.length,\n\t\t\t});\n\t\t\tthis.#pos = text.length;\n\t\t\treturn;\n\t\t}\n\n\t\tconst start = match.index;\n\t\tconst end = start + match[0].length;\n\t\tif (start > this.#pos) {\n\t\t\tparts.push({\n\t\t\t\tkind: \"text\",\n\t\t\t\tstart: this.#pos,\n\t\t\t\tend: start,\n\t\t\t\tfrom: this.#pos,\n\t\t\t\tto: start,\n\t\t\t});\n\t\t}\n\t\tconst nameStart = text.indexOf(\"endverbatim\", start);\n\t\tconst trimBefore = match[1] === \"-\";\n\t\tconst trimAfter = match[2] === \"-\";\n\t\tparts.push({\n\t\t\tkind: \"tag\",\n\t\t\tstart,\n\t\t\tend,\n\t\t\ttrimBefore,\n\t\t\ttrimAfter,\n\t\t\t// Token values include trim markers, as `#scanDelimited` writes them.\n\t\t\ttokens: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"tagOpen\",\n\t\t\t\t\tvalue: trimBefore ? \"{%-\" : \"{%\",\n\t\t\t\t\tstart,\n\t\t\t\t\tend: start + 2,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: \"name\",\n\t\t\t\t\tvalue: \"endverbatim\",\n\t\t\t\t\tstart: nameStart,\n\t\t\t\t\tend: nameStart + 11,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: \"tagClose\",\n\t\t\t\t\tvalue: trimAfter ? \"-%}\" : \"%}\",\n\t\t\t\t\tstart: end - 2,\n\t\t\t\t\tend,\n\t\t\t\t},\n\t\t\t],\n\t\t});\n\t\tthis.#pos = end;\n\t}\n\n\t/**\n\t * Lexes expression tokens until the closing delimiter for `mode`.\n\t *\n\t * `closed` is false when the source ended, or a new tag started, before the delimiter.\n\t */\n\t#lexExpression(mode: ExpressionMode): { closed: boolean; trim: boolean } {\n\t\tconst text = this.#text;\n\t\tconst length = text.length;\n\t\tconst tokens = this.#tokens;\n\t\tlet depth = 0;\n\t\t// The position lives in a local while lexing names and punctuators, and in `#pos` around everything else.\n\t\tlet pos = this.#pos;\n\n\t\tfor (;;) {\n\t\t\twhile (pos < length && isSpace(text.charCodeAt(pos))) pos++;\n\t\t\tif (pos >= length) {\n\t\t\t\tthis.#pos = pos;\n\t\t\t\treturn NOT_CLOSED;\n\t\t\t}\n\n\t\t\tconst code = text.charCodeAt(pos);\n\t\t\tconst next = text.charCodeAt(pos + 1);\n\n\t\t\tif (mode === \"tag\") {\n\t\t\t\t// -%} or %}\n\t\t\t\tif (code === 45 && next === 37 && text.charCodeAt(pos + 2) === 125) {\n\t\t\t\t\tthis.#pos = pos + 3;\n\t\t\t\t\treturn CLOSED_TRIM;\n\t\t\t\t}\n\t\t\t\tif (code === 37 && next === 125) {\n\t\t\t\t\tthis.#pos = pos + 2;\n\t\t\t\t\treturn CLOSED;\n\t\t\t\t}\n\t\t\t} else if (mode === \"output\" && depth === 0) {\n\t\t\t\t// -}} or }}\n\t\t\t\tif (code === 45 && next === 125 && text.charCodeAt(pos + 2) === 125) {\n\t\t\t\t\tthis.#pos = pos + 3;\n\t\t\t\t\treturn CLOSED_TRIM;\n\t\t\t\t}\n\t\t\t\tif (code === 125 && next === 125) {\n\t\t\t\t\tthis.#pos = pos + 2;\n\t\t\t\t\treturn CLOSED;\n\t\t\t\t}\n\t\t\t} else if (mode === \"interp\" && depth === 0 && code === 125) {\n\t\t\t\ttokens.push({\n\t\t\t\t\ttype: \"interpClose\",\n\t\t\t\t\tvalue: \"}\",\n\t\t\t\t\tstart: pos,\n\t\t\t\t\tend: pos + 1,\n\t\t\t\t});\n\t\t\t\tthis.#pos = pos + 1;\n\t\t\t\treturn CLOSED;\n\t\t\t}\n\n\t\t\t// A new delimiter means this one was never closed. None of these pairs is valid inside an expression.\n\t\t\tif (code === 123 && (next === 123 || next === 37 || next === 35)) {\n\t\t\t\tthis.#pos = pos;\n\t\t\t\treturn NOT_CLOSED;\n\t\t\t}\n\t\t\tif (mode === \"interp\" && code === 37 && next === 125) {\n\t\t\t\tthis.#pos = pos;\n\t\t\t\treturn NOT_CLOSED;\n\t\t\t}\n\n\t\t\tif (isNameStart(code)) {\n\t\t\t\tlet end = pos + 1;\n\t\t\t\twhile (end < length && isNamePart(text.charCodeAt(end))) end++;\n\t\t\t\ttokens.push({\n\t\t\t\t\ttype: \"name\",\n\t\t\t\t\tvalue: text.slice(pos, end),\n\t\t\t\t\tstart: pos,\n\t\t\t\t\tend,\n\t\t\t\t});\n\t\t\t\tpos = end;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isDigit(code)) {\n\t\t\t\tthis.#pos = pos;\n\t\t\t\tthis.#lexNumber();\n\t\t\t\tpos = this.#pos;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (code === 34 || code === 39) {\n\t\t\t\tthis.#pos = pos;\n\t\t\t\tthis.#lexString();\n\t\t\t\tpos = this.#pos;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst punct = punctuatorAt(text, pos, code, next);\n\t\t\tif (punct !== null) {\n\t\t\t\tif (code === 123) depth++;\n\t\t\t\telse if (code === 125 && depth > 0) depth--;\n\t\t\t\ttokens.push({\n\t\t\t\t\ttype: \"punct\",\n\t\t\t\t\tvalue: punct,\n\t\t\t\t\tstart: pos,\n\t\t\t\t\tend: pos + punct.length,\n\t\t\t\t});\n\t\t\t\tpos += punct.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// A whole code point, so a character outside the Basic Multilingual Plane is one problem, not two halves.\n\t\t\tconst character = String.fromCodePoint(text.codePointAt(pos) as number);\n\t\t\tthis.#problem(\n\t\t\t\t\"unexpected-character\",\n\t\t\t\t`Unexpected character \"${character}\"`,\n\t\t\t\tpos,\n\t\t\t\tpos + character.length,\n\t\t\t);\n\t\t\tpos += character.length;\n\t\t}\n\t}\n\n\t#lexNumber(): void {\n\t\tconst text = this.#text;\n\t\tconst start = this.#pos;\n\t\tconst previous = this.#tokens[this.#tokens.length - 1];\n\t\t// After `.` or `?.`, only an integer can follow, so `items.0.1` reads two indexes.\n\t\tconst integerOnly =\n\t\t\tprevious?.type === \"punct\" &&\n\t\t\t(previous.value === \".\" || previous.value === \"?.\");\n\n\t\tconst readDigits = () => {\n\t\t\twhile (this.#pos < text.length) {\n\t\t\t\tconst code = text.charCodeAt(this.#pos);\n\t\t\t\tif (isDigit(code)) this.#pos++;\n\t\t\t\telse if (code === 95 && isDigit(text.charCodeAt(this.#pos + 1))) {\n\t\t\t\t\tthis.#pos++;\n\t\t\t\t} else break;\n\t\t\t}\n\t\t};\n\n\t\treadDigits();\n\t\tif (\n\t\t\t!integerOnly &&\n\t\t\ttext[this.#pos] === \".\" &&\n\t\t\tisDigit(text.charCodeAt(this.#pos + 1))\n\t\t) {\n\t\t\tthis.#pos++;\n\t\t\treadDigits();\n\t\t}\n\t\tconst raw = text.slice(start, this.#pos);\n\t\tthis.#push(\"number\", raw.replaceAll(\"_\", \"\"), start, this.#pos);\n\t}\n\n\t#lexString(): void {\n\t\tconst text = this.#text;\n\t\tconst start = this.#pos;\n\t\tconst quote = text[start];\n\t\tlet value = \"\";\n\t\tlet segmentStart = start;\n\t\tlet interpolated = false;\n\t\tthis.#pos++;\n\n\t\twhile (this.#pos < text.length) {\n\t\t\tconst char = text[this.#pos] as string;\n\n\t\t\tif (char === quote) {\n\t\t\t\tthis.#pos++;\n\t\t\t\tif (interpolated) {\n\t\t\t\t\tif (value !== \"\") {\n\t\t\t\t\t\tthis.#push(\"string\", value, segmentStart, this.#pos - 1);\n\t\t\t\t\t}\n\t\t\t\t\tthis.#push(\"stringEnd\", quote, this.#pos - 1, this.#pos);\n\t\t\t\t} else {\n\t\t\t\t\tthis.#push(\"string\", value, start, this.#pos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (char === \"\\\\\") {\n\t\t\t\tvalue += this.#readEscape(quote as string);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (quote === '\"' && char === \"#\" && text[this.#pos + 1] === \"{\") {\n\t\t\t\tif (!interpolated) {\n\t\t\t\t\tinterpolated = true;\n\t\t\t\t\tthis.#push(\"stringStart\", quote, start, start + 1);\n\t\t\t\t}\n\t\t\t\tif (value !== \"\") {\n\t\t\t\t\tthis.#push(\"string\", value, segmentStart, this.#pos);\n\t\t\t\t\tvalue = \"\";\n\t\t\t\t}\n\t\t\t\tthis.#push(\"interpOpen\", \"#{\", this.#pos, this.#pos + 2);\n\t\t\t\tthis.#pos += 2;\n\t\t\t\tconst interpStart = this.#pos;\n\t\t\t\t// Each level of interpolation recurses, so stop before deeply nested strings overflow the stack.\n\t\t\t\tif (this.#interpolations === MAX_NESTING) {\n\t\t\t\t\tthis.#problem(\n\t\t\t\t\t\t\"too-deep\",\n\t\t\t\t\t\t`Template is nested more than ${MAX_NESTING} levels deep`,\n\t\t\t\t\t\tinterpStart - 2,\n\t\t\t\t\t\tinterpStart,\n\t\t\t\t\t);\n\t\t\t\t\tthis.#skipInterpolation();\n\t\t\t\t\tsegmentStart = this.#pos;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis.#interpolations++;\n\t\t\t\tconst { closed } = this.#lexExpression(\"interp\");\n\t\t\t\tthis.#interpolations--;\n\t\t\t\tif (!closed) {\n\t\t\t\t\tthis.#problem(\n\t\t\t\t\t\t\"unclosed-interpolation\",\n\t\t\t\t\t\t'Interpolation is missing its closing \"}\"',\n\t\t\t\t\t\tinterpStart - 2,\n\t\t\t\t\t\tinterpStart,\n\t\t\t\t\t);\n\t\t\t\t\tthis.#push(\"interpClose\", \"\", this.#pos, this.#pos);\n\t\t\t\t\tthis.#push(\"stringEnd\", \"\", this.#pos, this.#pos);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsegmentStart = this.#pos;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvalue += char;\n\t\t\tthis.#pos++;\n\t\t}\n\n\t\tthis.#problem(\n\t\t\t\"unclosed-string\",\n\t\t\t\"String is missing its closing quote\",\n\t\t\tstart,\n\t\t\tstart + 1,\n\t\t);\n\t\tif (interpolated) {\n\t\t\tif (value !== \"\") this.#push(\"string\", value, segmentStart, this.#pos);\n\t\t\tthis.#push(\"stringEnd\", \"\", this.#pos, this.#pos);\n\t\t} else {\n\t\t\tthis.#push(\"string\", value, start, this.#pos);\n\t\t}\n\t}\n\n\t/** Skips the rest of an interpolation without lexing it, up to the `}` that balances its `#{`. */\n\t#skipInterpolation(): void {\n\t\tconst text = this.#text;\n\t\tlet depth = 0;\n\t\twhile (this.#pos < text.length) {\n\t\t\tconst char = text[this.#pos++];\n\t\t\tif (char === \"{\") depth++;\n\t\t\telse if (char === \"}\" && depth-- === 0) {\n\t\t\t\tthis.#push(\"interpClose\", \"}\", this.#pos - 1, this.#pos);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Reads a backslash escape. `\\#{` is only an escape in double-quoted strings, where `#{` would start interpolation. */\n\t#readEscape(quote: string): string {\n\t\tconst text = this.#text;\n\t\tconst start = this.#pos;\n\t\tconst next = text[start + 1];\n\t\tif (next === undefined) {\n\t\t\tthis.#pos++;\n\t\t\treturn \"\";\n\t\t}\n\t\tif (next === \"#\" && quote === '\"' && text[start + 2] === \"{\") {\n\t\t\tthis.#pos += 2;\n\t\t\treturn \"#\";\n\t\t}\n\t\tconst simple = ESCAPES[next];\n\t\tif (simple !== undefined) {\n\t\t\tthis.#pos += 2;\n\t\t\treturn simple;\n\t\t}\n\t\tif (next === \"u\" && text[start + 2] === \"{\") {\n\t\t\t// Six hex digits at most, so look no further than the seventh character for the brace.\n\t\t\tconst brace = text.slice(start + 3, start + 10).indexOf(\"}\");\n\t\t\tconst close = brace === -1 ? -1 : start + 3 + brace;\n\t\t\tconst hex = close === -1 ? \"\" : text.slice(start + 3, close);\n\t\t\tif (/^[0-9a-fA-F]{1,6}$/.test(hex)) {\n\t\t\t\tconst code = Number.parseInt(hex, 16);\n\t\t\t\tif (code <= 0x10ffff) {\n\t\t\t\t\tthis.#pos = close + 1;\n\t\t\t\t\treturn String.fromCodePoint(code);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.#problem(\n\t\t\t\"invalid-escape\",\n\t\t\t`Unknown escape sequence \"\\\\${next}\"`,\n\t\t\tstart,\n\t\t\tstart + 2,\n\t\t);\n\t\tthis.#pos += 2;\n\t\treturn next;\n\t}\n\n\t#push(type: TokenType, value: string, start: number, end: number): void {\n\t\tthis.#tokens.push({ type, value, start, end });\n\t}\n\n\t#problem(code: string, message: string, start: number, end: number): void {\n\t\tthis.#problems.push({ code, message, span: { start, end } });\n\t}\n}\n\n/** Applies `-` markers, which remove all whitespace on their side. */\nconst applyTrimMarkers = (text: string, parts: Part[]): void => {\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i] as Part;\n\t\tif (part.kind === \"text\") continue;\n\n\t\tconst previous = parts[i - 1];\n\t\tif (part.trimBefore && previous?.kind === \"text\") {\n\t\t\tlet end = previous.end;\n\t\t\twhile (end > previous.start && isSpace(text.charCodeAt(end - 1))) end--;\n\t\t\tprevious.to = Math.min(previous.to, end);\n\t\t}\n\t\tconst next = parts[i + 1];\n\t\tif (part.trimAfter && next?.kind === \"text\") {\n\t\t\tlet start = next.start;\n\t\t\twhile (start < next.end && isSpace(text.charCodeAt(start))) start++;\n\t\t\tnext.from = Math.max(next.from, start);\n\t\t}\n\t}\n};\n\nconst isInlineBlank = (text: string, start: number, end: number): boolean => {\n\tfor (let i = start; i < end; i++) {\n\t\tif (!isInlineSpace(text.charCodeAt(i))) return false;\n\t}\n\treturn true;\n};\n\n/**\n * The first line feed from `start` up to `end`, or -1. The search stops at `end`, unlike `indexOf`, so a template with\n * many tags on one long line stays linear.\n */\nconst newlineIn = (text: string, start: number, end: number): number => {\n\tfor (let i = start; i < end; i++) {\n\t\tif (text.charCodeAt(i) === 10) return i;\n\t}\n\treturn -1;\n};\n\n/** The last line feed from `start` up to `end`, or -1. Stops at `start`, as `newlineIn` stops at `end`. */\nconst lastNewlineIn = (text: string, start: number, end: number): number => {\n\tfor (let i = end - 1; i >= start; i--) {\n\t\tif (text.charCodeAt(i) === 10) return i;\n\t}\n\treturn -1;\n};\n\n/**\n * Removes lines that hold only block tags and comments, including their indentation and line ending.\n *\n * Decisions use the original text, so they do not depend on what trim markers removed. Returns the start of each tag and comment it removed.\n */\nconst applyStandaloneLines = (\n\ttext: string,\n\tparts: Part[],\n): Map<number, number> => {\n\tconst removed = new Map<number, number>();\n\tconst isBlockLike = (part: Part | undefined) =>\n\t\tpart !== undefined && (part.kind === \"tag\" || part.kind === \"comment\");\n\n\tlet i = 0;\n\twhile (i < parts.length) {\n\t\tif (!isBlockLike(parts[i])) {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Group tags on the same line, separated only by spaces.\n\t\tlet last = i;\n\t\tfor (;;) {\n\t\t\tconst next = parts[last + 1];\n\t\t\tif (isBlockLike(next)) {\n\t\t\t\tlast++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tnext?.kind === \"text\" &&\n\t\t\t\tisInlineBlank(text, next.start, next.end) &&\n\t\t\t\tisBlockLike(parts[last + 2])\n\t\t\t) {\n\t\t\t\tlast += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tlet standalone = true;\n\t\tlet cutBefore = -1;\n\t\tconst previous = parts[i - 1];\n\t\tif (previous) {\n\t\t\tif (previous.kind !== \"text\") standalone = false;\n\t\t\telse {\n\t\t\t\tconst newline = lastNewlineIn(text, previous.start, previous.end);\n\t\t\t\tif (newline !== -1) {\n\t\t\t\t\tif (isInlineBlank(text, newline + 1, previous.end)) {\n\t\t\t\t\t\tcutBefore = newline + 1;\n\t\t\t\t\t} else standalone = false;\n\t\t\t\t} else if (\n\t\t\t\t\ti - 1 === 0 &&\n\t\t\t\t\tisInlineBlank(text, previous.start, previous.end)\n\t\t\t\t) {\n\t\t\t\t\tcutBefore = previous.start;\n\t\t\t\t} else standalone = false;\n\t\t\t}\n\t\t}\n\n\t\tlet cutAfter = -1;\n\t\tconst next = parts[last + 1];\n\t\tif (standalone && next) {\n\t\t\tif (next.kind !== \"text\") standalone = false;\n\t\t\telse {\n\t\t\t\tconst newline = newlineIn(text, next.start, next.end);\n\t\t\t\tif (newline !== -1) {\n\t\t\t\t\tif (isInlineBlank(text, next.start, newline)) {\n\t\t\t\t\t\tcutAfter = newline + 1;\n\t\t\t\t\t} else standalone = false;\n\t\t\t\t} else if (\n\t\t\t\t\tlast + 1 === parts.length - 1 &&\n\t\t\t\t\tisInlineBlank(text, next.start, next.end)\n\t\t\t\t) {\n\t\t\t\t\tcutAfter = next.end;\n\t\t\t\t} else standalone = false;\n\t\t\t}\n\t\t}\n\n\t\tif (standalone) {\n\t\t\tif (previous?.kind === \"text\") {\n\t\t\t\tprevious.to = Math.min(previous.to, cutBefore);\n\t\t\t}\n\t\t\tfor (let k = i; k <= last; k++) {\n\t\t\t\tconst part = parts[k] as Part;\n\t\t\t\tif (part.kind === \"text\") part.from = part.to;\n\t\t\t\telse removed.set(part.start, part.end);\n\t\t\t}\n\t\t\tif (next?.kind === \"text\") next.from = Math.max(next.from, cutAfter);\n\t\t}\n\t\ti = last + 1;\n\t}\n\treturn removed;\n};\n\n/** Finds the lines of text that hold content. See `TextLine`. */\nconst textLines = (\n\ttext: string,\n\tparts: Part[],\n\tremoved: ReadonlyMap<number, number>,\n): TextLine[] => {\n\tconst lines: TextLine[] = [];\n\tconst add = (start: number) => {\n\t\tlet indentEnd = start;\n\t\twhile (text[indentEnd] === \" \" || text[indentEnd] === \"\\t\") indentEnd++;\n\t\tconst next = text[indentEnd];\n\t\tif (next === undefined || next === \"\\n\" || next === \"\\r\") return;\n\t\tif (removed.has(indentEnd)) return;\n\t\tlines.push({ start, indentEnd });\n\t};\n\tfor (const part of parts) {\n\t\tif (part.kind !== \"text\") continue;\n\t\tfor (\n\t\t\tlet newline = newlineIn(text, part.start, part.end);\n\t\t\tnewline !== -1;\n\t\t\tnewline = newlineIn(text, newline + 1, part.end)\n\t\t) {\n\t\t\tconst start = newline + 1;\n\t\t\t// A `-` marker trimmed the line break or the whole line.\n\t\t\tif (start < part.from || start > part.to) continue;\n\t\t\tadd(start);\n\t\t}\n\t}\n\treturn lines;\n};\n","import { contentStart, type LexResult, type TextLine } from \"../lexer/lexer.js\";\nimport type { IslandStatement, Statement, TemplateNode } from \"./ast.js\";\n\n/** The statements inside one tag, with where the tag starts and where its whole span ends. */\ntype Body = {\n\topen: number;\n\tend: number;\n\tlists: Statement[][];\n\t/** Keeps every line's indentation, for content written back inside a wrapper, such as an island's fallback. */\n\tkeep?: boolean;\n};\n\n/** The bodies a statement holds. Branches share their tag's body. A component's fills are bodies of their own, inside the component's. */\nconst bodiesOf = (node: Statement): Body[] => {\n\tconst own = (lists: Statement[][]): Body => ({\n\t\topen: node.span.start,\n\t\tend: node.span.end,\n\t\tlists,\n\t});\n\tswitch (node.type) {\n\t\tcase \"If\":\n\t\t\treturn [\n\t\t\t\town([\n\t\t\t\t\t...node.branches.map((branch) => branch.body),\n\t\t\t\t\tnode.alternate ?? [],\n\t\t\t\t]),\n\t\t\t];\n\t\tcase \"For\":\n\t\t\treturn [own([node.body, node.alternate ?? []])];\n\t\tcase \"Component\":\n\t\t\treturn [\n\t\t\t\t...node.fills.map((fill) => ({\n\t\t\t\t\topen: fill.span.start,\n\t\t\t\t\tend: fill.span.end,\n\t\t\t\t\tlists: [fill.body],\n\t\t\t\t})),\n\t\t\t\town([node.body, ...node.fills.map((fill) => fill.body)]),\n\t\t\t];\n\t\tcase \"Island\":\n\t\t\treturn [{ ...own([node.body]), keep: true }];\n\t\tcase \"Block\":\n\t\tcase \"Slot\":\n\t\tcase \"Add\":\n\t\tcase \"SetBlock\":\n\t\tcase \"Macro\":\n\t\tcase \"Cache\":\n\t\tcase \"With\":\n\t\tcase \"Apply\":\n\t\tcase \"Autoescape\":\n\t\t\treturn [own([node.body])];\n\t\tdefault:\n\t\t\treturn NO_BODIES;\n\t}\n};\n\nconst NO_BODIES: Body[] = [];\n\n/** The statement lists inside a statement, each once. Only a component's fills appear in more than one body. */\nconst childLists = (bodies: Body[]): Iterable<Statement[]> =>\n\tbodies.length === 1\n\t\t? (bodies[0] as Body).lists\n\t\t: new Set(bodies.flatMap((body) => body.lists));\n\n/** The index of the first item whose key is at least `value`, in a list sorted by that key. */\nconst firstAtLeast = <T>(\n\titems: readonly T[],\n\tvalue: number,\n\tkey: (item: T) => number,\n): number => {\n\tlet low = 0;\n\tlet high = items.length;\n\twhile (low < high) {\n\t\tconst middle = (low + high) >>> 1;\n\t\tif (key(items[middle] as T) < value) low = middle + 1;\n\t\telse high = middle;\n\t}\n\treturn low;\n};\n\n/**\n * Finds `<pre>` and `<textarea>` tags, and the HTML comments, scripts and styles to skip, whose `<pre` is not a tag.\n * Each region runs to its end, or to the end of the source when it is not closed.\n */\nconst MARKUP =\n\t/<!--[\\s\\S]*?(?:-->|$)|<(script|style)(?=[\\s/>])[\\s\\S]*?(?:<\\/\\1\\s*>|$)|<(\\/?)(pre|textarea)(?=[\\s/>])/gi;\n\nconst MAY_PREFORMAT = /<(?:pre|textarea)/i;\n\n/** Where `<pre>` and `<textarea>` elements start and end in the template's text, whose whitespace is content. */\nconst preformatted = (\n\ttext: string,\n\ttextTokens: LexResult[\"tokens\"],\n): [number, number][] => {\n\t// Most templates have neither, which one scan finds.\n\tif (!MAY_PREFORMAT.test(text)) return [];\n\t// The template's text with everything else, such as tags and outputs, blanked out. Offsets stay the same, and the\n\t// filler is not a space, so `<pre{{ x }}>` is still not a `<pre>` tag.\n\tlet visible = \"\";\n\tfor (const token of textTokens) {\n\t\tvisible += \"\\0\".repeat(token.start - visible.length);\n\t\tvisible += text.slice(token.start, token.end);\n\t}\n\tconst ranges: [number, number][] = [];\n\tlet open: { name: string; start: number } | null = null;\n\tMARKUP.lastIndex = 0;\n\tfor (let match = MARKUP.exec(visible); match; match = MARKUP.exec(visible)) {\n\t\tconst tag = match[3];\n\t\tif (tag === undefined) continue;\n\t\tconst name = tag.toLowerCase();\n\t\tif (open === null && match[2] === \"\") open = { name, start: match.index };\n\t\telse if (open?.name === name && match[2] === \"/\") {\n\t\t\tranges.push([open.start, match.index]);\n\t\t\topen = null;\n\t\t}\n\t}\n\tif (open) ranges.push([open.start, text.length]);\n\treturn ranges;\n};\n\n/**\n * Removes the extra indentation inside tags that stand on their own line: the spaces and tabs that every content line\n * inside shares, beyond the tag's own indentation. It happens when compiling, so rendering is no slower.\n *\n * Also sets the indentation of `islands` whose tags stand on lines of their own, since a deferred island writes its\n * tags back as `<kiln-island>` lines. See `IslandStatement`.\n *\n * Lines inside `<pre>` and `<textarea>` keep their whitespace. Amounts come from the source alone, so nested tags each\n * remove their own step whatever order they are visited in. Then the text nodes holding those offsets are rebuilt.\n */\nexport const removeIndentation = (\n\tast: TemplateNode,\n\ttext: string,\n\t{ tokens, standalone, lines }: LexResult,\n\tislands: readonly IslandStatement[],\n): void => {\n\tconst textTokens = tokens.filter((token) => token.type === \"text\");\n\tconst pre = preformatted(text, textTokens);\n\tconst inPre = (offset: number): boolean => {\n\t\tconst range = pre[firstAtLeast(pre, offset, (range) => range[1])];\n\t\treturn range !== undefined && range[0] < offset;\n\t};\n\tconst textLines =\n\t\tpre.length > 0 ? lines.filter((line) => !inPre(line.start)) : lines;\n\n\t// The first line starts after any byte order mark, as the lexer's lines do.\n\tconst lineStart = (offset: number): number =>\n\t\ttext.lastIndexOf(\"\\n\", offset - 1) + 1 || contentStart(text);\n\tconst lineOf = (offset: number): TextLine => {\n\t\tconst start = lineStart(offset);\n\t\tlet indentEnd = start;\n\t\twhile (text[indentEnd] === \" \" || text[indentEnd] === \"\\t\") indentEnd++;\n\t\treturn { start, indentEnd };\n\t};\n\n\t// Island tags on lines of their own are written back as lines, so they count as content lines for the tags around them.\n\tconst islandLines: {\n\t\tnode: IslandStatement;\n\t\topen: TextLine | null;\n\t\tend: TextLine | null;\n\t}[] = [];\n\tfor (const node of islands) {\n\t\tif (inPre(node.span.start)) continue;\n\t\tconst end = text.lastIndexOf(\"{%\", node.span.end - 1);\n\t\tconst open = standalone.has(node.span.start)\n\t\t\t? lineOf(node.span.start)\n\t\t\t: null;\n\t\tconst close = standalone.has(end) ? lineOf(end) : null;\n\t\tif (open || close) islandLines.push({ node, open, end: close });\n\t}\n\tconst contentLines =\n\t\tislandLines.length > 0\n\t\t\t? [\n\t\t\t\t\t...textLines,\n\t\t\t\t\t...islandLines.flatMap((item) =>\n\t\t\t\t\t\t[item.open, item.end].filter((line) => line !== null),\n\t\t\t\t\t),\n\t\t\t\t].sort((a, b) => a.start - b.start)\n\t\t\t: textLines;\n\n\t// Source ranges to drop, as [start, end).\n\tconst cuts: [number, number][] = [];\n\n\tconst indentOf = (offset: number): string => {\n\t\tconst line = lineOf(offset);\n\t\treturn text.slice(line.start, line.indentEnd);\n\t};\n\n\tconst trim = (body: Body): void => {\n\t\tif (body.keep) return;\n\t\tconst openEnd = standalone.get(body.open);\n\t\tif (openEnd === undefined) return;\n\t\tconst newline = text.indexOf(\"\\n\", openEnd);\n\t\tif (newline === -1) return;\n\t\t// Lines from the one after the tag up to the end tag, which starts at the span's last `{%`.\n\t\tconst to = text.lastIndexOf(\"{%\", body.end - 1);\n\t\tconst first = firstAtLeast(contentLines, newline + 1, (line) => line.start);\n\t\tconst last = firstAtLeast(contentLines, to, (line) => line.start);\n\t\tif (first >= last) return;\n\n\t\tconst own = indentOf(body.open);\n\t\tlet shared = Infinity;\n\t\tconst firstLine = contentLines[first] as TextLine;\n\t\tfor (let i = first; i < last; i++) {\n\t\t\tconst line = contentLines[i] as TextLine;\n\t\t\tlet length = 0;\n\t\t\twhile (\n\t\t\t\tlength < line.indentEnd - line.start &&\n\t\t\t\ttext[line.start + length] === text[firstLine.start + length]\n\t\t\t) {\n\t\t\t\tlength++;\n\t\t\t}\n\t\t\tshared = Math.min(shared, length);\n\t\t}\n\t\tif (shared <= own.length) return;\n\t\tif (text.slice(firstLine.start, firstLine.start + own.length) !== own)\n\t\t\treturn;\n\t\tfor (let i = first; i < last; i++) {\n\t\t\tconst line = contentLines[i] as TextLine;\n\t\t\tcuts.push([line.start + own.length, line.start + shared]);\n\t\t}\n\t};\n\n\tconst visit = (list: Statement[]): void => {\n\t\tfor (const node of list) {\n\t\t\tconst bodies = bodiesOf(node);\n\t\t\tif (bodies.length === 0) continue;\n\t\t\tfor (const child of childLists(bodies)) visit(child);\n\t\t\tfor (const body of bodies) trim(body);\n\t\t}\n\t};\n\tvisit(ast.body);\n\n\t// Tags indented unusually can cut overlapping ranges of one line. Merging them keeps both ends in order for the searches below.\n\tcuts.sort((a, b) => a[0] - b[0]);\n\tconst merged: [number, number][] = [];\n\tfor (const range of cuts) {\n\t\tconst previous = merged[merged.length - 1];\n\t\tif (previous && range[0] <= previous[1]) {\n\t\t\tprevious[1] = Math.max(previous[1], range[1]);\n\t\t} else merged.push(range);\n\t}\n\n\t/** The source from `start` to `end`, without the cut ranges. */\n\tconst uncut = (start: number, end: number): string => {\n\t\tlet out = \"\";\n\t\tlet at = start;\n\t\tfor (\n\t\t\tlet i = firstAtLeast(merged, start, (range) => range[1] - 1);\n\t\t\ti < merged.length;\n\t\t\ti++\n\t\t) {\n\t\t\tconst [from, to] = merged[i] as [number, number];\n\t\t\tif (from >= end) break;\n\t\t\tout += text.slice(at, Math.max(at, from));\n\t\t\tat = Math.max(at, to);\n\t\t}\n\t\treturn out + text.slice(Math.min(at, end), end);\n\t};\n\n\tfor (const { node, open, end } of islandLines) {\n\t\tif (open) node.indent = uncut(open.start, open.indentEnd);\n\t\tif (end) {\n\t\t\tconst sameLine = open !== null && end.start === open.start;\n\t\t\tnode.closing = {\n\t\t\t\tindent: sameLine ? null : uncut(end.start, end.indentEnd),\n\t\t\t\tnewline: text.includes(\"\\n\", node.span.end),\n\t\t\t};\n\t\t}\n\t}\n\tif (merged.length === 0) return;\n\n\tconst hasCut = (start: number, end: number): boolean => {\n\t\tconst range = merged[firstAtLeast(merged, start, (range) => range[1] - 1)];\n\t\treturn range !== undefined && range[0] < end;\n\t};\n\n\t// A text token's value is its source slice, and a text node joins one or more tokens, so nodes are rebuilt token by token.\n\tconst rewrite = (list: Statement[]): void => {\n\t\tfor (const node of list) {\n\t\t\tif (node.type === \"Text\" && hasCut(node.span.start, node.span.end)) {\n\t\t\t\tlet value = \"\";\n\t\t\t\tfor (\n\t\t\t\t\tlet i = firstAtLeast(textTokens, node.span.start, (t) => t.start);\n\t\t\t\t\ti < textTokens.length;\n\t\t\t\t\ti++\n\t\t\t\t) {\n\t\t\t\t\tconst token = textTokens[i] as (typeof textTokens)[number];\n\t\t\t\t\tif (token.end > node.span.end) break;\n\t\t\t\t\tvalue += uncut(token.start, token.end);\n\t\t\t\t}\n\t\t\t\tnode.value = value;\n\t\t\t}\n\t\t\tconst bodies = bodiesOf(node);\n\t\t\tif (bodies.length > 0) {\n\t\t\t\tfor (const child of childLists(bodies)) rewrite(child);\n\t\t\t}\n\t\t}\n\t};\n\trewrite(ast.body);\n};\n","import {\n\ttype LexProblem,\n\tlex,\n\tMAX_NESTING,\n\ttype Token,\n} from \"../lexer/lexer.js\";\nimport type { Span } from \"../source.js\";\nimport {\n\ttype Argument,\n\ttype BinaryOperator,\n\tESCAPE_STRATEGIES,\n\ttype EscapeStrategy,\n\ttype Expression,\n\ttype FilterCall,\n\ttype HashEntry,\n\ttype Param,\n\ttype IslandStatement,\n\ttype PropParam,\n\ttype PropType,\n\ttype ShapeKey,\n\ttype Spread,\n\ttype Statement,\n\ttype TemplateNode,\n\tTYPE_NAMES,\n\ttype TypeName,\n} from \"./ast.js\";\nimport { removeIndentation } from \"./indent.js\";\n\nconst isTypeName = (name: string): name is TypeName =>\n\t(TYPE_NAMES as readonly string[]).includes(name);\n\nexport type ParseOptions = {\n\t/** Says whether a name is a registered test, so the parser can read two-word tests such as `divisible by`. */\n\tisTest: (name: string) => boolean;\n};\n\nexport type ParseResult = { ast: TemplateNode; problems: LexProblem[] };\n\n/** Names that cannot be declared as variables, because Kiln uses them itself. */\nexport const RESERVED_NAMES = new Set([\n\t\"true\",\n\t\"false\",\n\t\"null\",\n\t\"and\",\n\t\"or\",\n\t\"not\",\n\t\"in\",\n\t\"is\",\n\t\"loop\",\n\t\"slots\",\n]);\n\n/** Parses template source into a syntax tree, collecting every problem instead of stopping at the first. */\nexport const parse = (text: string, options: ParseOptions): ParseResult => {\n\tconst lexed = lex(text);\n\tconst parser = new Parser(lexed.tokens, options);\n\tconst ast = parser.parseTemplate(text.length);\n\tremoveIndentation(ast, text, lexed, parser.islands);\n\treturn { ast, problems: [...lexed.problems, ...parser.problems] };\n};\n\nclass ParseFailure {\n\tconstructor(\n\t\treadonly code: string,\n\t\treadonly message: string,\n\t\treadonly span: Span,\n\t) {}\n}\n\ntype BodyResult = {\n\tbody: Statement[];\n\t/** The end tag's name token, already consumed. Null when the template ended or an outer tag's end was found. */\n\tend: Token | null;\n};\n\n/** Words that can follow a one-word test, so they never form part of a two-word test name. */\nconst NOT_TEST_WORDS = new Set([\n\t\"and\",\n\t\"or\",\n\t\"not\",\n\t\"in\",\n\t\"is\",\n\t\"starts\",\n\t\"ends\",\n\t\"with\",\n\t\"ignore\",\n\t\"as\",\n]);\n\nconst COMPARISON_PUNCTUATORS = new Set([\"==\", \"!=\", \"<\", \">\", \"<=\", \">=\"]);\n\nconst describeToken = (token: Token): string => {\n\tswitch (token.type) {\n\t\tcase \"eof\":\n\t\t\treturn \"the end of the template\";\n\t\tcase \"tagClose\":\n\t\t\treturn '\"%}\"';\n\t\tcase \"outputClose\":\n\t\t\treturn '\"}}\"';\n\t\tcase \"text\":\n\t\t\treturn \"text\";\n\t\tcase \"string\":\n\t\t\treturn \"a string\";\n\t\tcase \"stringStart\":\n\t\t\treturn \"an interpolated string\";\n\t\tcase \"number\":\n\t\t\treturn `number ${token.value}`;\n\t\tdefault:\n\t\t\treturn `\"${token.value}\"`;\n\t}\n};\n\nclass Parser {\n\treadonly problems: LexProblem[] = [];\n\t/** Every island, for `removeIndentation`. */\n\treadonly islands: IslandStatement[] = [];\n\treadonly #tokens: Token[];\n\treadonly #options: ParseOptions;\n\t#index = 0;\n\t#lastEnd = 0;\n\t#nesting = 0;\n\t/** End tag names of every open block tag, innermost last. */\n\treadonly #endStack: (readonly string[])[] = [];\n\n\tconstructor(tokens: Token[], options: ParseOptions) {\n\t\tthis.#tokens = tokens;\n\t\tthis.#options = options;\n\t}\n\n\tparseTemplate(length: number): TemplateNode {\n\t\tconst { body } = this.#parseBody([]);\n\t\treturn { type: \"Template\", body, span: { start: 0, end: length } };\n\t}\n\n\t// Token helpers\n\n\t#peek(offset = 0): Token {\n\t\treturn (\n\t\t\tthis.#tokens[this.#index + offset] ??\n\t\t\t(this.#tokens[this.#tokens.length - 1] as Token)\n\t\t);\n\t}\n\n\t#next(): Token {\n\t\tconst token = this.#peek();\n\t\tif (token.type !== \"eof\") this.#index++;\n\t\tthis.#lastEnd = token.end;\n\t\treturn token;\n\t}\n\n\t#isPunct(value: string, offset = 0): boolean {\n\t\tconst token = this.#peek(offset);\n\t\treturn token.type === \"punct\" && token.value === value;\n\t}\n\n\t#isName(value: string, offset = 0): boolean {\n\t\tconst token = this.#peek(offset);\n\t\treturn token.type === \"name\" && token.value === value;\n\t}\n\n\t#fail(\n\t\tmessage: string,\n\t\ttoken = this.#peek(),\n\t\tcode = \"unexpected-token\",\n\t): never {\n\t\tthrow new ParseFailure(code, message, {\n\t\t\tstart: token.start,\n\t\t\tend: Math.max(token.end, token.start + 1),\n\t\t});\n\t}\n\n\t#expectPunct(value: string): Token {\n\t\tif (!this.#isPunct(value)) {\n\t\t\tthis.#fail(\n\t\t\t\t`Expected \"${value}\" but found ${describeToken(this.#peek())}`,\n\t\t\t);\n\t\t}\n\t\treturn this.#next();\n\t}\n\n\t#expectName(what = \"a name\"): Token {\n\t\tconst token = this.#peek();\n\t\tif (token.type !== \"name\") {\n\t\t\tthis.#fail(`Expected ${what} but found ${describeToken(token)}`);\n\t\t}\n\t\treturn this.#next();\n\t}\n\n\t#expectKeyword(value: string): Token {\n\t\tif (!this.#isName(value)) {\n\t\t\tthis.#fail(\n\t\t\t\t`Expected \"${value}\" but found ${describeToken(this.#peek())}`,\n\t\t\t);\n\t\t}\n\t\treturn this.#next();\n\t}\n\n\t#expectTagEnd(): Token {\n\t\tconst token = this.#peek();\n\t\tif (token.type !== \"tagClose\") {\n\t\t\tthis.#fail(`Expected \"%}\" but found ${describeToken(token)}`);\n\t\t}\n\t\treturn this.#next();\n\t}\n\n\t#expectDeclarableName(what: string): Token {\n\t\tconst token = this.#expectName(what);\n\t\tif (RESERVED_NAMES.has(token.value)) {\n\t\t\tthis.#problem(\n\t\t\t\t\"reserved-name\",\n\t\t\t\t`\"${token.value}\" is reserved and cannot be used as a name`,\n\t\t\t\ttoken,\n\t\t\t);\n\t\t}\n\t\treturn token;\n\t}\n\n\t#problem(code: string, message: string, span: Span): void {\n\t\tthis.problems.push({\n\t\t\tcode,\n\t\t\tmessage,\n\t\t\tspan: { start: span.start, end: span.end },\n\t\t});\n\t}\n\n\t/** Skips to just after the end of the current tag or output. */\n\t#recover(): void {\n\t\tfor (;;) {\n\t\t\tconst token = this.#peek();\n\t\t\tif (token.type === \"eof\") return;\n\t\t\tif (token.type === \"tagClose\" || token.type === \"outputClose\") {\n\t\t\t\tthis.#next();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\ttoken.type === \"text\" ||\n\t\t\t\ttoken.type === \"tagOpen\" ||\n\t\t\t\ttoken.type === \"outputOpen\"\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.#next();\n\t\t}\n\t}\n\n\t#record(failure: unknown): void {\n\t\tif (!(failure instanceof ParseFailure)) throw failure;\n\t\tthis.#problem(failure.code, failure.message, failure.span);\n\t\tthis.#recover();\n\t}\n\n\t/**\n\t * Parses a block tag's header and its `%}`. If that fails, records the problem and skips to the end of the tag, so the body still parses.\n\t */\n\t#header<T>(parse: () => T, fallback: T): T {\n\t\ttry {\n\t\t\tconst result = parse();\n\t\t\tthis.#expectTagEnd();\n\t\t\treturn result;\n\t\t} catch (failure) {\n\t\t\tthis.#record(failure);\n\t\t\treturn fallback;\n\t\t}\n\t}\n\n\t/** Whether the current tag holds the punctuator `value` before its `%}`. */\n\t#tagHasPunct(value: string): boolean {\n\t\tfor (let offset = 0; ; offset++) {\n\t\t\tconst token = this.#peek(offset);\n\t\t\tif (token.type === \"punct\" && token.value === value) return true;\n\t\t\tif (\n\t\t\t\ttoken.type === \"tagClose\" ||\n\t\t\t\ttoken.type === \"eof\" ||\n\t\t\t\ttoken.type === \"text\" ||\n\t\t\t\ttoken.type === \"tagOpen\" ||\n\t\t\t\ttoken.type === \"outputOpen\"\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t}\n\n\t#invalid(): Expression {\n\t\tconst token = this.#peek();\n\t\treturn { type: \"Invalid\", span: { start: token.start, end: token.end } };\n\t}\n\n\t// Statements\n\n\t#parseBody(ends: readonly string[]): BodyResult {\n\t\tthis.#enter();\n\t\tconst body: Statement[] = [];\n\t\tthis.#endStack.push(ends);\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst token = this.#peek();\n\t\t\t\tswitch (token.type) {\n\t\t\t\t\tcase \"eof\":\n\t\t\t\t\t\treturn { body, end: null };\n\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\tconst previous = body[body.length - 1];\n\t\t\t\t\t\tif (previous?.type === \"Text\") {\n\t\t\t\t\t\t\tprevious.value += token.value;\n\t\t\t\t\t\t\tprevious.span = { start: previous.span.start, end: token.end };\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbody.push({\n\t\t\t\t\t\t\t\ttype: \"Text\",\n\t\t\t\t\t\t\t\tvalue: token.value,\n\t\t\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"outputOpen\":\n\t\t\t\t\t\tthis.#parseOutput(body);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"tagOpen\": {\n\t\t\t\t\t\tconst name = this.#peek(1);\n\t\t\t\t\t\tif (name.type === \"name\") {\n\t\t\t\t\t\t\tif (ends.includes(name.value)) {\n\t\t\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\t\t\treturn { body, end: name };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (this.#endStack.some((outer) => outer.includes(name.value))) {\n\t\t\t\t\t\t\t\treturn { body, end: null };\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.#parseTag(body);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// Only reachable after a lexer problem. Skip the stray token.\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#endStack.pop();\n\t\t\tthis.#nesting--;\n\t\t}\n\t}\n\n\t#parseOutput(body: Statement[]): void {\n\t\tconst open = this.#next();\n\t\ttry {\n\t\t\tconst expression = this.#parseExpression();\n\t\t\tconst close = this.#peek();\n\t\t\tif (close.type !== \"outputClose\") {\n\t\t\t\tthis.#fail(`Expected \"}}\" but found ${describeToken(close)}`);\n\t\t\t}\n\t\t\tthis.#next();\n\t\t\tbody.push({\n\t\t\t\ttype: \"Output\",\n\t\t\t\texpression,\n\t\t\t\tspan: { start: open.start, end: close.end },\n\t\t\t});\n\t\t} catch (failure) {\n\t\t\tthis.#record(failure);\n\t\t}\n\t}\n\n\t#parseTag(body: Statement[]): void {\n\t\tconst open = this.#next();\n\t\tconst nameToken = this.#peek();\n\t\tif (nameToken.type !== \"name\") {\n\t\t\tthis.#problem(\n\t\t\t\t\"unexpected-token\",\n\t\t\t\t`Expected a tag name but found ${describeToken(nameToken)}`,\n\t\t\t\tnameToken,\n\t\t\t);\n\t\t\tthis.#recover();\n\t\t\treturn;\n\t\t}\n\t\tthis.#next();\n\t\tconst name = nameToken.value;\n\n\t\ttry {\n\t\t\tconst statement = this.#parseNamedTag(name, open, nameToken);\n\t\t\tif (statement) body.push(statement);\n\t\t} catch (failure) {\n\t\t\tthis.#record(failure);\n\t\t}\n\t}\n\n\t#parseNamedTag(\n\t\tname: string,\n\t\topen: Token,\n\t\tnameToken: Token,\n\t): Statement | null {\n\t\tswitch (name) {\n\t\t\tcase \"if\":\n\t\t\t\treturn this.#parseIf(open);\n\t\t\tcase \"for\":\n\t\t\t\treturn this.#parseFor(open);\n\t\t\tcase \"set\":\n\t\t\t\treturn this.#parseSet(open);\n\t\t\tcase \"props\":\n\t\t\t\treturn this.#parseProps(open);\n\t\t\tcase \"extends\": {\n\t\t\t\tconst template = this.#parseExpression();\n\t\t\t\tconst close = this.#expectTagEnd();\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"Extends\",\n\t\t\t\t\ttemplate,\n\t\t\t\t\tspan: { start: open.start, end: close.end },\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"block\":\n\t\t\t\treturn this.#parseBlock(open);\n\t\t\tcase \"include\":\n\t\t\t\treturn this.#parseInclude(open);\n\t\t\tcase \"component\":\n\t\t\t\treturn this.#parseComponent(open);\n\t\t\tcase \"slot\":\n\t\t\t\treturn this.#parseSlot(open);\n\t\t\tcase \"macro\":\n\t\t\t\treturn this.#parseMacro(open);\n\t\t\tcase \"import\":\n\t\t\t\treturn this.#parseImport(open);\n\t\t\tcase \"from\":\n\t\t\t\treturn this.#parseFromImport(open);\n\t\t\tcase \"with\":\n\t\t\t\treturn this.#parseWith(open);\n\t\t\tcase \"cache\":\n\t\t\t\treturn this.#parseCache(open);\n\t\t\tcase \"island\":\n\t\t\t\treturn this.#parseIsland(open);\n\t\t\tcase \"outlet\": {\n\t\t\t\tconst name = this.#parseStringLiteral(\"an outlet name\");\n\t\t\t\tconst close = this.#expectTagEnd();\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"Outlet\",\n\t\t\t\t\tname,\n\t\t\t\t\tspan: { start: open.start, end: close.end },\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"flush\": {\n\t\t\t\tconst close = this.#expectTagEnd();\n\t\t\t\treturn { type: \"Flush\", span: { start: open.start, end: close.end } };\n\t\t\t}\n\t\t\tcase \"add\":\n\t\t\t\treturn this.#parseAdd(open);\n\t\t\tcase \"apply\":\n\t\t\t\treturn this.#parseApply(open);\n\t\t\tcase \"autoescape\":\n\t\t\t\treturn this.#parseAutoescape(open);\n\t\t\tcase \"verbatim\":\n\t\t\t\treturn this.#parseVerbatim(open);\n\t\t\tdefault: {\n\t\t\t\tconst stray =\n\t\t\t\t\tname.startsWith(\"end\") ||\n\t\t\t\t\tname === \"else\" ||\n\t\t\t\t\tname === \"elseif\" ||\n\t\t\t\t\tname === \"fill\";\n\t\t\t\tthis.#problem(\n\t\t\t\t\tstray ? \"unexpected-tag\" : \"unknown-tag\",\n\t\t\t\t\tstray\n\t\t\t\t\t\t? `\"${name}\" has no matching opening tag here`\n\t\t\t\t\t\t: `Unknown tag \"${name}\"`,\n\t\t\t\t\tnameToken,\n\t\t\t\t);\n\t\t\t\tthis.#recover();\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Reports a block tag whose end tag never came. */\n\t#unclosed(name: string, open: Token, endName: string): void {\n\t\tthis.#problem(\n\t\t\t\"unclosed-block\",\n\t\t\t`\"${name}\" is missing its \"${endName}\" tag`,\n\t\t\t{ start: open.start, end: open.end },\n\t\t);\n\t}\n\n\t/** Consumes an end tag's `%}`, plus an optional repeated name such as `endblock content`. */\n\t#finishEndTag(expectedName?: string): void {\n\t\ttry {\n\t\t\tif (expectedName !== undefined && this.#peek().type === \"name\") {\n\t\t\t\tconst repeated = this.#next();\n\t\t\t\tif (repeated.value !== expectedName) {\n\t\t\t\t\tthis.#problem(\n\t\t\t\t\t\t\"mismatched-end\",\n\t\t\t\t\t\t`End tag names \"${repeated.value}\" but closes \"${expectedName}\"`,\n\t\t\t\t\t\trepeated,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.#expectTagEnd();\n\t\t} catch (failure) {\n\t\t\tthis.#record(failure);\n\t\t}\n\t}\n\n\t#parseIf(open: Token): Statement {\n\t\tconst branches: { test: Expression; body: Statement[] }[] = [];\n\t\tlet test = this.#header(() => this.#parseExpression(), this.#invalid());\n\t\tlet alternate: Statement[] | null = null;\n\n\t\tfor (;;) {\n\t\t\tconst { body, end } = this.#parseBody([\"elseif\", \"else\", \"endif\"]);\n\t\t\tbranches.push({ test, body });\n\t\t\tif (!end) {\n\t\t\t\tthis.#unclosed(\"if\", open, \"endif\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (end.value === \"elseif\") {\n\t\t\t\ttest = this.#header(() => this.#parseExpression(), this.#invalid());\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (end.value === \"else\") {\n\t\t\t\tthis.#finishEndTag();\n\t\t\t\talternate = this.#parseAlternate(\"if\", open, [\"elseif\", \"else\"]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.#finishEndTag();\n\t\t\tbreak;\n\t\t}\n\t\treturn {\n\t\t\ttype: \"If\",\n\t\t\tbranches,\n\t\t\talternate,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t/**\n\t * Parses the `else` branch of `if` or `for` up to its end tag. A branch tag after `else`, such as a second `else`,\n\t * is reported where it stands, so it can't close an outer tag instead.\n\t */\n\t#parseAlternate(name: string, open: Token, branches: string[]): Statement[] {\n\t\tconst endName = `end${name}`;\n\t\tconst alternate: Statement[] = [];\n\t\tfor (;;) {\n\t\t\tconst { body, end } = this.#parseBody([endName, ...branches]);\n\t\t\talternate.push(...body);\n\t\t\tif (!end) {\n\t\t\t\tthis.#unclosed(name, open, endName);\n\t\t\t\treturn alternate;\n\t\t\t}\n\t\t\tif (end.value === endName) {\n\t\t\t\tthis.#finishEndTag();\n\t\t\t\treturn alternate;\n\t\t\t}\n\t\t\tthis.#problem(\n\t\t\t\t\"unexpected-tag\",\n\t\t\t\t`\"${end.value}\" cannot follow \"else\" in \"${name}\"`,\n\t\t\t\tend,\n\t\t\t);\n\t\t\tthis.#recover();\n\t\t}\n\t}\n\n\t#parseFor(open: Token): Statement {\n\t\tconst header = this.#header(\n\t\t\t() => {\n\t\t\t\tlet keyName: string | null = null;\n\t\t\t\tlet valueName = this.#expectDeclarableName(\"a loop variable\").value;\n\t\t\t\tif (this.#isPunct(\",\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tkeyName = valueName;\n\t\t\t\t\tvalueName = this.#expectDeclarableName(\"a loop variable\").value;\n\t\t\t\t}\n\t\t\t\tthis.#expectKeyword(\"in\");\n\t\t\t\tconst iterable = this.#parseExpression();\n\t\t\t\treturn { keyName, valueName, iterable };\n\t\t\t},\n\t\t\t{ keyName: null, valueName: \"_\", iterable: this.#invalid() },\n\t\t);\n\n\t\tconst { body, end } = this.#parseBody([\"else\", \"endfor\"]);\n\t\tlet alternate: Statement[] | null = null;\n\t\tif (!end) this.#unclosed(\"for\", open, \"endfor\");\n\t\telse if (end.value === \"else\") {\n\t\t\tthis.#finishEndTag();\n\t\t\talternate = this.#parseAlternate(\"for\", open, [\"else\"]);\n\t\t} else this.#finishEndTag();\n\n\t\treturn {\n\t\t\ttype: \"For\",\n\t\t\t...header,\n\t\t\tbody,\n\t\t\talternate,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseSet(open: Token): Statement {\n\t\tif (this.#tagHasPunct(\"=\")) {\n\t\t\tconst name = this.#expectDeclarableName(\"a variable name\").value;\n\t\t\tthis.#expectPunct(\"=\");\n\t\t\tconst value = this.#parseExpression();\n\t\t\tconst close = this.#expectTagEnd();\n\t\t\treturn {\n\t\t\t\ttype: \"Set\",\n\t\t\t\tname,\n\t\t\t\tvalue,\n\t\t\t\tspan: { start: open.start, end: close.end },\n\t\t\t};\n\t\t}\n\t\t// Without \"=\" the tag captures a body, even when the rest of it is broken, so its end tag still matches.\n\t\tconst name = this.#header(\n\t\t\t() => this.#expectDeclarableName(\"a variable name\").value,\n\t\t\t\"\",\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endset\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"set\", open, \"endset\");\n\t\treturn {\n\t\t\ttype: \"SetBlock\",\n\t\t\tname,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t/** Reads parameters for `macro` and `props`. Only `props` may declare types, so macros' `type` is always null. */\n\t#parseParams(closing: string | null, typed = false): PropParam[] {\n\t\tconst params: PropParam[] = [];\n\t\t// A rest prop, `...name`, ends the list. `#parseProps` reads it.\n\t\tconst done = () =>\n\t\t\tclosing === null\n\t\t\t\t? this.#peek().type === \"tagClose\" || this.#isPunct(\"...\")\n\t\t\t\t: this.#isPunct(closing);\n\t\twhile (!done()) {\n\t\t\tconst nameToken = this.#expectDeclarableName(\"a parameter name\");\n\t\t\tif (params.some((param) => param.name === nameToken.value)) {\n\t\t\t\tthis.#problem(\n\t\t\t\t\t\"duplicate-parameter\",\n\t\t\t\t\t`\"${nameToken.value}\" is declared more than once`,\n\t\t\t\t\tnameToken,\n\t\t\t\t);\n\t\t\t}\n\t\t\tlet type: PropType[] | null = null;\n\t\t\tif (typed && this.#isPunct(\":\")) {\n\t\t\t\tthis.#next();\n\t\t\t\ttype = this.#parsePropType();\n\t\t\t}\n\t\t\tlet defaultValue: Expression | null = null;\n\t\t\tif (this.#isPunct(\"=\")) {\n\t\t\t\tthis.#next();\n\t\t\t\tdefaultValue = this.#parseExpression();\n\t\t\t}\n\t\t\tparams.push({\n\t\t\t\tname: nameToken.value,\n\t\t\t\ttype,\n\t\t\t\tdefault: defaultValue,\n\t\t\t\tspan: { start: nameToken.start, end: this.#lastEnd },\n\t\t\t});\n\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\tthis.#next();\n\t\t}\n\t\treturn params;\n\t}\n\n\t/** Reads a prop type such as `string | null`, `\"primary\" | \"secondary\"`, `Post[]` or `{ name: string }`. */\n\t#parsePropType(): PropType[] {\n\t\tthis.#enter();\n\t\tconst nesting = this.#nesting;\n\t\ttry {\n\t\t\tconst members: PropType[] = [];\n\t\t\tfor (;;) {\n\t\t\t\tlet type = this.#parsePropTypeTerm();\n\t\t\t\t// Each `[]` nests the type inside a list, so it counts as a level.\n\t\t\t\twhile (this.#isPunct(\"[\") && this.#isPunct(\"]\", 1)) {\n\t\t\t\t\tthis.#enter();\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tthis.#next();\n\t\t\t\t\ttype = [{ list: type }];\n\t\t\t\t}\n\t\t\t\tthis.#nesting = nesting;\n\t\t\t\tmembers.push(...type);\n\t\t\t\tif (!this.#isPunct(\"|\")) return members;\n\t\t\t\tthis.#next();\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#nesting = nesting - 1;\n\t\t}\n\t}\n\n\t/** Reads one part of a union. Brackets return the union inside them, so `(2 | 3)[]` lists either. */\n\t#parsePropTypeTerm(): PropType[] {\n\t\tconst token = this.#peek();\n\t\tif (token.type === \"punct\" && token.value === \"(\") {\n\t\t\tthis.#next();\n\t\t\tconst inner = this.#parsePropType();\n\t\t\tthis.#expectPunct(\")\");\n\t\t\treturn inner;\n\t\t}\n\t\tif (token.type === \"punct\" && token.value === \"{\") {\n\t\t\treturn [{ shape: this.#parseShape() }];\n\t\t}\n\t\tthis.#next();\n\t\tif (token.type === \"string\") return [{ literal: token.value }];\n\t\tif (token.type === \"number\") return [{ literal: Number(token.value) }];\n\t\tif (token.type === \"name\" && isTypeName(token.value)) return [token.value];\n\t\t// Host types start with a capital letter, so they never clash with built-in names.\n\t\tif (token.type === \"name\" && /^[A-Z]/.test(token.value)) {\n\t\t\treturn [{ named: token.value }];\n\t\t}\n\t\tif (token.type === \"name\") {\n\t\t\tthis.#problem(\"unknown-type\", `Unknown type \"${token.value}\"`, token);\n\t\t\treturn [];\n\t\t}\n\t\treturn this.#fail(\n\t\t\t`Expected a type but found ${describeToken(token)}`,\n\t\t\ttoken,\n\t\t);\n\t}\n\n\t/** Reads a shape type such as `{ name: string, url?: string }`. */\n\t#parseShape(): ShapeKey[] {\n\t\tthis.#expectPunct(\"{\");\n\t\tconst keys: ShapeKey[] = [];\n\t\twhile (!this.#isPunct(\"}\")) {\n\t\t\tconst token = this.#next();\n\t\t\tif (token.type !== \"name\" && token.type !== \"string\") {\n\t\t\t\tthis.#fail(`Expected a key but found ${describeToken(token)}`, token);\n\t\t\t}\n\t\t\tif (keys.some((key) => key.name === token.value)) {\n\t\t\t\tthis.#problem(\n\t\t\t\t\t\"duplicate-key\",\n\t\t\t\t\t`\"${token.value}\" is declared more than once`,\n\t\t\t\t\ttoken,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The lexer reads `?:` as one token, as in `url?: string`.\n\t\t\tconst optional = this.#isPunct(\"?:\") || this.#isPunct(\"?\");\n\t\t\tif (this.#isPunct(\"?:\")) this.#next();\n\t\t\telse {\n\t\t\t\tif (optional) this.#next();\n\t\t\t\tthis.#expectPunct(\":\");\n\t\t\t}\n\t\t\tkeys.push({ name: token.value, optional, type: this.#parsePropType() });\n\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\tthis.#next();\n\t\t}\n\t\tthis.#expectPunct(\"}\");\n\t\treturn keys;\n\t}\n\n\t#parseProps(open: Token): Statement {\n\t\tconst props = this.#parseParams(null, true);\n\t\tlet rest: string | null = null;\n\t\tif (this.#isPunct(\"...\")) {\n\t\t\tthis.#next();\n\t\t\tconst nameToken = this.#expectDeclarableName(\"a rest prop name\");\n\t\t\tif (props.some((prop) => prop.name === nameToken.value)) {\n\t\t\t\tthis.#problem(\n\t\t\t\t\t\"duplicate-parameter\",\n\t\t\t\t\t`\"${nameToken.value}\" is declared more than once`,\n\t\t\t\t\tnameToken,\n\t\t\t\t);\n\t\t\t}\n\t\t\trest = nameToken.value;\n\t\t\tif (this.#isPunct(\",\")) this.#next();\n\t\t\tif (this.#peek().type !== \"tagClose\") {\n\t\t\t\tthis.#fail(\"The rest prop must come last, with no type or default\");\n\t\t\t}\n\t\t}\n\t\tconst close = this.#expectTagEnd();\n\t\treturn {\n\t\t\ttype: \"Props\",\n\t\t\tprops,\n\t\t\trest,\n\t\t\tspan: { start: open.start, end: close.end },\n\t\t};\n\t}\n\n\t#parseBlock(open: Token): Statement | null {\n\t\t// A tag holding only a bad name is the long form, so its body and end tag are still read.\n\t\tconst first = this.#peek();\n\t\tif (\n\t\t\tfirst.type !== \"name\" &&\n\t\t\t(first.type === \"tagClose\" || this.#peek(1).type === \"tagClose\")\n\t\t) {\n\t\t\tthis.#header(() => {\n\t\t\t\tthis.#expectName(\"a block name\");\n\t\t\t}, undefined);\n\t\t\tconst { end } = this.#parseBody([\"endblock\"]);\n\t\t\tif (end) this.#finishEndTag();\n\t\t\telse this.#unclosed(\"block\", open, \"endblock\");\n\t\t\treturn null;\n\t\t}\n\t\tconst name = this.#expectName(\"a block name\").value;\n\t\tif (this.#peek().type !== \"tagClose\") {\n\t\t\t// Short form: {% block title page.title %}\n\t\t\tconst expression = this.#parseExpression();\n\t\t\tconst close = this.#expectTagEnd();\n\t\t\treturn {\n\t\t\t\ttype: \"Block\",\n\t\t\t\tname,\n\t\t\t\tbody: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"Output\",\n\t\t\t\t\t\texpression,\n\t\t\t\t\t\tspan: { start: expression.span.start, end: expression.span.end },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tspan: { start: open.start, end: close.end },\n\t\t\t};\n\t\t}\n\t\tthis.#expectTagEnd();\n\t\tconst { body, end } = this.#parseBody([\"endblock\"]);\n\t\tif (end) this.#finishEndTag(name);\n\t\telse this.#unclosed(\"block\", open, \"endblock\");\n\t\treturn {\n\t\t\ttype: \"Block\",\n\t\t\tname,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseInclude(open: Token): Statement {\n\t\tconst template = this.#parseExpression();\n\t\tlet withValue: Expression | null = null;\n\t\tlet ignoreMissing = false;\n\t\tif (this.#isName(\"with\")) {\n\t\t\tthis.#next();\n\t\t\twithValue = this.#parseExpression();\n\t\t}\n\t\tif (this.#isName(\"ignore\")) {\n\t\t\tthis.#next();\n\t\t\tthis.#expectKeyword(\"missing\");\n\t\t\tignoreMissing = true;\n\t\t}\n\t\tconst close = this.#expectTagEnd();\n\t\treturn {\n\t\t\ttype: \"Include\",\n\t\t\ttemplate,\n\t\t\twith: withValue,\n\t\t\tignoreMissing,\n\t\t\tspan: { start: open.start, end: close.end },\n\t\t};\n\t}\n\n\t#parseComponent(open: Token): Statement {\n\t\tconst header = this.#header(\n\t\t\t() => {\n\t\t\t\tconst template = this.#parseExpression();\n\t\t\t\tlet withValue: Expression | null = null;\n\t\t\t\tif (this.#isName(\"with\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\twithValue = this.#parseExpression();\n\t\t\t\t}\n\t\t\t\treturn { template, with: withValue };\n\t\t\t},\n\t\t\t{ template: this.#invalid(), with: null },\n\t\t);\n\n\t\tconst body: Statement[] = [];\n\t\tconst fills: { name: string; body: Statement[]; span: Span }[] = [];\n\t\tfor (;;) {\n\t\t\tconst part = this.#parseBody([\"fill\", \"endcomponent\"]);\n\t\t\tbody.push(...part.body);\n\t\t\tif (!part.end) {\n\t\t\t\tthis.#unclosed(\"component\", open, \"endcomponent\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (part.end.value === \"endcomponent\") {\n\t\t\t\tthis.#finishEndTag();\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tconst fillStart = this.#tokens[this.#index - 2] ?? part.end;\n\t\t\tconst name = this.#header(\n\t\t\t\t() => this.#parseStringLiteral(\"a slot name\"),\n\t\t\t\t\"\",\n\t\t\t);\n\t\t\tconst fill = this.#parseBody([\"endfill\"]);\n\t\t\tif (fill.end) this.#finishEndTag();\n\t\t\telse this.#unclosed(\"fill\", fillStart, \"endfill\");\n\t\t\tif (fills.some((existing) => existing.name === name)) {\n\t\t\t\tthis.#problem(\n\t\t\t\t\t\"duplicate-fill\",\n\t\t\t\t\t`Slot \"${name}\" is filled more than once`,\n\t\t\t\t\t{ start: fillStart.start, end: fillStart.end },\n\t\t\t\t);\n\t\t\t}\n\t\t\tfills.push({\n\t\t\t\tname,\n\t\t\t\tbody: fill.body,\n\t\t\t\tspan: { start: fillStart.start, end: this.#lastEnd },\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\ttype: \"Component\",\n\t\t\t...header,\n\t\t\tfills,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseStringLiteral(what: string): string {\n\t\tconst token = this.#peek();\n\t\tif (token.type !== \"string\") {\n\t\t\tthis.#fail(\n\t\t\t\t`Expected ${what} as a string but found ${describeToken(token)}`,\n\t\t\t);\n\t\t}\n\t\tthis.#next();\n\t\treturn token.value;\n\t}\n\n\t#parseSlot(open: Token): Statement {\n\t\tconst name = this.#header(\n\t\t\t() =>\n\t\t\t\tthis.#peek().type === \"tagClose\"\n\t\t\t\t\t? \"default\"\n\t\t\t\t\t: this.#parseStringLiteral(\"a slot name\"),\n\t\t\t\"default\",\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endslot\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"slot\", open, \"endslot\");\n\t\treturn {\n\t\t\ttype: \"Slot\",\n\t\t\tname,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseMacro(open: Token): Statement {\n\t\tconst header = this.#header(\n\t\t\t() => {\n\t\t\t\tconst name = this.#expectDeclarableName(\"a macro name\").value;\n\t\t\t\tthis.#expectPunct(\"(\");\n\t\t\t\tconst params = this.#parseParams(\")\");\n\t\t\t\tthis.#expectPunct(\")\");\n\t\t\t\treturn { name, params };\n\t\t\t},\n\t\t\t{ name: \"\", params: [] as Param[] },\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endmacro\"]);\n\t\tif (end) this.#finishEndTag(header.name);\n\t\telse this.#unclosed(\"macro\", open, \"endmacro\");\n\t\treturn {\n\t\t\ttype: \"Macro\",\n\t\t\t...header,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseImport(open: Token): Statement {\n\t\tconst template = this.#parseStringLiteral(\"a template name\");\n\t\tthis.#expectKeyword(\"as\");\n\t\tconst alias = this.#expectDeclarableName(\"an alias\").value;\n\t\tconst close = this.#expectTagEnd();\n\t\treturn {\n\t\t\ttype: \"Import\",\n\t\t\ttemplate,\n\t\t\talias,\n\t\t\tspan: { start: open.start, end: close.end },\n\t\t};\n\t}\n\n\t#parseFromImport(open: Token): Statement {\n\t\tconst template = this.#parseStringLiteral(\"a template name\");\n\t\tthis.#expectKeyword(\"import\");\n\t\tconst names: { name: string; alias: string; span: Span }[] = [];\n\t\tdo {\n\t\t\tif (names.length > 0) this.#next();\n\t\t\tconst nameToken = this.#expectName(\"a macro name\");\n\t\t\tlet alias = nameToken.value;\n\t\t\tif (this.#isName(\"as\")) {\n\t\t\t\tthis.#next();\n\t\t\t\talias = this.#expectDeclarableName(\"an alias\").value;\n\t\t\t}\n\t\t\tnames.push({\n\t\t\t\tname: nameToken.value,\n\t\t\t\talias,\n\t\t\t\tspan: { start: nameToken.start, end: this.#lastEnd },\n\t\t\t});\n\t\t} while (this.#isPunct(\",\"));\n\t\tconst close = this.#expectTagEnd();\n\t\treturn {\n\t\t\ttype: \"FromImport\",\n\t\t\ttemplate,\n\t\t\tnames,\n\t\t\tspan: { start: open.start, end: close.end },\n\t\t};\n\t}\n\n\t#parseWith(open: Token): Statement {\n\t\tconst value = this.#header(() => this.#parseExpression(), this.#invalid());\n\t\tconst { body, end } = this.#parseBody([\"endwith\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"with\", open, \"endwith\");\n\t\treturn {\n\t\t\ttype: \"With\",\n\t\t\tvalue,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseAdd(open: Token): Statement {\n\t\tconst { outlet, once } = this.#header(\n\t\t\t() => {\n\t\t\t\tthis.#expectKeyword(\"to\");\n\t\t\t\tconst outlet = this.#parseStringLiteral(\"an outlet name\");\n\t\t\t\tconst once = this.#isName(\"once\");\n\t\t\t\tif (once) this.#next();\n\t\t\t\treturn { outlet, once };\n\t\t\t},\n\t\t\t{ outlet: \"\", once: false },\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endadd\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"add\", open, \"endadd\");\n\t\treturn {\n\t\t\ttype: \"Add\",\n\t\t\toutlet,\n\t\t\tonce,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseCache(open: Token): Statement {\n\t\tconst { key, seconds } = this.#header(\n\t\t\t() => {\n\t\t\t\tconst key = this.#parseExpression();\n\t\t\t\tlet seconds: Expression | null = null;\n\t\t\t\tif (this.#isName(\"for\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tseconds = this.#parseExpression();\n\t\t\t\t}\n\t\t\t\treturn { key, seconds };\n\t\t\t},\n\t\t\t{ key: this.#invalid(), seconds: null },\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endcache\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"cache\", open, \"endcache\");\n\t\treturn {\n\t\t\ttype: \"Cache\",\n\t\t\tkey,\n\t\t\tseconds,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseIsland(open: Token): Statement {\n\t\tconst header = this.#header(\n\t\t\t() => {\n\t\t\t\tconst template = this.#parseExpression();\n\t\t\t\tlet withValue: Expression | null = null;\n\t\t\t\tif (this.#isName(\"with\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\twithValue = this.#parseExpression();\n\t\t\t\t}\n\t\t\t\treturn { template, with: withValue };\n\t\t\t},\n\t\t\t{ template: this.#invalid(), with: null },\n\t\t);\n\t\tconst { body, end } = this.#parseBody([\"endisland\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"island\", open, \"endisland\");\n\t\tconst island: IslandStatement = {\n\t\t\ttype: \"Island\",\n\t\t\t...header,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t\tthis.islands.push(island);\n\t\treturn island;\n\t}\n\n\t#parseApply(open: Token): Statement {\n\t\tconst filters = this.#header(() => {\n\t\t\tconst list: FilterCall[] = [];\n\t\t\tdo {\n\t\t\t\tif (list.length > 0) this.#next();\n\t\t\t\tconst nameToken = this.#expectName(\"a filter name\");\n\t\t\t\tconst args = this.#isPunct(\"(\") ? this.#parseArguments() : [];\n\t\t\t\tlist.push({\n\t\t\t\t\tname: nameToken.value,\n\t\t\t\t\targs,\n\t\t\t\t\tspan: { start: nameToken.start, end: this.#lastEnd },\n\t\t\t\t});\n\t\t\t} while (this.#isPunct(\"|\"));\n\t\t\treturn list;\n\t\t}, [] as FilterCall[]);\n\t\tconst { body, end } = this.#parseBody([\"endapply\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"apply\", open, \"endapply\");\n\t\treturn {\n\t\t\ttype: \"Apply\",\n\t\t\tfilters,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseAutoescape(open: Token): Statement {\n\t\tconst strategy = this.#header((): EscapeStrategy | false => {\n\t\t\tconst token = this.#peek();\n\t\t\tif (token.type === \"tagClose\") return \"html\";\n\t\t\tif (token.type === \"name\" && token.value === \"false\") {\n\t\t\t\tthis.#next();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst value = this.#parseStringLiteral(\"an escaping strategy\");\n\t\t\tif (!ESCAPE_STRATEGIES.includes(value as EscapeStrategy)) {\n\t\t\t\tthis.#fail(\n\t\t\t\t\t`Unknown escaping strategy \"${value}\". Use ${ESCAPE_STRATEGIES.map((s) => `\"${s}\"`).join(\", \")} or false`,\n\t\t\t\t\ttoken,\n\t\t\t\t\t\"unknown-strategy\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn value as EscapeStrategy;\n\t\t}, \"html\");\n\t\tconst { body, end } = this.#parseBody([\"endautoescape\"]);\n\t\tif (end) this.#finishEndTag();\n\t\telse this.#unclosed(\"autoescape\", open, \"endautoescape\");\n\t\treturn {\n\t\t\ttype: \"Autoescape\",\n\t\t\tstrategy,\n\t\t\tbody,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseVerbatim(open: Token): Statement | null {\n\t\tthis.#expectTagEnd();\n\t\tlet value = \"\";\n\t\tlet start = this.#lastEnd;\n\t\tlet end = start;\n\t\tconst token = this.#peek();\n\t\tif (token.type === \"text\") {\n\t\t\tthis.#next();\n\t\t\tvalue = token.value;\n\t\t\tstart = token.start;\n\t\t\tend = token.end;\n\t\t}\n\t\tif (this.#peek().type === \"tagOpen\" && this.#isName(\"endverbatim\", 1)) {\n\t\t\tthis.#next();\n\t\t\tthis.#next();\n\t\t\tthis.#finishEndTag();\n\t\t}\n\t\t// The lexer already reported a missing `endverbatim`.\n\t\tif (value === \"\") return null;\n\t\treturn {\n\t\t\ttype: \"Text\",\n\t\t\tvalue,\n\t\t\tspan: { start: Math.max(start, open.end), end },\n\t\t};\n\t}\n\n\t// Expressions\n\n\t/** Guards against source nested so deeply that parsing it would overflow the call stack. */\n\t#enter(): void {\n\t\tif (++this.#nesting > MAX_NESTING) {\n\t\t\tthis.#nesting--;\n\t\t\tthis.#fail(\n\t\t\t\t`Template is nested more than ${MAX_NESTING} levels deep`,\n\t\t\t\tthis.#peek(),\n\t\t\t\t\"too-deep\",\n\t\t\t);\n\t\t}\n\t}\n\n\t#parseExpression(): Expression {\n\t\tthis.#enter();\n\t\ttry {\n\t\t\treturn this.#parseConditional();\n\t\t} finally {\n\t\t\tthis.#nesting--;\n\t\t}\n\t}\n\n\t#parseConditional(): Expression {\n\t\tconst test = this.#parseCoalesce();\n\t\tif (this.#isPunct(\"?\")) {\n\t\t\tthis.#next();\n\t\t\tconst consequent = this.#parseExpression();\n\t\t\tlet alternate: Expression | null = null;\n\t\t\tif (this.#isPunct(\":\")) {\n\t\t\t\tthis.#next();\n\t\t\t\talternate = this.#parseExpression();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\ttype: \"Conditional\",\n\t\t\t\ttest,\n\t\t\t\tconsequent,\n\t\t\t\talternate,\n\t\t\t\tspan: { start: test.span.start, end: this.#lastEnd },\n\t\t\t};\n\t\t}\n\t\tif (this.#isPunct(\"?:\")) {\n\t\t\tthis.#next();\n\t\t\tconst right = this.#parseExpression();\n\t\t\treturn this.#binary(\"?:\", test, right);\n\t\t}\n\t\treturn test;\n\t}\n\n\t#binary(\n\t\toperator: BinaryOperator,\n\t\tleft: Expression,\n\t\tright: Expression,\n\t): Expression {\n\t\treturn {\n\t\t\ttype: \"Binary\",\n\t\t\toperator,\n\t\t\tleft,\n\t\t\tright,\n\t\t\tspan: { start: left.span.start, end: right.span.end },\n\t\t};\n\t}\n\n\t#parseCoalesce(): Expression {\n\t\tconst left = this.#parseOr();\n\t\tif (!this.#isPunct(\"??\")) return left;\n\t\tthis.#next();\n\t\t// `??` groups to the right, so each one nests the rest of the chain inside it.\n\t\tthis.#enter();\n\t\ttry {\n\t\t\treturn this.#binary(\"??\", left, this.#parseCoalesce());\n\t\t} finally {\n\t\t\tthis.#nesting--;\n\t\t}\n\t}\n\n\t#parseOr(): Expression {\n\t\tlet left = this.#parseAnd();\n\t\twhile (this.#isName(\"or\")) {\n\t\t\tthis.#next();\n\t\t\tleft = this.#binary(\"or\", left, this.#parseAnd());\n\t\t}\n\t\treturn left;\n\t}\n\n\t#parseAnd(): Expression {\n\t\tlet left = this.#parseNot();\n\t\twhile (this.#isName(\"and\")) {\n\t\t\tthis.#next();\n\t\t\tleft = this.#binary(\"and\", left, this.#parseNot());\n\t\t}\n\t\treturn left;\n\t}\n\n\t#parseNot(): Expression {\n\t\tthis.#enter();\n\t\ttry {\n\t\t\treturn this.#parseNotInner();\n\t\t} finally {\n\t\t\tthis.#nesting--;\n\t\t}\n\t}\n\n\t#parseNotInner(): Expression {\n\t\tif (this.#isName(\"not\")) {\n\t\t\tconst token = this.#next();\n\t\t\tconst operand = this.#parseNot();\n\t\t\treturn {\n\t\t\t\ttype: \"Unary\",\n\t\t\t\toperator: \"not\",\n\t\t\t\toperand,\n\t\t\t\tspan: { start: token.start, end: operand.span.end },\n\t\t\t};\n\t\t}\n\t\treturn this.#parseComparison();\n\t}\n\n\t/** Reads a comparison operator at the cursor without consuming it, and how many tokens it spans. */\n\t#comparisonAhead(): {\n\t\toperator: BinaryOperator | \"is\";\n\t\tlength: number;\n\t} | null {\n\t\tconst token = this.#peek();\n\t\tif (token.type === \"punct\" && COMPARISON_PUNCTUATORS.has(token.value)) {\n\t\t\treturn { operator: token.value as BinaryOperator, length: 1 };\n\t\t}\n\t\tif (token.type !== \"name\") return null;\n\t\tswitch (token.value) {\n\t\t\tcase \"in\":\n\t\t\t\treturn { operator: \"in\", length: 1 };\n\t\t\tcase \"is\":\n\t\t\t\treturn { operator: \"is\", length: 1 };\n\t\t\tcase \"not\":\n\t\t\t\treturn this.#isName(\"in\", 1) ? { operator: \"not in\", length: 2 } : null;\n\t\t\tcase \"starts\":\n\t\t\t\treturn this.#isName(\"with\", 1)\n\t\t\t\t\t? { operator: \"starts with\", length: 2 }\n\t\t\t\t\t: null;\n\t\t\tcase \"ends\":\n\t\t\t\treturn this.#isName(\"with\", 1)\n\t\t\t\t\t? { operator: \"ends with\", length: 2 }\n\t\t\t\t\t: null;\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t}\n\n\t#parseComparison(): Expression {\n\t\tconst left = this.#parseRange();\n\t\tconst ahead = this.#comparisonAhead();\n\t\tif (!ahead) return left;\n\n\t\tlet result: Expression;\n\t\tif (ahead.operator === \"is\") {\n\t\t\tresult = this.#parseTest(left);\n\t\t} else {\n\t\t\tfor (let i = 0; i < ahead.length; i++) this.#next();\n\t\t\tresult = this.#binary(ahead.operator, left, this.#parseRange());\n\t\t}\n\n\t\tif (this.#comparisonAhead()) {\n\t\t\tthis.#fail(\n\t\t\t\t'Comparisons cannot be chained. Join them with \"and\" or \"or\"',\n\t\t\t\tthis.#peek(),\n\t\t\t\t\"chained-comparison\",\n\t\t\t);\n\t\t}\n\t\treturn result;\n\t}\n\n\t#parseTest(input: Expression): Expression {\n\t\tthis.#next();\n\t\tlet negated = false;\n\t\tif (this.#isName(\"not\")) {\n\t\t\tthis.#next();\n\t\t\tnegated = true;\n\t\t}\n\t\tconst first = this.#expectName(\"a test name\");\n\t\tlet name = first.value;\n\t\tlet nameEnd = first.end;\n\t\tconst second = this.#peek();\n\t\t// Tests can be two words, such as `divisible by`. An unknown pair is kept together, so the error names the whole test.\n\t\tif (\n\t\t\tsecond.type === \"name\" &&\n\t\t\t(this.#options.isTest(`${name} ${second.value}`) ||\n\t\t\t\t(!this.#options.isTest(name) && !NOT_TEST_WORDS.has(second.value)))\n\t\t) {\n\t\t\tthis.#next();\n\t\t\tname = `${name} ${second.value}`;\n\t\t\tnameEnd = second.end;\n\t\t}\n\t\tconst args = this.#isPunct(\"(\") ? this.#parseArguments() : [];\n\t\treturn {\n\t\t\ttype: \"Test\",\n\t\t\tname,\n\t\t\tnameSpan: { start: first.start, end: nameEnd },\n\t\t\tinput,\n\t\t\targs,\n\t\t\tnegated,\n\t\t\tspan: { start: input.span.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseRange(): Expression {\n\t\tconst left = this.#parseConcat();\n\t\tif (this.#isPunct(\"..\")) {\n\t\t\tthis.#next();\n\t\t\treturn this.#binary(\"..\", left, this.#parseConcat());\n\t\t}\n\t\treturn left;\n\t}\n\n\t#parseConcat(): Expression {\n\t\tlet left = this.#parseAdditive();\n\t\twhile (this.#isPunct(\"~\")) {\n\t\t\tthis.#next();\n\t\t\tleft = this.#binary(\"~\", left, this.#parseAdditive());\n\t\t}\n\t\treturn left;\n\t}\n\n\t#parseAdditive(): Expression {\n\t\tlet left = this.#parseMultiplicative();\n\t\twhile (this.#isPunct(\"+\") || this.#isPunct(\"-\")) {\n\t\t\tconst operator = this.#next().value as \"+\" | \"-\";\n\t\t\tleft = this.#binary(operator, left, this.#parseMultiplicative());\n\t\t}\n\t\treturn left;\n\t}\n\n\t#parseMultiplicative(): Expression {\n\t\tlet left = this.#parseUnary();\n\t\tfor (;;) {\n\t\t\tconst token = this.#peek();\n\t\t\tif (\n\t\t\t\ttoken.type === \"punct\" &&\n\t\t\t\t(token.value === \"*\" ||\n\t\t\t\t\ttoken.value === \"/\" ||\n\t\t\t\t\ttoken.value === \"//\" ||\n\t\t\t\t\ttoken.value === \"%\")\n\t\t\t) {\n\t\t\t\tthis.#next();\n\t\t\t\tleft = this.#binary(\n\t\t\t\t\ttoken.value as BinaryOperator,\n\t\t\t\t\tleft,\n\t\t\t\t\tthis.#parseUnary(),\n\t\t\t\t);\n\t\t\t} else return left;\n\t\t}\n\t}\n\n\t#parseUnary(): Expression {\n\t\tthis.#enter();\n\t\ttry {\n\t\t\treturn this.#parseUnaryInner();\n\t\t} finally {\n\t\t\tthis.#nesting--;\n\t\t}\n\t}\n\n\t#parseUnaryInner(): Expression {\n\t\tif (this.#isPunct(\"-\") || this.#isPunct(\"+\")) {\n\t\t\tconst token = this.#next();\n\t\t\tconst operand = this.#parseUnary();\n\t\t\treturn {\n\t\t\t\ttype: \"Unary\",\n\t\t\t\toperator: token.value as \"-\" | \"+\",\n\t\t\t\toperand,\n\t\t\t\tspan: { start: token.start, end: operand.span.end },\n\t\t\t};\n\t\t}\n\t\treturn this.#parsePower();\n\t}\n\n\t#parsePower(): Expression {\n\t\tconst base = this.#parsePostfix();\n\t\tif (this.#isPunct(\"**\")) {\n\t\t\tthis.#next();\n\t\t\treturn this.#binary(\"**\", base, this.#parseUnary());\n\t\t}\n\t\treturn base;\n\t}\n\n\t#parsePostfix(): Expression {\n\t\tlet expression = this.#parsePrimary();\n\t\tlet optional = false;\n\t\tconst start = expression.span.start;\n\t\tconst span = () => ({ start, end: this.#lastEnd });\n\t\tconst closeChain = () => {\n\t\t\tif (optional) {\n\t\t\t\texpression = { type: \"OptionalChain\", expression, span: span() };\n\t\t\t\toptional = false;\n\t\t\t}\n\t\t};\n\n\t\tfor (;;) {\n\t\t\tif (this.#isPunct(\".\") || this.#isPunct(\"?.\")) {\n\t\t\t\tconst isOptional = this.#next().value === \"?.\";\n\t\t\t\tif (isOptional) optional = true;\n\t\t\t\tif (isOptional && this.#isPunct(\"[\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tconst property = this.#parseExpression();\n\t\t\t\t\tthis.#expectPunct(\"]\");\n\t\t\t\t\texpression = {\n\t\t\t\t\t\ttype: \"Member\",\n\t\t\t\t\t\tobject: expression,\n\t\t\t\t\t\tproperty,\n\t\t\t\t\t\toptional: true,\n\t\t\t\t\t\tspan: span(),\n\t\t\t\t\t};\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst token = this.#peek();\n\t\t\t\tif (token.type === \"name\") {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\texpression = {\n\t\t\t\t\t\ttype: \"Member\",\n\t\t\t\t\t\tobject: expression,\n\t\t\t\t\t\tproperty: {\n\t\t\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\t\t\tvalue: token.value,\n\t\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptional: isOptional,\n\t\t\t\t\t\tspan: span(),\n\t\t\t\t\t};\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (token.type === \"number\" && /^\\d+$/.test(token.value)) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\texpression = {\n\t\t\t\t\t\ttype: \"Member\",\n\t\t\t\t\t\tobject: expression,\n\t\t\t\t\t\tproperty: {\n\t\t\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\t\t\tvalue: Number(token.value),\n\t\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t\t},\n\t\t\t\t\t\toptional: isOptional,\n\t\t\t\t\t\tspan: span(),\n\t\t\t\t\t};\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthis.#fail(\n\t\t\t\t\t`Expected a property name but found ${describeToken(token)}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (this.#isPunct(\"[\")) {\n\t\t\t\tthis.#next();\n\t\t\t\tconst property = this.#parseExpression();\n\t\t\t\tthis.#expectPunct(\"]\");\n\t\t\t\texpression = {\n\t\t\t\t\ttype: \"Member\",\n\t\t\t\t\tobject: expression,\n\t\t\t\t\tproperty,\n\t\t\t\t\toptional: false,\n\t\t\t\t\tspan: span(),\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (this.#isPunct(\"(\")) {\n\t\t\t\tconst callee = expression;\n\t\t\t\tif (callee.type !== \"Name\" && callee.type !== \"Member\") {\n\t\t\t\t\tthis.#fail(\n\t\t\t\t\t\t\"Only named functions, macros and exposed methods can be called\",\n\t\t\t\t\t\tthis.#peek(),\n\t\t\t\t\t\t\"invalid-call\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst args = this.#parseArguments();\n\t\t\t\texpression = { type: \"Call\", callee, args, span: span() };\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (this.#isPunct(\"|\")) {\n\t\t\t\tcloseChain();\n\t\t\t\tthis.#next();\n\t\t\t\tconst nameToken = this.#expectName(\"a filter name\");\n\t\t\t\tconst args = this.#isPunct(\"(\") ? this.#parseArguments() : [];\n\t\t\t\texpression = {\n\t\t\t\t\ttype: \"Filter\",\n\t\t\t\t\tname: nameToken.value,\n\t\t\t\t\tnameSpan: { start: nameToken.start, end: nameToken.end },\n\t\t\t\t\tinput: expression,\n\t\t\t\t\targs,\n\t\t\t\t\tspan: span(),\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcloseChain();\n\t\t\treturn expression;\n\t\t}\n\t}\n\n\t#parsePrimary(): Expression {\n\t\tconst token = this.#peek();\n\t\tconst tokenSpan = { start: token.start, end: token.end };\n\n\t\tswitch (token.type) {\n\t\t\tcase \"number\":\n\t\t\t\tthis.#next();\n\t\t\t\treturn { type: \"Literal\", value: Number(token.value), span: tokenSpan };\n\t\t\tcase \"string\":\n\t\t\t\tthis.#next();\n\t\t\t\treturn { type: \"Literal\", value: token.value, span: tokenSpan };\n\t\t\tcase \"stringStart\":\n\t\t\t\treturn this.#parseInterpolation();\n\t\t\tcase \"name\": {\n\t\t\t\tswitch (token.value) {\n\t\t\t\t\tcase \"true\":\n\t\t\t\t\tcase \"false\":\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\t\t\tvalue: token.value === \"true\",\n\t\t\t\t\t\t\tspan: tokenSpan,\n\t\t\t\t\t\t};\n\t\t\t\t\tcase \"null\":\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\treturn { type: \"Literal\", value: null, span: tokenSpan };\n\t\t\t\t\tcase \"and\":\n\t\t\t\t\tcase \"or\":\n\t\t\t\t\tcase \"not\":\n\t\t\t\t\tcase \"in\":\n\t\t\t\t\tcase \"is\":\n\t\t\t\t\t\tthis.#fail(`Expected a value but found \"${token.value}\"`);\n\t\t\t\t}\n\t\t\t\tif (this.#isPunct(\"=>\", 1)) {\n\t\t\t\t\tthis.#fail(\n\t\t\t\t\t\t\"Arrow functions can only be passed as arguments to filters, functions and methods\",\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\"invalid-arrow\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthis.#next();\n\t\t\t\treturn { type: \"Name\", name: token.value, span: tokenSpan };\n\t\t\t}\n\t\t\tcase \"punct\":\n\t\t\t\tswitch (token.value) {\n\t\t\t\t\tcase \"[\":\n\t\t\t\t\t\treturn this.#parseArray();\n\t\t\t\t\tcase \"{\":\n\t\t\t\t\t\treturn this.#parseHash();\n\t\t\t\t\tcase \"(\": {\n\t\t\t\t\t\tif (this.#arrowAhead()) {\n\t\t\t\t\t\t\tthis.#fail(\n\t\t\t\t\t\t\t\t\"Arrow functions can only be passed as arguments to filters, functions and methods\",\n\t\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\t\t\"invalid-arrow\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\tconst inner = this.#parseExpression();\n\t\t\t\t\t\tthis.#expectPunct(\")\");\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...inner,\n\t\t\t\t\t\t\tspan: { start: token.start, end: this.#lastEnd },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t}\n\t\treturn this.#fail(`Expected a value but found ${describeToken(token)}`);\n\t}\n\n\t#parseInterpolation(): Expression {\n\t\tconst start = this.#next();\n\t\tconst parts: Expression[] = [];\n\t\tfor (;;) {\n\t\t\tconst token = this.#peek();\n\t\t\tif (token.type === \"stringEnd\") {\n\t\t\t\tthis.#next();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (token.type === \"string\") {\n\t\t\t\tthis.#next();\n\t\t\t\tparts.push({\n\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\tvalue: token.value,\n\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (token.type === \"interpOpen\") {\n\t\t\t\tthis.#next();\n\t\t\t\tparts.push(this.#parseExpression());\n\t\t\t\tconst close = this.#peek();\n\t\t\t\tif (close.type !== \"interpClose\") {\n\t\t\t\t\tthis.#fail(`Expected \"}\" but found ${describeToken(close)}`);\n\t\t\t\t}\n\t\t\t\tthis.#next();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthis.#fail(`Unexpected ${describeToken(token)} in string`);\n\t\t}\n\t\treturn {\n\t\t\ttype: \"Interpolation\",\n\t\t\tparts,\n\t\t\tspan: { start: start.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseSpread(): Spread {\n\t\tconst token = this.#next();\n\t\tconst value = this.#parseExpression();\n\t\treturn {\n\t\t\ttype: \"Spread\",\n\t\t\tvalue,\n\t\t\tspan: { start: token.start, end: value.span.end },\n\t\t};\n\t}\n\n\t#parseArray(): Expression {\n\t\tconst open = this.#next();\n\t\tconst elements: (Expression | Spread)[] = [];\n\t\twhile (!this.#isPunct(\"]\")) {\n\t\t\telements.push(\n\t\t\t\tthis.#isPunct(\"...\") ? this.#parseSpread() : this.#parseExpression(),\n\t\t\t);\n\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\tthis.#next();\n\t\t}\n\t\tthis.#expectPunct(\"]\");\n\t\treturn {\n\t\t\ttype: \"Array\",\n\t\t\telements,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t#parseHash(): Expression {\n\t\tconst open = this.#next();\n\t\tconst entries: HashEntry[] = [];\n\t\twhile (!this.#isPunct(\"}\")) {\n\t\t\tif (this.#isPunct(\"...\")) {\n\t\t\t\tentries.push(this.#parseSpread());\n\t\t\t} else {\n\t\t\t\tconst token = this.#peek();\n\t\t\t\tlet key: Expression;\n\t\t\t\tif (token.type === \"name\") {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tkey = {\n\t\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\t\tvalue: token.value,\n\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t};\n\t\t\t\t\tif (!this.#isPunct(\":\")) {\n\t\t\t\t\t\t// Shorthand: { title } means { title: title }. `loop` and `slots` are reserved but can be read.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tRESERVED_NAMES.has(token.value) &&\n\t\t\t\t\t\t\ttoken.value !== \"loop\" &&\n\t\t\t\t\t\t\ttoken.value !== \"slots\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.#fail(`Expected \":\" after \"${token.value}\"`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tentries.push({\n\t\t\t\t\t\t\ttype: \"Property\",\n\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\tvalue: {\n\t\t\t\t\t\t\t\ttype: \"Name\",\n\t\t\t\t\t\t\t\tname: token.value,\n\t\t\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\t\t\t\tthis.#next();\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t} else if (token.type === \"string\" || token.type === \"number\") {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tkey = {\n\t\t\t\t\t\ttype: \"Literal\",\n\t\t\t\t\t\t// A number key is the number as JavaScript writes it, so `1.0` and `01` are the key \"1\".\n\t\t\t\t\t\tvalue:\n\t\t\t\t\t\t\ttoken.type === \"number\"\n\t\t\t\t\t\t\t\t? String(Number(token.value))\n\t\t\t\t\t\t\t\t: token.value,\n\t\t\t\t\t\tspan: { start: token.start, end: token.end },\n\t\t\t\t\t};\n\t\t\t\t} else if (this.#isPunct(\"(\")) {\n\t\t\t\t\tthis.#next();\n\t\t\t\t\tkey = this.#parseExpression();\n\t\t\t\t\tthis.#expectPunct(\")\");\n\t\t\t\t} else {\n\t\t\t\t\tthis.#fail(`Expected a hash key but found ${describeToken(token)}`);\n\t\t\t\t}\n\t\t\t\tthis.#expectPunct(\":\");\n\t\t\t\tconst value = this.#parseExpression();\n\t\t\t\tentries.push({\n\t\t\t\t\ttype: \"Property\",\n\t\t\t\t\tkey,\n\t\t\t\t\tvalue,\n\t\t\t\t\tspan: { start: token.start, end: value.span.end },\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\tthis.#next();\n\t\t}\n\t\tthis.#expectPunct(\"}\");\n\t\treturn {\n\t\t\ttype: \"Hash\",\n\t\t\tentries,\n\t\t\tspan: { start: open.start, end: this.#lastEnd },\n\t\t};\n\t}\n\n\t/** Checks whether the tokens at the cursor start an arrow function such as `(a, b) =>`. */\n\t#arrowAhead(): boolean {\n\t\tif (this.#peek().type === \"name\") return this.#isPunct(\"=>\", 1);\n\t\tif (!this.#isPunct(\"(\")) return false;\n\t\tlet offset = 1;\n\t\tif (this.#isPunct(\")\", offset)) return this.#isPunct(\"=>\", offset + 1);\n\t\tfor (;;) {\n\t\t\tif (this.#peek(offset).type !== \"name\") return false;\n\t\t\toffset++;\n\t\t\tif (this.#isPunct(\")\", offset)) return this.#isPunct(\"=>\", offset + 1);\n\t\t\tif (!this.#isPunct(\",\", offset)) return false;\n\t\t\toffset++;\n\t\t}\n\t}\n\n\t#parseArrow(): Expression {\n\t\tconst start = this.#peek();\n\t\tconst params: string[] = [];\n\t\tif (start.type === \"name\") {\n\t\t\tparams.push(this.#expectDeclarableName(\"a parameter name\").value);\n\t\t} else {\n\t\t\tthis.#next();\n\t\t\twhile (!this.#isPunct(\")\")) {\n\t\t\t\tparams.push(this.#expectDeclarableName(\"a parameter name\").value);\n\t\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\t\tthis.#next();\n\t\t\t}\n\t\t\tthis.#expectPunct(\")\");\n\t\t}\n\t\tthis.#expectPunct(\"=>\");\n\t\tconst body = this.#parseExpression();\n\t\treturn {\n\t\t\ttype: \"Arrow\",\n\t\t\tparams,\n\t\t\tbody,\n\t\t\tspan: { start: start.start, end: body.span.end },\n\t\t};\n\t}\n\n\t#parseArguments(): Argument[] {\n\t\tthis.#expectPunct(\"(\");\n\t\tconst args: Argument[] = [];\n\t\tlet named = false;\n\t\twhile (!this.#isPunct(\")\")) {\n\t\t\tconst token = this.#peek();\n\t\t\tif (this.#isPunct(\"...\")) {\n\t\t\t\tif (named) {\n\t\t\t\t\tthis.#fail(\n\t\t\t\t\t\t\"Positional arguments cannot follow named arguments\",\n\t\t\t\t\t\tthis.#peek(),\n\t\t\t\t\t\t\"positional-after-named\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\targs.push(this.#parseSpread());\n\t\t\t} else if (token.type === \"name\" && this.#isPunct(\":\", 1)) {\n\t\t\t\tthis.#next();\n\t\t\t\tthis.#next();\n\t\t\t\tnamed = true;\n\t\t\t\tconst value = this.#arrowAhead()\n\t\t\t\t\t? this.#parseArrow()\n\t\t\t\t\t: this.#parseExpression();\n\t\t\t\targs.push({\n\t\t\t\t\ttype: \"Named\",\n\t\t\t\t\tname: token.value,\n\t\t\t\t\tvalue,\n\t\t\t\t\tspan: { start: token.start, end: value.span.end },\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tif (named) {\n\t\t\t\t\tthis.#fail(\n\t\t\t\t\t\t\"Positional arguments cannot follow named arguments\",\n\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t\"positional-after-named\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst value = this.#arrowAhead()\n\t\t\t\t\t? this.#parseArrow()\n\t\t\t\t\t: this.#parseExpression();\n\t\t\t\targs.push({ type: \"Positional\", value, span: value.span });\n\t\t\t}\n\t\t\tif (!this.#isPunct(\",\")) break;\n\t\t\tthis.#next();\n\t\t}\n\t\tthis.#expectPunct(\")\");\n\t\treturn args;\n\t}\n}\n"],"mappings":";;AAgPA,MAAa,eAAe;AAE5B,MAAa,oBAA+C;CAC3D;CACA;CACA;CACA;CACA;AACD;;AAGA,MAAa,aAAa;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;AChMA,MAAM,cAAc;CACnB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD;;AAGA,MAAM,2CAA2B,IAAI,IAAsB;AAC3D,KAAK,MAAM,SAAS,aAAa;CAChC,MAAM,OAAO,MAAM,WAAW,CAAC;CAC/B,MAAM,OAAO,yBAAyB,IAAI,IAAI;CAC9C,IAAI,MAAM,KAAK,KAAK,KAAK;MACpB,yBAAyB,IAAI,MAAM,CAAC,KAAK,CAAC;AAChD;;;;;AAMA,MAAM,gBACL,MACA,KACA,MACA,SACmB;CACnB,QAAQ,MAAR;EACC,KAAK;GACJ,IAAI,SAAS,IAAI,OAAO,KAAK,WAAW,MAAM,CAAC,MAAM,KAAK,QAAQ;GAClE,OAAO;EACR,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,OAAO;EACvE,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO;EAC7B,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO;EAC7B,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO,SAAS,KAAK,OAAO;EAClD,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO;EAC7B,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO;EAC7B,KAAK,IACJ,OAAO,SAAS,KAAK,OAAO;EAC7B,SAAS;GACR,MAAM,SAAS,mBAAmB;GAClC,OAAO,WAAW,KAAA,IAAY,OAAO;EACtC;CACD;AACD;;AAGA,MAAM,qBAA6C,CAAC;AACpD,KAAK,MAAM,SAAS,aAAa;CAChC,MAAM,OAAO,MAAM,WAAW,CAAC;CAC/B,IAAK,yBAAyB,IAAI,IAAI,CAAC,CAAc,WAAW,GAC/D,mBAAmB,QAAQ;AAE7B;AAEA,MAAM,SAAS;CAAE,QAAQ;CAAM,MAAM;AAAM;AAC3C,MAAM,cAAc;CAAE,QAAQ;CAAM,MAAM;AAAK;AAC/C,MAAM,aAAa;CAAE,QAAQ;CAAO,MAAM;AAAM;AAEhD,MAAM,UAAkC;CACvC,GAAG;CACH,GAAG;CACH,GAAG;CACH,MAAM;CACN,KAAK;CACL,MAAK;AACN;AAEA,MAAM,eAAe;AAErB,MAAM,iBAAiB,SACtB,SAAS,MAAM,SAAS,KAAK,SAAS,MAAM,SAAS,MAAM,SAAS;AACrE,MAAM,WAAW,SAAiB,SAAS,MAAM,cAAc,IAAI;AACnE,MAAM,eAAe,SACnB,QAAQ,MAAM,QAAQ,OAAS,QAAQ,MAAM,QAAQ,MAAO,SAAS;AACvE,MAAM,WAAW,SAAiB,QAAQ,MAAM,QAAQ;AACxD,MAAM,cAAc,SAAiB,YAAY,IAAI,KAAK,QAAQ,IAAI;;;;;;AAOtE,MAAa,OAAO,SAA4B,IAAI,MAAM,IAAI,CAAC,CAAC,IAAI;;;;AAKpE,MAAa,aACZ,SAC+C,IAAI,MAAM,IAAI,CAAC,CAAC,KAAK;;AAGrE,MAAa,gBAAgB,SAC5B,KAAK,WAAW,CAAC,MAAM,QAAS,IAAI;AAErC,IAAM,QAAN,MAAY;CACX;CACA;;CAEA,kBAAkB;CAClB,UAAmB,CAAC;CACpB,YAAmC,CAAC;CAEpC,YAAY,MAAc;EACzB,KAAK,QAAQ;EACb,KAAK,OAAO,aAAa,IAAI;CAC9B;CAEA,OAAkD;EACjD,OAAO;GAAE,OAAO,KAAK,WAAW;GAAG,UAAU,KAAK;EAAU;CAC7D;CAEA,MAAiB;EAChB,MAAM,QAAQ,KAAK,WAAW;EAC9B,iBAAiB,KAAK,OAAO,KAAK;EAClC,MAAM,aAAa,qBAAqB,KAAK,OAAO,KAAK;EACzD,MAAM,QAAQ,UAAU,KAAK,OAAO,OAAO,UAAU;EAErD,MAAM,SAAkB,CAAC;EACzB,KAAK,MAAM,QAAQ,OAClB,IAAI,KAAK,SAAS,QACb;OAAA,KAAK,OAAO,KAAK,IACpB,OAAO,KAAK;IACX,MAAM;IACN,OAAO,KAAK,MAAM,MAAM,KAAK,MAAM,KAAK,EAAE;IAC1C,OAAO,KAAK;IACZ,KAAK,KAAK;GACX,CAAC;EAAA,OAEI,IAAI,KAAK,SAAS,WACxB,KAAK,MAAM,SAAS,KAAK,QAAQ,OAAO,KAAK,KAAK;EAGpD,OAAO,KAAK;GACX,MAAM;GACN,OAAO;GACP,OAAO,KAAK,MAAM;GAClB,KAAK,KAAK,MAAM;EACjB,CAAC;EACD,OAAO;GAAE;GAAQ,UAAU,KAAK;GAAW;GAAY;EAAM;CAC9D;CAEA,aAAqB;EACpB,MAAM,OAAO,KAAK;EAClB,MAAM,QAAgB,CAAC;EACvB,MAAM,YAAY,OAAe,QAAgB;GAChD,IAAI,MAAM,OACT,MAAM,KAAK;IAAE,MAAM;IAAQ;IAAO;IAAK,MAAM;IAAO,IAAI;GAAI,CAAC;EAE/D;EAEA,OAAO,KAAK,OAAO,KAAK,QAAQ;GAC/B,MAAM,OAAO,KAAK,UAAU,KAAK,IAAI;GACrC,IAAI,SAAS,IAAI;IAChB,SAAS,KAAK,MAAM,KAAK,MAAM;IAC/B;GACD;GACA,SAAS,KAAK,MAAM,IAAI;GAExB,MAAM,OAAO,KAAK,OAAO;GACzB,IAAI,SAAS,KAAK;IACjB,MAAM,KAAK,KAAK,aAAa,IAAI,CAAC;IAClC;GACD;GAEA,MAAM,OAAO,KAAK,eAAe,MAAM,SAAS,MAAM,WAAW,KAAK;GACtE,MAAM,KAAK,IAAI;GAEf,MAAM,QAAQ,KAAK;GACnB,IACC,KAAK,SAAS,SACd,MAAM,WAAW,KACjB,MAAM,EAAE,EAAE,SAAS,UACnB,MAAM,EAAE,CAAC,UAAU,YAEnB,KAAK,cAAc,MAAM,KAAK;EAEhC;EACA,OAAO;CACR;CAEA,UAAU,MAAsB;EAC/B,MAAM,OAAO,KAAK;EAClB,IAAI,QAAQ,KAAK,QAAQ,KAAK,IAAI;EAClC,OAAO,UAAU,IAAI;GACpB,MAAM,OAAO,KAAK,WAAW,QAAQ,CAAC;GAEtC,IAAI,SAAS,OAAO,SAAS,MAAM,SAAS,IAAI,OAAO;GACvD,QAAQ,KAAK,QAAQ,KAAK,QAAQ,CAAC;EACpC;EACA,OAAO;CACR;CAEA,aAAa,MAA6B;EACzC,MAAM,OAAO,KAAK;EAClB,MAAM,QAAQ,KAAK,QAAQ,MAAM,OAAO,CAAC;EACzC,MAAM,aAAa,KAAK,OAAO,OAAO;EACtC,IAAI,UAAU,IAAI;GACjB,KAAK,SACJ,oBACA,yCACA,MACA,OAAO,CACR;GACA,KAAK,OAAO,KAAK;GACjB,OAAO;IACN,MAAM;IACN,OAAO;IACP,KAAK,KAAK;IACV;IACA,WAAW;IACX,QAAQ,CAAC;GACV;EACD;EACA,KAAK,OAAO,QAAQ;EACpB,OAAO;GACN,MAAM;GACN,OAAO;GACP,KAAK,QAAQ;GACb;GACA,WAAW,QAAQ,OAAO,KAAK,KAAK,QAAQ,OAAO;GACnD,QAAQ,CAAC;EACV;CACD;CAEA,eAAe,MAAc,MAAuC;EACnE,MAAM,OAAO,KAAK;EAClB,MAAM,aAAa,KAAK,OAAO,OAAO;EACtC,KAAK,UAAU,CACd;GACC,MAAM,SAAS,WAAW,eAAe;GACzC,OAAO,KAAK,MAAM,MAAM,QAAQ,aAAa,IAAI,EAAE;GACnD,OAAO;GACP,KAAK,OAAO;EACb,CACD;EACA,KAAK,OAAO,QAAQ,aAAa,IAAI;EAErC,MAAM,aAAa,KAAK;EACxB,MAAM,EAAE,MAAM,WAAW,KAAK,eAAe,IAAI;EACjD,MAAM,MAAM,KAAK;EACjB,IAAI,CAAC,QACJ,KAAK,SACJ,gBACA,SAAS,WACN,yCACA,qCACH,MACA,OAAO,CACR;EAED,KAAK,QAAQ,KAAK;GACjB,MAAM,SAAS,WAAW,gBAAgB;GAC1C,OAAO,SAAS,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM,GAAG,GAAG,IAAI;GAC5D,OAAO,SAAS,MAAM,IAAI,KAAK,IAAI,YAAY,GAAG;GAClD;EACD,CAAC;EACD,OAAO;GACN;GACA,OAAO;GACP;GACA;GACA,WAAW;GACX,QAAQ,KAAK;EACd;CACD;;CAGA,cAAc,KAAoB,OAAqB;EACtD,MAAM,OAAO,KAAK;EAClB,aAAa,YAAY,KAAK;EAC9B,MAAM,QAAQ,aAAa,KAAK,IAAI;EACpC,IAAI,CAAC,OAAO;GACX,KAAK,SACJ,kBACA,mDACA,IAAI,OACJ,IAAI,GACL;GACA,MAAM,KAAK;IACV,MAAM;IACN,OAAO,KAAK;IACZ,KAAK,KAAK;IACV,MAAM,KAAK;IACX,IAAI,KAAK;GACV,CAAC;GACD,KAAK,OAAO,KAAK;GACjB;EACD;EAEA,MAAM,QAAQ,MAAM;EACpB,MAAM,MAAM,QAAQ,MAAM,EAAE,CAAC;EAC7B,IAAI,QAAQ,KAAK,MAChB,MAAM,KAAK;GACV,MAAM;GACN,OAAO,KAAK;GACZ,KAAK;GACL,MAAM,KAAK;GACX,IAAI;EACL,CAAC;EAEF,MAAM,YAAY,KAAK,QAAQ,eAAe,KAAK;EACnD,MAAM,aAAa,MAAM,OAAO;EAChC,MAAM,YAAY,MAAM,OAAO;EAC/B,MAAM,KAAK;GACV,MAAM;GACN;GACA;GACA;GACA;GAEA,QAAQ;IACP;KACC,MAAM;KACN,OAAO,aAAa,QAAQ;KAC5B;KACA,KAAK,QAAQ;IACd;IACA;KACC,MAAM;KACN,OAAO;KACP,OAAO;KACP,KAAK,YAAY;IAClB;IACA;KACC,MAAM;KACN,OAAO,YAAY,QAAQ;KAC3B,OAAO,MAAM;KACb;IACD;GACD;EACD,CAAC;EACD,KAAK,OAAO;CACb;;;;;;CAOA,eAAe,MAA0D;EACxE,MAAM,OAAO,KAAK;EAClB,MAAM,SAAS,KAAK;EACpB,MAAM,SAAS,KAAK;EACpB,IAAI,QAAQ;EAEZ,IAAI,MAAM,KAAK;EAEf,SAAS;GACR,OAAO,MAAM,UAAU,QAAQ,KAAK,WAAW,GAAG,CAAC,GAAG;GACtD,IAAI,OAAO,QAAQ;IAClB,KAAK,OAAO;IACZ,OAAO;GACR;GAEA,MAAM,OAAO,KAAK,WAAW,GAAG;GAChC,MAAM,OAAO,KAAK,WAAW,MAAM,CAAC;GAEpC,IAAI,SAAS,OAAO;IAEnB,IAAI,SAAS,MAAM,SAAS,MAAM,KAAK,WAAW,MAAM,CAAC,MAAM,KAAK;KACnE,KAAK,OAAO,MAAM;KAClB,OAAO;IACR;IACA,IAAI,SAAS,MAAM,SAAS,KAAK;KAChC,KAAK,OAAO,MAAM;KAClB,OAAO;IACR;GACD,OAAO,IAAI,SAAS,YAAY,UAAU,GAAG;IAE5C,IAAI,SAAS,MAAM,SAAS,OAAO,KAAK,WAAW,MAAM,CAAC,MAAM,KAAK;KACpE,KAAK,OAAO,MAAM;KAClB,OAAO;IACR;IACA,IAAI,SAAS,OAAO,SAAS,KAAK;KACjC,KAAK,OAAO,MAAM;KAClB,OAAO;IACR;GACD,OAAO,IAAI,SAAS,YAAY,UAAU,KAAK,SAAS,KAAK;IAC5D,OAAO,KAAK;KACX,MAAM;KACN,OAAO;KACP,OAAO;KACP,KAAK,MAAM;IACZ,CAAC;IACD,KAAK,OAAO,MAAM;IAClB,OAAO;GACR;GAGA,IAAI,SAAS,QAAQ,SAAS,OAAO,SAAS,MAAM,SAAS,KAAK;IACjE,KAAK,OAAO;IACZ,OAAO;GACR;GACA,IAAI,SAAS,YAAY,SAAS,MAAM,SAAS,KAAK;IACrD,KAAK,OAAO;IACZ,OAAO;GACR;GAEA,IAAI,YAAY,IAAI,GAAG;IACtB,IAAI,MAAM,MAAM;IAChB,OAAO,MAAM,UAAU,WAAW,KAAK,WAAW,GAAG,CAAC,GAAG;IACzD,OAAO,KAAK;KACX,MAAM;KACN,OAAO,KAAK,MAAM,KAAK,GAAG;KAC1B,OAAO;KACP;IACD,CAAC;IACD,MAAM;IACN;GACD;GACA,IAAI,QAAQ,IAAI,GAAG;IAClB,KAAK,OAAO;IACZ,KAAK,WAAW;IAChB,MAAM,KAAK;IACX;GACD;GACA,IAAI,SAAS,MAAM,SAAS,IAAI;IAC/B,KAAK,OAAO;IACZ,KAAK,WAAW;IAChB,MAAM,KAAK;IACX;GACD;GAEA,MAAM,QAAQ,aAAa,MAAM,KAAK,MAAM,IAAI;GAChD,IAAI,UAAU,MAAM;IACnB,IAAI,SAAS,KAAK;SACb,IAAI,SAAS,OAAO,QAAQ,GAAG;IACpC,OAAO,KAAK;KACX,MAAM;KACN,OAAO;KACP,OAAO;KACP,KAAK,MAAM,MAAM;IAClB,CAAC;IACD,OAAO,MAAM;IACb;GACD;GAGA,MAAM,YAAY,OAAO,cAAc,KAAK,YAAY,GAAG,CAAW;GACtE,KAAK,SACJ,wBACA,yBAAyB,UAAU,IACnC,KACA,MAAM,UAAU,MACjB;GACA,OAAO,UAAU;EAClB;CACD;CAEA,aAAmB;EAClB,MAAM,OAAO,KAAK;EAClB,MAAM,QAAQ,KAAK;EACnB,MAAM,WAAW,KAAK,QAAQ,KAAK,QAAQ,SAAS;EAEpD,MAAM,cACL,UAAU,SAAS,YAClB,SAAS,UAAU,OAAO,SAAS,UAAU;EAE/C,MAAM,mBAAmB;GACxB,OAAO,KAAK,OAAO,KAAK,QAAQ;IAC/B,MAAM,OAAO,KAAK,WAAW,KAAK,IAAI;IACtC,IAAI,QAAQ,IAAI,GAAG,KAAK;SACnB,IAAI,SAAS,MAAM,QAAQ,KAAK,WAAW,KAAK,OAAO,CAAC,CAAC,GAC7D,KAAK;SACC;GACR;EACD;EAEA,WAAW;EACX,IACC,CAAC,eACD,KAAK,KAAK,UAAU,OACpB,QAAQ,KAAK,WAAW,KAAK,OAAO,CAAC,CAAC,GACrC;GACD,KAAK;GACL,WAAW;EACZ;EACA,MAAM,MAAM,KAAK,MAAM,OAAO,KAAK,IAAI;EACvC,KAAK,MAAM,UAAU,IAAI,WAAW,KAAK,EAAE,GAAG,OAAO,KAAK,IAAI;CAC/D;CAEA,aAAmB;EAClB,MAAM,OAAO,KAAK;EAClB,MAAM,QAAQ,KAAK;EACnB,MAAM,QAAQ,KAAK;EACnB,IAAI,QAAQ;EACZ,IAAI,eAAe;EACnB,IAAI,eAAe;EACnB,KAAK;EAEL,OAAO,KAAK,OAAO,KAAK,QAAQ;GAC/B,MAAM,OAAO,KAAK,KAAK;GAEvB,IAAI,SAAS,OAAO;IACnB,KAAK;IACL,IAAI,cAAc;KACjB,IAAI,UAAU,IACb,KAAK,MAAM,UAAU,OAAO,cAAc,KAAK,OAAO,CAAC;KAExD,KAAK,MAAM,aAAa,OAAO,KAAK,OAAO,GAAG,KAAK,IAAI;IACxD,OACC,KAAK,MAAM,UAAU,OAAO,OAAO,KAAK,IAAI;IAE7C;GACD;GAEA,IAAI,SAAS,MAAM;IAClB,SAAS,KAAK,YAAY,KAAe;IACzC;GACD;GAEA,IAAI,UAAU,QAAO,SAAS,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK;IACjE,IAAI,CAAC,cAAc;KAClB,eAAe;KACf,KAAK,MAAM,eAAe,OAAO,OAAO,QAAQ,CAAC;IAClD;IACA,IAAI,UAAU,IAAI;KACjB,KAAK,MAAM,UAAU,OAAO,cAAc,KAAK,IAAI;KACnD,QAAQ;IACT;IACA,KAAK,MAAM,cAAc,MAAM,KAAK,MAAM,KAAK,OAAO,CAAC;IACvD,KAAK,QAAQ;IACb,MAAM,cAAc,KAAK;IAEzB,IAAI,KAAK,oBAAA,KAAiC;KACzC,KAAK,SACJ,YACA,gDACA,cAAc,GACd,WACD;KACA,KAAK,mBAAmB;KACxB,eAAe,KAAK;KACpB;IACD;IACA,KAAK;IACL,MAAM,EAAE,WAAW,KAAK,eAAe,QAAQ;IAC/C,KAAK;IACL,IAAI,CAAC,QAAQ;KACZ,KAAK,SACJ,0BACA,8CACA,cAAc,GACd,WACD;KACA,KAAK,MAAM,eAAe,IAAI,KAAK,MAAM,KAAK,IAAI;KAClD,KAAK,MAAM,aAAa,IAAI,KAAK,MAAM,KAAK,IAAI;KAChD;IACD;IACA,eAAe,KAAK;IACpB;GACD;GAEA,SAAS;GACT,KAAK;EACN;EAEA,KAAK,SACJ,mBACA,uCACA,OACA,QAAQ,CACT;EACA,IAAI,cAAc;GACjB,IAAI,UAAU,IAAI,KAAK,MAAM,UAAU,OAAO,cAAc,KAAK,IAAI;GACrE,KAAK,MAAM,aAAa,IAAI,KAAK,MAAM,KAAK,IAAI;EACjD,OACC,KAAK,MAAM,UAAU,OAAO,OAAO,KAAK,IAAI;CAE9C;;CAGA,qBAA2B;EAC1B,MAAM,OAAO,KAAK;EAClB,IAAI,QAAQ;EACZ,OAAO,KAAK,OAAO,KAAK,QAAQ;GAC/B,MAAM,OAAO,KAAK,KAAK;GACvB,IAAI,SAAS,KAAK;QACb,IAAI,SAAS,OAAO,YAAY,GAAG;IACvC,KAAK,MAAM,eAAe,KAAK,KAAK,OAAO,GAAG,KAAK,IAAI;IACvD;GACD;EACD;CACD;;CAGA,YAAY,OAAuB;EAClC,MAAM,OAAO,KAAK;EAClB,MAAM,QAAQ,KAAK;EACnB,MAAM,OAAO,KAAK,QAAQ;EAC1B,IAAI,SAAS,KAAA,GAAW;GACvB,KAAK;GACL,OAAO;EACR;EACA,IAAI,SAAS,OAAO,UAAU,QAAO,KAAK,QAAQ,OAAO,KAAK;GAC7D,KAAK,QAAQ;GACb,OAAO;EACR;EACA,MAAM,SAAS,QAAQ;EACvB,IAAI,WAAW,KAAA,GAAW;GACzB,KAAK,QAAQ;GACb,OAAO;EACR;EACA,IAAI,SAAS,OAAO,KAAK,QAAQ,OAAO,KAAK;GAE5C,MAAM,QAAQ,KAAK,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC,QAAQ,GAAG;GAC3D,MAAM,QAAQ,UAAU,KAAK,KAAK,QAAQ,IAAI;GAC9C,MAAM,MAAM,UAAU,KAAK,KAAK,KAAK,MAAM,QAAQ,GAAG,KAAK;GAC3D,IAAI,qBAAqB,KAAK,GAAG,GAAG;IACnC,MAAM,OAAO,OAAO,SAAS,KAAK,EAAE;IACpC,IAAI,QAAQ,SAAU;KACrB,KAAK,OAAO,QAAQ;KACpB,OAAO,OAAO,cAAc,IAAI;IACjC;GACD;EACD;EACA,KAAK,SACJ,kBACA,8BAA8B,KAAK,IACnC,OACA,QAAQ,CACT;EACA,KAAK,QAAQ;EACb,OAAO;CACR;CAEA,MAAM,MAAiB,OAAe,OAAe,KAAmB;EACvE,KAAK,QAAQ,KAAK;GAAE;GAAM;GAAO;GAAO;EAAI,CAAC;CAC9C;CAEA,SAAS,MAAc,SAAiB,OAAe,KAAmB;EACzE,KAAK,UAAU,KAAK;GAAE;GAAM;GAAS,MAAM;IAAE;IAAO;GAAI;EAAE,CAAC;CAC5D;AACD;;AAGA,MAAM,oBAAoB,MAAc,UAAwB;CAC/D,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACtC,MAAM,OAAO,MAAM;EACnB,IAAI,KAAK,SAAS,QAAQ;EAE1B,MAAM,WAAW,MAAM,IAAI;EAC3B,IAAI,KAAK,cAAc,UAAU,SAAS,QAAQ;GACjD,IAAI,MAAM,SAAS;GACnB,OAAO,MAAM,SAAS,SAAS,QAAQ,KAAK,WAAW,MAAM,CAAC,CAAC,GAAG;GAClE,SAAS,KAAK,KAAK,IAAI,SAAS,IAAI,GAAG;EACxC;EACA,MAAM,OAAO,MAAM,IAAI;EACvB,IAAI,KAAK,aAAa,MAAM,SAAS,QAAQ;GAC5C,IAAI,QAAQ,KAAK;GACjB,OAAO,QAAQ,KAAK,OAAO,QAAQ,KAAK,WAAW,KAAK,CAAC,GAAG;GAC5D,KAAK,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK;EACtC;CACD;AACD;AAEA,MAAM,iBAAiB,MAAc,OAAe,QAAyB;CAC5E,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAC5B,IAAI,CAAC,cAAc,KAAK,WAAW,CAAC,CAAC,GAAG,OAAO;CAEhD,OAAO;AACR;;;;;AAMA,MAAM,aAAa,MAAc,OAAe,QAAwB;CACvE,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,KAC5B,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,OAAO;CAEvC,OAAO;AACR;;AAGA,MAAM,iBAAiB,MAAc,OAAe,QAAwB;CAC3E,KAAK,IAAI,IAAI,MAAM,GAAG,KAAK,OAAO,KACjC,IAAI,KAAK,WAAW,CAAC,MAAM,IAAI,OAAO;CAEvC,OAAO;AACR;;;;;;AAOA,MAAM,wBACL,MACA,UACyB;CACzB,MAAM,0BAAU,IAAI,IAAoB;CACxC,MAAM,eAAe,SACpB,SAAS,KAAA,MAAc,KAAK,SAAS,SAAS,KAAK,SAAS;CAE7D,IAAI,IAAI;CACR,OAAO,IAAI,MAAM,QAAQ;EACxB,IAAI,CAAC,YAAY,MAAM,EAAE,GAAG;GAC3B;GACA;EACD;EAGA,IAAI,OAAO;EACX,SAAS;GACR,MAAM,OAAO,MAAM,OAAO;GAC1B,IAAI,YAAY,IAAI,GAAG;IACtB;IACA;GACD;GACA,IACC,MAAM,SAAS,UACf,cAAc,MAAM,KAAK,OAAO,KAAK,GAAG,KACxC,YAAY,MAAM,OAAO,EAAE,GAC1B;IACD,QAAQ;IACR;GACD;GACA;EACD;EAEA,IAAI,aAAa;EACjB,IAAI,YAAY;EAChB,MAAM,WAAW,MAAM,IAAI;EAC3B,IAAI,UAAU;GACb,IAAI,SAAS,SAAS,QAAQ,aAAa;QACtC;IACJ,MAAM,UAAU,cAAc,MAAM,SAAS,OAAO,SAAS,GAAG;IAChE,IAAI,YAAY,IAAI;KACnB,IAAI,cAAc,MAAM,UAAU,GAAG,SAAS,GAAG,GAChD,YAAY,UAAU;UAChB,aAAa;IACrB,OAAO,IACN,IAAI,MAAM,KACV,cAAc,MAAM,SAAS,OAAO,SAAS,GAAG,GAEhD,YAAY,SAAS;SACf,aAAa;GACrB;EACD;EAEA,IAAI,WAAW;EACf,MAAM,OAAO,MAAM,OAAO;EAC1B,IAAI,cAAc,MAAM;GACvB,IAAI,KAAK,SAAS,QAAQ,aAAa;QAClC;IACJ,MAAM,UAAU,UAAU,MAAM,KAAK,OAAO,KAAK,GAAG;IACpD,IAAI,YAAY,IAAI;KACnB,IAAI,cAAc,MAAM,KAAK,OAAO,OAAO,GAC1C,WAAW,UAAU;UACf,aAAa;IACrB,OAAO,IACN,OAAO,MAAM,MAAM,SAAS,KAC5B,cAAc,MAAM,KAAK,OAAO,KAAK,GAAG,GAExC,WAAW,KAAK;SACV,aAAa;GACrB;EACD;EAEA,IAAI,YAAY;GACf,IAAI,UAAU,SAAS,QACtB,SAAS,KAAK,KAAK,IAAI,SAAS,IAAI,SAAS;GAE9C,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,KAAK;IAC/B,MAAM,OAAO,MAAM;IACnB,IAAI,KAAK,SAAS,QAAQ,KAAK,OAAO,KAAK;SACtC,QAAQ,IAAI,KAAK,OAAO,KAAK,GAAG;GACtC;GACA,IAAI,MAAM,SAAS,QAAQ,KAAK,OAAO,KAAK,IAAI,KAAK,MAAM,QAAQ;EACpE;EACA,IAAI,OAAO;CACZ;CACA,OAAO;AACR;;AAGA,MAAM,aACL,MACA,OACA,YACgB;CAChB,MAAM,QAAoB,CAAC;CAC3B,MAAM,OAAO,UAAkB;EAC9B,IAAI,YAAY;EAChB,OAAO,KAAK,eAAe,OAAO,KAAK,eAAe,KAAM;EAC5D,MAAM,OAAO,KAAK;EAClB,IAAI,SAAS,KAAA,KAAa,SAAS,QAAQ,SAAS,MAAM;EAC1D,IAAI,QAAQ,IAAI,SAAS,GAAG;EAC5B,MAAM,KAAK;GAAE;GAAO;EAAU,CAAC;CAChC;CACA,KAAK,MAAM,QAAQ,OAAO;EACzB,IAAI,KAAK,SAAS,QAAQ;EAC1B,KACC,IAAI,UAAU,UAAU,MAAM,KAAK,OAAO,KAAK,GAAG,GAClD,YAAY,IACZ,UAAU,UAAU,MAAM,UAAU,GAAG,KAAK,GAAG,GAC9C;GACD,MAAM,QAAQ,UAAU;GAExB,IAAI,QAAQ,KAAK,QAAQ,QAAQ,KAAK,IAAI;GAC1C,IAAI,KAAK;EACV;CACD;CACA,OAAO;AACR;;;;ACj4BA,MAAM,YAAY,SAA4B;CAC7C,MAAM,OAAO,WAAgC;EAC5C,MAAM,KAAK,KAAK;EAChB,KAAK,KAAK,KAAK;EACf;CACD;CACA,QAAQ,KAAK,MAAb;EACC,KAAK,MACJ,OAAO,CACN,IAAI,CACH,GAAG,KAAK,SAAS,KAAK,WAAW,OAAO,IAAI,GAC5C,KAAK,aAAa,CAAC,CACpB,CAAC,CACF;EACD,KAAK,OACJ,OAAO,CAAC,IAAI,CAAC,KAAK,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,CAAC;EAC/C,KAAK,aACJ,OAAO,CACN,GAAG,KAAK,MAAM,KAAK,UAAU;GAC5B,MAAM,KAAK,KAAK;GAChB,KAAK,KAAK,KAAK;GACf,OAAO,CAAC,KAAK,IAAI;EAClB,EAAE,GACF,IAAI,CAAC,KAAK,MAAM,GAAG,KAAK,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,CACxD;EACD,KAAK,UACJ,OAAO,CAAC;GAAE,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;GAAG,MAAM;EAAK,CAAC;EAC5C,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,cACJ,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;EACzB,SACC,OAAO;CACT;AACD;AAEA,MAAM,YAAoB,CAAC;;AAG3B,MAAM,cAAc,WACnB,OAAO,WAAW,IACd,OAAO,EAAE,CAAU,QACpB,IAAI,IAAI,OAAO,SAAS,SAAS,KAAK,KAAK,CAAC;;AAGhD,MAAM,gBACL,OACA,OACA,QACY;CACZ,IAAI,MAAM;CACV,IAAI,OAAO,MAAM;CACjB,OAAO,MAAM,MAAM;EAClB,MAAM,SAAU,MAAM,SAAU;EAChC,IAAI,IAAI,MAAM,OAAY,IAAI,OAAO,MAAM,SAAS;OAC/C,OAAO;CACb;CACA,OAAO;AACR;;;;;AAMA,MAAM,SACL;AAED,MAAM,gBAAgB;;AAGtB,MAAM,gBACL,MACA,eACwB;CAExB,IAAI,CAAC,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC;CAGvC,IAAI,UAAU;CACd,KAAK,MAAM,SAAS,YAAY;EAC/B,WAAW,KAAK,OAAO,MAAM,QAAQ,QAAQ,MAAM;EACnD,WAAW,KAAK,MAAM,MAAM,OAAO,MAAM,GAAG;CAC7C;CACA,MAAM,SAA6B,CAAC;CACpC,IAAI,OAA+C;CACnD,OAAO,YAAY;CACnB,KAAK,IAAI,QAAQ,OAAO,KAAK,OAAO,GAAG,OAAO,QAAQ,OAAO,KAAK,OAAO,GAAG;EAC3E,MAAM,MAAM,MAAM;EAClB,IAAI,QAAQ,KAAA,GAAW;EACvB,MAAM,OAAO,IAAI,YAAY;EAC7B,IAAI,SAAS,QAAQ,MAAM,OAAO,IAAI,OAAO;GAAE;GAAM,OAAO,MAAM;EAAM;OACnE,IAAI,MAAM,SAAS,QAAQ,MAAM,OAAO,KAAK;GACjD,OAAO,KAAK,CAAC,KAAK,OAAO,MAAM,KAAK,CAAC;GACrC,OAAO;EACR;CACD;CACA,IAAI,MAAM,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,MAAM,CAAC;CAC/C,OAAO;AACR;;;;;;;;;;;AAYA,MAAa,qBACZ,KACA,MACA,EAAE,QAAQ,YAAY,SACtB,YACU;CACV,MAAM,aAAa,OAAO,QAAQ,UAAU,MAAM,SAAS,MAAM;CACjE,MAAM,MAAM,aAAa,MAAM,UAAU;CACzC,MAAM,SAAS,WAA4B;EAC1C,MAAM,QAAQ,IAAI,aAAa,KAAK,SAAS,UAAU,MAAM,EAAE;EAC/D,OAAO,UAAU,KAAA,KAAa,MAAM,KAAK;CAC1C;CACA,MAAM,YACL,IAAI,SAAS,IAAI,MAAM,QAAQ,SAAS,CAAC,MAAM,KAAK,KAAK,CAAC,IAAI;CAG/D,MAAM,aAAa,WAClB,KAAK,YAAY,MAAM,SAAS,CAAC,IAAI,KAAK,aAAa,IAAI;CAC5D,MAAM,UAAU,WAA6B;EAC5C,MAAM,QAAQ,UAAU,MAAM;EAC9B,IAAI,YAAY;EAChB,OAAO,KAAK,eAAe,OAAO,KAAK,eAAe,KAAM;EAC5D,OAAO;GAAE;GAAO;EAAU;CAC3B;CAGA,MAAM,cAIA,CAAC;CACP,KAAK,MAAM,QAAQ,SAAS;EAC3B,IAAI,MAAM,KAAK,KAAK,KAAK,GAAG;EAC5B,MAAM,MAAM,KAAK,YAAY,MAAM,KAAK,KAAK,MAAM,CAAC;EACpD,MAAM,OAAO,WAAW,IAAI,KAAK,KAAK,KAAK,IACxC,OAAO,KAAK,KAAK,KAAK,IACtB;EACH,MAAM,QAAQ,WAAW,IAAI,GAAG,IAAI,OAAO,GAAG,IAAI;EAClD,IAAI,QAAQ,OAAO,YAAY,KAAK;GAAE;GAAM;GAAM,KAAK;EAAM,CAAC;CAC/D;CACA,MAAM,eACL,YAAY,SAAS,IAClB,CACA,GAAG,WACH,GAAG,YAAY,SAAS,SACvB,CAAC,KAAK,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,SAAS,SAAS,IAAI,CACrD,CACD,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,IACjC;CAGJ,MAAM,OAA2B,CAAC;CAElC,MAAM,YAAY,WAA2B;EAC5C,MAAM,OAAO,OAAO,MAAM;EAC1B,OAAO,KAAK,MAAM,KAAK,OAAO,KAAK,SAAS;CAC7C;CAEA,MAAM,QAAQ,SAAqB;EAClC,IAAI,KAAK,MAAM;EACf,MAAM,UAAU,WAAW,IAAI,KAAK,IAAI;EACxC,IAAI,YAAY,KAAA,GAAW;EAC3B,MAAM,UAAU,KAAK,QAAQ,MAAM,OAAO;EAC1C,IAAI,YAAY,IAAI;EAEpB,MAAM,KAAK,KAAK,YAAY,MAAM,KAAK,MAAM,CAAC;EAC9C,MAAM,QAAQ,aAAa,cAAc,UAAU,IAAI,SAAS,KAAK,KAAK;EAC1E,MAAM,OAAO,aAAa,cAAc,KAAK,SAAS,KAAK,KAAK;EAChE,IAAI,SAAS,MAAM;EAEnB,MAAM,MAAM,SAAS,KAAK,IAAI;EAC9B,IAAI,SAAS;EACb,MAAM,YAAY,aAAa;EAC/B,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM,KAAK;GAClC,MAAM,OAAO,aAAa;GAC1B,IAAI,SAAS;GACb,OACC,SAAS,KAAK,YAAY,KAAK,SAC/B,KAAK,KAAK,QAAQ,YAAY,KAAK,UAAU,QAAQ,SAErD;GAED,SAAS,KAAK,IAAI,QAAQ,MAAM;EACjC;EACA,IAAI,UAAU,IAAI,QAAQ;EAC1B,IAAI,KAAK,MAAM,UAAU,OAAO,UAAU,QAAQ,IAAI,MAAM,MAAM,KACjE;EACD,KAAK,IAAI,IAAI,OAAO,IAAI,MAAM,KAAK;GAClC,MAAM,OAAO,aAAa;GAC1B,KAAK,KAAK,CAAC,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,MAAM,CAAC;EACzD;CACD;CAEA,MAAM,SAAS,SAA4B;EAC1C,KAAK,MAAM,QAAQ,MAAM;GACxB,MAAM,SAAS,SAAS,IAAI;GAC5B,IAAI,OAAO,WAAW,GAAG;GACzB,KAAK,MAAM,SAAS,WAAW,MAAM,GAAG,MAAM,KAAK;GACnD,KAAK,MAAM,QAAQ,QAAQ,KAAK,IAAI;EACrC;CACD;CACA,MAAM,IAAI,IAAI;CAGd,KAAK,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,EAAE;CAC/B,MAAM,SAA6B,CAAC;CACpC,KAAK,MAAM,SAAS,MAAM;EACzB,MAAM,WAAW,OAAO,OAAO,SAAS;EACxC,IAAI,YAAY,MAAM,MAAM,SAAS,IACpC,SAAS,KAAK,KAAK,IAAI,SAAS,IAAI,MAAM,EAAE;OACtC,OAAO,KAAK,KAAK;CACzB;;CAGA,MAAM,SAAS,OAAe,QAAwB;EACrD,IAAI,MAAM;EACV,IAAI,KAAK;EACT,KACC,IAAI,IAAI,aAAa,QAAQ,QAAQ,UAAU,MAAM,KAAK,CAAC,GAC3D,IAAI,OAAO,QACX,KACC;GACD,MAAM,CAAC,MAAM,MAAM,OAAO;GAC1B,IAAI,QAAQ,KAAK;GACjB,OAAO,KAAK,MAAM,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC;GACxC,KAAK,KAAK,IAAI,IAAI,EAAE;EACrB;EACA,OAAO,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAG,GAAG,GAAG;CAC/C;CAEA,KAAK,MAAM,EAAE,MAAM,MAAM,SAAS,aAAa;EAC9C,IAAI,MAAM,KAAK,SAAS,MAAM,KAAK,OAAO,KAAK,SAAS;EACxD,IAAI,KAEH,KAAK,UAAU;GACd,QAFgB,SAAS,QAAQ,IAAI,UAAU,KAAK,QAEjC,OAAO,MAAM,IAAI,OAAO,IAAI,SAAS;GACxD,SAAS,KAAK,SAAS,MAAM,KAAK,KAAK,GAAG;EAC3C;CAEF;CACA,IAAI,OAAO,WAAW,GAAG;CAEzB,MAAM,UAAU,OAAe,QAAyB;EACvD,MAAM,QAAQ,OAAO,aAAa,QAAQ,QAAQ,UAAU,MAAM,KAAK,CAAC;EACxE,OAAO,UAAU,KAAA,KAAa,MAAM,KAAK;CAC1C;CAGA,MAAM,WAAW,SAA4B;EAC5C,KAAK,MAAM,QAAQ,MAAM;GACxB,IAAI,KAAK,SAAS,UAAU,OAAO,KAAK,KAAK,OAAO,KAAK,KAAK,GAAG,GAAG;IACnE,IAAI,QAAQ;IACZ,KACC,IAAI,IAAI,aAAa,YAAY,KAAK,KAAK,QAAQ,MAAM,EAAE,KAAK,GAChE,IAAI,WAAW,QACf,KACC;KACD,MAAM,QAAQ,WAAW;KACzB,IAAI,MAAM,MAAM,KAAK,KAAK,KAAK;KAC/B,SAAS,MAAM,MAAM,OAAO,MAAM,GAAG;IACtC;IACA,KAAK,QAAQ;GACd;GACA,MAAM,SAAS,SAAS,IAAI;GAC5B,IAAI,OAAO,SAAS,GACnB,KAAK,MAAM,SAAS,WAAW,MAAM,GAAG,QAAQ,KAAK;EAEvD;CACD;CACA,QAAQ,IAAI,IAAI;AACjB;;;AC/QA,MAAM,cAAc,SAClB,WAAiC,SAAS,IAAI;;AAUhD,MAAa,iCAAiB,IAAI,IAAI;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC;;AAGD,MAAa,SAAS,MAAc,YAAuC;CAC1E,MAAM,QAAQ,IAAI,IAAI;CACtB,MAAM,SAAS,IAAI,OAAO,MAAM,QAAQ,OAAO;CAC/C,MAAM,MAAM,OAAO,cAAc,KAAK,MAAM;CAC5C,kBAAkB,KAAK,MAAM,OAAO,OAAO,OAAO;CAClD,OAAO;EAAE;EAAK,UAAU,CAAC,GAAG,MAAM,UAAU,GAAG,OAAO,QAAQ;CAAE;AACjE;AAEA,IAAM,eAAN,MAAmB;CAER;CACA;CACA;CAHV,YACC,MACA,SACA,MACC;EAHQ,KAAA,OAAA;EACA,KAAA,UAAA;EACA,KAAA,OAAA;CACP;AACJ;;AASA,MAAM,iCAAiB,IAAI,IAAI;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC;AAED,MAAM,yCAAyB,IAAI,IAAI;CAAC;CAAM;CAAM;CAAK;CAAK;CAAM;AAAI,CAAC;AAEzE,MAAM,iBAAiB,UAAyB;CAC/C,QAAQ,MAAM,MAAd;EACC,KAAK,OACJ,OAAO;EACR,KAAK,YACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,KAAK,eACJ,OAAO;EACR,KAAK,UACJ,OAAO,UAAU,MAAM;EACxB,SACC,OAAO,IAAI,MAAM,MAAM;CACzB;AACD;AAEA,IAAM,SAAN,MAAa;CACZ,WAAkC,CAAC;;CAEnC,UAAsC,CAAC;CACvC;CACA;CACA,SAAS;CACT,WAAW;CACX,WAAW;;CAEX,YAA4C,CAAC;CAE7C,YAAY,QAAiB,SAAuB;EACnD,KAAK,UAAU;EACf,KAAK,WAAW;CACjB;CAEA,cAAc,QAA8B;EAC3C,MAAM,EAAE,SAAS,KAAK,WAAW,CAAC,CAAC;EACnC,OAAO;GAAE,MAAM;GAAY;GAAM,MAAM;IAAE,OAAO;IAAG,KAAK;GAAO;EAAE;CAClE;CAIA,MAAM,SAAS,GAAU;EACxB,OACC,KAAK,QAAQ,KAAK,SAAS,WAC1B,KAAK,QAAQ,KAAK,QAAQ,SAAS;CAEtC;CAEA,QAAe;EACd,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,OAAO,KAAK;EAC/B,KAAK,WAAW,MAAM;EACtB,OAAO;CACR;CAEA,SAAS,OAAe,SAAS,GAAY;EAC5C,MAAM,QAAQ,KAAK,MAAM,MAAM;EAC/B,OAAO,MAAM,SAAS,WAAW,MAAM,UAAU;CAClD;CAEA,QAAQ,OAAe,SAAS,GAAY;EAC3C,MAAM,QAAQ,KAAK,MAAM,MAAM;EAC/B,OAAO,MAAM,SAAS,UAAU,MAAM,UAAU;CACjD;CAEA,MACC,SACA,QAAQ,KAAK,MAAM,GACnB,OAAO,oBACC;EACR,MAAM,IAAI,aAAa,MAAM,SAAS;GACrC,OAAO,MAAM;GACb,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,QAAQ,CAAC;EACzC,CAAC;CACF;CAEA,aAAa,OAAsB;EAClC,IAAI,CAAC,KAAK,SAAS,KAAK,GACvB,KAAK,MACJ,aAAa,MAAM,cAAc,cAAc,KAAK,MAAM,CAAC,GAC5D;EAED,OAAO,KAAK,MAAM;CACnB;CAEA,YAAY,OAAO,UAAiB;EACnC,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,QAClB,KAAK,MAAM,YAAY,KAAK,aAAa,cAAc,KAAK,GAAG;EAEhE,OAAO,KAAK,MAAM;CACnB;CAEA,eAAe,OAAsB;EACpC,IAAI,CAAC,KAAK,QAAQ,KAAK,GACtB,KAAK,MACJ,aAAa,MAAM,cAAc,cAAc,KAAK,MAAM,CAAC,GAC5D;EAED,OAAO,KAAK,MAAM;CACnB;CAEA,gBAAuB;EACtB,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,YAClB,KAAK,MAAM,2BAA2B,cAAc,KAAK,GAAG;EAE7D,OAAO,KAAK,MAAM;CACnB;CAEA,sBAAsB,MAAqB;EAC1C,MAAM,QAAQ,KAAK,YAAY,IAAI;EACnC,IAAI,eAAe,IAAI,MAAM,KAAK,GACjC,KAAK,SACJ,iBACA,IAAI,MAAM,MAAM,6CAChB,KACD;EAED,OAAO;CACR;CAEA,SAAS,MAAc,SAAiB,MAAkB;EACzD,KAAK,SAAS,KAAK;GAClB;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAI;EAC1C,CAAC;CACF;;CAGA,WAAiB;EAChB,SAAS;GACR,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,MAAM,SAAS,OAAO;GAC1B,IAAI,MAAM,SAAS,cAAc,MAAM,SAAS,eAAe;IAC9D,KAAK,MAAM;IACX;GACD;GACA,IACC,MAAM,SAAS,UACf,MAAM,SAAS,aACf,MAAM,SAAS,cAEf;GAED,KAAK,MAAM;EACZ;CACD;CAEA,QAAQ,SAAwB;EAC/B,IAAI,EAAE,mBAAmB,eAAe,MAAM;EAC9C,KAAK,SAAS,QAAQ,MAAM,QAAQ,SAAS,QAAQ,IAAI;EACzD,KAAK,SAAS;CACf;;;;CAKA,QAAW,OAAgB,UAAgB;EAC1C,IAAI;GACH,MAAM,SAAS,MAAM;GACrB,KAAK,cAAc;GACnB,OAAO;EACR,SAAS,SAAS;GACjB,KAAK,QAAQ,OAAO;GACpB,OAAO;EACR;CACD;;CAGA,aAAa,OAAwB;EACpC,KAAK,IAAI,SAAS,IAAK,UAAU;GAChC,MAAM,QAAQ,KAAK,MAAM,MAAM;GAC/B,IAAI,MAAM,SAAS,WAAW,MAAM,UAAU,OAAO,OAAO;GAC5D,IACC,MAAM,SAAS,cACf,MAAM,SAAS,SACf,MAAM,SAAS,UACf,MAAM,SAAS,aACf,MAAM,SAAS,cAEf,OAAO;EAET;CACD;CAEA,WAAuB;EACtB,MAAM,QAAQ,KAAK,MAAM;EACzB,OAAO;GAAE,MAAM;GAAW,MAAM;IAAE,OAAO,MAAM;IAAO,KAAK,MAAM;GAAI;EAAE;CACxE;CAIA,WAAW,MAAqC;EAC/C,KAAK,OAAO;EACZ,MAAM,OAAoB,CAAC;EAC3B,KAAK,UAAU,KAAK,IAAI;EACxB,IAAI;GACH,SAAS;IACR,MAAM,QAAQ,KAAK,MAAM;IACzB,QAAQ,MAAM,MAAd;KACC,KAAK,OACJ,OAAO;MAAE;MAAM,KAAK;KAAK;KAC1B,KAAK,QAAQ;MACZ,KAAK,MAAM;MACX,MAAM,WAAW,KAAK,KAAK,SAAS;MACpC,IAAI,UAAU,SAAS,QAAQ;OAC9B,SAAS,SAAS,MAAM;OACxB,SAAS,OAAO;QAAE,OAAO,SAAS,KAAK;QAAO,KAAK,MAAM;OAAI;MAC9D,OACC,KAAK,KAAK;OACT,MAAM;OACN,OAAO,MAAM;OACb,MAAM;QAAE,OAAO,MAAM;QAAO,KAAK,MAAM;OAAI;MAC5C,CAAC;MAEF;KACD;KACA,KAAK;MACJ,KAAK,aAAa,IAAI;MACtB;KACD,KAAK,WAAW;MACf,MAAM,OAAO,KAAK,MAAM,CAAC;MACzB,IAAI,KAAK,SAAS,QAAQ;OACzB,IAAI,KAAK,SAAS,KAAK,KAAK,GAAG;QAC9B,KAAK,MAAM;QACX,KAAK,MAAM;QACX,OAAO;SAAE;SAAM,KAAK;QAAK;OAC1B;OACA,IAAI,KAAK,UAAU,MAAM,UAAU,MAAM,SAAS,KAAK,KAAK,CAAC,GAC5D,OAAO;QAAE;QAAM,KAAK;OAAK;MAE3B;MACA,KAAK,UAAU,IAAI;MACnB;KACD;KACA,SAEC,KAAK,MAAM;IACb;GACD;EACD,UAAU;GACT,KAAK,UAAU,IAAI;GACnB,KAAK;EACN;CACD;CAEA,aAAa,MAAyB;EACrC,MAAM,OAAO,KAAK,MAAM;EACxB,IAAI;GACH,MAAM,aAAa,KAAK,iBAAiB;GACzC,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,MAAM,SAAS,eAClB,KAAK,MAAM,2BAA2B,cAAc,KAAK,GAAG;GAE7D,KAAK,MAAM;GACX,KAAK,KAAK;IACT,MAAM;IACN;IACA,MAAM;KAAE,OAAO,KAAK;KAAO,KAAK,MAAM;IAAI;GAC3C,CAAC;EACF,SAAS,SAAS;GACjB,KAAK,QAAQ,OAAO;EACrB;CACD;CAEA,UAAU,MAAyB;EAClC,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,YAAY,KAAK,MAAM;EAC7B,IAAI,UAAU,SAAS,QAAQ;GAC9B,KAAK,SACJ,oBACA,iCAAiC,cAAc,SAAS,KACxD,SACD;GACA,KAAK,SAAS;GACd;EACD;EACA,KAAK,MAAM;EACX,MAAM,OAAO,UAAU;EAEvB,IAAI;GACH,MAAM,YAAY,KAAK,eAAe,MAAM,MAAM,SAAS;GAC3D,IAAI,WAAW,KAAK,KAAK,SAAS;EACnC,SAAS,SAAS;GACjB,KAAK,QAAQ,OAAO;EACrB;CACD;CAEA,eACC,MACA,MACA,WACmB;EACnB,QAAQ,MAAR;GACC,KAAK,MACJ,OAAO,KAAK,SAAS,IAAI;GAC1B,KAAK,OACJ,OAAO,KAAK,UAAU,IAAI;GAC3B,KAAK,OACJ,OAAO,KAAK,UAAU,IAAI;GAC3B,KAAK,SACJ,OAAO,KAAK,YAAY,IAAI;GAC7B,KAAK,WAAW;IACf,MAAM,WAAW,KAAK,iBAAiB;IACvC,MAAM,QAAQ,KAAK,cAAc;IACjC,OAAO;KACN,MAAM;KACN;KACA,MAAM;MAAE,OAAO,KAAK;MAAO,KAAK,MAAM;KAAI;IAC3C;GACD;GACA,KAAK,SACJ,OAAO,KAAK,YAAY,IAAI;GAC7B,KAAK,WACJ,OAAO,KAAK,cAAc,IAAI;GAC/B,KAAK,aACJ,OAAO,KAAK,gBAAgB,IAAI;GACjC,KAAK,QACJ,OAAO,KAAK,WAAW,IAAI;GAC5B,KAAK,SACJ,OAAO,KAAK,YAAY,IAAI;GAC7B,KAAK,UACJ,OAAO,KAAK,aAAa,IAAI;GAC9B,KAAK,QACJ,OAAO,KAAK,iBAAiB,IAAI;GAClC,KAAK,QACJ,OAAO,KAAK,WAAW,IAAI;GAC5B,KAAK,SACJ,OAAO,KAAK,YAAY,IAAI;GAC7B,KAAK,UACJ,OAAO,KAAK,aAAa,IAAI;GAC9B,KAAK,UAAU;IACd,MAAM,OAAO,KAAK,oBAAoB,gBAAgB;IACtD,MAAM,QAAQ,KAAK,cAAc;IACjC,OAAO;KACN,MAAM;KACN;KACA,MAAM;MAAE,OAAO,KAAK;MAAO,KAAK,MAAM;KAAI;IAC3C;GACD;GACA,KAAK,SAAS;IACb,MAAM,QAAQ,KAAK,cAAc;IACjC,OAAO;KAAE,MAAM;KAAS,MAAM;MAAE,OAAO,KAAK;MAAO,KAAK,MAAM;KAAI;IAAE;GACrE;GACA,KAAK,OACJ,OAAO,KAAK,UAAU,IAAI;GAC3B,KAAK,SACJ,OAAO,KAAK,YAAY,IAAI;GAC7B,KAAK,cACJ,OAAO,KAAK,iBAAiB,IAAI;GAClC,KAAK,YACJ,OAAO,KAAK,eAAe,IAAI;GAChC,SAAS;IACR,MAAM,QACL,KAAK,WAAW,KAAK,KACrB,SAAS,UACT,SAAS,YACT,SAAS;IACV,KAAK,SACJ,QAAQ,mBAAmB,eAC3B,QACG,IAAI,KAAK,sCACT,gBAAgB,KAAK,IACxB,SACD;IACA,KAAK,SAAS;IACd,OAAO;GACR;EACD;CACD;;CAGA,UAAU,MAAc,MAAa,SAAuB;EAC3D,KAAK,SACJ,kBACA,IAAI,KAAK,oBAAoB,QAAQ,QACrC;GAAE,OAAO,KAAK;GAAO,KAAK,KAAK;EAAI,CACpC;CACD;;CAGA,cAAc,cAA6B;EAC1C,IAAI;GACH,IAAI,iBAAiB,KAAA,KAAa,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ;IAC/D,MAAM,WAAW,KAAK,MAAM;IAC5B,IAAI,SAAS,UAAU,cACtB,KAAK,SACJ,kBACA,kBAAkB,SAAS,MAAM,gBAAgB,aAAa,IAC9D,QACD;GAEF;GACA,KAAK,cAAc;EACpB,SAAS,SAAS;GACjB,KAAK,QAAQ,OAAO;EACrB;CACD;CAEA,SAAS,MAAwB;EAChC,MAAM,WAAsD,CAAC;EAC7D,IAAI,OAAO,KAAK,cAAc,KAAK,iBAAiB,GAAG,KAAK,SAAS,CAAC;EACtE,IAAI,YAAgC;EAEpC,SAAS;GACR,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW;IAAC;IAAU;IAAQ;GAAO,CAAC;GACjE,SAAS,KAAK;IAAE;IAAM;GAAK,CAAC;GAC5B,IAAI,CAAC,KAAK;IACT,KAAK,UAAU,MAAM,MAAM,OAAO;IAClC;GACD;GACA,IAAI,IAAI,UAAU,UAAU;IAC3B,OAAO,KAAK,cAAc,KAAK,iBAAiB,GAAG,KAAK,SAAS,CAAC;IAClE;GACD;GACA,IAAI,IAAI,UAAU,QAAQ;IACzB,KAAK,cAAc;IACnB,YAAY,KAAK,gBAAgB,MAAM,MAAM,CAAC,UAAU,MAAM,CAAC;IAC/D;GACD;GACA,KAAK,cAAc;GACnB;EACD;EACA,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;;;;;CAMA,gBAAgB,MAAc,MAAa,UAAiC;EAC3E,MAAM,UAAU,MAAM;EACtB,MAAM,YAAyB,CAAC;EAChC,SAAS;GACR,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,SAAS,GAAG,QAAQ,CAAC;GAC5D,UAAU,KAAK,GAAG,IAAI;GACtB,IAAI,CAAC,KAAK;IACT,KAAK,UAAU,MAAM,MAAM,OAAO;IAClC,OAAO;GACR;GACA,IAAI,IAAI,UAAU,SAAS;IAC1B,KAAK,cAAc;IACnB,OAAO;GACR;GACA,KAAK,SACJ,kBACA,IAAI,IAAI,MAAM,6BAA6B,KAAK,IAChD,GACD;GACA,KAAK,SAAS;EACf;CACD;CAEA,UAAU,MAAwB;EACjC,MAAM,SAAS,KAAK,cACb;GACL,IAAI,UAAyB;GAC7B,IAAI,YAAY,KAAK,sBAAsB,iBAAiB,CAAC,CAAC;GAC9D,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,KAAK,MAAM;IACX,UAAU;IACV,YAAY,KAAK,sBAAsB,iBAAiB,CAAC,CAAC;GAC3D;GACA,KAAK,eAAe,IAAI;GACxB,MAAM,WAAW,KAAK,iBAAiB;GACvC,OAAO;IAAE;IAAS;IAAW;GAAS;EACvC,GACA;GAAE,SAAS;GAAM,WAAW;GAAK,UAAU,KAAK,SAAS;EAAE,CAC5D;EAEA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,QAAQ,QAAQ,CAAC;EACxD,IAAI,YAAgC;EACpC,IAAI,CAAC,KAAK,KAAK,UAAU,OAAO,MAAM,QAAQ;OACzC,IAAI,IAAI,UAAU,QAAQ;GAC9B,KAAK,cAAc;GACnB,YAAY,KAAK,gBAAgB,OAAO,MAAM,CAAC,MAAM,CAAC;EACvD,OAAO,KAAK,cAAc;EAE1B,OAAO;GACN,MAAM;GACN,GAAG;GACH;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,UAAU,MAAwB;EACjC,IAAI,KAAK,aAAa,GAAG,GAAG;GAC3B,MAAM,OAAO,KAAK,sBAAsB,iBAAiB,CAAC,CAAC;GAC3D,KAAK,aAAa,GAAG;GACrB,MAAM,QAAQ,KAAK,iBAAiB;GACpC,MAAM,QAAQ,KAAK,cAAc;GACjC,OAAO;IACN,MAAM;IACN;IACA;IACA,MAAM;KAAE,OAAO,KAAK;KAAO,KAAK,MAAM;IAAI;GAC3C;EACD;EAEA,MAAM,OAAO,KAAK,cACX,KAAK,sBAAsB,iBAAiB,CAAC,CAAC,OACpD,EACD;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,QAAQ,CAAC;EAChD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,OAAO,MAAM,QAAQ;EACzC,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;;CAGA,aAAa,SAAwB,QAAQ,OAAoB;EAChE,MAAM,SAAsB,CAAC;EAE7B,MAAM,aACL,YAAY,OACT,KAAK,MAAM,CAAC,CAAC,SAAS,cAAc,KAAK,SAAS,KAAK,IACvD,KAAK,SAAS,OAAO;EACzB,OAAO,CAAC,KAAK,GAAG;GACf,MAAM,YAAY,KAAK,sBAAsB,kBAAkB;GAC/D,IAAI,OAAO,MAAM,UAAU,MAAM,SAAS,UAAU,KAAK,GACxD,KAAK,SACJ,uBACA,IAAI,UAAU,MAAM,+BACpB,SACD;GAED,IAAI,OAA0B;GAC9B,IAAI,SAAS,KAAK,SAAS,GAAG,GAAG;IAChC,KAAK,MAAM;IACX,OAAO,KAAK,eAAe;GAC5B;GACA,IAAI,eAAkC;GACtC,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,KAAK,MAAM;IACX,eAAe,KAAK,iBAAiB;GACtC;GACA,OAAO,KAAK;IACX,MAAM,UAAU;IAChB;IACA,SAAS;IACT,MAAM;KAAE,OAAO,UAAU;KAAO,KAAK,KAAK;IAAS;GACpD,CAAC;GACD,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;GACzB,KAAK,MAAM;EACZ;EACA,OAAO;CACR;;CAGA,iBAA6B;EAC5B,KAAK,OAAO;EACZ,MAAM,UAAU,KAAK;EACrB,IAAI;GACH,MAAM,UAAsB,CAAC;GAC7B,SAAS;IACR,IAAI,OAAO,KAAK,mBAAmB;IAEnC,OAAO,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,KAAK,CAAC,GAAG;KACnD,KAAK,OAAO;KACZ,KAAK,MAAM;KACX,KAAK,MAAM;KACX,OAAO,CAAC,EAAE,MAAM,KAAK,CAAC;IACvB;IACA,KAAK,WAAW;IAChB,QAAQ,KAAK,GAAG,IAAI;IACpB,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,OAAO;IAChC,KAAK,MAAM;GACZ;EACD,UAAU;GACT,KAAK,WAAW,UAAU;EAC3B;CACD;;CAGA,qBAAiC;EAChC,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,WAAW,MAAM,UAAU,KAAK;GAClD,KAAK,MAAM;GACX,MAAM,QAAQ,KAAK,eAAe;GAClC,KAAK,aAAa,GAAG;GACrB,OAAO;EACR;EACA,IAAI,MAAM,SAAS,WAAW,MAAM,UAAU,KAC7C,OAAO,CAAC,EAAE,OAAO,KAAK,YAAY,EAAE,CAAC;EAEtC,KAAK,MAAM;EACX,IAAI,MAAM,SAAS,UAAU,OAAO,CAAC,EAAE,SAAS,MAAM,MAAM,CAAC;EAC7D,IAAI,MAAM,SAAS,UAAU,OAAO,CAAC,EAAE,SAAS,OAAO,MAAM,KAAK,EAAE,CAAC;EACrE,IAAI,MAAM,SAAS,UAAU,WAAW,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK;EAEzE,IAAI,MAAM,SAAS,UAAU,SAAS,KAAK,MAAM,KAAK,GACrD,OAAO,CAAC,EAAE,OAAO,MAAM,MAAM,CAAC;EAE/B,IAAI,MAAM,SAAS,QAAQ;GAC1B,KAAK,SAAS,gBAAgB,iBAAiB,MAAM,MAAM,IAAI,KAAK;GACpE,OAAO,CAAC;EACT;EACA,OAAO,KAAK,MACX,6BAA6B,cAAc,KAAK,KAChD,KACD;CACD;;CAGA,cAA0B;EACzB,KAAK,aAAa,GAAG;EACrB,MAAM,OAAmB,CAAC;EAC1B,OAAO,CAAC,KAAK,SAAS,GAAG,GAAG;GAC3B,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,MAAM,SAAS,UAAU,MAAM,SAAS,UAC3C,KAAK,MAAM,4BAA4B,cAAc,KAAK,KAAK,KAAK;GAErE,IAAI,KAAK,MAAM,QAAQ,IAAI,SAAS,MAAM,KAAK,GAC9C,KAAK,SACJ,iBACA,IAAI,MAAM,MAAM,+BAChB,KACD;GAGD,MAAM,WAAW,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,GAAG;GACzD,IAAI,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM;QAC/B;IACJ,IAAI,UAAU,KAAK,MAAM;IACzB,KAAK,aAAa,GAAG;GACtB;GACA,KAAK,KAAK;IAAE,MAAM,MAAM;IAAO;IAAU,MAAM,KAAK,eAAe;GAAE,CAAC;GACtE,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;GACzB,KAAK,MAAM;EACZ;EACA,KAAK,aAAa,GAAG;EACrB,OAAO;CACR;CAEA,YAAY,MAAwB;EACnC,MAAM,QAAQ,KAAK,aAAa,MAAM,IAAI;EAC1C,IAAI,OAAsB;EAC1B,IAAI,KAAK,SAAS,KAAK,GAAG;GACzB,KAAK,MAAM;GACX,MAAM,YAAY,KAAK,sBAAsB,kBAAkB;GAC/D,IAAI,MAAM,MAAM,SAAS,KAAK,SAAS,UAAU,KAAK,GACrD,KAAK,SACJ,uBACA,IAAI,UAAU,MAAM,+BACpB,SACD;GAED,OAAO,UAAU;GACjB,IAAI,KAAK,SAAS,GAAG,GAAG,KAAK,MAAM;GACnC,IAAI,KAAK,MAAM,CAAC,CAAC,SAAS,YACzB,KAAK,MAAM,uDAAuD;EAEpE;EACA,MAAM,QAAQ,KAAK,cAAc;EACjC,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,MAAM;GAAI;EAC3C;CACD;CAEA,YAAY,MAA+B;EAE1C,MAAM,QAAQ,KAAK,MAAM;EACzB,IACC,MAAM,SAAS,WACd,MAAM,SAAS,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,aACpD;GACD,KAAK,cAAc;IAClB,KAAK,YAAY,cAAc;GAChC,GAAG,KAAA,CAAS;GACZ,MAAM,EAAE,QAAQ,KAAK,WAAW,CAAC,UAAU,CAAC;GAC5C,IAAI,KAAK,KAAK,cAAc;QACvB,KAAK,UAAU,SAAS,MAAM,UAAU;GAC7C,OAAO;EACR;EACA,MAAM,OAAO,KAAK,YAAY,cAAc,CAAC,CAAC;EAC9C,IAAI,KAAK,MAAM,CAAC,CAAC,SAAS,YAAY;GAErC,MAAM,aAAa,KAAK,iBAAiB;GACzC,MAAM,QAAQ,KAAK,cAAc;GACjC,OAAO;IACN,MAAM;IACN;IACA,MAAM,CACL;KACC,MAAM;KACN;KACA,MAAM;MAAE,OAAO,WAAW,KAAK;MAAO,KAAK,WAAW,KAAK;KAAI;IAChE,CACD;IACA,MAAM;KAAE,OAAO,KAAK;KAAO,KAAK,MAAM;IAAI;GAC3C;EACD;EACA,KAAK,cAAc;EACnB,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,UAAU,CAAC;EAClD,IAAI,KAAK,KAAK,cAAc,IAAI;OAC3B,KAAK,UAAU,SAAS,MAAM,UAAU;EAC7C,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,cAAc,MAAwB;EACrC,MAAM,WAAW,KAAK,iBAAiB;EACvC,IAAI,YAA+B;EACnC,IAAI,gBAAgB;EACpB,IAAI,KAAK,QAAQ,MAAM,GAAG;GACzB,KAAK,MAAM;GACX,YAAY,KAAK,iBAAiB;EACnC;EACA,IAAI,KAAK,QAAQ,QAAQ,GAAG;GAC3B,KAAK,MAAM;GACX,KAAK,eAAe,SAAS;GAC7B,gBAAgB;EACjB;EACA,MAAM,QAAQ,KAAK,cAAc;EACjC,OAAO;GACN,MAAM;GACN;GACA,MAAM;GACN;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,MAAM;GAAI;EAC3C;CACD;CAEA,gBAAgB,MAAwB;EACvC,MAAM,SAAS,KAAK,cACb;GACL,MAAM,WAAW,KAAK,iBAAiB;GACvC,IAAI,YAA+B;GACnC,IAAI,KAAK,QAAQ,MAAM,GAAG;IACzB,KAAK,MAAM;IACX,YAAY,KAAK,iBAAiB;GACnC;GACA,OAAO;IAAE;IAAU,MAAM;GAAU;EACpC,GACA;GAAE,UAAU,KAAK,SAAS;GAAG,MAAM;EAAK,CACzC;EAEA,MAAM,OAAoB,CAAC;EAC3B,MAAM,QAA2D,CAAC;EAClE,SAAS;GACR,MAAM,OAAO,KAAK,WAAW,CAAC,QAAQ,cAAc,CAAC;GACrD,KAAK,KAAK,GAAG,KAAK,IAAI;GACtB,IAAI,CAAC,KAAK,KAAK;IACd,KAAK,UAAU,aAAa,MAAM,cAAc;IAChD;GACD;GACA,IAAI,KAAK,IAAI,UAAU,gBAAgB;IACtC,KAAK,cAAc;IACnB;GACD;GAEA,MAAM,YAAY,KAAK,QAAQ,KAAK,SAAS,MAAM,KAAK;GACxD,MAAM,OAAO,KAAK,cACX,KAAK,oBAAoB,aAAa,GAC5C,EACD;GACA,MAAM,OAAO,KAAK,WAAW,CAAC,SAAS,CAAC;GACxC,IAAI,KAAK,KAAK,KAAK,cAAc;QAC5B,KAAK,UAAU,QAAQ,WAAW,SAAS;GAChD,IAAI,MAAM,MAAM,aAAa,SAAS,SAAS,IAAI,GAClD,KAAK,SACJ,kBACA,SAAS,KAAK,6BACd;IAAE,OAAO,UAAU;IAAO,KAAK,UAAU;GAAI,CAC9C;GAED,MAAM,KAAK;IACV;IACA,MAAM,KAAK;IACX,MAAM;KAAE,OAAO,UAAU;KAAO,KAAK,KAAK;IAAS;GACpD,CAAC;EACF;EAEA,OAAO;GACN,MAAM;GACN,GAAG;GACH;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,oBAAoB,MAAsB;EACzC,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,UAClB,KAAK,MACJ,YAAY,KAAK,yBAAyB,cAAc,KAAK,GAC9D;EAED,KAAK,MAAM;EACX,OAAO,MAAM;CACd;CAEA,WAAW,MAAwB;EAClC,MAAM,OAAO,KAAK,cAEhB,KAAK,MAAM,CAAC,CAAC,SAAS,aACnB,YACA,KAAK,oBAAoB,aAAa,GAC1C,SACD;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,SAAS,CAAC;EACjD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,QAAQ,MAAM,SAAS;EAC3C,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,YAAY,MAAwB;EACnC,MAAM,SAAS,KAAK,cACb;GACL,MAAM,OAAO,KAAK,sBAAsB,cAAc,CAAC,CAAC;GACxD,KAAK,aAAa,GAAG;GACrB,MAAM,SAAS,KAAK,aAAa,GAAG;GACpC,KAAK,aAAa,GAAG;GACrB,OAAO;IAAE;IAAM;GAAO;EACvB,GACA;GAAE,MAAM;GAAI,QAAQ,CAAC;EAAa,CACnC;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,UAAU,CAAC;EAClD,IAAI,KAAK,KAAK,cAAc,OAAO,IAAI;OAClC,KAAK,UAAU,SAAS,MAAM,UAAU;EAC7C,OAAO;GACN,MAAM;GACN,GAAG;GACH;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,aAAa,MAAwB;EACpC,MAAM,WAAW,KAAK,oBAAoB,iBAAiB;EAC3D,KAAK,eAAe,IAAI;EACxB,MAAM,QAAQ,KAAK,sBAAsB,UAAU,CAAC,CAAC;EACrD,MAAM,QAAQ,KAAK,cAAc;EACjC,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,MAAM;GAAI;EAC3C;CACD;CAEA,iBAAiB,MAAwB;EACxC,MAAM,WAAW,KAAK,oBAAoB,iBAAiB;EAC3D,KAAK,eAAe,QAAQ;EAC5B,MAAM,QAAuD,CAAC;EAC9D,GAAG;GACF,IAAI,MAAM,SAAS,GAAG,KAAK,MAAM;GACjC,MAAM,YAAY,KAAK,YAAY,cAAc;GACjD,IAAI,QAAQ,UAAU;GACtB,IAAI,KAAK,QAAQ,IAAI,GAAG;IACvB,KAAK,MAAM;IACX,QAAQ,KAAK,sBAAsB,UAAU,CAAC,CAAC;GAChD;GACA,MAAM,KAAK;IACV,MAAM,UAAU;IAChB;IACA,MAAM;KAAE,OAAO,UAAU;KAAO,KAAK,KAAK;IAAS;GACpD,CAAC;EACF,SAAS,KAAK,SAAS,GAAG;EAC1B,MAAM,QAAQ,KAAK,cAAc;EACjC,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,MAAM;GAAI;EAC3C;CACD;CAEA,WAAW,MAAwB;EAClC,MAAM,QAAQ,KAAK,cAAc,KAAK,iBAAiB,GAAG,KAAK,SAAS,CAAC;EACzE,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,SAAS,CAAC;EACjD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,QAAQ,MAAM,SAAS;EAC3C,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,UAAU,MAAwB;EACjC,MAAM,EAAE,QAAQ,SAAS,KAAK,cACvB;GACL,KAAK,eAAe,IAAI;GACxB,MAAM,SAAS,KAAK,oBAAoB,gBAAgB;GACxD,MAAM,OAAO,KAAK,QAAQ,MAAM;GAChC,IAAI,MAAM,KAAK,MAAM;GACrB,OAAO;IAAE;IAAQ;GAAK;EACvB,GACA;GAAE,QAAQ;GAAI,MAAM;EAAM,CAC3B;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,QAAQ,CAAC;EAChD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,OAAO,MAAM,QAAQ;EACzC,OAAO;GACN,MAAM;GACN;GACA;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,YAAY,MAAwB;EACnC,MAAM,EAAE,KAAK,YAAY,KAAK,cACvB;GACL,MAAM,MAAM,KAAK,iBAAiB;GAClC,IAAI,UAA6B;GACjC,IAAI,KAAK,QAAQ,KAAK,GAAG;IACxB,KAAK,MAAM;IACX,UAAU,KAAK,iBAAiB;GACjC;GACA,OAAO;IAAE;IAAK;GAAQ;EACvB,GACA;GAAE,KAAK,KAAK,SAAS;GAAG,SAAS;EAAK,CACvC;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,UAAU,CAAC;EAClD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,SAAS,MAAM,UAAU;EAC7C,OAAO;GACN,MAAM;GACN;GACA;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,aAAa,MAAwB;EACpC,MAAM,SAAS,KAAK,cACb;GACL,MAAM,WAAW,KAAK,iBAAiB;GACvC,IAAI,YAA+B;GACnC,IAAI,KAAK,QAAQ,MAAM,GAAG;IACzB,KAAK,MAAM;IACX,YAAY,KAAK,iBAAiB;GACnC;GACA,OAAO;IAAE;IAAU,MAAM;GAAU;EACpC,GACA;GAAE,UAAU,KAAK,SAAS;GAAG,MAAM;EAAK,CACzC;EACA,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,WAAW,CAAC;EACnD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,UAAU,MAAM,WAAW;EAC/C,MAAM,SAA0B;GAC/B,MAAM;GACN,GAAG;GACH;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;EACA,KAAK,QAAQ,KAAK,MAAM;EACxB,OAAO;CACR;CAEA,YAAY,MAAwB;EACnC,MAAM,UAAU,KAAK,cAAc;GAClC,MAAM,OAAqB,CAAC;GAC5B,GAAG;IACF,IAAI,KAAK,SAAS,GAAG,KAAK,MAAM;IAChC,MAAM,YAAY,KAAK,YAAY,eAAe;IAClD,MAAM,OAAO,KAAK,SAAS,GAAG,IAAI,KAAK,gBAAgB,IAAI,CAAC;IAC5D,KAAK,KAAK;KACT,MAAM,UAAU;KAChB;KACA,MAAM;MAAE,OAAO,UAAU;MAAO,KAAK,KAAK;KAAS;IACpD,CAAC;GACF,SAAS,KAAK,SAAS,GAAG;GAC1B,OAAO;EACR,GAAG,CAAC,CAAiB;EACrB,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,UAAU,CAAC;EAClD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,SAAS,MAAM,UAAU;EAC7C,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,iBAAiB,MAAwB;EACxC,MAAM,WAAW,KAAK,cAAsC;GAC3D,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,MAAM,SAAS,YAAY,OAAO;GACtC,IAAI,MAAM,SAAS,UAAU,MAAM,UAAU,SAAS;IACrD,KAAK,MAAM;IACX,OAAO;GACR;GACA,MAAM,QAAQ,KAAK,oBAAoB,sBAAsB;GAC7D,IAAI,CAAC,kBAAkB,SAAS,KAAuB,GACtD,KAAK,MACJ,8BAA8B,MAAM,SAAS,kBAAkB,KAAK,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,YAC/F,OACA,kBACD;GAED,OAAO;EACR,GAAG,MAAM;EACT,MAAM,EAAE,MAAM,QAAQ,KAAK,WAAW,CAAC,eAAe,CAAC;EACvD,IAAI,KAAK,KAAK,cAAc;OACvB,KAAK,UAAU,cAAc,MAAM,eAAe;EACvD,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,eAAe,MAA+B;EAC7C,KAAK,cAAc;EACnB,IAAI,QAAQ;EACZ,IAAI,QAAQ,KAAK;EACjB,IAAI,MAAM;EACV,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,QAAQ;GAC1B,KAAK,MAAM;GACX,QAAQ,MAAM;GACd,QAAQ,MAAM;GACd,MAAM,MAAM;EACb;EACA,IAAI,KAAK,MAAM,CAAC,CAAC,SAAS,aAAa,KAAK,QAAQ,eAAe,CAAC,GAAG;GACtE,KAAK,MAAM;GACX,KAAK,MAAM;GACX,KAAK,cAAc;EACpB;EAEA,IAAI,UAAU,IAAI,OAAO;EACzB,OAAO;GACN,MAAM;GACN;GACA,MAAM;IAAE,OAAO,KAAK,IAAI,OAAO,KAAK,GAAG;IAAG;GAAI;EAC/C;CACD;;CAKA,SAAe;EACd,IAAI,EAAE,KAAK,WAAA,KAAwB;GAClC,KAAK;GACL,KAAK,MACJ,gDACA,KAAK,MAAM,GACX,UACD;EACD;CACD;CAEA,mBAA+B;EAC9B,KAAK,OAAO;EACZ,IAAI;GACH,OAAO,KAAK,kBAAkB;EAC/B,UAAU;GACT,KAAK;EACN;CACD;CAEA,oBAAgC;EAC/B,MAAM,OAAO,KAAK,eAAe;EACjC,IAAI,KAAK,SAAS,GAAG,GAAG;GACvB,KAAK,MAAM;GACX,MAAM,aAAa,KAAK,iBAAiB;GACzC,IAAI,YAA+B;GACnC,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,KAAK,MAAM;IACX,YAAY,KAAK,iBAAiB;GACnC;GACA,OAAO;IACN,MAAM;IACN;IACA;IACA;IACA,MAAM;KAAE,OAAO,KAAK,KAAK;KAAO,KAAK,KAAK;IAAS;GACpD;EACD;EACA,IAAI,KAAK,SAAS,IAAI,GAAG;GACxB,KAAK,MAAM;GACX,MAAM,QAAQ,KAAK,iBAAiB;GACpC,OAAO,KAAK,QAAQ,MAAM,MAAM,KAAK;EACtC;EACA,OAAO;CACR;CAEA,QACC,UACA,MACA,OACa;EACb,OAAO;GACN,MAAM;GACN;GACA;GACA;GACA,MAAM;IAAE,OAAO,KAAK,KAAK;IAAO,KAAK,MAAM,KAAK;GAAI;EACrD;CACD;CAEA,iBAA6B;EAC5B,MAAM,OAAO,KAAK,SAAS;EAC3B,IAAI,CAAC,KAAK,SAAS,IAAI,GAAG,OAAO;EACjC,KAAK,MAAM;EAEX,KAAK,OAAO;EACZ,IAAI;GACH,OAAO,KAAK,QAAQ,MAAM,MAAM,KAAK,eAAe,CAAC;EACtD,UAAU;GACT,KAAK;EACN;CACD;CAEA,WAAuB;EACtB,IAAI,OAAO,KAAK,UAAU;EAC1B,OAAO,KAAK,QAAQ,IAAI,GAAG;GAC1B,KAAK,MAAM;GACX,OAAO,KAAK,QAAQ,MAAM,MAAM,KAAK,UAAU,CAAC;EACjD;EACA,OAAO;CACR;CAEA,YAAwB;EACvB,IAAI,OAAO,KAAK,UAAU;EAC1B,OAAO,KAAK,QAAQ,KAAK,GAAG;GAC3B,KAAK,MAAM;GACX,OAAO,KAAK,QAAQ,OAAO,MAAM,KAAK,UAAU,CAAC;EAClD;EACA,OAAO;CACR;CAEA,YAAwB;EACvB,KAAK,OAAO;EACZ,IAAI;GACH,OAAO,KAAK,eAAe;EAC5B,UAAU;GACT,KAAK;EACN;CACD;CAEA,iBAA6B;EAC5B,IAAI,KAAK,QAAQ,KAAK,GAAG;GACxB,MAAM,QAAQ,KAAK,MAAM;GACzB,MAAM,UAAU,KAAK,UAAU;GAC/B,OAAO;IACN,MAAM;IACN,UAAU;IACV;IACA,MAAM;KAAE,OAAO,MAAM;KAAO,KAAK,QAAQ,KAAK;IAAI;GACnD;EACD;EACA,OAAO,KAAK,iBAAiB;CAC9B;;CAGA,mBAGS;EACR,MAAM,QAAQ,KAAK,MAAM;EACzB,IAAI,MAAM,SAAS,WAAW,uBAAuB,IAAI,MAAM,KAAK,GACnE,OAAO;GAAE,UAAU,MAAM;GAAyB,QAAQ;EAAE;EAE7D,IAAI,MAAM,SAAS,QAAQ,OAAO;EAClC,QAAQ,MAAM,OAAd;GACC,KAAK,MACJ,OAAO;IAAE,UAAU;IAAM,QAAQ;GAAE;GACpC,KAAK,MACJ,OAAO;IAAE,UAAU;IAAM,QAAQ;GAAE;GACpC,KAAK,OACJ,OAAO,KAAK,QAAQ,MAAM,CAAC,IAAI;IAAE,UAAU;IAAU,QAAQ;GAAE,IAAI;GACpE,KAAK,UACJ,OAAO,KAAK,QAAQ,QAAQ,CAAC,IAC1B;IAAE,UAAU;IAAe,QAAQ;GAAE,IACrC;GACJ,KAAK,QACJ,OAAO,KAAK,QAAQ,QAAQ,CAAC,IAC1B;IAAE,UAAU;IAAa,QAAQ;GAAE,IACnC;GACJ,SACC,OAAO;EACT;CACD;CAEA,mBAA+B;EAC9B,MAAM,OAAO,KAAK,YAAY;EAC9B,MAAM,QAAQ,KAAK,iBAAiB;EACpC,IAAI,CAAC,OAAO,OAAO;EAEnB,IAAI;EACJ,IAAI,MAAM,aAAa,MACtB,SAAS,KAAK,WAAW,IAAI;OACvB;GACN,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,KAAK,MAAM;GAClD,SAAS,KAAK,QAAQ,MAAM,UAAU,MAAM,KAAK,YAAY,CAAC;EAC/D;EAEA,IAAI,KAAK,iBAAiB,GACzB,KAAK,MACJ,mEACA,KAAK,MAAM,GACX,oBACD;EAED,OAAO;CACR;CAEA,WAAW,OAA+B;EACzC,KAAK,MAAM;EACX,IAAI,UAAU;EACd,IAAI,KAAK,QAAQ,KAAK,GAAG;GACxB,KAAK,MAAM;GACX,UAAU;EACX;EACA,MAAM,QAAQ,KAAK,YAAY,aAAa;EAC5C,IAAI,OAAO,MAAM;EACjB,IAAI,UAAU,MAAM;EACpB,MAAM,SAAS,KAAK,MAAM;EAE1B,IACC,OAAO,SAAS,WACf,KAAK,SAAS,OAAO,GAAG,KAAK,GAAG,OAAO,OAAO,KAC7C,CAAC,KAAK,SAAS,OAAO,IAAI,KAAK,CAAC,eAAe,IAAI,OAAO,KAAK,IAChE;GACD,KAAK,MAAM;GACX,OAAO,GAAG,KAAK,GAAG,OAAO;GACzB,UAAU,OAAO;EAClB;EACA,MAAM,OAAO,KAAK,SAAS,GAAG,IAAI,KAAK,gBAAgB,IAAI,CAAC;EAC5D,OAAO;GACN,MAAM;GACN;GACA,UAAU;IAAE,OAAO,MAAM;IAAO,KAAK;GAAQ;GAC7C;GACA;GACA;GACA,MAAM;IAAE,OAAO,MAAM,KAAK;IAAO,KAAK,KAAK;GAAS;EACrD;CACD;CAEA,cAA0B;EACzB,MAAM,OAAO,KAAK,aAAa;EAC/B,IAAI,KAAK,SAAS,IAAI,GAAG;GACxB,KAAK,MAAM;GACX,OAAO,KAAK,QAAQ,MAAM,MAAM,KAAK,aAAa,CAAC;EACpD;EACA,OAAO;CACR;CAEA,eAA2B;EAC1B,IAAI,OAAO,KAAK,eAAe;EAC/B,OAAO,KAAK,SAAS,GAAG,GAAG;GAC1B,KAAK,MAAM;GACX,OAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,eAAe,CAAC;EACrD;EACA,OAAO;CACR;CAEA,iBAA6B;EAC5B,IAAI,OAAO,KAAK,qBAAqB;EACrC,OAAO,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;GAChD,MAAM,WAAW,KAAK,MAAM,CAAC,CAAC;GAC9B,OAAO,KAAK,QAAQ,UAAU,MAAM,KAAK,qBAAqB,CAAC;EAChE;EACA,OAAO;CACR;CAEA,uBAAmC;EAClC,IAAI,OAAO,KAAK,YAAY;EAC5B,SAAS;GACR,MAAM,QAAQ,KAAK,MAAM;GACzB,IACC,MAAM,SAAS,YACd,MAAM,UAAU,OAChB,MAAM,UAAU,OAChB,MAAM,UAAU,QAChB,MAAM,UAAU,MAChB;IACD,KAAK,MAAM;IACX,OAAO,KAAK,QACX,MAAM,OACN,MACA,KAAK,YAAY,CAClB;GACD,OAAO,OAAO;EACf;CACD;CAEA,cAA0B;EACzB,KAAK,OAAO;EACZ,IAAI;GACH,OAAO,KAAK,iBAAiB;EAC9B,UAAU;GACT,KAAK;EACN;CACD;CAEA,mBAA+B;EAC9B,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,GAAG,GAAG;GAC7C,MAAM,QAAQ,KAAK,MAAM;GACzB,MAAM,UAAU,KAAK,YAAY;GACjC,OAAO;IACN,MAAM;IACN,UAAU,MAAM;IAChB;IACA,MAAM;KAAE,OAAO,MAAM;KAAO,KAAK,QAAQ,KAAK;IAAI;GACnD;EACD;EACA,OAAO,KAAK,YAAY;CACzB;CAEA,cAA0B;EACzB,MAAM,OAAO,KAAK,cAAc;EAChC,IAAI,KAAK,SAAS,IAAI,GAAG;GACxB,KAAK,MAAM;GACX,OAAO,KAAK,QAAQ,MAAM,MAAM,KAAK,YAAY,CAAC;EACnD;EACA,OAAO;CACR;CAEA,gBAA4B;EAC3B,IAAI,aAAa,KAAK,cAAc;EACpC,IAAI,WAAW;EACf,MAAM,QAAQ,WAAW,KAAK;EAC9B,MAAM,cAAc;GAAE;GAAO,KAAK,KAAK;EAAS;EAChD,MAAM,mBAAmB;GACxB,IAAI,UAAU;IACb,aAAa;KAAE,MAAM;KAAiB;KAAY,MAAM,KAAK;IAAE;IAC/D,WAAW;GACZ;EACD;EAEA,SAAS;GACR,IAAI,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAAG;IAC9C,MAAM,aAAa,KAAK,MAAM,CAAC,CAAC,UAAU;IAC1C,IAAI,YAAY,WAAW;IAC3B,IAAI,cAAc,KAAK,SAAS,GAAG,GAAG;KACrC,KAAK,MAAM;KACX,MAAM,WAAW,KAAK,iBAAiB;KACvC,KAAK,aAAa,GAAG;KACrB,aAAa;MACZ,MAAM;MACN,QAAQ;MACR;MACA,UAAU;MACV,MAAM,KAAK;KACZ;KACA;IACD;IACA,MAAM,QAAQ,KAAK,MAAM;IACzB,IAAI,MAAM,SAAS,QAAQ;KAC1B,KAAK,MAAM;KACX,aAAa;MACZ,MAAM;MACN,QAAQ;MACR,UAAU;OACT,MAAM;OACN,OAAO,MAAM;OACb,MAAM;QAAE,OAAO,MAAM;QAAO,KAAK,MAAM;OAAI;MAC5C;MACA,UAAU;MACV,MAAM,KAAK;KACZ;KACA;IACD;IACA,IAAI,MAAM,SAAS,YAAY,QAAQ,KAAK,MAAM,KAAK,GAAG;KACzD,KAAK,MAAM;KACX,aAAa;MACZ,MAAM;MACN,QAAQ;MACR,UAAU;OACT,MAAM;OACN,OAAO,OAAO,MAAM,KAAK;OACzB,MAAM;QAAE,OAAO,MAAM;QAAO,KAAK,MAAM;OAAI;MAC5C;MACA,UAAU;MACV,MAAM,KAAK;KACZ;KACA;IACD;IACA,KAAK,MACJ,sCAAsC,cAAc,KAAK,GAC1D;GACD;GAEA,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,KAAK,MAAM;IACX,MAAM,WAAW,KAAK,iBAAiB;IACvC,KAAK,aAAa,GAAG;IACrB,aAAa;KACZ,MAAM;KACN,QAAQ;KACR;KACA,UAAU;KACV,MAAM,KAAK;IACZ;IACA;GACD;GAEA,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,MAAM,SAAS;IACf,IAAI,OAAO,SAAS,UAAU,OAAO,SAAS,UAC7C,KAAK,MACJ,kEACA,KAAK,MAAM,GACX,cACD;IAGD,aAAa;KAAE,MAAM;KAAQ;KAAQ,MADxB,KAAK,gBACsB;KAAG,MAAM,KAAK;IAAE;IACxD;GACD;GAEA,IAAI,KAAK,SAAS,GAAG,GAAG;IACvB,WAAW;IACX,KAAK,MAAM;IACX,MAAM,YAAY,KAAK,YAAY,eAAe;IAClD,MAAM,OAAO,KAAK,SAAS,GAAG,IAAI,KAAK,gBAAgB,IAAI,CAAC;IAC5D,aAAa;KACZ,MAAM;KACN,MAAM,UAAU;KAChB,UAAU;MAAE,OAAO,UAAU;MAAO,KAAK,UAAU;KAAI;KACvD,OAAO;KACP;KACA,MAAM,KAAK;IACZ;IACA;GACD;GAEA,WAAW;GACX,OAAO;EACR;CACD;CAEA,gBAA4B;EAC3B,MAAM,QAAQ,KAAK,MAAM;EACzB,MAAM,YAAY;GAAE,OAAO,MAAM;GAAO,KAAK,MAAM;EAAI;EAEvD,QAAQ,MAAM,MAAd;GACC,KAAK;IACJ,KAAK,MAAM;IACX,OAAO;KAAE,MAAM;KAAW,OAAO,OAAO,MAAM,KAAK;KAAG,MAAM;IAAU;GACvE,KAAK;IACJ,KAAK,MAAM;IACX,OAAO;KAAE,MAAM;KAAW,OAAO,MAAM;KAAO,MAAM;IAAU;GAC/D,KAAK,eACJ,OAAO,KAAK,oBAAoB;GACjC,KAAK;IACJ,QAAQ,MAAM,OAAd;KACC,KAAK;KACL,KAAK;MACJ,KAAK,MAAM;MACX,OAAO;OACN,MAAM;OACN,OAAO,MAAM,UAAU;OACvB,MAAM;MACP;KACD,KAAK;MACJ,KAAK,MAAM;MACX,OAAO;OAAE,MAAM;OAAW,OAAO;OAAM,MAAM;MAAU;KACxD,KAAK;KACL,KAAK;KACL,KAAK;KACL,KAAK;KACL,KAAK,MACJ,KAAK,MAAM,+BAA+B,MAAM,MAAM,EAAE;IAC1D;IACA,IAAI,KAAK,SAAS,MAAM,CAAC,GACxB,KAAK,MACJ,qFACA,OACA,eACD;IAED,KAAK,MAAM;IACX,OAAO;KAAE,MAAM;KAAQ,MAAM,MAAM;KAAO,MAAM;IAAU;GAE3D,KAAK,SACJ,QAAQ,MAAM,OAAd;IACC,KAAK,KACJ,OAAO,KAAK,YAAY;IACzB,KAAK,KACJ,OAAO,KAAK,WAAW;IACxB,KAAK,KAAK;KACT,IAAI,KAAK,YAAY,GACpB,KAAK,MACJ,qFACA,OACA,eACD;KAED,KAAK,MAAM;KACX,MAAM,QAAQ,KAAK,iBAAiB;KACpC,KAAK,aAAa,GAAG;KACrB,OAAO;MACN,GAAG;MACH,MAAM;OAAE,OAAO,MAAM;OAAO,KAAK,KAAK;MAAS;KAChD;IACD;GACD;EACF;EACA,OAAO,KAAK,MAAM,8BAA8B,cAAc,KAAK,GAAG;CACvE;CAEA,sBAAkC;EACjC,MAAM,QAAQ,KAAK,MAAM;EACzB,MAAM,QAAsB,CAAC;EAC7B,SAAS;GACR,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,MAAM,SAAS,aAAa;IAC/B,KAAK,MAAM;IACX;GACD;GACA,IAAI,MAAM,SAAS,UAAU;IAC5B,KAAK,MAAM;IACX,MAAM,KAAK;KACV,MAAM;KACN,OAAO,MAAM;KACb,MAAM;MAAE,OAAO,MAAM;MAAO,KAAK,MAAM;KAAI;IAC5C,CAAC;IACD;GACD;GACA,IAAI,MAAM,SAAS,cAAc;IAChC,KAAK,MAAM;IACX,MAAM,KAAK,KAAK,iBAAiB,CAAC;IAClC,MAAM,QAAQ,KAAK,MAAM;IACzB,IAAI,MAAM,SAAS,eAClB,KAAK,MAAM,0BAA0B,cAAc,KAAK,GAAG;IAE5D,KAAK,MAAM;IACX;GACD;GACA,KAAK,MAAM,cAAc,cAAc,KAAK,EAAE,WAAW;EAC1D;EACA,OAAO;GACN,MAAM;GACN;GACA,MAAM;IAAE,OAAO,MAAM;IAAO,KAAK,KAAK;GAAS;EAChD;CACD;CAEA,eAAuB;EACtB,MAAM,QAAQ,KAAK,MAAM;EACzB,MAAM,QAAQ,KAAK,iBAAiB;EACpC,OAAO;GACN,MAAM;GACN;GACA,MAAM;IAAE,OAAO,MAAM;IAAO,KAAK,MAAM,KAAK;GAAI;EACjD;CACD;CAEA,cAA0B;EACzB,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,WAAoC,CAAC;EAC3C,OAAO,CAAC,KAAK,SAAS,GAAG,GAAG;GAC3B,SAAS,KACR,KAAK,SAAS,KAAK,IAAI,KAAK,aAAa,IAAI,KAAK,iBAAiB,CACpE;GACA,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;GACzB,KAAK,MAAM;EACZ;EACA,KAAK,aAAa,GAAG;EACrB,OAAO;GACN,MAAM;GACN;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;CAEA,aAAyB;EACxB,MAAM,OAAO,KAAK,MAAM;EACxB,MAAM,UAAuB,CAAC;EAC9B,OAAO,CAAC,KAAK,SAAS,GAAG,GAAG;GAC3B,IAAI,KAAK,SAAS,KAAK,GACtB,QAAQ,KAAK,KAAK,aAAa,CAAC;QAC1B;IACN,MAAM,QAAQ,KAAK,MAAM;IACzB,IAAI;IACJ,IAAI,MAAM,SAAS,QAAQ;KAC1B,KAAK,MAAM;KACX,MAAM;MACL,MAAM;MACN,OAAO,MAAM;MACb,MAAM;OAAE,OAAO,MAAM;OAAO,KAAK,MAAM;MAAI;KAC5C;KACA,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;MAExB,IACC,eAAe,IAAI,MAAM,KAAK,KAC9B,MAAM,UAAU,UAChB,MAAM,UAAU,SAEhB,KAAK,MAAM,uBAAuB,MAAM,MAAM,EAAE;MAEjD,QAAQ,KAAK;OACZ,MAAM;OACN;OACA,OAAO;QACN,MAAM;QACN,MAAM,MAAM;QACZ,MAAM;SAAE,OAAO,MAAM;SAAO,KAAK,MAAM;QAAI;OAC5C;OACA,MAAM;QAAE,OAAO,MAAM;QAAO,KAAK,MAAM;OAAI;MAC5C,CAAC;MACD,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;MACzB,KAAK,MAAM;MACX;KACD;IACD,OAAO,IAAI,MAAM,SAAS,YAAY,MAAM,SAAS,UAAU;KAC9D,KAAK,MAAM;KACX,MAAM;MACL,MAAM;MAEN,OACC,MAAM,SAAS,WACZ,OAAO,OAAO,MAAM,KAAK,CAAC,IAC1B,MAAM;MACV,MAAM;OAAE,OAAO,MAAM;OAAO,KAAK,MAAM;MAAI;KAC5C;IACD,OAAO,IAAI,KAAK,SAAS,GAAG,GAAG;KAC9B,KAAK,MAAM;KACX,MAAM,KAAK,iBAAiB;KAC5B,KAAK,aAAa,GAAG;IACtB,OACC,KAAK,MAAM,iCAAiC,cAAc,KAAK,GAAG;IAEnE,KAAK,aAAa,GAAG;IACrB,MAAM,QAAQ,KAAK,iBAAiB;IACpC,QAAQ,KAAK;KACZ,MAAM;KACN;KACA;KACA,MAAM;MAAE,OAAO,MAAM;MAAO,KAAK,MAAM,KAAK;KAAI;IACjD,CAAC;GACF;GACA,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;GACzB,KAAK,MAAM;EACZ;EACA,KAAK,aAAa,GAAG;EACrB,OAAO;GACN,MAAM;GACN;GACA,MAAM;IAAE,OAAO,KAAK;IAAO,KAAK,KAAK;GAAS;EAC/C;CACD;;CAGA,cAAuB;EACtB,IAAI,KAAK,MAAM,CAAC,CAAC,SAAS,QAAQ,OAAO,KAAK,SAAS,MAAM,CAAC;EAC9D,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,OAAO;EAChC,IAAI,SAAS;EACb,IAAI,KAAK,SAAS,KAAK,MAAM,GAAG,OAAO,KAAK,SAAS,MAAM,SAAS,CAAC;EACrE,SAAS;GACR,IAAI,KAAK,MAAM,MAAM,CAAC,CAAC,SAAS,QAAQ,OAAO;GAC/C;GACA,IAAI,KAAK,SAAS,KAAK,MAAM,GAAG,OAAO,KAAK,SAAS,MAAM,SAAS,CAAC;GACrE,IAAI,CAAC,KAAK,SAAS,KAAK,MAAM,GAAG,OAAO;GACxC;EACD;CACD;CAEA,cAA0B;EACzB,MAAM,QAAQ,KAAK,MAAM;EACzB,MAAM,SAAmB,CAAC;EAC1B,IAAI,MAAM,SAAS,QAClB,OAAO,KAAK,KAAK,sBAAsB,kBAAkB,CAAC,CAAC,KAAK;OAC1D;GACN,KAAK,MAAM;GACX,OAAO,CAAC,KAAK,SAAS,GAAG,GAAG;IAC3B,OAAO,KAAK,KAAK,sBAAsB,kBAAkB,CAAC,CAAC,KAAK;IAChE,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;IACzB,KAAK,MAAM;GACZ;GACA,KAAK,aAAa,GAAG;EACtB;EACA,KAAK,aAAa,IAAI;EACtB,MAAM,OAAO,KAAK,iBAAiB;EACnC,OAAO;GACN,MAAM;GACN;GACA;GACA,MAAM;IAAE,OAAO,MAAM;IAAO,KAAK,KAAK,KAAK;GAAI;EAChD;CACD;CAEA,kBAA8B;EAC7B,KAAK,aAAa,GAAG;EACrB,MAAM,OAAmB,CAAC;EAC1B,IAAI,QAAQ;EACZ,OAAO,CAAC,KAAK,SAAS,GAAG,GAAG;GAC3B,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,KAAK,SAAS,KAAK,GAAG;IACzB,IAAI,OACH,KAAK,MACJ,sDACA,KAAK,MAAM,GACX,wBACD;IAED,KAAK,KAAK,KAAK,aAAa,CAAC;GAC9B,OAAO,IAAI,MAAM,SAAS,UAAU,KAAK,SAAS,KAAK,CAAC,GAAG;IAC1D,KAAK,MAAM;IACX,KAAK,MAAM;IACX,QAAQ;IACR,MAAM,QAAQ,KAAK,YAAY,IAC5B,KAAK,YAAY,IACjB,KAAK,iBAAiB;IACzB,KAAK,KAAK;KACT,MAAM;KACN,MAAM,MAAM;KACZ;KACA,MAAM;MAAE,OAAO,MAAM;MAAO,KAAK,MAAM,KAAK;KAAI;IACjD,CAAC;GACF,OAAO;IACN,IAAI,OACH,KAAK,MACJ,sDACA,OACA,wBACD;IAED,MAAM,QAAQ,KAAK,YAAY,IAC5B,KAAK,YAAY,IACjB,KAAK,iBAAiB;IACzB,KAAK,KAAK;KAAE,MAAM;KAAc;KAAO,MAAM,MAAM;IAAK,CAAC;GAC1D;GACA,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG;GACzB,KAAK,MAAM;EACZ;EACA,KAAK,aAAa,GAAG;EACrB,OAAO;CACR;AACD"}
|