@xaendar/compiler 0.1.0 → 0.1.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.1.0",
3
+ "version": "0.1.6",
4
4
  "description": "A library containing compiler engine",
5
5
  "type": "module",
6
6
  "main": "./xaendar-compiler.es.js",
@@ -8,12 +8,14 @@
8
8
  "types": "./xaendar-compiler.es.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./xaendar-compiler.es.js",
12
- "types": "./xaendar-compiler.es.d.ts"
11
+ "import": {
12
+ "types": "./xaendar-compiler.es.d.ts",
13
+ "default": "./xaendar-compiler.es.js"
14
+ }
13
15
  }
14
16
  },
15
17
  "peerDependencies": {},
16
18
  "dependencies": {
17
- "@xaendar/common": "0.0.2"
19
+ "@xaendar/common": "0.1.6"
18
20
  }
19
- }
21
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"xaendar-compiler.es.js","names":[],"sources":["../../../packages/compiler/src/lexer/models/lexer-cursor.model.ts","../../../packages/compiler/src/lexer/models/lexer-state.enum.ts","../../../packages/compiler/src/lexer/models/token-type.enum.ts","../../../packages/compiler/src/lexer/states/attribute.state.ts","../../../packages/compiler/src/lexer/states/event.state.ts","../../../packages/compiler/src/lexer/states/interpolation-expression.state.ts","../../../packages/compiler/src/lexer/states/interpolation-literal.state.ts","../../../packages/compiler/src/utils/chars.utils.ts","../../../packages/compiler/src/lexer/states/interpolation.state.ts","../../../packages/compiler/src/lexer/states/tag-body.state.ts","../../../packages/compiler/src/lexer/states/tag-close.state.ts","../../../packages/compiler/src/lexer/states/tag-open-end.state.ts","../../../packages/compiler/src/lexer/states/tag-open-name.state.ts","../../../packages/compiler/src/lexer/states/text.state.ts","../../../packages/compiler/src/lexer/lexer.ts","../../../packages/compiler/src/parser/models/node.enum.ts","../../../packages/compiler/src/parser/models/parser-cursor.model.ts","../../../packages/compiler/src/parser/parser.ts","../../../packages/compiler/src/render-generator/render-generator.model.ts"],"sourcesContent":["import { PositiveInteger, TupleOfLength } from '@xaendar/common';\r\nimport { CR, EOF, LF, SPACE } from '../../costants/chars.constants';\r\nimport { CurrentChar } from './current-char.type';\r\nimport { CursorPosition } from './current-position.type';\r\n\r\n/**\r\n * Cursor abstraction used by the Lexer to navigate the input source.\r\n *\r\n * The LexerCursor is responsible for:\r\n * - Sequential character consumption\r\n * - Lookahead (peek) operations without state mutation\r\n * - Tracking logical position (row, column)\r\n * - Handling end-of-file conditions\r\n *\r\n * This class deliberately contains **no lexer logic**:\r\n * it does not know about tokens, states, or grammar rules.\r\n * Its sole responsibility is controlled navigation of the input stream.\r\n */\r\nexport class LexerCursor {\r\n /**\r\n * Representation of the current character.\r\n *\r\n * - `index`: absolute index within the input string\r\n * - `code`: Unicode code point of the character\r\n * - `value`: actual character value\r\n *\r\n * An index of `-1` indicates that the cursor has not yet consumed\r\n * any character or has reached EOF.\r\n */\r\n private readonly _currentChar: CurrentChar = {\r\n code: 0,\r\n index: -1,\r\n value: ''\r\n };\r\n /**\r\n * Returns a read-only snapshot of the current character.\r\n */\r\n public get currentChar(): Readonly<CurrentChar> {\r\n return this._currentChar;\r\n }\r\n /**\r\n * Cache used by peek operations to avoid re-reading\r\n * the same character positions multiple times.\r\n *\r\n * Key: absolute character index\r\n * Value: Unicode code point\r\n */\r\n private readonly _peekCache = new Map<number, number>();\r\n /**\r\n * Logical position of the cursor in the input.\r\n *\r\n * - `row`: zero-based line number\r\n * - `column`: zero-based column number\r\n */\r\n private readonly _position: CursorPosition = {\r\n row: 0,\r\n column: 0\r\n };\r\n /**\r\n * Returns a read-only snapshot of the current cursor position.\r\n */\r\n public get position(): Readonly<CursorPosition> {\r\n return this._position;\r\n }\r\n /**\r\n * Creates a new cursor for the given input source.\r\n *\r\n * @param input Full source string to be tokenized.\r\n */\r\n constructor(public input: string) { }\r\n\r\n /**\r\n * Advances the cursor by the specified number of characters.\r\n *\r\n * This method:\r\n * - Updates the current character\r\n * - Updates row/column position\r\n * - Detects line breaks (LF / CR)\r\n * - Throws an EOF error when the end of the input is reached\r\n *\r\n * @param chars Number of characters to consume (must be >= 1)\r\n *\r\n * @throws Error with cause `EOF` when advancing past input length\r\n */\r\n public advance(chars = 1): void {\r\n if (chars < 1) {\r\n throw new Error(`${chars} is not a valid value. Please enter a number equal or greater than 1`);\r\n }\r\n\r\n const newIndex = this._currentChar.index + chars;\r\n\r\n if (newIndex >= this.input.length) {\r\n this._currentChar.code = EOF;\r\n this._currentChar.index = -1;\r\n this._currentChar.value = '';\r\n this.throwEOFError();\r\n } else {\r\n /*\r\n Before updating the character, adjust logical position.\r\n Line breaks reset column and increment row.\r\n */\r\n if ([LF, CR].includes(this._currentChar.code)) {\r\n this._position.row++;\r\n this._position.column = 0;\r\n } else {\r\n this._position.column++;\r\n }\r\n\r\n this._currentChar.index = newIndex;\r\n this._currentChar.value = this.input[newIndex]!;\r\n this._currentChar.code = this.input.charCodeAt(newIndex);\r\n }\r\n }\r\n\r\n /**\r\n * Peeks ahead in the input stream without advancing the cursor.\r\n *\r\n * This method supports:\r\n * - Single-character lookahead\r\n * - Multi-character lookahead\r\n * - Optional offset from the current position\r\n *\r\n * Peek operations are cached for performance reasons and do not\r\n * modify the cursor state.\r\n *\r\n * @returns\r\n * - A single Unicode code point when peeking one character\r\n * - An array of Unicode code points when peeking multiple characters\r\n *\r\n * @throws Error with cause `EOF` if the peek exceeds input length\r\n */\r\n public peek(): number;\r\n public peek<OffSet extends number>(options?: { offset?: PositiveInteger<OffSet> }): number;\r\n public peek(chars: 1): number;\r\n public peek<OffSet extends number>(chars: 1, options?: { offset?: PositiveInteger<OffSet> }): number; \r\n public peek<ReadChars extends number>(chars: PositiveInteger<ReadChars>): TupleOfLength<ReadChars>; \r\n public peek<ReadChars extends number, OffSet extends number>(chars: PositiveInteger<ReadChars>, options?: { offset?: PositiveInteger<OffSet> }): TupleOfLength<ReadChars>;\r\n public peek(charsOrOptions?: number | { offset?: number }, options?: { offset?: number }): number | number[] {\r\n const cache = this._peekCache;\r\n const chars = typeof charsOrOptions === 'number' ? charsOrOptions : 1;\r\n const offset = (typeof charsOrOptions === 'object' ? charsOrOptions : options)?.offset ?? 0;\r\n return chars === 1 ? this.peekOneChar(this._currentChar.index + offset + 1, cache) : this.peekMany(chars + offset, cache);\r\n }\r\n\r\n /**\r\n * Skips all consecutive space characters from the current position.\r\n */\r\n public skipSpaces(): void {\r\n while (this.peek() === SPACE) {\r\n this.advance();\r\n }\r\n }\r\n\r\n /**\r\n * Peeks multiple characters ahead.\r\n */\r\n private peekMany(chars: number, cache: Map<number, number>): number[] {\r\n const peekedChars: number[] = [];\r\n const nextCharIndex = this._currentChar.index + 1;\r\n\r\n for (let i = nextCharIndex; i < nextCharIndex + chars; i++) {\r\n peekedChars.push(this.peekOneChar(i, cache));\r\n }\r\n\r\n return peekedChars;\r\n }\r\n\r\n /**\r\n * Peeks a single character at the given absolute index.\r\n */\r\n private peekOneChar(index: number, cache: Map<number, number>): number {\r\n if (cache.has(index)) {\r\n return cache.get(index)!;\r\n }\r\n\r\n if (index >= this.input.length) {\r\n this.throwEOFError();\r\n }\r\n\r\n const charCode = this.input.charCodeAt(index);\r\n cache.set(index, charCode);\r\n return charCode;\r\n }\r\n\r\n /**\r\n * Throws a standardized EOF error used by the lexer engine\r\n * to terminate tokenization.\r\n */\r\n private throwEOFError(): never {\r\n throw new Error('', { cause: EOF });\r\n }\r\n}\r\n","export enum LexerState {\r\n START = 'start', \r\n TEXT = 'text',\r\n TAG_OPEN_NAME = 'tag-open-name',\r\n TAG_BODY = 'tag-body',\r\n TAG_OPEN_END = 'tag-open-end',\r\n TAG_CLOSE = 'tag-close',\r\n ATTRIBUTE = 'attribute',\r\n EVENT = 'event', \r\n INTERPOLATION = 'interpolation',\r\n INTERPOLATION_EXPRESSION = 'interpolation-expression',\r\n INTERPOLATION_LITERAL = 'interpolation-literal'\r\n}\r\n","export enum TokenType {\r\n TEXT,\r\n\r\n TAG_OPEN_NAME, // <div\r\n TAG_SELF_CLOSE, // />\r\n TAG_OPEN_END,\r\n\r\n TAG_CLOSE_NAME, // </div\r\n\r\n ATTRIBUTE,\r\n EVENT,\r\n\r\n INTERPOLATION_LITERAL,\r\n INTERPOLATION_EXPRESSION,\r\n\r\n EOF\r\n}\r\n","import { GREATER_THEN, LEFT_BRACE, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeAttribute(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let attribute = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{\r\n type: TokenType.ATTRIBUTE,\r\n parts: [attribute]\r\n }] \r\n };\r\n read = false;\r\n break;\r\n\r\n case LEFT_BRACE:\r\n retVal = {\r\n state: LexerState.INTERPOLATION,\r\n tokens: [{\r\n type: TokenType.ATTRIBUTE,\r\n parts: [attribute]\r\n }],\r\n pushState: true \r\n };\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n attribute = `${attribute}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeEvent(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let event = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '@' character\r\n cursor.advance();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{ \r\n type: TokenType.EVENT, \r\n parts: [event] \r\n }]\r\n };\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n event = `${event}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { LEFT_BRACE, RIGHT_BRACE, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolationExpression(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let interpolation = '';\r\n let deep = 1\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case LEFT_BRACE:\r\n deep++;\r\n interpolation = addCharacter(cursor, interpolation);\r\n break;\r\n\r\n case RIGHT_BRACE:\r\n deep--;\r\n \r\n if (deep === 0) {\r\n cursor.advance();\r\n /*\r\n After an interpolation we have to understanad where to transite\r\n The next state depends from the previous state\r\n */\r\n const previousState = context.history.pop();\r\n let state!: LexerState;\r\n\r\n switch (previousState) {\r\n case LexerState.ATTRIBUTE:\r\n state = LexerState.TAG_BODY\r\n break;\r\n\r\n case LexerState.TEXT:\r\n state = LexerState.TEXT\r\n };\r\n\r\n retVal = {\r\n state,\r\n tokens: [{ \r\n type: TokenType.INTERPOLATION_EXPRESSION, \r\n parts: [interpolation] \r\n }],\r\n popState: true\r\n }\r\n read = false;\r\n } else {\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n\r\n break;\r\n\r\n default:\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n }\r\n\r\n return retVal;\r\n}\r\n\r\nfunction addCharacter(cursor: LexerCursor, interpolation: string): string {\r\n cursor.advance(1);\r\n return `${interpolation}${cursor.currentChar.value}`;\r\n}","import { GRAVE_ACCENT, RIGHT_BRACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolationliteral(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let interpolation = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '`' character\r\n cursor.advance();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case GRAVE_ACCENT:\r\n cursor.advance();\r\n\r\n if (cursor.peek() === RIGHT_BRACE) {\r\n cursor.advance();\r\n /*\r\n After an interpolation we have to understanad where to transite\r\n The next state depends from the previous state\r\n */\r\n const previousState = context.history.pop();\r\n let state!: LexerState;\r\n\r\n switch (previousState) {\r\n case LexerState.ATTRIBUTE:\r\n state = LexerState.TAG_BODY\r\n break;\r\n\r\n case LexerState.TEXT:\r\n state = LexerState.TEXT\r\n };\r\n\r\n retVal = {\r\n state,\r\n tokens: [{\r\n type: TokenType.INTERPOLATION_LITERAL,\r\n parts: [interpolation]\r\n }],\r\n popState: true\r\n }\r\n read = false;\r\n } else {\r\n /*\r\n If ` is not followed by }, it means the interpolation is not closed\r\n and ` is part of the interpolated string\r\n |\r\n ˅\r\n Example: {`text ${var} ` text`}\r\n */\r\n interpolation = `${interpolation}${cursor.currentChar.value}`\r\n }\r\n break;\r\n\r\n default:\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n }\r\n\r\n return retVal;\r\n}\r\n\r\nfunction addCharacter(cursor: LexerCursor, interpolation: string): string {\r\n cursor.advance(1);\r\n return `${interpolation}${cursor.currentChar.value}`;\r\n}","import { A, a, CR, LF, Z, z } from '../costants/chars.constants';\r\n\r\n/**\r\n * Check if char code is a Line Feed (\\n) or Carriage Return (\\r)\r\n * @param char Character to control\r\n * @returns True if character is LF or CR, false otherwise\r\n */\r\nexport function isNewLine(char: number): boolean {\r\n return char === LF || char === CR;\r\n}\r\n\r\n/**\r\n * Check if char code is is a lower case letter\r\n * @param char Character to control\r\n * @returns True if character is a lowercase letter, false otherwise\r\n */\r\nexport function isLowerCase(char: number): boolean {\r\n return char >= a && char <= z;\r\n}\r\n\r\n/**\r\n * Check if char code is is a upper case letter\r\n * @param char Character to control\r\n * @returns True if character is a upper case letter, false otherwise\r\n */\r\nexport function isUpperCase(char: number): boolean {\r\n return char >= A && char <= Z;\r\n}\r\n\r\n/**\r\n * Check if the string contains at least one character different from\r\n * ' '\r\n * \\n\r\n * \\r\r\n * \\t\r\n * \\f\r\n * \\v\r\n * @param str String to check\r\n * @returns True if string is not blank, false otherwise\r\n */\r\nexport function isNotBlank(str: string): boolean {\r\n /* \r\n Differently from the approach of the other functions\r\n here we are working with string and not numbers.\r\n\r\n Number checks are usually faster when checking a character is\r\n included in a specific range.\r\n For this case we are checking if the string contains at least one char\r\n different from a list of non adiacent characters in the ASCII code, resulting\r\n in a very long condition with multiple OR\r\n\r\n This has been proven slower than using a regex\r\n */\r\n return /\\S/.test(str)\r\n}\r\n\r\n/**\r\n * Check if given ascii code is a valid First Character\r\n * for Javasript Identifiers\r\n * @param code The ascii code to valuate\r\n * @returns True if is valid, false otherwise\r\n */\r\nexport function isJSIdentifierStart(code: number): boolean {\r\n return (\r\n (code >= 65 && code <= 90) || // A-Z\r\n (code >= 97 && code <= 122) || // a-z\r\n code === 36 || // $\r\n code === 95 // _\r\n );\r\n}","import { GRAVE_ACCENT, SPACE } from '../../costants/chars.constants';\r\nimport { isJSIdentifierStart } from '../../utils/chars.utils';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolation(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '{' characters\r\n cursor.advance();\r\n\r\n /*\r\n Skip all the spaces between '{' and the actual interpolation content\r\n Ex: '{ label}\r\n */\r\n cursor.skipSpaces();\r\n \r\n const nextChar = cursor.peek();\r\n\r\n if (nextChar === GRAVE_ACCENT) {\r\n retVal = { state: LexerState.INTERPOLATION_LITERAL };\r\n } else if (isJSIdentifierStart(nextChar)) {\r\n retVal = { state: LexerState.INTERPOLATION_EXPRESSION };\r\n } else {\r\n throw new Error(`Unrecognized First Character ${String.fromCharCode(nextChar)} in interpolation`);\r\n }\r\n\r\n return retVal;\r\n}","import { AT_SIGN, GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagBody(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n const nextChar = cursor.peek();\r\n\r\n switch (nextChar) {\r\n case AT_SIGN:\r\n retVal = {\r\n state: LexerState.EVENT\r\n }\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n cursor.advance();\r\n break;\r\n\r\n case GREATER_THEN:\r\n case SLASH:\r\n retVal = {\r\n state: LexerState.TAG_OPEN_END\r\n }\r\n read = false;\r\n break;\r\n\r\n default:\r\n retVal = {\r\n state: LexerState.ATTRIBUTE\r\n }\r\n read = false;\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { GREATER_THEN, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagClose(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let tagName = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Skip '</'\r\n cursor.advance(2);\r\n\r\n /*\r\n Skip all the spaces between '</' and the actual tag name\r\n Ex: '</ div>\r\n */\r\n cursor.skipSpaces();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case GREATER_THEN:\r\n cursor.advance();\r\n retVal = {\r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_CLOSE_NAME, \r\n parts: [tagName]\r\n }]\r\n };\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n throw new Error('Tag Close Name cannot contains spaces');\r\n\r\n default:\r\n cursor.advance();\r\n tagName = `${tagName}${cursor.currentChar.value}`;\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { GREATER_THEN } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagOpenEnd(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n // We arrive in this point by reading '>' or '/' at the end of a Open Tag \r\n if (cursor.peek() === GREATER_THEN) {\r\n cursor.advance();\r\n retVal = { \r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_OPEN_END,\r\n parts: []\r\n }] \r\n };\r\n } else {\r\n cursor.advance();\r\n const nextChar = cursor.peek();\r\n\r\n if (nextChar === GREATER_THEN) {\r\n cursor.advance();\r\n retVal = {\r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_SELF_CLOSE,\r\n parts: []\r\n }]\r\n };\r\n } else {\r\n throw new Error(`Unexpected character ${nextChar} for closing tag.\\nExpected />\\nRead of /${String.fromCharCode(nextChar)}\\nAt line ${cursor.position.row + 1} col ${cursor.position.column + 1}`)\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagOpenName(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let tagName = '';\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n // Consume '<' character\r\n cursor.advance();\r\n\r\n /*\r\n Skip all the spaces between '<' and the actual tag name\r\n Ex: '< div>\r\n */\r\n cursor.skipSpaces();\r\n\r\n /*\r\n Keep read input until:\r\n - Space: <span \r\n - GT: <span>\r\n - Slash (Self Closing tag) <span / or <span/\r\n */\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{ \r\n type: TokenType.TAG_OPEN_NAME, \r\n parts: [tagName] \r\n }]\r\n }\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n tagName = `${tagName}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { CR, LEFT_BRACE, LESS_THAN, LF, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { isNotBlank } from '../../utils/chars.utils';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeText(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let text = '';\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case LESS_THAN:\r\n // If after '<' we read a '/', we suppose we're approaching a ClosureTag, otherwise an OpenTag\r\n const nextState = cursor.peek(1, { offset: 1 }) === SLASH ? LexerState.TAG_CLOSE : LexerState.TAG_OPEN_NAME;\r\n retVal = { state: nextState }\r\n read = false;\r\n break;\r\n\r\n case LEFT_BRACE:\r\n retVal = { \r\n state: LexerState.INTERPOLATION,\r\n pushState: true\r\n };\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n case LF:\r\n case CR:\r\n cursor.advance();\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n text = `${text}${cursor.currentChar.value}`;\r\n }\r\n }\r\n\r\n\r\n /*\r\n If the first read character trigger a StateChange\r\n The cumulative `text` variable will be empty\r\n\r\n In this case we must NOT add any token\r\n\r\n Ex:\r\n Template starts with a tag:\r\n `<div ...`\r\n Or an interpolation:\r\n `{ myVariable }`\r\n */\r\n retVal.tokens = isNotBlank(text)\r\n ? [{ type: TokenType.TEXT, parts: [text] }]\r\n : undefined;\r\n\r\n return retVal\r\n}","import { Dictionary, Stack } from '@xaendar/common';\r\nimport { EOF } from '../costants/chars.constants';\r\nimport { LexerCursor } from './models/lexer-cursor.model';\r\nimport { LexerState } from './models/lexer-state.enum';\r\nimport { Token } from './models/token.type';\r\nimport { LexerTransitionFunction } from './models/transition-function/transition-function.type';\r\nimport { consumeAttribute } from './states/attribute.state';\r\nimport { consumeEvent } from './states/event.state';\r\nimport { consumeInterpolationExpression } from './states/interpolation-expression.state';\r\nimport { consumeInterpolationliteral } from './states/interpolation-literal.state';\r\nimport { consumeInterpolation } from './states/interpolation.state';\r\nimport { consumeTagBody } from './states/tag-body.state';\r\nimport { consumeTagClose } from './states/tag-close.state';\r\nimport { consumeTagOpenEnd } from './states/tag-open-end.state';\r\nimport { consumeTagOpenName } from './states/tag-open-name.state';\r\nimport { consumeText } from './states/text.state';\r\n\r\n/**\r\n * Utility class that emulates a cursor navigating through a template string.\r\n *\r\n * The cursor keeps track of the current character, its absolute position\r\n * within the text, and its logical position expressed as row and column.\r\n * This is useful when parsing or analyzing template content character by character.\r\n */\r\nexport class Lexer {\r\n\r\n private readonly _cursor;\r\n\r\n private _state = LexerState.START;\r\n\r\n private _stack = new Stack<LexerState>;\r\n\r\n private readonly _tokens = new Array<Token>;\r\n\r\n private readonly _states: Dictionary<LexerState, LexerTransitionFunction> = {\r\n [LexerState.START]: consumeText,\r\n [LexerState.TEXT]: consumeText,\r\n [LexerState.TAG_OPEN_NAME]: consumeTagOpenName,\r\n [LexerState.TAG_BODY]: consumeTagBody,\r\n [LexerState.TAG_OPEN_END]: consumeTagOpenEnd,\r\n [LexerState.TAG_CLOSE]: consumeTagClose,\r\n [LexerState.ATTRIBUTE]: consumeAttribute,\r\n [LexerState.EVENT]: consumeEvent,\r\n [LexerState.INTERPOLATION]: consumeInterpolation,\r\n [LexerState.INTERPOLATION_EXPRESSION]: consumeInterpolationExpression,\r\n [LexerState.INTERPOLATION_LITERAL]: consumeInterpolationliteral\r\n }\r\n\r\n /**\r\n * Creates a new Cursor instance for the given template content.\r\n *\r\n * @param input The full template text that the cursor will navigate.\r\n */\r\n constructor(public input: string) {\r\n this._cursor = new LexerCursor(this.input);\r\n }\r\n\r\n public tokenize(): Token[] {\r\n let eof = false;\r\n\r\n while (!eof) {\r\n try {\r\n const transitionFunction = this._states[this._state];\r\n const { state, tokens, popState, pushState } = transitionFunction!(this._cursor, { history: this._stack.values });\r\n \r\n if (tokens?.length) {\r\n this._tokens.push(...tokens);\r\n }\r\n \r\n if (pushState) {\r\n this._stack.push(this._state);\r\n }\r\n \r\n if (popState) {\r\n this._stack.pop();\r\n } \r\n \r\n this._state = state;\r\n } catch (err) {\r\n const error = err as Error;\r\n if (error.cause === EOF) {\r\n eof = true;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n return this._tokens;\r\n }\r\n}","export enum ASTNodeType {\r\n Element,\r\n Text,\r\n Interpolation\r\n}","import { PositiveInteger, TupleOfLength } from '@xaendar/common';\r\nimport { EOF } from '../../costants/chars.constants';\r\nimport { TokenType } from '../../lexer/models/token-type.enum';\r\nimport { Token } from '../../lexer/models/token.type';\r\nimport { CurrentToken } from './current-token.type';\r\n\r\n/**\r\n * Cursor abstraction used by the Parser to navigate\r\n * through a sequence of tokens produced by the Lexer.\r\n *\r\n * Responsibilities:\r\n * - Sequential token consumption\r\n * - Lookahead (peek) operations without mutating state\r\n * - Handling end-of-file conditions\r\n *\r\n * This class does not perform parsing itself: it only\r\n * manages position and access to the token stream.\r\n */\r\nexport class ParserCursor {\r\n\r\n /**\r\n * Representation of the current token.\r\n *\r\n * - `index`: absolute index within the token array\r\n * - `value`: current token object (or EOF token)\r\n *\r\n * An index of `-1` indicates that the cursor has not\r\n * yet consumed any token or has reached EOF.\r\n */\r\n private readonly _currentToken: CurrentToken = {\r\n value: { type: TokenType.EOF },\r\n index: -1\r\n };\r\n\r\n /**\r\n * Returns a read-only snapshot of the current token.\r\n */\r\n public get currentToken(): Readonly<CurrentToken> {\r\n return this._currentToken;\r\n }\r\n\r\n /**\r\n * Creates a new ParserCursor for the given token array.\r\n *\r\n * @param _tokens Array of tokens to navigate.\r\n */\r\n constructor(private readonly _tokens: Token[]) { }\r\n\r\n /**\r\n * Advances the cursor by the specified number of tokens.\r\n *\r\n * Updates the current token and index.\r\n *\r\n * @param chars Number of tokens to advance (must be >= 1)\r\n *\r\n * @throws Error with cause `EOF` when advancing past the end\r\n */\r\n public advance(chars = 1): void {\r\n if (chars < 1) {\r\n throw new Error(`${chars} is not a valid value. Please enter a number equal or greater than 1`);\r\n }\r\n\r\n const newIndex = this._currentToken.index + chars;\r\n\r\n if (newIndex >= this._tokens.length) {\r\n this._currentToken.value = { type: TokenType.EOF };\r\n this._currentToken.index = -1;\r\n this.throwEOFError();\r\n } else {\r\n this._currentToken.index = newIndex;\r\n this._currentToken.value = this._tokens[newIndex]!;\r\n }\r\n }\r\n\r\n /**\r\n * Peeks ahead in the token stream without advancing the cursor.\r\n *\r\n * Supports:\r\n * - Single-token lookahead\r\n * - Multi-token lookahead\r\n * - Optional offset from the current token\r\n *\r\n * @returns\r\n * - A single Token when peeking one token\r\n * - An array of Tokens when peeking multiple tokens\r\n *\r\n * @throws Error with cause `EOF` if the peek exceeds the token array\r\n */\r\n public peek(): Token;\r\n public peek<OffSet extends number>(options?: { offset?: PositiveInteger<OffSet> }): Token;\r\n public peek(chars: 1): Token;\r\n public peek<OffSet extends number>(chars: 1, options?: { offset?: PositiveInteger<OffSet> }): Token; \r\n public peek<ReadChars extends number>(chars: PositiveInteger<ReadChars>): TupleOfLength<ReadChars, Token>; \r\n public peek<ReadChars extends number, OffSet extends number>(chars: PositiveInteger<ReadChars>, options?: { offset?: PositiveInteger<OffSet> }): TupleOfLength<ReadChars, Token>;\r\n public peek(charsOrOptions?: number | { offset?: number }, options?: { offset?: number }): Token | Token[] {\r\n const tokens = typeof charsOrOptions === 'number' ? charsOrOptions : 1;\r\n const offset = (typeof charsOrOptions === 'object' ? charsOrOptions : options)?.offset ?? 0;\r\n return tokens === 1 ? this.peekOneToken(this._currentToken.index + offset + 1) : this.peekMany(tokens + offset);\r\n }\r\n\r\n /**\r\n * Peeks multiple tokens ahead.\r\n */\r\n private peekMany(chars: number): Token[] {\r\n const peekedTokens: Token[] = [];\r\n const nextTokenIndex = this._currentToken.index + 1;\r\n\r\n for (let i = nextTokenIndex; i < nextTokenIndex + chars; i++) {\r\n peekedTokens.push(this.peekOneToken(i));\r\n }\r\n\r\n return peekedTokens;\r\n }\r\n\r\n /**\r\n * Peeks a single token at the given absolute index.\r\n */\r\n private peekOneToken(index: number): Token {\r\n if (index >= this._tokens.length) {\r\n this.throwEOFError();\r\n }\r\n\r\n return this._tokens[index]!;\r\n }\r\n\r\n /**\r\n * Throws a standardized EOF error used by the parser\r\n * to terminate token consumption.\r\n */\r\n private throwEOFError(): never {\r\n throw new Error('', { cause: EOF });\r\n }\r\n}\r\n","import { EOF } from '../costants/chars.constants';\r\nimport { TokenType } from '../lexer/models/token-type.enum';\r\nimport { AttributeToken, EventToken, InterpolationExpressionToken, InterpolationLiteralToken, TagOpenNameToken, TextToken, Token } from '../lexer/models/token.type';\r\nimport { ASTNode, AttributeNode, ElementNode, EventNode, InterpolationNode, TextNode } from './models/ast.type';\r\nimport { ASTNodeType } from './models/node.enum';\r\nimport { ParserCursor } from './models/parser-cursor.model';\r\n\r\n/**\r\n * Parser class that transforms a stream of tokens (from the Lexer)\r\n * into an Abstract Syntax Tree (AST) representing the template structure.\r\n *\r\n * Responsibilities:\r\n * - Parse text nodes, elements, attributes, events, and interpolations\r\n * - Maintain cursor state for sequential token consumption\r\n * - Detect tag boundaries and nested structures\r\n *\r\n * The parser assumes that the token stream is syntactically valid according\r\n * to the Lexer rules. Parsing errors are thrown as exceptions.\r\n */\r\nexport class Parser {\r\n\r\n /** Internal cursor for navigating tokens */\r\n private readonly _cursor: ParserCursor;\r\n\r\n /**\r\n * Creates a new Parser instance.\r\n *\r\n * @param tokens Array of tokens produced by the Lexer\r\n */\r\n constructor(private readonly tokens: Token[]) {\r\n this._cursor = new ParserCursor(this.tokens);\r\n }\r\n\r\n /**\r\n * Entry point for parsing the token stream into AST nodes.\r\n *\r\n * @returns Array of top-level AST nodes\r\n */\r\n public parse(): ASTNode[] {\r\n let eof = false;\r\n const nodes: ASTNode[] = [];\r\n\r\n while (!eof) {\r\n try {\r\n nodes.push(this.parseNode());\r\n } catch (err) {\r\n const error = err as Error;\r\n if (error.cause === EOF) {\r\n eof = true;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n /**\r\n * Parses the next AST node based on the current token.\r\n *\r\n * @returns Parsed AST node\r\n * @throws Error if an unexpected token is encountered\r\n */\r\n private parseNode(): ASTNode {\r\n const token = this._cursor.peek();\r\n\r\n switch (token.type) {\r\n case TokenType.TEXT:\r\n return this.parseText(token);\r\n\r\n case TokenType.INTERPOLATION_EXPRESSION:\r\n case TokenType.INTERPOLATION_LITERAL:\r\n return this.parseInterpolation(token);\r\n\r\n case TokenType.TAG_OPEN_NAME:\r\n return this.parseElement(token);\r\n\r\n default:\r\n throw this.error(`Unexpected token ${TokenType[token.type]}`);\r\n }\r\n }\r\n\r\n /**\r\n * Parses a text token into a TextNode.\r\n */\r\n private parseText(token: TextToken): TextNode {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Text,\r\n value: token.parts[0]\r\n };\r\n }\r\n\r\n /**\r\n * Parses an interpolation token into an InterpolationNode.\r\n */\r\n private parseInterpolation(token: InterpolationExpressionToken | InterpolationLiteralToken): InterpolationNode {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Interpolation,\r\n expression: token.parts[0]\r\n };\r\n }\r\n\r\n /**\r\n * Parses an element starting from a TAG_OPEN_NAME token.\r\n * Handles attributes, events, children, and tag closure.\r\n */\r\n private parseElement(token: TagOpenNameToken): ElementNode {\r\n this._cursor.advance();\r\n const tagName = token.parts[0];\r\n\r\n const attributes: AttributeNode[] = [];\r\n const events: EventNode[] = [];\r\n\r\n let read = true;\r\n while (read) {\r\n const token = this._cursor.peek();\r\n switch (token.type) {\r\n case TokenType.ATTRIBUTE:\r\n attributes.push(this.parseAttribute(token));\r\n break;\r\n\r\n case TokenType.EVENT:\r\n events.push(this.parseEvent(token));\r\n break;\r\n\r\n default:\r\n read = false;\r\n }\r\n }\r\n\r\n // Consume TAG_OPEN_END if present: <div>\r\n if (this._cursor.peek().type === TokenType.TAG_OPEN_END) {\r\n this._cursor.advance();\r\n }\r\n\r\n // Handle self-closing tags: <div />\r\n if (this._cursor.peek().type === TokenType.TAG_SELF_CLOSE) {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Element,\r\n tagName,\r\n attributes,\r\n events,\r\n children: []\r\n };\r\n }\r\n\r\n // Parse children recursively until closing tag\r\n const children: ASTNode[] = [];\r\n while (!this.isTagClose(tagName)) {\r\n children.push(this.parseNode());\r\n }\r\n\r\n // Consume closing tag </div>\r\n this._cursor.advance();\r\n\r\n return {\r\n type: ASTNodeType.Element,\r\n tagName,\r\n attributes,\r\n events,\r\n children\r\n };\r\n }\r\n\r\n /**\r\n * Parses an attribute token into an AttributeNode.\r\n * Supports literal values and interpolations as attribute values.\r\n */\r\n private parseAttribute(token: AttributeToken): AttributeNode {\r\n this._cursor.advance();\r\n const raw = token.parts[0];\r\n\r\n if (!raw.includes('=')) {\r\n return { name: raw, value: 'true' };\r\n }\r\n\r\n const [name, value] = raw.split('=');\r\n\r\n const nextToken = this._cursor.peek();\r\n if (nextToken.type === TokenType.INTERPOLATION_EXPRESSION || nextToken.type === TokenType.INTERPOLATION_LITERAL) {\r\n return {\r\n name: name!,\r\n value: this.parseInterpolation(nextToken)\r\n };\r\n }\r\n\r\n return {\r\n name: name!,\r\n value: value!.replace(/^['']|['']$/g, '')\r\n };\r\n }\r\n\r\n /**\r\n * Parses an event token into an EventNode.\r\n */\r\n private parseEvent(token: EventToken): EventNode {\r\n this._cursor.advance();\r\n const raw = token.parts[0];\r\n const [name, value] = raw.split('=');\r\n\r\n return {\r\n name: name!,\r\n handler: value!.replace(/^['']|['']$/g, '')\r\n };\r\n }\r\n\r\n /**\r\n * Checks whether the next token is a closing tag matching the given name.\r\n */\r\n private isTagClose(tagName: string): boolean {\r\n const nextToken = this._cursor.peek();\r\n return nextToken.type === TokenType.TAG_CLOSE_NAME && nextToken.parts[0] === tagName;\r\n }\r\n\r\n /**\r\n * Creates a parser error with a consistent prefix.\r\n */\r\n private error(message: string): Error {\r\n return new Error(`[Parser] ${message}`);\r\n }\r\n}\r\n","import { ASTNode, TextNode, InterpolationNode, ElementNode, AttributeNode, EventNode } from '../parser/models/ast.type';\r\nimport { ASTNodeType } from '../parser/models/node.enum';\r\n\r\n/**\r\n * Genera il codice TypeScript della funzione render\r\n * @param ast L'albero AST del template\r\n * @param componentVar Nome della variabile 'this' del componente (di solito `this`)\r\n * @returns Stringa contenente il corpo della funzione render\r\n */\r\nexport function generateRenderFunction(ast: ASTNode[], componentVar = 'this'): string {\r\n const lines: string[] = [];\r\n\r\n // Apertura funzione\r\n lines.push(`const shadow = ${componentVar}.shadowRoot!;`);\r\n\r\n ast.forEach((node, i) => {\r\n lines.push(...processNode(node, `node${i}`, componentVar));\r\n lines.push(`shadow.appendChild(node${i});`);\r\n });\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Genera il codice per creare un singolo nodo\r\n */\r\nfunction processNode(node: ASTNode, varName: string, componentVar: string): string[] {\r\n const code = new Array<string>;\r\n\r\n switch (node.type) {\r\n case ASTNodeType.Text:\r\n code.push(`const ${varName} = document.createTextNode(${JSON.stringify((node as TextNode).value)});`);\r\n break;\r\n\r\n case ASTNodeType.Interpolation:\r\n code.push(`const ${varName} = document.createTextNode(${componentVar}.${(node as InterpolationNode).expression});`);\r\n break;\r\n\r\n case ASTNodeType.Element:\r\n const elNode = node as ElementNode;\r\n code.push(`const ${varName} = document.createElement(${JSON.stringify(elNode.tagName)});`);\r\n\r\n // Attributi\r\n (elNode.attributes || []).forEach((attr: AttributeNode) => {\r\n if (typeof attr.value === 'string') {\r\n code.push(`${varName}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(attr.value)});`);\r\n } else {\r\n // Interpolazione come value\r\n const interp = attr.value as InterpolationNode;\r\n code.push(`${varName}.setAttribute(${JSON.stringify(attr.name)}, ${componentVar}.${interp.expression});`);\r\n }\r\n });\r\n\r\n // Eventi\r\n (elNode.events || []).forEach((event: EventNode) => {\r\n if (event.name.startsWith('@')) {\r\n event.name = event.name.slice(1);\r\n }\r\n code.push(`${varName}.addEventListener(${JSON.stringify(event.name)}, ${componentVar}.${event.handler}.bind(${componentVar}));`);\r\n });\r\n\r\n // Children\r\n (elNode.children || []).forEach((child, idx) => {\r\n const childVar = `${varName}_child${idx}`;\r\n code.push(...processNode(child, childVar, componentVar));\r\n code.push(`${varName}.appendChild(${childVar});`);\r\n });\r\n\r\n break;\r\n }\r\n\r\n return code;\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"xaendar-compiler.es.js","names":[],"sources":["../../../packages/compiler/src/lexer/models/lexer-cursor.model.ts","../../../packages/compiler/src/lexer/models/lexer-state.enum.ts","../../../packages/compiler/src/lexer/models/token-type.enum.ts","../../../packages/compiler/src/lexer/states/attribute.state.ts","../../../packages/compiler/src/lexer/states/event.state.ts","../../../packages/compiler/src/lexer/states/interpolation-expression.state.ts","../../../packages/compiler/src/lexer/states/interpolation-literal.state.ts","../../../packages/compiler/src/utils/chars.utils.ts","../../../packages/compiler/src/lexer/states/interpolation.state.ts","../../../packages/compiler/src/lexer/states/tag-body.state.ts","../../../packages/compiler/src/lexer/states/tag-close.state.ts","../../../packages/compiler/src/lexer/states/tag-open-end.state.ts","../../../packages/compiler/src/lexer/states/tag-open-name.state.ts","../../../packages/compiler/src/lexer/states/text.state.ts","../../../packages/compiler/src/lexer/lexer.ts","../../../packages/compiler/src/parser/models/node.enum.ts","../../../packages/compiler/src/parser/models/parser-cursor.model.ts","../../../packages/compiler/src/parser/parser.ts","../../../packages/compiler/src/render-generator/render-generator.model.ts"],"sourcesContent":["import { PositiveInteger, TupleOfLength } from '@xaendar/common';\r\nimport { CR, EOF, LF, SPACE } from '../../costants/chars.constants';\r\nimport { CurrentChar } from './current-char.type';\r\nimport { CursorPosition } from './current-position.type';\r\n\r\n/**\r\n * Cursor abstraction used by the Lexer to navigate the input source.\r\n *\r\n * The LexerCursor is responsible for:\r\n * - Sequential character consumption\r\n * - Lookahead (peek) operations without state mutation\r\n * - Tracking logical position (row, column)\r\n * - Handling end-of-file conditions\r\n *\r\n * This class deliberately contains **no lexer logic**:\r\n * it does not know about tokens, states, or grammar rules.\r\n * Its sole responsibility is controlled navigation of the input stream.\r\n */\r\nexport class LexerCursor {\r\n /**\r\n * Representation of the current character.\r\n *\r\n * - `index`: absolute index within the input string\r\n * - `code`: Unicode code point of the character\r\n * - `value`: actual character value\r\n *\r\n * An index of `-1` indicates that the cursor has not yet consumed\r\n * any character or has reached EOF.\r\n */\r\n private readonly _currentChar: CurrentChar = {\r\n code: 0,\r\n index: -1,\r\n value: ''\r\n };\r\n /**\r\n * Returns a read-only snapshot of the current character.\r\n */\r\n public get currentChar(): Readonly<CurrentChar> {\r\n return this._currentChar;\r\n }\r\n /**\r\n * Cache used by peek operations to avoid re-reading\r\n * the same character positions multiple times.\r\n *\r\n * Key: absolute character index\r\n * Value: Unicode code point\r\n */\r\n private readonly _peekCache = new Map<number, number>();\r\n /**\r\n * Logical position of the cursor in the input.\r\n *\r\n * - `row`: zero-based line number\r\n * - `column`: zero-based column number\r\n */\r\n private readonly _position: CursorPosition = {\r\n row: 0,\r\n column: 0\r\n };\r\n /**\r\n * Returns a read-only snapshot of the current cursor position.\r\n */\r\n public get position(): Readonly<CursorPosition> {\r\n return this._position;\r\n }\r\n /**\r\n * Creates a new cursor for the given input source.\r\n *\r\n * @param input Full source string to be tokenized.\r\n */\r\n constructor(public input: string) { }\r\n\r\n /**\r\n * Advances the cursor by the specified number of characters.\r\n *\r\n * This method:\r\n * - Updates the current character\r\n * - Updates row/column position\r\n * - Detects line breaks (LF / CR)\r\n * - Throws an EOF error when the end of the input is reached\r\n *\r\n * @param chars Number of characters to consume (must be >= 1)\r\n *\r\n * @throws Error with cause `EOF` when advancing past input length\r\n */\r\n public advance(chars = 1): void {\r\n if (chars < 1) {\r\n throw new Error(`${chars} is not a valid value. Please enter a number equal or greater than 1`);\r\n }\r\n\r\n const newIndex = this._currentChar.index + chars;\r\n\r\n if (newIndex >= this.input.length) {\r\n this._currentChar.code = EOF;\r\n this._currentChar.index = -1;\r\n this._currentChar.value = '';\r\n this.throwEOFError();\r\n } else {\r\n /*\r\n Before updating the character, adjust logical position.\r\n Line breaks reset column and increment row.\r\n */\r\n if ([LF, CR].includes(this._currentChar.code)) {\r\n this._position.row++;\r\n this._position.column = 0;\r\n } else {\r\n this._position.column++;\r\n }\r\n\r\n this._currentChar.index = newIndex;\r\n this._currentChar.value = this.input[newIndex]!;\r\n this._currentChar.code = this.input.charCodeAt(newIndex);\r\n }\r\n }\r\n\r\n /**\r\n * Peeks ahead in the input stream without advancing the cursor.\r\n *\r\n * This method supports:\r\n * - Single-character lookahead\r\n * - Multi-character lookahead\r\n * - Optional offset from the current position\r\n *\r\n * Peek operations are cached for performance reasons and do not\r\n * modify the cursor state.\r\n *\r\n * @returns\r\n * - A single Unicode code point when peeking one character\r\n * - An array of Unicode code points when peeking multiple characters\r\n *\r\n * @throws Error with cause `EOF` if the peek exceeds input length\r\n */\r\n public peek(): number;\r\n public peek<OffSet extends number>(options?: { offset?: PositiveInteger<OffSet> }): number;\r\n public peek(chars: 1): number;\r\n public peek<OffSet extends number>(chars: 1, options?: { offset?: PositiveInteger<OffSet> }): number; \r\n public peek<ReadChars extends number>(chars: PositiveInteger<ReadChars>): TupleOfLength<ReadChars>; \r\n public peek<ReadChars extends number, OffSet extends number>(chars: PositiveInteger<ReadChars>, options?: { offset?: PositiveInteger<OffSet> }): TupleOfLength<ReadChars>;\r\n public peek(charsOrOptions?: number | { offset?: number }, options?: { offset?: number }): number | number[] {\r\n const cache = this._peekCache;\r\n const chars = typeof charsOrOptions === 'number' ? charsOrOptions : 1;\r\n const offset = (typeof charsOrOptions === 'object' ? charsOrOptions : options)?.offset ?? 0;\r\n return chars === 1 ? this.peekOneChar(this._currentChar.index + offset + 1, cache) : this.peekMany(chars + offset, cache);\r\n }\r\n\r\n /**\r\n * Skips all consecutive space characters from the current position.\r\n */\r\n public skipSpaces(): void {\r\n while (this.peek() === SPACE) {\r\n this.advance();\r\n }\r\n }\r\n\r\n /**\r\n * Peeks multiple characters ahead.\r\n */\r\n private peekMany(chars: number, cache: Map<number, number>): number[] {\r\n const peekedChars: number[] = [];\r\n const nextCharIndex = this._currentChar.index + 1;\r\n\r\n for (let i = nextCharIndex; i < nextCharIndex + chars; i++) {\r\n peekedChars.push(this.peekOneChar(i, cache));\r\n }\r\n\r\n return peekedChars;\r\n }\r\n\r\n /**\r\n * Peeks a single character at the given absolute index.\r\n */\r\n private peekOneChar(index: number, cache: Map<number, number>): number {\r\n if (cache.has(index)) {\r\n return cache.get(index)!;\r\n }\r\n\r\n if (index >= this.input.length) {\r\n this.throwEOFError();\r\n }\r\n\r\n const charCode = this.input.charCodeAt(index);\r\n cache.set(index, charCode);\r\n return charCode;\r\n }\r\n\r\n /**\r\n * Throws a standardized EOF error used by the lexer engine\r\n * to terminate tokenization.\r\n */\r\n private throwEOFError(): never {\r\n throw new Error('', { cause: EOF });\r\n }\r\n}\r\n","export enum LexerState {\r\n START = 'start', \r\n TEXT = 'text',\r\n TAG_OPEN_NAME = 'tag-open-name',\r\n TAG_BODY = 'tag-body',\r\n TAG_OPEN_END = 'tag-open-end',\r\n TAG_CLOSE = 'tag-close',\r\n ATTRIBUTE = 'attribute',\r\n EVENT = 'event', \r\n INTERPOLATION = 'interpolation',\r\n INTERPOLATION_EXPRESSION = 'interpolation-expression',\r\n INTERPOLATION_LITERAL = 'interpolation-literal'\r\n}\r\n","export enum TokenType {\r\n TEXT,\r\n\r\n TAG_OPEN_NAME, // <div\r\n TAG_SELF_CLOSE, // />\r\n TAG_OPEN_END,\r\n\r\n TAG_CLOSE_NAME, // </div\r\n\r\n ATTRIBUTE,\r\n EVENT,\r\n\r\n INTERPOLATION_LITERAL,\r\n INTERPOLATION_EXPRESSION,\r\n\r\n EOF\r\n}\r\n","import { GREATER_THEN, LEFT_BRACE, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeAttribute(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let attribute = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{\r\n type: TokenType.ATTRIBUTE,\r\n parts: [attribute]\r\n }] \r\n };\r\n read = false;\r\n break;\r\n\r\n case LEFT_BRACE:\r\n retVal = {\r\n state: LexerState.INTERPOLATION,\r\n tokens: [{\r\n type: TokenType.ATTRIBUTE,\r\n parts: [attribute]\r\n }],\r\n pushState: true \r\n };\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n attribute = `${attribute}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeEvent(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let event = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '@' character\r\n cursor.advance();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{ \r\n type: TokenType.EVENT, \r\n parts: [event] \r\n }]\r\n };\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n event = `${event}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { LEFT_BRACE, RIGHT_BRACE, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolationExpression(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let interpolation = '';\r\n let deep = 1\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case LEFT_BRACE:\r\n deep++;\r\n interpolation = addCharacter(cursor, interpolation);\r\n break;\r\n\r\n case RIGHT_BRACE:\r\n deep--;\r\n \r\n if (deep === 0) {\r\n cursor.advance();\r\n /*\r\n After an interpolation we have to understanad where to transite\r\n The next state depends from the previous state\r\n */\r\n const previousState = context.history.pop();\r\n let state!: LexerState;\r\n\r\n switch (previousState) {\r\n case LexerState.ATTRIBUTE:\r\n state = LexerState.TAG_BODY\r\n break;\r\n\r\n case LexerState.TEXT:\r\n state = LexerState.TEXT\r\n };\r\n\r\n retVal = {\r\n state,\r\n tokens: [{ \r\n type: TokenType.INTERPOLATION_EXPRESSION, \r\n parts: [interpolation] \r\n }],\r\n popState: true\r\n }\r\n read = false;\r\n } else {\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n\r\n break;\r\n\r\n default:\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n }\r\n\r\n return retVal;\r\n}\r\n\r\nfunction addCharacter(cursor: LexerCursor, interpolation: string): string {\r\n cursor.advance(1);\r\n return `${interpolation}${cursor.currentChar.value}`;\r\n}","import { GRAVE_ACCENT, RIGHT_BRACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolationliteral(cursor: LexerCursor, context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let interpolation = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '`' character\r\n cursor.advance();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case GRAVE_ACCENT:\r\n cursor.advance();\r\n\r\n if (cursor.peek() === RIGHT_BRACE) {\r\n cursor.advance();\r\n /*\r\n After an interpolation we have to understanad where to transite\r\n The next state depends from the previous state\r\n */\r\n const previousState = context.history.pop();\r\n let state!: LexerState;\r\n\r\n switch (previousState) {\r\n case LexerState.ATTRIBUTE:\r\n state = LexerState.TAG_BODY\r\n break;\r\n\r\n case LexerState.TEXT:\r\n state = LexerState.TEXT\r\n };\r\n\r\n retVal = {\r\n state,\r\n tokens: [{\r\n type: TokenType.INTERPOLATION_LITERAL,\r\n parts: [interpolation]\r\n }],\r\n popState: true\r\n }\r\n read = false;\r\n } else {\r\n /*\r\n If ` is not followed by }, it means the interpolation is not closed\r\n and ` is part of the interpolated string\r\n |\r\n ˅\r\n Example: {`text ${var} ` text`}\r\n */\r\n interpolation = `${interpolation}${cursor.currentChar.value}`\r\n }\r\n break;\r\n\r\n default:\r\n interpolation = addCharacter(cursor, interpolation);\r\n }\r\n }\r\n\r\n return retVal;\r\n}\r\n\r\nfunction addCharacter(cursor: LexerCursor, interpolation: string): string {\r\n cursor.advance(1);\r\n return `${interpolation}${cursor.currentChar.value}`;\r\n}","import { A, a, CR, LF, Z, z } from '../costants/chars.constants';\r\n\r\n/**\r\n * Check if char code is a Line Feed (\\n) or Carriage Return (\\r)\r\n * @param char Character to control\r\n * @returns True if character is LF or CR, false otherwise\r\n */\r\nexport function isNewLine(char: number): boolean {\r\n return char === LF || char === CR;\r\n}\r\n\r\n/**\r\n * Check if char code is is a lower case letter\r\n * @param char Character to control\r\n * @returns True if character is a lowercase letter, false otherwise\r\n */\r\nexport function isLowerCase(char: number): boolean {\r\n return char >= a && char <= z;\r\n}\r\n\r\n/**\r\n * Check if char code is is a upper case letter\r\n * @param char Character to control\r\n * @returns True if character is a upper case letter, false otherwise\r\n */\r\nexport function isUpperCase(char: number): boolean {\r\n return char >= A && char <= Z;\r\n}\r\n\r\n/**\r\n * Check if the string contains at least one character different from\r\n * ' '\r\n * \\n\r\n * \\r\r\n * \\t\r\n * \\f\r\n * \\v\r\n * @param str String to check\r\n * @returns True if string is not blank, false otherwise\r\n */\r\nexport function isNotBlank(str: string): boolean {\r\n /* \r\n Differently from the approach of the other functions\r\n here we are working with string and not numbers.\r\n\r\n Number checks are usually faster when checking a character is\r\n included in a specific range.\r\n For this case we are checking if the string contains at least one char\r\n different from a list of non adiacent characters in the ASCII code, resulting\r\n in a very long condition with multiple OR\r\n\r\n This has been proven slower than using a regex\r\n */\r\n return /\\S/.test(str)\r\n}\r\n\r\n/**\r\n * Check if given ascii code is a valid First Character\r\n * for Javasript Identifiers\r\n * @param code The ascii code to valuate\r\n * @returns True if is valid, false otherwise\r\n */\r\nexport function isJSIdentifierStart(code: number): boolean {\r\n return (\r\n (code >= 65 && code <= 90) || // A-Z\r\n (code >= 97 && code <= 122) || // a-z\r\n code === 36 || // $\r\n code === 95 // _\r\n );\r\n}","import { GRAVE_ACCENT, SPACE } from '../../costants/chars.constants';\r\nimport { isJSIdentifierStart } from '../../utils/chars.utils';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeInterpolation(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Consume '{' characters\r\n cursor.advance();\r\n\r\n /*\r\n Skip all the spaces between '{' and the actual interpolation content\r\n Ex: '{ label}\r\n */\r\n cursor.skipSpaces();\r\n \r\n const nextChar = cursor.peek();\r\n\r\n if (nextChar === GRAVE_ACCENT) {\r\n retVal = { state: LexerState.INTERPOLATION_LITERAL };\r\n } else if (isJSIdentifierStart(nextChar)) {\r\n retVal = { state: LexerState.INTERPOLATION_EXPRESSION };\r\n } else {\r\n throw new Error(`Unrecognized First Character ${String.fromCharCode(nextChar)} in interpolation`);\r\n }\r\n\r\n return retVal;\r\n}","import { AT_SIGN, GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagBody(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n while (read) {\r\n const nextChar = cursor.peek();\r\n\r\n switch (nextChar) {\r\n case AT_SIGN:\r\n retVal = {\r\n state: LexerState.EVENT\r\n }\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n cursor.advance();\r\n break;\r\n\r\n case GREATER_THEN:\r\n case SLASH:\r\n retVal = {\r\n state: LexerState.TAG_OPEN_END\r\n }\r\n read = false;\r\n break;\r\n\r\n default:\r\n retVal = {\r\n state: LexerState.ATTRIBUTE\r\n }\r\n read = false;\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { GREATER_THEN, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagClose(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let tagName = '';\r\n let retVal!: LexerTransitionFunctionReturnType;\r\n\r\n // Skip '</'\r\n cursor.advance(2);\r\n\r\n /*\r\n Skip all the spaces between '</' and the actual tag name\r\n Ex: '</ div>\r\n */\r\n cursor.skipSpaces();\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case GREATER_THEN:\r\n cursor.advance();\r\n retVal = {\r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_CLOSE_NAME, \r\n parts: [tagName]\r\n }]\r\n };\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n throw new Error('Tag Close Name cannot contains spaces');\r\n\r\n default:\r\n cursor.advance();\r\n tagName = `${tagName}${cursor.currentChar.value}`;\r\n }\r\n }\r\n\r\n return retVal;\r\n}","import { GREATER_THEN } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagOpenEnd(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n // We arrive in this point by reading '>' or '/' at the end of a Open Tag \r\n if (cursor.peek() === GREATER_THEN) {\r\n cursor.advance();\r\n retVal = { \r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_OPEN_END,\r\n parts: []\r\n }] \r\n };\r\n } else {\r\n cursor.advance();\r\n const nextChar = cursor.peek();\r\n\r\n if (nextChar === GREATER_THEN) {\r\n cursor.advance();\r\n retVal = {\r\n state: LexerState.TEXT,\r\n tokens: [{\r\n type: TokenType.TAG_SELF_CLOSE,\r\n parts: []\r\n }]\r\n };\r\n } else {\r\n throw new Error(`Unexpected character ${nextChar} for closing tag.\\nExpected />\\nRead of /${String.fromCharCode(nextChar)}\\nAt line ${cursor.position.row + 1} col ${cursor.position.column + 1}`)\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { GREATER_THEN, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeTagOpenName(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let tagName = '';\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n // Consume '<' character\r\n cursor.advance();\r\n\r\n /*\r\n Skip all the spaces between '<' and the actual tag name\r\n Ex: '< div>\r\n */\r\n cursor.skipSpaces();\r\n\r\n /*\r\n Keep read input until:\r\n - Space: <span \r\n - GT: <span>\r\n - Slash (Self Closing tag) <span / or <span/\r\n */\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case SPACE:\r\n case SLASH:\r\n case GREATER_THEN:\r\n retVal = {\r\n state: LexerState.TAG_BODY,\r\n tokens: [{ \r\n type: TokenType.TAG_OPEN_NAME, \r\n parts: [tagName] \r\n }]\r\n }\r\n read = false;\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n tagName = `${tagName}${cursor.currentChar.value}`\r\n }\r\n }\r\n\r\n return retVal\r\n}","import { CR, LEFT_BRACE, LESS_THAN, LF, SLASH, SPACE } from '../../costants/chars.constants';\r\nimport { isNotBlank } from '../../utils/chars.utils';\r\nimport { LexerCursor } from '../models/lexer-cursor.model';\r\nimport { LexerState } from '../models/lexer-state.enum';\r\nimport { TokenType } from '../models/token-type.enum';\r\nimport { LexerTransitionFunctionContext } from '../models/transition-function/transition-function-context.type';\r\nimport { LexerTransitionFunctionReturnType } from '../models/transition-function/transition-function-return-type.type';\r\n\r\nexport function consumeText(cursor: LexerCursor, _context: LexerTransitionFunctionContext): LexerTransitionFunctionReturnType {\r\n let read = true;\r\n let text = '';\r\n let retVal!: LexerTransitionFunctionReturnType\r\n\r\n while (read) {\r\n switch (cursor.peek()) {\r\n case LESS_THAN:\r\n // If after '<' we read a '/', we suppose we're approaching a ClosureTag, otherwise an OpenTag\r\n const nextState = cursor.peek(1, { offset: 1 }) === SLASH ? LexerState.TAG_CLOSE : LexerState.TAG_OPEN_NAME;\r\n retVal = { state: nextState }\r\n read = false;\r\n break;\r\n\r\n case LEFT_BRACE:\r\n retVal = { \r\n state: LexerState.INTERPOLATION,\r\n pushState: true\r\n };\r\n read = false;\r\n break;\r\n\r\n case SPACE:\r\n case LF:\r\n case CR:\r\n cursor.advance();\r\n break;\r\n\r\n default:\r\n cursor.advance();\r\n text = `${text}${cursor.currentChar.value}`;\r\n }\r\n }\r\n\r\n\r\n /*\r\n If the first read character trigger a StateChange\r\n The cumulative `text` variable will be empty\r\n\r\n In this case we must NOT add any token\r\n\r\n Ex:\r\n Template starts with a tag:\r\n `<div ...`\r\n Or an interpolation:\r\n `{ myVariable }`\r\n */\r\n retVal.tokens = isNotBlank(text)\r\n ? [{ type: TokenType.TEXT, parts: [text] }]\r\n : undefined;\r\n\r\n return retVal\r\n}","import { Dictionary, Stack } from '@xaendar/common';\r\nimport { EOF } from '../costants/chars.constants';\r\nimport { LexerCursor } from './models/lexer-cursor.model';\r\nimport { LexerState } from './models/lexer-state.enum';\r\nimport { Token } from './models/token.type';\r\nimport { LexerTransitionFunction } from './models/transition-function/transition-function.type';\r\nimport { consumeAttribute } from './states/attribute.state';\r\nimport { consumeEvent } from './states/event.state';\r\nimport { consumeInterpolationExpression } from './states/interpolation-expression.state';\r\nimport { consumeInterpolationliteral } from './states/interpolation-literal.state';\r\nimport { consumeInterpolation } from './states/interpolation.state';\r\nimport { consumeTagBody } from './states/tag-body.state';\r\nimport { consumeTagClose } from './states/tag-close.state';\r\nimport { consumeTagOpenEnd } from './states/tag-open-end.state';\r\nimport { consumeTagOpenName } from './states/tag-open-name.state';\r\nimport { consumeText } from './states/text.state';\r\n\r\n/**\r\n * Utility class that emulates a cursor navigating through a template string.\r\n *\r\n * The cursor keeps track of the current character, its absolute position\r\n * within the text, and its logical position expressed as row and column.\r\n * This is useful when parsing or analyzing template content character by character.\r\n */\r\nexport class Lexer {\r\n\r\n private readonly _cursor;\r\n\r\n private _state = LexerState.START;\r\n\r\n private _stack = new Stack<LexerState>;\r\n\r\n private readonly _tokens = new Array<Token>;\r\n\r\n private readonly _states: Dictionary<LexerState, LexerTransitionFunction> = {\r\n [LexerState.START]: consumeText,\r\n [LexerState.TEXT]: consumeText,\r\n [LexerState.TAG_OPEN_NAME]: consumeTagOpenName,\r\n [LexerState.TAG_BODY]: consumeTagBody,\r\n [LexerState.TAG_OPEN_END]: consumeTagOpenEnd,\r\n [LexerState.TAG_CLOSE]: consumeTagClose,\r\n [LexerState.ATTRIBUTE]: consumeAttribute,\r\n [LexerState.EVENT]: consumeEvent,\r\n [LexerState.INTERPOLATION]: consumeInterpolation,\r\n [LexerState.INTERPOLATION_EXPRESSION]: consumeInterpolationExpression,\r\n [LexerState.INTERPOLATION_LITERAL]: consumeInterpolationliteral\r\n }\r\n\r\n /**\r\n * Creates a new Cursor instance for the given template content.\r\n *\r\n * @param input The full template text that the cursor will navigate.\r\n */\r\n constructor(public input: string) {\r\n this._cursor = new LexerCursor(this.input);\r\n }\r\n\r\n public tokenize(): Token[] {\r\n let eof = false;\r\n\r\n while (!eof) {\r\n try {\r\n const transitionFunction = this._states[this._state];\r\n const { state, tokens, popState, pushState } = transitionFunction!(this._cursor, { history: this._stack.values });\r\n \r\n if (tokens?.length) {\r\n this._tokens.push(...tokens);\r\n }\r\n \r\n if (pushState) {\r\n this._stack.push(this._state);\r\n }\r\n \r\n if (popState) {\r\n this._stack.pop();\r\n } \r\n \r\n this._state = state;\r\n } catch (err) {\r\n const error = err as Error;\r\n if (error.cause === EOF) {\r\n eof = true;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n return this._tokens;\r\n }\r\n}","export enum ASTNodeType {\r\n Element,\r\n Text,\r\n Interpolation\r\n}","import { PositiveInteger, TupleOfLength } from '@xaendar/common';\r\nimport { EOF } from '../../costants/chars.constants';\r\nimport { TokenType } from '../../lexer/models/token-type.enum';\r\nimport { Token } from '../../lexer/models/token.type';\r\nimport { CurrentToken } from './current-token.type';\r\n\r\n/**\r\n * Cursor abstraction used by the Parser to navigate\r\n * through a sequence of tokens produced by the Lexer.\r\n *\r\n * Responsibilities:\r\n * - Sequential token consumption\r\n * - Lookahead (peek) operations without mutating state\r\n * - Handling end-of-file conditions\r\n *\r\n * This class does not perform parsing itself: it only\r\n * manages position and access to the token stream.\r\n */\r\nexport class ParserCursor {\r\n\r\n /**\r\n * Representation of the current token.\r\n *\r\n * - `index`: absolute index within the token array\r\n * - `value`: current token object (or EOF token)\r\n *\r\n * An index of `-1` indicates that the cursor has not\r\n * yet consumed any token or has reached EOF.\r\n */\r\n private readonly _currentToken: CurrentToken = {\r\n value: { type: TokenType.EOF },\r\n index: -1\r\n };\r\n\r\n /**\r\n * Returns a read-only snapshot of the current token.\r\n */\r\n public get currentToken(): Readonly<CurrentToken> {\r\n return this._currentToken;\r\n }\r\n\r\n /**\r\n * Creates a new ParserCursor for the given token array.\r\n *\r\n * @param _tokens Array of tokens to navigate.\r\n */\r\n constructor(private readonly _tokens: Token[]) { }\r\n\r\n /**\r\n * Advances the cursor by the specified number of tokens.\r\n *\r\n * Updates the current token and index.\r\n *\r\n * @param chars Number of tokens to advance (must be >= 1)\r\n *\r\n * @throws Error with cause `EOF` when advancing past the end\r\n */\r\n public advance(chars = 1): void {\r\n if (chars < 1) {\r\n throw new Error(`${chars} is not a valid value. Please enter a number equal or greater than 1`);\r\n }\r\n\r\n const newIndex = this._currentToken.index + chars;\r\n\r\n if (newIndex >= this._tokens.length) {\r\n this._currentToken.value = { type: TokenType.EOF };\r\n this._currentToken.index = -1;\r\n this.throwEOFError();\r\n } else {\r\n this._currentToken.index = newIndex;\r\n this._currentToken.value = this._tokens[newIndex]!;\r\n }\r\n }\r\n\r\n /**\r\n * Peeks ahead in the token stream without advancing the cursor.\r\n *\r\n * Supports:\r\n * - Single-token lookahead\r\n * - Multi-token lookahead\r\n * - Optional offset from the current token\r\n *\r\n * @returns\r\n * - A single Token when peeking one token\r\n * - An array of Tokens when peeking multiple tokens\r\n *\r\n * @throws Error with cause `EOF` if the peek exceeds the token array\r\n */\r\n public peek(): Token;\r\n public peek<OffSet extends number>(options?: { offset?: PositiveInteger<OffSet> }): Token;\r\n public peek(chars: 1): Token;\r\n public peek<OffSet extends number>(chars: 1, options?: { offset?: PositiveInteger<OffSet> }): Token; \r\n public peek<ReadChars extends number>(chars: PositiveInteger<ReadChars>): TupleOfLength<ReadChars, Token>; \r\n public peek<ReadChars extends number, OffSet extends number>(chars: PositiveInteger<ReadChars>, options?: { offset?: PositiveInteger<OffSet> }): TupleOfLength<ReadChars, Token>;\r\n public peek(charsOrOptions?: number | { offset?: number }, options?: { offset?: number }): Token | Token[] {\r\n const tokens = typeof charsOrOptions === 'number' ? charsOrOptions : 1;\r\n const offset = (typeof charsOrOptions === 'object' ? charsOrOptions : options)?.offset ?? 0;\r\n return tokens === 1 ? this.peekOneToken(this._currentToken.index + offset + 1) : this.peekMany(tokens + offset);\r\n }\r\n\r\n /**\r\n * Peeks multiple tokens ahead.\r\n */\r\n private peekMany(chars: number): Token[] {\r\n const peekedTokens: Token[] = [];\r\n const nextTokenIndex = this._currentToken.index + 1;\r\n\r\n for (let i = nextTokenIndex; i < nextTokenIndex + chars; i++) {\r\n peekedTokens.push(this.peekOneToken(i));\r\n }\r\n\r\n return peekedTokens;\r\n }\r\n\r\n /**\r\n * Peeks a single token at the given absolute index.\r\n */\r\n private peekOneToken(index: number): Token {\r\n if (index >= this._tokens.length) {\r\n this.throwEOFError();\r\n }\r\n\r\n return this._tokens[index]!;\r\n }\r\n\r\n /**\r\n * Throws a standardized EOF error used by the parser\r\n * to terminate token consumption.\r\n */\r\n private throwEOFError(): never {\r\n throw new Error('', { cause: EOF });\r\n }\r\n}\r\n","import { EOF } from '../costants/chars.constants';\r\nimport { TokenType } from '../lexer/models/token-type.enum';\r\nimport { AttributeToken, EventToken, InterpolationExpressionToken, InterpolationLiteralToken, TagOpenNameToken, TextToken, Token } from '../lexer/models/token.type';\r\nimport { ASTNode, AttributeNode, ElementNode, EventNode, InterpolationNode, TextNode } from './models/ast.type';\r\nimport { ASTNodeType } from './models/node.enum';\r\nimport { ParserCursor } from './models/parser-cursor.model';\r\n\r\n/**\r\n * Parser class that transforms a stream of tokens (from the Lexer)\r\n * into an Abstract Syntax Tree (AST) representing the template structure.\r\n *\r\n * Responsibilities:\r\n * - Parse text nodes, elements, attributes, events, and interpolations\r\n * - Maintain cursor state for sequential token consumption\r\n * - Detect tag boundaries and nested structures\r\n *\r\n * The parser assumes that the token stream is syntactically valid according\r\n * to the Lexer rules. Parsing errors are thrown as exceptions.\r\n */\r\nexport class Parser {\r\n\r\n /** Internal cursor for navigating tokens */\r\n private readonly _cursor: ParserCursor;\r\n\r\n /**\r\n * Creates a new Parser instance.\r\n *\r\n * @param tokens Array of tokens produced by the Lexer\r\n */\r\n constructor(private readonly tokens: Token[]) {\r\n this._cursor = new ParserCursor(this.tokens);\r\n }\r\n\r\n /**\r\n * Entry point for parsing the token stream into AST nodes.\r\n *\r\n * @returns Array of top-level AST nodes\r\n */\r\n public parse(): ASTNode[] {\r\n let eof = false;\r\n const nodes: ASTNode[] = [];\r\n\r\n while (!eof) {\r\n try {\r\n nodes.push(this.parseNode());\r\n } catch (err) {\r\n const error = err as Error;\r\n if (error.cause === EOF) {\r\n eof = true;\r\n } else {\r\n throw err;\r\n }\r\n }\r\n }\r\n\r\n return nodes;\r\n }\r\n\r\n /**\r\n * Parses the next AST node based on the current token.\r\n *\r\n * @returns Parsed AST node\r\n * @throws Error if an unexpected token is encountered\r\n */\r\n private parseNode(): ASTNode {\r\n const token = this._cursor.peek();\r\n\r\n switch (token.type) {\r\n case TokenType.TEXT:\r\n return this.parseText(token);\r\n\r\n case TokenType.INTERPOLATION_EXPRESSION:\r\n case TokenType.INTERPOLATION_LITERAL:\r\n return this.parseInterpolation(token);\r\n\r\n case TokenType.TAG_OPEN_NAME:\r\n return this.parseElement(token);\r\n\r\n default:\r\n throw this.error(`Unexpected token ${TokenType[token.type]}`);\r\n }\r\n }\r\n\r\n /**\r\n * Parses a text token into a TextNode.\r\n */\r\n private parseText(token: TextToken): TextNode {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Text,\r\n value: token.parts[0]\r\n };\r\n }\r\n\r\n /**\r\n * Parses an interpolation token into an InterpolationNode.\r\n */\r\n private parseInterpolation(token: InterpolationExpressionToken | InterpolationLiteralToken): InterpolationNode {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Interpolation,\r\n expression: token.parts[0]\r\n };\r\n }\r\n\r\n /**\r\n * Parses an element starting from a TAG_OPEN_NAME token.\r\n * Handles attributes, events, children, and tag closure.\r\n */\r\n private parseElement(token: TagOpenNameToken): ElementNode {\r\n this._cursor.advance();\r\n const tagName = token.parts[0];\r\n\r\n const attributes: AttributeNode[] = [];\r\n const events: EventNode[] = [];\r\n\r\n let read = true;\r\n while (read) {\r\n const token = this._cursor.peek();\r\n switch (token.type) {\r\n case TokenType.ATTRIBUTE:\r\n attributes.push(this.parseAttribute(token));\r\n break;\r\n\r\n case TokenType.EVENT:\r\n events.push(this.parseEvent(token));\r\n break;\r\n\r\n default:\r\n read = false;\r\n }\r\n }\r\n\r\n // Consume TAG_OPEN_END if present: <div>\r\n if (this._cursor.peek().type === TokenType.TAG_OPEN_END) {\r\n this._cursor.advance();\r\n }\r\n\r\n // Handle self-closing tags: <div />\r\n if (this._cursor.peek().type === TokenType.TAG_SELF_CLOSE) {\r\n this._cursor.advance();\r\n return {\r\n type: ASTNodeType.Element,\r\n tagName,\r\n attributes,\r\n events,\r\n children: []\r\n };\r\n }\r\n\r\n // Parse children recursively until closing tag\r\n const children: ASTNode[] = [];\r\n while (!this.isTagClose(tagName)) {\r\n children.push(this.parseNode());\r\n }\r\n\r\n // Consume closing tag </div>\r\n this._cursor.advance();\r\n\r\n return {\r\n type: ASTNodeType.Element,\r\n tagName,\r\n attributes,\r\n events,\r\n children\r\n };\r\n }\r\n\r\n /**\r\n * Parses an attribute token into an AttributeNode.\r\n * Supports literal values and interpolations as attribute values.\r\n */\r\n private parseAttribute(token: AttributeToken): AttributeNode {\r\n this._cursor.advance();\r\n const raw = token.parts[0];\r\n\r\n if (!raw.includes('=')) {\r\n return { name: raw, value: 'true' };\r\n }\r\n\r\n const [name, value] = raw.split('=');\r\n\r\n const nextToken = this._cursor.peek();\r\n if (nextToken.type === TokenType.INTERPOLATION_EXPRESSION || nextToken.type === TokenType.INTERPOLATION_LITERAL) {\r\n return {\r\n name: name!,\r\n value: this.parseInterpolation(nextToken)\r\n };\r\n }\r\n\r\n return {\r\n name: name!,\r\n value: value!.replace(/^['']|['']$/g, '')\r\n };\r\n }\r\n\r\n /**\r\n * Parses an event token into an EventNode.\r\n */\r\n private parseEvent(token: EventToken): EventNode {\r\n this._cursor.advance();\r\n const raw = token.parts[0];\r\n const [name, value] = raw.split('=');\r\n\r\n return {\r\n name: name!,\r\n handler: value!.replace(/^['']|['']$/g, '')\r\n };\r\n }\r\n\r\n /**\r\n * Checks whether the next token is a closing tag matching the given name.\r\n */\r\n private isTagClose(tagName: string): boolean {\r\n const nextToken = this._cursor.peek();\r\n return nextToken.type === TokenType.TAG_CLOSE_NAME && nextToken.parts[0] === tagName;\r\n }\r\n\r\n /**\r\n * Creates a parser error with a consistent prefix.\r\n */\r\n private error(message: string): Error {\r\n return new Error(`[Parser] ${message}`);\r\n }\r\n}\r\n","import { ASTNode, TextNode, InterpolationNode, ElementNode, AttributeNode, EventNode } from '../parser/models/ast.type';\r\nimport { ASTNodeType } from '../parser/models/node.enum';\r\n\r\n/**\r\n * Genera il codice TypeScript della funzione render\r\n * @param ast L'albero AST del template\r\n * @param componentVar Nome della variabile 'this' del componente (di solito `this`)\r\n * @returns Stringa contenente il corpo della funzione render\r\n */\r\nexport function generateRenderFunction(ast: ASTNode[], componentVar = 'this'): string {\r\n const lines: string[] = [];\r\n\r\n // Apertura funzione\r\n lines.push(`const shadow = ${componentVar}.shadowRoot!;`);\r\n\r\n ast.forEach((node, i) => {\r\n lines.push(...processNode(node, `node${i}`, componentVar));\r\n lines.push(`shadow.appendChild(node${i});`);\r\n });\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\n/**\r\n * Genera il codice per creare un singolo nodo\r\n */\r\nfunction processNode(node: ASTNode, varName: string, componentVar: string): string[] {\r\n const code = new Array<string>;\r\n\r\n switch (node.type) {\r\n case ASTNodeType.Text:\r\n code.push(`const ${varName} = document.createTextNode(${JSON.stringify((node as TextNode).value)});`);\r\n break;\r\n\r\n case ASTNodeType.Interpolation:\r\n code.push(`const ${varName} = document.createTextNode(${componentVar}.${(node as InterpolationNode).expression});`);\r\n break;\r\n\r\n case ASTNodeType.Element:\r\n const elNode = node as ElementNode;\r\n code.push(`const ${varName} = document.createElement(${JSON.stringify(elNode.tagName)});`);\r\n\r\n // Attributi\r\n (elNode.attributes || []).forEach((attr: AttributeNode) => {\r\n if (typeof attr.value === 'string') {\r\n code.push(`${varName}.setAttribute(${JSON.stringify(attr.name)}, ${JSON.stringify(attr.value)});`);\r\n } else {\r\n // Interpolazione come value\r\n const interp = attr.value as InterpolationNode;\r\n code.push(`${varName}.setAttribute(${JSON.stringify(attr.name)}, ${componentVar}.${interp.expression});`);\r\n }\r\n });\r\n\r\n // Eventi\r\n (elNode.events || []).forEach((event: EventNode) => {\r\n if (event.name.startsWith('@')) {\r\n event.name = event.name.slice(1);\r\n }\r\n code.push(`${varName}.addEventListener(${JSON.stringify(event.name)}, ${componentVar}.${event.handler}.bind(${componentVar}));`);\r\n });\r\n\r\n // Children\r\n (elNode.children || []).forEach((child, idx) => {\r\n const childVar = `${varName}_child${idx}`;\r\n code.push(...processNode(child, childVar, componentVar));\r\n code.push(`${varName}.appendChild(${childVar});`);\r\n });\r\n\r\n break;\r\n }\r\n\r\n return code;\r\n}\r\n"],"mappings":";;AAkBA,IAAa,IAAb,MAAyB;CAWvB,eAA6C;EAC3C,MAAM;EACN,OAAO;EACP,OAAO;EACR;CAID,IAAW,cAAqC;AAC9C,SAAO,KAAK;;CASd,6BAA8B,IAAI,KAAqB;CAOvD,YAA6C;EAC3C,KAAK;EACL,QAAQ;EACT;CAID,IAAW,WAAqC;AAC9C,SAAO,KAAK;;CAOd,YAAY,GAAsB;AAAf,OAAA,QAAA;;CAenB,QAAe,IAAQ,GAAS;AAC9B,MAAI,IAAQ,EACV,OAAU,MAAM,GAAG,EAAM,sEAAsE;EAGjG,IAAM,IAAW,KAAK,aAAa,QAAQ;AAE3C,EAAI,KAAY,KAAK,MAAM,UACzB,KAAK,aAAa,OAAA,GAClB,KAAK,aAAa,QAAQ,IAC1B,KAAK,aAAa,QAAQ,IAC1B,KAAK,eAAe,KAMhB,CAAA,IAAA,GAAQ,CAAC,SAAS,KAAK,aAAa,KAAK,IAC3C,KAAK,UAAU,OACf,KAAK,UAAU,SAAS,KAExB,KAAK,UAAU,UAGjB,KAAK,aAAa,QAAQ,GAC1B,KAAK,aAAa,QAAQ,KAAK,MAAM,IACrC,KAAK,aAAa,OAAO,KAAK,MAAM,WAAW,EAAS;;CA2B5D,KAAY,GAA+C,GAAkD;EAC3G,IAAM,IAAQ,KAAK,YACb,IAAQ,OAAO,KAAmB,WAAW,IAAiB,GAC9D,KAAU,OAAO,KAAmB,WAAW,IAAiB,IAAU,UAAU;AAC1F,SAAO,MAAU,IAAI,KAAK,YAAY,KAAK,aAAa,QAAQ,IAAS,GAAG,EAAM,GAAG,KAAK,SAAS,IAAQ,GAAQ,EAAM;;CAM3H,aAA0B;AACxB,SAAO,KAAK,MAAM,KAAA,IAChB,MAAK,SAAS;;CAOlB,SAAiB,GAAe,GAAsC;EACpE,IAAM,IAAwB,EAAE,EAC1B,IAAgB,KAAK,aAAa,QAAQ;AAEhD,OAAK,IAAI,IAAI,GAAe,IAAI,IAAgB,GAAO,IACrD,GAAY,KAAK,KAAK,YAAY,GAAG,EAAM,CAAC;AAG9C,SAAO;;CAMT,YAAoB,GAAe,GAAoC;AACrE,MAAI,EAAM,IAAI,EAAM,CAClB,QAAO,EAAM,IAAI,EAAM;AAGzB,EAAI,KAAS,KAAK,MAAM,UACtB,KAAK,eAAe;EAGtB,IAAM,IAAW,KAAK,MAAM,WAAW,EAAM;AAE7C,SADA,EAAM,IAAI,GAAO,EAAS,EACnB;;CAOT,gBAA+B;AAC7B,QAAU,MAAM,IAAI,EAAE,OAAA,GAAY,CAAC;;GC7L3B,IAAL,yBAAA,GAAA;QACL,EAAA,QAAQ,SACR,EAAA,OAAO,QACP,EAAA,gBAAgB,iBAChB,EAAA,WAAY,YACZ,EAAA,eAAe,gBACf,EAAA,YAAY,aACZ,EAAA,YAAY,aACZ,EAAA,QAAQ,SACR,EAAA,gBAAgB,iBAChB,EAAA,2BAA2B,4BAC3B,EAAA,wBAAwB;KACzB,ECZW,IAAL,yBAAA,GAAA;QACL,EAAA,EAAA,OAAA,KAAA,QAEA,EAAA,EAAA,gBAAA,KAAA,iBACA,EAAA,EAAA,iBAAA,KAAA,kBACA,EAAA,EAAA,eAAA,KAAA,gBAEA,EAAA,EAAA,iBAAA,KAAA,kBAEA,EAAA,EAAA,YAAA,KAAA,aACA,EAAA,EAAA,QAAA,KAAA,SAEA,EAAA,EAAA,wBAAA,KAAA,yBACA,EAAA,EAAA,2BAAA,KAAA,4BAEA,EAAA,EAAA,MAAA,KAAA;KACD;;;ACTD,SAAgB,EAAiB,GAAqB,GAA6E;CACjI,IAAI,IAAO,IACP,IAAY,IACZ;AAEJ,QAAO,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;EACA,KAAA;EACA,KAAA;AAQE,GAPA,IAAS;IACP,OAAO,EAAW;IAClB,QAAQ,CAAC;KACP,MAAM,EAAU;KAChB,OAAO,CAAC,EAAU;KACnB,CAAC;IACH,EACD,IAAO;AACP;EAEF,KAAA;AASE,GARA,IAAS;IACP,OAAO,EAAW;IAClB,QAAQ,CAAC;KACP,MAAM,EAAU;KAChB,OAAO,CAAC,EAAU;KACnB,CAAC;IACF,WAAW;IACZ,EACD,IAAO;AACP;EAEF,QAEE,CADA,EAAO,SAAS,EAChB,IAAY,GAAG,IAAY,EAAO,YAAY;;AAIpD,QAAO;;;;ACtCT,SAAgB,EAAa,GAAqB,GAA6E;CAC7H,IAAI,IAAO,IACP,IAAQ,IACR;AAKJ,MAFA,EAAO,SAAS,EAET,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;EACA,KAAA;EACA,KAAA;AAQE,GAPA,IAAS;IACP,OAAO,EAAW;IAClB,QAAQ,CAAC;KACP,MAAM,EAAU;KAChB,OAAO,CAAC,EAAM;KACf,CAAC;IACH,EACD,IAAO;AACP;EAEF,QAEE,CADA,EAAO,SAAS,EAChB,IAAQ,GAAG,IAAQ,EAAO,YAAY;;AAI5C,QAAO;;;;AC7BT,SAAgB,EAA+B,GAAqB,GAA4E;CAC9I,IAAI,IAAO,IACP,IAAgB,IAChB,IAAO,GACP;AAEJ,QAAO,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;AAEE,GADA,KACA,IAAgB,EAAa,GAAQ,EAAc;AACnD;EAEF,KAAA;AAGE,OAFA,KAEI,MAAS,GAAG;AACd,MAAO,SAAS;IAKhB,IAAM,IAAgB,EAAQ,QAAQ,KAAK,EACvC;AAEJ,YAAQ,GAAR;KACE,KAAK,EAAW;AACd,UAAQ,EAAW;AACnB;KAEF,KAAK,EAAW,KACd,KAAQ,EAAW;;AAWvB,IARA,IAAS;KACP;KACA,QAAQ,CAAC;MACP,MAAM,EAAU;MAChB,OAAO,CAAC,EAAc;MACvB,CAAC;KACF,UAAU;KACX,EACD,IAAO;SAEP,KAAgB,EAAa,GAAQ,EAAc;AAGrD;EAEF,QACE,KAAgB,EAAa,GAAQ,EAAc;;AAIzD,QAAO;;AAGT,SAAS,EAAa,GAAqB,GAA+B;AAExE,QADA,EAAO,QAAQ,EAAE,EACV,GAAG,IAAgB,EAAO,YAAY;;;;AC3D/C,SAAgB,EAA4B,GAAqB,GAA4E;CAC3I,IAAI,IAAO,IACP,IAAgB,IAChB;AAKJ,MAFA,EAAO,SAAS,EAET,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;AAGE,OAFA,EAAO,SAAS,EAEZ,EAAO,MAAM,KAAA,KAAkB;AACjC,MAAO,SAAS;IAKhB,IAAM,IAAgB,EAAQ,QAAQ,KAAK,EACvC;AAEJ,YAAQ,GAAR;KACE,KAAK,EAAW;AACd,UAAQ,EAAW;AACnB;KAEF,KAAK,EAAW,KACd,KAAQ,EAAW;;AAWvB,IARA,IAAS;KACP;KACA,QAAQ,CAAC;MACP,MAAM,EAAU;MAChB,OAAO,CAAC,EAAc;MACvB,CAAC;KACF,UAAU;KACX,EACD,IAAO;SASP,KAAgB,GAAG,IAAgB,EAAO,YAAY;AAExD;EAEF,QACE,KAAgB,EAAa,GAAQ,EAAc;;AAIzD,QAAO;;AAGT,SAAS,EAAa,GAAqB,GAA+B;AAExE,QADA,EAAO,QAAQ,EAAE,EACV,GAAG,IAAgB,EAAO,YAAY;;;;AC7B/C,SAAgB,EAAW,GAAsB;AAa/C,QAAO,KAAK,KAAK,EAAI;;AASvB,SAAgB,EAAoB,GAAuB;AACzD,QACG,KAAQ,MAAM,KAAQ,MACtB,KAAQ,MAAM,KAAQ,OACvB,MAAS,MACT,MAAS;;;;AC5Db,SAAgB,EAAqB,GAAqB,GAA6E;CACrI,IAAI;AASJ,CANA,EAAO,SAAS,EAMhB,EAAO,YAAY;CAEnB,IAAM,IAAW,EAAO,MAAM;AAE9B,KAAI,MAAA,GACF,KAAS,EAAE,OAAO,EAAW,uBAAuB;UAC3C,EAAoB,EAAS,CACtC,KAAS,EAAE,OAAO,EAAW,0BAA0B;KAEvD,OAAU,MAAM,gCAAgC,OAAO,aAAa,EAAS,CAAC,mBAAmB;AAGnG,QAAO;;;;ACvBT,SAAgB,EAAe,GAAqB,GAA6E;CAC/H,IAAI,IAAO,IACP;AAEJ,QAAO,GAGL,SAFiB,EAAO,MAEhB,EAAR;EACE,KAAA;AAIE,GAHA,IAAS,EACP,OAAO,EAAW,OACnB,EACD,IAAO;AACP;EAEF,KAAA;AACE,KAAO,SAAS;AAChB;EAEF,KAAA;EACA,KAAA;AAIE,GAHA,IAAS,EACP,OAAO,EAAW,cACnB,EACD,IAAO;AACP;EAEF,QAIE,CAHA,IAAS,EACP,OAAO,EAAW,WACnB,EACD,IAAO;;AAIb,QAAO;;;;AClCT,SAAgB,EAAgB,GAAqB,GAA6E;CAChI,IAAI,IAAO,IACP,IAAU,IACV;AAWJ,MARA,EAAO,QAAQ,EAAE,EAMjB,EAAO,YAAY,EAEZ,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;AASE,GARA,EAAO,SAAS,EAChB,IAAS;IACP,OAAO,EAAW;IAClB,QAAQ,CAAC;KACP,MAAM,EAAU;KAChB,OAAO,CAAC,EAAQ;KACjB,CAAC;IACH,EACD,IAAO;AACP;EAEF,KAAA,GACE,OAAU,MAAM,wCAAwC;EAE1D,QAEE,CADA,EAAO,SAAS,EAChB,IAAU,GAAG,IAAU,EAAO,YAAY;;AAIhD,QAAO;;;;ACrCT,SAAgB,EAAkB,GAAqB,GAA6E;CAClI,IAAI;AAGJ,KAAI,EAAO,MAAM,KAAA,GAEf,CADA,EAAO,SAAS,EAChB,IAAS;EACP,OAAO,EAAW;EAClB,QAAQ,CAAC;GACP,MAAM,EAAU;GAChB,OAAO,EAAE;GACV,CAAC;EACH;MACI;AACL,IAAO,SAAS;EAChB,IAAM,IAAW,EAAO,MAAM;AAE9B,MAAI,MAAA,GAEF,CADA,EAAO,SAAS,EAChB,IAAS;GACP,OAAO,EAAW;GAClB,QAAQ,CAAC;IACP,MAAM,EAAU;IAChB,OAAO,EAAE;IACV,CAAC;GACH;MAED,OAAU,MAAM,wBAAwB,EAAS,2CAA2C,OAAO,aAAa,EAAS,CAAC,YAAY,EAAO,SAAS,MAAM,EAAE,OAAO,EAAO,SAAS,SAAS,IAAI;;AAItM,QAAO;;;;AC/BT,SAAgB,EAAmB,GAAqB,GAA6E;CACnI,IAAI,IAAO,IACP,IAAU,IACV;AAiBJ,MAdA,EAAO,SAAS,EAMhB,EAAO,YAAY,EAQZ,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;EACA,KAAA;EACA,KAAA;AAQE,GAPA,IAAS;IACP,OAAO,EAAW;IAClB,QAAQ,CAAC;KACP,MAAM,EAAU;KAChB,OAAO,CAAC,EAAQ;KACjB,CAAC;IACH,EACD,IAAO;AACP;EAEF,QAEE,CADA,EAAO,SAAS,EAChB,IAAU,GAAG,IAAU,EAAO,YAAY;;AAIhD,QAAO;;;;ACxCT,SAAgB,EAAY,GAAqB,GAA6E;CAC5H,IAAI,IAAO,IACP,IAAO,IACP;AAEJ,QAAO,GACL,SAAQ,EAAO,MAAM,EAArB;EACE,KAAA;AAIE,GADA,IAAS,EAAE,OADO,EAAO,KAAK,GAAG,EAAE,QAAQ,GAAG,CAAC,KAAA,KAAa,EAAW,YAAY,EAAW,eACjE,EAC7B,IAAO;AACP;EAEF,KAAA;AAKE,GAJA,IAAS;IACP,OAAO,EAAW;IAClB,WAAW;IACZ,EACD,IAAO;AACP;EAEF,KAAA;EACA,KAAA;EACA,KAAA;AACE,KAAO,SAAS;AAChB;EAEF,QAEE,CADA,EAAO,SAAS,EAChB,IAAO,GAAG,IAAO,EAAO,YAAY;;AAqB1C,QAJA,EAAO,SAAS,EAAW,EAAK,GAC5B,CAAC;EAAE,MAAM,EAAU;EAAM,OAAO,CAAC,EAAK;EAAE,CAAC,GACzC,KAAA,GAEG;;;;ACnCT,IAAa,IAAb,MAAmB;CAEjB;CAEA,SAAiB,EAAW;CAE5B,SAAiB,IAAI,GAAiB;CAEtC,UAA2B,EAAgB;CAE3C,UAA4E;GACzE,EAAW,QAAQ;GACnB,EAAW,OAAO;GAClB,EAAW,gBAAgB;GAC3B,EAAW,WAAW;GACtB,EAAW,eAAe;GAC1B,EAAW,YAAY;GACvB,EAAW,YAAY;GACvB,EAAW,QAAQ;GACnB,EAAW,gBAAgB;GAC3B,EAAW,2BAA2B;GACtC,EAAW,wBAAwB;EACrC;CAOD,YAAY,GAAsB;AAChC,EADiB,KAAA,QAAA,GACjB,KAAK,UAAU,IAAI,EAAY,KAAK,MAAM;;CAG5C,WAA2B;EACzB,IAAI,IAAM;AAEV,SAAO,CAAC,GACN,KAAI;GACF,IAAM,IAAqB,KAAK,QAAQ,KAAK,SACvC,EAAE,UAAO,WAAQ,aAAU,iBAAc,EAAoB,KAAK,SAAS,EAAE,SAAS,KAAK,OAAO,QAAQ,CAAC;AAcjH,GAZI,GAAQ,UACV,KAAK,QAAQ,KAAK,GAAG,EAAO,EAG1B,KACF,KAAK,OAAO,KAAK,KAAK,OAAO,EAG3B,KACF,KAAK,OAAO,KAAK,EAGnB,KAAK,SAAS;WACP,GAAK;AAEZ,OAAI,EAAM,UAAA,EACR,KAAM;OAEN,OAAM;;AAKZ,SAAO,KAAK;;GCxFJ,IAAL,yBAAA,GAAA;QACL,EAAA,EAAA,UAAA,KAAA,WACA,EAAA,EAAA,OAAA,KAAA,QACA,EAAA,EAAA,gBAAA,KAAA;OCeW,IAAb,MAA0B;CAWxB,gBAA+C;EAC7C,OAAO,EAAE,MAAM,EAAU,KAAK;EAC9B,OAAO;EACR;CAKD,IAAW,eAAuC;AAChD,SAAO,KAAK;;CAQd,YAAY,GAAmC;AAAlB,OAAA,UAAA;;CAW7B,QAAe,IAAQ,GAAS;AAC9B,MAAI,IAAQ,EACV,OAAU,MAAM,GAAG,EAAM,sEAAsE;EAGjG,IAAM,IAAW,KAAK,cAAc,QAAQ;AAE5C,EAAI,KAAY,KAAK,QAAQ,UAC3B,KAAK,cAAc,QAAQ,EAAE,MAAM,EAAU,KAAK,EAClD,KAAK,cAAc,QAAQ,IAC3B,KAAK,eAAe,KAEpB,KAAK,cAAc,QAAQ,GAC3B,KAAK,cAAc,QAAQ,KAAK,QAAQ;;CAwB5C,KAAY,GAA+C,GAAgD;EACzG,IAAM,IAAS,OAAO,KAAmB,WAAW,IAAiB,GAC/D,KAAU,OAAO,KAAmB,WAAW,IAAiB,IAAU,UAAU;AAC1F,SAAO,MAAW,IAAI,KAAK,aAAa,KAAK,cAAc,QAAQ,IAAS,EAAE,GAAG,KAAK,SAAS,IAAS,EAAO;;CAMjH,SAAiB,GAAwB;EACvC,IAAM,IAAwB,EAAE,EAC1B,IAAiB,KAAK,cAAc,QAAQ;AAElD,OAAK,IAAI,IAAI,GAAgB,IAAI,IAAiB,GAAO,IACvD,GAAa,KAAK,KAAK,aAAa,EAAE,CAAC;AAGzC,SAAO;;CAMT,aAAqB,GAAsB;AAKzC,SAJI,KAAS,KAAK,QAAQ,UACxB,KAAK,eAAe,EAGf,KAAK,QAAQ;;CAOtB,gBAA+B;AAC7B,QAAU,MAAM,IAAI,EAAE,OAAA,GAAY,CAAC;;GC/G1B,IAAb,MAAoB;CAGlB;CAOA,YAAY,GAAkC;AAC5C,EAD2B,KAAA,SAAA,GAC3B,KAAK,UAAU,IAAI,EAAa,KAAK,OAAO;;CAQ9C,QAA0B;EACxB,IAAI,IAAM,IACJ,IAAmB,EAAE;AAE3B,SAAO,CAAC,GACN,KAAI;AACF,KAAM,KAAK,KAAK,WAAW,CAAC;WACrB,GAAK;AAEZ,OAAI,EAAM,UAAA,EACR,KAAM;OAEN,OAAM;;AAKZ,SAAO;;CAST,YAA6B;EAC3B,IAAM,IAAQ,KAAK,QAAQ,MAAM;AAEjC,UAAQ,EAAM,MAAd;GACE,KAAK,EAAU,KACb,QAAO,KAAK,UAAU,EAAM;GAE9B,KAAK,EAAU;GACf,KAAK,EAAU,sBACb,QAAO,KAAK,mBAAmB,EAAM;GAEvC,KAAK,EAAU,cACb,QAAO,KAAK,aAAa,EAAM;GAEjC,QACE,OAAM,KAAK,MAAM,oBAAoB,EAAU,EAAM,QAAQ;;;CAOnE,UAAkB,GAA4B;AAE5C,SADA,KAAK,QAAQ,SAAS,EACf;GACL,MAAM,EAAY;GAClB,OAAO,EAAM,MAAM;GACpB;;CAMH,mBAA2B,GAAoF;AAE7G,SADA,KAAK,QAAQ,SAAS,EACf;GACL,MAAM,EAAY;GAClB,YAAY,EAAM,MAAM;GACzB;;CAOH,aAAqB,GAAsC;AACzD,OAAK,QAAQ,SAAS;EACtB,IAAM,IAAU,EAAM,MAAM,IAEtB,IAA8B,EAAE,EAChC,IAAsB,EAAE,EAE1B,IAAO;AACX,SAAO,IAAM;GACX,IAAM,IAAQ,KAAK,QAAQ,MAAM;AACjC,WAAQ,EAAM,MAAd;IACE,KAAK,EAAU;AACb,OAAW,KAAK,KAAK,eAAe,EAAM,CAAC;AAC3C;IAEF,KAAK,EAAU;AACb,OAAO,KAAK,KAAK,WAAW,EAAM,CAAC;AACnC;IAEF,QACE,KAAO;;;AAUb,MALI,KAAK,QAAQ,MAAM,CAAC,SAAS,EAAU,gBACzC,KAAK,QAAQ,SAAS,EAIpB,KAAK,QAAQ,MAAM,CAAC,SAAS,EAAU,eAEzC,QADA,KAAK,QAAQ,SAAS,EACf;GACL,MAAM,EAAY;GAClB;GACA;GACA;GACA,UAAU,EAAE;GACb;EAIH,IAAM,IAAsB,EAAE;AAC9B,SAAO,CAAC,KAAK,WAAW,EAAQ,EAC9B,GAAS,KAAK,KAAK,WAAW,CAAC;AAMjC,SAFA,KAAK,QAAQ,SAAS,EAEf;GACL,MAAM,EAAY;GAClB;GACA;GACA;GACA;GACD;;CAOH,eAAuB,GAAsC;AAC3D,OAAK,QAAQ,SAAS;EACtB,IAAM,IAAM,EAAM,MAAM;AAExB,MAAI,CAAC,EAAI,SAAS,IAAI,CACpB,QAAO;GAAE,MAAM;GAAK,OAAO;GAAQ;EAGrC,IAAM,CAAC,GAAM,KAAS,EAAI,MAAM,IAAI,EAE9B,IAAY,KAAK,QAAQ,MAAM;AAQrC,SAPI,EAAU,SAAS,EAAU,4BAA4B,EAAU,SAAS,EAAU,wBACjF;GACC;GACN,OAAO,KAAK,mBAAmB,EAAU;GAC1C,GAGI;GACC;GACN,OAAO,EAAO,QAAQ,gBAAgB,GAAG;GAC1C;;CAMH,WAAmB,GAA8B;AAC/C,OAAK,QAAQ,SAAS;EAEtB,IAAM,CAAC,GAAM,KADD,EAAM,MAAM,GACE,MAAM,IAAI;AAEpC,SAAO;GACC;GACN,SAAS,EAAO,QAAQ,gBAAgB,GAAG;GAC5C;;CAMH,WAAmB,GAA0B;EAC3C,IAAM,IAAY,KAAK,QAAQ,MAAM;AACrC,SAAO,EAAU,SAAS,EAAU,kBAAkB,EAAU,MAAM,OAAO;;CAM/E,MAAc,GAAwB;AACpC,SAAO,gBAAI,MAAM,YAAY,IAAU;;;;;ACrN3C,SAAgB,EAAuB,GAAgB,IAAe,QAAgB;CACpF,IAAM,IAAkB,EAAE;AAU1B,QAPA,EAAM,KAAK,kBAAkB,EAAa,eAAe,EAEzD,EAAI,SAAS,GAAM,MAAM;AAEvB,EADA,EAAM,KAAK,GAAG,EAAY,GAAM,OAAO,KAAK,EAAa,CAAC,EAC1D,EAAM,KAAK,0BAA0B,EAAE,IAAI;GAC3C,EAEK,EAAM,KAAK,KAAK;;AAMzB,SAAS,EAAY,GAAe,GAAiB,GAAgC;CACnF,IAAM,IAAO,EAAiB;AAE9B,SAAQ,EAAK,MAAb;EACE,KAAK,EAAY;AACf,KAAK,KAAK,SAAS,EAAQ,6BAA6B,KAAK,UAAW,EAAkB,MAAM,CAAC,IAAI;AACrG;EAEF,KAAK,EAAY;AACf,KAAK,KAAK,SAAS,EAAQ,6BAA6B,EAAa,GAAI,EAA2B,WAAW,IAAI;AACnH;EAEF,KAAK,EAAY;GACf,IAAM,IAAS;AAuBf,GAtBA,EAAK,KAAK,SAAS,EAAQ,4BAA4B,KAAK,UAAU,EAAO,QAAQ,CAAC,IAAI,GAGzF,EAAO,cAAc,EAAE,EAAE,SAAS,MAAwB;AACzD,QAAI,OAAO,EAAK,SAAU,SACxB,GAAK,KAAK,GAAG,EAAQ,gBAAgB,KAAK,UAAU,EAAK,KAAK,CAAC,IAAI,KAAK,UAAU,EAAK,MAAM,CAAC,IAAI;SAC7F;KAEL,IAAM,IAAS,EAAK;AACpB,OAAK,KAAK,GAAG,EAAQ,gBAAgB,KAAK,UAAU,EAAK,KAAK,CAAC,IAAI,EAAa,GAAG,EAAO,WAAW,IAAI;;KAE3G,GAGD,EAAO,UAAU,EAAE,EAAE,SAAS,MAAqB;AAIlD,IAHI,EAAM,KAAK,WAAW,IAAI,KAC5B,EAAM,OAAO,EAAM,KAAK,MAAM,EAAE,GAElC,EAAK,KAAK,GAAG,EAAQ,oBAAoB,KAAK,UAAU,EAAM,KAAK,CAAC,IAAI,EAAa,GAAG,EAAM,QAAQ,QAAQ,EAAa,KAAK;KAChI,GAGD,EAAO,YAAY,EAAE,EAAE,SAAS,GAAO,MAAQ;IAC9C,IAAM,IAAW,GAAG,EAAQ,QAAQ;AAEpC,IADA,EAAK,KAAK,GAAG,EAAY,GAAO,GAAU,EAAa,CAAC,EACxD,EAAK,KAAK,GAAG,EAAQ,eAAe,EAAS,IAAI;KACjD;AAEF;;AAGJ,QAAO"}