diff --git a/.github/workflows/ci-jobs.yml b/.github/workflows/ci-jobs.yml index 0cafa28c79d..716194715cf 100644 --- a/.github/workflows/ci-jobs.yml +++ b/.github/workflows/ci-jobs.yml @@ -37,8 +37,6 @@ jobs: run: pnpm build:types - name: Check internal types run: pnpm type-check:internals - - name: Check @handlebars/parser types - run: pnpm type-check:handlebars - name: Check published types run: pnpm type-check:types @@ -222,7 +220,7 @@ jobs: SHOULD_TRANSPILE_FOR_NODE: true run: pnpm build - name: test - run: pnpm test:node && pnpm --filter "@handlebars/parser" test + run: pnpm test:node blueprint-test: name: Blueprint Tests diff --git a/.github/workflows/glimmer-syntax-prettier-smoke-test.yml b/.github/workflows/glimmer-syntax-prettier-smoke-test.yml index 3b87973841f..c5034cfd572 100644 --- a/.github/workflows/glimmer-syntax-prettier-smoke-test.yml +++ b/.github/workflows/glimmer-syntax-prettier-smoke-test.yml @@ -17,7 +17,6 @@ on: - "packages/@glimmer/interfaces/**" - "packages/@glimmer/util/**" - "packages/@glimmer/wire-format/**" - - "packages/@handlebars/parser/**" pull_request: paths: - ".github/workflows/glimmer-syntax-prettier-smoke-test.yml" @@ -27,7 +26,6 @@ on: - "packages/@glimmer/interfaces/**" - "packages/@glimmer/util/**" - "packages/@glimmer/wire-format/**" - - "packages/@handlebars/parser/**" workflow_dispatch: permissions: diff --git a/.gitignore b/.gitignore index 9bf32df156f..3fc45271b1f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ dist-prod lib/*/tests/all.js lib/*/tests/qunit* lib/bundler/man -pkg +/pkg rdoc spade-boot.js spec/reports @@ -55,3 +55,7 @@ npm-debug.log # couple of the files. Once it is, we can switch this over to just ignoring # `types/stable` entirely. types/stable + +# Rust build artifacts (WASM output in pkg/ is committed) +packages/@glimmer/syntax/target/ +packages/@glimmer/syntax/Cargo.lock diff --git a/.prettierignore b/.prettierignore index aad3009a647..e66009a1a1b 100644 --- a/.prettierignore +++ b/.prettierignore @@ -14,3 +14,9 @@ package.json pnpm-lock.yaml internal-docs/**/*.md tracerbench-testing/ +packages/@glimmer/syntax/target/ +packages/@glimmer/syntax/pkg/ +packages/@glimmer/syntax/Cargo.lock +packages/@glimmer/syntax/src/ +*.pest +*.wasm diff --git a/eslint.config.mjs b/eslint.config.mjs index 7407d64b580..98d8a048c8e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -28,8 +28,9 @@ export default [ '**/type-tests/', 'internal-docs/guides/**', 'packages/@glimmer-workspace/**', - 'packages/@handlebars/parser/lib/parser.js', - 'packages/@handlebars/parser/src/**', + 'packages/@glimmer/syntax/pkg/**', + 'packages/@glimmer/syntax/src/**', + 'packages/@glimmer/syntax/target/**', 'tracerbench-testing/', ], }, @@ -171,33 +172,6 @@ export default [ 'ember-internal/no-const-outside-module-scope': 'error', }, }, - { - files: ['packages/@handlebars/**/*.js'], - - languageOptions: { - ecmaVersion: 2017, - sourceType: 'module', - }, - - rules: { - 'ember-internal/require-yuidoc-access': 'off', - 'ember-internal/no-const-outside-module-scope': 'off', - 'disable-features/disable-async-await': 'off', - 'disable-features/disable-generator-functions': 'off', - 'no-implicit-coercion': 'off', - 'no-unused-vars': 'off', - 'import/namespace': 'off', - }, - }, - { - files: ['packages/@handlebars/parser/spec/**/*.js'], - - languageOptions: { - globals: { - ...globals.mocha, - }, - }, - }, { files: [ 'packages/*/tests/**/*.[jt]s', diff --git a/internal-docs/guides/development/build-constraints.md b/internal-docs/guides/development/build-constraints.md index 8e94bd664f6..49034cdc0f0 100644 --- a/internal-docs/guides/development/build-constraints.md +++ b/internal-docs/guides/development/build-constraints.md @@ -137,8 +137,6 @@ The build system has specific rules for what gets inlined vs treated as external - TypeScript helper library (`tslib`) **Always External:** -- `@handlebars/parser` -- `simple-html-tokenizer` - `babel-plugin-debug-macros` - Other `@glimmer/*` packages (to avoid duplication) - `@simple-dom/*` packages diff --git a/package.json b/package.json index 8cf0f30d3d4..bb9e59cbfd2 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,6 @@ "test:browserstack": "node bin/run-browserstack-tests.js", "test:wip": "vite build --mode development --minify false && testem ci", "type-check:internals": "tsc --noEmit", - "type-check:handlebars": "tsc --noEmit --project packages/@handlebars/parser/tsconfig.json", "type-check:types": "tsc --noEmit --project type-tests", "type-check": "npm-run-all type-check:*" }, @@ -76,8 +75,7 @@ "inflection": "^2.0.1", "route-recognizer": "^0.3.4", "semver": "^7.5.2", - "silent-error": "^1.1.1", - "simple-html-tokenizer": "^0.5.11" + "silent-error": "^1.1.1" }, "devDependencies": { "@aws-sdk/client-s3": "^3.731.0", diff --git a/packages/@glimmer-workspace/integration-tests/lib/snapshot.ts b/packages/@glimmer-workspace/integration-tests/lib/snapshot.ts index 23eec8d87d9..9688f204b10 100644 --- a/packages/@glimmer-workspace/integration-tests/lib/snapshot.ts +++ b/packages/@glimmer-workspace/integration-tests/lib/snapshot.ts @@ -1,10 +1,8 @@ import type { Nullable, SimpleElement, SimpleNode } from '@glimmer/interfaces'; -import type { EndTag, Token } from 'simple-html-tokenizer'; import { COMMENT_NODE, TEXT_NODE } from '@glimmer/constants'; -import { castToSimple, unwrap } from '@glimmer/debug-util'; -import { tokenize } from 'simple-html-tokenizer'; +import { unwrap } from '@glimmer/debug-util'; -import { replaceHTML, toInnerHTML } from './dom/simple-utils'; +import { toInnerHTML } from './dom/simple-utils'; export type IndividualSnapshot = 'up' | 'down' | SimpleNode; export type NodesSnapshot = IndividualSnapshot[]; @@ -13,6 +11,40 @@ export function snapshotIsNode(snapshot: IndividualSnapshot): snapshot is Simple return snapshot !== 'up' && snapshot !== 'down'; } +// -- HTML equivalence (replaces simple-html-tokenizer) ---------------------- +// +// Compares two HTML fragments for semantic equivalence by normalizing +// attribute order via the browser's DOM parser. Ember ID attributes +// are normalized to a stable counter so order-independent tests pass. + +function normalizeHTML(html: string): string { + const container = document.createElement('div'); + container.innerHTML = html; + sortAttributes(container); + return container.innerHTML; +} + +function sortAttributes(element: Element): void { + for (const child of Array.from(element.children)) { + if (child.attributes.length > 1) { + const attrs = Array.from(child.attributes).map((a) => [a.name, a.value] as const); + attrs.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)); + for (const [name] of attrs) { + child.removeAttribute(name); + } + for (const [name, value] of attrs) { + child.setAttribute(name, value); + } + } + sortAttributes(child); + } +} + +function cleanEmberIds(html: string): string { + let id = 0; + return html.replace(/ember(\d+|\*)/gu, () => `ember${++id}`); +} + export function equalTokens( testFragment: SimpleElement | string | null, testHTML: SimpleElement | string, @@ -22,41 +54,17 @@ export function equalTokens( throw new Error(`Unexpectedly passed null to equalTokens`); } - const fragTokens = generateTokens(testFragment); - const htmlTokens = generateTokens(testHTML); - - cleanEmberIds(fragTokens.tokens); - cleanEmberIds(htmlTokens.tokens); - - const equiv = QUnit.equiv(fragTokens.tokens, htmlTokens.tokens); - - if (equiv && fragTokens.html !== htmlTokens.html) { - QUnit.assert.deepEqual( - fragTokens.tokens, - htmlTokens.tokens, - message || 'expected tokens to match' - ); - } else { - QUnit.assert.pushResult({ - result: QUnit.equiv(fragTokens.tokens, htmlTokens.tokens), - actual: fragTokens.html, - expected: htmlTokens.html, - message: message || 'expected tokens to match', - }); - } - - // QUnit.assert.deepEqual(fragTokens.tokens, htmlTokens.tokens, msg); -} - -function cleanEmberIds(tokens: Token[]) { - let id = 0; + const fragHTML = typeof testFragment === 'string' ? testFragment : toInnerHTML(testFragment); + const expectedHTML = typeof testHTML === 'string' ? testHTML : toInnerHTML(testHTML); - tokens.forEach((token) => { - const idAttr = 'attributes' in token && token.attributes.filter((a) => a[0] === 'id')[0]; + const normalizedFrag = cleanEmberIds(normalizeHTML(fragHTML)); + const normalizedExpected = cleanEmberIds(normalizeHTML(expectedHTML)); - if (idAttr) { - idAttr[1] = idAttr[1].replace(/ember(\d+|\*)/u, `ember${++id}`); - } + QUnit.assert.pushResult({ + result: normalizedFrag === normalizedExpected, + actual: fragHTML, + expected: expectedHTML, + message: message || 'expected tokens to match', }); } @@ -86,49 +94,6 @@ export function generateSnapshot(element: SimpleElement): SimpleNode[] { return snapshot; } -function generateTokens(divOrHTML: SimpleElement | string): { tokens: Token[]; html: string } { - let div: SimpleElement; - if (typeof divOrHTML === 'string') { - div = castToSimple(document.createElement('div')); - replaceHTML(div, divOrHTML); - } else { - div = divOrHTML; - } - - let tokens = tokenize(toInnerHTML(div), {}); - - tokens = tokens.reduce((tokens, token) => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison - if (token.type === 'StartTag') { - if (token.attributes) { - token.attributes.sort((a, b) => { - if (a[0] > b[0]) { - return 1; - } - if (a[0] < b[0]) { - return -1; - } - return 0; - }); - } - - if (token.selfClosing) { - token.selfClosing = false; - tokens.push(token); - tokens.push({ type: 'EndTag', tagName: token.tagName } as EndTag); - } else { - tokens.push(token); - } - } else { - tokens.push(token); - } - - return tokens; - }, new Array()); - - return { tokens, html: toInnerHTML(div) }; -} - export function equalSnapshots(a: SimpleNode[], b: SimpleNode[]) { QUnit.assert.strictEqual(a.length, b.length, 'Same number of nodes'); for (let i = 0; i < b.length; i++) { diff --git a/packages/@glimmer-workspace/integration-tests/package.json b/packages/@glimmer-workspace/integration-tests/package.json index c303372f5d5..642e160c94d 100644 --- a/packages/@glimmer-workspace/integration-tests/package.json +++ b/packages/@glimmer-workspace/integration-tests/package.json @@ -36,8 +36,7 @@ "@simple-dom/serializer": "^1.4.0", "@simple-dom/void-map": "^1.4.0", "js-reporters": "^2.1.0", - "qunit": "^2.24.1", - "simple-html-tokenizer": "^0.5.11" + "qunit": "^2.24.1" }, "devDependencies": { "@ember/runloop": "workspace:*", diff --git a/packages/@glimmer/syntax/Cargo.toml b/packages/@glimmer/syntax/Cargo.toml new file mode 100644 index 00000000000..6785ab18626 --- /dev/null +++ b/packages/@glimmer/syntax/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "glimmer-template-parser" +version = "0.1.0" +edition = "2024" +description = "A Rust-based PEG parser for Glimmer/Handlebars templates" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +pest = "2" +pest_derive = "2" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +wasm-bindgen = "0.2" + +[profile.release] +opt-level = "z" +lto = "fat" +codegen-units = 1 +strip = true +panic = "abort" diff --git a/packages/@glimmer/syntax/build.sh b/packages/@glimmer/syntax/build.sh new file mode 100755 index 00000000000..883d277de88 --- /dev/null +++ b/packages/@glimmer/syntax/build.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "🦀 Building Glimmer template parser (WASM)..." + +# Clean previous builds +rm -rf pkg/standalone pkg/wasm-bytes.mjs + +# Build only the web (standalone) target. We use a universal wrapper +# (pkg/universal.mjs) that inlines the WASM bytes as base64, so there's +# no need for separate Node/bundler targets. +echo " → Building web target..." +wasm-pack build --target web --out-dir pkg/standalone 2>&1 | grep -v "^warning:" || true + +# Remove files that cause build:types issues +rm -f pkg/standalone/.gitignore +rm -f pkg/standalone/glimmer_template_parser_bg.wasm.d.ts + +# Extra wasm-opt pass to shrink the binary further beyond wasm-pack's default. +# Uses the wasm-opt binary that wasm-pack already downloaded. +WASM_OPT="$(find "$HOME/.cache/.wasm-pack" -name wasm-opt -type f 2>/dev/null | head -1)" +if [ -n "$WASM_OPT" ]; then + echo " → wasm-opt -Oz (extra pass)..." + "$WASM_OPT" -Oz \ + --enable-bulk-memory --enable-reference-types --enable-multivalue \ + --strip-debug --strip-producers --vacuum \ + pkg/standalone/glimmer_template_parser_bg.wasm \ + -o pkg/standalone/glimmer_template_parser_bg.wasm.opt + mv pkg/standalone/glimmer_template_parser_bg.wasm.opt pkg/standalone/glimmer_template_parser_bg.wasm +fi + +# Generate the base64-encoded WASM bytes module for the universal wrapper. +echo " → Generating wasm-bytes.mjs..." +node -e " +const fs = require('fs'); +const wasm = fs.readFileSync('pkg/standalone/glimmer_template_parser_bg.wasm'); +const base64 = wasm.toString('base64'); +const content = 'export const WASM_BYTES_BASE64 = ' + JSON.stringify(base64) + ';\n'; +fs.writeFileSync('pkg/wasm-bytes.mjs', content); +console.log(' wasm bytes: ' + (wasm.length / 1024).toFixed(1) + 'KB raw'); +console.log(' wasm-bytes.mjs: ' + (content.length / 1024).toFixed(1) + 'KB (b64)'); +" + +echo "✅ Build complete!" +ls -lh pkg/standalone/glimmer_template_parser_bg.wasm pkg/wasm-bytes.mjs pkg/universal.mjs diff --git a/packages/@glimmer/syntax/lib/parser.ts b/packages/@glimmer/syntax/lib/parser.ts deleted file mode 100644 index ba4197100bb..00000000000 --- a/packages/@glimmer/syntax/lib/parser.ts +++ /dev/null @@ -1,209 +0,0 @@ -import type { Nullable } from '@glimmer/interfaces'; -import { asPresentArray, expect, getLast, localAssert, unwrap } from '@glimmer/debug-util'; -import { assign } from '@glimmer/util'; -import { - EntityParser, - EventedTokenizer, - HTML5NamedCharRefs as namedCharRefs, -} from 'simple-html-tokenizer'; - -import type * as src from './source/api'; -import type * as ASTv1 from './v1/api'; -import type * as HBS from './v1/handlebars-ast'; - -export type ParserNodeBuilder = Omit & { - start: src.SourceOffset; -}; - -export interface StartTag { - readonly type: 'StartTag'; - name: string; - nameStart: Nullable; - nameEnd: Nullable; - readonly attributes: ASTv1.AttrNode[]; - readonly modifiers: ASTv1.ElementModifierStatement[]; - readonly comments: ASTv1.MustacheCommentStatement[]; - readonly params: ASTv1.VarHead[]; - selfClosing: boolean; - readonly loc: src.SourceSpan; -} - -export interface EndTag { - readonly type: 'EndTag'; - name: string; - readonly loc: src.SourceSpan; -} - -export interface Attribute { - name: string; - currentPart: ASTv1.TextNode | null; - parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[]; - isQuoted: boolean; - isDynamic: boolean; - start: src.SourceOffset; - valueSpan: src.SourceSpan; -} - -export abstract class Parser { - protected elementStack: ASTv1.ParentNode[] = []; - private lines: string[]; - readonly source: src.Source; - public currentAttribute: Nullable = null; - public currentNode: Nullable< - Readonly< - | ParserNodeBuilder - | ParserNodeBuilder - | ParserNodeBuilder - | ParserNodeBuilder - > - > = null; - public tokenizer: EventedTokenizer; - - constructor( - source: src.Source, - entityParser = new EntityParser(namedCharRefs), - mode: 'precompile' | 'codemod' = 'precompile' - ) { - this.source = source; - this.lines = source.source.split(/\r\n?|\n/u); - this.tokenizer = new EventedTokenizer(this, entityParser, mode); - } - - offset(): src.SourceOffset { - let { line, column } = this.tokenizer; - return this.source.offsetFor(line, column); - } - - pos({ line, column }: src.SourcePosition): src.SourceOffset { - return this.source.offsetFor(line, column); - } - - finish(node: ParserNodeBuilder): T { - return assign({}, node, { - loc: node.start.until(this.offset()), - } as const) as unknown as T; - - // node.loc = node.loc.withEnd(end); - } - - abstract parse(node: HBS.Program, locals: string[]): ASTv1.Template; - - abstract Program(node: HBS.Program): HBS.Output<'Program'>; - abstract MustacheStatement(node: HBS.MustacheStatement): HBS.Output<'MustacheStatement'>; - abstract Decorator(node: HBS.Decorator): HBS.Output<'Decorator'>; - abstract BlockStatement(node: HBS.BlockStatement): HBS.Output<'BlockStatement'>; - abstract DecoratorBlock(node: HBS.DecoratorBlock): HBS.Output<'DecoratorBlock'>; - abstract PartialStatement(node: HBS.PartialStatement): HBS.Output<'PartialStatement'>; - abstract PartialBlockStatement( - node: HBS.PartialBlockStatement - ): HBS.Output<'PartialBlockStatement'>; - abstract ContentStatement(node: HBS.ContentStatement): HBS.Output<'ContentStatement'>; - abstract CommentStatement(node: HBS.CommentStatement): HBS.Output<'CommentStatement'>; - abstract SubExpression(node: HBS.SubExpression): HBS.Output<'SubExpression'>; - abstract PathExpression(node: HBS.PathExpression): HBS.Output<'PathExpression'>; - abstract StringLiteral(node: HBS.StringLiteral): HBS.Output<'StringLiteral'>; - abstract BooleanLiteral(node: HBS.BooleanLiteral): HBS.Output<'BooleanLiteral'>; - abstract NumberLiteral(node: HBS.NumberLiteral): HBS.Output<'NumberLiteral'>; - abstract UndefinedLiteral(node: HBS.UndefinedLiteral): HBS.Output<'UndefinedLiteral'>; - abstract NullLiteral(node: HBS.NullLiteral): HBS.Output<'NullLiteral'>; - - abstract reset(): void; - abstract finishData(): void; - abstract tagOpen(): void; - abstract beginData(): void; - abstract appendToData(char: string): void; - abstract beginStartTag(): void; - abstract appendToTagName(char: string): void; - abstract beginAttribute(): void; - abstract appendToAttributeName(char: string): void; - abstract beginAttributeValue(quoted: boolean): void; - abstract appendToAttributeValue(char: string): void; - abstract finishAttributeValue(): void; - abstract markTagAsSelfClosing(): void; - abstract beginEndTag(): void; - abstract finishTag(): void; - abstract beginComment(): void; - abstract appendToCommentData(char: string): void; - abstract finishComment(): void; - abstract reportSyntaxError(error: string): void; - - get currentAttr(): Attribute { - return expect(this.currentAttribute, 'expected attribute'); - } - - get currentTag(): ParserNodeBuilder | ParserNodeBuilder { - let node = this.currentNode; - localAssert(node && (node.type === 'StartTag' || node.type === 'EndTag'), 'expected tag'); - return node; - } - - get currentStartTag(): ParserNodeBuilder { - let node = this.currentNode; - localAssert(node && node.type === 'StartTag', 'expected start tag'); - return node; - } - - get currentEndTag(): ParserNodeBuilder { - let node = this.currentNode; - localAssert(node && node.type === 'EndTag', 'expected end tag'); - return node; - } - - get currentComment(): ParserNodeBuilder { - let node = this.currentNode; - localAssert(node && node.type === 'CommentStatement', 'expected a comment'); - return node; - } - - get currentData(): ParserNodeBuilder { - let node = this.currentNode; - localAssert(node && node.type === 'TextNode', 'expected a text node'); - return node; - } - - acceptNode(node: HBS.Node): HBS.Output { - return (this[node.type as T] as (node: HBS.Node) => HBS.Output)(node); - } - - currentElement(): ASTv1.ParentNode { - return getLast(asPresentArray(this.elementStack)); - } - - sourceForNode(node: HBS.Node, endNode?: { loc: HBS.SourceLocation }): string { - let firstLine = node.loc.start.line - 1; - let currentLine = firstLine - 1; - let firstColumn = node.loc.start.column; - let string = []; - let line: string; - - let lastLine: number; - let lastColumn: number; - - if (endNode) { - lastLine = endNode.loc.end.line - 1; - lastColumn = endNode.loc.end.column; - } else { - lastLine = node.loc.end.line - 1; - lastColumn = node.loc.end.column; - } - - while (currentLine < lastLine) { - currentLine++; - line = unwrap(this.lines[currentLine]); - - if (currentLine === firstLine) { - if (firstLine === lastLine) { - string.push(line.slice(firstColumn, lastColumn)); - } else { - string.push(line.slice(firstColumn)); - } - } else if (currentLine === lastLine) { - string.push(line.slice(0, lastColumn)); - } else { - string.push(line); - } - } - - return string.join('\n'); - } -} diff --git a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts b/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts deleted file mode 100644 index 7101169e21b..00000000000 --- a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts +++ /dev/null @@ -1,708 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */ -import type { Nullable, Recast } from '@glimmer/interfaces'; -import type { TokenizerState } from 'simple-html-tokenizer'; -import { getLast, isPresentArray, localAssert, unwrap } from '@glimmer/debug-util'; - -import type { ParserNodeBuilder, StartTag } from '../parser'; -import type * as src from '../source/api'; -import type { SourceOffset, SourceSpan } from '../source/span'; -import type * as ASTv1 from '../v1/api'; -import type * as HBS from '../v1/handlebars-ast'; - -import { Parser } from '../parser'; -import { NON_EXISTENT_LOCATION } from '../source/location'; -import { generateSyntaxError } from '../syntax-error'; -import { appendChild, isHBSLiteral, printLiteral } from '../utils'; -import b from '../v1/parser-builders'; - -const BEFORE_ATTRIBUTE_NAME = 'beforeAttributeName' as TokenizerState.beforeAttributeName; -const ATTRIBUTE_VALUE_UNQUOTED = 'attributeValueUnquoted' as TokenizerState.attributeValueUnquoted; - -export interface PendingError { - mustache(span: SourceSpan): never; - eof(offset: SourceOffset): never; -} - -export abstract class HandlebarsNodeVisitors extends Parser { - // Because we interleave the HTML and HBS parsing, sometimes the HTML - // tokenizer can run out of tokens when we switch into {{...}} or reached - // EOF. There are positions where neither of these are expected, and it would - // like to generate an error, but there is no span to attach the error to. - // This allows the HTML tokenization to stash an error message and the next - // mustache visitor will attach the message to the appropriate span and throw - // the error. - protected pendingError: Nullable = null; - - abstract override appendToCommentData(s: string): void; - abstract override beginAttributeValue(quoted: boolean): void; - abstract override finishAttributeValue(): void; - - parse(program: HBS.UpstreamProgram, blockParams: string[]): ASTv1.Template { - localAssert(program.loc, '[BUG] Program in parser unexpectedly did not have loc'); - - let node = b.template({ - body: [], - blockParams, - loc: this.source.spanFor(program.loc), - }); - - let template = this.parseProgram(node, program); - - // TODO: we really need to verify that the tokenizer is in an acceptable - // state when we are "done" parsing. For example, right now, `(node: T, program: HBS.UpstreamProgram): T { - if (program.body.length === 0) { - return node; - } - - let poppedNode; - - try { - this.elementStack.push(node); - - for (let child of program.body) { - this.acceptNode(child); - } - } finally { - poppedNode = this.elementStack.pop(); - } - - // Ensure that that the element stack is balanced properly. - if (node !== poppedNode) { - if (poppedNode?.type === 'ElementNode') { - throw generateSyntaxError(`Unclosed element \`${poppedNode.tag}\``, poppedNode.loc); - } else { - // If the stack is not balanced, then it is likely our own bug, because - // any unclosed Handlebars blocks should already been caught by now - localAssert(poppedNode !== undefined, '[BUG] empty parser elementStack'); - localAssert(false, `[BUG] mismatched parser elementStack node: ${node.type}`); - } - } - - return node; - } - - BlockStatement(block: HBS.UpstreamBlockStatement): ASTv1.BlockStatement | void { - if (this.tokenizer.state === 'comment') { - localAssert(block.loc, '[BUG] BlockStatement in parser unexpectedly did not have loc'); - this.appendToCommentData(this.sourceForNode(block as HBS.Node)); - return; - } - - if (this.tokenizer.state !== 'data' && this.tokenizer.state !== 'beforeData') { - throw generateSyntaxError( - 'A block may only be used inside an HTML element or another block.', - this.source.spanFor(block.loc) - ); - } - - const { path, params, hash } = acceptCallNodes(this, block); - const loc = this.source.spanFor(block.loc); - - // Backfill block params loc for the default block - let blockParams: ASTv1.VarHead[] = []; - let repairedBlock: HBS.BlockStatement; - - if (block.program.blockParams?.length) { - // Start from right after the hash - let span = hash.loc.collapse('end'); - - // Extend till the beginning of the block - if (block.program.loc) { - span = span.withEnd(this.source.spanFor(block.program.loc).getStart()); - } else if (block.program.body[0]) { - span = span.withEnd(this.source.spanFor(block.program.body[0].loc).getStart()); - } else { - // ...or if all else fail, use the end of the block statement - // this can only happen if the block statement is empty anyway - span = span.withEnd(loc.getEnd()); - } - - repairedBlock = repairBlock(this.source, block, span); - - // Now we have a span for something like this: - // - // {{#foo bar baz=bat as |wow wat|}} - // ~~~~~~~~~~~~~~~ - // - // Or, if we are unlucky: - // - // {{#foo bar baz=bat as |wow wat|}}{{/foo}} - // ~~~~~~~~~~~~~~~~~~~~~~~ - // - // Either way, within this span, there should be exactly two pipes - // fencing our block params, neatly whitespace separated and with - // legal identifiers only - const content = span.asString(); - let skipStart = content.indexOf('|') + 1; - const limit = content.indexOf('|', skipStart); - - for (const name of block.program.blockParams) { - let nameStart: number; - let loc: SourceSpan; - - if (skipStart >= limit) { - nameStart = -1; - } else { - nameStart = content.indexOf(name, skipStart); - } - - if (nameStart === -1 || nameStart + name.length > limit) { - skipStart = limit; - loc = this.source.spanFor(NON_EXISTENT_LOCATION); - } else { - skipStart = nameStart; - loc = span.sliceStartChars({ skipStart, chars: name.length }); - skipStart += name.length; - } - - blockParams.push(b.var({ name, loc })); - } - } else { - repairedBlock = repairBlock(this.source, block, loc); - } - - const program = this.Program(repairedBlock.program, blockParams); - const inverse = repairedBlock.inverse ? this.Program(repairedBlock.inverse, []) : null; - - const node = b.block({ - path, - params, - hash, - defaultBlock: program, - elseBlock: inverse, - loc: this.source.spanFor(block.loc), - openStrip: block.openStrip, - inverseStrip: block.inverseStrip, - closeStrip: block.closeStrip, - }); - - const parentProgram = this.currentElement(); - - appendChild(parentProgram, node); - } - - MustacheStatement(rawMustache: HBS.MustacheStatement): ASTv1.MustacheStatement | void { - this.pendingError?.mustache(this.source.spanFor(rawMustache.loc)); - - const { tokenizer } = this; - - if (tokenizer.state === 'comment') { - this.appendToCommentData(this.sourceForNode(rawMustache)); - return; - } - - let mustache: ASTv1.MustacheStatement; - const { escaped, loc, strip } = rawMustache; - - if ('original' in rawMustache.path && rawMustache.path.original === '...attributes') { - throw generateSyntaxError( - 'Illegal use of ...attributes', - this.source.spanFor(rawMustache.loc) - ); - } - - if (isHBSLiteral(rawMustache.path)) { - mustache = b.mustache({ - path: this.acceptNode<(typeof rawMustache.path)['type']>(rawMustache.path), - params: [], - hash: b.hash({ pairs: [], loc: this.source.spanFor(rawMustache.path.loc).collapse('end') }), - trusting: !escaped, - loc: this.source.spanFor(loc), - strip, - }); - } else { - const { path, params, hash } = acceptCallNodes( - this, - rawMustache as HBS.MustacheStatement & { - path: HBS.PathExpression | HBS.SubExpression; - } - ); - mustache = b.mustache({ - path, - params, - hash, - trusting: !escaped, - loc: this.source.spanFor(loc), - strip, - }); - } - - switch (tokenizer.state) { - // Tag helpers - case 'tagOpen': - case 'tagName': - throw generateSyntaxError(`Cannot use mustaches in an elements tagname`, mustache.loc); - - case 'beforeAttributeName': - addElementModifier(this.currentStartTag, mustache); - break; - case 'attributeName': - case 'afterAttributeName': - this.beginAttributeValue(false); - this.finishAttributeValue(); - addElementModifier(this.currentStartTag, mustache); - tokenizer.transitionTo(BEFORE_ATTRIBUTE_NAME); - break; - case 'afterAttributeValueQuoted': - addElementModifier(this.currentStartTag, mustache); - tokenizer.transitionTo(BEFORE_ATTRIBUTE_NAME); - break; - - // Attribute values - case 'beforeAttributeValue': - this.beginAttributeValue(false); - this.appendDynamicAttributeValuePart(mustache); - tokenizer.transitionTo(ATTRIBUTE_VALUE_UNQUOTED); - break; - case 'attributeValueDoubleQuoted': - case 'attributeValueSingleQuoted': - case 'attributeValueUnquoted': - this.appendDynamicAttributeValuePart(mustache); - break; - - // TODO: Only append child when the tokenizer state makes - // sense to do so, otherwise throw an error. - default: - appendChild(this.currentElement(), mustache); - } - - return mustache; - } - - appendDynamicAttributeValuePart(part: ASTv1.MustacheStatement): void { - this.finalizeTextPart(); - const attr = this.currentAttr; - attr.isDynamic = true; - attr.parts.push(part); - } - - finalizeTextPart(): void { - const attr = this.currentAttr; - const text = attr.currentPart; - if (text !== null) { - this.currentAttr.parts.push(text); - this.startTextPart(); - } - } - - startTextPart(): void { - this.currentAttr.currentPart = null; - } - - ContentStatement(content: HBS.ContentStatement): void { - updateTokenizerLocation(this.tokenizer, content); - - this.tokenizer.tokenizePart(content.value); - this.tokenizer.flushData(); - } - - CommentStatement(rawComment: HBS.CommentStatement): Nullable { - const { tokenizer } = this; - - if (tokenizer.state === 'comment') { - this.appendToCommentData(this.sourceForNode(rawComment)); - return null; - } - - const { value, loc } = rawComment; - const comment = b.mustacheComment({ value, loc: this.source.spanFor(loc) }); - - switch (tokenizer.state) { - case 'beforeAttributeName': - case 'afterAttributeName': - this.currentStartTag.comments.push(comment); - break; - - case 'beforeData': - case 'data': - appendChild(this.currentElement(), comment); - break; - - default: - throw generateSyntaxError( - `Using a Handlebars comment when in the \`${tokenizer['state']}\` state is not supported`, - this.source.spanFor(rawComment.loc) - ); - } - - return comment; - } - - PartialStatement(partial: HBS.PartialStatement): never { - throw generateSyntaxError( - `Handlebars partials are not supported`, - this.source.spanFor(partial.loc) - ); - } - - PartialBlockStatement(partialBlock: HBS.PartialBlockStatement): never { - throw generateSyntaxError( - `Handlebars partial blocks are not supported`, - this.source.spanFor(partialBlock.loc) - ); - } - - Decorator(decorator: HBS.Decorator): never { - throw generateSyntaxError( - `Handlebars decorators are not supported`, - this.source.spanFor(decorator.loc) - ); - } - - DecoratorBlock(decoratorBlock: HBS.DecoratorBlock): never { - throw generateSyntaxError( - `Handlebars decorator blocks are not supported`, - this.source.spanFor(decoratorBlock.loc) - ); - } - - SubExpression(sexpr: HBS.SubExpression): ASTv1.SubExpression { - const { path, params, hash } = acceptCallNodes(this, sexpr); - return b.sexpr({ path, params, hash, loc: this.source.spanFor(sexpr.loc) }); - } - - PathExpression(path: HBS.PathExpression): ASTv1.PathExpression { - const { original } = path; - let parts: string[]; - - if (original.indexOf('/') !== -1) { - if (original.slice(0, 2) === './') { - throw generateSyntaxError( - `Using "./" is not supported in Glimmer and unnecessary`, - this.source.spanFor(path.loc) - ); - } - if (original.slice(0, 3) === '../') { - throw generateSyntaxError( - `Changing context using "../" is not supported in Glimmer`, - this.source.spanFor(path.loc) - ); - } - if (original.indexOf('.') !== -1) { - throw generateSyntaxError( - `Mixing '.' and '/' in paths is not supported in Glimmer; use only '.' to separate property paths`, - this.source.spanFor(path.loc) - ); - } - parts = [path.parts.join('/')]; - } else if (original === '.') { - throw generateSyntaxError( - `'.' is not a supported path in Glimmer; check for a path with a trailing '.'`, - this.source.spanFor(path.loc) - ); - } else { - parts = path.parts; - } - - let thisHead = false; - - // This is to fix a bug in the Handlebars AST where the path expressions in - // `{{this.foo}}` (and similarly `{{foo-bar this.foo named=this.foo}}` etc) - // are simply turned into `{{foo}}`. The fix is to push it back onto the - // parts array and let the runtime see the difference. However, we cannot - // simply use the string `this` as it means literally the property called - // "this" in the current context (it can be expressed in the syntax as - // `{{[this]}}`, where the square bracket are generally for this kind of - // escaping – such as `{{foo.["bar.baz"]}}` would mean lookup a property - // named literally "bar.baz" on `this.foo`). By convention, we use `null` - // for this purpose. - if (/^this(?:\..+)?$/u.test(original)) { - thisHead = true; - } - - let pathHead: ASTv1.PathHead; - if (thisHead) { - pathHead = b.this({ - loc: this.source.spanFor({ - start: path.loc.start, - end: { line: path.loc.start.line, column: path.loc.start.column + 4 }, - }), - }); - } else if (path.data) { - const head = parts.shift(); - - if (head === undefined) { - throw generateSyntaxError( - `Attempted to parse a path expression, but it was not valid. Paths beginning with @ must start with a-z.`, - this.source.spanFor(path.loc) - ); - } - - pathHead = b.atName({ - name: `@${head}`, - loc: this.source.spanFor({ - start: path.loc.start, - end: { line: path.loc.start.line, column: path.loc.start.column + head.length + 1 }, - }), - }); - } else { - const head = parts.shift(); - - if (head === undefined) { - throw generateSyntaxError( - `Attempted to parse a path expression, but it was not valid. Paths must start with a-z or A-Z.`, - this.source.spanFor(path.loc) - ); - } - - pathHead = b.var({ - name: head, - loc: this.source.spanFor({ - start: path.loc.start, - end: { line: path.loc.start.line, column: path.loc.start.column + head.length }, - }), - }); - } - - return b.path({ - head: pathHead, - tail: parts, - loc: this.source.spanFor(path.loc), - }); - } - - Hash(hash: HBS.Hash): ASTv1.Hash { - const pairs = hash.pairs.map((pair) => - b.pair({ - key: pair.key, - value: this.acceptNode(pair.value), - loc: this.source.spanFor(pair.loc), - }) - ); - - return b.hash({ pairs, loc: this.source.spanFor(hash.loc) }); - } - - StringLiteral(string: HBS.StringLiteral): ASTv1.StringLiteral { - return b.literal({ - type: 'StringLiteral', - value: string.value, - loc: this.source.spanFor(string.loc), - }); - } - - BooleanLiteral(boolean: HBS.BooleanLiteral): ASTv1.BooleanLiteral { - return b.literal({ - type: 'BooleanLiteral', - value: boolean.value, - loc: this.source.spanFor(boolean.loc), - }); - } - - NumberLiteral(number: HBS.NumberLiteral): ASTv1.NumberLiteral { - return b.literal({ - type: 'NumberLiteral', - value: number.value, - loc: this.source.spanFor(number.loc), - }); - } - - UndefinedLiteral(undef: HBS.UndefinedLiteral): ASTv1.UndefinedLiteral { - return b.literal({ - type: 'UndefinedLiteral', - value: undefined, - loc: this.source.spanFor(undef.loc), - }); - } - - NullLiteral(nul: HBS.NullLiteral): ASTv1.NullLiteral { - return b.literal({ - type: 'NullLiteral', - value: null, - loc: this.source.spanFor(nul.loc), - }); - } -} - -function calculateRightStrippedOffsets(original: string, value: string) { - if (value === '') { - // if it is empty, just return the count of newlines - // in original - return { - lines: original.split('\n').length - 1, - columns: 0, - }; - } - - // otherwise, return the number of newlines prior to - // `value` - const [difference] = original.split(value) as [string]; - const lines = difference.split(/\n/u); - const lineCount = lines.length - 1; - - return { - lines: lineCount, - columns: unwrap(lines[lineCount]).length, - }; -} - -function updateTokenizerLocation(tokenizer: Parser['tokenizer'], content: HBS.ContentStatement) { - let line = content.loc.start.line; - let column = content.loc.start.column; - - const offsets = calculateRightStrippedOffsets( - content.original as Recast, - content.value - ); - - line = line + offsets.lines; - if (offsets.lines) { - column = offsets.columns; - } else { - column = column + offsets.columns; - } - - tokenizer.line = line; - tokenizer.column = column; -} - -function acceptCallNodes( - compiler: HandlebarsNodeVisitors, - node: { - path: - | HBS.PathExpression - | HBS.SubExpression - | HBS.StringLiteral - | HBS.UndefinedLiteral - | HBS.NullLiteral - | HBS.NumberLiteral - | HBS.BooleanLiteral; - params: HBS.Expression[]; - hash?: HBS.Hash; - } -): { - path: ASTv1.PathExpression | ASTv1.SubExpression; - params: ASTv1.Expression[]; - hash: ASTv1.Hash; -} { - let path: ASTv1.PathExpression | ASTv1.SubExpression; - - switch (node.path.type) { - case 'PathExpression': - path = compiler.PathExpression(node.path); - break; - - case 'SubExpression': - path = compiler.SubExpression(node.path); - break; - - case 'StringLiteral': - case 'UndefinedLiteral': - case 'NullLiteral': - case 'NumberLiteral': - case 'BooleanLiteral': { - let value: string; - if (node.path.type === 'BooleanLiteral') { - value = node.path.original.toString(); - } else if (node.path.type === 'StringLiteral') { - value = `"${node.path.original}"`; - } else if (node.path.type === 'NullLiteral') { - value = 'null'; - } else if (node.path.type === 'NumberLiteral') { - value = node.path.value.toString(); - } else { - value = 'undefined'; - } - throw generateSyntaxError( - `${node.path.type} "${ - node.path.type === 'StringLiteral' ? node.path.original : value - }" cannot be called as a sub-expression, replace (${value}) with ${value}`, - compiler.source.spanFor(node.path.loc) - ); - } - } - - const params = node.params.map((e) => compiler.acceptNode(e)); - - // if there is no hash, position it as a collapsed node immediately after the last param (or the - // path, if there are also no params) - const end = isPresentArray(params) ? getLast(params).loc : path.loc; - - const hash = node.hash - ? compiler.Hash(node.hash) - : b.hash({ - pairs: [], - loc: compiler.source.spanFor(end).collapse('end'), - }); - - return { path, params, hash }; -} - -function addElementModifier( - element: ParserNodeBuilder, - mustache: ASTv1.MustacheStatement -) { - const { path, params, hash, loc } = mustache; - - if (isHBSLiteral(path)) { - const modifier = `{{${printLiteral(path)}}}`; - const tag = `<${element.name} ... ${modifier} ...`; - - throw generateSyntaxError(`In ${tag}, ${modifier} is not a valid modifier`, mustache.loc); - } - - const modifier = b.elementModifier({ path, params, hash, loc }); - element.modifiers.push(modifier); -} - -function repairBlock( - source: src.Source, - block: HBS.UpstreamBlockStatement, - fallbackStart: SourceSpan -): HBS.BlockStatement { - // Extend till the beginning of the block - if (!block.program.loc) { - const start = block.program.body.at(0); - const end = block.program.body.at(-1); - - if (start && end) { - block.program.loc = { - ...start.loc, - end: end.loc.end, - }; - } else { - const loc = source.spanFor(block.loc); - block.program.loc = fallbackStart.withEnd(loc.getEnd()); - } - } - - let endProgram = source.spanFor(block.program.loc).getEnd(); - - if (block.inverse && !block.inverse.loc) { - block.inverse.loc = endProgram.collapsed(); - } - - return block as HBS.BlockStatement; -} diff --git a/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts b/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts index 6052abbe97f..902ae9c76c7 100644 --- a/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts +++ b/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts @@ -1,634 +1,31 @@ +/** + * Rust-based template preprocessing. + * + * This module replaces the old multipass pipeline (Jison + simple-html-tokenizer) + * with a single-pass Rust/WASM parser built on pest.rs. + * + * The Rust parser produces ASTv1-compatible plain JSON. This wrapper then: + * 1. Converts plain location objects to SourceSpan instances + * 2. Applies AST plugins + * 3. Sets up blockParams/locals + */ + import type { Nullable } from '@glimmer/interfaces'; -import type { TokenizerState } from 'simple-html-tokenizer'; -import { - asPresentArray, - assertPresentArray, - getFirst, - getLast, - isPresentArray, - localAssert, -} from '@glimmer/debug-util'; import { assign } from '@glimmer/util'; -import { parse, parseWithoutProcessing } from '@handlebars/parser'; -import { EntityParser } from 'simple-html-tokenizer'; -import type { EndTag, StartTag } from '../parser'; import type { NodeVisitor } from '../traversal/visitor'; import type * as ASTv1 from '../v1/api'; -import type * as HBS from '../v1/handlebars-ast'; import print from '../generation/print'; -import { voidMap } from '../generation/printer'; import * as src from '../source/api'; import { generateSyntaxError } from '../syntax-error'; import traverse from '../traversal/traverse'; import Walker from '../traversal/walker'; -import { appendChild } from '../utils'; -import b from '../v1/parser-builders'; import publicBuilder from '../v1/public-builders'; -import { HandlebarsNodeVisitors } from './handlebars-node-visitors'; - -// vendored from simple-html-tokenizer because it's unexported -function isSpace(char: string): boolean { - return /[\t\n\f ]/u.test(char); -} - -export class TokenizerEventHandlers extends HandlebarsNodeVisitors { - private tagOpenLine = 0; - private tagOpenColumn = 0; - - reset(): void { - this.currentNode = null; - } - - // Comment - - beginComment(): void { - this.currentNode = { - type: 'CommentStatement', - value: '', - start: this.source.offsetFor(this.tagOpenLine, this.tagOpenColumn), - }; - } - - appendToCommentData(char: string): void { - this.currentComment.value += char; - } - - finishComment(): void { - appendChild(this.currentElement(), b.comment(this.finish(this.currentComment))); - } - - // Data - - beginData(): void { - this.currentNode = { - type: 'TextNode', - chars: '', - start: this.offset(), - }; - } - - appendToData(char: string): void { - this.currentData.chars += char; - } - - finishData(): void { - appendChild(this.currentElement(), b.text(this.finish(this.currentData))); - } - - // Tags - basic - - tagOpen(): void { - this.tagOpenLine = this.tokenizer.line; - this.tagOpenColumn = this.tokenizer.column; - } - - beginStartTag(): void { - this.currentNode = { - type: 'StartTag', - name: '', - nameStart: null, - nameEnd: null, - attributes: [], - modifiers: [], - comments: [], - params: [], - selfClosing: false, - start: this.source.offsetFor(this.tagOpenLine, this.tagOpenColumn), - }; - } - - beginEndTag(): void { - this.currentNode = { - type: 'EndTag', - name: '', - start: this.source.offsetFor(this.tagOpenLine, this.tagOpenColumn), - }; - } - - finishTag(): void { - let tag = this.finish(this.currentTag); - - if (tag.type === 'StartTag') { - this.finishStartTag(); - - if (tag.name === ':') { - throw generateSyntaxError( - 'Invalid named block named detected, you may have created a named block without a name, or you may have began your name with a number. Named blocks must have names that are at least one character long, and begin with a lower case letter', - this.source.spanFor({ - start: this.currentTag.start.toJSON(), - end: this.offset().toJSON(), - }) - ); - } - - if (voidMap.has(tag.name) || tag.selfClosing) { - this.finishEndTag(true); - } - } else { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- exhaustive - localAssert(tag.type === 'EndTag', `Invalid tag type ${tag.type}`); - this.finishEndTag(false); - } - } - - finishStartTag(): void { - let { name, nameStart, nameEnd } = this.currentStartTag; - - // <> should probably be a syntax error, but s-h-t is currently broken for that case - localAssert(name !== '', 'tag name cannot be empty'); - localAssert(nameStart !== null, 'nameStart unexpectedly null'); - localAssert(nameEnd !== null, 'nameEnd unexpectedly null'); - - let nameLoc = nameStart.until(nameEnd); - let [head, ...tail] = asPresentArray(name.split('.')); - let path = b.path({ - head: b.head({ original: head, loc: nameLoc.sliceStartChars({ chars: head.length }) }), - tail, - loc: nameLoc, - }); - - let { attributes, modifiers, comments, params, selfClosing, loc } = this.finish( - this.currentStartTag - ); - - let element = b.element({ - path, - selfClosing, - attributes, - modifiers, - comments, - params, - children: [], - openTag: loc, - closeTag: selfClosing ? null : src.SourceSpan.broken(), - loc, - }); - this.elementStack.push(element); - } - - finishEndTag(isVoid: boolean): void { - let { start: closeTagStart } = this.currentTag; - let tag = this.finish(this.currentTag); - - let element = this.elementStack.pop() as ASTv1.ParentNode; - - this.validateEndTag(tag, element, isVoid); - let parent = this.currentElement(); - - if (isVoid) { - element.closeTag = null; - } else if (element.selfClosing) { - localAssert(element.closeTag === null, 'element.closeTag unexpectedly present'); - } else { - element.closeTag = closeTagStart.until(this.offset()); - } - - element.loc = element.loc.withEnd(this.offset()); - - appendChild(parent, b.element(element)); - } - - markTagAsSelfClosing(): void { - let tag = this.currentTag; - - if (tag.type === 'StartTag') { - tag.selfClosing = true; - } else { - throw generateSyntaxError( - `Invalid end tag: closing tag must not be self-closing`, - this.source.spanFor({ start: tag.start.toJSON(), end: this.offset().toJSON() }) - ); - } - } - - // Tags - name - - appendToTagName(char: string): void { - let tag = this.currentTag; - tag.name += char; - - if (tag.type === 'StartTag') { - let offset = this.offset(); - - if (tag.nameStart === null) { - localAssert(tag.nameEnd === null, 'nameStart and nameEnd must both be null'); - - // Note that the tokenizer already consumed the token here - tag.nameStart = offset.move(-1); - } - - tag.nameEnd = offset; - } - } - - // Tags - attributes - - beginAttribute(): void { - let offset = this.offset(); - - this.currentAttribute = { - name: '', - parts: [], - currentPart: null, - isQuoted: false, - isDynamic: false, - start: offset, - valueSpan: offset.collapsed(), - }; - } - - appendToAttributeName(char: string): void { - this.currentAttr.name += char; - - // The block params parsing code can actually handle peek=non-space just - // fine, but this check was added as an optimization, as there is a little - // bit of setup overhead for the parsing logic just to immediately bail - if (this.currentAttr.name === 'as') { - this.parsePossibleBlockParams(); - } - } - - beginAttributeValue(isQuoted: boolean): void { - this.currentAttr.isQuoted = isQuoted; - this.startTextPart(); - this.currentAttr.valueSpan = this.offset().collapsed(); - } - - appendToAttributeValue(char: string): void { - let parts = this.currentAttr.parts; - let lastPart = parts[parts.length - 1]; - - let current = this.currentAttr.currentPart; - if (current) { - current.chars += char; - - // update end location for each added char - current.loc = current.loc.withEnd(this.offset()); - } else { - // initially assume the text node is a single char - let loc: src.SourceOffset = this.offset(); - - // the tokenizer line/column have already been advanced, correct location info - if (char === '\n') { - loc = lastPart ? lastPart.loc.getEnd() : this.currentAttr.valueSpan.getStart(); - } else { - loc = loc.move(-1); - } - - this.currentAttr.currentPart = b.text({ chars: char, loc: loc.collapsed() }); - } - } - - finishAttributeValue(): void { - this.finalizeTextPart(); - - let tag = this.currentTag; - let tokenizerPos = this.offset(); - - if (tag.type === 'EndTag') { - throw generateSyntaxError( - `Invalid end tag: closing tag must not have attributes`, - this.source.spanFor({ start: tag.start.toJSON(), end: tokenizerPos.toJSON() }) - ); - } - - let { name, parts, start, isQuoted, isDynamic, valueSpan } = this.currentAttr; - - // Just trying to be helpful with `` rather than letting it through as an attribute - if (name.startsWith('|') && parts.length === 0 && !isQuoted && !isDynamic) { - throw generateSyntaxError( - 'Invalid block parameters syntax: block parameters must be preceded by the `as` keyword', - start.until(start.move(name.length)) - ); - } - - let value = this.assembleAttributeValue(parts, isQuoted, isDynamic, start.until(tokenizerPos)); - value.loc = valueSpan.withEnd(tokenizerPos); - - let attribute = b.attr({ name, value, loc: start.until(tokenizerPos) }); - - this.currentStartTag.attributes.push(attribute); - } - - private parsePossibleBlockParams() { - // const enums that we can't use directly - const BEFORE_ATTRIBUTE_NAME = 'beforeAttributeName' as TokenizerState.beforeAttributeName; - const ATTRIBUTE_NAME = 'attributeName' as TokenizerState.attributeName; - const AFTER_ATTRIBUTE_NAME = 'afterAttributeName' as TokenizerState.afterAttributeName; - - // Regex to validate the identifier for block parameters. - // Based on the ID validation regex in Handlebars. - - const ID_INVERSE_PATTERN = /[!"#%&'()*+./;<=>@[\\\]^`{|}~]/u; - - type States = { - PossibleAs: { state: 'PossibleAs' }; - BeforeStartPipe: { state: 'BeforeStartPipe' }; - BeforeBlockParamName: { state: 'BeforeBlockParamName' }; - BlockParamName: { - state: 'BlockParamName'; - name: string; - start: src.SourceOffset; - }; - AfterEndPipe: { state: 'AfterEndPipe' }; - Error: { - state: 'Error'; - message: string; - start: src.SourceOffset; - }; - Done: { state: 'Done' }; - }; - - type State = States[keyof States]; - - type Handler = (next: string) => void; - - localAssert(this.tokenizer.state === ATTRIBUTE_NAME, 'must be in TokenizerState.attributeName'); - - const element = this.currentStartTag; - const as = this.currentAttr; - - let state = { state: 'PossibleAs' } as State; - - const handlers = { - PossibleAs: (next: string) => { - localAssert(state.state === 'PossibleAs', 'bug in block params parser'); - - if (isSpace(next)) { - // " as ..." - state = { state: 'BeforeStartPipe' }; - this.tokenizer.transitionTo(AFTER_ATTRIBUTE_NAME); - this.tokenizer.consume(); - } else if (next === '|') { - // " as|..." - // Following Handlebars and require a space between "as" and the pipe - throw generateSyntaxError( - `Invalid block parameters syntax: expecting at least one space character between "as" and "|"`, - as.start.until(this.offset().move(1)) - ); - } else { - // " as{{...", " async...", " as=...", " as>...", " as/>..." - // Don't consume, let the normal tokenizer code handle the next steps - state = { state: 'Done' }; - } - }, - - BeforeStartPipe: (next: string) => { - localAssert(state.state === 'BeforeStartPipe', 'bug in block params parser'); - - if (isSpace(next)) { - this.tokenizer.consume(); - } else if (next === '|') { - state = { state: 'BeforeBlockParamName' }; - this.tokenizer.transitionTo(BEFORE_ATTRIBUTE_NAME); - this.tokenizer.consume(); - } else { - // " as {{...", " as bs...", " as =...", " as ...", " as/>..." - // Don't consume, let the normal tokenizer code handle the next steps - state = { state: 'Done' }; - } - }, - - BeforeBlockParamName: (next: string) => { - localAssert(state.state === 'BeforeBlockParamName', 'bug in block params parser'); - - if (isSpace(next)) { - this.tokenizer.consume(); - } else if (next === '') { - // The HTML tokenizer ran out of characters, so we are either - // encountering mustache or - state = { state: 'Done' }; - this.pendingError = { - mustache(loc: src.SourceSpan) { - throw generateSyntaxError( - `Invalid block parameters syntax: mustaches cannot be used inside parameters list`, - loc - ); - }, - eof(loc: src.SourceOffset) { - throw generateSyntaxError( - `Invalid block parameters syntax: expecting the tag to be closed with ">" or "/>" after parameters list`, - as.start.until(loc) - ); - }, - }; - } else if (next === '|') { - if (element.params.length === 0) { - // Following Handlebars and treat empty block params a syntax error - throw generateSyntaxError( - `Invalid block parameters syntax: empty parameters list, expecting at least one identifier`, - as.start.until(this.offset().move(1)) - ); - } else { - state = { state: 'AfterEndPipe' }; - this.tokenizer.consume(); - } - } else if (next === '>' || next === '/') { - throw generateSyntaxError( - `Invalid block parameters syntax: incomplete parameters list, expecting "|" but the tag was closed prematurely`, - as.start.until(this.offset().move(1)) - ); - } else { - // slurp up anything else into the name, validate later - state = { - state: 'BlockParamName', - name: next, - start: this.offset(), - }; - this.tokenizer.consume(); - } - }, - - BlockParamName: (next: string) => { - localAssert(state.state === 'BlockParamName', 'bug in block params parser'); - - if (next === '') { - // The HTML tokenizer ran out of characters, so we are either - // encountering mustache or , HBS side will attach the error - // to the next span - state = { state: 'Done' }; - this.pendingError = { - mustache(loc: src.SourceSpan) { - throw generateSyntaxError( - `Invalid block parameters syntax: mustaches cannot be used inside parameters list`, - loc - ); - }, - eof(loc: src.SourceOffset) { - throw generateSyntaxError( - `Invalid block parameters syntax: expecting the tag to be closed with ">" or "/>" after parameters list`, - as.start.until(loc) - ); - }, - }; - } else if (next === '|' || isSpace(next)) { - let loc = state.start.until(this.offset()); - - if (state.name === 'this' || ID_INVERSE_PATTERN.test(state.name)) { - throw generateSyntaxError( - `Invalid block parameters syntax: invalid identifier name \`${state.name}\``, - loc - ); - } - - element.params.push(b.var({ name: state.name, loc })); - - state = next === '|' ? { state: 'AfterEndPipe' } : { state: 'BeforeBlockParamName' }; - this.tokenizer.consume(); - } else if (next === '>' || next === '/') { - throw generateSyntaxError( - `Invalid block parameters syntax: expecting "|" but the tag was closed prematurely`, - as.start.until(this.offset().move(1)) - ); - } else { - // slurp up anything else into the name, validate later - state.name += next; - this.tokenizer.consume(); - } - }, - - AfterEndPipe: (next: string) => { - localAssert(state.state === 'AfterEndPipe', 'bug in block params parser'); - - if (isSpace(next)) { - this.tokenizer.consume(); - } else if (next === '') { - // The HTML tokenizer ran out of characters, so we are either - // encountering mustache or , HBS side will attach the error - // to the next span - state = { state: 'Done' }; - this.pendingError = { - mustache(loc: src.SourceSpan) { - throw generateSyntaxError( - `Invalid block parameters syntax: modifiers cannot follow parameters list`, - loc - ); - }, - eof(loc: src.SourceOffset) { - throw generateSyntaxError( - `Invalid block parameters syntax: expecting the tag to be closed with ">" or "/>" after parameters list`, - as.start.until(loc) - ); - }, - }; - } else if (next === '>' || next === '/') { - // Don't consume, let the normal tokenizer code handle the next steps - state = { state: 'Done' }; - } else { - // Slurp up the next "token" for the error span - state = { - state: 'Error', - message: - 'Invalid block parameters syntax: expecting the tag to be closed with ">" or "/>" after parameters list', - start: this.offset(), - }; - this.tokenizer.consume(); - } - }, - - Error: (next: string) => { - localAssert(state.state === 'Error', 'bug in block params parser'); - - if (next === '' || next === '/' || next === '>' || isSpace(next)) { - throw generateSyntaxError(state.message, state.start.until(this.offset())); - } else { - // Slurp up the next "token" for the error span - this.tokenizer.consume(); - } - }, - - Done: () => { - localAssert(false, 'This should never be called'); - }, - } as const satisfies { - [S in keyof States]: Handler; - }; - - let next: string; - - do { - next = this.tokenizer.peek(); - handlers[state.state](next); - } while (state.state !== 'Done' && next !== ''); - - localAssert(state.state === 'Done', 'bug in block params parser'); - } - - reportSyntaxError(message: string): void { - throw generateSyntaxError(message, this.offset().collapsed()); - } - - assembleConcatenatedValue( - parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[] - ): ASTv1.ConcatStatement { - assertPresentArray(parts, `the concatenation parts of an element should not be empty`); - - let first = getFirst(parts); - let last = getLast(parts); - - return b.concat({ - parts, - loc: this.source.spanFor(first.loc).extend(this.source.spanFor(last.loc)), - }); - } - - validateEndTag( - tag: StartTag | EndTag, - element: ASTv1.ParentNode, - selfClosing: boolean - ): asserts element is ASTv1.ElementNode { - if (voidMap.has(tag.name) && !selfClosing) { - // EngTag is also called by StartTag for void and self-closing tags (i.e. - // or
, so we need to check for that here. Otherwise, we would - // throw an error for those cases. - throw generateSyntaxError( - `<${tag.name}> elements do not need end tags. You should remove it`, - tag.loc - ); - } else if (element.type !== 'ElementNode') { - throw generateSyntaxError(`Closing tag without an open tag`, tag.loc); - } else if (element.tag !== tag.name) { - throw generateSyntaxError( - `Closing tag did not match last open tag <${element.tag}> (on line ${element.loc.startPosition.line})`, - tag.loc - ); - } - } - - assembleAttributeValue( - parts: ASTv1.AttrPart[], - isQuoted: boolean, - isDynamic: boolean, - span: src.SourceSpan - ): ASTv1.AttrValue { - if (isDynamic) { - if (isQuoted) { - return this.assembleConcatenatedValue(parts); - } else { - assertPresentArray(parts); - - const [head, a] = parts; - if (a === undefined || (a.type === 'TextNode' && a.chars === '/')) { - return head; - } else { - throw generateSyntaxError( - `An unquoted attribute value must be a string or a mustache, ` + - `preceded by whitespace or a '=' character, and ` + - `followed by whitespace, a '>' character, or '/>'`, - span - ); - } - } - } else if (isPresentArray(parts)) { - return parts[0]; - } else { - return b.text({ chars: '', loc: span }); - } - } -} +// --------------------------------------------------------------------------- +// Public type exports (preserved from the old tokenizer-event-handlers.ts) +// --------------------------------------------------------------------------- /** ASTPlugins can make changes to the Glimmer template AST before @@ -732,72 +129,753 @@ const syntax: Syntax = { Walker, }; -class CodemodEntityParser extends EntityParser { - // match upstream types, but never match an entity - constructor() { - super({}); - } +// --------------------------------------------------------------------------- +// Rust WASM parser loading +// --------------------------------------------------------------------------- - override parse(): string | undefined { - return undefined; +interface RustWasmParser { + parseTemplateToJson(source: string, srcName?: string): string; +} + +interface RustParseError { + message: string; + loc?: { start: { line: number; column: number }; end: { line: number; column: number } }; + context?: { source_line: string; pointer: string; suggestion?: string }; +} + +interface PlainLocation { + start: { line: number; column: number }; + end: { line: number; column: number }; +} + +let rustParser: RustWasmParser | null = null; +let rustParserLoaded = false; + +// Import the WASM parser JS wrapper statically. +// Rollup resolves this through hiddenDependencies in rollup.config.mjs. +import { parseTemplateToJson as wasmParseTemplateToJson } from '../../pkg/universal.mjs'; + +function loadRustParser(): RustWasmParser | null { + if (rustParserLoaded) return rustParser; + rustParserLoaded = true; + + try { + rustParser = { parseTemplateToJson: wasmParseTemplateToJson }; + } catch { + rustParser = null; } + + return rustParser; } +// --------------------------------------------------------------------------- +// preprocess() — the main public entry point +// --------------------------------------------------------------------------- + +/** + * Parse a Glimmer template using the Rust/WASM parser. + */ export function preprocess( - input: string | src.Source | HBS.Program, + input: string | src.Source, options: PreprocessOptions = {} ): ASTv1.Template { - let mode = options.mode || 'precompile'; + const parser = loadRustParser(); + if (!parser) { + throw new Error( + 'Rust WASM parser not available. Build it first: cd packages/@glimmer/syntax/rust-parser && ./build.sh' + ); + } let source: src.Source; - let ast: HBS.Program; + let sourceStr: string; + if (typeof input === 'string') { source = new src.Source(input, options.meta?.moduleName); + sourceStr = input; + } else if (input instanceof src.Source) { + source = input; + sourceStr = input.source; + } else { + // Legacy: HBS.Program was previously accepted but is no longer supported + throw new Error('preprocess() no longer accepts HBS.Program objects. Pass a string instead.'); + } + + const srcName = options.parseOptions?.srcName ?? options.meta?.moduleName; + + // Parse with the Rust WASM parser + let rawAst: Record; + try { + const jsonStr = parser.parseTemplateToJson(sourceStr, srcName ?? undefined); + rawAst = JSON.parse(jsonStr) as Record; + } catch (error: unknown) { + // Convert Rust parse errors to GlimmerSyntaxError + if (typeof error === 'string') { + let parsed: RustParseError; + try { + parsed = JSON.parse(error) as RustParseError; + } catch { + throw generateSyntaxError( + error, + src.SourceSpan.forCharPositions(source, 0, sourceStr.length) + ); + } + throw convertRustError(parsed, source, sourceStr); + } + throw error; + } + + // Apply whitespace stripping for strip flags (~) before location conversion, + // while text-node chars are still plain strings. Then delete the transient + // __strip field from comments in a second pass. + if (options.mode !== 'codemod') { + applyWhitespaceStripping(rawAst); + } + cleanupStripFlags(rawAst); + + // Convert plain location objects to SourceSpan instances + const template = convertToASTv1(rawAst, source); + + // Set initial blockParams from options.locals + template.blockParams = options.locals ? [...options.locals] : []; + + // Apply AST plugins + if (options.plugins?.ast) { + for (const transform of options.plugins.ast) { + const env: ASTPluginEnvironment = assign({}, options, { syntax }, { plugins: undefined }); + const pluginResult = transform(env); + traverse(template, pluginResult.visitor); + } + } + + // Re-set blockParams after plugins (babel plugin's Proxy) + template.blockParams = options.locals ? [...options.locals] : []; + + return template; +} + +// --------------------------------------------------------------------------- +// AST conversion (JSON → SourceSpan) +// --------------------------------------------------------------------------- + +function convertToASTv1(raw: Record, source: src.Source): ASTv1.Template { + convertLocations(raw, source); + return raw as unknown as ASTv1.Template; +} + +// --------------------------------------------------------------------------- +// Whitespace stripping (strip flags) +// --------------------------------------------------------------------------- +// +// Applies `{{~` and `~}}` strip flags by trimming whitespace from neighboring +// text nodes. Operates on the raw JSON AST before location conversion. + +interface PlainLoc { + start: { line: number; column: number }; + end: { line: number; column: number }; +} + +interface Stripable { + type: string; + chars?: string; + // plain during stripping pass, SourceSpan later — declared unknown + // because both shapes flow through here. + loc?: unknown; + strip?: { open: boolean; close: boolean }; + __strip?: { open: boolean; close: boolean }; + openStrip?: { open: boolean; close: boolean }; + inverseStrip?: { open: boolean; close: boolean }; + closeStrip?: { open: boolean; close: boolean }; + program?: { body: Stripable[] }; + inverse?: { body: Stripable[] } | null; + body?: Stripable[]; + children?: Stripable[]; +} + +function applyWhitespaceStripping(node: unknown): void { + if (node === null || node === undefined || typeof node !== 'object') return; + + const n = node as Stripable; + + // Recurse first so inner bodies are stripped before the outer array pass + if (Array.isArray(n.body)) { + for (const item of n.body) applyWhitespaceStripping(item); + stripBodyWhitespace(n.body); + } + if (n.program?.body) { + for (const item of n.program.body) applyWhitespaceStripping(item); + stripBodyWhitespace(n.program.body); + } + if (n.inverse?.body) { + for (const item of n.inverse.body) applyWhitespaceStripping(item); + stripBodyWhitespace(n.inverse.body); + } + if (Array.isArray(n.children)) { + for (const item of n.children) applyWhitespaceStripping(item); + stripBodyWhitespace(n.children); + } +} + +function cleanupStripFlags(node: unknown): void { + if (node === null || node === undefined || typeof node !== 'object') return; + + if (Array.isArray(node)) { + for (const item of node) cleanupStripFlags(item); + return; + } + + const n = node as Stripable; + if (n.type === 'MustacheCommentStatement' && '__strip' in n) { + delete n.__strip; + } + for (const key of Object.keys(n) as Array) { + const v = n[key]; + if (typeof v === 'object' && v !== null) cleanupStripFlags(v); + } +} + +function stripTextEnd(node: Stripable, pattern: RegExp): void { + if (node.type !== 'TextNode' || typeof node.chars !== 'string') return; + const original = node.chars; + node.chars = original.replace(pattern, ''); + retractEnd(node, original.length - node.chars.length, original); +} + +function stripTextStart(node: Stripable, pattern: RegExp): void { + if (node.type !== 'TextNode' || typeof node.chars !== 'string') return; + const original = node.chars; + node.chars = original.replace(pattern, ''); + advanceStart(node, original.length - node.chars.length, original); +} + +function stripBodyWhitespace(body: Stripable[]): void { + // Pass 1: apply explicit strip flags (~) and BlockStatement inner strips. + for (let i = 0; i < body.length; i++) { + const stmt = body[i]; + if (!stmt) continue; + const leftStrip = getOpenStrip(stmt); + const rightStrip = getCloseStrip(stmt); + + if (leftStrip && i > 0) { + const prev = body[i - 1]; + if (prev) stripTextEnd(prev, /[ \t\r\n]+$/u); + } + if (rightStrip && i + 1 < body.length) { + const next = body[i + 1]; + if (next) stripTextStart(next, /^[ \t\r\n]+/u); + } + + // BlockStatement has additional inner stripping: + // openStrip.close → trim leading ws on program body's first text + // inverseStrip.open → trim trailing ws on program body's last text + // inverseStrip.close → trim leading ws on inverse body's first text + // closeStrip.open → trim trailing ws on inverse (or program) last text + if (stmt.type === 'BlockStatement') { + const program = stmt.program?.body; + const inverse = stmt.inverse?.body; + + if (stmt.openStrip?.close && program && program.length > 0) { + stripFirstTextLeading(program); + } + if (stmt.inverseStrip?.open && program && program.length > 0) { + stripLastTextTrailing(program); + } + if (stmt.inverseStrip?.close && inverse && inverse.length > 0) { + stripFirstTextLeading(inverse); + } + if (stmt.closeStrip?.open) { + if (inverse && inverse.length > 0) { + stripLastTextTrailing(inverse); + } else if (program && program.length > 0) { + stripLastTextTrailing(program); + } + } + } + } + + // Pass 2: standalone stripping. If a block/comment is alone on its line + // (only whitespace before it back to a newline and only whitespace after + // it forward to a newline), strip that whitespace including the newlines. + applyStandaloneStripping(body); + + // Drop any text nodes that are now empty after stripping. + for (let i = body.length - 1; i >= 0; i--) { + const stmt = body[i]; + if (stmt?.type === 'TextNode' && stmt.chars === '') { + body.splice(i, 1); + } + } +} + +function isStandaloneCandidate(stmt: Stripable | undefined): boolean { + if (!stmt) return false; + // BlockStatement gets standalone treatment on its open and close tags + // independently; MustacheCommentStatement too. MustacheStatement does + // NOT get standalone stripping in the legacy parser. + return stmt.type === 'BlockStatement' || stmt.type === 'MustacheCommentStatement'; +} + +function applyStandaloneStripping(body: Stripable[]): void { + for (let i = 0; i < body.length; i++) { + const stmt = body[i]; + if (!isStandaloneCandidate(stmt)) continue; + + const prev = body[i - 1]; + const next = body[i + 1]; + + // For a block to be standalone: + // 1. The text before it (back to the previous newline or start) must + // be whitespace only. + // 2. The text after it (forward to the next newline or end) must be + // whitespace only. + // 3. At least one side must contain a real newline (otherwise it's + // just inline whitespace around the block). + const prevOk = isEmptyOrWhitespaceToNewline(prev, 'backward'); + const nextOk = isEmptyOrWhitespaceToNewline(next, 'forward'); + const hasNewline = containsNewline(prev) || containsNewline(next); + + if (prevOk && nextOk && hasNewline) { + // Strip trailing inline whitespace on prev (leave the preceding + // newline intact so body boundary text nodes don't vanish). + if (prev) stripTextEnd(prev, /[ \t]+$/u); + // Strip leading whitespace + the trailing newline from next. + if (next) stripTextStart(next, /^[ \t]*(?:\r\n|\r|\n)/u); + + // If this is a standalone BlockStatement, also strip the leading + // newline from its program body's first text (consumed by the block + // open tag) and the trailing inline whitespace from its program or + // inverse body's last text (consumed by the block close tag). + if (stmt?.type === 'BlockStatement') { + const program = stmt.program?.body; + const inverse = stmt.inverse?.body; + + if (program && program.length > 0) { + const first = program[0]; + if (first) stripTextStart(first, /^[ \t]*(?:\r\n|\r|\n)/u); + } + const trailingBody = (inverse && inverse.length > 0 ? inverse : program) || []; + if (trailingBody.length > 0) { + const last = trailingBody[trailingBody.length - 1]; + if (last) stripTextEnd(last, /[ \t]+$/u); + } + } + } + } +} + +function containsNewline(node: Stripable | undefined): boolean { + if (!node || node.type !== 'TextNode') return false; + return /[\r\n]/u.test(node.chars ?? ''); +} + +// Check that `node` exists and (going backward from its end or forward from +// its start) has only whitespace until the next newline, or reaches the +// start/end of the body. +function isEmptyOrWhitespaceToNewline( + node: Stripable | undefined, + direction: 'backward' | 'forward' +): boolean { + if (!node) return true; // body boundary + if (node.type !== 'TextNode') return false; + const chars = node.chars ?? ''; + if (direction === 'backward') { + // The tail (from last newline to end) must be only whitespace. + const lastNewline = Math.max(chars.lastIndexOf('\n'), chars.lastIndexOf('\r')); + const tail = lastNewline === -1 ? chars : chars.slice(lastNewline + 1); + return /^[ \t]*$/u.test(tail); + } else { + // The head (up to first newline) must be only whitespace. + const match = chars.match(/^[ \t]*(?:\r\n|\r|\n|$)/u); + return match !== null; + } +} + +function stripFirstTextLeading(body: Stripable[]): void { + const first = body[0]; + if (first?.type === 'TextNode' && typeof first.chars === 'string') { + const original = first.chars; + first.chars = original.replace(/^[ \t\r\n]+/u, ''); + advanceStart(first, original.length - first.chars.length, original); + } +} + +function stripLastTextTrailing(body: Stripable[]): void { + const last = body[body.length - 1]; + if (last?.type === 'TextNode' && typeof last.chars === 'string') { + const original = last.chars; + last.chars = original.replace(/[ \t\r\n]+$/u, ''); + retractEnd(last, original.length - last.chars.length, original); + } +} - if (mode === 'codemod') { - ast = parseWithoutProcessing(input, options.parseOptions) as HBS.Program; +// Move a TextNode's loc.start forward by `n` characters (across newlines). +function advanceStart(node: Stripable, n: number, original: string): void { + if (n <= 0) return; + const loc = node.loc as PlainLoc | undefined; + if (!loc || !isPlainLocObj(loc)) return; + let { line, column } = loc.start; + for (let i = 0; i < n; i++) { + const ch = original[i]; + if (ch === '\n') { + line++; + column = 0; + } else if (ch === '\r') { + // treat \r and \r\n as single newline; peek next + if (original[i + 1] === '\n') continue; + line++; + column = 0; } else { - ast = parse(input, options.parseOptions) as HBS.Program; + column++; } - } else if (input instanceof src.Source) { - source = input; + } + loc.start = { line, column }; +} - if (mode === 'codemod') { - ast = parseWithoutProcessing(input.source, options.parseOptions) as HBS.Program; +// Move a TextNode's loc.end backward by `n` characters (across newlines). +function retractEnd(node: Stripable, n: number, original: string): void { + if (n <= 0) return; + const loc = node.loc as PlainLoc | undefined; + if (!loc || !isPlainLocObj(loc)) return; + let { line, column } = loc.end; + for (let i = 0; i < n; i++) { + const ch = original[original.length - 1 - i]; + if (ch === '\n') { + // '\r\n' treated as one — peek ahead (toward start) for '\r' + if (original[original.length - 2 - i] === '\r') { + i++; + } + line--; + // Recompute column: find the length of the line we're now on by + // scanning backward to previous newline. + let col = 0; + for (let j = original.length - 2 - i; j >= 0; j--) { + if (original[j] === '\n' || original[j] === '\r') break; + col++; + } + column = col; + } else if (ch === '\r') { + line--; + let col = 0; + for (let j = original.length - 2 - i; j >= 0; j--) { + if (original[j] === '\n' || original[j] === '\r') break; + col++; + } + column = col; } else { - ast = parse(input.source, options.parseOptions) as HBS.Program; + column = Math.max(0, column - 1); } - } else { - source = new src.Source('', options.meta?.moduleName); - ast = input; + } + loc.end = { line, column }; +} + +function isPlainLocObj(value: unknown): value is PlainLoc { + return ( + value !== null && + typeof value === 'object' && + 'start' in value && + 'end' in value && + // Real SourceSpan has methods; plain objects don't. + typeof (value as { until?: unknown }).until !== 'function' + ); +} + +function getOpenStrip(stmt: Stripable): boolean { + if (stmt.type === 'MustacheStatement') return Boolean(stmt.strip?.open); + if (stmt.type === 'MustacheCommentStatement') return Boolean(stmt.__strip?.open); + if (stmt.type === 'BlockStatement') return Boolean(stmt.openStrip?.open); + return false; +} + +function getCloseStrip(stmt: Stripable): boolean { + if (stmt.type === 'MustacheStatement') return Boolean(stmt.strip?.close); + if (stmt.type === 'MustacheCommentStatement') return Boolean(stmt.__strip?.close); + if (stmt.type === 'BlockStatement') return Boolean(stmt.closeStrip?.close); + return false; +} + +function convertLocations(node: unknown, source: src.Source): void { + if (node === null || node === undefined || typeof node !== 'object') return; + + if (Array.isArray(node)) { + for (const item of node) { + convertLocations(item, source); + } + return; + } + + const obj = node as Record; + + // Convert 'loc' property + if (isPlainLocation(obj['loc'])) { + const { start, end } = obj['loc']; + obj['loc'] = src.SourceSpan.forCharPositions( + source, + charPosToOffset(source.source, start.line, start.column), + charPosToOffset(source.source, end.line, end.column) + ); + } + + // Convert 'openTag' and 'closeTag' properties + for (const key of ['openTag', 'closeTag'] as const) { + if (isPlainLocation(obj[key])) { + const { start, end } = obj[key]; + obj[key] = src.SourceSpan.forCharPositions( + source, + charPosToOffset(source.source, start.line, start.column), + charPosToOffset(source.source, end.line, end.column) + ); + } + } + + // Add deprecated `parts` as a non-enumerable getter on PathExpression nodes + // so live code still works but deepEqual comparisons against the reference + // builder (which also uses defineProperty) match. + if (obj['type'] === 'PathExpression' && !Object.getOwnPropertyDescriptor(obj, 'parts')) { + Object.defineProperty(obj, 'parts', { + enumerable: false, + configurable: true, + get(this: { original: string }): readonly string[] { + const segs = this.original.split('.'); + if (segs[0] === 'this') { + segs.shift(); + } else if (segs[0]?.startsWith('@')) { + segs[0] = segs[0].slice(1); + } + return Object.freeze(segs); + }, + }); + } + + // Add deprecated `escaped` as a non-enumerable getter on MustacheStatement nodes + if (obj['type'] === 'MustacheStatement' && !Object.getOwnPropertyDescriptor(obj, 'escaped')) { + Object.defineProperty(obj, 'escaped', { + enumerable: false, + configurable: true, + get(this: { trusting: boolean }): boolean { + return !this.trusting; + }, + }); + } + + // Add deprecated `original` as a non-enumerable getter on literal nodes + // (matches the reference builder's defineProperty pattern). + if ( + (obj['type'] === 'StringLiteral' || + obj['type'] === 'NumberLiteral' || + obj['type'] === 'BooleanLiteral' || + obj['type'] === 'NullLiteral' || + obj['type'] === 'UndefinedLiteral') && + !Object.getOwnPropertyDescriptor(obj, 'original') + ) { + Object.defineProperty(obj, 'original', { + enumerable: false, + configurable: true, + get(this: { value: unknown }): unknown { + return this.value; + }, + }); } - let entityParser = undefined; - if (mode === 'codemod') { - entityParser = new CodemodEntityParser(); + // UndefinedLiteral needs a real `value: undefined` property (the reference + // builder creates it this way). We can't emit undefined from JSON so we + // assign it here. + if (obj['type'] === 'UndefinedLiteral' && !('value' in obj)) { + obj['value'] = undefined; } - let offsets = src.SourceSpan.forCharPositions(source, 0, source.source.length); - ast.loc = { - source: '(program)', - start: offsets.startPosition, - end: offsets.endPosition, - }; + // Decode HTML entities in text node content (precompile mode only). + // The old parser used simple-html-tokenizer's EntityParser; we inline + // a minimal decoder here to avoid re-adding that dependency. + if (obj['type'] === 'TextNode' && typeof obj['chars'] === 'string') { + obj['chars'] = decodeEntities(obj['chars']); + } - let template = new TokenizerEventHandlers(source, entityParser, mode).parse( - ast, - options.locals ?? [] + // Recurse into all object properties + for (const key of Object.keys(obj)) { + if (key === 'loc' || key === 'openTag' || key === 'closeTag') continue; + const val = obj[key]; + if (typeof val === 'object' && val !== null) { + convertLocations(val, source); + } + } +} + +function isPlainLocation(value: unknown): value is PlainLocation { + return ( + value !== null && + typeof value === 'object' && + 'start' in value && + 'end' in value && + !(value instanceof src.SourceSpan) ); +} - if (options.plugins?.ast) { - for (const transform of options.plugins.ast) { - let env: ASTPluginEnvironment = assign({}, options, { syntax }, { plugins: undefined }); +// Minimal HTML entity decoder. Handles named entities commonly used +// in Glimmer templates plus numeric references ({ and «). +const NAMED_ENTITIES: Record = { + amp: '&', + lt: '<', + gt: '>', + quot: '"', + apos: "'", + nbsp: '\u00a0', + copy: '\u00a9', + reg: '\u00ae', + trade: '\u2122', + hellip: '\u2026', + mdash: '\u2014', + ndash: '\u2013', + lsquo: '\u2018', + rsquo: '\u2019', + ldquo: '\u201c', + rdquo: '\u201d', + laquo: '\u00ab', + raquo: '\u00bb', + middot: '\u00b7', + bull: '\u2022', + deg: '\u00b0', + plusmn: '\u00b1', + times: '\u00d7', + divide: '\u00f7', + euro: '\u20ac', + pound: '\u00a3', + yen: '\u00a5', + cent: '\u00a2', + sect: '\u00a7', + para: '\u00b6', + check: '\u2713', + cross: '\u2717', +}; - let pluginResult = transform(env); +function decodeEntities(input: string): string { + if (!input.includes('&')) return input; + return input.replace(/&(#x[0-9a-f]+|#[0-9]+|[a-z][a-z0-9]*);/giu, (match, body: string) => { + if (body.startsWith('#x') || body.startsWith('#X')) { + const code = parseInt(body.slice(2), 16); + if (Number.isFinite(code)) return String.fromCodePoint(code); + } else if (body.startsWith('#')) { + const code = parseInt(body.slice(1), 10); + if (Number.isFinite(code)) return String.fromCodePoint(code); + } else { + const decoded = NAMED_ENTITIES[body]; + if (decoded !== undefined) return decoded; + } + return match; + }); +} - traverse(template, pluginResult.visitor); +function charPosToOffset(source: string, line: number, column: number): number { + let currentLine = 1; + let currentCol = 0; + + for (let i = 0; i < source.length; i++) { + if (currentLine === line && currentCol === column) { + return i; + } + if (source[i] === '\n') { + currentLine++; + currentCol = 0; + } else { + currentCol++; } } - return template; + if (currentLine === line && currentCol === column) { + return source.length; + } + + return source.length; +} + +// --------------------------------------------------------------------------- +// Error conversion +// --------------------------------------------------------------------------- + +function convertRustError(error: RustParseError, source: src.Source, sourceStr: string): Error { + const { loc } = error; + + // Try to upgrade generic parse errors to more specific messages by + // looking at the source around the error location. Matches common + // patterns that the legacy parser detected semantically. + const specific = detectSpecificError(sourceStr, loc); + if (specific) { + const offset = loc ? charPosToOffset(sourceStr, loc.start.line, loc.start.column) : 0; + const span = src.SourceSpan.forCharPositions(source, offset, offset + (specific.length ?? 0)); + return generateSyntaxError(specific.message, span); + } + + const { message, context } = error; + let fullMessage = message || 'Parse error'; + + if (context) { + fullMessage += '\n\n'; + if (loc) { + const lineNum = loc.start.line; + const lineStr = String(lineNum); + fullMessage += ` ${lineStr} | ${context.source_line}\n`; + fullMessage += ` ${' '.repeat(lineStr.length)} | ${context.pointer}\n`; + } + if (context.suggestion) { + fullMessage += `\n Hint: ${context.suggestion}\n`; + } + } + + const offset = loc ? charPosToOffset(sourceStr, loc.start.line, loc.start.column) : 0; + const span = src.SourceSpan.forCharPositions(source, offset, offset); + + return generateSyntaxError(fullMessage, span); +} + +// Void HTML tag names — matches grammar's VoidTagName +const VOID_TAG_NAMES = new Set([ + 'area', + 'base', + 'br', + 'col', + 'command', + 'embed', + 'hr', + 'img', + 'input', + 'keygen', + 'link', + 'meta', + 'param', + 'source', + 'track', + 'wbr', +]); + +interface SpecificError { + message: string; + length?: number; +} + +function detectSpecificError(sourceStr: string, loc: RustParseError['loc']): SpecificError | null { + if (!loc) return null; + + const offset = charPosToOffset(sourceStr, loc.start.line, loc.start.column); + const around = sourceStr.slice(Math.max(0, offset - 30), offset + 30); + + // Void element with explicit close tag: `` + // The parser reaches the `/` character (just after `<`) because + // VoidElement consumed ``. Walk back one char to see ``. + const closeStart = sourceStr[offset - 1] === '<' ? offset - 1 : offset; + const closeMatch = /^<\/([a-z][a-z0-9-]*)>/u.exec(sourceStr.slice(closeStart)); + if (closeMatch && closeMatch[1]) { + const tagName = closeMatch[1]; + if (VOID_TAG_NAMES.has(tagName.toLowerCase())) { + return { + message: `<${tagName}> elements do not need end tags. You should remove it`, + }; + } + } + + // Unclosed element with a weird tag name: `<{@name>` → legacy parser + // reports the inner name as the tag. + const weirdTag = /<\{(@?[a-zA-Z][a-zA-Z0-9_-]*)/u.exec(around); + if (weirdTag) { + return { message: `Unclosed element \`${weirdTag[1]}\`` }; + } + + return null; } diff --git a/packages/@glimmer/syntax/lib/utils.ts b/packages/@glimmer/syntax/lib/utils.ts index ec6f6ed06b5..a65e35457bf 100644 --- a/packages/@glimmer/syntax/lib/utils.ts +++ b/packages/@glimmer/syntax/lib/utils.ts @@ -1,5 +1,4 @@ import type * as ASTv1 from './v1/api'; -import type * as HBS from './v1/handlebars-ast'; export function childrenFor( node: ASTv1.Block | ASTv1.Template | ASTv1.ElementNode @@ -20,11 +19,7 @@ export function appendChild( childrenFor(parent).push(node); } -export function isHBSLiteral(path: HBS.Expression): path is HBS.Literal; -export function isHBSLiteral(path: ASTv1.Expression): path is ASTv1.Literal; -export function isHBSLiteral( - path: HBS.Expression | ASTv1.Expression -): path is HBS.Literal | ASTv1.Literal { +export function isLiteral(path: ASTv1.Expression): path is ASTv1.Literal { return ( path.type === 'StringLiteral' || path.type === 'BooleanLiteral' || @@ -34,6 +29,9 @@ export function isHBSLiteral( ); } +/** @deprecated use isLiteral instead */ +export const isHBSLiteral = isLiteral; + export function printLiteral(literal: ASTv1.Literal): string { if (literal.type === 'UndefinedLiteral') { return 'undefined'; diff --git a/packages/@glimmer/syntax/lib/v1/handlebars-ast.ts b/packages/@glimmer/syntax/lib/v1/handlebars-ast.ts deleted file mode 100644 index de607ed0ea7..00000000000 --- a/packages/@glimmer/syntax/lib/v1/handlebars-ast.ts +++ /dev/null @@ -1,217 +0,0 @@ -/** - * This file contains types for the raw AST returned from the Handlebars parser. - * These types were originally imported from - * https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/handlebars/index.d.ts. - */ - -import type * as ASTv1 from './api'; - -export interface CommonNode { - loc: SourceLocation; -} - -export interface NodeMap { - Program: { input: Program; output: ASTv1.Block }; - MustacheStatement: { input: MustacheStatement; output: ASTv1.MustacheStatement | void }; - Decorator: { input: Decorator; output: never }; - BlockStatement: { input: BlockStatement; output: ASTv1.BlockStatement | void }; - DecoratorBlock: { input: DecoratorBlock; output: never }; - PartialStatement: { input: PartialStatement; output: never }; - PartialBlockStatement: { input: PartialBlockStatement; output: never }; - ContentStatement: { input: ContentStatement; output: void }; - CommentStatement: { input: CommentStatement; output: ASTv1.MustacheCommentStatement | null }; - SubExpression: { input: SubExpression; output: ASTv1.SubExpression }; - PathExpression: { input: PathExpression; output: ASTv1.PathExpression }; - StringLiteral: { input: StringLiteral; output: ASTv1.StringLiteral }; - BooleanLiteral: { input: BooleanLiteral; output: ASTv1.BooleanLiteral }; - NumberLiteral: { input: NumberLiteral; output: ASTv1.NumberLiteral }; - UndefinedLiteral: { input: UndefinedLiteral; output: ASTv1.UndefinedLiteral }; - NullLiteral: { input: NullLiteral; output: ASTv1.NullLiteral }; -} - -/** - * `loc` is sometimes missing in the upstream Handlebars parser. This is a bug that should be - * fixed. In addition, we should use the types from the upstream parser rather than our own types, - * and if they're not accurate, we should fix them upstream. - * - * @see {https://github.com/handlebars-lang/handlebars-parser/blob/master/types/ast.d.ts} - */ -export interface UpstreamProgram extends Omit { - loc?: SourceLocation; -} - -export interface UpstreamBlockStatement extends Omit { - program: UpstreamProgram; - inverse?: UpstreamProgram; -} - -export interface UpstreamNodeMap extends Omit { - Program: { input: UpstreamProgram; output: ASTv1.Block }; -} - -export type NodeType = keyof NodeMap; -export type Node = NodeMap[T]['input']; - -export type UpstreamNodeType = keyof UpstreamNodeMap; -export type UpstreamNode = - UpstreamNodeMap[T]['input']; - -export type Output = NodeMap[T]['output']; - -export interface SourceLocation { - source: string; - start: Position; - end: Position; -} - -export interface Position { - line: number; - column: number; -} - -export interface Program extends CommonNode { - type: 'Program'; - body: Statement[]; - blockParams?: string[]; - chained?: boolean; -} - -export type Statement = - | MustacheStatement - | BlockStatement - | DecoratorBlock - | PartialStatement - | PartialBlockStatement - | ContentStatement - | CommentStatement; - -export interface CommonMustache extends CommonNode { - path: Expression; - params: Expression[]; - hash: Hash; - escaped: boolean; - strip: StripFlags; -} - -export interface MustacheStatement extends CommonMustache { - type: 'MustacheStatement'; -} - -export interface Decorator extends CommonMustache { - type: 'DecoratorStatement'; -} - -export interface CommonBlock extends CommonNode { - chained: boolean; - path: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; - program: Program; - inverse?: Program; - openStrip?: StripFlags; - inverseStrip?: StripFlags; - closeStrip?: StripFlags; -} - -export interface BlockStatement extends CommonBlock { - type: 'BlockStatement'; -} - -export interface DecoratorBlock extends CommonBlock { - type: 'DecoratorBlock'; -} - -export interface PartialStatement extends CommonNode { - type: 'PartialStatement'; - name: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; - indent: string; - strip: StripFlags; -} - -export interface PartialBlockStatement extends CommonNode { - type: 'PartialBlockStatement'; - name: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; - program: Program; - openStrip: StripFlags; - closeStrip: StripFlags; -} - -export interface ContentStatement extends CommonNode { - type: 'ContentStatement'; - value: string; - original: StripFlags; -} - -export interface CommentStatement extends CommonNode { - type: 'CommentStatement'; - value: string; - strip: StripFlags; -} - -export type Expression = SubExpression | PathExpression | Literal; - -export interface SubExpression extends CommonNode { - type: 'SubExpression'; - path: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; -} - -export interface PathExpression extends CommonNode { - type: 'PathExpression'; - data: boolean; - depth: number; - parts: string[]; - original: string; -} - -export type Literal = - | StringLiteral - | BooleanLiteral - | NumberLiteral - | UndefinedLiteral - | NullLiteral; - -export interface StringLiteral extends CommonNode { - type: 'StringLiteral'; - value: string; - original: string; -} - -export interface BooleanLiteral extends CommonNode { - type: 'BooleanLiteral'; - value: boolean; - original: boolean; -} - -export interface NumberLiteral extends CommonNode { - type: 'NumberLiteral'; - value: number; - original: number; -} - -export interface UndefinedLiteral extends CommonNode { - type: 'UndefinedLiteral'; -} - -export interface NullLiteral extends CommonNode { - type: 'NullLiteral'; -} - -export interface Hash extends CommonNode { - pairs: HashPair[]; -} - -export interface HashPair extends CommonNode { - key: string; - value: Expression; -} - -export interface StripFlags { - open: boolean; - close: boolean; -} diff --git a/packages/@glimmer/syntax/package.json b/packages/@glimmer/syntax/package.json index 886a9b99963..e8b2e52266e 100644 --- a/packages/@glimmer/syntax/package.json +++ b/packages/@glimmer/syntax/package.json @@ -8,6 +8,7 @@ "directory": "packages/@glimmer/syntax" }, "type": "module", + "sideEffects": false, "exports": "./index.ts", "repo-meta": { "supportcjs": true @@ -29,14 +30,13 @@ "dist" ], "scripts": { - "test:publint": "publint" + "test:publint": "publint", + "build:rust-parser": "./build.sh" }, "dependencies": { "@glimmer/interfaces": "workspace:*", "@glimmer/util": "workspace:*", - "@glimmer/wire-format": "workspace:*", - "@handlebars/parser": "workspace:*", - "simple-html-tokenizer": "^0.5.11" + "@glimmer/wire-format": "workspace:*" }, "devDependencies": { "@glimmer/debug-util": "workspace:*", diff --git a/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.d.ts b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.d.ts new file mode 100644 index 00000000000..6d9995a75af --- /dev/null +++ b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.d.ts @@ -0,0 +1,44 @@ +/* tslint:disable */ +/* eslint-disable */ + +/** + * Parse a Glimmer/Handlebars template string and return an ASTv1 Template as a JSON string. + * + * The JS side parses the JSON into a plain object then decorates it with + * SourceSpans, non-enumerable getters, etc. This avoids a wasm-bindgen + * serde bridge and keeps the wasm binary smaller. + */ +export function parseTemplateToJson(source: string, src_name?: string | null): string; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly parseTemplateToJson: (a: number, b: number, c: number, d: number, e: number) => void; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; + readonly __wbindgen_export: (a: number, b: number) => number; + readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_export3: (a: number, b: number, c: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; + +/** + * Instantiates the given `module`, which can either be bytes or + * a precompiled `WebAssembly.Module`. + * + * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. + * + * @returns {InitOutput} + */ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** + * If `module_or_path` is {RequestInfo} or {URL}, makes a request and + * for everything else, calls `WebAssembly.instantiate` directly. + * + * @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. + * + * @returns {Promise} + */ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.js b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.js new file mode 100644 index 00000000000..5f65efb426b --- /dev/null +++ b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser.js @@ -0,0 +1,265 @@ +/* @ts-self-types="./glimmer_template_parser.d.ts" */ + +/** + * Parse a Glimmer/Handlebars template string and return an ASTv1 Template as a JSON string. + * + * The JS side parses the JSON into a plain object then decorates it with + * SourceSpans, non-enumerable getters, etc. This avoids a wasm-bindgen + * serde bridge and keeps the wasm binary smaller. + * @param {string} source + * @param {string | null} [src_name] + * @returns {string} + */ +export function parseTemplateToJson(source, src_name) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(source, wasm.__wbindgen_export, wasm.__wbindgen_export2); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(src_name) ? 0 : passStringToWasm0(src_name, wasm.__wbindgen_export, wasm.__wbindgen_export2); + var len1 = WASM_VECTOR_LEN; + wasm.parseTemplateToJson(retptr, ptr0, len0, ptr1, len1); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export3(deferred4_0, deferred4_1, 1); + } +} +function __wbg_get_imports() { + const import0 = { + __proto__: null, + __wbindgen_cast_0000000000000001: function(arg0, arg1) { + // Cast intrinsic for `Ref(String) -> Externref`. + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }, + }; + return { + __proto__: null, + "./glimmer_template_parser_bg.js": import0, + }; +} + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function dropObject(idx) { + if (idx < 1028) return; + heap[idx] = heap_next; + heap_next = idx; +} + +let cachedDataViewMemory0 = null; +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return decodeText(ptr, len); +} + +let cachedUint8ArrayMemory0 = null; +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getObject(idx) { return heap[idx]; } + +let heap = new Array(1024).fill(undefined); +heap.push(undefined, null, true, false); + +let heap_next = heap.length; + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = cachedTextEncoder.encodeInto(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); +cachedTextDecoder.decode(); +const MAX_SAFARI_DECODE_BYTES = 2146435072; +let numBytesDecoded = 0; +function decodeText(ptr, len) { + numBytesDecoded += len; + if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) { + cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + cachedTextDecoder.decode(); + numBytesDecoded = len; + } + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +const cachedTextEncoder = new TextEncoder(); + +if (!('encodeInto' in cachedTextEncoder)) { + cachedTextEncoder.encodeInto = function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; + }; +} + +let WASM_VECTOR_LEN = 0; + +let wasmModule, wasm; +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + wasmModule = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + return wasm; +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + } catch (e) { + const validResponse = module.ok && expectedResponseType(module.type); + + if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { throw e; } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + } else { + return instance; + } + } + + function expectedResponseType(type) { + switch (type) { + case 'basic': case 'cors': case 'default': return true; + } + return false; + } +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (module !== undefined) { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + const instance = new WebAssembly.Instance(module, imports); + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (module_or_path !== undefined) { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (module_or_path === undefined) { + module_or_path = new URL('glimmer_template_parser_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync, __wbg_init as default }; diff --git a/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser_bg.wasm b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser_bg.wasm new file mode 100644 index 00000000000..020662144a7 Binary files /dev/null and b/packages/@glimmer/syntax/pkg/standalone/glimmer_template_parser_bg.wasm differ diff --git a/packages/@glimmer/syntax/pkg/universal.mjs b/packages/@glimmer/syntax/pkg/universal.mjs new file mode 100644 index 00000000000..8e50b46327d --- /dev/null +++ b/packages/@glimmer/syntax/pkg/universal.mjs @@ -0,0 +1,35 @@ +// Universal WASM wrapper — works in both Node.js and browsers. +// +// Lazy-initialized on first call so rollup can tree-shake the WASM bytes +// when a consumer never calls parseTemplateToJson. + +import { + initSync, + parseTemplateToJson as rawParseTemplateToJson, +} from './standalone/glimmer_template_parser.js'; +import { WASM_BYTES_BASE64 } from './wasm-bytes.mjs'; + +let initialized = false; + +function ensureInit() { + if (initialized) return; + initialized = true; + initSync({ module: base64ToUint8Array(WASM_BYTES_BASE64) }); +} + +function base64ToUint8Array(base64) { + if (typeof Buffer !== 'undefined') { + return new Uint8Array(Buffer.from(base64, 'base64')); + } + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes; +} + +export function parseTemplateToJson(source, srcName) { + ensureInit(); + return rawParseTemplateToJson(source, srcName); +} diff --git a/packages/@glimmer/syntax/pkg/wasm-bytes.mjs b/packages/@glimmer/syntax/pkg/wasm-bytes.mjs new file mode 100644 index 00000000000..ba237cffcf5 --- /dev/null +++ b/packages/@glimmer/syntax/pkg/wasm-bytes.mjs @@ -0,0 +1 @@ +export const WASM_BYTES_BASE64 = "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IQECQCACKALYAkEBcQ0AIAJB0AJqIAEQ2wIgAigC1AIhASACKALQAkEBcQ0AIAJBoANqIQYDQCACQcgCaiABENsCIAIoAswCIQECQCACKALIAkEBcQRAQQEhAwwBCyAGIAFBiAFqKAIANgIAIAIgASkCgAE3A5gDIAEoAhQhByACQcACaiABEMcBIAIoAsQCIQEgAigCwAIiA0EBcUUNACABIAIpA5gDNwKAASABQYgBaiAGKAIANgIAIAcgASgCFEsNACABIAc2AhQLIANBAXFFDQALCyACQbgCaiABEFAgAigCvAIhASACKAK4AiEDDAELIAEgAikD8AM3AoABIAFBiAFqIAcoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsCQCADQQFxBEBBASEDDAELIAJBsAJqIAEQ2wJBASEDIAIoArQCIQEgAigCsAJBAXENACACQfgDaiIHIAFBiAFqKAIANgIAIAIgASkCgAE3A/ADIAEoAhQhBiACQagCaiABENsCIAIoAqwCIQEgAigCqAJBAXFFBEAgAkGgAmogARDHAUEAIQMgAigCpAIhASACKAKgAkEBcQ0BIAJBmAJqIAEQ2wIgAigCnAIhASACKAKYAkEBcQ0BIAJBoANqIQYDQCACQZACaiABENsCIAIoApQCIQECQCACKAKQAkEBcQRAQQEhBwwBCyAGIAFBiAFqKAIANgIAIAIgASkCgAE3A5gDIAEoAhQhCSACQYgCaiABEMcBIAIoAowCIQEgAigCiAIiB0EBcUUNACABIAIpA5gDNwKAASABQYgBaiAGKAIANgIAIAkgASgCFEsNACABIAk2AhQLIAdBAXFFDQALDAELIAEgAikD8AM3AoABIAFBiAFqIAcoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgA0EBcUUNACABIAIpA+ADNwKAASABQYgBaiACQegDaigCADYCACAFIAEoAhRLDQAgASAFNgIUCwJAIANBAXENACACQYACaiABENsCIAIoAoQCIQEgAigCgAJBAXENACACQcgDaiIEIAFBiAFqKAIANgIAIAIgASkCgAE3A8ADIAEoAhQhBSACQfgBaiABENsCQQEhAyACKAL8ASEBIAIoAvgBQQFxRQRAIAJB8AFqIAEQ2wIgAigC9AEhAQJAIAIoAvABQQFxDQAgAkHoA2ogAUGIAWooAgA2AgAgAiABKQKAATcD4AMgASgCFCEFIAJB6AFqIAEQ2wJBASEEIAIoAuwBIQECQCACKALoAUEBcQ0AIAJB+ANqIAFBiAFqKAIANgIAIAIgASkCgAE3A/ADIAEoAhQhAyACQeABaiABENsCIAIoAuQBIQEgAigC4AFBAXFFBEAgAkHYAWogARDHASACKALcASEBAkAgAigC2AFBAXENACACQdABaiABENsCIAIoAtQBIQEgAigC0AFBAXENACACQaADaiEDA0AgAkHIAWogARDbAiACKALMASEBAkAgAigCyAFBAXEEQEEBIQQMAQsgAyABQYgBaigCADYCACACIAEpAoABNwOYAyABKAIUIQYgAkHAAWogARDHASACKALEASEBIAIoAsABIgRBAXFFDQAgASACKQOYAzcCgAEgAUGIAWogAygCADYCACAGIAEoAhRLDQAgASAGNgIUCyAEQQFxRQ0ACwsgAkG4AWogARBQIAIoArwBIQEgAigCuAEhBAwBCyABIAIpA/ADNwKAASABQYgBaiACQfgDaigCADYCACADIAEoAhRLDQAgASADNgIUCwJAIARBAXEEQEEBIQMMAQsgAkGwAWogARDbAkEBIQMgAigCtAEhASACKAKwAUEBcQ0AIAJB+ANqIgYgAUGIAWooAgA2AgAgAiABKQKAATcD8AMgASgCFCEEIAJBqAFqIAEQ2wIgAigCrAEhASACKAKoAUEBcUUEQCACQaABaiABEMcBQQAhAyACKAKkASEBIAIoAqABQQFxDQEgAkGYAWogARDbAiACKAKcASEBIAIoApgBQQFxDQEgAkGgA2ohBgNAIAJBkAFqIAEQ2wIgAigClAEhAQJAIAIoApABQQFxBEBBASEEDAELIAYgAUGIAWooAgA2AgAgAiABKQKAATcDmAMgASgCFCEHIAJBiAFqIAEQxwEgAigCjAEhASACKAKIASIEQQFxRQ0AIAEgAikDmAM3AoABIAFBiAFqIAYoAgA2AgAgByABKAIUSw0AIAEgBzYCFAsgBEEBcUUNAAsMAQsgASACKQPwAzcCgAEgAUGIAWogBigCADYCACAEIAEoAhRLDQAgASAENgIUCyADQQFxRQ0AIAEgAikD4AM3AoABIAFBiAFqIAJB6ANqKAIANgIAIAUgASgCFEsNACABIAU2AhQLQQAhBCADQQFx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kA1qIAFBCGopAgA3AwAgBCABKQIANwOIDQsCQAJAAkACQAJAIARBiA1qEOkCQf8BcUE3aw4DAQIDAAsgBCAEQYgNahDpAjoAoAIgBEEHNgJkIAQgBEGgAmo2AmBB04bAACAEQeAAakH4pcAAEMsCAAsgBEGwBWohBSMAQfAGayIBJAAgAUEANgIYIAFCgICAgBA3AhAgASAEQbgHaiIJKAIMIgY2AiggASAJKAIIIgc2AiQgASAJKAIEIgg2AiAgASAJKAIAIgo2AhwgAUEANgI0IAFCgICAgIABNwIsIAFBADYCQCABQoCAgICAATcCOCABQQA2AkwgAUKAgICAwAA3AkQgAUEANgJYIAFCgICAgMAANwJQIAFBADYCZCABQoCAgICAATcCXCABIAY2ArgBIAEgBzYCtAEgASAINgKwASABIAo2AqwBIAFB6ABqIARBiA1qEPkCIAFB8ANqIQogAUGABGohDANAAkAgAUGEAWoiCCABQegAahDaAQJAAkACQCABKAKEAQRAIAFBqAFqIgYgAUGUAWooAgA2AgAgAUGgAWoiByABQYwBaikCADcDACABIAEpAoQBNwOYASAIEOkCQf8BcUE7aw4CAwIBCyABQegAahCtAyAFQRRqIAEoAhQgAUEYaiICKAIAIAFBHGoQgwEgBUGAAWogAUE0aigCADYCACAFIAEpAiw3AnggBUGEAWogASgCVCABQdgAaiIDKAIAIAkQxQIgBUGYAWogAUFAaygCADYCACAFIAEpAjg3ApABIAUgASkCRDcCnAEgBUGkAWogAUHMAGooAgA2AgAgBSABKQJcNwKoASAFQbABaiABQeQAaigCADYCACAFIAEpAxA3ArQBIAVBvAFqIAIoAgA2AgAgBUHIAWogAygCADYCACAFIAEpA1A3AsABIAVBADoA9AEgBUELNgLQASAFQc2cwAA2AswBIAUgDTYCACAFIAEpAqwBNwLUASAFQdwBaiABQbQBaikCADcCACAFIAEpAqgENwIEIAVBDGogAUGwBGopAgA3AgAgBSAJKQIANwLkASAFQewBaiAJQQhqKQIANwIAIAFB8AZqJAAMAwsgAUHAAmogBigCADYCACABQbgCaiAHKQMANwMAIAEgASkDmAE3A7ACIAFBuARqIgYgAUGwAmogAiADEAMgASgCuARBDUYNAyABQdwA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HGogAiADIAcQlQIMBwsgAUGYAWogAiADIAFBgAFqEJUCIBBBjYHAAEENEJsCIAogASkCmAEiEjcCACAKQQhqIAFBoAFqKQIAIhM3AgAgAUEINgLkAiABQYacwAA2AuACIAFBCDYCvAEgAUGhnMAANgK4ASABQgE3A7ABIAFCBzcDqAEgASATNwPIASABIBI3A8ABIAFBLGogAUGoAWoQvwIMBgsgAUGYA2ogBygCADYCACABQZADaiAIKQMANwMAIAEgASkDgAE3A4gDIAFBqAFqIgcgAUGIA2ogAiADEDIgAUE4aiAHEMACDAcLIAFBmANqIAcoAgA2AgAgAUGQA2ogCCkDADcDACABIAEpA4ABNwOIAyABQagBaiIHIAFBiANqIAIgAxANIAFBLGogBxC/AgwGCyABQZgDaiAHKAIANgIAIAFBkANqIAgpAwA3AwAgASABKQOAATcDiAMgAUGoAWoiByABQYgDaiACIAMQlQEgAUEsaiAHEL8CDAULIBFBAkYNASABQZgDaiAHKAIANgIAIAFBkANqIAgpAwA3AwAgASABKQOAATcDiAMgAUGoAWoiByABQYgDaiACIAMQfCABQcQAaiAHEMECDAQLIAFB0ABqEK0DIAVBFGogASgCFCABQRhqIgIoAgAgAUEcahCDASAFIAlBAXE6APQBIAVBCzYC0AEgBUHNnMAANgLMASAFQYABaiABQTRqKAIANgIAIAUgASkCLDcCeCAFIAEpAjg3ApABIAVBmAFqIAFBQGsoAgA2AgAgBSABKQJENwKcASAFQaQBaiABQcwAaigCADYCACAFIAEpAxA3ArQBIAVBvAFqIAIoAgA2AgAgBSAMNgLgASAFIA02AtwBIAUgDjYC2AEgBSAPNgLUASAFQQA2ArABIAVCgICAgIABNwKoASAFQQA2AowBIAVCgICAgMAANwKEASAFQQA2AgAgBUEANgLIASAFQoCAgIDAADcCwAEgBSAGKQIANwLkASAFQewBaiAGQQhqKQIANwIAIAFBoANqJAAMAgsgC0E6Rw0AIAEgAUGAAWoQmQIgASABKQMANwKoASABQagBakGIqMAAEJwDIAlyIQkLIAFBgAFqEK0DDAELCwsgAEELNgIAIABBBGogBEGwBWpB+AH8CgAACyAEQbANaiQADwtB6KXAABC/AwAL8RkBEn8jAEHQA2siAiQAIAJBGDoAzwIgAkHAAmogARDbAiACKALEAiEBAn9BASACKALAAkEBcQ0AGiABKAKIASIJIAEoAowBIgRGBEAgASgCLCEPIAEoAiAhCwsgASgCFCEMAkAgAS0AkAFBAkcNACABLQCRAUUNACACIAk2AuACIAJBADYC3AIgAkEAOgDYAiABQQxqIAJB2AJqEJMCIAEoAowBIQQLIAQgCUYEQCABKAIsIAEoAiBqIQ0LIAIgASgCXDYC0AIgAiABKAJ4NgLUAiACQbgCaiABENsCQQEhBCACKAK8AiEBAkAgAigCuAJBAXENACACQfgCaiABQYgBaigCADYCACACIAEpAoABNwPwAiABKAIUIRAgAkGwAmogAUGagcAAQQEQ0gEgAigCtAIhAQJ/AkAgAigCsAJBAXENACACQagCaiABENsCIAIoAqwCIQEgAigCqAJBAXENACACQcgDaiIEIAFBiAFqKAIANgIAIAIgASkCgAE3A8ADIAEoAhQhAyACQaACaiABENsCIAIoAqQCIQEgAigCoAJBAXFFBEAgAkGYAmogARDHASACKAKcAiEBAkAgAigCmAJBAXENACACQZACaiABENsCIAIoApQCIQEgAigCkAJBAXENACACQeACaiEDA0AgAkGIAmogARDbAiACKAKMAiEBAkAgAigCiAJBAXEEQEEBIQQMAQsgAyABQYgBaigCADYCACACIAEpAoABNwPYAiABKAIUIQUgAkGAAmogARDHASACKAKEAiEBIAIoAoACIgRBAXFFDQAgASACKQPYAjcCgAEgAUGIAWogAygCADYCACAFIAEoAhRLDQAgASAFNgIUCyAEQQFxRQ0ACwsgAkH4AWogARDnASACKAL8ASEBIAIoAvgBDAILIAEgAikDwAM3AoABIAFBiAFqIAQoAgA2AgAgAyABKAIUSw0AIAEgAzYCFAtBAQshA0EBIQQCQCADQQFxDQAgAkHwAWogARDbAiACKAL0ASEBIAIoAvABQQFxDQAgAkGIA2oiBSABQYgBaigCADYCACACIAEpAoABNwOAAyABKAIUIQMgAkHoAWogARDbAiACKALsASEBIAIoAugBQQFxRQRAIAJB4AFqIAEQ2wIgAigC5AEhAQJAIAIoAuABQQFxBEBBASEDDAELIAJBqANqIAFBiAFqKAIANgIAIAIgASkCgAE3A6ADIAEoAhQhBSACQdgBaiABENsCIAIoAtwBIQECQCACKALYAUEBcQRAQQEhAwwBCyACQbgDaiABQYgBaigCADYCACACIAEpAoABNwOwAyABKAIUIQogAkHQAWogARDHASACKALUASEBAkAgAigC0AFBAXEEQEEBIQMMAQsgAkHIAWogARDbAkEBIQMgAigCzAEhASACKALIAUEBcQ0AIAJByANqIgggAUGIAWooAgA2AgAgAiABKQKAATcDwAMgASgCFCEGIAJBwAFqIAEQ2wIgAigCxAEhASACKALAAUEBcUUEQCACQbgBaiABEMcBQQAhAyACKAK8ASEBIAIoArgBQQFxDQEgAkGwAWogARDbAiACKAK0ASEBIAIoArABQQFxDQEgAkHgAmohBgNAIAJBqAFqIAEQ2wIgAigCrAEhAQJAIAIoAqgBQQFxBEBBASEIDAELIAYgAUGIAWooAgA2AgAgAiABKQKAATcD2AIgASgCFCEHIAJBoAFqIAEQxwEgAigCpAEhASACKAKgASIIQQFxRQ0AIAEgAikD2AI3AoABIAFBiAFqIAYoAgA2AgAgByABKAIUSw0AIAEgBzYCFAsgCEEBcUUNAAsMAQsgASACKQPAAzcCgAEgAUGIAWogCCgCADYCACAGIAEoAhRLDQAgASAGNgIUCyADQQFxRQ0AIAEgAikDsAM3AoABIAFBiAFqIAJBuANqKAIANgIAIAogASgCFEsNACABIAo2AhQLIANBAXEEf0EBBSACQZgBaiABEIoCIAIoApwBIQEgAigCmAELIgNBAXFFDQAgASACKQOgAzcCgAEgAUGIAWogAkGoA2ooAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsCQCADQQFxDQAgAkGQAWogARDbAiACKAKUASEBIAIoApABQQFxDQAgAkGYA2ohBQNAIAJBiAFqIAEQ2wIgAigCjAEhAQJAIAIoAogBQQFxBEBBASEDDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDkAMgASgCFCEKIAJBgAFqIAEQ2wIgAigChAEhAQJAIAIoAoABQQFxBEBBASEDDAELIAJBqANqIhEgAUGIAWooAgA2AgAgAiABKQKAATcDoAMgASgCFCEGIAJB+ABqIAEQ2wJBASEDIAIoAnwhAQJAIAIoAnhBAXENACACQbgDaiIS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QQEgAigCgAJBAXENABogASgCiAEiByABKAKMASIDRgRAIAEoAiwhCyABKAIgIQgLIAEoAhQhCQJAIAEtAJABQQJHDQAgAS0AkQFFDQAgAiAHNgKgAiACQQA2ApwCIAJBADoAmAIgAUEMaiACQZgCahCTAiABKAKMASEDCyADIAdGBEAgASgCLCABKAIgaiEKCyACIAEoAlw2ApACIAIgASgCeDYClAIgAkH4AWogARDbAkEBIQMgAigC/AEhAQJAIAIoAvgBQQFxDQAgAkG4AmogAUGIAWooAgA2AgAgAiABKQKAATcDsAIgASgCFCEMIAJB8AFqIAFBpYDAAEECENIBIAIoAvQBIQECfwJAIAIoAvABQQFxDQAgAkHoAWogARDbAiACKALsASEBIAIoAugBQQFxDQAgAkHgAWogARA6IAJB2AFqIAIoAuQBENsCIAIoAtwBIQEgAigC2AFBAXENACACQdgCaiIEIAFBiAFqKAIANgIAIAIgASkCgAE3A9ACIAEoAhQhAyACQdABaiABENsCIAIoAtQBIQEgAigC0AFBAXFFBEAgAkHIAWogARDHASACKALMASEBAkAgAigCyAFBAXENACACQcABaiABENsCIAIoAsQBIQEgAigCwAFBAXENACACQaACaiEEA0AgAkG4AWogARDbAiACKAK8ASEBAkAgAigCuAFBAXEEQEEBIQMMAQsgBCABQYgBaigCADYCACACIAEpAoABNwOYAiABKAIUIQUgAkGwAWogARDHASACKAK0ASEBIAIoArABIgNBAXFFDQAgASACKQOYAjcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkGoAWogAUGJgcAAQQQQ0gEgAigCrAEhASACKAKoAQwCCyABIAIpA9ACNwKAASABQYgBaiAEKAIANgIAIAMgASgCFEsNACABIAM2AhQLQQELIQRBASEDAn8CQCAEQQFxRQRAIAJBoAFqIAEQ2wIgAigCpAEhAQJAIAIoAqABQQFxDQAgAkHIAmogAUGIAWooAgA2AgAgAiABKQKAATcDwAIgASgCFCEFIAJBmAFqIAEQxwEgAigCnAEhAQJAIAIoApgBQQFxBEAMAQsgAkGQAWogARDbAiACKAKUASEBIAIoApABQQFxDQAgAkHYAmoiBiAB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AkHAAWogARDbAiACKALEASEBIAIoAsABQQFxRQRAIAJBuAFqIAEQxwEgAigCvAEhAQJAIAIoArgBQQFxDQAgAkGwAWogARDbAiACKAK0ASEBIAIoArABQQFxDQAgAkGQAmohBANAIAJBqAFqIAEQ2wIgAigCrAEhAQJAIAIoAqgBQQFxBEBBASEDDAELIAQgAUGIAWooAgA2AgAgAiABKQKAATcDiAIgASgCFCEFIAJBoAFqIAEQxwEgAigCpAEhASACKAKgASIDQQFxRQ0AIAEgAikDiAI3AoABIAFBiAFqIAQoAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsgA0EBcUUNAAsLIAJBmAFqIAFByIHAAEEBENIBIAIoApwBIQEgAigCmAEMAgsgASACKQOwAjcCgAEgAUGIAWogBCgCADYCACADIAEoAhRLDQAgASADNgIUC0EBCyEDQQEhBAJAIANBAXENACACQZABaiABENsCIAIoApQBIQEgAigCkAFBAXENACACQbgCaiIFIAFBiAFqKAIANgIAIAIgASkCgAE3A7ACIAEoAhQhAyACQYgBaiABENsCIAIoAowBIQEgAigCiAFBAXFFBEAgAkGAAWogARDHASACKAKEASEBAkAgAigCgAFBAXENACACQfgAaiABENsCIAIoAnwhASACKAJ4QQFxDQAgAkGQAmohBANAIAJB8ABqIAEQ2wIgAigCdCEBAkAgAigCcEEBcQRAQQEhAwwBCyAEIAFBiAFqKAIANgIAIAIgASkCgAE3A4gCIAEoAhQhBSACQegAaiABEMcBIAIoAmwhASACKAJoIgNBAXFFDQAgASACKQOIAjcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkHgAGogARAHIAIoAmQhASACKAJgIQQMAQsgASACKQOwAjcCgAEgAUGIAWogBSgCADYCACADIAEoAhRLDQAgASADNgIUC0EBIQMCQCAEQQFxDQAgAkHYAGogARDbAiACKAJcIQEgAigCWEEBcQ0AIAJB0ABqIAEQDCACQcgAaiACKAJUENsCIAIoAkwhASACKAJIQQFxDQAgAkG4AmoiBSABQYgBaigCADYCACACIAEpAoABNwOwAiABKAIUIQQgAkFAayABENsCIAIoAkQhASACKAJAQQFxRQRAIAJBOGogARDHASACKAI8IQECQCACKAI4QQFxDQAgAkEwaiABENsCIAIoAjQhASACKAIwQQFxDQAgAkGQAmohBQNAIAJBKGogARDbAiACKAIsIQECQCACKAIoQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDiAIgASgCFCEMIAJBIGogARDHASACKAIkIQEgAigCICIEQQFxRQ0AIAEgAikDiAI3AoABIAFBiAFqIAUoAgA2AgAgDCABKAIUSw0AIAEgDDYCFAsgBEEBcUUNAAsLIAJBGGogARDbAiACKAIcIQEgAigCGEEBcQ0BIAJBEGogARA8IAJBCGogAigCFEGngMAAQQIQ0gEgAigCDCEBIAIoAgghAwwBCyABIAIpA7ACNwKAASABQYgBaiAFKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIANBAXFFDQAgASACKQOgAjcCgAEgAUGIAWogAkGoAmooAgA2AgAgCyABKAIUSw0AIAEgCzYCFAsgAiACQf8BajYCuAIgAiACQYACajYCtAIgAiACQYQCajYCsAICQAJAAkACQAJAIANBAXEEQCACIAE2AogCIAEtAJABQQFGDQUgAUEOIAYgByAKIAkQvQEgAS0AfA0BDAQLIAIgATYCoAIgAS0AkAEiA0EBRgR/IAFBDiAGIAcgCiAJEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIEIAgQ9wIiBi0AAEEBRg0BIAYgAzYCBCABKAKIASEDIAIgCDYCjAIgAiADNgKYAiACQQA2ApACIAIgAi0A/wE6AIkCIAJBAToAiAIgBCACQYgCahCTAgwCCyACQbACaiACQYgCahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQbACaiACQaACahC5AgtBAAwCCyABLQCQAUECRw0AIAEtAJEBRQ0AIAggASgCFEsNACABIAg2AhQLQQELIQMgACABNgIEIAAgAzYCACACQcACaiQAC58QAQt/IwBBsAJrIgIkACACQQ86AO8BIAJB4AFqIAEQ2wIgAigC5AEhAQJ/QQEgAigC4AFBAXENABogASgCiAEiBiABKAKMASIDRgRAIAEoAiwhCiABKAIgIQcLIAEoAhQhCAJAIAEtAJABQQJHDQAgAS0AkQFFDQAgAiAGNgKAAiACQQA2AvwBIAJBADoA+AEgAUEMaiACQfgBahCTAiABKAKMASEDCyADIAZGBEAgASgCLCABKAIgaiEJCyACIAEoAlw2AvABIAIgASgCeDYC9AEgAkHYAWogARDbAkEBIQMgAigC3AEhAQJAIAIoAtgBQQFxDQAgAkGYAmogAUGIAWooAgA2AgAgAiABKQKAATcDkAIgASgCFCELIAJB0AFqIAFBpYDAAEECENIBIAIoAtQBIQECfwJAIAIoAtABQQFxDQAgAkHIAWogARDbAiACKALMASEBIAIoAsgBQQFxDQAgAkHAAWogARA6IAJBuAFqIAIoAsQBENsCIAIoArwBIQEgAigCuAFBAXENACACQagCaiIEIAFBiAFqKAIANgIAIAIgASkCgAE3A6ACIAEoAhQhAyACQbABaiABENsCIAIoArQBIQEgAigCsAFBAXFFBEAgAkGoAWogARDHASACKAKsASEBAkAgAigCqAFBAXENACACQaABaiABENsCIAIoAqQBIQEgAigCoAFBAXENACACQYACaiEEA0AgAkGYAWogARDbAiACKAKcASEBAkAgAigCmAFBAXEEQEEBIQMMAQsgBCABQYgBaigCADYCACACIAEpAoABNwP4ASABKAIUIQUgAkGQAWogARDHASACKAKUASEBIAIoApABIgNBAXFFDQAgASACKQP4ATcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkGIAWogAUGpgMAAQQEQ0gEgAigCjAEhASACKAKIAQwCCyABIAIpA6ACNwKAASABQYgBaiAEKAIANgIAIAMgASgCFEsNACABIAM2AhQLQQELIQNBASEEAkAgA0EBcQ0AIAJBgAFqIAEQ2wIgAigChAEhASACKAKAAUEBcQ0AIAJBqAJqIgUgAUGIAWooAgA2AgAgAiABKQKAATcDoAIgASgCFCEDIAJB+ABqIAEQ2wIgAigCfCEBIAIoAnhBAXFFBEAgAkHwAGogARDHASACKAJ0IQECQCACKAJwQQFxDQAgAkHoAGogARDbAiACKAJsIQEgAigCaEEBcQ0AIAJBgAJqIQQDQCACQeAAaiABENsCIAIoAmQhAQJAIAIoAmBBAXEEQEEBIQMMAQsgBCABQYgBaigCADYCACACIAEpAoABNwP4ASABKAIUIQUgAkHYAGogARDHASACKAJcIQEgAigCWCIDQQFxRQ0AIAEgAikD+AE3AoABIAFBiAFqIAQoAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsgA0EBcUUNAAsLIAJB0ABqIAEQOyACKAJUIQEgAigCUCEEDAELIAEgAikDoAI3AoABIAFBiAFqIAUoAgA2AgAgAyABKAIUSw0AIAEgAzYCFAtBASEDAkAgBEEBcQ0AIAJByABqIAEQ2wIgAigCTCEBIAIoAkhBAXENACACQagCaiIFIAFBiAFqKAIANgIAIAIgASkCgAE3A6ACIAEoAhQhBCACQUBrIAEQ2wIgAigCRCEBIAIoAkBBAXFFBEAgAkE4aiABEMcBIAIoAjwhAQJAIAIoAjhBAXENACACQTBqIAEQ2wIgAigCNCEBIAIoAjBBAXENACACQYACaiEFA0AgAkEoaiABENsCIAIoAiwhAQJAIAIoAihBAXEEQEEBIQQMAQsgBSABQYgBaigCADYCACACIAEpAoABNwP4ASABKAIUIQwgAkEgaiABEMcBIAIoAiQhASACKAIgIgRBAXFFDQAgASACKQP4ATcCgAEgAUGIAWogBSgCADYCACAMIAEoAhRLDQAgASAMNgIUCyAEQQFxRQ0ACwsgAkEYaiABENsCIAIoAhwhASACKAIYQQFxDQEgAkEQaiABEDwgAkEIaiACKAIUQaeAwABBAhDSASACKAIMIQEgAigCCCEDDAELIAEgAikDoAI3AoABIAFBiAFqIAUoAgA2AgAgBCABKAIUSw0AIAEgBDYCFAsgA0EBcUUNACABIAIpA5ACNwKAASABQYgBaiACQZgCaigCADYCACALIAEoAhRLDQAgASALNgIUCyACIAJB7wFqNgKoAiACIAJB8AFqNgKkAiACIAJB9AFqNgKgAgJAAkACQAJAAkAgA0EBcQRAIAIgATYC+AEgAS0AkAFBAUYNBSABQQ8gBiAHIAogCRC9ASABLQB8DQEMBAsgAiABNgKQAiABLQCQASIDQQFGBH8gAUEPIAYgByAKIAkQvQEgAS0AkAEFIAMLQf8BcUECRw0CIAEtAJEBRQ0CIAEoAhQhAyABQQxqIgQgCBD3AiIGLQAAQQFGDQEgBiADNgIEIAEoAogBIQMgAiAINgL8ASACIAM2AogCIAJBADYCgAIgAiACLQDvAToA+QEgAkEBOgD4ASAEIAJB+AFqEJMCDAILIAJBoAJqIAJB+AFqELkCDAILQdCtwABBKEH4rcAAEJ0DAAsgAS0AfARAIAJBoAJqIAJBkAJqELkCC0EADAILIAEtAJABQQJHDQAgAS0AkQFFDQAgCCABKAIUSw0AIAEgCDYCFAtBAQshAyAAIAE2AgQgACADNgIAIAJBsAJqJAALsw8BDH8jAEGQAmsiAiQAIAJBMzoAvwEgAkGwAWogARDbAiACKAK0ASEBAn9BASACKAKwAUEBcQ0AGiABKAKIASIGIAEoAowBIgNGBEAgASgCLCEMIAEoAiAhCQsgASgCFCEKAkAgAS0AkAFBAkcNACABLQCRAUUNACACIAY2AtABIAJBADYCzAEgAkEAOgDIASABQQxqIAJByAFqEJMCIAEoAowBIQMLIAMgBkYEQCABKAIsIAEoAiBqIQsLIAIgASgCXDYCwAEgAiABKAJ4NgLEASACQagBaiABENsCQQEhAyACKAKsASEBAkAgAigCqAFBAXEEQAwBCyACQegBaiABQYgBaigCADYCACACIAEpAoABNwPgASABKAIUIQ0gAkGgAWogARDbAiACKAKkASEBAkAgAigCoAFBAXENACACQfgBaiABQYgBaigCADYCACACIAEpAoABNwPwASABKAIUIQcgAkGYAWogARDHASACKAKcASEBAkAgAigCmAFBAXEEQAwBCyACQZABaiABENsCIAIoApQBIQEgAigCkAFBAXENACACQYgCaiIFIAFBiAFqKAIANgIAIAIgASkCgAE3A4ACIAEoAhQhBCACQYgBaiABENsCIAIoAowBIQEgAigCiAFBAXFFBEAgAkGAAWogARDHAUEAIQMgAigChAEhASACKAKAAUEBcQ0BIAJB+ABqIAEQ2wIgAigCfCEBIAIoAnhBAXENASACQdABaiEFA0AgAkHwAGogARDbAiACKAJ0IQECQCACKAJwQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDyAEgASgCFCEIIAJB6ABqIAEQxwEgAigCbCEBIAIoAmgiBEEBcUUNACABIAIpA8gBNwKAASABQYgBaiAFKAIANgIAIAggASgCFEsNACABIAg2AhQLIARBAXFFDQALDAELIAEgAikDgAI3AoAB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FAsgA0EBcUUNAAsLIAJByABqIAFBiYHAAEEEENIBIAIoAkwhASACKAJIDAILIAEgAikD4AE3AoABIAFBiAFqIAQoAgA2AgAgAyABKAIUSw0AIAEgAzYCFAtBAQshBEEBIQMCQCAEQQFxDQAgAkFAayABENsCIAIoAkQhASACKAJAQQFxDQAgAkHoAWoiBSABQYgBaigCADYCACACIAEpAoABNwPgASABKAIUIQQgAkE4aiABENsCIAIoAjwhASACKAI4QQFxRQRAIAJBMGogARDHASACKAI0IQECQCACKAIwQQFxDQAgAkEoaiABENsCIAIoAiwhASACKAIoQQFxDQAgAkHAAWohBQNAIAJBIGogARDbAiACKAIkIQECQCACKAIgQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDuAEgASgCFCEMIAJBGGogARDHASACKAIcIQEgAigCGCIEQQFxRQ0AIAEgAikDuAE3AoABIAFBiAFqIAUoAgA2AgAgDCABKAIUSw0AIAEgDDYCFAsgBEEBcUUNAAsLIAJBEGogARDbAiACKAIUIQEgAigCEEEBcQ0BIAJBCGogARA8IAIgAigCDEGngMAAQQIQ0gEgAigCBCEBIAIoAgAhAwwBCyABIAIpA+ABNwKAASABQYgBaiAFKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIANBAXFFDQAgASACKQPQATcCgAEgAUGIAWogAkHYAWooAgA2AgAgCyABKAIUSw0AIAEgCzYCFAsgAiACQa8BajYC6AEgAiACQbABajYC5AEgAiACQbQBajYC4AECQAJAAkACQAJAIANBAXEEQCACIAE2ArgBIAEtAJABQQFGDQUgAUETIAYgByAKIAkQvQEgAS0AfA0BDAQLIAIgATYC0AEgAS0AkAEiA0EBRgR/IAFBEyAGIAcgCiAJEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIEIAgQ9wIiBi0AAEEBRg0BIAYgAzYCBCABKAKIASEDIAIgCDYCvAEgAiADNgLIASACQQA2AsABIAIgAi0ArwE6ALkBIAJBAToAuAEgBCACQbgBahCTAgwCCyACQeABaiACQbgBahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQeAB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BiABKAKMASIDRgRAIAEoAiwhCiABKAIgIQcLIAEoAhQhCAJAIAEtAJABQQJHDQAgAS0AkQFFDQAgAiAGNgLAASACQQA2ArwBIAJBADoAuAEgAUEMaiACQbgBahCTAiABKAKMASEDCyADIAZGBEAgASgCLCABKAIgaiEJCyACIAEoAlw2ArABIAIgASgCeDYCtAEgAkGYAWogARDbAkEBIQMgAigCnAEhAQJAIAIoApgBQQFxDQAgAkHYAWogAUGIAWooAgA2AgAgAiABKQKAATcD0AEgASgCFCELIAJBkAFqIAFBpYDAAEECENIBIAIoApQBIQECfwJAIAIoApABQQFxDQAgAkGIAWogARDbAiACKAKMASEBIAIoAogBQQFxDQAgAkGAAWogARA6IAJB+ABqIAIoAoQBENsCIAIoAnwhASACKAJ4QQFxDQAgAkHoAWoiBCABQYgBaigCADYCACACIAEpAoABNwPgASABKAIUIQMgAkHwAGogARDbAiACKAJ0IQEgAigCcEEBcUUEQCACQegAaiABEMcBIAIoAmwhAQJAIAIoAmhBAXENACACQeAAaiABENsCIAIoAmQhASACKAJgQQFxDQAgAkHAAWohBANAIAJB2ABqIAEQ2wIgAigCXCEBAkAgAigCWEEBcQRAQQEhAwwBCyAEIAFBiAFqKAIANgIAIAIgASkCgAE3A7gBIAEoAhQhBSACQdAAaiABEMcBIAIoAlQhASACKAJQIgNBAXFFDQAgASACKQO4ATcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkHIAGogARAIIAIoAkwhASACKAJIDAILIAEgAikD4AE3AoABIAFBiAFqIAQoAgA2AgAgAyABKAIUSw0AIAEgAzYCFAtBAQshBEEBIQMCQCAEQQFxDQAgAkFAayABENsCIAIoAkQhASACKAJAQQFxDQAgAkHoAWoiBSABQYgBaigCADYCACACIAEpAoABNwPgASABKAIUIQQgAkE4aiABENsCIAIoAjwhASACKAI4QQFxRQRAIAJBMGogARDHASACKAI0IQECQCACKAIwQQFxDQAgAkEoaiABENsCIAIoAiwhASACKAIoQQFxDQAgAkHAAWohBQNAIAJBIGogARDbAiACKAIkIQECQCACKAIgQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDuAEgASgCFCEMIAJBGGogARDHASACKAIcIQEgAigCGCIEQQFxRQ0AIAEgAikDuAE3AoABIAFBiAFqIAUoAgA2AgAgDCABKAIUSw0AIAEgDDYCFAsgBEEBcUUNAAsLIAJBEGogARDbAiACKAIUIQEgAigCEEEBcQ0BIAJBCGogARA8IAIgAigCDEGngMAAQQIQ0gEgAigCBCEBIAIoAgAhAwwBCyABIAIpA+ABNwKAASABQYgBaiAFKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIANBAXFFDQAgASACKQPQATcCgAEgAUGIAWogAkHYAWooAgA2AgAgCyABKAIUSw0AIAEgCzYCFAsgAiACQa8BajYC6AEgAiACQbABajYC5AEgAiACQbQBajYC4AECQAJAAkACQAJAIANBAXEEQCACIAE2ArgBIAEtAJABQQFGDQUgAUEHIAYgByAKIAkQvQEgAS0AfA0BDAQLIAIgATYC0AEgAS0AkAEiA0EBRgR/IAFBByAGIAcgCiAJEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIEIAgQ9wIiBi0AAEEBRg0BIAYgAzYCBCABKAKIASEDIAIgCDYCvAEgAiADNgLIASACQQA2AsABIAIgAi0ArwE6ALkBIAJBAToAuAEgBCACQbgBahCTAgwCCyACQeABaiACQbgBahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQeABaiACQdABahC5AgtBAAwCCyABLQCQAUECRw0AIAEtAJEBRQ0AIAggASgCFEsNACABIAg2AhQLQQELIQMgACABNgIEIAAgAzYCACACQfABaiQACxIAIAAgAUE7QQFBgoHAABDkAwsSACAAIAFBOEECQbCBwAAQ5AMLgQwBC38jAEHQAWsiAiQAIAJBOToAjwEgAkGAAWogARDbAiACKAKEASEBAn9BASACKAKAAUEBcQ0AGiABKAKIASIGIAEoAowBIgNGBEAgASgCLCEKIAEoAiAhBwsgASgCFCEIAkAgAS0AkAFBAkcNACABLQCRAUUNACACIAY2AqABIAJBADYCnAEgAkEAOgCYASABQQxqIAJBmAFqEJMCIAEoAowBIQMLIAMgBkYEQCABKAIsIAEoAiBqIQkLIAIgASgCXDYCkAEgAiABKAJ4NgKUASACQfgAaiABENsCQQEhAyACKAJ8IQECQCACKAJ4QQFxDQAgAkG4AWogAUGIAWooAgA2AgAgAiABKQKAATcDsAEgASgCFCELIAJB8ABqIAFBvYDAAEEBENIBIAIoAnQhAQJAIAIoAnBBAXEEf0EBBSACQegAaiABEEYgAigCbCEBIAIoAmgLQQFxDQAgAkHgAGogARDbAiACKAJkIQEgAigCYEEBcQ0AIAJByAFqIgUgAUGIAWooAgA2AgAgAiABKQKAATcDwAEgASgCFCEEIAJB2ABqIAEQ2wIgAigCXCEBIAIoAlhBAXFFBEAgAkHQAGogARAtIAIoAlQhAQJAIAIoAlBBAXENACACQcgAaiABENsCIAIoAkwhASACKAJIQQFxDQAgAkGgAWohBQNAIAJBQGsgARDbAiACKAJEIQECQCACKAJAQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDmAEgASgCFCEMIAJBOGogARAtIAIoAjwhASACKAI4IgRBAXFFDQAgASACKQOYATcCgAEgAUGIAWogBSgCADYCACAMIAEoAhRLDQAgASAMNgIUCyAEQQFxRQ0ACwsgAkEwaiABENsCIAIoAjQhASACKAIwQQFxDQEgAkHIAWoiBSABQYgBaigCADYCACACIAEpAoABNwPAASABKAIUIQQgAkEoaiABENsCIAIoAiwhASACKAIoQQFxRQRAIAJBIGogARDHASACKAIkIQECQCACKAIgQQFxDQAgAkEYaiABENsCIAIoAhwhASACKAIYQQFxDQAgAkGgAWohBANAIAJBEGogARDbAiACKAIUIQECQCACKAIQQQFxBEBBASEDDAELIAQgAUGIAWooAgA2AgAgAiABKQKAATcDmAEgASgCFCEFIAJBCGogARDHASACKAIMIQEgAigCCCIDQQFxRQ0AIAEgAikDmAE3AoABIAFBiAFqIAQoAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsgA0EBcUUNAAsLIAIgARBHIAIoAgQhASACKAIAIQMMAgsgASACKQPAATcCgAEgAUGIAWogBSgCADYCACAEIAEoAhRLDQEgASAENgIUDAELIAEgAikDwAE3AoABIAFBiAFqIAUoAgA2AgAgBCAB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AUEMaiIHIAgQ9wIiBi0AAEEBRg0BIAYgAzYCBCABKAKIASEDIAIgCDYCnAEgAiADNgKoASACQQA2AqABIAIgAi0AjwE6AJkBIAJBAToAmAEgByACQZgBahCTAgwCCyACQcABaiACQZgBahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQcABaiACQbABahC5AgtBAAwCCyABLQCQAUECRw0AIAEtAJEBRQ0AIAggASgCFEsNACABIAg2AhQLQQELIQMgACABNgIEIAAgAzYCACACQdABaiQAC5AMAQp/IwBB0AFrIgIkACACQS46AI8BIAJBgAFqIAEQ2wIgAigChAEhAQJ/QQEgAigCgAFBAXENABogASgCiAEiByABKAKMASIDRgRAIAEoAiwhCiABKAIgIQYLIAEoAhQhCAJAIAEtAJABQQJHDQAgAS0AkQFFDQAgAiAHNgKgASACQQA2ApwBIAJBADoAmAEgAUEMaiACQZgBahCTAiABKAKMASEDCyADIAdGBEAgASgCLCABKAIgaiEJCyACIAEoAlw2ApABIAIgASgCeDYClAEgAkH4AGogARDbAkEBIQMgAigCfCEBAkAgAigCeEEBcQ0AIAJBuAFqIAFBiAFqKAIANgIAIAIgASkCgAE3A7ABIAEoAhQhCyACQfAAaiABEF8gAigCdCEBAn8CQCACKAJwQQFxDQAgAkHoAGogARDbAiACKAJsIQEgAigCaEEBcQ0AIAJByAFqIgQgAUGIAWooAgA2AgAgAiABKQKAATcDwAEgASgCFCEDIAJB4ABqIAEQ2wIgAigCZCEBIAIoAmBBAXFFBEAgAkHYAGogARDHASACKAJcIQECQCACKAJYQQFxDQAgAkHQAGogARDbAiACKAJUIQEgAigCUEEBcQ0AIAJBoAFqIQQDQCACQcgAaiABENsCIAIoAkwhAQJAIAIoAkhBAXEEQEEBIQMMAQsgBCABQYgBaigCADYCACACIAEpAoABNwOYASABKAIUIQUgAkFAayABEMcBIAIoAkQhASACKAJAIgNBAXFFDQAgASACKQOYATcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkE4aiABQYOBwABBARDSASACKAI8IQEgAigCOAwCCyABIAIpA8ABNwKAASAB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LQAARg0ACyAOIQkMBQsgCSAEQaixwQAQngIACyABIAZBmLHBABCeAgALIAEgAmogBE8NASABIAVqLQAAIAEgDWotAABGBEAgCUEBayEJIAFBAWohAQwBCwtBACAJayECDAILIAQgAiAKaiIAIAAgBEkbIARBiLHBABCeAgALIAIgCWohAgwACwALIAcgAUEoaiADIAQgBSAGEMMBIAcoAgQhAiAHKAIAIQgMBQsgByAJNgIsIAcgAjYCKCAGDQELQQAhAgwDCyAGIA5rIQlBASABKAIQIgtrIQ8gASkDCCERQQAhCEEAIQICQAJAAkADQCACIAZqIARLDQMCQCAHQShqELUCRQRAIAggCyAIIAtLGyEKDAELIAdBIGogAiADIARBuLHBABDoAiAHQRhqIAdBKGogBygCICAHKAIkEOoBIAcoAhhBAXFFDQRBACEIIAshCiAHKAIcIAJqIgIgBmogBEsNBwsgBCACIBBqIgFNBEAgASAEQcixwQAQngIACwJAIBEgASADajEAAIhCAYNQRQRAIAogBiAGIApJGyEMIAIgA2ohDSAKIQECQAJAA0ACQCABIAxGBEAgCyEBDAELIAEgAmogBE8NBSABIAVqLQAAIAEgDWotAABHDQIgAUEBaiEBDAELCwJAAkADQCABIAhNDQIgASAGTw0IIAEgAmoiCiAETw0BIAEgBWotAAAgASANai0AAEYEQCABQQFrIQEMAQsLIAkhCCAOIQEMAwsgCiAEQfixwQAQngIACyAGIAhNDQYgBCACIAhqIgxLBEAgBSAIaiEKIAkhCCAOIQEgCi0AACADIAxqLQAARg0KDAILIAwgBEGYssEAEJ4CAAsgASAPaiEBQQAhCAsgASACaiECDAILIAIgBmohAkEAIQgMAQsLIAQgAiAKaiIAIAAgBEkbIARB2LHBABCeAgALIAEgBkHoscEAEJ4CAAsgCCAGQYiywQAQngIAC0EAIQgMAgsgASAEQfiwwQAQngIAC0EBIQgLIAAgCDYCACAAIAI2AgQgB0EwaiQAC4QRARh/IwBBgAFrIgUkAAJAAkACQCADQQJHBEAgBUEoaiABKAKIASIaIAEoAoABIAEoAoQBIhNB9LDAABDoAiACKAIEIQogAigCACEJIAUoAighDiAFKAIsIhRBwABPBEAgBUEBOgB4IAVBMGohDyMAQdAAayIEJAAgBUH4AGotAAAhGyAEIAkgChDdASAEKAIEIREgBCgCACESAkACQAJAAkACQAJAAkAgCkECTwRAIAktAAAhAiAEQQA6AE8gCS0AASEHIARBAToAQAJ/IARBCGoiAyAHENYDQf8BcSADIAIQ1gNB/wFxTwRAIAIhAyAHIQJBASELQQAMAQsgBEEAOgBAIARBAToATyAHIQNBAQshByAJIApqIRZBAiEQQf8BIQggCSENA0AgAyEMAkACQANAAkACfyAXBEAgCEUgDSAWRnINAiAIQQFrIQggGAwBCyAIIBBNIBAgFiANa09yDQEgDSAQaiENIAggEEF/c2ohCCAQIBhqCyEGIA0tAAAhAyAGQQFqIRggDUEBaiENIARBCGoiFSADENYDQf8BcSAVIAwQ1gNB/wFxSQ0CQQAhEEEBIRcgA0H/AXEgDEH/AXFGDQEgFSADENYDQf8BcSAVIAIQ1gNB/wFxTw0BIAZBgAJPDQcgBCAGOgBAIAMhAiAGIQsMAQsLIAdB/wFxIAtB/wFxRw0BIwBBEGsiASQAIAEgBEFAazYCDCABIARBzwBqNgIIIwBBQGoiACQAIABBsK3AADYCBCAAIAFBCGo2AgAgAEGwrcAANgIMIAAgAUEMajYCCCAAQfC2wgAoAgA2AhQgAEHktsIAKAIANgIQIAAgAEEIaq1CgICAgJAGhDcDMCAAIACtQoCAgICQBoQ3AyggACAAQRBqrUKAgICA0AWENwMgQbmFwAAgAEEgakG4vcAAEMsCAAsgBCAHOgBAIAZBgAJPDQMgBCAGOgBPQQAhEEEBIRcgDCECIAchCyAGIQcMAQsLIBtBAXENBCAEQQA2AkAgBEEIaiAJIAogEiARIARBQGsQwAEMBQsgCkUNAiAEQQg2AjggBCARNgI0IAQgEjYCMCAEIAktAAA6AAgMBAtBhK3AAEErIARBCGpB9KzAAEHYvcAAEP8BAAtBhK3AAEErIARBCGpB9KzAAEHIvcAAEP8BAAsgBCARNgI0IAQgEjYCMCAEQQk2AjgMAQsgCiAHQf8BcSICTQ0BAkACQCAEQQhqIAIgCWotAAAiBhDWA0H/AXFB+gFNBEAgCiALQf8BcSIDSw0BIAMgCkHovcAAEJ4CAAsgBEEANgJADAELIAQgBzoASSAEIAY6AEggBEEKNgJAIAQgBkEQdCADQQh0ciADIAlqLQAAQRh0ciACcjYCRAsgBEEIaiAJIAogEiARIARBQGsQwAELIA8gCjYCQCAPIAk2AjwgD0EANgI4IA8gBEEIakE4/AoAACAEQdAAaiQADAELIAIgCkH4vcAAEJ4CAAsgBUIBNwJ4IAUoAnAiAiAUSwR/QQAFIAVBIGogBUEwaiAFQfgAaiAOIBQgBSgCbCACIAUoAmARCQAgBSgCJCEZIAUoAiALIQMgBSgCaEUgAkVyRQRAIAUoAmwgAkEBELoDCyADQQFxRQ0DDAILIAVBGGogCSAKEN0BIAUoAhwhBiAFKAIYIQsgDiAUaiIMIA4Q3gMgCSAKaiAJEN4DIgdJDQIgByAOaiENQQAhAyAOIQIDQCACIA1PBEAgDCAHayEMIA4hAgNAAkAgAyALRgRAIAIgCSAHENQBDQELIAIgDE8NBiACIAdqLQAAIAMgBiACLQAAbGtBAXRqIQMgAkEBaiECDAELCyACIA4Q3gMhGQwDBSACLQAAIANBAXRqIQMgAkEBaiECDAELAAsACwJAIAIoAgRFDQAgAigCDEUNACACQQhqIQ0gAigCAC0AACELIAIoAggtAAAhDCAFQRBqIAEoAogBIgQgASgCgAEiCiABKAKEASITQYSxwAAQ6AIgDEGBgoQIbCEOIAtBgYKECGwhCSAFKAIQIgcgBSgCFGoiBkEEayEQIAchAwNAIAMgBk8NAwJAIAYgAxDeA0EDSwRAAkBBgIKECCADKAAAIgggCXMiD2sgD3JBgIGChHhxQYCBgoR4Rw0AQYCChAggCCAOcyIIayAIckGAgYKEeHFBgIGChHhHDQAgA0F8cUEEaiEDA0ACQAJAIAMgEEsNAEGAgoQIIAMoAgAiCCAJcyIPayAPckGAgYKEeHFBgIGChHhHDQBBgIKECCAIIA5zIghrIAhyQYCBgoR4cUGAgYKEeEYNAQsDQCADIAZPDQkgCyADLQAAIghGIAggDEZyDQUgA0EBaiEDDAALAAsgA0EEaiEDDAALAAsDQCADIAZPDQYgCyADLQAAIghGIAggDEZyDQIgA0EBaiEDDAALAAsDQCADIAZPDQUgCyADLQAAIghGIAggDEZyDQEgA0EBaiEDDAALAAsgBUEIaiAKIBMgAyAHEN4DIARqIghBlLHAABCfAiAFKAIIIg8gBSgCDCIRIAIQqANFBEAgA0EBaiEDIA8gESANEKgDRQ0BCwsgASAINgKIAQwDCyABKAKIASIHIAEoAoQBIgsgByALSxshDiABKAKAASEJA0ACQCAOIAciBkYEQCALIQYMAQsgBSAGIAkgCxCaAiAGQQFqIQcgBSgCBCENIAUoAgAiBEUNAUEAIQMDQCADQRBGDQIgBSACIANqIgpBBGooAgAiDDYCfCAFIAooAgA2AnggBSAMNgI0IAUgBEEAIAwgDU0bNgIwIAVB+ABqIAVBMGoQ3QINASADQQhqIQMMAAsACwsgASAGNgKIAQwCCyABIBkgGmo2AogBDAELIAEgEzYCiAELIAAgATYCBCAAQQA2AgAgBUGAAWokAAvbCwIPfwF+IwBB0AFrIgQkACAEQShqIAIgAyABEJUCIARBIGogARCZAiAEQThqIAQoAiAgBCgCJBCbAiAEQaABaiIFIAQoAjwiAyAEKAJAIgIQigMgBEHEAGoiCSAFEOMCAn8CfwJAAkACQCAEKAJMBEAgBCAJQQBBpKfAABD4AiIGKAIEIgU2AlQgBCAGKAIAIgY2AlAgBEEYaiAJQbSnwAAQ6wIgBEHYAGogBCgCGCIJIAkgBCgCHEEDdGoQ+AEgBSAEKAIsIg9qIRAgBCgCKCEJIARB0ABqQcSnwAAQnAMNAQJAIAYgBUHAABDJAkUEQCAGIAVByYHAAEEDELsDRQ0BDAULIARBoAFqIAYgBRCbAiAEQawBaiAGIAUQmwJBASELQfWbwAAhA0EGIQIMAwsgBEHQAGpB0KfAABCcAw0DIARBoAFqIAYgBRCbAiAEQawBaiAGIAUQmwJBAiELQf+bwAAhA0EHIQIMAgtBAiELQQEhBkH/m8AAIQNBByECQQQhByAEKAI0IRAgBCgCMCEJIAQoAiwhD0EAIQVBASEIIAQoAigMBAtBCCEIQYSBwAAhCkEEIQwgBCgCYCENIAQoAlwhByAEKAJYIQ4gECECIA8hBSAJIgMhBkGunMAADAILIAQoArQBIQUgBCgCsAEhBiAEKAKsASEMIAQoAqgBIQogBCgCpAEhCCAEKAJgIQ0gBCgCXCEHIAQoAlghDiAEKAKgAQwBCwNAIAMgAkHJgcAAQQMQuwMEQCAEQQhqIAMgAkEDQdinwAAQnwIgC0EBaiELIAQoAgwhAiAEKAIIIQMMAQsLIAIhBiADIgUgAkEuEOoCBEAgBEGgAWoiBSADIAIQigMgBEEQaiAFEOYBIAQoAhQgAiAEKAIQIgUbIQYgBSADIAUbIQULIAQgBjYCaCAEIAU2AmQCfyADIAJBLhDqAkUEQCAEQQA2AnQgBEKAgICAwAA3AmxBBAwBCyAEQaABaiIHIAMgAhCKAyAEQQE2AsgBIARB7ABqIQojAEHQAGsiAyQAIANBGGogBxDuAQJAIAMoAhhBgICAgHhHBEAgA0EEQQRBDBCcAiADKAIAIQggAygCBCICIAMpAhg3AgAgAkEIaiADQSBqKAIANgIAIANBFGoiDUEBNgIAIAMgAjYCECADIAg2AgwgA0EkaiICIAdBLPwKAAAgA0EMaiEHIwBBEGsiCCQAA0ACQCAIQQRqIAIQ7gEgCCgCBEGAgICAeEYNACAHKAIIIgwgBygCAEYEQCAHQQEQhQMLIAcoAgQgDEEMbGoiDiAIKQIENwIAIA5BCGogCEEMaigCADYCACAHIAxBAWo2AggMAQsLIAhBEGokACAKQQhqIA0oAgA2AgAgCiADKQIMNwIADAELIApBADYCCCAKQoCAgIDAADcCAAsgA0HQAGokACAEKAJ0IQ0gBCgCbCEOIAQoAnALIQcgBEH4AGogBSAGEJsCIARBhAFqIgJByYHAAEEDIAsQpQEgBEECNgKcASAEQQQ2ApQBIAQgBEHkAGo2ApgBIAQgAjYCkAEgBEGsAWpBzIHAACAEQZABahD/AiACEMgDIARBqAFqIARBgAFqKAIAIgo2AgAgBCAEKQJ4IhM3A6ABIAQoAqwBIQwgBCgCsAEhBiAEKAK0ASEFIAQoAqQBIQggBEHYAGoQxQNBAiELQf+bwAAhA0EHIQIgE6cLIREgCQshEiAEQcQAahDHAyABEK0DIAAgEDYCNCAAIAk2AjAgACAPNgIsIAAgEjYCKCAAIAI2AiQgACADNgIgIAAgBTYCHCAAIAY2AhggACAMNgIUIAAgCjYCECAAIAg2AgwgACARNgIIIAAgCzYCBCAAQQ42AlQgAEGYmsAANgJQIAAgDTYCTCAAIAc2AkggACAONgJEIAAgBCkCODcCOCAAQUBrIARBQGsoAgA2AgAgAEEBNgIAIABB4ABqIARBMGopAgA3AgAgACAEKQIoNwJYIARB0AFqJAALzQgBBH8jAEHQAWsiAiQAIAJBqAFqIAEQ2wJBASEDIAIoAqwBIQECQCACKAKoAUEBcQ0AIAJBuAFqIAFBiAFqKAIANgIAIAIgASkCgAE3A7ABIAEoAhQhBCACQaABaiABQb6AwABBBBDSASACKAKkASEBAn9BAQJ/An8CfwJ/An8CfwJ/An8CfwJ/An8CfwJ/An8CfyACKAKgAUEBcQRAIAJBmAFqIAFB5oDAAEEEENIBIAIoApwBIQEgAigCmAEMAQtBAAtBAXEEQCACQZABaiABQfyAwABBAhDSASACKAKUASEBIAIoApABDAELQQALQQFxBEAgAkGIAWogAUHIgMAAQQMQ0gEgAigCjAEhASACKAKIAQwBC0EAC0EBcQRAIAJBgAFqIAFB34DAAEEHENIBIAIoAoQBIQEgAigCgAEMAQtBAAtBAXEEQCACQfgAaiABQc6AwABBBRDSASACKAJ8IQEgAigCeAwBC0EAC0EBcQRAIAJB8ABqIAFB2YDAAEECENIBIAIoAnQhASACKAJwDAELQQALQQFxBEAgAkHoAGogAUHLgMAAQQMQ0gEgAigCbCEBIAIoAmgMAQtBAAtBAXEEQCACQeAAaiABQfeAwABBBRDSASACKAJkIQEgAigCYAwBC0EAC0EBcQRAIAJB2ABqIAFB04DAAEEGENIBIAIoAlwhASACKAJYDAELQQALQQFxBEAgAkHQAGogAUHbgMAAQQQQ0gEgAigCVCEBIAIoAlAMAQtBAAtBAXEEQCACQcgAaiABQf6AwABBBBDSASACKAJMIQEgAigCSAwBC0EAC0EBcQRAIAJBQGsgAUHvgMAAQQUQ0gEgAigCRCEBIAIoAkAMAQtBAAtBAXEEQCACQThqIAFBwoDAAEEGENIBIAIoAjwhASACKAI4DAELQQALQQFxBEAgAkEwaiABQeqAwABBBRDSASACKAI0IQEgAigCMAwBC0EAC0EBcQRAIAJBKGogAUH0gMAAQQMQ0gEgAigCLCEBIAIoAigMAQtBAAtBAXENABogAkEgaiABENsCIAIoAiQhAUEBIAIoAiBBAXENABogASABLQCQASIFQQFGOgCQASACQcgBaiABQYgBaigCADYCACACIAEpAoABNwPAASABQTBqEK0CIAJBGGogARDHASACKAIcIQECfwJ/IAIoAhhBAXEEQCACQRBqIAFBgoHAAEEBENIBIAIoAhQhASACKAIQDAELQQALQQFxBEAgAkEIaiABQamAwABBARDSASACKAIMIQEgAigCCAwBC0EACyEDIAEgAikDwAE3AoABIAEgBToAkAEgAUGIAWogAkHIAWooAgA2AgAgAUEwahDOASADQQFxCyIDQQFxRQ0AIAEgAikDsAE3AoABIAFBiAFqIAJBuAFqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkHQAWokAAuNCQEKfyMAQaABayICJAAgAkE8OgBfIAJB0ABqIAEQ2wIgAigCVCEBAn9BASACKAJQQQFxDQAaIAEoAogBIgUgASgCjAEiA0YEQCABKAIsIQogASgCICEECyABKAIUIQcCQCABLQCQAUECRw0AIAEtAJEBRQ0AIAIgBTYCcCACQQA2AmwgAkEAOgBoIAFBDGogAkHoAGoQkwIgASgCjAEhAwsgAyAFRgRAIAEoAiwgASgCIGohCAsgAiABKAJcNgJgIAIgASgCeDYCZCACQcgAaiABENsCQQEhAyACKAJMIQECQCACKAJIQQFxDQAgAkGIAWogAUGIAWooAgA2AgAgAiABKQKAATcDgAEgASgCFCELIAJBQGsgAUHGgcAAQQIQ0gEgAigCRCEBAkAgAigCQEEBcQR/QQEFIAJBOGogARBcIAIoAjwhASACKAI4C0EBcQ0AIAJBMGogARDbAiACKAI0IQEgAigCMEEBcQ0AIAJBmAFqIgkgAUGIAWooAgA2AgAgAiABKQKAATcDkAEgASgCFCEGIAJBKGogARDbAiACKAIsIQEgAigCKEEBcUUEQCACQSBqIAEQxwEgAigCJCEBAkAgAigCIEEBcQ0AIAJBGGogARDbAiACKAIcIQEgAigCGEEBcQ0AIAJB8ABqIQYDQCACQRBqIAEQ2wIgAigCFCEBAkAgAigCEEEBcQRAQQEhAwwBCyAGIAFBiAFqKAIANgIAIAIgASkCgAE3A2ggASgCFCEJIAJBCGogARDHASACKAIMIQEgAigCCCIDQQFxRQ0AIAEgAikDaDcCgAEgAUGIAWogBigCADYCACAJIAEoAhRLDQAgASAJNgIUCyADQQFxRQ0ACwsgAiABQYKBwABBARDSASACKAIEIQEgAigCACEDDAELIAEgAikDkAE3AoABIAFBiAFqIAkoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgA0EBcUUNACABIAIpA4ABNwKAASABQYgBaiACQYgBaigCADYCACALIAEoAhRLDQAgASALNgIUCyACIAJB3wBqNgKYASACIAJB4ABqNgKUASACIAJB5ABqNgKQAQJAAkACQAJAAkAgA0EBcQRAIAIgATYCaCABLQCQAUEBRg0FIAFBPCAFIAQgCiAIEL0BIAEtAHwNAQwECyACIAE2AoABIAEtAJABIgNBAUYEfyABQTwgBSAEIAogCBC9ASABLQCQAQUgAwtB/wFxQQJHDQIgAS0AkQFFDQIgASgCFCEDIAFBDGoiBSAHEPcCIgQtAABBAUYNASAEIAM2AgQgASgCiAEhAyACIAc2AmwgAiADNgJ4IAJBADYCcCACIAItAF86AGkgAkEBOgBoIAUgAkHoAGoQkwIMAgsgAkGQAWogAkHoAGoQuQIMAgtB0K3AAEEoQfitwAAQnQMACyABLQB8BEAgAkGQAWogAkGAAWoQuQILQQAMAgsgAS0AkAFBAkcNACABLQCRAUUNACAHIAEoAhRLDQAgASAHNgIUC0EBCyEDIAAgATYCBCAAIAM2AgAgAkGgAWokAAuRCQEKfyMAQbABayICJAAgAkELOgBvIAJB4ABqIAEQ2wIgAigCZCEBAn9BASACKAJgQQFxDQAaIAEoAogBIgUgASgCjAEiA0YEQCABKAIsIQkgASgCICEECyABKAIUIQYCQCABLQCQAUECRw0AIAEtAJEBRQ0AIAIgBTYCgAEgAkEANgJ8IAJBADoAeCABQQxqIAJB+ABqEJMCIAEoAowBIQMLIAMgBUYEQCABKAIsIAEoAiBqIQcLIAIgASgCXDYCcCACIAEoAng2AnQgAkHYAGogARDbAkEBIQMgAigCXCEBAkAgAigCWEEBcQ0AIAJBmAFqIAFBiAFqKAIANgIAIAIgASkCgAE3A5ABIAEoAhQhCiACQdAAaiABEAogAigCVCEBAn8CQCACKAJQQQFxDQAgAkHIAGogARDbAiACKAJMIQEgAigCSEEBcQ0AIAJBqAFqIgggAUGIAWooAgA2AgAgAiABKQKAATcDoAEgASgCFCEDIAJBQGsgARDbAiACKAJEIQEgAigCQEEBcUUEQCACQThqIAEQlwEgAigCPCEBAkAgAigCOEEBcQ0AIAJBMGogARDbAiACKAI0IQEgAigCMEEBcQ0AIAJBgAFqIQgDQCACQShqIAEQ2wIgAigCLCEBAkAgAigCKEEBcQRAQQEhAwwBCyAIIAFBiAFqKAIANgIAIAIgASkCgAE3A3ggASgCFCELIAJBIGogARCXASACKAIkIQEgAigCICIDQQFxRQ0AIAEgAikDeDcCgAEgAUGIAWogCCgCADYCACALIAEoAhRLDQAgASALNgIUCyADQQFxRQ0ACwsgAkEYaiABENsCIAIoAhwhASACKAIYQQFxDQEgAkEQaiABECEgAkEIaiACKAIUEAsgAigCDCEBIAIoAggMAgsgASACKQOgATcCgAEgAUGIAWogCCgCADYCACADIAEoAhRLDQAgASADNgIUC0EBCyIDQQFxRQ0AIAEgAikDkAE3AoABIAFBiAFqIAJBmAFqKAIANgIAIAogASgCFEsNACABIAo2AhQLIAIgAkHvAGo2AqgBIAIgAkHwAGo2AqQBIAIgAkH0AGo2AqABAkACQAJAAkACQCADQQFxBEAgAiABNgJ4IAEtAJABQQFGDQUgAUELIAUgBCAJIAcQvQEgAS0AfA0BDAQLIAIgATYCkAEgAS0AkAEiA0EBRgR/IAFBCyAFIAQgCSAHEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIFIAYQ9wIiBC0AAEEBRg0BIAQgAzYCBCABKAKIASEDIAIgBjYCfCACIAM2AogBIAJBADYCgAEgAiACLQBvOgB5IAJBAToAeCAFIAJB+ABqEJMCDAILIAJBoAFqIAJB+ABqELkCDAILQdCtwABBKEH4rcAAEJ0DAAsgAS0AfARAIAJBoAFqIAJBkAFqELkCC0EADAILIAEtAJABQQJHDQAgAS0AkQFFDQAgBiABKAIUSw0AIAEgBjYCFAtBAQshAyAAIAE2AgQgACADNgIAIAJBsAFqJAALhQkBC38jAEGgAWsiAiQAIAJBEDoAXyACQdAAaiABENsCQQEhAyACKAJUIQECQCACKAJQQQFxDQAgASgCiAEiBSABKAKMASIDRgRAIAEoAiwhCiABKAIgIQQLIAEoAhQhBwJAIAEtAJABQQJHDQAgAS0AkQFFDQAgAiAFNgJwIAJBADYCbCACQQA6AGggAUEMaiACQegAahCTAiABKAKMASEDCyADIAVGBEAgASgCLCABKAIgaiEICyACIAEoAlw2AmAgAiABKAJ4NgJkIAJByABqIAEQ2wIgAigCTCEBAkAgAigCSEEBcQRAQQEhAwwBCyACQYgBaiABQYgBaigCADYCACACIAEpAoABNwOAASABKAIUIQsgAkFAayABEGggAigCRCEBAkAgAigCQEEBcQRAQQEhAwwBCyACQThqIAEQ2wJBASEDIAIoAjwhASACKAI4QQFxDQAgAkGYAWoiCSABQYgBaigCADYCACACIAEpAoABNwOQASABKAIUIQYgAkEwaiABENsCIAIoAjQhASACKAIwQQFxRQRAIAJBKGogARCXASACKAIsIQECQCACKAIoQQFxDQAgAkEgaiABENsCIAIoAiQhASACKAIgQQFxDQAgAkHwAGohBgNAIAJBGGogARDbAiACKAIcIQECQCACKAIYQQFxBEBBASEJDAELIAYgAUGIAWooAgA2AgAgAiABKQKAATcDaCABKAIUIQwgAkEQaiABEJcBIAIoAhQhASACKAIQIglBAXFFDQAgASACKQNoNwKAASABQYgBaiAGKAIANgIAIAwgASgCFEsNACABIAw2AhQLIAlBAXFFDQALCyACQQhqIAEQ2wIgAigCDCEBIAIoAghBAXENASACIAEQIUEAIQMgAigCBCEBDAELIAEgAikDkAE3AoABIAFBiAFqIAkoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgA0EBcUUNACABIAIpA4ABNwKAASABQYgBaiACQYgBaigCADYCACALIAEoAhRLDQAgASALNgIUCyACIAJB3wBqNgKYASACIAJB4ABqNgKUASACIAJB5ABqNgKQAQJAAkACQAJAIANBAXEEQCACIAE2AmhBASEDIAEtAJABQQFGDQUgAUEQIAUgBCAKIAgQvQEgAS0AfA0BDAQLIAIgATYCgAEgAS0AkAEiA0EBRgR/IAFBECAFIAQgCiAIEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIFIAcQ9wIiBC0AAEEBRg0BIAQgAzYCBCABKAKIASEDIAIgBzYCbCACIAM2AnggAkEANgJwIAIgAi0AXzoAaSACQQE6AGggBSACQegAahCTAgwCCyACQZABaiACQegAahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQZABaiACQYABahC5AgtB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IQUgAkFAayABEMcBIAIoAkQhASACKAJAIgNBAXFFDQAgASACKQOwATcCgAEgAUGIAWogBCgCADYCACAFIAEoAhRLDQAgASAFNgIUCyADQQFxRQ0ACwsgAkE4aiABENsCIAIoAjwhASACKAI4QQFxRQ0CQQEhAwwDCyABIAIpA6ABNwKAASABQYgBaiAEKAIANgIAIAMgASgCFEsNACABIAM2AhQLQQEMAgsgAkGoAWogAUGIAWooAgA2AgAgAiABKQKAATcDoAEgASgCFCEEIAJBMGogAUGJgcAAQQQQ0gEgAigCNCEBAn9BASACKAIwQQFxDQAaIAJBKGogARDbAiACKAIsIQFBASACKAIoQQFxDQAaIAEgAS0AkAEiBUEBRjoAkAEgAkG4AWogAUGIAWooAgA2AgAgAiABKQKAATcDsAEgAUEwahCtAiACQSBqIAEQxwEgAigCJCEBAn8CfyACKAIgQQFxBEAgAkEYaiABQaeAwABBAhDSASACKAIcIQEgAigCGAwBC0EAC0EBcQRAIAJBEGogAUG5gMAAQQMQ0gEgAigCFCEBIAIoAhAMAQtBAAshAyABIAIpA7ABNwKAASABIAU6AJABIAFBiAFqIAJBuAFqKAIANgIAIAFBMGoQzgEgA0EBcQsiA0EBcUUNACABIAIpA6ABNwKAASABQYgBaiACQagBaigCADYCACAEIAEoAhRLDQAgASAENgIUCyADQQFxBEAgAkEIaiABQamAwABBARDSASACKAIMIQEgAigCCAwBC0EACyIDQQFxRQ0AIAEgAikDkAE3AoABIAFBiAFqIAJBmAFqKAIANgIAIAYgASgCFEsNACABIAY2AhQLIAAgATYCBCAAIAM2AgAgAkHAAWokAAvsCAERfyMAQeAAayIDJAAgA0EoaiEJAkACfyACQQoQoQJFBEAgAkENEKECIQQgA0EgaiACEP0BIAMoAiQhByADKAIgIgogBA0BGiADQRhqQQBBAUEBEJwCIANBADYCQCADIAMpAxg3AjggA0EANgJcIAMgCjYCVCADIAo2AkwgA0ECNgJIIANBnK7AADYCRCADIAc2AlAgAyAHIApqIgY2AlggA0HUAGohEiAKIQQDQCADQRBqIBIQ8AECQCADKAIUIhBBgIDEAEcEQCADKAIQIREgAygCSCIJQQ9xIRMgAygCRCILIAlB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AQshAyAAIAE2AgQgACADNgIAIAJBkAFqJAALtgcBCn8jAEHwAGsiAiQAIAJBFjoAOyACQTBqIAEQ2wIgAigCNCEBAn9BASACKAIwQQFxDQAaIAEoAogBIgUgASgCjAEiA0YEQCABKAIsIQggASgCICEECyABKAIUIQYCQCABLQCQAUECRw0AIAEtAJEBRQ0AIAIgBTYCUCACQQA2AkwgAkEAOgBIIAFBDGogAkHIAGoQkwIgASgCjAEhAwsgAyAFRgRAIAEoAiwgASgCIGohBwsgAiABKAJcNgI8IAIgASgCeDYCQCACQShqIAEQ2wJBASEDIAIoAiwhAQJAIAIoAihBAXENACACQegAaiABQYgBaigCADYCACACIAEpAoABNwNgIAEoAhQhCSACQSBqIAEQ2wIgAigCJCEBAn8CQCACKAIgQQFxRQRAIAEgAS0AkAEiA0EBRzoAkAEgAkHQAGoiCiABQYgBaigCADYCACACIAEpAoABNwNIIAFBMGoQrQIgAkEYaiABEDUgAigCGCELIAIoAhwiASACKQNINwKAASABIAM6AJABIAFBiAFqIAooAgA2AgAgAUEwahDOASALQQFxDQELQQEMAQsgAkEQaiABEAQgAigCFCEBAn8gAigCEEEBcQRAIAJBCGogARC6ASACKAIMIQEgAigCCAwBC0EAC0EBcQRAIAIgARA7IAIoAgQhASACKAIADAELQQALIgNBAXFFDQAgASACKQNgNwKAASABQYgBaiACQegAaigCADYCACAJIAEoAhRLDQAgASAJNgIUCyACIAJBO2o2AmggAiACQTxqNgJkIAIgAkFAazYCYAJAAkACQAJAAkAgA0EBcQRAIAIgATYCSCABLQCQAUEBRg0FIAFBFiAFIAQgCCAHEL0BIAEtAHwNAQwECyACIAE2AkQgAS0AkAEiA0EBRgR/IAFBFiAFIAQgCCAHEL0BIAEtAJABBSADC0H/AXFBAkcNAiABLQCRAUUNAiABKAIUIQMgAUEMaiIFIAYQ9wIiBC0AAEEBRg0BIAQgAzYCBCABKAKIASEDIAIgBjYCTCACIAM2AlggAkEANgJQIAIgAi0AOzoASSACQQE6AEggBSACQcgAahCTAgwCCyACQeAAaiACQcgAahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCACQeAAaiACQcQAahC5AgtBAAwCCyABLQCQAUECRw0AIAEtAJEBRQ0AIAYgASgCFEsNACABIAY2AhQLQQELIQMgACABNgIEIAAgAzYCACACQfAAaiQAC/AGAgp/AX4jAEEQayINJAACQAJAAkACQCAEQRBPBEAgBkEBayEQQQEhDCABKAIEIQ4gASgCAEEBRw0BIAZFDQMgASgCECIKIAYgBiAKSRshCCAKQQFrIQkgASkDCCERQQAhDEEAIQECQANAIAQgASIHIAZqIgFJDQYgByAQaiICIARPDQEgESACIANqMQAAiEIBg1ANACADIAdqIQsgB0F/cyECIAohAQJAA0AgASAIRgRAIAkhAQJAAkADQCABQX9GDQogBiAJTQ0CIAEgB2oiAiAETw0BIAEgC2ohAiABIAVqIQ8gAUEBayEBIA8tAAAgAi0AAEYNAAsgByAOaiEBDAULIAIgBEGoscEAEJ4CAAsgASAGQZixwQAQngIACyABIAdqIARPDQEgASAFai0AACABIAtqLQAARgRAIAJBAWshAiABQQFqIQEMAQsLQQAgAmshAQwBCwsgBCAHIApqIgAgACAESRsgBEGIscEAEJ4CAAsgAiAEQfiwwQAQngIACyANQQhqIAFBKGogAyAEIAUgBhDDASANKAIMIQcgDSgCCCEMDAMLIAZFDQEgBiAOayEKQQEgASgCECILayEPIAEpAwghEUEAIQxBACECQQAhAQJAAkACQANAIAIhCSABIgcgBmoiASAESw0GIAQgByAQaiIISwRAQQAhAiARIAMgCGoxAACIQgGDUA0BIAMgB2ohAiAJIAsgCSALSxsiCCEBAkACQANAAkAgASAGTwRAIAshAQwBCyABIAdqIARPDQYgASAFai0AACABIAJqLQAARw0CIAFBAWohAQwBCwsCQAJAA0AgASAJTQ0CIAEgBk8NCCABIAdqIgggBE8NASABIAVqLQAAIAEgAmotAABGBEAgAUEBayEBDAELCyAKIQIgDiEBDAMLIAggBEH4scEAEJ4CAAsgBiAJTQ0GIAQgByAJaiIISwRAIAohAiAOIQEgBSAJai0AACADIAhqLQAARg0IDAILIAggBEGYssEAEJ4CAAsgASAPaiEBQQAhAgsgASAHaiEBDAELCyAIIARByLHBABCeAgALIAQgByAIaiIAIAAgBEkbIARB2LHBABCe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QQF2IQkLIAdB////AHEhCiAAKAIEIQcgACgCACEAA0AgAUH//wNxIAlB//8DcU8NAkEBIQYgAUEBaiEBIAAgCiAHKAIQEQEARQ0ACwwECyAAIAApAggiDadBgICA/3lxQbCAgIACcjYCCEEBIQYgACgCACIHIAAoAgQiCiALIAIgAxDiAg0DQQAhASAIIAlrQf//A3EhAgNAIAFB//8DcSACTw0CIAFBAWohASAHQTAgCigCEBEBAEUNAAsMAwtBASEGIAAgByALIAIgAxDiAg0CIAAgBCAFIAcoAgwRBAANAkEAIQEgCCAJa0H//wNxIQIDQCABQf//A3EiAyACSSEGIAIgA00NAyABQQFqIQEgACAKIAcoAhARAQBFDQALDAILIAcgBCAFIAooAgwRBAANASAAIA03AghBAA8LQQEhBiAAKAIAIgEgACgCBCIAIAsgAiADEOICDQAgASAEIAUgACgCDBEEACEGCyAGC5cGAQV/IABBCGsiASAAQQRrKAIAIgNBeHEiAGohAgJAAkAgA0EBcQ0AIANBAnFFDQEgASgCACIDIABqIQAgASADayIBQci6wgAoAgBGBEAgAigCBEEDcUEDRw0BQcC6wgAgADYCACACIAIoAgRBfnE2AgQgASAAQQFyNgIEIAIgADYCAA8LIAEgAxCUAQsCQAJAAkACQAJAIAIoAgQiA0ECcUUEQCACQcy6wgAoAgBGDQIgAkHIusIAKAIARg0DIAIgA0F4cSICEJQBIAEgACACaiIAQQFyNgIEIAAgAWogADYCACABQci6wgAoAgBHDQFBwLrCACAANgIADwsgAiADQX5xNgIEIAEgAEEBcjYCBCAAIAFqIAA2AgALIABBgAJJDQIgASAAEJgBQQAhAUHgusIAQeC6wgAoAgBBAWsiADYCACAADQRBqLjCACgCACIABEADQCABQQFqIQEgACgCCCIADQALC0HgusIAQf8fIAEgAUH/H00bNgIADwtBzLrCACABNgIAQcS6wgBBxLrCACgCACAAaiIANgIAIAEgAEEBcjYCBEHIusIAKAIAIAFGBEBBwLrCAEEANgIAQci6wgBBADYCAAsgAEHYusIAKAIAIgNNDQNBzLrCACgCACICRQ0DQQAhAEHEusIAKAIAIgRBKUkNAkGguMIAIQEDQCACIAEoAgAiBU8EQCACIAUgASgCBGpJDQQLIAEoAgghAQwACwALQci6wgAgATYCAEHAusIAQcC6wgAoAgAgAGoiADYCACABIABBAXI2AgQgACABaiAANgIADwsCQEG4usIAKAIAIgJBASAAQQN2dCIDcUUEQEG4usIAIAIgA3I2AgAgAEH4AXFBsLjCAGoiACECDAELIABB+AFxIgBBsLjCAGohAiAAQbi4wgBqKAIAIQALIAIgATYCCCAAIAE2AgwgASACNgIMIAEgADYCCA8LQai4wgAoAgAiAQRAA0AgAEEBaiEAIAEoAggiAQ0ACwtB4LrCAEH/HyAAIABB/x9NGzYCACADIARPDQBB2LrCAEF/NgIACwvQBQEFfyMAQZABayICJAAgAkHoAGogARDbAkEBIQMgAigCbCEBAkAgAigCaEEBcQ0AIAJB+ABqIAFBiAFqKAIANgIAIAIgASkCgAE3A3AgASgCFCEEIAJB4ABqIAEQ2wIgAigCZCEBAkAgAigCYEEBcQRADAELIAJB2ABqIAFBrIDAAEEBENIBIAJB0ABqIAIoAlwQ2wIgAigCVCEBAkAgAigCUEEBcQRAQQEhBQwBCyACQYgBaiABQYgBaigCADYCACACIAEpAoABNwOAASABKAIUIQYgAkHIAGogARDPAiACKAJMIQECf0EBIAIoAkhBAXENABogAkFAayABENsCIAIoAkQhAUEBIAIoAkBBAXENABoDQCACQThqIAEQzwIgAigCPCEBIAIoAjhBAXFFDQALQQALIgVBAXFFDQAgASACKQOAATcCgAEgAUGIAWogAkGIAWooAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgBUEBcQ0AIAJBMGogARDbAiACKAI0IQEgAigCMEEBcQ0AIAJBKGogARDbAiACKAIsIQECQCACKAIoQQFxDQAgAkGIAWogAUGIAWooAgA2AgAgAiABKQKAATcDgAEgASgCFCEDIAJBIGogAUGIgcAAQQEQ0gEgAigCJCEBAkAgAigCIEEBcQR/QQEFIAJBGGogARDPAiACKAIcIQEgAigCGAtBAXENACACQRBqIAEQ2wIgAigCFCEBIAIoAhBBAXENAANAIAJBCGogARDPAiACKAIMIQEgAigCCEEBcUUNAAsMAQsgASACKQOAATcCgAEgAUGIAWogAkGIAWooAgA2AgAgAyABKAIUSw0AIAEgAzYC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KAIUSw0AIAEgBTYCFAsgACABNgIEIAAgAzYCACACQfAAaiQAC90EAQR/IwBB8ABrIgIkACACQcgAaiABENsCQQEhAyACKAJMIQECQCACKAJIQQFxDQAgAkHYAGogAUGIAWooAgA2AgAgAiABKQKAATcDUCABKAIUIQQgAkFAayABQYSBwABBBBDSASACKAJEIQECf0EBIAIoAkBBAXENABogAkE4aiABENsCIAIoAjwhAUEBIAIoAjhBAXENABogASABLQCQASIFQQFGOgCQASACQegAaiABQYgBaigCADYCACACIAEpAoABNwNgIAFBMGoQrQIgAkEwaiABQYiBwABBARDSASACKAI0IQECfwJ/An8CfwJ/An8gAigCMEEBcQRAIAJBKGogARDHASACKAIsIQEgAigCKAwBC0EAC0EBcQRAIAJBIGogAUGngMAAQQIQ0gEgAigCJCEBIAIoAiAMAQtBAAtBAXEEQCACQRhqIAFBvIDAAEEBENIBIAIoAhwhASACKAIYDAELQQALQQFxBEAgAkEQaiABQbmAwABBAxDSASACKAIUIQEgAigCEAwBC0EAC0EBcQRAIAJBCGogAUGDgcAAQQEQ0gEgAigCDCEBIAIoAggMAQtBAAtBAXEEQCACIAFBr4DAAEEBENIBIAIoAgQhASACKAIADAELQQALIQMgASACKQNgNwKAASABIAU6AJABIAFBiAFqIAJB6ABqKAIANgIAIAFBMGoQzgEgA0EBcQsiA0UNACABIAIpA1A3AoABIAFBiAFqIAJB2ABqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkHwAGokAAvZBAEEfyMAQfAAayICJAAgAkHIAGogARDbAkEBIQMgAigCTCEBAkAgAigCSEEBcQ0AIAJB2ABqIAFBiAFqKAIANgIAIAIgASkCgAE3A1AgASgCFCEEIAJBQGsgARDbAiACKAJEIQECfwJAIAIoAkBBAXFFBEAgASABLQCQASIFQQFHOgCQASACQegAaiABQYgBaigCADYCACACIAEpAoABNwNgIAFBMGoQrQIgAkE4aiABEMcBIAIoAjwhAQJ/An8CfwJ/An8CfyACKAI4QQFxBEAgAkEwaiABQYOBwABBARDSASACKAI0IQEgAigCMAwBC0EAC0EBcQRAIAJBKGog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QYgBaigCADYCACACIAEpAoABNwNQIAFBMGoQrQIgAkEgaiABQbiBwABBBBDSASACKAIgIQUgAigCJCIBIAIpA1A3AoABIAEgBDoAkAEgAUGIAWogAygCADYCACABQTBqEM4BIAVBAXFFDQAgAkEYaiABENsCIAIoAhwhASACKAIYQQFxDQAgASABLQCQASIEQQFHOgCQASADIAFBiAFqKAIANgIAIAIgASkCgAE3A1AgAUEwahCtAiACQRBqIAFBvIHAAEEFENIBIAIoAhAhBSACKAIUIgEgAikDUDcCgAEgASAEOgCQASABQYgBaiADKAIANgIAIAFBMGoQzgEgBUEBcQ0BC0EBDAELIAJBCGogARDGASACKAIMIQEgAigCCAsiA0EBcUUNACABIAIpA0A3AoABIAFBiAFqIAYoAgA2AgAgByABKAIUSw0AIAEgBzYCFAsgA0EBcUUNAAtBACEDCyAAIAE2AgQgACADNgIAIAJB4ABqJAALiwQBBH8jAEHgAGsiAiQAIAJBOGogARDbAkEBIQMgAigCPCEBAkAgAigCOEEBcQ0AIAJByABqIAFBiAFqKAIANgIAIAIgASkCgAE3A0AgASgCFCEEIAJBMGogAUGHgMAAQQQQ0gEgAigCNCEBAn9BAQJ/IAIoAjBBAXEEQCACQShqIAFBgoDAAEEFENIBIAIoAiwhASACKAIoDAELQQALQQFxDQAaIAJBIGogARDbAiACKAIkIQFBASACKAIgQQFxDQAaIAEgAS0AkAEiBUEBRjoAkAEgAkHYAGogAUGIAWooAgA2AgAgAiABKQKAATcDUCABQTBqEK0CIAJBGGogARDHASACKAIcIQECfwJ/An8gAigCGEEBcQRAIAJBEGogAUGngMAAQQIQ0gEgAigCFCEBIAIoAhAMAQtBAAtBAXEEQCACQQhqIAFBvIDAAEEBENIBIAIoAgwhASACKAIIDAELQQALQQFxBEAgAiABQbmAwABBAxDSASACKAIEIQEgAigCAAwBC0EACyEDIAEgAikDUDcCgAEgASAFOgCQASABQYgBaiACQdgAaigCADYCACABQTBqEM4BIANBAXELIgNBAXFFDQAgASACKQNANwKAASABQYgBaiACQcgAaigCADYCACAEIAEoAhRLDQAgASAENgIUCyAAIAE2AgQgACADNgIAIAJB4ABq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BEEBcUUEQEEAIQMMAQsgAkEgaiABENsCIAIoAiQhASACKAIgQQFxDQAgAkHIAGogAUGIAWooAgA2AgAgAiABKQKAATcDQCABKAIUIQQgAkEYaiABQayAwABBARDSASACKAIcIQECf0EBIAIoAhhBAXENABogAkEQaiABENsCIAIoAhQhAUEBIAIoAhBBAXENABogASABLQCQASIDQQFGOgCQASACQdgAaiIFIAFBiAFqKAIANgIAIAIgASkCgAE3A1AgAUEwahCtAiACQQhqIAEQ+gEgAigCCCEGIAIoAgwiASACKQNQNwKAASABIAM6AJABIAFBiAFqIAUoAgA2AgAgAUEwahDOASAGQQFxCyIDQQFxRQ0AIAEgAikDQDcCgAEgAUGIAWogAkHIAGooAgA2AgAgBCABKAIUSw0AIAEgBDYCFAsgACABNgIEIAAgAzYCACACQeAAaiQAC80DAQV/IwBB4ABrIgIkACACQThqIAEQ2wJBASEDIAIoAjwhAQJAIAIoAjhBAXENACACQcgAaiABQYgBaigCADYCACACIAEpAoABNwNAIAEoAhQhBCACQTBqIAFBxYHAAEEBENIBIAIoAjQhASACKAIwQQFxRQRAIAJBKGogARA9IAIoAighAyACKAIsIQELAn9BASADQQFxDQAaIAJBIGogARDbAiACKAIkIQFBASACKAIgQQFxDQAaIAJB2ABqIQUDQCACQRhqIAEQ2wIgAigCHCEBAkAgAigCGEEBcQRAQQEhAwwBCyAFIAFBiAFqKAIANgIAIAIgASkCgAE3A1AgASgCFCEGIAJBEGogAUGIgcAAQQEQ0gEgAigCFCEBIAIoAhBBAXEEf0EBBSACQQhqIAEQQyACKAIMIQEgAigCCAsiA0EBcUUNACABIAIpA1A3AoABIAFBiAFqIAUoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgA0EBcUUNAAtBAAsiA0EBcUUNACABIAIpA0A3AoABIAFBiAFqIAJByABqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkHgAGokAAugAwIFfgN/IwBBIGsiCiQAIABB/w82AgggAEIANwMAAkACQCACUCABQqp9U3INACABQrQCVQ0BIApBEGogAaciCUEEdCIIQaj+wQBqKQMAIAIgAnkiBYYiAxDtASAKKQMQIQQgCikDGCICQv8Dg0L/A1EEQCAKIAhBsP7BAGopAwAgAxDtASACIAopAwgiAiAEfCIEIAJUrXwhAgsgAUIbfELTAFoEQEF/IQggBEJ/UQ0BCyACIAJCP4giBkIJfCIHiCEDIAACfiAGpyAJQeqkDWxBEHUgBadrakE/aiIJQYJ4TgRAIAlBgAhB/wcgA0L8/////////wCDIAMgAyAHhiACURsgAyADQgODQgFRGyADIARCAlQbIAMgAUIEfEIcVBsiAUIBgyABfCIBQv////////8fViIJG2oiCEH+D0sNA0IAIAFCAYhC//////////f/AIMgCRsMAQtBACEIIAlBw3dJDQEgA0GCeCAJa62IIgFCAYMgAXwiAUL/////////D1YhCCABQgGICzcDAAsgACAINgIICyAKQSBqJAALtQMBBH8jAEHQAGsiAiQAIAJBKGogARDbAkEBIQMgAigCLCEBAkAgAigCKEEBcQ0AIAJBOGogAUGIAWooAgA2AgAgAiABKQKAATcDMCABKAIUIQQgAkEgaiABENsCIAIoAiQhAQJ/AkAgAigCIEEBcUUEQCABIAEtAJABIgVBAUc6AJABIAJByABqIAFBiAFqKAIANgIAIAIgASkCgAE3A0AgAUEwahCtAiACQRhqIAFBvYDAAEEBENIBIAIoAhwhAQJ/An8gAigCGEEBcQRAIAJBEGogAUGlgMAAQQIQ0gEgAigCFCEBIAIoAhAMAQtBAAtBAXEEQCACQQhqIAFBoYHAAEEDENIBIAIoAgwhASACKAIIDAELQQALIQMgASACKQNANwKAASABIAU6AJABIAFBiAFqIAJByABqKAIANgIAIAFBMGoQzgEgA0EBcQ0BC0EBDAELIAIgARDGASACKAIEIQEgAigCAAsiA0EBcUUNACABIAIpAzA3AoABIAFBiAFqIAJBOGooAgA2AgAgBCABKAIUSw0AIAEgBDYCFAsgACABNgIEIAAgAzYCACACQdAAaiQAC6YDAQR/IwBB0ABrIgIkACACQShqIAEQ2wJBASEEIAIoAiwhAQJAIAIoAihBAXEEQEEBIQMMAQsgAkE4aiABQYgBaigCADYCACACIAEpAoABNwMwIAEoAhQhBSACQSBqIAEQ2wIgAigCJCEBAkAgAigCIEEBcQ0AIAJByABqIAFBiAFqKAIANgIAIAIgASkCgAE3A0AgASgCFCEDIAJBGGogAUHJgcAAQQMQ0gEgAigCHCEBAn9BASACKAIYQQFxDQAaIAJBEGogARDbAiACKAIUIQFBASACKAIQQQFxDQAaA0AgAkEIaiABQcmBwABBAxDSASACKAIMIQEgAigCCEEBcUUNAAtBAAsiBEUNACABIAIpA0A3AoABIAFBiAFqIAJByABqKAIANgIAIAMgASgCFEsNACABIAM2AhQLQQEhAyAERQRAIAIgARA9IAIoAgAhAyACKAIEIQELIANBAXFFDQAgASACKQMwNwKAASABQYgBaiACQThqKAIANgIAIAUgASgCFEsNACABIAU2AhQLIAAgATYCBCAAIAM2AgAgAkHQAGokAAugAwEFfyMAQdAAayICJAAgAkEoaiABENsCQQEhAyACKAIsIQECQCACKAIoQQFxDQAgAkE4aiABQYgBaigCADYCACACIAEpAoABNwMwIAEoAhQhBCACQSBqIAEQUyACKAIkIQECf0EBIAIoAiBBAXENABogAkEYaiABENsCIAIoAhwhAUEBIAIoAhhBAXENABogAkHIAGohBQNAIAJBEGogARDbAiACKAIUIQECQCACKAIQQQFxBEBBASEDDAELIAUgAUGIAWooAgA2AgAgAiABKQKAATcDQCABKAIUIQYgAkEIaiABQYiBwABBARDSASACKAIMIQEgAigCCEEBcQR/QQEFIAIgARBDIAIoAgQhASACKAIACyIDQQFxRQ0AIAEgAikDQDcCgAEgAUGIAWogBSgCADYCACAGIAEoAhRLDQAgASAGNgIUCyADQQFxRQ0AC0EACyIDQQFxRQ0AIAEgAikDMDcCgAEgAUGIAWogAkE4aigCADYCACAEIAEoAhRLDQAgASAENgIUCyAAIAE2AgQgACADNgIAIAJB0ABqJAAL6QIBBX8CQCABQc3/e0EQIAAgAEEQTRsiAGtPDQAgAEEQIAFBC2pBeHEgAUELSRsiBGpBDGoQASICRQ0AIAJBCGshAQJAIABBAWsiAyACcUUEQCABIQAMAQsgAkEEayIFKAIAIgZBeHEgAiADakEAIABrcUEIayICIABBACACIAFrQRBNG2oiACABayICayEDIAZBA3EEQCAAIAMgACgCBEEBcXJBAnI2AgQgACADaiIDIAMoAgRBAXI2AgQg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KALQAkGAgICAeEcEQCAGQdACahDIAyAGQdwCahDIAwwBCyAGQdQCahDIAwsgBigC6AIiAUEMahCfAyABEMgDIAFBGGoQnwMgAUEkahChAyABQdAAQQQQugMLIBMQnwMgBkGgB2okACAMQRxqEJADIAxBMGokAEEBIQEgCkEcaiECAn8gCigCGEEBRgRAIApBMGogAkEIaigCACIDNgIAIAogAikCADcDKCAKKAIsIAMQACECIBUQyANBACEEQQAMAQsgCkEwaiACQQhqKAIANgIAIAogAikCADcDKCMAQRBrIgYkAAJAAkAgCiAKQShqIgIoAggiASACKAIASQR/IAZBCGohDEEBIQMjAEEQayIEJAAgBEEEaiACQQFBARC0AgJAIAQoAggiBQRAIAQoAgwhByAEKAIEIQgCQCABRQRAIAggBSAHEKQDIAJBATYCBAwBCyAIIAcgBSABIgMQrwMiB0UNAiACIAc2AgQLIAIgATYCAAtBgYCAgHghBQsgDCADNgIEIAwgBTYCACAEQRBqJAAgBigCCCIBQYGAgIB4Rw0BIAIoAggFIAELNgIEIAogAigCBDYCACAGQRBqJAAMAQsgASAGKAIMEJsDAAsgCigCBCEEQQAhAkEAIQEgCigCAAshAyAAIAE2AgwgACACNgIIIAAgBDYCBCAAIAM2AgAgCkHQAGokAAuBAgEBfyMAQUBqIgIkACACQThqIAEQMyACKAI8IQEgAAJ/An8CfwJ/An8CfyACKAI4QQFxBEAgAkEwaiABEGwgAigCNCEBIAIoAjAMAQtBAAtBAXEEQCACQShqIAEQICACKAIsIQEgAigCKAwBC0EAC0EBcQRAIAJBIGogARBUIAIoAiQhASACKAIgDAELQQALQQFxBEAgAkEYaiABEG4gAigCHCEBIAIoAhgMAQtBAAtBAXEEQCACQRBqIAEQOSACKAIUIQEgAigCEAwBC0EAC0EBcQRAIAJBCGogARBEIAIoAgwhASACKAIIDAELQQALNgIAIAAgATYCBCACQUBrJAALmwIBAX8jAEEgayIEJAACQAJAAkAgACACTQRAIAEgAksNASAAIAFNDQIgBCAANgIIIAQgATYCDCAEIARBDGqtQoCAgICwAYQ3AxggBCAEQQhqrUKAgICAsAGENwMQQe+CwAAgBEEQaiADEMsCAAsgBCAANgII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AAsgBEEgaiQAC54CAQN/IwBBQGoiAiQAIAJBKGogARDbAkEBIQMgAigCLCEBAkAgAigCKEEBcQ0AIAJBOGogAUGIAWooAgA2AgAgAiABKQKAATcDMCABKAIUIQQgAkEgaiABQYGAwABBARDSASACKAIkIQECfwJAIAIoAiBBAXENACACQRhqIAEQ2wIgAigCHCEBIAIoAhhBAXENAANAIAJBEGogARBVIAIoAhQhASACKAIQQQFxRQ0ACyACQQhqIAFBgYDAAEEBENIBIAIoAgwhASACKAIIDAELQQELIgNBAXFFDQAgASACKQMwNwKAASABQYgBaiACQThqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkFAayQAC54CAQN/IwBBQGoiAiQAIAJBKGogARDbAkEBIQMgAigCLCEBAkAgAigCKEEBcQ0AIAJBOGogAUGIAWooAgA2AgAgAiABKQKAATcDMCABKAIUIQQgAkEgaiABQa6AwABBARDSASACKAIkIQECfwJAIAIoAiBBAXENACACQRhqIAEQ2wIgAigCHCEBIAIoAhhBAXENAANAIAJBEGogARBXIAIoAhQhASACKAIQQQFxRQ0ACyACQQhqIAFBroDAAEEBENIBIAIoAgwhASACKAIIDAELQQELIgNBAXFFDQAgASACKQMwNwKAASABQYgBaiACQThqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkFAayQAC48CAQl/IwBBIGsiAiQAIAEoAgQhCCACQQhqIAEoAggiBUEEQRAQnAIgBUEEdCEJIAJBFGohBiACKAIMIQdBACEBIAIoAggiCiEEA0AgBEUgASAJRnJFBEACQAJAAkACQAJAIAEgCGoiAygCAEEBaw4DAQIDAAsgBiADQQRqEJICIAJBADYCEAwDCyAGIANBBGoQkgIgAkEBNgIQDAILIAJBGGogA0EIaikCADcDACACIAMpAgA3AxAMAQsgAkEDNgIQCyABIAdqIgMgAikDEDcCACADQQhqIAJBGGopAwA3AgAgBEEBayEEIAFBEGohAQwBCwsgACAFNgIIIAAgBzYCBCAAIAo2AgAgAkEgaiQAC/gBAQp/IAIgAUEBayIDaiEGIAAgA2ohBSAAIAFBAXYiB2oiA0EBayEE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JAAL9QEBA38jAEEwayICJAAgAkEYaiABENsCQQEhAyACKAIcIQECQCACKAIYQQFxDQAgAkEoaiABQYgBaigCADYCACACIAEpAoABNwMgIAEoAhQhBCACQRBqIAEQ0AIgAigCFCEBAn9BASACKAIQQQFxDQAaIAJBCGogARDbAiACKAIMIQFBASACKAIIQQFxDQAaA0AgAiABEEsgAigCBCEBIAIoAgBBAXFFDQALQQALIgNFDQAgASACKQMgNwKAASABQYgBaiACQShqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkEwaiQAC/QBAQN/IwBBMGsiAiQAIAJBGGogARDbAkEBIQMgAigCHCEBAkAgAigCGEEBcQ0AIAJBKGogAUGIAWooAgA2AgAgAiABKQKAATcDICABKAIUIQQgAkEQaiABEEggAigCFCEBAn9BASACKAIQQQFxDQAaIAJBCGogARDbAiACKAIMIQFBASACKAIIQQFxDQAaA0AgAiABEEggAigCBCEBIAIoAgBBAXFFDQALQQALIgNFDQAgASACKQMgNwKAASABQYgBaiACQShqKAIANgIAIAQgASgCFEsNACABIAQ2AhQLIAAgATYCBCAAIAM2AgAgAkEwaiQAC/kBAQN/IwBBMGsiAiQAIAJBGGogARDbAkEBIQMgAigCHCEBAkAgAigCGEEBcQ0AIAJBKGogAUGIAWooAgA2AgAgAiABKQKAATcDICABKAIUIQQgAkEQaiABENsCIAIoAhQhAQJ/IAIoAhBBAXFFBEADQCACQQhqIAEQxwEgAigCDCEBIAIoAghBAXFFDQALIAIgAUGtgMAAQQEQ0gEgAigCBCEBIAIoAgAMAQtBAQsiA0EBcUUNACABIAIpAyA3AoABIAFBiAFqIAJBKGooAgA2AgAgBCABKAIUSw0AIAEgBDYCFAsgACABNgIEIAAgAzYCACACQTBqJAAL0wEBBX8CQCABKAIAIgYgASgCBCIERgRAQYCAxAAhAgwBCyABIARBAWsiAzYCBCADLAAAIgJBAEgEQCABIARBAmsiAzYCBCACQT9xAn8gAy0AACICwCIFQUBOBEAgAkEfcQwBCyABIARBA2siAzYCBCAFQT9xAn8gAy0AACICwCIFQUBOBEAgAkEPcQwBCyABIARBBGsiAzYCBCAFQT9xIAMtAABBB3FBBnRyC0EGdHILQQZ0ciECCyABKAIIIAZrIANqIQELIAAgAjYCBCAAIAE2AgAL/AECA38BfiMAQTBrIgIkACABKAIAQYCAgIB4RgRAIAEoAgwhAyACQSxqIgRBADYCACACQoCAgIAQNwIkIAJBJGpB7LjBACADKAIAIgMoAgAgAygCBBB6GiACQSBqIAQoAgAiAzYCACACIAIpAiQiBTcDGCABQQhqIAM2AgAgASAFNwIACyABKQIAIQUgAUKAgICAEDcCACACQRBqIgMgAUEIaiIBKAIANgIAIAFBADYCACACIAU3AwhBDEEEENIDIgFFBEBBBEEMENkDAAsgASACKQMINwIAIAFBCGogAygCADYCACAAQcy6wQA2AgQgACABNgIAIAJBMGokAAvdAQEDfyMAQRBrIgIkACACQQhqIgMgARCqAiACKAIIIQECQCACLQAMIgRBA0YNACACIAQ6AAwgAiABNgIIIANBm5nAAEEEIABB6ABqEPwBIgENACADQcGZwABBBCAAEIYCIgENACADIABBgAFqEIACIgENACADIABBjAFqEIQCIgENACADQY2bwABBCCAAQbIBahDrASIBDQAgA0GVm8AAQQUgAEGwAWoQhwIiAQ0AIANBpJnAAEEDIABB8ABqEIICIgENACACKAIIIAItAAwQrgIhAQsgAkEQaiQAIAEL5QEBBH8jAEEwayIEJAAgASgCiAEhBiAEIAM2AhggBCACNgIUIARBAjYCECAEQQhqIAEoAoABIAEoAoQBIAZBpLHAABCfAiAEIAQoAggiBTYCICAEIAUgBCgCDGo2AiRBACEFIARBIGoQzgIiB0GAgMQARiACIAdLciADIAdJckUEQCABIAZBAWo2AogBQQEhBQsCQCABLQB8RQRAIARBEGoQlQMMAQsgBEEoaiAEQRhqKQIANwMAIAQgBCkCEDcDICABIAYgBEEgaiAFEPEBCyAAIAE2AgQgACAFRTYCACAEQTBqJAALvQEBAX8jAEEwayICJAAgAkEoaiABEGsgAigCLCEBIAACfwJ/An8CfyACKAIoQQFxBEAgAkEgaiABEE0gAigCJCEBIAIoAiAMAQtBAAtBAXEEQCACQRhqIAEQUSACKAIcIQEgAigCGAwBC0EAC0EBcQRAIAJBEGogARBYIAIoAhQhASAC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AiAAQf//A00EQCABIAM6AAIgASACOgABIAEgBEHgAXI6AAAPCyABIAM6AAMgASACOgACIAEgBEE/cUGAf3I6AAEgASAAQRJ2QXByOgAADwsgASAAOgAAC5ABAQR/IAIhBANAIAAgA2ohBSABIANqIQYCQAJAAkAgBEEDTQRAQQEhACAEQQFLBH8gBS8AACAGLwAARw0CIAZBAmohBiAFQQJqIQUgAiADa0ECawUgBAtFDQIgBS0AACAGLQAARg8LIAUoAAAgBigAAEYNAgtBACEACyAADwsgA0EEaiEDIARBBGshBAwACwALpgEBA38jAEEQayICJAAgAkEIaiIDIAEQqgIgAigCCCEBAkAgAi0ADCIEQQNGDQAgAiAEOgAMIAIgATYCCCADQZuZwABBBCAAQRhqEPwBIgENACADQfubwABBBCAAEIgCIgENACADQaaawABBCCAAQQxqEIgCIgENACADQaSZwABBAyAAQSBqEIICIgENACACKAIIIAItAAwQrgIhAQsgAkEQaiQAIAELpgEBA38jAEEQayICJAAgAkEIaiIDIAEQqgIgAigCCCEBAkAgAi0ADCIEQQNGDQAgAiAEOgAMIAIgATYCCCADQZuZwABBBCAAQQxqEPwBIgENACADQZ+ZwABBBSAAEIgCIgENACADQcqbwABBByAAQSRqEIcCIgENACADQaSZwABBAyAAQRRqEIICIgENACACKAIIIAItAAwQrgIhAQsgAkEQaiQAIAELkwICBn8BfiMAQRBrIgMkACACIAEgAmoiAUsEQEEAQQAQmwMACyADQQRqIQQgACgCBCEIQQEhBkEEIQICQEEIIAEgACgCACIHQQF0IgUgASAFSxsiASABQQhNGyIFrSIJQiCIUEUEQEEAIQEMAQsgCaciAUH/////B0sEQEEAIQEMAQsCQAJAAn8gBwRAIAggB0EBIAEQrwMMAQsgAUUEQEEBIQIMAgsgAUEBENIDCyICDQAgBEEBNgIEDAELIAQgAjYCBEEAIQYLQQghAgsgAiAEaiABNgIAIAQgBjYCACADKAIEQQFGBEAgAygCCCADKAIMEJsDAAsgAygCCCEBIAAgBTYCACAAIAE2AgQgA0EQaiQAC48BAQJ/IwBBEGsiAyQAIAEoAgBBj4DAAEEBELEDIANBBDoACAJAIANBCGoQxAIiBARAIABB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BAsgA0EQaiQAIAQLZgEEfyAAKAIIIgIoAgAgACgCECIDIAAoAgwiBGoiBWsgAUkEQCACIAUgAUEBQQIQtwILIAEgBGohASADQQF0IgMEQCACKAIEIgIgAUEBdGogAiAEQQF0aiAD/AoAAAsgACABNgIMC+EOAwx/CX4BfAJAAkACQAJAAkACQAJAAkAgACgCAEEBaw4GAQIDBAUGAAsgACgCBCABEMwBDwsgAEEEaiABEM0BDwsgAEEEaiABEOEBDwsgAEEEaiECIwBBEGsiACQAIABBCGoiAyABEKoCIAAoAgghAQJAIAAtAAwiBUEDRg0AIAAgBToADCAAIAE2AgggA0GbmcAAQQQgAhD8ASIBDQAgA0GfmcAAQQUgAkEYahDrASIBDQAgA0GkmcAAQQMgAkEIahCCAiIBDQAgACgCCCAALQAMEK4CIQELDAMLIABBCGohCiMAQRBrIgAkACAAQQhqIgkgARCqAiAAKAIIIQECQCAALQAMIgJBA0YNACAAIAI6AAwgACABNgIIIAlBm5nAAEEEIAoQ/AEiAQ0AIApBCGohASMAQTBrIgUkAAJAIAlBn5nAAEEFEPMBIgINACAFQRhqIgggCSgCACIMELgDIAgQxAIiAg0AAn8gASsDACIXvUL///////////8Ag0L/////////9/8AWARAIwBBMGsiAyQAIAhBLToAACAXvSIPQv////////8HgyEOIAggD0I/iKdqIQECfwJAAkACQCAPQjSIQv8PgyIPUARAIA5QDQEgA0EgaiAOQs53QQEQoQEgAygCKCECIAMpAyAhDgNAIA5C//+D/qbe4RFVDQQgAkEBayECIA5CCn4hDgwACwALIA9Cswh9IQ8gDkKAgICAgICACIQhECAOUA0BIANBIGpBgIPBACAPpyIEQYWiE2xBFHUiAkEEdCIGaykDACIRQYiDwQAgBmspAwAgECAEQeLWwABqLQAAIgRBP3GthhCYAiADKQMoIhJCgICAgICAgICAf1ENASADIAMpAyAiE0Kas+bMmbPmzBkQ7QEgEyADKQMIQnZ+IhR8QjyGIBJCBIiEIhUgEUEFIARrQT9xrYgiEVENASARIBV8IhZCgYCAgICAgIDgAHxCAlQNAUIKIBR9QgAgFH0gEkI/iCATfCARIBVWGyAWQoCAgICAgICAoH9WGyEODAILIAFBMDoAAiABQbDcADsAACABQQNqDAILIANBEGogECAPIA5CAFIQoQEgAygCGCECIAMpAxAhDgsgASAOQoDC1y+AIhCnIgdBgMLXL24iC0EwajoAASADIAJBEEEPIA5C//+D/qbe4RFVIg0baiIENgIgIA0gAUEBaiIGaiICIAcgC0GAwtcvbGutENkBIg9CsODAgYOGjJgwfDcAACAOIBBCgMLXL359Ig5QRQRAIAIgDhDZASIPQrDgwIGDhoyYMHw3AAggAkEIaiECCyACQcYAIA9CAYZCAYR5p2tBA3ZqIAZrIQIgA0EgaigCACIHQYCswQAoAgBOBH9BhKzBACgCACILIAdOIAcgC0hBiKzBAC0AAEUbBUEACwRAAkAgBCACQQFrSARAIARBAE4NASABQQEgBGsiBGohByACBEAgByAGIAL8CgAACyAEBEAgAUEwIAT8CwALIAFBLjoAASACIAdqDAMLIAIEQCABIAYgAvwKAAALIARBA2oiBiACayIHBEAgASACakEwIAf8CwALIAEgBGpBAWpBLjoAACABIAZqDAILIARBAWoiBARAIAEgBiAE/AoAAAsgASAEakEuOgAAIAEgAmpBAWoMAQsgAS0AASEGIAFBLjoAASABIAY6AAAgASACaiACQQFLaiICIAQgBEEfdSIBcyABayIBQQlKaiIGIAFB+yhsQRN2IgdBMGo6AAEgBkEBaiABQeMASmoiBiAHQbh+bCABQQF0akGMrMEAai8BADsAACACQeXWAEHl2gAgBEEAThs7AAAgBkECagshASADQTBqJAAgBUEIaiICIAEgCGs2AgQgAiAINgIAIAwoAgAgBSgCCCAFKAIMELEDIAVBBDoAECAFQRBqEMQCDAELIAVBGGoiASAMELcDIAEQxAILIgINACAFQQQ6ABggBUEYahDEAiECCyAFQTBqJAAgAiIBDQAgCUGkmcAAQQMgCkEQahCCAiIBDQAgACgCCCAALQAMEK4CIQELDAILIABBBGohAiMAQRBrIgAkACAAQQhqIgMgARCqAiAAKAIIIQECQCAALQAMIgVBA0YNACAAIAU6AAwgACABNgIIIANBm5nAAEEEIAIQ/AEiAQ0AIANBpJnAAEEDIAJBCGoQggIiAQ0AIAAoAgggAC0ADBCuAiEBCwwBCyAAQQRqIQUjAEEQayICJAAgAkEIaiID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fyACKAIIQQFxBEAgAiABQYKBwABBARDSASACKAIEIQEgAigCAAwBC0EACzYCACAAIAE2AgQgAkEQaiQAC2QBAX8jAEEQayIEJAACQCAAIAEgAhDzASICDQAgBEEIaiIBIAAoAgAiABC4AyABEMQCIgINACAAIAMoAgAgAygCBBDaAiICDQAgBEEEOgAIIARBCGoQxAIhAgsgBEEQaiQAIAILugQBBn8jAEEQayIGJAAgASgCBCICIAEoAghPBEAgBkEIaiABKAIAIAIjAEEwayIDJAAgASICKAIEIgQEfyADQQA6ACwgA0EANgIkIAMgAjYCKCADIAIoAgAiBTYCHCADIAQgBWo2AiAgAigCCCEFAn8DQCADQRBqIANBHGoiBBC2AUGAgMQAIAMoAhQiB0GAgMQARg0BGiADKAIQIgIgBU8NAAsgA0EBOgAsQQogB0EKRg0AGiADQQhqIQUjAEEQayICJAACQANAIAJBCGogBBC2ASACKAIMIgdBgIDEAEYNASAHQQpHDQALIAIoAgghBAsgBSAHNgIEIAUgBDYCACACQRBqJAAgAygCCCECIAMoAgwLIQQgAkEBakEAIARBgIDEAEcbBUEACyECIANBMGokACACIwBBMGsiAiQAAkAgASgCBCIDRQRAQQAhAwwBCyABKAIIIgQgA0EBa0YNACACQQA6ACwgAkEANgIkIAIgATYCKCACIAEoAgAiATYCHCACIAEgA2o2AiADQCACQRBqIAJBHGoQ8AEgAigCFCIBQYCAxABGDQEgAigCECIFIARJDQALIAJBAToALCABQQpHBH8DQCACQQhqIAJBHGoQ8AEgAigCDCIBQYCAxABGDQIgAUEKRw0ACyACKAIIBSAFC0EBaiEDCyACQTBqJAAgA0HEscAAEOgBIAYoAgwhASAAIAYoAgg2AgAgACABNgIEIAZBEGokAA8LQdSxwABBLUHsscAAEMsCAAvDBgEHfyMAQRBrIgMkACADQQRqIQUjAEEQayIEJAAgASIGKAIAIQEgBigCBCEHAkACQANAIAEgB0cEQCAGIAFBAWoiCDYCACAEQQRqIQICQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCABLQAAIgFBJWsOJwwBAQEBDQ4PEBEBAQEB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aiITIAAQqgIgBygCCCEAAkAgBy0ADCIBQQNGDQAgByABOgAMIAcgADYCCCATQZuZwABBBCASQQxqEPwBIgANACMAQRBrIhckAAJAIBNB15rAAEEFEPMBIgANACAXQQhqIh0iACATKAIAIgEQuAMgABDEAiIADQAjAEEQayIKJAAgEigCBCEQIApBCGogASASKAIIIgAQ2AEgCigCCCEBAkAgCi0ADCIYQQNGBEAgASEADAELIABBuAFsIRkgGEEBRiEaA0AgGQRAIApBCGoiACABIBoQjwMgABDEAiIADQICfyAQKAIAQQdHBEAgECABELgBDAELIBBBBGogARDiAQsiAA0CIBBBuAFqIRAgCkEEOgAIIBlBuAFrIRlBACEaQQIhGCAKQQhqEMQCIgBFDQEMAgsLIAEgGBC4AiEACyAKQRBqJAAgAA0AIBdBBDoACCAdEMQCIQALIBdBEGokACAADQAgE0GkmcAAQQMgEkEUahCCAiIADQAgBygCCCAHLQAMEK4CIQALIAdBEGokACAACyIBDQAgFkEEOgAIIBwQxAIhAQsgFkEQaiQAIAENACANQaSZwABBAyAFQcABahCCAiIBDQAgBigCCCAGLQAMEK4CIQELIAZBEGokACABIgANAiAFQeABaiEFIAlBBDoACCAMQeABayEMQQAhBkECIQEgCUEIahDEAiIARQ0BDAILCyADIAEQuAIhAAsgCUEQaiQAIAANACAVQQQ6AAggGxDEAiEACyAVQRBqJAAgAA0AIAQgCEGEAWoQgwIiAA0AIAhBkAFqIQEjAEEQayIJJAACQCAEQe2cwABBCRDzASIADQAgCUEIaiIKIgAgBCgCACIDELgDIAAQxAIiAA0AIwBBEGsiByQAIAEoAgQhBSAHQQhqIAMgASgCCCIAENgBIAcoAgghAQJAIActAAwiBkEDRgRAIAEhAAwBCyAAQbABbCEDIAZBAUYhDANAIAMEQCAHQQhqIg0iACABIAwQjwMgABDEAiIADQIgBSABEMwBIgANAiAFQbABaiEFIAdBBDoACCADQbABayEDQQAhDEECIQYgDRDEAiIARQ0BDAILCyABIAYQuAIhAAsgB0EQaiQAIAANACAJQQQ6AAggChDEAiEACyAJQRBqJAAgAA0AIAhBnAFqIQEjAEEQayIJJAACQCAEQfacwABBCBDzASIA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IAAgAUEKRjoAACADIAEgAigCEBEBAAuEAQEEfyAAKAIIIQMgACgCICIEIAAoAhhGBEAjAEEQayIBJAAgAUEIaiAAQRhqIgIgAigCAEEBQQRBCBDRASABKAIIIgJBgYCAgHhHBEAgAiABKAIMEJsDAAsgAUEQaiQACyAAKAIcIARBA3RqIgEgAzYCBCABIAM2AgAgACAEQQFqNgIgC0IBAX8jAEEQayICJAAgAUH/AXEEfyAAKAIAQYCAwABBARCxAyACQQQ6AAggAkEIahDEAgVBAAshASACQRBqJAAgAQuAAwEHfyMAQRBrIgUkACAFQQRqIQMCQCABQSBqIgEoAgBBgICAgHhGBEAgA0GAgICAeDYCACADIAEpAgg3AgQMAQsgASgCBCEHIAEoAgghBCABKAIQIQYgASgCFCECIwBBMGsiASQAAkAgAgRAIAQEQCABQQRqIgggBiACIAFBL2oiBhCeASABQRBqIgIgByAEIAYQngEgAUEENgIoIAFBBDYCICABIAI2AiQgASAINgIcIANBhIXAACABQRxqEP8CIAIQyAMgCBDIAwwCCyABQRxqIgQgBiACIAFBL2oQngEgAUEENgIUIAEgBDYCECADQfaEwAAgAUEQahD/AiAEEMgDDAELIAQEQCABQRxqIgIgByAEIAFBL2oQngEgAUEENgIUIAEgAjYCECADQa2FwAAgAUEQahD/AiACEMgDDAELIANBpK7AAEEVEJsCCyABQTBqJAALIAAgBSgCCCAFKAIMEJsCIAUoAgRBgICAgHhHBEAgAxDIAwsgBUEQaiQAC0UBAX8jAEEQayICJAAgAkEEaiAAQQQgARC0AgJAIAIoAggiAEUNACACKAIMIgFFDQAgAigCBCABIAAQugMLIAJBEGokAAs/ACABKAIABEAgACABKQIANwIAIABBEGogAUEQaigCADYCACAAQQhqIAFBCGopAgA3AgAPCyACIAMgBBDMAgALRQEBfyMAQRBrIgEkACABQQhqIAAgACgCAEEBQQRBFBDRASABKAIIIgBBgYCAgHhHBEAgACABKAIMEJsDAAsgAUEQaiQAC4wCAgV/AX4jAEEQayIFJAACQCABQQJJDQAgAUEVTwRAIAVBD2ohBiMAQYAgayICJAACQEGApOgDIAEgAUGApOgDTxsiAyABIAFBAXZrIgQgAyAESxsi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BjYCBCABKAKIASEGIAUgCzYCnAEgBSAGNgKoASAFQQA2AqABIAUgBS0AjwE6AJkBIAVBAToAmAEgByAFQZgBahCTAgwCCyAFQcABaiAFQZgBahC5AgwCC0HQrcAAQShB+K3AABCdAwALIAEtAHwEQCAFQcABaiAFQbABahC5AgtBAAwCCyABLQCQAUECRw0AIAEtAJEBRQ0AIAsgASgCFEsNACABIAs2AhQLQQELIQYgACABNgIEIAAgBjYCACAFQdABaiQAC9QBAQN/IwBBMGsiAyQAIANBGGogARDbAkEBIQQgAygCHCEBAkAgAygCGEEBcQ0AIANBKGogAUGIAWooAgA2AgAgAyABKQKAATcDICABKAIUIQUgA0EQaiABIAJBARDSASADKAIUIQEgAygCEEEBcQR/QQEFIANBCGogARA9IAMoAgwhASADKAIICyIEQQFxRQ0AIAEgAykDIDcCgAEgAUGIAWogA0EoaigCADYCACAFIAEoAhRLDQAgASAFNgIUCyAAIAE2AgQgACAENgIAIANBMGokAAuOAQEDfyMAQRBrIgMkACADQQhqIgQgARCqAiADKAIIIQECQCADLQAMIgVBA0YNACADIAU6AAwgAyABNgIIIARBm5nAAEEEIABBDGoQ/AEiAQ0AIAQgAkEFIAAQiAIiAQ0AIARBpJnAAEEDIABBFGoQggIiAQ0AIAMoAgggAy0ADBCuAiEBCyADQRBqJAAgAQtyAQN/IAAoAggiBSAAKAIARgRAIwBBEGsiBCQAIARBCGogACAAKAIAQQEgAyACENEBIAQoAggiBkGBgICAeEcEQCAGIAQoAgwQmwMACyAEQRBqJAALIAAoAgQgBSACbGogASAC/AoAACAAIAVBAWo2AggLOgEBfyMAQRBrIgQkACAEQQhqIAEgAyACELkBIAQoAgwhASAAIAQoAgg2AgAgACABNgIEIARBEGokAAs5AgF/AX4jAEEQayIEJAAgBEEIaiADIAIgARCcAiAEKQMIIQUgAEEANgIIIAAgBTcCACAEQRBqJAALqwcBB38jAEGQAWsiAyQAIANB2ABqIAEQ2wJBASEEIAMoAlwhAQJAIAMoAlhBAXENACADQegAaiABQYgBaigCADYCACADIAEpAoABNwNgIAEoAhQhByADQdAAaiABENsCIAMoAlQhAQJAIAMoAlBBAXENACADQfgAaiABQYgBaigCADYCACADIAEpAoABNwNwIAEoAhQhBSADQcgAaiABENsCIAMoAkwhAQJ/AkAgAygCSEEBcUUEQCABIAEtAJABIgZBAUc6AJABIANBiAFqIAFBiAFqKAIANgIAIAMgASkCgAE3A4ABIAFBMGoQrQIgA0FAayABIAJBARDSASADKAJEIQECfyADKAJAQQFxBEAgA0E4aiABQaWAwABBAhDSASADKAI8IQEgAygCOAwBC0EACyEEIAEgAykDgAE3AoABIAEgBjoAkAEgAUGIAWogA0GIAWooAgA2AgAgAUEwahDOASAEQQFxDQELQQEMAQsgA0EwaiABEMYBIAMoAjQhASADKAIwCyIEQQFxRQ0AIAEgAykDcDcCgAEgAUGIAWogA0H4AGooAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsCf0EBIARBAXENABogA0EoaiABENsCIAMoAiwhAUEBIAMoAihBAXENABogA0H4AGohBQNAIANBIGogARDbAiADKAIkIQECQCADKAIgQQFxBEBBASEEDAELIAUgAUGIAWooAgA2AgAgAyABKQKAATcDcCABKAIUIQYgA0EYaiABENsCIAMoAhwhAQJ/AkAgAygCGEEBcUUEQCABIAEtAJABIghBAUc6AJABIANBiAFqIgkgAUGIAWooAgA2AgAgAyABKQKAATcDgAEgAUEwahCtAiADQRBqIAEgAkEBENIBIAMoAhQhAQJ/IAMoAhBBAXEEQCADQQhqIAFBpYDAAEECENIBIAMoAgwhASADKAIIDAELQQALIQQgASADKQOAATcCgAEgASAIOgCQASABQYgBaiAJKAIANgIAIAFBMGoQzgEgBEEBcQ0BC0EBDAELIAMgARDGASADKAIEIQEgAygCAAsiBEEBcUUNACABIAMpA3A3AoABIAFBiAFqIAUoAgA2AgAgBiABKAIUSw0AIAEgBjYCFAsgBEEBcUUNAAtBAAsiBEEBcUUNACABIAMpA2A3AoABIAFBiAFqIANB6ABqKAIANgIAIAcgASgCFEsNACABIAc2AhQLIAAgATYCBCAAIAQ2AgAgA0GQAWokAAurEwESfyMAQeACayIDJAAgAyACOgDfASADQdABaiABENsCQQEhBCADKALUASEBAkAgAygC0AFBAXENACABKAKIASIIIAEoAowBIgRGBEAgASgCLCEQIAEoAiAhDAsgASgCFCENAkAgAS0AkAFBAkcNACABLQCRAUUNACADIAg2AvABIANBADYC7AEgA0EAOgDoASABQQxqIANB6AFqEJMCIAEoAowBIQQLIAQgCEYEQCABKAIsIAEoAiBqIQ4LIAMgASgCXDYC4AEgAyABKAJ4NgLkASADQcgBaiABENsCIAMoAswBIQECQCADKALIAUEBcQRAQQEhBAwBCyADQYgCaiABQYgBaigCADYCACADIAEpAoABNwOAAiABKAIUIREgA0HAAWogARDnASADKALEASEBAkAgAygCwAFBAXEEQEEBIQQMAQsgA0G4AWogARDbAkEBIQQgAygCvAEhASADKAK4AUEBcQ0AIANBmAJqIgYgAUGIAWooAgA2AgAgAyABKQKAATcDkAIgASgCFCEFIANBsAFqIAEQ2wIgAygCtAEhASADKAKwAUEBcUUEQCADQagBaiABENsCIAMoAqwBIQECQCADKAKoAUEBcQRAQQEhBQwBCyADQbgCaiABQYgBaigCADYCACADIAEpAoABNwOwAiABKAIUIQYgA0GgAWogARDbAiADKAKkASEBAkAgAygCoAFBAXEEQAwBCyADQcgCaiABQYgBaigCADYCACADIAEpAoABNwPAAiABKAIUIQkgA0GYAWogARDHASADKAKcASEBAkAgAygCmAFBAXEEQAwBCyADQZABaiABENsCIAMoApQBIQEgAygCkAFBAXENACADQdgCaiIHIAFBiAFqKAIANgIAIAMgASkCgAE3A9ACIAEoAhQhBSADQYgBaiABENsCIAMoAowBIQEgAygCiAFBAXFFBEAgA0GAAWogARDHAUEAIQQgAygChAEhASADKAKAAUEBcQ0BIANB+ABqIAEQ2wIgAygCfCEBIAMoAnhBAXENASADQfABaiEHA0AgA0HwAGogARDbAiADKAJ0IQECQCADKAJwQQFxBEBBASEFDAELIAcgAUGIAWooAgA2AgAgAyABKQKAATcD6AEgASgCFCEKIANB6ABqIAEQxwEgAygCbCEBIAMoAmgiBUEBcUUNACABIAMpA+gBNwKAASABQYgBaiAHKAIANgIAIAogASgCFEsNACABIAo2AhQLIAVBAXFFDQALDAELIAEgAykD0AI3AoABIAFBiAFqIAcoAgA2AgAgBSABKAIUSw0AIAEgBTYCFAsgBEEBcUUNACABIAMpA8ACNwKAASABQYgBaiADQcgCaigCADYCACAJIAEoAhRLDQAgASAJNgIUCyAEQQFxBH9BAQUgA0HgAGogARCKAiADKAJkIQEgAygCYAsiBUEBcUUNACABIAMpA7ACNwKAASABQYgBaiADQbgCaigCADYCACAGIAEoAhRLDQAgASAGNgIUC0EAIQQgBUEBcQ0BIANB2ABqIAEQ2wIgAygCXCEBIAMoAlhBAXENASADQagCaiEGA0AgA0HQAGogARDbAiADKAJUIQECQCADKAJQQQFxBEBBASEFDAELIAYgAUGIAWooAgA2AgAgAyABKQKAATcDoAIgASgCFCEJIANByABqIAEQ2wIgAygCTCEBAkAgAygCSEEBcQRAQQEhBQwBCyADQbgCaiISIAFBiAFqKAIANgIAIAMgASkCgAE3A7ACIAEoAhQhByADQUBrIAEQ2wJBASEFIAMoAkQhAQJAIAMoAkBBAXENACADQcgCaiITIAFBiAFqKAIANgIAIAMgASkCgAE3A8ACIAEoAhQhCiADQThqIAEQxwEgAygCPCEBAkAgAygCOEEBcQ0AIANBMGogARDbAiADKAI0IQEgAygCMEEBcQ0AIANB2AJqIg8gAUGIAWooAgA2AgAgAyABKQKAATcD0AIgASgCFCELIANBKGogARDbAiADKAIsIQEgAygCKEEBcUUEQCADQSBqIAEQxwFBACEFIAMoAiQhASADKAIgQQFxDQEgA0EYaiABENsCIAMoAhwhASADKAIYQQFxDQEDQCADQRBqIAEQ2wIgAygCFCEBAkAgAygCEEEBcQRAQQEhCwwBCyADQfABaiIUIAFBiAFqKAIANgIAIAMgASkCgAE3A+gBIAEoAhQhDyADQQhqIAEQxwEgAygCDCEBIAMoAggiC0EBcUUNACABIAMpA+gBNwKAASABQYgBaiAUKAIANgIAIA8gASgCFEsNACABIA82AhQLIAtBAXFFDQALDAELIAEgAykD0AI3AoABIAFBiAFqIA8oAgA2AgAgCyABKAIUSw0AIAEgCzYCFAsgBUEBcUUNACABIAMpA8ACNwKAASABQYgBaiATKAIANgIAIAogASgCFEsNACABIAo2AhQLIAVBAXEEf0EBBSADIAEQigIgAygCBCEBIAMoAgAL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wAAScmFuZ2Ugc3RhcnQgaW5kZXggwCIgb3V0IG9mIHJhbmdlIGZvciBzbGljZSBvZiBsZW5ndGggwAAQcmFuZ2UgZW5kIGluZGV4IMAiIG91dCBvZiByYW5nZSBmb3Igc2xpY2Ugb2YgbGVuZ3RoIMAADSwgdW5leHBlY3RlZCDAAAt1bmV4cGVjdGVkIMAAC3VuZXhwZWN0ZWQgwAs7IGV4cGVjdGVkIMAACywgZXhwZWN0ZWQgwAAJZXhwZWN0ZWQgwAAQYXNzZXJ0aW9uIGBsZWZ0IMAXIHJpZ2h0YCBmYWlsZWQKICBsZWZ0OiDACQogcmlnaHQ6IMAAEGFzc2VydGlvbiBgbGVmdCDAECByaWdodGAgZmFpbGVkOiDACQogIGxlZnQ6IMAJCiByaWdodDogwAAVU2VyaWFsaXphdGlvbiBlcnJvcjogwAANUGFyc2UgZXJyb3I6IMAAGVVuZXhwZWN0ZWQgZWxlbWVudCB0eXBlOiDAAMACOiDAAC9ob21lL252cC8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL21lbWNoci0yLjguMC9zcmMvYXJjaC9hbGwvdHdvd2F5LnJzAC9ydXN0Yy80YTRlZjQ5M2UzYTE0ODhjNmUzMjE1NzAyMzgwODRiMzg5NDhmNmRiL2xpYnJhcnkvY29yZS9zcmMvc2xpY2Uvc29ydC9zaGFyZWQvc21hbGxzb3J0LnJzAC9ydXN0Yy80YTRlZjQ5M2UzYTE0ODhjNmUzMjE1NzAyMzgwODRiMzg5NDhmNmRiL2xpYnJhcnkvY29yZS9zcmMvc2xpY2Uvc29ydC9zdGFibGUvcXVpY2tzb3J0LnJzAC9ydXN0Yy80YTRlZjQ5M2UzYTE0ODhjNmUzMjE1NzAyMzgwODRiMzg5NDhmNmRiL2xpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5ycwBzcmMvZXJyb3JzLnJzAC9ob21lL252cC8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Blc3QtMi44LjYvc3JjL2l0ZXJhdG9ycy9wYWlycy5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2FsbG9jL3NyYy9zdHIucnMAL2hvbWUvbnZwLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcGVzdC0yLjguNi9zcmMvZXJyb3IucnMAL2hvbWUvbnZwLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcGVzdC0yLjguNi9zcmMvaXRlcmF0b3JzL3BhaXIucnMAL2hvbWUvbnZwLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvbWVtY2hyLTIuOC4wL3NyYy9tZW1tZW0vc2VhcmNoZXIucnMAc3JjL2J1aWxkZXIucnMAL3J1c3RjLzRhNGVmNDkzZTNhMTQ4OGM2ZTMyMTU3MDIzODA4NGIzODk0OGY2ZGIvbGlicmFyeS9jb3JlL3NyYy9udW0vZGVjMmZsdC9kZWNpbWFsX3NlcS5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2NvcmUvc3JjL3N0ci9wYXR0ZXJuLnJzAC9ob21lL252cC8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Blc3QtMi44LjYvc3JjL3Bvc2l0aW9uLnJzAC9ydXN0Yy80YTRlZjQ5M2UzYTE0ODhjNmUzMjE1NzAyMzgwODRiMzg5NDhmNmRiL2xpYnJhcnkvY29yZS9zcmMvZm10L251bS5ycwAvaG9tZS9udnAvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi93YXNtLWJpbmRnZW4tMC4yLjExOC9zcmMvZXh0ZXJucmVmLnJzAC9ob21lL252cC8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Blc3QtMi44LjYvc3JjL3BhcnNlcl9zdGF0ZS5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2NvcmUvc3JjL251bS9kZWMyZmx0L3BhcnNlLnJzAC9ydXN0Yy80YTRlZjQ5M2UzYTE0ODhjNmUzMjE1NzAyMzgwODRiMzg5NDhmNmRiL2xpYnJhcnkvY29yZS9zcmMvdW5pY29kZS9wcmludGFibGUucnMAL3J1c3RjLzRhNGVmNDkzZTNhMTQ4OGM2ZTMyMTU3MDIzODA4NGIzODk0OGY2ZGIvbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnMAL2hvbWUvbnZwLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvbWVtY2hyLTIuOC4wL3NyYy9hcmNoL2FsbC9wYWNrZWRwYWlyL21vZC5ycwAvaG9tZS9udnAvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9tZW1jaHItMi44LjAvc3JjL2FyY2gvYWxsL21vZC5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2NvcmUvc3JjL3NsaWNlL21vZC5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjL21vZC5ycwAvcnVzdGMvNGE0ZWY0OTNlM2ExNDg4YzZlMzIxNTcwMjM4MDg0YjM4OTQ4ZjZkYi9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvbW9kLnJzAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjExL3NyYy9kbG1hbGxvYy5ycwAvaG9tZS9udnAvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9pdG9hLTEuMC4xOC9zcmMvbGliLnJzAMALUGFyc2UgZXJyb3IAwAFeAMABOgAmY29weV9mcm9tX3NsaWNlOiBzb3VyY2Ugc2xpY2UgbGVuZ3RoICjAKykgZG9lcyBub3QgbWF0Y2ggZGVzdGluYXRpb24gc2xpY2UgbGVuZ3RoICjAASkAwAsgKG9zIGVycm9yIMABKQADaW4gwAI6IABOdW1iZXJMaXRlcmFsdHlwZXZhbHVlbG9jU3RyaW5nTGl0ZXJhbFN1YkV4cHJlc3Npb25wYXRocGFyYW1zaGFzaEJsb2NrU3RhdGVtZW50cHJvZ3JhbWludmVyc2VvcGVuU3RyaXBpbnZlcnNlU3RyaXBjbG9zZVN0cmlwQm9vbGVhbkxpdGVyYWxQYXRoRXhwcmVzc2lvbm9yaWdpbmFsaGVhZHRhaWxzdGFydGVuZGxpbmVjb2x1bW5Db25jYXRTdGF0ZW1lbnRwYXJ0c0NvbW1lbnRTdGF0ZW1lbnRVbmRlZmluZWRMaXRlcmFsTXVzdGFjaGVTdGF0ZW1lbnR0cnVzdGluZ3N0cmlwRWxlbWVudE1vZGlmaWVyU3RhdGVtZW50TXVzdGFjaGVDb21tZW50U3RhdGVtZW50X19zdHJpcEhhc2hwYWlyc0Jsb2NrYm9keWJsb2NrUGFyYW1zY2hhaW5lZEF0SGVhZG5hbWVWYXJIZWFkQXR0ck5vZGVIYXNoUGFpcmtleVRlbXBsYXRlVGV4dE5vZGVjaGFyc1RoaXNIZWFkbWVzc2FnZWNvbnRleHRvcGVuY2xvc2VFbGVtZW50Tm9kZXNlbGZDbG9zaW5nYXR0cmlidXRlc21vZGlmaWVyc2NvbW1lbnRzY2hpbGRyZW5vcGVuVGFnY2xvc2VUYWd0YWdOdWxsTGl0ZXJhbHNvdXJjZV9saW5lcG9pbnRlcnN1Z2dlc3Rpb24A4QQQAA0AAABgAAAADgAAACwgAADhBBAADQAAAHoAAAAVAAAA4QQQAA0AAACCAAAAMQAAAEl0IGxvb2tzIGxpa2UgdGhpcyBtdXN0YWNoZSBleHByZXNzaW9uIGlzIG5vdCBjbG9zZWQuIEFkZCAnfX0nIHRvIGNsb3NlIGl0Lnt7fX1UaGlzIGVsZW1lbnQgdGFnIGFwcGVhcnMgdG8gYmUgdW5jbG9zZWQuIEFkZCAnPicgb3IgJy8+JyB0byBjbG9zZSBpdC5hc3xJZiB5b3Ugd2FudCB0byBkaXNwbGF5IGxpdGVyYWwgJ3t7JywgZXNjYXBlIGl0IHdpdGggJ1x7eycuQmxvY2sgcGFyYW1ldGVycyByZXF1aXJlIGEgc3BhY2UgYmV0d2VlbiAnYXMnIGFuZCAnfCcuIFVzZSAnYXMgfHBhcmFtfCcgaW5zdGVhZCBvZiAnYXN8cGFyYW18Jy5DaGVjayB0aGF0IHRoaXMgY2xvc2luZyB0YWcgbWF0Y2hlcyBpdHMgY29ycmVzcG9uZGluZyBvcGVuaW5nIHRhZy5FbXB0eSBtdXN0YWNoZSBleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQuIEFkZCBhbiBleHByZXNzaW9uIGxpa2Uge3tteVZhcmlhYmxlfX0uZW5kIG9mIGlucHV0dGVtcGxhdGV0ZXh0IGNvbnRlbnRtdXN0YWNoZSBleHByZXNzaW9uICd7ey4uLn19J3Jhdy90cmlwbGUgbXVzdGFjaGUgZXhwcmVzc2lvbiAne3t7Li4ufX19J2Jsb2NrIHN0YXRlbWVudCAne3sjLi4ufX0nYmxvY2sgb3BlbmluZyAne3sjLi4ufX0nYmxvY2sgY2xvc2luZyAne3svLi4ufX0nc3ViLWV4cHJlc3Npb24gJyguLi4pJ3BhdGggZXhwcmVzc2lvbnN0cmluZyBsaXRlcmFsbnVtYmVyIGxpdGVyYWxib29sZWFuIGxpdGVyYWwndW5kZWZpbmVkJydudWxsJ2hhc2ggcGFpciAna2V5PXZhbHVlJ2Jsb2NrIHBhcmFtZXRlcnMgJ2FzIHwuLi58J0hUTUwgZWxlbWVudHNlbGYtY2xvc2luZyBlbGVtZW50ICc8Li4uLz4ndm9pZCBlbGVtZW50b3BlbmluZyB0YWcgJzwuLi4+J2Nsb3NpbmcgdGFnICc8Ly4uLj4ndGFnIG5hbWUnLi4uYXR0cmlidXRlcydhdHRyaWJ1dGVhdHRyaWJ1dGUgbmFtZUhUTUwgY29tbWVudCAnPCEtLSAtLT4nbXVzdGFjaGUgY29tbWVudCAne3shLi4ufX0nUGFyYW0gbXVzdCBoYXZlIGlubmVyIGV4cHJlc3Npb24AALMGEAAOAAAARQEAACoAAACzBhAADgAAACsEAAAzAAAAswYQAA4AAAAzBAAADgAAAE11c3RhY2hlIGhhcyBpbm5lciBydWxlALMGEAAOAAAAewAAACIAAACzBhAADgAAAMsAAAAkAAAASGFzaFBhaXIgbXVzdCBoYXZlIGEgdmFsdWUAALMGEAAOAAAAjgIAABYAAABVbmV4cGVjdGVkIHJ1bGUgaW4gZXhwcmVzc2lv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RG91YmxlTXVzdGFjaGVUcmlwbGVNdXN0YWNoZU11c3RhY2hlQm9keVBhcmFtT3JIYXNoQmxvY2tCb2R5U3RhdGVtZW50QmxvY2tCb2R5VGVybWluYXRvckJsb2NrT3BlbkJsb2NrQ2xvc2VJbnZlcnNlQ2hhaW5JbnZlcnNlQmxvY2tJbnZlcnNlRWxzZUJsb2NrSW52ZXJzZVNpbXBsZUNhbGxFeHByZXNzaW9uRXhwcmVzc2lvblBhcmFtQmxvY2tQYXJhbXNMb29rYWhlYWRQYXRoSGVhZFNsYXNoZWRJZGVudGlmaWVyVGhpc1JlZkF0TmFtZVBhcmVudFJlZlNpbXBsZUlkZW50aWZpZXJQYXRoU2VnbWVudElkZW50Q2hhcnNJZGVudFN0YXJ0SWRlbnRDb250aW51ZUxpdGVyYWxEb3VibGVRdW90ZWRTdHJpbmdEb3VibGVRdW90ZWRDaGFyU2luZ2xlUXVvdGVkU3RyaW5nU2luZ2xlUXVvdGVkQ2hhckhhc2hLZXlIYXNoVmFsdWVTdHJpcE9wZW5TdHJpcENsb3NlQmxvY2tQYXJhbXNCbG9ja1BhcmFtTGlzdEJsb2NrUGFyYW1OYW1lRWxlbWVudE5vcm1hbEVsZW1lbnRTZWxmQ2xvc2luZ0VsZW1lbnRWb2lkRWxlbWVudFRhZ0VuZE9wZW5UYWdDbG9zZVRhZ0VsZW1lbnRDb250ZW50VGFnTmFtZU5hbWVkQmxvY2tUYWdBdFBhdGhUYWdOYW1lc3BhY2VkUGF0aFRhZ0RvdHRlZFBhdGhUYWdDb21wb25lbnRJZGVudEh0bWxJZGVudFRhZ05hbWVDb250aW51ZVZvaWRUYWdOYW1lU3BsYXR0cmlidXRlc0F0dHJNb2RpZmllckF0dHJXaXRoVmFsdWVBdHRyTmFtZU9ubHlBdHRyTmFtZUF0dHJOYW1lQ2hhckF0dHJWYWx1ZVBhcnRRdW90ZWRBdHRyVmFsdWVEb3VibGVRdW90ZWRBdHRyVmFsdWVTaW5nbGVRdW90ZWRBdHRyVmFsdWVBdHRyVGV4dE9yTXVzdGFjaGVfRFFBdHRyVGV4dE9yTXVzdGFjaGVfU1FBdHRyVGV4dF9EUUF0dHJUZXh0X1NRQXR0ck11c3RhY2hlVW5xdW90ZWRBdHRyVmFsdWVVbnF1b3RlZE11c3RhY2hlVW5xdW90ZWRUZXh0VmFsdWVIdG1sQ29tbWVudEh0bWxDb21tZW50Q29udGVudE11c3RhY2hlQ29tbWVudE11c3RhY2hlQ29tbWVudExvbmdNdXN0YWNoZUNvbW1lbnRMb25nQ29udGVudE11c3RhY2hlQ29tbWVudFNob3J0TXVzdGFjaGVDb21tZW50U2hvcnRDb250ZW50V1MAzgkQAGoAAADDAAAACQAAAM4JEABqAAAAvAAAACoAAADOCRAAagAAALkAAAAqAAAAzgkQAGoAAAA6AAAAFQAAAFAGEABiAAAAdAIAABsAAAAAAAAABAAAAAQAAAAQAAAAVHJ5RnJvbUludEVycm9yAB4HEABPAAAAaAQAACQAAAAeBxAATwAAAM0BAAA3AAAAeAAAAPAAAAAYAAAAGAAAAOgAAAAYAAAAAwAAAAgAAAARAAAACwAAAAgAAAAPAAAACAAAAA4AAAAOAAAADAAAAAsAAAAOAAAAEgAAABMAAAAJAAAACgAAAAwAAAAMAAAAEAAAAA0AAAAOAAAACgAAAAUAAAAUAAAADQAAAA4AAAAIAAAAEQAAAAcAAAAGAAAACQAAABAAAAALAAAACgAAAAoAAAANAAAABwAAAA0AAAASAAAAEAAAABIAAAAQAAAADQAAAA4AAAAQAAAACwAAAAgAAAAHAAAACQAAAAkAAAAKAAAACwAAAA4AAAAOAAAABwAAAA0AAAASAAAACwAAAAYAAAAHAAAACAAAAA4AAAAHAAAADQAAAAkAAAARAAAADQAAAA4AAAAJAAAADwAAAAsAAAANAAAADAAAAA0AAAAMAAAACAAAAAwAAAANAAAADwAAABUAAAAVAAAAFQAAABUAAAALAAAACwAAAAwAAAARAAAAEAAAABEAAAALAAAAEgAAAA8AAAATAAAAGgAAABQAAAAbAAAAAgAAAFQaEAAZDhAAVxoQAGgaEABzGhAAexoQAIoaEACSGhAAoBoQAK4aEAC6GhAAzwwQAMUaEADXGhAA6hoQAPMaEAD9GhAACRsQABUbEAAlGxAAMhsQAEAbEABKGxAATxsQALQMEAAYDRAAYxsQAGsbEAB8GxAAgxsQAIkbEACSGxAAohsQAK0bEAC3GxAAwRsQAM4bEACnDBAA1RsQAOcbEAD3GxAACRwQAI4MEAAKDRAAbA0QAJgOEAAODhAAGRwQACAcEAApHBAAMhwQADwcEABHHBAAVRwQAGMcEABqHBAAdxwQAIkcEACUHBAAmhwQAKEcEACpHBAAtxwQAL4cEADLHBAA1BwQAOUcEADyHBAAAB0QAAkdEAAYHRAAIx0QADAdEAA8HRAASR0QAFUdEABdHRAAaR0QAHYdEACFHRAAmh0QAK8dEADEHRAA2R0QAOQdEADvHRAA+x0QAAweEAAcHhAALR4QADgeEABKHhAAWR4QAGweEACGHhAAmh4QALUeEAB1dXV1dXV1dWJ0bnVmcnV1dXV1dXV1dXV1dXV1dXV1dQAAIgBBxMXAAAsBXABB6MbAAAvOBTAxMjM0NTY3ODlhYmNkZWZFT0Ygd2hpbGUgcGFyc2luZyBhIGxpc3RFT0Ygd2hpbGUgcGFyc2luZyBhbiBvYmplY3RFT0Ygd2hpbGUgcGFyc2luZyBhIHN0cmluZ0VPRiB3aGlsZSBwYXJzaW5nIGEgdmFsdWVleHBlY3RlZCBgOmBleHBlY3RlZCBgLGAgb3IgYF1gZXhwZWN0ZWQgYCxgIG9yIGB9YGV4cGVjdGVkIGlkZW50ZXhwZWN0ZWQgdmFsdWVleHBlY3RlZCBgImBpbnZhbGlkIGVzY2FwZWludmFsaWQgbnVtYmVybnVtYmVyIG91dCBvZiByYW5nZWludmFsaWQgdW5pY29kZSBjb2RlIHBvaW50Y29udHJvbCBjaGFyYWN0ZXIgKFx1MDAwMC1cdTAwMUYpIGZvdW5kIHdoaWxlIHBhcnNpbmcgYSBzdHJpbmdrZXkgbXVzdCBiZSBhIHN0cmluZ2ludmFsaWQgdmFsdWU6IGV4cGVjdGVkIGtleSB0byBiZSBhIG51bWJlciBpbiBxdW90ZXNmbG9hdCBrZXkgbXVzdCBiZSBmaW5pdGUgKGdvdCBOYU4gb3IgKy8taW5mKWxvbmUgbGVhZGluZyBzdXJyb2dhdGUgaW4gaGV4IGVzY2FwZXRyYWlsaW5nIGNvbW1hdHJhaWxpbmcgY2hhcmFjdGVyc3VuZXhwZWN0ZWQgZW5kIG9mIGhleCBlc2NhcGVyZWN1cnNpb24gbGltaXQgZXhjZWVkZWQeBxAATwAAAM0BAAA3AAAAYnJhbmNoIGlzIG5vdCBoaXQgZm9yIHR5cGVzIHRoYXQgY2Fubm90IGZpdCA5OTkgKHU4KWJyYW5jaCBpcyBub3QgaGl0IGZvciB0eXBlcyB0aGF0IGNhbm5vdCBmaXQgMUU0ICh1OCmwCxAAVQAAAEwBAAABAAAAKCkAQcDMwAAL7xEBAAAAEgAAADAwMDEwMjAzMDQwNTA2MDcwODA5MTAxMTEyMTMxNDE1MTYxNzE4MTkyMDIxMjIyMzI0MjUyNjI3MjgyOTMwMzEzMjMzMzQzNTM2MzczODM5NDA0MTQyNDM0NDQ1NDY0NzQ4NDk1MDUxNTI1MzU0NTU1NjU3NTg1OTYwNjE2MjYzNjQ2NTY2Njc2ODY5NzA3MTcyNzM3NDc1NzY3Nzc4Nzk4MDgxODI4Mzg0ODU4Njg3ODg4OTkwOTE5MjkzOTQ5NTk2OTc5ODk5AAAAAAQAAAAEAAAAEwAAAFRyeUZyb21JbnRFcnJvcgMDBAECAwECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwQBAgMBAgMBAgMEAQIDAQIDAQIDBAECAwECAwECAwECAwQBAgMB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AAAADAAAAAQAAAApAAAAKgAAACsAQdS9wQAL3EABAAAALAAAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90AACYBBAASAAAAIoCAAAOAAAAY2FwYWNpdHkgb3ZlcmZsb3cAAADnChAAUAAAABwAAAAFAAAAAHAABwAtAQEBAgECAQFICzAVEAFlBwIGAgIBBCMBHhtbCzoJCQEYBAEJAQMBBSsDOwkqGAEgNwEBAQQIBAEDBwoCHQE6AQEBAgQIAQkBCgIaAQICOQEEAgQCAgMDAR4CAwELAjkBBAUBAgQBFAIWBgEBOgEBAgEECAEHAwoCHgE7AQEBDAEJASgBAwE3AQEDBQMBBAcCCwIdAToBAgIBAQMDAQQHAgsCHAI5AgEBAgQIAQkBCgIdAUgBBAECAwEBCAFRAQIHDAhiAQIJCwdJAhsBAQEBATcOAQUBAgULASQJAWYEAQYBAgICGQIEAxAEDQECAgYBDwEAAwAEHAMdAh4CQAIBBwgBAgsJAS0DAQF1AiIBdgMEAgkBBgPbAgIBOgEBBwEBAQECCAYKAgEwLgIMFAQwCgQDJgkMAiAEAgY4AQECAwEBBTgIAgKYAwENAQcEAQYBAwLGQAABwyEAA40BYCAABmkCAAQBCiACUAIAAQMBBAEZAgUBlwIaEg0BJggZCwEBLAMwAQIEAgICASQBQwYCAgICDAEIAS8BMwEBAwICBQIBASoCCAHuAQIBBAEAAQAQEBAAAgAB4gGVBQADAQIFBCgDBAGlAgAEQQUAAk0GRgsxBHsBNg8pAQICCgMxBAICBwE9AyQFAQg+AQwCNAkBAQgEAgFfAwIEBgECAZ0BAwgVAjkCAQEBAQwBCQEOBwMFQwECBgEBAgEBAwQDAQEOAlUIAgMBARcBUQECBgEBAgEBAgEC6wECBAYCAQIbAlUIAgEBAmoBAQECCGUBAQECBAEFAAkBAvUBCgQEAZAEAgIEASAKKAYCBAgBCQYCAy4NAQLGAQEDAQHJBwEGAQFSFgIHAQIBAnoGAwEBAgEHAQFIAgMBAQEAAgsCNAUFAxcBAAEGDwAMAwMABTsHAAE/BFEBCwIAAgAuAhcABQMGCAgCBx4ElAMANwQyCAEOARYFAQ8ABwERAgcBAgEFZAGgBwABPQQABP4C8wECAQcCBQEAB20HAGCA8AAwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OQDIBxAASwAAAFcCAAAFAAAAMDEyMzQ1Njc4OWFiY2RlZjB4MDEyMzQ1Njc4OUFCQ0RFRiwKKCgKKSwAAAAAAAAADAAAAAQAAAAzAAAANAAAADUAAADCBhAAWwAAAFYAAAAnAAAAwgYQAFsAAACIAAAAEwAAAMIGEABbAAAAsAAAACAAAADCBhAAWwAAAMcAAAAlAAAAwgYQAFsAAAD0AAAAFQAAAMIGEABbAAAA/wAAABgAAAAAAAAIAQgDCAYQCRANEBIYFxgdGCQgKyAzIDwgRihQKFsoZzBzMIAwjjicOKs4uzjMQN1A70ACSRVJKUk+UVNRaVGAUZhZsFnJWeNh/WEYYjRqUGptaotqqnLJculyCnsre017cIOTg7eD3IMCjCiMT4x3lJ+UyJTynBwFHAUcBRwFBQIFAQIFBgIFAwECBQEFBgIFBwgBAgUDCQAGAgUBCQUDAQIFCQcGBQYCBQQICAIIAQIFAgQEAQQABgIFAQICAAcAAwECBQYBAAMFAQUGAgUDAAUBBwUHCAECBQEFAgUIBwgJAAYCBQcGAgkDCQQFAwECBQMIAQQGCQcCBgUGAgUBCQAHAwQIBgMCCAECBQkFAwYHBAMBBgQABgIFBAcGCAMHAQUIAgADAQIFAgMIBAEIBQcJAQABBQYCBQEBCQIACQIICQUFAAcIAQIFBQkGAAQGBAQHBwUDCQAGAgUCCQgAAgMCAgMIBwYJBQMBAgUBBAkAAQEGAQEJAwgEBwYFBgIFBwQFAAUIAAUJBgkCAwgCCAECBQMHAgUCCQACCQgEBgEJAQQABgIFAQgGAgYEBQEECQIDAAkFBwADAQIFCQMBAwICBQcEBgEFBAcIBQEFBgIFBAYFBgYBAggHAwAHBwMJAgUHCAECBQIDAggDAAYEAwYFAwgGCQYCCAkABgIFAQEGBAEFAwIBCAIGCQMECAEEBAUDAQIFBQgCAAcGBgAJAQMEBgcEAAcCAgYFBgIFAgkBAAMIAwAEBQYHAwMHAAMGAQMCCAECBQEEBQUBCQEFAgIIAwYGCAUBCAAGBgQABgIFBwIHBQkFBwYBBAEIAwQCBQkAAwMCAAMBAgUDBgMHCQcICAAHAAkBBwECCQUBBgYAAQUGAgUBCAEICQgJBAADBQQFCAUGBAcFCAMAAAcIAQIFCQAJBAkEBwABBwcCCQIIAgMHCQEFAAMJAAYCBQQFBAcEBwMFAAgIBgQGBAEBCAkFBwUBCQUDAQIFAgIHAwcDBgcFBAQDAgMCAAUJBAcIBwUJBwYFBgIFAQEDBggGCAMHBwIBBgEGAAIJBwMJAwcJCAgCCAECBQUGCAQDBAEICAYACAAIAAEECAYJBggJCQQBBAAGAgUCCAQCAQcACQQDAAQABAAABwQDBAgEBAkHAAcAAwECBQEEAgEACAUEBwEFAgACAAADBwEHBAICBAgFAwUBBQYCBQcBAAUEAgcDBQcGAAEAAAEIBQgHAQECBAIGBwUHCAECBQMFBQIHAQMGBwgIAAAFAAAJAgkDBQUGAgEDAwcICQAGAgUBBwcGAwUGCAMJBAAAAgUABAYEBgcHCAEABgYICQQFAwECBQgICAEHCAQBCQcAAAECBQIDAgMDCAkABQMDBAQHAgYFBgIFBAQEAAgJAgAJCAUAAAYCBgEGAQYJBAUCBgYHAgMGAwIIAQIFAgICAAQEBgAECQIFAAMBAwAIAAgEBwIGAwMDBgEIAQYEAAYCBQEBAQACAgMAAgQGAgUBBQYFBAAEAgMGAwEGBggACQAIAgADAQIFBQUFAQEBBQECAwECBQcIAgcAAgEBCAEFCAMEAAQFBAEAAQUGAgUCBwcFBQUHBQYBBQYCCAkBAwUBAAUJAAcJAQcAAgIHAAUABwgBAgUBAwgHBwcIBwgABwgBBAQFBgcFBQIJBQMJBQgFAQEDBQIFAwkABgIFBgkDCAgJAwkAAwkABwICCAMHBwYEBwYJBwkCBQUGBwYCBgkFAwECBQMEBgkEBAYJBQEJBQMGAQQBCAgIAgMIBAgJBgIHCAMIAQMEBwYFBgIFAQcDBAcCAwQHBQkHBggABwAJBAQB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"; diff --git a/packages/@glimmer/syntax/src/ast.rs b/packages/@glimmer/syntax/src/ast.rs new file mode 100644 index 00000000000..e36f69a353d --- /dev/null +++ b/packages/@glimmer/syntax/src/ast.rs @@ -0,0 +1,342 @@ +//! ASTv1-compatible node types for Glimmer templates. +//! +//! These types serialize to JSON that matches the shape expected by +//! @glimmer/syntax's ASTv1 types. The JS side converts plain location +//! objects into SourceSpan instances. + +use serde::Serialize; + +#[derive(Debug, Serialize, Clone)] +pub struct SourcePosition { + pub line: usize, + pub column: usize, +} + +#[derive(Debug, Serialize, Clone)] +pub struct SourceLocation { + pub start: SourcePosition, + pub end: SourcePosition, +} + +// -- Template & Block -------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct Template { + #[serde(rename = "type")] + pub node_type: &'static str, // "Template" + pub body: Vec, + #[serde(rename = "blockParams")] + pub block_params: Vec, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct Block { + #[serde(rename = "type")] + pub node_type: &'static str, // "Block" + pub body: Vec, + pub params: Vec, + #[serde(rename = "blockParams")] + pub block_params: Vec, + pub chained: bool, // always emitted + pub loc: SourceLocation, +} + +// -- Statements -------------------------------------------------------------- + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum Statement { + Mustache(MustacheStatement), + Block(BlockStatement), + Comment(CommentStatement), + MustacheComment(MustacheCommentStatement), + Element(ElementNode), + Text(TextNode), +} + +#[derive(Debug, Serialize)] +pub struct MustacheStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "MustacheStatement" + pub path: Expression, + pub params: Vec, + pub hash: Hash, + pub trusting: bool, + // `escaped` is deprecated — JS wrapper adds it as a non-enumerable getter + pub strip: StripFlags, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct BlockStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "BlockStatement" + pub path: Expression, + pub params: Vec, + pub hash: Hash, + pub program: Block, + pub inverse: Option, // always emitted (null when absent) + #[serde(rename = "openStrip")] + pub open_strip: StripFlags, + #[serde(rename = "inverseStrip")] + pub inverse_strip: StripFlags, + #[serde(rename = "closeStrip")] + pub close_strip: StripFlags, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct CommentStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "CommentStatement" + pub value: String, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct MustacheCommentStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "MustacheCommentStatement" + pub value: String, + // Transient: used by the JS wrapper for whitespace stripping, then deleted + #[serde(rename = "__strip")] + pub strip: StripFlags, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct TextNode { + #[serde(rename = "type")] + pub node_type: &'static str, // "TextNode" + pub chars: String, + pub loc: SourceLocation, +} + +// -- Element ----------------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct ElementNode { + #[serde(rename = "type")] + pub node_type: &'static str, // "ElementNode" + pub path: PathExpression, + #[serde(rename = "selfClosing")] + pub self_closing: bool, + pub attributes: Vec, + pub params: Vec, + pub modifiers: Vec, + pub comments: Vec, + pub children: Vec, + #[serde(rename = "openTag")] + pub open_tag: SourceLocation, + #[serde(rename = "closeTag")] + pub close_tag: Option, + pub tag: String, + #[serde(rename = "blockParams")] + pub block_params: Vec, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct ElementModifierStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "ElementModifierStatement" + pub path: Expression, + pub params: Vec, + pub hash: Hash, + pub loc: SourceLocation, +} + +// -- Attributes -------------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct AttrNode { + #[serde(rename = "type")] + pub node_type: &'static str, // "AttrNode" + pub name: String, + pub value: AttrValue, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum AttrValue { + Text(TextNode), + Mustache(MustacheStatement), + Concat(ConcatStatement), +} + +#[derive(Debug, Serialize)] +pub struct ConcatStatement { + #[serde(rename = "type")] + pub node_type: &'static str, // "ConcatStatement" + pub parts: Vec, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum AttrPart { + Text(TextNode), + Mustache(MustacheStatement), +} + +// -- Expressions ------------------------------------------------------------- + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum Expression { + SubExpression(Box), + Path(PathExpression), + StringLiteral(StringLiteral), + BooleanLiteral(BooleanLiteral), + NumberLiteral(NumberLiteral), + UndefinedLiteral(UndefinedLiteral), + NullLiteral(NullLiteral), +} + +#[derive(Debug, Serialize)] +pub struct SubExpression { + #[serde(rename = "type")] + pub node_type: &'static str, // "SubExpression" + pub path: Expression, + pub params: Vec, + pub hash: Hash, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct PathExpression { + #[serde(rename = "type")] + pub node_type: &'static str, // "PathExpression" + pub original: String, + pub head: PathHead, + pub tail: Vec, + // `parts` is deprecated on the ASTv1 type; the JS wrapper adds it + // as a non-enumerable getter to match the reference builder output + // so deepEqual-based tests don't see extra keys. + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum PathHead { + This(ThisHead), + At(AtHead), + Var(VarHead), +} + +#[derive(Debug, Serialize)] +pub struct ThisHead { + #[serde(rename = "type")] + pub node_type: &'static str, // "ThisHead" + pub original: &'static str, // "this" + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct AtHead { + #[serde(rename = "type")] + pub node_type: &'static str, // "AtHead" + pub name: String, + pub original: String, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize, Clone)] +pub struct VarHead { + #[serde(rename = "type")] + pub node_type: &'static str, // "VarHead" + pub name: String, + pub original: String, + pub loc: SourceLocation, +} + +// -- Literals ---------------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct StringLiteral { + #[serde(rename = "type")] + pub node_type: &'static str, // "StringLiteral" + pub value: String, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct BooleanLiteral { + #[serde(rename = "type")] + pub node_type: &'static str, // "BooleanLiteral" + pub value: bool, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct NumberLiteral { + #[serde(rename = "type")] + pub node_type: &'static str, // "NumberLiteral" + pub value: f64, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct UndefinedLiteral { + #[serde(rename = "type")] + pub node_type: &'static str, // "UndefinedLiteral" + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct NullLiteral { + #[serde(rename = "type")] + pub node_type: &'static str, // "NullLiteral" + // value and original are both `null` in ASTv1 + pub value: Option<()>, + pub loc: SourceLocation, +} + +// -- Hash -------------------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct Hash { + #[serde(rename = "type")] + pub node_type: &'static str, // "Hash" + pub pairs: Vec, + pub loc: SourceLocation, +} + +#[derive(Debug, Serialize)] +pub struct HashPair { + #[serde(rename = "type")] + pub node_type: &'static str, // "HashPair" + pub key: String, + pub value: Expression, + pub loc: SourceLocation, +} + +// -- Strip Flags ------------------------------------------------------------- + +#[derive(Debug, Serialize, Clone)] +pub struct StripFlags { + pub open: bool, + pub close: bool, +} + +// -- Parse Error ------------------------------------------------------------- + +#[derive(Debug, Serialize)] +pub struct ParseError { + pub message: String, + pub loc: SourceLocation, + /// Source context lines around the error for rich error display + pub context: Option, +} + +#[derive(Debug, Serialize)] +pub struct ErrorContext { + /// The source line where the error occurred + pub source_line: String, + /// A visual pointer showing where in the line the error is + pub pointer: String, + /// Suggestion for how to fix, if available + pub suggestion: Option, +} diff --git a/packages/@glimmer/syntax/src/builder.rs b/packages/@glimmer/syntax/src/builder.rs new file mode 100644 index 00000000000..973eaeaa92c --- /dev/null +++ b/packages/@glimmer/syntax/src/builder.rs @@ -0,0 +1,1574 @@ +//! Converts pest parse tree (Pairs) into ASTv1 node structures. + +use pest::iterators::{Pair, Pairs}; + +use crate::ast::*; +use crate::Rule; + +/// Compute (line, column) from a byte offset into the source string. +/// Lines are 1-based, columns are 0-based (matching Glimmer conventions). +fn offset_to_position(source: &str, offset: usize) -> SourcePosition { + let mut line = 1; + let mut col = 0; + + for (i, ch) in source.char_indices() { + if i >= offset { + break; + } + if ch == '\n' { + line += 1; + col = 0; + } else { + col += 1; + } + } + + SourcePosition { line, column: col } +} + +fn span_to_loc(source: &str, pair: &Pair<'_, Rule>) -> SourceLocation { + let span = pair.as_span(); + SourceLocation { + start: offset_to_position(source, span.start()), + end: offset_to_position(source, span.end()), + } +} + +fn default_strip() -> StripFlags { + StripFlags { + open: false, + close: false, + } +} + +pub fn build_template(pairs: Pairs<'_, Rule>, source: &str, _src_name: Option<&str>) -> Template { + let mut body = vec![]; + + for pair in pairs { + match pair.as_rule() { + Rule::Template => { + for inner in pair.into_inner() { + if let Some(stmt) = build_statement(inner, source) { + body.push(stmt); + } + } + } + _ => { + if let Some(stmt) = build_statement(pair, source) { + body.push(stmt); + } + } + } + } + + let loc = SourceLocation { + start: SourcePosition { line: 1, column: 0 }, + end: offset_to_position(source, source.len()), + }; + + Template { + node_type: "Template", + body, + block_params: vec![], + loc, + } +} + +fn build_statement(pair: Pair<'_, Rule>, source: &str) -> Option { + match pair.as_rule() { + Rule::TextContent => Some(Statement::Text(build_text_node(pair, source))), + Rule::EscapedMustache => Some(Statement::Text(build_escaped_mustache(pair, source))), + Rule::Mustache | Rule::DoubleMustache | Rule::TripleMustache => { + Some(Statement::Mustache(build_mustache(pair, source))) + } + Rule::BlockStatement => Some(Statement::Block(build_block_statement(pair, source))), + Rule::HtmlComment => Some(Statement::Comment(build_html_comment(pair, source))), + Rule::MustacheComment | Rule::MustacheCommentLong | Rule::MustacheCommentShort => { + Some(Statement::MustacheComment(build_mustache_comment( + pair, source, + ))) + } + Rule::Element | Rule::NormalElement | Rule::SelfClosingElement | Rule::VoidElement => { + Some(Statement::Element(build_element(pair, source))) + } + Rule::EOI => None, + _ => None, + } +} + +fn build_text_node(pair: Pair<'_, Rule>, source: &str) -> TextNode { + let loc = span_to_loc(source, &pair); + TextNode { + node_type: "TextNode", + chars: pair.as_str().to_string(), + loc, + } +} + +fn build_escaped_mustache(pair: Pair<'_, Rule>, source: &str) -> TextNode { + let loc = span_to_loc(source, &pair); + // \{{ becomes {{ + TextNode { + node_type: "TextNode", + chars: "{{".to_string(), + loc, + } +} + +fn build_mustache(pair: Pair<'_, Rule>, source: &str) -> MustacheStatement { + let loc = span_to_loc(source, &pair); + + // Unwrap outer Mustache wrapper if present + let actual = if pair.as_rule() == Rule::Mustache { + pair.into_inner().next().expect("Mustache has inner rule") + } else { + pair + }; + + let is_triple = matches!(actual.as_rule(), Rule::TripleMustache); + + let mut strip_open = false; + let mut strip_close = false; + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + // Navigate into the mustache: might be DoubleMustache/TripleMustache > MustacheBody + let inner = unwrap_to_body(actual); + + for child in inner { + match child.as_rule() { + Rule::StripOpen => strip_open = true, + Rule::StripClose => strip_close = true, + Rule::MustacheBody => { + let (p, pars, hp) = build_mustache_body(child, source); + path = Some(p); + params = pars; + hash_pairs = hp; + } + Rule::PathExpression => { + if path.is_none() { + path = Some(build_expression_from_path(child, source)); + } + } + Rule::SubExpression => { + if path.is_none() { + path = Some(build_sub_expression(child, source)); + } + } + Rule::Param => { + params.push(build_param(child, source)); + } + Rule::HashPair => { + hash_pairs.push(build_hash_pair(child, source)); + } + _ => { + // Recurse into wrapper rules + if let Some(inner_pair) = unwrap_single(child) { + match inner_pair.as_rule() { + Rule::MustacheBody => { + let (p, pars, hp) = build_mustache_body(inner_pair, source); + path = Some(p); + params = pars; + hash_pairs = hp; + } + _ => {} + } + } + } + } + } + + let path = path.unwrap_or_else(|| { + Expression::Path(PathExpression { + node_type: "PathExpression", + original: String::new(), + head: PathHead::Var(VarHead { + node_type: "VarHead", + name: String::new(), + original: String::new(), + loc: loc.clone(), + }), + tail: vec![], + + loc: loc.clone(), + }) + }); + + let hash_loc = if hash_pairs.is_empty() { + loc.clone() + } else { + SourceLocation { + start: hash_pairs.first().unwrap().loc.start.clone(), + end: hash_pairs.last().unwrap().loc.end.clone(), + } + }; + + MustacheStatement { + node_type: "MustacheStatement", + path, + params, + hash: Hash { + node_type: "Hash", + pairs: hash_pairs, + loc: hash_loc, + }, + trusting: is_triple, + strip: StripFlags { + open: strip_open, + close: strip_close, + }, + loc, + } +} + +fn build_mustache_body( + pair: Pair<'_, Rule>, + source: &str, +) -> (Expression, Vec, Vec) { + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::PathExpression => { + if path.is_none() { + path = Some(build_expression_from_path(child, source)); + } else { + params.push(build_expression_from_path(child, source)); + } + } + Rule::SubExpression => { + if path.is_none() { + path = Some(build_sub_expression(child, source)); + } else { + params.push(build_sub_expression(child, source)); + } + } + Rule::StringLiteral | Rule::DoubleQuotedString | Rule::SingleQuotedString => { + let expr = build_string_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::NumberLiteral => { + let expr = build_number_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::BooleanLiteral => { + let expr = build_boolean_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::UndefinedLiteral => { + let expr = build_undefined_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::NullLiteral => { + let expr = build_null_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::Param => { + params.push(build_param(child, source)); + } + Rule::HashPair => { + hash_pairs.push(build_hash_pair(child, source)); + } + _ => {} + } + } + + let path = path.unwrap_or_else(|| { + Expression::Path(PathExpression { + node_type: "PathExpression", + original: String::new(), + head: PathHead::Var(VarHead { + node_type: "VarHead", + name: String::new(), + original: String::new(), + loc: SourceLocation { + start: SourcePosition { line: 1, column: 0 }, + end: SourcePosition { line: 1, column: 0 }, + }, + }), + tail: vec![], + + loc: SourceLocation { + start: SourcePosition { line: 1, column: 0 }, + end: SourcePosition { line: 1, column: 0 }, + }, + }) + }); + + (path, params, hash_pairs) +} + +fn build_param(pair: Pair<'_, Rule>, source: &str) -> Expression { + let inner = pair.into_inner().next().expect("Param must have inner expression"); + build_expression(inner, source) +} + +fn build_expression(pair: Pair<'_, Rule>, source: &str) -> Expression { + match pair.as_rule() { + Rule::PathExpression => build_expression_from_path(pair, source), + Rule::SubExpression => build_sub_expression(pair, source), + Rule::StringLiteral | Rule::DoubleQuotedString | Rule::SingleQuotedString => { + build_string_literal(pair, source) + } + Rule::NumberLiteral => build_number_literal(pair, source), + Rule::BooleanLiteral => build_boolean_literal(pair, source), + Rule::UndefinedLiteral => build_undefined_literal(pair, source), + Rule::NullLiteral => build_null_literal(pair, source), + // For Param and other wrapper rules, descend + _ => { + if let Some(inner) = pair.into_inner().next() { + build_expression(inner, source) + } else { + panic!("Unexpected rule in expression position"); + } + } + } +} + +fn build_expression_from_path(pair: Pair<'_, Rule>, source: &str) -> Expression { + Expression::Path(build_path_expression(pair, source)) +} + +fn build_path_expression(pair: Pair<'_, Rule>, source: &str) -> PathExpression { + let loc = span_to_loc(source, &pair); + let original = pair.as_str().to_string(); + + let (head, tail) = parse_path_parts(&original, &loc); + + PathExpression { + node_type: "PathExpression", + original, + head, + tail, + loc, + } +} + +fn parse_path_parts(original: &str, loc: &SourceLocation) -> (PathHead, Vec) { + let segments: Vec<&str> = original.split('.').collect(); + + if segments.is_empty() { + return ( + PathHead::Var(VarHead { + node_type: "VarHead", + name: String::new(), + original: String::new(), + loc: loc.clone(), + }), + vec![], + ); + } + + let first = segments[0]; + let tail: Vec = segments[1..].iter().map(|s| s.to_string()).collect(); + + // Calculate head location (just the first segment) + let head_loc = SourceLocation { + start: loc.start.clone(), + end: SourcePosition { + line: loc.start.line, + column: loc.start.column + first.len(), + }, + }; + + if first == "this" { + ( + PathHead::This(ThisHead { + node_type: "ThisHead", + original: "this", + loc: head_loc, + }), + tail, + ) + } else if first.starts_with('@') { + ( + PathHead::At(AtHead { + node_type: "AtHead", + name: first.to_string(), + original: first.to_string(), + loc: head_loc, + }), + tail, + ) + } else if first.starts_with("../") || first == ".." { + // Parent reference: ../foo or ../../foo + // The entire parent ref sequence is the head + let mut depth = 0; + let mut remaining = original; + while remaining.starts_with("../") { + depth += 1; + remaining = &remaining[3..]; + } + + let head_name = if remaining.contains('.') { + remaining.split('.').next().unwrap_or(remaining) + } else { + remaining + }; + + let var_tail: Vec = if remaining.contains('.') { + remaining + .split('.') + .skip(1) + .map(|s| s.to_string()) + .collect() + } else { + vec![] + }; + + ( + PathHead::Var(VarHead { + node_type: "VarHead", + name: head_name.to_string(), + original: format!("{}{}", "../".repeat(depth), head_name), + loc: head_loc, + }), + var_tail, + ) + } else { + ( + PathHead::Var(VarHead { + node_type: "VarHead", + name: first.to_string(), + original: first.to_string(), + loc: head_loc, + }), + tail, + ) + } +} + +fn build_sub_expression(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::PathExpression => { + if path.is_none() { + path = Some(build_expression_from_path(child, source)); + } else { + params.push(build_expression_from_path(child, source)); + } + } + Rule::SubExpression => { + if path.is_none() { + path = Some(build_sub_expression(child, source)); + } else { + params.push(build_sub_expression(child, source)); + } + } + Rule::Param => { + params.push(build_param(child, source)); + } + Rule::HashPair => { + hash_pairs.push(build_hash_pair(child, source)); + } + Rule::StringLiteral | Rule::DoubleQuotedString | Rule::SingleQuotedString => { + let expr = build_string_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::NumberLiteral => { + let expr = build_number_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::BooleanLiteral => { + let expr = build_boolean_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::UndefinedLiteral => { + let expr = build_undefined_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::NullLiteral => { + let expr = build_null_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + _ => {} + } + } + + let path = path.expect("SubExpression must have a path"); + + let hash_loc = if hash_pairs.is_empty() { + loc.clone() + } else { + SourceLocation { + start: hash_pairs.first().unwrap().loc.start.clone(), + end: hash_pairs.last().unwrap().loc.end.clone(), + } + }; + + Expression::SubExpression(Box::new(SubExpression { + node_type: "SubExpression", + path, + params, + hash: Hash { + node_type: "Hash", + pairs: hash_pairs, + loc: hash_loc, + }, + loc, + })) +} + +fn build_string_literal(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + let raw = pair.as_str(); + + // Remove surrounding quotes + let value = if (raw.starts_with('"') && raw.ends_with('"')) + || (raw.starts_with('\'') && raw.ends_with('\'')) + { + raw[1..raw.len() - 1].to_string() + } else { + // might be a wrapper rule + let inner = pair.into_inner().next(); + if let Some(inner_pair) = inner { + let inner_raw = inner_pair.as_str(); + if (inner_raw.starts_with('"') && inner_raw.ends_with('"')) + || (inner_raw.starts_with('\'') && inner_raw.ends_with('\'')) + { + inner_raw[1..inner_raw.len() - 1].to_string() + } else { + inner_raw.to_string() + } + } else { + raw.to_string() + } + }; + + // Unescape backslash sequences + let unescaped = value.replace("\\\"", "\"").replace("\\'", "'").replace("\\\\", "\\"); + + Expression::StringLiteral(StringLiteral { + node_type: "StringLiteral", + value: unescaped.clone(), + loc, + }) +} + +fn build_number_literal(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + let value: f64 = pair.as_str().parse().unwrap_or(0.0); + + Expression::NumberLiteral(NumberLiteral { + node_type: "NumberLiteral", + value, + loc, + }) +} + +fn build_boolean_literal(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + let value = pair.as_str() == "true"; + + Expression::BooleanLiteral(BooleanLiteral { + node_type: "BooleanLiteral", + value, + loc, + }) +} + +fn build_undefined_literal(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + Expression::UndefinedLiteral(UndefinedLiteral { + node_type: "UndefinedLiteral", + loc, + }) +} + +fn build_null_literal(pair: Pair<'_, Rule>, source: &str) -> Expression { + let loc = span_to_loc(source, &pair); + Expression::NullLiteral(NullLiteral { + node_type: "NullLiteral", + value: None, + loc, + }) +} + +fn build_hash_pair(pair: Pair<'_, Rule>, source: &str) -> HashPair { + let loc = span_to_loc(source, &pair); + let mut key = String::new(); + let mut value = None; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::HashKey => { + key = child.as_str().to_string(); + } + _ => { + value = Some(build_expression(child, source)); + } + } + } + + HashPair { + node_type: "HashPair", + key, + value: value.expect("HashPair must have a value"), + loc, + } +} + +fn build_block_statement(pair: Pair<'_, Rule>, source: &str) -> BlockStatement { + let loc = span_to_loc(source, &pair); + let mut path = None; + let mut params_expr = vec![]; + let mut hash_pairs = vec![]; + let mut block_params = vec![]; + let mut body = vec![]; + let mut inverse: Option = None; + let mut open_strip = default_strip(); + let mut close_strip = default_strip(); + let mut inverse_strip = default_strip(); + + for child in pair.into_inner() { + match child.as_rule() { + Rule::BlockOpen => { + for sub in child.into_inner() { + match sub.as_rule() { + Rule::StripOpen => open_strip.open = true, + Rule::StripClose => open_strip.close = true, + Rule::CallExpression => { + let (p, pars, hp) = build_call_expression(sub, source); + path = Some(p); + params_expr = pars; + hash_pairs = hp; + } + Rule::BlockParams => { + block_params = build_block_params(sub); + } + _ => {} + } + } + } + Rule::BlockClose => { + for sub in child.into_inner() { + match sub.as_rule() { + Rule::StripOpen => close_strip.open = true, + Rule::StripClose => close_strip.close = true, + _ => {} + } + } + } + Rule::InverseChain => { + let (inv, inv_strip) = build_inverse_chain(child, source); + inverse = Some(inv); + inverse_strip = inv_strip; + } + _ => { + if let Some(stmt) = build_statement(child, source) { + body.push(stmt); + } + } + } + } + + let path = path.expect("BlockStatement must have a path"); + + let program_loc = if body.is_empty() { + loc.clone() + } else { + SourceLocation { + start: body.first().map(|s| stmt_loc(s).start.clone()).unwrap_or(loc.start.clone()), + end: body.last().map(|s| stmt_loc(s).end.clone()).unwrap_or(loc.end.clone()), + } + }; + + let var_heads: Vec = block_params + .iter() + .map(|name| VarHead { + node_type: "VarHead", + name: name.clone(), + original: name.clone(), + loc: loc.clone(), // approximate + }) + .collect(); + + let hash_loc = if hash_pairs.is_empty() { + loc.clone() + } else { + SourceLocation { + start: hash_pairs.first().unwrap().loc.start.clone(), + end: hash_pairs.last().unwrap().loc.end.clone(), + } + }; + + BlockStatement { + node_type: "BlockStatement", + path, + params: params_expr, + hash: Hash { + node_type: "Hash", + pairs: hash_pairs, + loc: hash_loc, + }, + program: Block { + node_type: "Block", + body, + params: var_heads, + block_params, + chained: false, + loc: program_loc, + }, + inverse, + open_strip, + inverse_strip, + close_strip, + loc, + } +} + +fn build_call_expression( + pair: Pair<'_, Rule>, + source: &str, +) -> (Expression, Vec, Vec) { + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::PathExpression => { + if path.is_none() { + path = Some(build_expression_from_path(child, source)); + } else { + params.push(build_expression_from_path(child, source)); + } + } + Rule::SubExpression => { + if path.is_none() { + path = Some(build_sub_expression(child, source)); + } else { + params.push(build_sub_expression(child, source)); + } + } + Rule::Param => { + params.push(build_param(child, source)); + } + Rule::HashPair => { + hash_pairs.push(build_hash_pair(child, source)); + } + Rule::StringLiteral | Rule::DoubleQuotedString | Rule::SingleQuotedString => { + let expr = build_string_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::NumberLiteral => { + let expr = build_number_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + Rule::BooleanLiteral => { + let expr = build_boolean_literal(child, source); + if path.is_none() { + path = Some(expr); + } else { + params.push(expr); + } + } + _ => {} + } + } + + let path = path.expect("CallExpression must have a path"); + (path, params, hash_pairs) +} + +fn build_block_params(pair: Pair<'_, Rule>) -> Vec { + let mut params = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::BlockParamList => { + for param in child.into_inner() { + if param.as_rule() == Rule::BlockParamName { + params.push(param.as_str().to_string()); + } + } + } + _ => {} + } + } + + params +} + +/// Build a Block for an InverseChain. +/// +/// Handles both plain `{{else}}...` and `{{else if cond}}...` chains. +/// For `{{else if cond}}`, the returned Block contains a single nested +/// BlockStatement with `program.chained = true`, matching the legacy +/// handlebars parser's transformation. +/// +/// Returns (block, open_strip_flags). +fn build_inverse_chain(pair: Pair<'_, Rule>, source: &str) -> (Block, StripFlags) { + let loc = span_to_loc(source, &pair); + let mut strip = default_strip(); + let mut body = vec![]; + let mut else_call: Option = None; + let mut block_params: Vec = vec![]; + let mut nested_inverse: Option = None; + let mut nested_inverse_strip = default_strip(); + + for child in pair.into_inner() { + match child.as_rule() { + Rule::InverseBlock => { + // Unwrap to get the actual InverseSimple or InverseElseBlock + for inner in child.into_inner() { + match inner.as_rule() { + Rule::InverseSimple => { + for sub in inner.into_inner() { + match sub.as_rule() { + Rule::StripOpen => strip.open = true, + Rule::StripClose => strip.close = true, + _ => {} + } + } + } + Rule::InverseElseBlock => { + let info = parse_inverse_else_block(inner, source); + strip = info.strip.clone(); + else_call = Some(info); + } + _ => {} + } + } + } + Rule::InverseChain => { + let (inv, inv_strip) = build_inverse_chain(child, source); + nested_inverse = Some(inv); + nested_inverse_strip = inv_strip; + } + _ => { + if let Some(stmt) = build_statement(child, source) { + body.push(stmt); + } + } + } + } + + // If this inverse chain starts with `{{else if ...}}`, transform the + // entire body into a single nested BlockStatement with chained=true. + if let Some(info) = else_call { + let program_loc = if body.is_empty() { + loc.clone() + } else { + SourceLocation { + start: body.first().map(|s| stmt_loc(s).start.clone()).unwrap_or(loc.start.clone()), + end: body.last().map(|s| stmt_loc(s).end.clone()).unwrap_or(loc.end.clone()), + } + }; + let var_heads = block_params_to_var_heads(&block_params, &loc); + + let hash_loc = if info.hash_pairs.is_empty() { + loc.clone() + } else { + SourceLocation { + start: info.hash_pairs.first().unwrap().loc.start.clone(), + end: info.hash_pairs.last().unwrap().loc.end.clone(), + } + }; + + let nested_block = BlockStatement { + node_type: "BlockStatement", + path: info.path, + params: info.params, + hash: Hash { + node_type: "Hash", + pairs: info.hash_pairs, + loc: hash_loc, + }, + program: Block { + node_type: "Block", + body, + params: var_heads, + block_params: block_params.clone(), + chained: false, + loc: program_loc, + }, + inverse: nested_inverse, + open_strip: info.strip, + inverse_strip: nested_inverse_strip, + close_strip: default_strip(), + loc: loc.clone(), + }; + + return ( + Block { + node_type: "Block", + body: vec![Statement::Block(nested_block)], + params: vec![], + block_params: vec![], + chained: true, // marks this inverse as `{{else if}}` chained + loc, + }, + strip, + ); + } + + // Plain `{{else}}` branch — merge body and nested inverse content + let mut merged_body = body; + if let Some(inv) = nested_inverse { + merged_body.extend(inv.body); + } + + ( + Block { + node_type: "Block", + body: merged_body, + params: vec![], + block_params: vec![], + chained: false, + loc, + }, + strip, + ) +} + +struct ElseCallInfo { + path: Expression, + params: Vec, + hash_pairs: Vec, + strip: StripFlags, +} + +fn parse_inverse_else_block(pair: Pair<'_, Rule>, source: &str) -> ElseCallInfo { + let mut strip = default_strip(); + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + for sub in pair.into_inner() { + match sub.as_rule() { + Rule::StripOpen => strip.open = true, + Rule::StripClose => strip.close = true, + Rule::CallExpression => { + let (p, pars, hp) = build_call_expression(sub, source); + path = Some(p); + params = pars; + hash_pairs = hp; + } + _ => {} + } + } + + ElseCallInfo { + path: path.expect("InverseElseBlock must have a call expression"), + params, + hash_pairs, + strip, + } +} + +fn build_html_comment(pair: Pair<'_, Rule>, source: &str) -> CommentStatement { + let loc = span_to_loc(source, &pair); + let mut value = String::new(); + + for child in pair.into_inner() { + if child.as_rule() == Rule::HtmlCommentContent { + value = child.as_str().to_string(); + } + } + + CommentStatement { + node_type: "CommentStatement", + value, + loc, + } +} + +fn build_mustache_comment(pair: Pair<'_, Rule>, source: &str) -> MustacheCommentStatement { + let loc = span_to_loc(source, &pair); + let mut value = String::new(); + let mut strip = default_strip(); + + let inner_pair = match pair.as_rule() { + Rule::MustacheComment => pair.into_inner().next().unwrap(), + _ => pair, + }; + + for child in inner_pair.into_inner() { + match child.as_rule() { + Rule::MustacheCommentLongContent | Rule::MustacheCommentShortContent => { + value = child.as_str().to_string(); + } + Rule::StripOpen => strip.open = true, + Rule::StripClose => strip.close = true, + _ => {} + } + } + + MustacheCommentStatement { + node_type: "MustacheCommentStatement", + value, + strip, + loc, + } +} + +fn build_element(pair: Pair<'_, Rule>, source: &str) -> ElementNode { + let loc = span_to_loc(source, &pair); + + // Unwrap Element wrapper if present + let inner_pair = match pair.as_rule() { + Rule::Element => pair.into_inner().next().unwrap(), + _ => pair, + }; + + match inner_pair.as_rule() { + Rule::NormalElement => build_normal_element(inner_pair, source, loc), + Rule::SelfClosingElement => build_self_closing_element(inner_pair, source, loc), + Rule::VoidElement => build_void_element(inner_pair, source, loc), + _ => panic!("Unexpected element type: {:?}", inner_pair.as_rule()), + } +} + +fn build_normal_element( + pair: Pair<'_, Rule>, + source: &str, + loc: SourceLocation, +) -> ElementNode { + let mut tag_name = String::new(); + let mut tag_loc = loc.clone(); + let mut attributes = vec![]; + let mut modifiers = vec![]; + let mut comments = vec![]; + let mut block_params: Vec = vec![]; + let mut children = vec![]; + let mut open_tag = loc.clone(); + let mut close_tag = None; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::OpenTag => { + open_tag = span_to_loc(source, &child); + for sub in child.into_inner() { + match sub.as_rule() { + Rule::TagName => { + tag_name = sub.as_str().to_string(); + tag_loc = span_to_loc(source, &sub); + } + Rule::Splattributes => { + let attr_loc = span_to_loc(source, &sub); + attributes.push(AttrNode { + node_type: "AttrNode", + name: "...attributes".to_string(), + value: AttrValue::Text(TextNode { + node_type: "TextNode", + chars: String::new(), + loc: attr_loc.clone(), + }), + loc: attr_loc, + }); + } + Rule::AttrWithValue => { + attributes.push(build_attr_with_value(sub, source)); + } + Rule::AttrNameOnly => { + attributes.push(build_attr_name_only(sub, source)); + } + Rule::AttrModifier => { + modifiers.push(build_element_modifier(sub, source)); + } + Rule::BlockParams => { + block_params = build_block_params(sub); + } + Rule::MustacheComment + | Rule::MustacheCommentLong + | Rule::MustacheCommentShort => { + comments.push(build_mustache_comment(sub, source)); + } + _ => {} + } + } + } + Rule::CloseTag => { + close_tag = Some(span_to_loc(source, &child)); + } + _ => { + if let Some(stmt) = build_statement(child, source) { + children.push(stmt); + } + } + } + } + + let path = build_element_path(&tag_name, &tag_loc); + + ElementNode { + node_type: "ElementNode", + path, + self_closing: false, + attributes, + params: block_params_to_var_heads(&block_params, &loc), + modifiers, + comments, + children, + open_tag, + close_tag, + tag: tag_name, + block_params, + loc, + } +} + +fn build_self_closing_element( + pair: Pair<'_, Rule>, + source: &str, + loc: SourceLocation, +) -> ElementNode { + let mut tag_name = String::new(); + let mut tag_loc = loc.clone(); + let mut attributes = vec![]; + let mut modifiers = vec![]; + let mut comments = vec![]; + let mut block_params: Vec = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::TagName => { + tag_name = child.as_str().to_string(); + tag_loc = span_to_loc(source, &child); + } + Rule::Splattributes => { + let attr_loc = span_to_loc(source, &child); + attributes.push(AttrNode { + node_type: "AttrNode", + name: "...attributes".to_string(), + value: AttrValue::Text(TextNode { + node_type: "TextNode", + chars: String::new(), + loc: attr_loc.clone(), + }), + loc: attr_loc, + }); + } + Rule::AttrWithValue => { + attributes.push(build_attr_with_value(child, source)); + } + Rule::AttrNameOnly => { + attributes.push(build_attr_name_only(child, source)); + } + Rule::AttrModifier => { + modifiers.push(build_element_modifier(child, source)); + } + Rule::BlockParams => { + block_params = build_block_params(child); + } + Rule::MustacheComment | Rule::MustacheCommentLong | Rule::MustacheCommentShort => { + comments.push(build_mustache_comment(child, source)); + } + _ => {} + } + } + + let path = build_element_path(&tag_name, &tag_loc); + + ElementNode { + node_type: "ElementNode", + path, + self_closing: true, + attributes, + params: block_params_to_var_heads(&block_params, &loc), + modifiers, + comments, + children: vec![], + open_tag: loc.clone(), + close_tag: None, + tag: tag_name, + block_params, + loc, + } +} + +fn build_void_element( + pair: Pair<'_, Rule>, + source: &str, + loc: SourceLocation, +) -> ElementNode { + let mut tag_name = String::new(); + let mut tag_loc = loc.clone(); + let mut attributes = vec![]; + let mut modifiers = vec![]; + let mut comments = vec![]; + let mut self_closing = false; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::VoidTagName => { + tag_name = child.as_str().to_string(); + tag_loc = span_to_loc(source, &child); + } + Rule::TagEnd => { + // `/>` marks a self-closing void element like
+ if child.as_str() == "/>" { + self_closing = true; + } + } + Rule::Splattributes => { + let attr_loc = span_to_loc(source, &child); + attributes.push(AttrNode { + node_type: "AttrNode", + name: "...attributes".to_string(), + value: AttrValue::Text(TextNode { + node_type: "TextNode", + chars: String::new(), + loc: attr_loc.clone(), + }), + loc: attr_loc, + }); + } + Rule::AttrWithValue => { + attributes.push(build_attr_with_value(child, source)); + } + Rule::AttrNameOnly => { + attributes.push(build_attr_name_only(child, source)); + } + Rule::AttrModifier => { + modifiers.push(build_element_modifier(child, source)); + } + Rule::MustacheComment | Rule::MustacheCommentLong | Rule::MustacheCommentShort => { + comments.push(build_mustache_comment(child, source)); + } + _ => {} + } + } + + let path = build_element_path(&tag_name, &tag_loc); + + ElementNode { + node_type: "ElementNode", + path, + self_closing, + attributes, + params: vec![], + modifiers, + comments, + children: vec![], + open_tag: loc.clone(), + close_tag: None, + tag: tag_name, + block_params: vec![], + loc, + } +} + +/// Build an element path from the tag name source span. +/// `tag_loc` must be the location of just the tag name in the source +/// (NOT the whole element). +fn build_element_path(tag_name: &str, tag_loc: &SourceLocation) -> PathExpression { + let segments: Vec<&str> = tag_name.split('.').collect(); + let head_name = segments[0]; + let tail: Vec = segments[1..].iter().map(|s| s.to_string()).collect(); + + let head_loc = SourceLocation { + start: tag_loc.start.clone(), + end: SourcePosition { + line: tag_loc.start.line, + column: tag_loc.start.column + head_name.len(), + }, + }; + + // Match head type to its text: , <@arg>, or /<:block> + let head = if head_name == "this" { + PathHead::This(ThisHead { + node_type: "ThisHead", + original: "this", + loc: head_loc, + }) + } else if head_name.starts_with('@') { + PathHead::At(AtHead { + node_type: "AtHead", + name: head_name.to_string(), + original: head_name.to_string(), + loc: head_loc, + }) + } else { + PathHead::Var(VarHead { + node_type: "VarHead", + name: head_name.to_string(), + original: head_name.to_string(), + loc: head_loc, + }) + }; + + PathExpression { + node_type: "PathExpression", + original: tag_name.to_string(), + head, + tail, + loc: tag_loc.clone(), + } +} + +fn build_attr_with_value(pair: Pair<'_, Rule>, source: &str) -> AttrNode { + let loc = span_to_loc(source, &pair); + let mut name = String::new(); + let mut value = AttrValue::Text(TextNode { + node_type: "TextNode", + chars: String::new(), + loc: loc.clone(), + }); + + for child in pair.into_inner() { + match child.as_rule() { + Rule::AttrName => { + name = child.as_str().to_string(); + } + Rule::QuotedAttrValue | Rule::DoubleQuotedAttrValue | Rule::SingleQuotedAttrValue => { + value = build_quoted_attr_value(child, source); + } + Rule::UnquotedAttrValue => { + value = build_unquoted_attr_value(child, source); + } + _ => {} + } + } + + AttrNode { + node_type: "AttrNode", + name, + value, + loc, + } +} + +fn build_attr_name_only(pair: Pair<'_, Rule>, source: &str) -> AttrNode { + let loc = span_to_loc(source, &pair); + let mut name = String::new(); + + for child in pair.into_inner() { + if child.as_rule() == Rule::AttrName { + name = child.as_str().to_string(); + } + } + + AttrNode { + node_type: "AttrNode", + name, + value: AttrValue::Text(TextNode { + node_type: "TextNode", + chars: String::new(), + loc: loc.clone(), + }), + loc, + } +} + +fn build_quoted_attr_value(pair: Pair<'_, Rule>, source: &str) -> AttrValue { + let loc = span_to_loc(source, &pair); + + // Unwrap QuotedAttrValue -> DoubleQuotedAttrValue/SingleQuotedAttrValue + let inner = match pair.as_rule() { + Rule::QuotedAttrValue => pair.into_inner().next().unwrap(), + _ => pair, + }; + + let mut parts: Vec = vec![]; + + for child in inner.into_inner() { + match child.as_rule() { + Rule::AttrText_DQ | Rule::AttrText_SQ => { + let text_loc = span_to_loc(source, &child); + parts.push(AttrPart::Text(TextNode { + node_type: "TextNode", + chars: child.as_str().to_string(), + loc: text_loc, + })); + } + Rule::AttrMustache | Rule::DoubleMustache => { + let mustache = build_mustache(child, source); + parts.push(AttrPart::Mustache(mustache)); + } + _ => {} + } + } + + let has_mustache = parts.iter().any(|p| matches!(p, AttrPart::Mustache(_))); + + if has_mustache { + // Always produce ConcatStatement for quoted attrs with mustaches + AttrValue::Concat(ConcatStatement { + node_type: "ConcatStatement", + parts, + loc, + }) + } else if parts.len() == 1 { + match parts.into_iter().next().unwrap() { + AttrPart::Text(t) => AttrValue::Text(t), + AttrPart::Mustache(m) => AttrValue::Mustache(m), + } + } else { + // Multiple text parts (shouldn't happen, but handle gracefully) + let chars: String = parts + .iter() + .map(|p| match p { + AttrPart::Text(t) => t.chars.clone(), + AttrPart::Mustache(_) => String::new(), + }) + .collect(); + AttrValue::Text(TextNode { + node_type: "TextNode", + chars, + loc, + }) + } +} + +fn build_unquoted_attr_value(pair: Pair<'_, Rule>, source: &str) -> AttrValue { + let inner = pair.into_inner().next().unwrap(); + + match inner.as_rule() { + Rule::UnquotedMustache | Rule::DoubleMustache => { + AttrValue::Mustache(build_mustache(inner, source)) + } + Rule::UnquotedTextValue => { + let loc = span_to_loc(source, &inner); + AttrValue::Text(TextNode { + node_type: "TextNode", + chars: inner.as_str().to_string(), + loc, + }) + } + _ => { + let loc = span_to_loc(source, &inner); + AttrValue::Text(TextNode { + node_type: "TextNode", + chars: inner.as_str().to_string(), + loc, + }) + } + } +} + +fn build_element_modifier(pair: Pair<'_, Rule>, source: &str) -> ElementModifierStatement { + let loc = span_to_loc(source, &pair); + let mut path = None; + let mut params = vec![]; + let mut hash_pairs = vec![]; + + for child in pair.into_inner() { + match child.as_rule() { + Rule::CallExpression => { + let (p, pars, hp) = build_call_expression(child, source); + path = Some(p); + params = pars; + hash_pairs = hp; + } + Rule::StripOpen | Rule::StripClose => {} + _ => {} + } + } + + let path = path.expect("ElementModifier must have a path"); + let hash_loc = if hash_pairs.is_empty() { + loc.clone() + } else { + SourceLocation { + start: hash_pairs.first().unwrap().loc.start.clone(), + end: hash_pairs.last().unwrap().loc.end.clone(), + } + }; + + ElementModifierStatement { + node_type: "ElementModifierStatement", + path, + params, + hash: Hash { + node_type: "Hash", + pairs: hash_pairs, + loc: hash_loc, + }, + loc, + } +} + +fn block_params_to_var_heads(params: &[String], loc: &SourceLocation) -> Vec { + params + .iter() + .map(|name| VarHead { + node_type: "VarHead", + name: name.clone(), + original: name.clone(), + loc: loc.clone(), + }) + .collect() +} + +// -- Helpers ----------------------------------------------------------------- + +fn unwrap_to_body(pair: Pair<'_, Rule>) -> Vec> { + let mut result = vec![]; + for child in pair.into_inner() { + result.push(child); + } + result +} + +fn unwrap_single(pair: Pair<'_, Rule>) -> Option> { + pair.into_inner().next() +} + +fn stmt_loc(stmt: &Statement) -> &SourceLocation { + match stmt { + Statement::Mustache(m) => &m.loc, + Statement::Block(b) => &b.loc, + Statement::Comment(c) => &c.loc, + Statement::MustacheComment(c) => &c.loc, + Statement::Element(e) => &e.loc, + Statement::Text(t) => &t.loc, + } +} diff --git a/packages/@glimmer/syntax/src/errors.rs b/packages/@glimmer/syntax/src/errors.rs new file mode 100644 index 00000000000..6e162382b93 --- /dev/null +++ b/packages/@glimmer/syntax/src/errors.rs @@ -0,0 +1,207 @@ +//! Rich error reporting for Glimmer template parse errors. +//! +//! Converts pest parse errors into structured error objects with: +//! - Exact source locations (line/column) +//! - Source context (the offending line with a visual pointer) +//! - Human-readable error messages +//! - Suggestions for common mistakes + +use pest::error::{Error as PestError, ErrorVariant, LineColLocation}; + +use crate::ast::{ErrorContext, ParseError, SourceLocation, SourcePosition}; +use crate::Rule; + +/// Convert a pest parse error into a structured ParseError with rich context. +pub fn convert_pest_error( + error: &PestError, + source: &str, + src_name: Option<&str>, +) -> ParseError { + let (line, col) = match error.line_col { + LineColLocation::Pos((line, col)) => (line, col), + LineColLocation::Span((line, col), _) => (line, col), + }; + + // Convert to 0-based column for Glimmer compatibility + let column = if col > 0 { col - 1 } else { 0 }; + + let loc = SourceLocation { + start: SourcePosition { line, column }, + end: SourcePosition { line, column }, + }; + + let message = build_error_message(error, src_name); + let context = build_error_context(source, line, column, error); + + ParseError { + message, + loc, + context: Some(context), + } +} + +fn build_error_message(error: &PestError, src_name: Option<&str>) -> String { + let location_prefix = match src_name { + Some(name) => format!("in {name}: "), + None => String::new(), + }; + + match &error.variant { + ErrorVariant::ParsingError { + positives, + negatives, + } => { + let mut msg = format!("{location_prefix}Parse error"); + + if !positives.is_empty() { + let expected: Vec = positives + .iter() + .map(|r| rule_to_human_readable(r)) + .filter(|s| !s.is_empty()) + .collect(); + + if !expected.is_empty() { + msg.push_str(&format!(", expected {}", expected.join(", "))); + } + } + + if !negatives.is_empty() { + let unexpected: Vec = negatives + .iter() + .map(|r| rule_to_human_readable(r)) + .filter(|s| !s.is_empty()) + .collect(); + + if !unexpected.is_empty() { + msg.push_str(&format!(", unexpected {}", unexpected.join(", "))); + } + } + + msg + } + ErrorVariant::CustomError { message } => { + format!("{location_prefix}{message}") + } + } +} + +fn build_error_context( + source: &str, + line: usize, + column: usize, + error: &PestError, +) -> ErrorContext { + let lines: Vec<&str> = source.lines().collect(); + let source_line = if line > 0 && line <= lines.len() { + lines[line - 1].to_string() + } else { + String::new() + }; + + // Build a visual pointer like: + //
+ // -----^ + let pointer = format!("{}^", "-".repeat(column)); + + let suggestion = generate_suggestion(error, &source_line, column); + + ErrorContext { + source_line, + pointer, + suggestion, + } +} + +/// Generate helpful suggestions for common template errors. +fn generate_suggestion( + error: &PestError, + source_line: &str, + column: usize, +) -> Option { + let context = if column < source_line.len() { + &source_line[column..] + } else { + "" + }; + + // Check for common mistakes + + // Unclosed mustache: {{ without }} + if context.starts_with("{{") && !source_line[column..].contains("}}") { + return Some("It looks like this mustache expression is not closed. Add '}}' to close it.".to_string()); + } + + // Empty mustache: {{}} + if context.starts_with("{{}}") { + return Some( + "Empty mustache expressions are not allowed. Add an expression like {{myVariable}}.".to_string(), + ); + } + + // Unclosed element + if context.starts_with('<') && !context.starts_with("') { + return Some("This element tag appears to be unclosed. Add '>' or '/>' to close it.".to_string()); + } + + // Mismatched closing tag + if context.starts_with(" String { + match rule { + Rule::Template => "template".to_string(), + Rule::TextContent => "text content".to_string(), + Rule::Mustache | Rule::DoubleMustache => "mustache expression '{{...}}'".to_string(), + Rule::TripleMustache => { + "raw/triple mustache expression '{{{...}}}'".to_string() + } + Rule::BlockStatement => "block statement '{{#...}}'".to_string(), + Rule::BlockOpen => "block opening '{{#...}}'".to_string(), + Rule::BlockClose => "block closing '{{/...}}'".to_string(), + Rule::Element | Rule::NormalElement => "HTML element".to_string(), + Rule::SelfClosingElement => "self-closing element '<.../>'".to_string(), + Rule::VoidElement => "void element".to_string(), + Rule::OpenTag => "opening tag '<...>'".to_string(), + Rule::CloseTag => "closing tag ''".to_string(), + Rule::TagName => "tag name".to_string(), + Rule::PathExpression => "path expression".to_string(), + Rule::SubExpression => "sub-expression '(...)'".to_string(), + Rule::StringLiteral => "string literal".to_string(), + Rule::NumberLiteral => "number literal".to_string(), + Rule::BooleanLiteral => "boolean literal".to_string(), + Rule::NullLiteral => "'null'".to_string(), + Rule::UndefinedLiteral => "'undefined'".to_string(), + Rule::HashPair => "hash pair 'key=value'".to_string(), + Rule::AttrName => "attribute name".to_string(), + Rule::AttrWithValue => "attribute".to_string(), + Rule::HtmlComment => "HTML comment ''".to_string(), + Rule::MustacheComment | Rule::MustacheCommentLong | Rule::MustacheCommentShort => { + "mustache comment '{{!...}}'".to_string() + } + Rule::BlockParams => "block parameters 'as |...|'".to_string(), + Rule::Splattributes => "'...attributes'".to_string(), + Rule::EOI => "end of input".to_string(), + _ => String::new(), // Skip less interesting rules + } +} diff --git a/packages/@glimmer/syntax/src/glimmer.pest b/packages/@glimmer/syntax/src/glimmer.pest new file mode 100644 index 00000000000..d70c443caf9 --- /dev/null +++ b/packages/@glimmer/syntax/src/glimmer.pest @@ -0,0 +1,465 @@ +// ============================================================================ +// Glimmer Template Grammar (pest PEG) +// +// Parses HTML + Handlebars template syntax into an AST. +// No implicit WHITESPACE rule — whitespace is significant in templates +// and must be handled explicitly in each rule. +// ============================================================================ + +// -- Entry Points ----------------------------------------------------------- + +Template = { SOI ~ TopLevelStatement* ~ EOI } + +TopLevelStatement = _{ + HtmlComment + | MustacheComment + | BlockStatement + | EscapedMustache + | Mustache + | Element + | TextContent +} + +// -- Text Content ----------------------------------------------------------- + +TextContent = @{ + TextChar+ +} + +TextChar = @{ + !("<" | "{{" | "\\{{") ~ ANY +} + +// -- Escaped Mustaches ------------------------------------------------------ +// \{{ becomes literal {{ in output + +EscapedMustache = @{ + "\\" ~ "{{" +} + +// -- Mustache Statements ---------------------------------------------------- +// {{expr}}, {{{expr}}}, {{~expr~}} + +Mustache = { + TripleMustache + | DoubleMustache +} + +DoubleMustache = { + "{{" ~ StripOpen? ~ WS* ~ MustacheBody ~ WS* ~ StripClose? ~ "}}" +} + +TripleMustache = { + "{{{" ~ WS* ~ MustacheBody ~ WS* ~ "}}}" +} + +MustacheBody = { + Expression ~ (WS+ ~ ParamOrHash)* +} + +ParamOrHash = _{ + HashPair + | Param +} + +// -- Block Statements ------------------------------------------------------- +// {{#name}}...{{/name}}, {{#name as |params|}}...{{/name}} + +BlockStatement = { + BlockOpen ~ BlockBodyStatement* ~ InverseChain? ~ BlockClose +} + +// BlockBodyStatement is like TopLevelStatement but excludes `{{else}}` and +// `{{/...}}` so the enclosing block's InverseChain / BlockClose can match. +BlockBodyStatement = _{ + !BlockBodyTerminator ~ TopLevelStatement +} + +// Patterns that end a block body: {{else ...}}, {{/...}}, {{~else ...}}, {{~/...}} +BlockBodyTerminator = _{ + "{{" ~ "~"? ~ WS* ~ ("else" ~ &(WS | "}}" | "~}}") | "/") +} + +BlockOpen = { + "{{" ~ StripOpen? ~ WS* ~ "#" ~ WS* ~ CallExpression ~ BlockParams? ~ WS* ~ StripClose? ~ "}}" +} + +BlockClose = { + "{{" ~ StripOpen? ~ WS* ~ "/" ~ WS* ~ PathExpression ~ WS* ~ StripClose? ~ "}}" +} + +InverseChain = { + InverseBlock ~ BlockBodyStatement* ~ InverseChain? +} + +InverseBlock = { + InverseElseBlock + | InverseSimple +} + +InverseElseBlock = { + "{{" ~ StripOpen? ~ WS* ~ "else" ~ WS+ ~ CallExpression ~ BlockParams? ~ WS* ~ StripClose? ~ "}}" +} + +InverseSimple = { + "{{" ~ StripOpen? ~ WS* ~ "else" ~ WS* ~ StripClose? ~ "}}" +} + +// -- Call Expression (path + params + hash) ---------------------------------- + +CallExpression = { + Expression ~ (WS+ ~ ParamOrHash)* +} + +// -- Expressions ------------------------------------------------------------ + +Expression = _{ + SubExpression + | Literal + | PathExpression +} + +Param = { + !BlockParamsLookahead ~ (SubExpression | Literal | PathExpression) +} + +// Prevent "as |" from being consumed as a param +BlockParamsLookahead = _{ + "as" ~ WS+ ~ "|" +} + +// -- Sub-expressions -------------------------------------------------------- +// (helper arg1 key=val) + +SubExpression = { + "(" ~ WS* ~ Expression ~ (WS+ ~ ParamOrHash)* ~ WS* ~ ")" +} + +// -- Path Expressions ------------------------------------------------------- +// foo, foo.bar, this.foo, @bar, ../foo + +PathExpression = @{ + PathHead ~ ("." ~ PathSegment)* +} + +PathHead = @{ + ThisRef + | AtName + | ParentRef + | SlashedIdentifier + | SimpleIdentifier +} + +// Slashed identifier: fizz-bar/baz-bar (used for component/helper lookup) +SlashedIdentifier = @{ + IdentChars ~ ("/" ~ IdentChars)+ +} + +ThisRef = @{ "this" ~ &("." | WS | "}}" | ")" | "~}}" | "=" | "|") } + +AtName = @{ "@" ~ IdentChars } + +ParentRef = @{ ("../" )+ ~ IdentChars } + +SimpleIdentifier = @{ IdentChars } + +PathSegment = @{ IdentChars } + +IdentChars = @{ + IdentStart ~ IdentContinue* +} + +IdentStart = @{ + ASCII_ALPHA | "_" | "$" | ("-" ~ &ASCII_ALPHA) +} + +IdentContinue = @{ + ASCII_ALPHANUMERIC | "_" | "$" | "-" +} + +// -- Literals --------------------------------------------------------------- + +Literal = _{ + StringLiteral + | NumberLiteral + | BooleanLiteral + | UndefinedLiteral + | NullLiteral +} + +StringLiteral = { + DoubleQuotedString + | SingleQuotedString +} + +DoubleQuotedString = @{ + "\"" ~ DoubleQuotedChar* ~ "\"" +} + +DoubleQuotedChar = @{ + !("\"" | "\\") ~ ANY + | "\\" ~ ANY +} + +SingleQuotedString = @{ + "'" ~ SingleQuotedChar* ~ "'" +} + +SingleQuotedChar = @{ + !("'" | "\\") ~ ANY + | "\\" ~ ANY +} + +NumberLiteral = @{ + "-"? ~ ASCII_DIGIT+ ~ ("." ~ ASCII_DIGIT+)? +} + +BooleanLiteral = @{ + ("true" | "false") ~ &(WS | "}}" | ")" | "~}}") +} + +UndefinedLiteral = @{ + "undefined" ~ &(WS | "}}" | ")" | "~}}") +} + +NullLiteral = @{ + "null" ~ &(WS | "}}" | ")" | "~}}") +} + +// -- Hash Pairs ------------------------------------------------------------- +// key=value, key="string", key=(helper arg) + +HashPair = { + HashKey ~ WS* ~ "=" ~ WS* ~ HashValue +} + +HashKey = @{ IdentChars } + +HashValue = _{ + SubExpression + | Literal + | PathExpression +} + +// -- Strip Flags ------------------------------------------------------------ + +StripOpen = @{ "~" ~ WS* } +StripClose = @{ WS* ~ "~" } + +// -- Block Params ----------------------------------------------------------- +// as |foo bar| + +BlockParams = { + WS+ ~ "as" ~ WS+ ~ "|" ~ BlockParamList ~ "|" +} + +BlockParamList = { + (WS* ~ BlockParamName ~ WS*)+ +} + +BlockParamName = @{ IdentChars } + +// -- HTML Elements ---------------------------------------------------------- +// Order matters: try more specific matches first + +Element = { + VoidElement + | SelfClosingElement + | NormalElement +} + +NormalElement = { + OpenTag ~ TopLevelStatement* ~ CloseTag +} + +SelfClosingElement = { + "<" ~ TagName ~ ElementContent* ~ WS* ~ "/>" +} + +VoidElement = { + "<" ~ VoidTagName ~ ElementContent* ~ WS* ~ TagEnd +} + +// Separate TagEnd to handle both > and /> for void elements +TagEnd = @{ "/>" | ">" } + +OpenTag = { + "<" ~ TagName ~ ElementContent* ~ WS* ~ ">" +} + +CloseTag = { + "" +} + +// ElementContent covers attributes, modifiers, splattributes, block params, and comments +// Check BlockParams first so `as |x|` isn't consumed as attribute name `as`. +ElementContent = _{ + BlockParams + | WS+ ~ (Splattributes | MustacheComment | AttrModifier | AttrWithValue | AttrNameOnly) +} + +// TagName unifies all valid angle-bracket tag name forms: +// :inverse — named block +// @arg, @Arg.x — argument / path +// this.Foo, Foo.Bar — path expressions (upper/lower, dots, ::) +// Foo, FooBar — component identifiers (PascalCase) +// div, my-element — HTML/custom elements (lowercase) +TagName = @{ + NamedBlockTag + | AtPathTag + | NamespacedPathTag + | DottedPathTag + | ComponentIdent + | HtmlIdent +} + +NamedBlockTag = @{ ":" ~ IdentChars } + +// @-prefixed path: @foo, @Foo, @foo.bar +AtPathTag = @{ "@" ~ IdentChars ~ ("." ~ PathSegment)* } + +// Colon-namespaced path: Foo::Bar, Foo::Bar::Baz, Foo::Bar.Baz +NamespacedPathTag = @{ + ASCII_ALPHA_UPPER ~ TagNameContinue* ~ ("::" ~ ASCII_ALPHA ~ TagNameContinue*)+ ~ ("." ~ PathSegment)* +} + +// Dotted path tags (both cases): foo.bar, Foo.Bar, this.Foo +DottedPathTag = @{ + ("this" | ASCII_ALPHA ~ TagNameContinue*) ~ ("." ~ PathSegment)+ +} + +// Component identifier: PascalCase tags (Foo, FooBar) +ComponentIdent = @{ ASCII_ALPHA_UPPER ~ TagNameContinue* } + +// HTML/custom-element identifier: lowercase tags (div, my-element) +HtmlIdent = @{ ASCII_ALPHA_LOWER ~ TagNameContinue* } + +TagNameContinue = @{ ASCII_ALPHANUMERIC | "-" | "_" } + +// Case-sensitive: PascalCase versions (e.g. ) are components, +// not void tags, so they must have matching close tags. +VoidTagName = @{ + ( + "area" | "base" | "br" | "col" | "command" + | "embed" | "hr" | "img" | "input" | "keygen" + | "link" | "meta" | "param" | "source" | "track" + | "wbr" + ) ~ &(WS | ">" | "/") +} + +// -- Attributes ------------------------------------------------------------- + +Splattributes = { + "...attributes" +} + +AttrModifier = { + "{{" ~ StripOpen? ~ WS* ~ CallExpression ~ WS* ~ StripClose? ~ "}}" +} + +AttrWithValue = { + AttrName ~ "=" ~ AttrValuePart +} + +AttrNameOnly = { + AttrName +} + +AttrName = @{ + AttrNameChar+ +} + +AttrNameChar = @{ + !(WS | "=" | ">" | "/" | "{{" | "\"" | "'") ~ ANY +} + +AttrValuePart = _{ + QuotedAttrValue + | UnquotedAttrValue +} + +QuotedAttrValue = { + DoubleQuotedAttrValue + | SingleQuotedAttrValue +} + +DoubleQuotedAttrValue = { + "\"" ~ AttrTextOrMustache_DQ* ~ "\"" +} + +SingleQuotedAttrValue = { + "'" ~ AttrTextOrMustache_SQ* ~ "'" +} + +AttrTextOrMustache_DQ = _{ + AttrMustache | AttrText_DQ +} + +AttrTextOrMustache_SQ = _{ + AttrMustache | AttrText_SQ +} + +AttrText_DQ = @{ + (!("\"" | "{{") ~ ANY)+ +} + +AttrText_SQ = @{ + (!("'" | "{{") ~ ANY)+ +} + +AttrMustache = { + TripleMustache + | DoubleMustache +} + +UnquotedAttrValue = { + UnquotedMustache + | UnquotedTextValue +} + +UnquotedMustache = { + TripleMustache + | DoubleMustache +} + +UnquotedTextValue = @{ + (!(WS | ">" | "/>" | "{{") ~ ANY)+ +} + +// -- HTML Comments ---------------------------------------------------------- + +HtmlComment = { + "" +} + +HtmlCommentContent = @{ + (!"-->" ~ ANY)* +} + +// -- Mustache Comments ------------------------------------------------------ +// {{!-- comment --}} and {{! comment }} + +MustacheComment = { + MustacheCommentLong + | MustacheCommentShort +} + +MustacheCommentLong = { + "{{" ~ StripOpen? ~ "!--" ~ MustacheCommentLongContent ~ "--" ~ StripClose? ~ "}}" +} + +MustacheCommentLongContent = @{ + (!"--}}" ~ !"--~}}" ~ ANY)* +} + +MustacheCommentShort = { + "{{" ~ StripOpen? ~ "!" ~ MustacheCommentShortContent ~ StripClose? ~ "}}" +} + +MustacheCommentShortContent = @{ + (!("}}" | "~}}") ~ ANY)* +} + +// -- Whitespace (explicit only, no implicit WHITESPACE rule) ---------------- + +WS = _{ " " | "\t" | "\n" | "\r" } diff --git a/packages/@glimmer/syntax/src/lib.rs b/packages/@glimmer/syntax/src/lib.rs new file mode 100644 index 00000000000..18bf0dd1cad --- /dev/null +++ b/packages/@glimmer/syntax/src/lib.rs @@ -0,0 +1,164 @@ +use pest::Parser; +use pest_derive::Parser; +use wasm_bindgen::prelude::*; + +mod ast; +mod builder; +mod errors; + +#[derive(Parser)] +#[grammar = "glimmer.pest"] +pub struct GlimmerParser; + +/// Parse a Glimmer/Handlebars template string and return an ASTv1 Template as a JSON string. +/// +/// The JS side parses the JSON into a plain object then decorates it with +/// SourceSpans, non-enumerable getters, etc. This avoids a wasm-bindgen +/// serde bridge and keeps the wasm binary smaller. +#[wasm_bindgen(js_name = "parseTemplateToJson")] +pub fn parse_template_to_json(source: &str, src_name: Option) -> Result { + let result = GlimmerParser::parse(Rule::Template, source); + + match result { + Ok(pairs) => { + let template = builder::build_template(pairs, source, src_name.as_deref()); + serde_json::to_string(&template).map_err(|e| format!("Serialization error: {e}")) + } + Err(pest_error) => { + let parse_error = errors::convert_pest_error(&pest_error, source, src_name.as_deref()); + Err(serde_json::to_string(&parse_error) + .unwrap_or_else(|_| format!("Parse error: {pest_error}"))) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_simple_text() { + let result = GlimmerParser::parse(Rule::Template, "Hello world"); + assert!(result.is_ok(), "Failed to parse simple text: {:?}", result.err()); + } + + #[test] + fn test_parse_mustache() { + let result = GlimmerParser::parse(Rule::Template, "{{foo}}"); + assert!(result.is_ok(), "Failed to parse mustache: {:?}", result.err()); + } + + #[test] + fn test_parse_element() { + let result = GlimmerParser::parse(Rule::Template, "
hello
"); + assert!(result.is_ok(), "Failed to parse element: {:?}", result.err()); + } + + #[test] + fn test_parse_self_closing() { + let result = GlimmerParser::parse(Rule::Template, "
"); + assert!(result.is_ok(), "Failed to parse self-closing: {:?}", result.err()); + } + + #[test] + fn test_parse_block() { + let result = GlimmerParser::parse(Rule::Template, "{{#if cond}}yes{{else}}no{{/if}}"); + assert!(result.is_ok(), "Failed to parse block: {:?}", result.err()); + } + + #[test] + fn test_parse_element_with_attrs() { + let result = GlimmerParser::parse(Rule::Template, r#"
content
"#); + assert!(result.is_ok(), "Failed to parse element with attrs: {:?}", result.err()); + } + + #[test] + fn test_parse_mustache_comment() { + let result = GlimmerParser::parse(Rule::Template, "{{!-- this is a comment --}}"); + assert!(result.is_ok(), "Failed to parse mustache comment: {:?}", result.err()); + } + + #[test] + fn test_parse_html_comment() { + let result = GlimmerParser::parse(Rule::Template, ""); + assert!(result.is_ok(), "Failed to parse html comment: {:?}", result.err()); + } + + #[test] + fn test_parse_component() { + let result = GlimmerParser::parse(Rule::Template, ""); + assert!(result.is_ok(), "Failed to parse component: {:?}", result.err()); + } + + #[test] + fn test_parse_block_params() { + let result = GlimmerParser::parse(Rule::Template, "{{#each items as |item index|}}{{item}}{{/each}}"); + assert!(result.is_ok(), "Failed to parse block params: {:?}", result.err()); + } + + #[test] + fn test_parse_named_block() { + let result = GlimmerParser::parse(Rule::Template, "<:header>Title"); + assert!(result.is_ok(), "Failed to parse named block: {:?}", result.err()); + } + + #[test] + fn test_parse_sub_expression() { + let result = GlimmerParser::parse(Rule::Template, "{{(helper arg)}}"); + assert!(result.is_ok(), "Failed to parse sub expression: {:?}", result.err()); + } + + #[test] + fn test_parse_triple_mustache() { + let result = GlimmerParser::parse(Rule::Template, "{{{raw}}}"); + assert!(result.is_ok(), "Failed to parse triple mustache: {:?}", result.err()); + } + + #[test] + fn test_parse_concat_attr() { + let result = GlimmerParser::parse(Rule::Template, r#"
"#); + assert!(result.is_ok(), "Failed to parse concat attr: {:?}", result.err()); + } + + #[test] + fn test_parse_splattributes() { + let result = GlimmerParser::parse(Rule::Template, "
"); + assert!(result.is_ok(), "Failed to parse splattributes: {:?}", result.err()); + } + + #[test] + fn test_parse_modifier() { + let result = GlimmerParser::parse(Rule::Template, r#"
"#); + assert!(result.is_ok(), "Failed to parse modifier: {:?}", result.err()); + } + + #[test] + fn test_parse_hash_pairs() { + let result = GlimmerParser::parse(Rule::Template, "{{component name=value class=\"foo\"}}"); + assert!(result.is_ok(), "Failed to parse hash pairs: {:?}", result.err()); + } + + #[test] + fn test_parse_this_path() { + let result = GlimmerParser::parse(Rule::Template, "{{this.foo}}"); + assert!(result.is_ok(), "Failed to parse this path: {:?}", result.err()); + } + + #[test] + fn test_parse_at_path() { + let result = GlimmerParser::parse(Rule::Template, "{{@name}}"); + assert!(result.is_ok(), "Failed to parse at path: {:?}", result.err()); + } + + #[test] + fn test_parse_void_element() { + let result = GlimmerParser::parse(Rule::Template, ""); + assert!(result.is_ok(), "Failed to parse void element: {:?}", result.err()); + } + + #[test] + fn test_parse_escaped_mustache() { + let result = GlimmerParser::parse(Rule::Template, "\\{{not a mustache}}"); + assert!(result.is_ok(), "Failed to parse escaped mustache: {:?}", result.err()); + } +} diff --git a/packages/@handlebars/parser/CHANGELOG.md b/packages/@handlebars/parser/CHANGELOG.md deleted file mode 100644 index cd310aaf6b9..00000000000 --- a/packages/@handlebars/parser/CHANGELOG.md +++ /dev/null @@ -1,80 +0,0 @@ -# Changelog - -## Release (2025-11-29) - -* @handlebars/parser 2.2.2 (patch) - -#### :bug: Bug Fix -* `@handlebars/parser` - * [#27](https://github.com/handlebars-lang/handlebars-parser/pull/27) Fix commonjs build ([@kaermorchen](https://github.com/kaermorchen)) - -#### Committers: 1 -- Stanislav Romanov ([@kaermorchen](https://github.com/kaermorchen)) - -## Release (2025-08-01) - -* @handlebars/parser 2.2.1 (patch) - -#### :bug: Bug Fix -* `@handlebars/parser` - * [#24](https://github.com/handlebars-lang/handlebars-parser/pull/24) fix node engine and create a test matrix in CI ([@mansona](https://github.com/mansona)) - -#### Committers: 1 -- Chris Manson ([@mansona](https://github.com/mansona)) - -## Release (2025-03-19) - -* @handlebars/parser 2.2.0 (minor) - -#### :rocket: Enhancement -* `@handlebars/parser` - * [#15](https://github.com/handlebars-lang/handlebars-parser/pull/15) Implement hash and array literal syntax ([@wycats](https://github.com/wycats)) - * [#14](https://github.com/handlebars-lang/handlebars-parser/pull/14) Add support for a `#` prefix in path segments ([@wycats](https://github.com/wycats)) - -#### :bug: Bug Fix -* `@handlebars/parser` - * [#6](https://github.com/handlebars-lang/handlebars-parser/pull/6) [bugfix] Don't emit `parts: [undefined]` for `{{this}}` ([@dfreeman](https://github.com/dfreeman)) - -#### :house: Internal -* `@handlebars/parser` - * [#17](https://github.com/handlebars-lang/handlebars-parser/pull/17) Add release plan, remove release-it ([@NullVoxPopuli](https://github.com/NullVoxPopuli)) - -#### Committers: 3 -- Dan Freeman ([@dfreeman](https://github.com/dfreeman)) -- Yehuda Katz ([@wycats](https://github.com/wycats)) -- [@NullVoxPopuli](https://github.com/NullVoxPopuli) - -## v2.1.0 (2021-02-22) - -#### :rocket: Enhancement -* [#4](https://github.com/handlebars-lang/handlebars-parser/pull/4) [FEATURE] Allows SubExpressions to be PathExpression roots ([@pzuraq](https://github.com/pzuraq)) - -#### Committers: 1 -- Chris Garrett ([@pzuraq](https://github.com/pzuraq)) - -## v2.0.0 (2020-12-09) - -#### :boom: Breaking Change -* [#3](https://github.com/handlebars-lang/handlebars-parser/pull/3) Make sub-expressions callable ([@pzuraq](https://github.com/pzuraq)) - -#### Committers: 1 -- Chris Garrett ([@pzuraq](https://github.com/pzuraq)) - -## v1.1.0 (2020-09-18) - -#### :rocket: Enhancement -* [#2](https://github.com/handlebars-lang/handlebars-parser/pull/2) [FEAT] Adds types ([@pzuraq](https://github.com/pzuraq)) - -#### Committers: 1 -- Chris Garrett ([@pzuraq](https://github.com/pzuraq)) - - -## v1.0.0 (2020-09-14) - -#### :rocket: Enhancement -* [#1](https://github.com/handlebars-lang/handlebars-parser/pull/1) [FEAT] Adds initial setup, lint, ci ([@pzuraq](https://github.com/pzuraq)) - -#### Committers: 1 -- Chris Garrett ([@pzuraq](https://github.com/pzuraq)) - - diff --git a/packages/@handlebars/parser/README.md b/packages/@handlebars/parser/README.md deleted file mode 100644 index f77e27ef052..00000000000 --- a/packages/@handlebars/parser/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Handlebars Parser - -The official Handlebars.js parser. This package contains the definition for -for the Handlebars language AST, and the parser for parsing into that AST. diff --git a/packages/@handlebars/parser/lib/exception.js b/packages/@handlebars/parser/lib/exception.js deleted file mode 100644 index 94ffc7340b7..00000000000 --- a/packages/@handlebars/parser/lib/exception.js +++ /dev/null @@ -1,68 +0,0 @@ -const errorProps = [ - 'description', - 'fileName', - 'lineNumber', - 'endLineNumber', - 'message', - 'name', - 'number', - 'stack', -]; - -function Exception(message, node) { - let loc = node && node.loc, - line, - endLineNumber, - column, - endColumn; - - if (loc) { - line = loc.start.line; - endLineNumber = loc.end.line; - column = loc.start.column; - endColumn = loc.end.column; - - message += ' - ' + line + ':' + column; - } - - let tmp = Error.prototype.constructor.call(this, message); - - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. - for (let idx = 0; idx < errorProps.length; idx++) { - this[errorProps[idx]] = tmp[errorProps[idx]]; - } - - /* istanbul ignore else */ - if (Error.captureStackTrace) { - Error.captureStackTrace(this, Exception); - } - - try { - if (loc) { - this.lineNumber = line; - this.endLineNumber = endLineNumber; - - // Work around issue under safari where we can't directly set the column value - /* istanbul ignore next */ - if (Object.defineProperty) { - Object.defineProperty(this, 'column', { - value: column, - enumerable: true, - }); - Object.defineProperty(this, 'endColumn', { - value: endColumn, - enumerable: true, - }); - } else { - this.column = column; - this.endColumn = endColumn; - } - } - } catch (nop) { - /* Ignore if the browser is very particular */ - } -} - -Exception.prototype = new Error(); - -export default Exception; diff --git a/packages/@handlebars/parser/lib/helpers.js b/packages/@handlebars/parser/lib/helpers.js deleted file mode 100644 index fb2998e2ebe..00000000000 --- a/packages/@handlebars/parser/lib/helpers.js +++ /dev/null @@ -1,224 +0,0 @@ -import Exception from './exception.js'; - -function validateClose(open, close) { - close = close.path ? close.path.original : close; - - if (open.path.original !== close) { - let errorNode = { loc: open.path.loc }; - - throw new Exception(open.path.original + " doesn't match " + close, errorNode); - } -} - -export function SourceLocation(source, locInfo) { - this.source = source; - this.start = { - line: locInfo.first_line, - column: locInfo.first_column, - }; - this.end = { - line: locInfo.last_line, - column: locInfo.last_column, - }; -} - -export function id(token) { - if (/^\[.*\]$/.test(token)) { - return token.substring(1, token.length - 1); - } else { - return token; - } -} - -export function stripFlags(open, close) { - return { - open: open.charAt(2) === '~', - close: close.charAt(close.length - 3) === '~', - }; -} - -export function stripComment(comment) { - return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, ''); -} - -export function preparePath(data, sexpr, parts, loc) { - loc = this.locInfo(loc); - - let original; - - if (data) { - original = '@'; - } else if (sexpr) { - original = sexpr.original + '.'; - } else { - original = ''; - } - - let tail = []; - let depth = 0; - - for (let i = 0, l = parts.length; i < l; i++) { - let part = parts[i].part; - // If we have [] syntax then we do not treat path references as operators, - // i.e. foo.[this] resolves to approximately context.foo['this'] - let isLiteral = parts[i].original !== part; - let separator = parts[i].separator; - - let partPrefix = separator === '.#' ? '#' : ''; - - original += (separator || '') + part; - - if (!isLiteral && (part === '..' || part === '.' || part === 'this')) { - if (tail.length > 0) { - throw new Exception('Invalid path: ' + original, { loc }); - } else if (part === '..') { - depth++; - } - } else { - tail.push(`${partPrefix}${part}`); - } - } - - let head = sexpr || tail.shift(); - - return { - type: 'PathExpression', - this: original.startsWith('this.'), - data, - depth, - head, - tail, - parts: head ? [head, ...tail] : tail, - original, - loc, - }; -} - -export function prepareMustache(path, params, hash, open, strip, locInfo) { - // Must use charAt to support IE pre-10 - let escapeFlag = open.charAt(3) || open.charAt(2), - escaped = escapeFlag !== '{' && escapeFlag !== '&'; - - let decorator = /\*/.test(open); - return { - type: decorator ? 'Decorator' : 'MustacheStatement', - path, - params, - hash, - escaped, - strip, - loc: this.locInfo(locInfo), - }; -} - -export function prepareRawBlock(openRawBlock, contents, close, locInfo) { - validateClose(openRawBlock, close); - - locInfo = this.locInfo(locInfo); - let program = { - type: 'Program', - body: contents, - strip: {}, - loc: locInfo, - }; - - return { - type: 'BlockStatement', - path: openRawBlock.path, - params: openRawBlock.params, - hash: openRawBlock.hash, - program, - openStrip: {}, - inverseStrip: {}, - closeStrip: {}, - loc: locInfo, - }; -} - -export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) { - if (close && close.path) { - validateClose(openBlock, close); - } - - let decorator = /\*/.test(openBlock.open); - - program.blockParams = openBlock.blockParams; - - let inverse, inverseStrip; - - if (inverseAndProgram) { - if (decorator) { - throw new Exception('Unexpected inverse block on decorator', inverseAndProgram); - } - - if (inverseAndProgram.chain) { - inverseAndProgram.program.body[0].closeStrip = close.strip; - } - - inverseStrip = inverseAndProgram.strip; - inverse = inverseAndProgram.program; - } - - if (inverted) { - inverted = inverse; - inverse = program; - program = inverted; - } - - return { - type: decorator ? 'DecoratorBlock' : 'BlockStatement', - path: openBlock.path, - params: openBlock.params, - hash: openBlock.hash, - program, - inverse, - openStrip: openBlock.strip, - inverseStrip, - closeStrip: close && close.strip, - loc: this.locInfo(locInfo), - }; -} - -export function prepareProgram(statements, loc) { - if (!loc && statements.length) { - const firstLoc = statements[0].loc, - lastLoc = statements[statements.length - 1].loc; - - /* istanbul ignore else */ - if (firstLoc && lastLoc) { - loc = { - source: firstLoc.source, - start: { - line: firstLoc.start.line, - column: firstLoc.start.column, - }, - end: { - line: lastLoc.end.line, - column: lastLoc.end.column, - }, - }; - } - } - - return { - type: 'Program', - body: statements, - strip: {}, - loc: loc, - }; -} - -export function preparePartialBlock(open, program, close, locInfo) { - validateClose(open, close); - - return { - type: 'PartialBlockStatement', - name: open.path, - params: open.params, - hash: open.hash, - program, - openStrip: open.strip, - closeStrip: close && close.strip, - loc: this.locInfo(locInfo), - }; -} diff --git a/packages/@handlebars/parser/lib/index.js b/packages/@handlebars/parser/lib/index.js deleted file mode 100644 index cf22bff15b9..00000000000 --- a/packages/@handlebars/parser/lib/index.js +++ /dev/null @@ -1,6 +0,0 @@ -export { default as Visitor } from './visitor.js'; -export { default as WhitespaceControl } from './whitespace-control.js'; -export { default as parser } from './parser.js'; -export { default as Exception } from './exception.js'; -export { print, PrintVisitor } from './printer.js'; -export { parse, parseWithoutProcessing } from './parse.js'; diff --git a/packages/@handlebars/parser/lib/parse.js b/packages/@handlebars/parser/lib/parse.js deleted file mode 100644 index 9927b5f4d73..00000000000 --- a/packages/@handlebars/parser/lib/parse.js +++ /dev/null @@ -1,73 +0,0 @@ -import parser from './parser.js'; -import WhitespaceControl from './whitespace-control.js'; -import * as Helpers from './helpers.js'; - -let baseHelpers = {}; - -for (let helper in Helpers) { - if (Object.prototype.hasOwnProperty.call(Helpers, helper)) { - baseHelpers[helper] = Helpers[helper]; - } -} - -export function parseWithoutProcessing(input, options) { - // Just return if an already-compiled AST was passed in. - if (input.type === 'Program') { - return input; - } - - parser.yy = baseHelpers; - - // Altering the shared object here, but this is ok as parser is a sync operation - parser.yy.locInfo = function (locInfo) { - return new Helpers.SourceLocation(options && options.srcName, locInfo); - }; - - let squareSyntax; - - if (typeof options?.syntax?.square === 'function') { - squareSyntax = options.syntax.square; - } else if (options?.syntax?.square === 'node') { - squareSyntax = arrayLiteralNode; - } else { - squareSyntax = 'string'; - } - - let hashSyntax; - - if (typeof options?.syntax?.hash === 'function') { - hashSyntax = options.syntax.hash; - } else { - hashSyntax = hashLiteralNode; - } - - parser.yy.syntax = { - square: squareSyntax, - hash: hashSyntax, - }; - - return parser.parse(input); -} - -function arrayLiteralNode(array, loc) { - return { - type: 'ArrayLiteral', - items: array, - loc, - }; -} - -function hashLiteralNode(hash, loc) { - return { - type: 'HashLiteral', - pairs: hash.pairs, - loc, - }; -} - -export function parse(input, options) { - let ast = parseWithoutProcessing(input, options); - let strip = new WhitespaceControl(options); - - return strip.accept(ast); -} diff --git a/packages/@handlebars/parser/lib/parser.js b/packages/@handlebars/parser/lib/parser.js deleted file mode 100644 index 136e73cc256..00000000000 --- a/packages/@handlebars/parser/lib/parser.js +++ /dev/null @@ -1,2032 +0,0 @@ -// @ts-nocheck -/* parser generated by jison 0.4.18 */ -/* - Returns a Parser object of the following structure: - - Parser: { - yy: {} - } - - Parser.prototype: { - yy: {}, - trace: function(), - symbols_: {associative list: name ==> number}, - terminals_: {associative list: number ==> name}, - productions_: [...], - performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$), - table: [...], - defaultActions: {...}, - parseError: function(str, hash), - parse: function(input), - - lexer: { - EOF: 1, - parseError: function(str, hash), - setInput: function(input), - input: function(), - unput: function(str), - more: function(), - less: function(n), - pastInput: function(), - upcomingInput: function(), - showPosition: function(), - test_match: function(regex_match_array, rule_index), - next: function(), - lex: function(), - begin: function(condition), - popState: function(), - _currentRules: function(), - topState: function(), - pushState: function(condition), - - options: { - ranges: boolean (optional: true ==> token location info will include a .range[] member) - flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match) - backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code) - }, - - performAction: function(yy, yy_, $avoiding_name_collisions, YY_START), - rules: [...], - conditions: {associative list: name ==> set}, - } - } - - - token location info (@$, _$, etc.): { - first_line: n, - last_line: n, - first_column: n, - last_column: n, - range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based) - } - - - the parseError function receives a 'hash' object with these members for lexer and parser errors: { - text: (matched text) - token: (the produced terminal token, if any) - line: (yylineno) - } - while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: { - loc: (yylloc) - expected: (string describing the set of expected tokens) - recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error) - } -*/ -var parser = (function () { - var o = function (k, v, o, l) { - for (o = o || {}, l = k.length; l--; o[k[l]] = v); - return o; - }, - $V0 = [2, 52], - $V1 = [1, 20], - $V2 = [5, 14, 15, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61], - $V3 = [1, 44], - $V4 = [1, 40], - $V5 = [1, 43], - $V6 = [1, 33], - $V7 = [1, 34], - $V8 = [1, 35], - $V9 = [1, 36], - $Va = [1, 37], - $Vb = [1, 42], - $Vc = [1, 46], - $Vd = [14, 15, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61], - $Ve = [14, 15, 19, 29, 34, 44, 47, 48, 53, 57, 61], - $Vf = [15, 18], - $Vg = [14, 15, 19, 29, 34, 47, 48, 53, 57, 61], - $Vh = [33, 67, 73, 75, 84, 85, 86, 87, 88, 89], - $Vi = [23, 33, 56, 67, 68, 73, 75, 77, 79, 84, 85, 86, 87, 88, 89], - $Vj = [1, 62], - $Vk = [1, 63], - $Vl = [23, 33, 56, 68, 73, 79], - $Vm = [23, 33, 56, 67, 68, 73, 75, 77, 79, 84, 85, 86, 87, 88, 89, 92, 93], - $Vn = [2, 51], - $Vo = [1, 64], - $Vp = [67, 73, 75, 77, 84, 85, 86, 87, 88, 89], - $Vq = [56, 67, 73, 75, 84, 85, 86, 87, 88, 89], - $Vr = [1, 75], - $Vs = [1, 76], - $Vt = [1, 83], - $Vu = [33, 67, 73, 75, 79, 84, 85, 86, 87, 88, 89], - $Vv = [23, 67, 73, 75, 84, 85, 86, 87, 88, 89], - $Vw = [67, 68, 73, 75, 84, 85, 86, 87, 88, 89], - $Vx = [33, 79], - $Vy = [1, 134], - $Vz = [73, 81]; - var parser = { - trace: function trace() {}, - yy: {}, - symbols_: { - error: 2, - root: 3, - program: 4, - EOF: 5, - program_repetition0: 6, - statement: 7, - mustache: 8, - block: 9, - rawBlock: 10, - partial: 11, - partialBlock: 12, - content: 13, - COMMENT: 14, - CONTENT: 15, - openRawBlock: 16, - rawBlock_repetition0: 17, - END_RAW_BLOCK: 18, - OPEN_RAW_BLOCK: 19, - helperName: 20, - openRawBlock_repetition0: 21, - openRawBlock_option0: 22, - CLOSE_RAW_BLOCK: 23, - openBlock: 24, - block_option0: 25, - closeBlock: 26, - openInverse: 27, - block_option1: 28, - OPEN_BLOCK: 29, - openBlock_repetition0: 30, - openBlock_option0: 31, - openBlock_option1: 32, - CLOSE: 33, - OPEN_INVERSE: 34, - openInverse_repetition0: 35, - openInverse_option0: 36, - openInverse_option1: 37, - openInverseChain: 38, - OPEN_INVERSE_CHAIN: 39, - openInverseChain_repetition0: 40, - openInverseChain_option0: 41, - openInverseChain_option1: 42, - inverseAndProgram: 43, - INVERSE: 44, - inverseChain: 45, - inverseChain_option0: 46, - OPEN_ENDBLOCK: 47, - OPEN: 48, - hash: 49, - expr: 50, - mustache_repetition0: 51, - mustache_option0: 52, - OPEN_UNESCAPED: 53, - mustache_repetition1: 54, - mustache_option1: 55, - CLOSE_UNESCAPED: 56, - OPEN_PARTIAL: 57, - partial_repetition0: 58, - partial_option0: 59, - openPartialBlock: 60, - OPEN_PARTIAL_BLOCK: 61, - openPartialBlock_repetition0: 62, - openPartialBlock_option0: 63, - exprHead: 64, - arrayLiteral: 65, - sexpr: 66, - OPEN_SEXPR: 67, - CLOSE_SEXPR: 68, - sexpr_repetition0: 69, - sexpr_option0: 70, - hash_repetition_plus0: 71, - hashSegment: 72, - ID: 73, - EQUALS: 74, - OPEN_ARRAY: 75, - arrayLiteral_repetition0: 76, - CLOSE_ARRAY: 77, - blockParams: 78, - OPEN_BLOCK_PARAMS: 79, - blockParams_repetition_plus0: 80, - CLOSE_BLOCK_PARAMS: 81, - path: 82, - dataName: 83, - STRING: 84, - NUMBER: 85, - BOOLEAN: 86, - UNDEFINED: 87, - NULL: 88, - DATA: 89, - pathSegments: 90, - sep: 91, - SEP: 92, - PRIVATE_SEP: 93, - $accept: 0, - $end: 1, - }, - terminals_: { - 2: 'error', - 5: 'EOF', - 14: 'COMMENT', - 15: 'CONTENT', - 18: 'END_RAW_BLOCK', - 19: 'OPEN_RAW_BLOCK', - 23: 'CLOSE_RAW_BLOCK', - 29: 'OPEN_BLOCK', - 33: 'CLOSE', - 34: 'OPEN_INVERSE', - 39: 'OPEN_INVERSE_CHAIN', - 44: 'INVERSE', - 47: 'OPEN_ENDBLOCK', - 48: 'OPEN', - 53: 'OPEN_UNESCAPED', - 56: 'CLOSE_UNESCAPED', - 57: 'OPEN_PARTIAL', - 61: 'OPEN_PARTIAL_BLOCK', - 67: 'OPEN_SEXPR', - 68: 'CLOSE_SEXPR', - 73: 'ID', - 74: 'EQUALS', - 75: 'OPEN_ARRAY', - 77: 'CLOSE_ARRAY', - 79: 'OPEN_BLOCK_PARAMS', - 81: 'CLOSE_BLOCK_PARAMS', - 84: 'STRING', - 85: 'NUMBER', - 86: 'BOOLEAN', - 87: 'UNDEFINED', - 88: 'NULL', - 89: 'DATA', - 92: 'SEP', - 93: 'PRIVATE_SEP', - }, - productions_: [ - 0, - [3, 2], - [4, 1], - [7, 1], - [7, 1], - [7, 1], - [7, 1], - [7, 1], - [7, 1], - [7, 1], - [13, 1], - [10, 3], - [16, 5], - [9, 4], - [9, 4], - [24, 6], - [27, 6], - [38, 6], - [43, 2], - [45, 3], - [45, 1], - [26, 3], - [8, 3], - [8, 5], - [8, 5], - [11, 5], - [12, 3], - [60, 5], - [50, 1], - [50, 1], - [64, 1], - [64, 1], - [66, 3], - [66, 5], - [49, 1], - [72, 3], - [65, 3], - [78, 3], - [20, 1], - [20, 1], - [20, 1], - [20, 1], - [20, 1], - [20, 1], - [20, 1], - [83, 2], - [91, 1], - [91, 1], - [82, 3], - [82, 1], - [90, 3], - [90, 1], - [6, 0], - [6, 2], - [17, 0], - [17, 2], - [21, 0], - [21, 2], - [22, 0], - [22, 1], - [25, 0], - [25, 1], - [28, 0], - [28, 1], - [30, 0], - [30, 2], - [31, 0], - [31, 1], - [32, 0], - [32, 1], - [35, 0], - [35, 2], - [36, 0], - [36, 1], - [37, 0], - [37, 1], - [40, 0], - [40, 2], - [41, 0], - [41, 1], - [42, 0], - [42, 1], - [46, 0], - [46, 1], - [51, 0], - [51, 2], - [52, 0], - [52, 1], - [54, 0], - [54, 2], - [55, 0], - [55, 1], - [58, 0], - [58, 2], - [59, 0], - [59, 1], - [62, 0], - [62, 2], - [63, 0], - [63, 1], - [69, 0], - [69, 2], - [70, 0], - [70, 1], - [71, 1], - [71, 2], - [76, 0], - [76, 2], - [80, 1], - [80, 2], - ], - performAction: function anonymous( - yytext, - yyleng, - yylineno, - yy, - yystate /* action[1] */, - $$ /* vstack */, - _$ /* lstack */ - ) { - /* this == yyval */ - - var $0 = $$.length - 1; - switch (yystate) { - case 1: - return $$[$0 - 1]; - break; - case 2: - this.$ = yy.prepareProgram($$[$0]); - break; - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 20: - case 28: - case 29: - case 30: - case 31: - case 38: - case 39: - case 46: - case 47: - this.$ = $$[$0]; - break; - case 9: - this.$ = { - type: 'CommentStatement', - value: yy.stripComment($$[$0]), - strip: yy.stripFlags($$[$0], $$[$0]), - loc: yy.locInfo(this._$), - }; - - break; - case 10: - this.$ = { - type: 'ContentStatement', - original: $$[$0], - value: $$[$0], - loc: yy.locInfo(this._$), - }; - - break; - case 11: - this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); - break; - case 12: - this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] }; - break; - case 13: - this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$); - break; - case 14: - this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$); - break; - case 15: - this.$ = { - open: $$[$0 - 5], - path: $$[$0 - 4], - params: $$[$0 - 3], - hash: $$[$0 - 2], - blockParams: $$[$0 - 1], - strip: yy.stripFlags($$[$0 - 5], $$[$0]), - }; - break; - case 16: - case 17: - this.$ = { - path: $$[$0 - 4], - params: $$[$0 - 3], - hash: $$[$0 - 2], - blockParams: $$[$0 - 1], - strip: yy.stripFlags($$[$0 - 5], $$[$0]), - }; - break; - case 18: - this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] }; - break; - case 19: - var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$), - program = yy.prepareProgram([inverse], $$[$0 - 1].loc); - program.chained = true; - - this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true }; - - break; - case 21: - this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) }; - break; - case 22: - this.$ = yy.prepareMustache( - yy.syntax.hash($$[$0 - 1], yy.locInfo(this._$), { yy, syntax: 'expr' }), - [], - undefined, - $$[$0 - 2], - yy.stripFlags($$[$0 - 2], $$[$0]), - this._$ - ); - break; - case 23: - case 24: - this.$ = yy.prepareMustache( - $$[$0 - 3], - $$[$0 - 2], - $$[$0 - 1], - $$[$0 - 4], - yy.stripFlags($$[$0 - 4], $$[$0]), - this._$ - ); - break; - case 25: - this.$ = { - type: 'PartialStatement', - name: $$[$0 - 3], - params: $$[$0 - 2], - hash: $$[$0 - 1], - indent: '', - strip: yy.stripFlags($$[$0 - 4], $$[$0]), - loc: yy.locInfo(this._$), - }; - - break; - case 26: - this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); - break; - case 27: - this.$ = { - path: $$[$0 - 3], - params: $$[$0 - 2], - hash: $$[$0 - 1], - strip: yy.stripFlags($$[$0 - 4], $$[$0]), - }; - break; - case 32: - this.$ = yy.syntax.hash($$[$0 - 1], yy.locInfo(this._$), { yy, syntax: 'expr' }); - break; - case 33: - this.$ = { - type: 'SubExpression', - path: $$[$0 - 3], - params: $$[$0 - 2], - hash: $$[$0 - 1], - loc: yy.locInfo(this._$), - }; - - break; - case 34: - this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) }; - break; - case 35: - this.$ = { - type: 'HashPair', - key: yy.id($$[$0 - 2]), - value: $$[$0], - loc: yy.locInfo(this._$), - }; - break; - case 36: - this.$ = yy.syntax.square($$[$0 - 1], yy.locInfo(this._$), { yy, syntax: 'expr' }); - break; - case 37: - this.$ = yy.id($$[$0 - 1]); - break; - case 40: - this.$ = { - type: 'StringLiteral', - value: $$[$0], - original: $$[$0], - loc: yy.locInfo(this._$), - }; - break; - case 41: - this.$ = { - type: 'NumberLiteral', - value: Number($$[$0]), - original: Number($$[$0]), - loc: yy.locInfo(this._$), - }; - break; - case 42: - this.$ = { - type: 'BooleanLiteral', - value: $$[$0] === 'true', - original: $$[$0] === 'true', - loc: yy.locInfo(this._$), - }; - break; - case 43: - this.$ = { - type: 'UndefinedLiteral', - original: undefined, - value: undefined, - loc: yy.locInfo(this._$), - }; - break; - case 44: - this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) }; - break; - case 45: - this.$ = yy.preparePath(true, false, $$[$0], this._$); - break; - case 48: - this.$ = yy.preparePath(false, $$[$0 - 2], $$[$0], this._$); - break; - case 49: - this.$ = yy.preparePath(false, false, $$[$0], this._$); - break; - case 50: - $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] }); - this.$ = $$[$0 - 2]; - break; - case 51: - this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }]; - break; - case 52: - case 54: - case 56: - case 64: - case 70: - case 76: - case 84: - case 88: - case 92: - case 96: - case 100: - case 106: - this.$ = []; - break; - case 53: - case 55: - case 57: - case 65: - case 71: - case 77: - case 85: - case 89: - case 93: - case 97: - case 101: - case 105: - case 107: - case 109: - $$[$0 - 1].push($$[$0]); - break; - case 104: - case 108: - this.$ = [$$[$0]]; - break; - } - }, - table: [ - o([5, 14, 15, 19, 29, 34, 48, 53, 57, 61], $V0, { 3: 1, 4: 2, 6: 3 }), - { 1: [3] }, - { 5: [1, 4] }, - o([5, 39, 44, 47], [2, 2], { - 7: 5, - 8: 6, - 9: 7, - 10: 8, - 11: 9, - 12: 10, - 13: 11, - 24: 15, - 27: 16, - 16: 17, - 60: 19, - 14: [1, 12], - 15: $V1, - 19: [1, 23], - 29: [1, 21], - 34: [1, 22], - 48: [1, 13], - 53: [1, 14], - 57: [1, 18], - 61: [1, 24], - }), - { 1: [2, 1] }, - o($V2, [2, 53]), - o($V2, [2, 3]), - o($V2, [2, 4]), - o($V2, [2, 5]), - o($V2, [2, 6]), - o($V2, [2, 7]), - o($V2, [2, 8]), - o($V2, [2, 9]), - { - 20: 28, - 49: 25, - 50: 26, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { - 20: 28, - 50: 45, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vd, $V0, { 6: 3, 4: 47 }), - o($Ve, $V0, { 6: 3, 4: 48 }), - o($Vf, [2, 54], { 17: 49 }), - { - 20: 28, - 50: 50, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vg, $V0, { 6: 3, 4: 51 }), - o([5, 14, 15, 18, 19, 29, 34, 39, 44, 47, 48, 53, 57, 61], [2, 10]), - { - 20: 52, - 64: 53, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { - 20: 54, - 64: 53, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { - 20: 55, - 64: 53, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { - 20: 28, - 50: 56, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 33: [1, 57] }, - o($Vh, [2, 84], { 51: 58 }), - o([23, 33, 56, 68, 79], [2, 34], { 72: 59, 73: [1, 60] }), - o($Vi, [2, 28]), - o($Vi, [2, 29], { 91: 61, 92: $Vj, 93: $Vk }), - o($Vl, [2, 104]), - o($Vi, [2, 38]), - o($Vi, [2, 39]), - o($Vi, [2, 40]), - o($Vi, [2, 41]), - o($Vi, [2, 42]), - o($Vi, [2, 43]), - o($Vi, [2, 44]), - o($Vm, [2, 30]), - o($Vm, [2, 31]), - o([23, 33, 56, 67, 68, 73, 75, 79, 84, 85, 86, 87, 88, 89, 92, 93], $Vn, { 74: $Vo }), - o($Vi, [2, 49], { 91: 65, 92: $Vj, 93: $Vk }), - { 73: $Vc, 90: 66 }, - o($Vp, [2, 106], { 76: 67 }), - { - 20: 28, - 49: 68, - 50: 69, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vq, [2, 88], { 54: 70 }), - o($Vm, $Vn), - { 25: 71, 38: 73, 39: $Vr, 43: 74, 44: $Vs, 45: 72, 47: [2, 60] }, - { 28: 77, 43: 78, 44: $Vs, 47: [2, 62] }, - { 13: 80, 15: $V1, 18: [1, 79] }, - o($Vh, [2, 92], { 58: 81 }), - { 26: 82, 47: $Vt }, - o($Vu, [2, 64], { 30: 84 }), - { 91: 61, 92: $Vj, 93: $Vk }, - o($Vu, [2, 70], { 35: 85 }), - o($Vv, [2, 56], { 21: 86 }), - o($Vh, [2, 96], { 62: 87 }), - o($V2, [2, 22]), - { - 20: 28, - 33: [2, 86], - 49: 90, - 50: 89, - 52: 88, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vl, [2, 105]), - { 74: $Vo }, - { 73: $Vc, 90: 91 }, - { 73: [2, 46] }, - { 73: [2, 47] }, - { - 20: 28, - 50: 92, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 73: [1, 93] }, - o($Vi, [2, 45], { 91: 65, 92: $Vj, 93: $Vk }), - { - 20: 28, - 50: 95, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 77: [1, 94], - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 68: [1, 96] }, - o($Vw, [2, 100], { 69: 97 }), - { - 20: 28, - 49: 100, - 50: 99, - 55: 98, - 56: [2, 90], - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 26: 101, 47: $Vt }, - { 47: [2, 61] }, - o($Vd, $V0, { 6: 3, 4: 102 }), - { 47: [2, 20] }, - { - 20: 103, - 64: 53, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vg, $V0, { 6: 3, 4: 104 }), - { 26: 105, 47: $Vt }, - { 47: [2, 63] }, - o($V2, [2, 11]), - o($Vf, [2, 55]), - { - 20: 28, - 33: [2, 94], - 49: 108, - 50: 107, - 59: 106, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($V2, [2, 26]), - { - 20: 109, - 64: 53, - 65: 38, - 66: 39, - 67: $V3, - 73: $Vc, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - o($Vx, [2, 66], { - 71: 27, - 20: 28, - 64: 29, - 72: 30, - 82: 31, - 83: 32, - 65: 38, - 66: 39, - 90: 41, - 31: 110, - 50: 111, - 49: 112, - 67: $V3, - 73: $V4, - 75: $V5, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - }), - o($Vx, [2, 72], { - 71: 27, - 20: 28, - 64: 29, - 72: 30, - 82: 31, - 83: 32, - 65: 38, - 66: 39, - 90: 41, - 36: 113, - 50: 114, - 49: 115, - 67: $V3, - 73: $V4, - 75: $V5, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - }), - { - 20: 28, - 22: 116, - 23: [2, 58], - 49: 118, - 50: 117, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { - 20: 28, - 33: [2, 98], - 49: 121, - 50: 120, - 63: 119, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 33: [1, 122] }, - o($Vh, [2, 85]), - { 33: [2, 87] }, - o($Vi, [2, 48], { 91: 65, 92: $Vj, 93: $Vk }), - o($Vl, [2, 35]), - o($Vm, [2, 50]), - o($Vm, [2, 36]), - o($Vp, [2, 107]), - o($Vm, [2, 32]), - { - 20: 28, - 49: 125, - 50: 124, - 64: 29, - 65: 38, - 66: 39, - 67: $V3, - 68: [2, 102], - 70: 123, - 71: 27, - 72: 30, - 73: $V4, - 75: $V5, - 82: 31, - 83: 32, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - 90: 41, - }, - { 56: [1, 126] }, - o($Vq, [2, 89]), - { 56: [2, 91] }, - o($V2, [2, 13]), - { 38: 73, 39: $Vr, 43: 74, 44: $Vs, 45: 128, 46: 127, 47: [2, 82] }, - o($Vu, [2, 76], { 40: 129 }), - { 47: [2, 18] }, - o($V2, [2, 14]), - { 33: [1, 130] }, - o($Vh, [2, 93]), - { 33: [2, 95] }, - { 33: [1, 131] }, - { 32: 132, 33: [2, 68], 78: 133, 79: $Vy }, - o($Vu, [2, 65]), - o($Vx, [2, 67]), - { 33: [2, 74], 37: 135, 78: 136, 79: $Vy }, - o($Vu, [2, 71]), - o($Vx, [2, 73]), - { 23: [1, 137] }, - o($Vv, [2, 57]), - { 23: [2, 59] }, - { 33: [1, 138] }, - o($Vh, [2, 97]), - { 33: [2, 99] }, - o($V2, [2, 23]), - { 68: [1, 139] }, - o($Vw, [2, 101]), - { 68: [2, 103] }, - o($V2, [2, 24]), - { 47: [2, 19] }, - { 47: [2, 83] }, - o($Vx, [2, 78], { - 71: 27, - 20: 28, - 64: 29, - 72: 30, - 82: 31, - 83: 32, - 65: 38, - 66: 39, - 90: 41, - 41: 140, - 50: 141, - 49: 142, - 67: $V3, - 73: $V4, - 75: $V5, - 84: $V6, - 85: $V7, - 86: $V8, - 87: $V9, - 88: $Va, - 89: $Vb, - }), - o($V2, [2, 25]), - o($V2, [2, 21]), - { 33: [1, 143] }, - { 33: [2, 69] }, - { 73: [1, 145], 80: 144 }, - { 33: [1, 146] }, - { 33: [2, 75] }, - o($Vf, [2, 12]), - o($Vg, [2, 27]), - o($Vm, [2, 33]), - { 33: [2, 80], 42: 147, 78: 148, 79: $Vy }, - o($Vu, [2, 77]), - o($Vx, [2, 79]), - o($Vd, [2, 15]), - { 73: [1, 150], 81: [1, 149] }, - o($Vz, [2, 108]), - o($Ve, [2, 16]), - { 33: [1, 151] }, - { 33: [2, 81] }, - { 33: [2, 37] }, - o($Vz, [2, 109]), - o($Vd, [2, 17]), - ], - defaultActions: { - 4: [2, 1], - 62: [2, 46], - 63: [2, 47], - 72: [2, 61], - 74: [2, 20], - 78: [2, 63], - 90: [2, 87], - 100: [2, 91], - 104: [2, 18], - 108: [2, 95], - 118: [2, 59], - 121: [2, 99], - 125: [2, 103], - 127: [2, 19], - 128: [2, 83], - 133: [2, 69], - 136: [2, 75], - 148: [2, 81], - 149: [2, 37], - }, - parseError: function parseError(str, hash) { - if (hash.recoverable) { - this.trace(str); - } else { - var error = new Error(str); - error.hash = hash; - throw error; - } - }, - parse: function parse(input) { - var self = this, - stack = [0], - tstack = [], - vstack = [null], - lstack = [], - table = this.table, - yytext = '', - yylineno = 0, - yyleng = 0, - recovering = 0, - TERROR = 2, - EOF = 1; - var args = lstack.slice.call(arguments, 1); - var lexer = Object.create(this.lexer); - var sharedState = { yy: {} }; - for (var k in this.yy) { - if (Object.prototype.hasOwnProperty.call(this.yy, k)) { - sharedState.yy[k] = this.yy[k]; - } - } - lexer.setInput(input, sharedState.yy); - sharedState.yy.lexer = lexer; - sharedState.yy.parser = this; - if (typeof lexer.yylloc == 'undefined') { - lexer.yylloc = {}; - } - var yyloc = lexer.yylloc; - lstack.push(yyloc); - var ranges = lexer.options && lexer.options.ranges; - if (typeof sharedState.yy.parseError === 'function') { - this.parseError = sharedState.yy.parseError; - } else { - this.parseError = Object.getPrototypeOf(this).parseError; - } - function popStack(n) { - stack.length = stack.length - 2 * n; - vstack.length = vstack.length - n; - lstack.length = lstack.length - n; - } - _token_stack: var lex = function () { - var token; - token = lexer.lex() || EOF; - if (typeof token !== 'number') { - token = self.symbols_[token] || token; - } - return token; - }; - var symbol, - preErrorSymbol, - state, - action, - a, - r, - yyval = {}, - p, - len, - newState, - expected; - while (true) { - state = stack[stack.length - 1]; - if (this.defaultActions[state]) { - action = this.defaultActions[state]; - } else { - if (symbol === null || typeof symbol == 'undefined') { - symbol = lex(); - } - action = table[state] && table[state][symbol]; - } - if (typeof action === 'undefined' || !action.length || !action[0]) { - var errStr = ''; - expected = []; - for (p in table[state]) { - if (this.terminals_[p] && p > TERROR) { - expected.push("'" + this.terminals_[p] + "'"); - } - } - if (lexer.showPosition) { - errStr = - 'Parse error on line ' + - (yylineno + 1) + - ':\n' + - lexer.showPosition() + - '\nExpecting ' + - expected.join(', ') + - ", got '" + - (this.terminals_[symbol] || symbol) + - "'"; - } else { - errStr = - 'Parse error on line ' + - (yylineno + 1) + - ': Unexpected ' + - (symbol == EOF ? 'end of input' : "'" + (this.terminals_[symbol] || symbol) + "'"); - } - this.parseError(errStr, { - text: lexer.match, - token: this.terminals_[symbol] || symbol, - line: lexer.yylineno, - loc: yyloc, - expected: expected, - }); - } - if (action[0] instanceof Array && action.length > 1) { - throw new Error( - 'Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol - ); - } - switch (action[0]) { - case 1: - stack.push(symbol); - vstack.push(lexer.yytext); - lstack.push(lexer.yylloc); - stack.push(action[1]); - symbol = null; - if (!preErrorSymbol) { - yyleng = lexer.yyleng; - yytext = lexer.yytext; - yylineno = lexer.yylineno; - yyloc = lexer.yylloc; - if (recovering > 0) { - recovering--; - } - } else { - symbol = preErrorSymbol; - preErrorSymbol = null; - } - break; - case 2: - len = this.productions_[action[1]][1]; - yyval.$ = vstack[vstack.length - len]; - yyval._$ = { - first_line: lstack[lstack.length - (len || 1)].first_line, - last_line: lstack[lstack.length - 1].last_line, - first_column: lstack[lstack.length - (len || 1)].first_column, - last_column: lstack[lstack.length - 1].last_column, - }; - if (ranges) { - yyval._$.range = [ - lstack[lstack.length - (len || 1)].range[0], - lstack[lstack.length - 1].range[1], - ]; - } - r = this.performAction.apply( - yyval, - [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args) - ); - if (typeof r !== 'undefined') { - return r; - } - if (len) { - stack = stack.slice(0, -1 * len * 2); - vstack = vstack.slice(0, -1 * len); - lstack = lstack.slice(0, -1 * len); - } - stack.push(this.productions_[action[1]][0]); - vstack.push(yyval.$); - lstack.push(yyval._$); - newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; - stack.push(newState); - break; - case 3: - return true; - } - } - return true; - }, - }; - /* generated by jison-lex 0.3.4 */ - var lexer = (function () { - var lexer = { - EOF: 1, - - parseError: function parseError(str, hash) { - if (this.yy.parser) { - this.yy.parser.parseError(str, hash); - } else { - throw new Error(str); - } - }, - - // resets the lexer, sets new input - setInput: function (input, yy) { - this.yy = yy || this.yy || {}; - this._input = input; - this._more = this._backtrack = this.done = false; - this.yylineno = this.yyleng = 0; - this.yytext = this.matched = this.match = ''; - this.conditionStack = ['INITIAL']; - this.yylloc = { - first_line: 1, - first_column: 0, - last_line: 1, - last_column: 0, - }; - if (this.options.ranges) { - this.yylloc.range = [0, 0]; - } - this.offset = 0; - return this; - }, - - // consumes and returns one char from the input - input: function () { - var ch = this._input[0]; - this.yytext += ch; - this.yyleng++; - this.offset++; - this.match += ch; - this.matched += ch; - var lines = ch.match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno++; - this.yylloc.last_line++; - } else { - this.yylloc.last_column++; - } - if (this.options.ranges) { - this.yylloc.range[1]++; - } - - this._input = this._input.slice(1); - return ch; - }, - - // unshifts one char (or a string) into the input - unput: function (ch) { - var len = ch.length; - var lines = ch.split(/(?:\r\n?|\n)/g); - - this._input = ch + this._input; - this.yytext = this.yytext.substr(0, this.yytext.length - len); - //this.yyleng -= len; - this.offset -= len; - var oldLines = this.match.split(/(?:\r\n?|\n)/g); - this.match = this.match.substr(0, this.match.length - 1); - this.matched = this.matched.substr(0, this.matched.length - 1); - - if (lines.length - 1) { - this.yylineno -= lines.length - 1; - } - var r = this.yylloc.range; - - this.yylloc = { - first_line: this.yylloc.first_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.first_column, - last_column: lines - ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + - oldLines[oldLines.length - lines.length].length - - lines[0].length - : this.yylloc.first_column - len, - }; - - if (this.options.ranges) { - this.yylloc.range = [r[0], r[0] + this.yyleng - len]; - } - this.yyleng = this.yytext.length; - return this; - }, - - // When called from action, caches matched text and appends it on next action - more: function () { - this._more = true; - return this; - }, - - // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. - reject: function () { - if (this.options.backtrack_lexer) { - this._backtrack = true; - } else { - return this.parseError( - 'Lexical error on line ' + - (this.yylineno + 1) + - '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + - this.showPosition(), - { - text: '', - token: null, - line: this.yylineno, - } - ); - } - return this; - }, - - // retain first n characters of the match - less: function (n) { - this.unput(this.match.slice(n)); - }, - - // displays already matched input, i.e. for error messages - pastInput: function () { - var past = this.matched.substr(0, this.matched.length - this.match.length); - return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ''); - }, - - // displays upcoming input, i.e. for error messages - upcomingInput: function () { - var next = this.match; - if (next.length < 20) { - next += this._input.substr(0, 20 - next.length); - } - return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ''); - }, - - // displays the character position where the lexing error occurred, i.e. for error messages - showPosition: function () { - var pre = this.pastInput(); - var c = new Array(pre.length + 1).join('-'); - return pre + this.upcomingInput() + '\n' + c + '^'; - }, - - // test the lexed token: return FALSE when not a match, otherwise return token - test_match: function (match, indexed_rule) { - var token, lines, backup; - - if (this.options.backtrack_lexer) { - // save context - backup = { - yylineno: this.yylineno, - yylloc: { - first_line: this.yylloc.first_line, - last_line: this.last_line, - first_column: this.yylloc.first_column, - last_column: this.yylloc.last_column, - }, - yytext: this.yytext, - match: this.match, - matches: this.matches, - matched: this.matched, - yyleng: this.yyleng, - offset: this.offset, - _more: this._more, - _input: this._input, - yy: this.yy, - conditionStack: this.conditionStack.slice(0), - done: this.done, - }; - if (this.options.ranges) { - backup.yylloc.range = this.yylloc.range.slice(0); - } - } - - lines = match[0].match(/(?:\r\n?|\n).*/g); - if (lines) { - this.yylineno += lines.length; - } - this.yylloc = { - first_line: this.yylloc.last_line, - last_line: this.yylineno + 1, - first_column: this.yylloc.last_column, - last_column: lines - ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length - : this.yylloc.last_column + match[0].length, - }; - this.yytext += match[0]; - this.match += match[0]; - this.matches = match; - this.yyleng = this.yytext.length; - if (this.options.ranges) { - this.yylloc.range = [this.offset, (this.offset += this.yyleng)]; - } - this._more = false; - this._backtrack = false; - this._input = this._input.slice(match[0].length); - this.matched += match[0]; - token = this.performAction.call( - this, - this.yy, - this, - indexed_rule, - this.conditionStack[this.conditionStack.length - 1] - ); - if (this.done && this._input) { - this.done = false; - } - if (token) { - return token; - } else if (this._backtrack) { - // recover context - for (var k in backup) { - this[k] = backup[k]; - } - return false; // rule action called reject() implying the next rule should be tested instead. - } - return false; - }, - - // return next match in input - next: function () { - if (this.done) { - return this.EOF; - } - if (!this._input) { - this.done = true; - } - - var token, match, tempMatch, index; - if (!this._more) { - this.yytext = ''; - this.match = ''; - } - var rules = this._currentRules(); - for (var i = 0; i < rules.length; i++) { - tempMatch = this._input.match(this.rules[rules[i]]); - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { - match = tempMatch; - index = i; - if (this.options.backtrack_lexer) { - token = this.test_match(tempMatch, rules[i]); - if (token !== false) { - return token; - } else if (this._backtrack) { - match = false; - continue; // rule action called reject() implying a rule MISmatch. - } else { - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - } else if (!this.options.flex) { - break; - } - } - } - if (match) { - token = this.test_match(match, rules[index]); - if (token !== false) { - return token; - } - // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace) - return false; - } - if (this._input === '') { - return this.EOF; - } else { - return this.parseError( - 'Lexical error on line ' + - (this.yylineno + 1) + - '. Unrecognized text.\n' + - this.showPosition(), - { - text: '', - token: null, - line: this.yylineno, - } - ); - } - }, - - // return next match that has a token - lex: function lex() { - var r = this.next(); - if (r) { - return r; - } else { - return this.lex(); - } - }, - - // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) - begin: function begin(condition) { - this.conditionStack.push(condition); - }, - - // pop the previously active lexer condition state off the condition stack - popState: function popState() { - var n = this.conditionStack.length - 1; - if (n > 0) { - return this.conditionStack.pop(); - } else { - return this.conditionStack[0]; - } - }, - - // produce the lexer rule set which is active for the currently active lexer condition state - _currentRules: function _currentRules() { - if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { - return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; - } else { - return this.conditions['INITIAL'].rules; - } - }, - - // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available - topState: function topState(n) { - n = this.conditionStack.length - 1 - Math.abs(n || 0); - if (n >= 0) { - return this.conditionStack[n]; - } else { - return 'INITIAL'; - } - }, - - // alias for begin(condition) - pushState: function pushState(condition) { - this.begin(condition); - }, - - // return the number of states currently on the stack - stateStackSize: function stateStackSize() { - return this.conditionStack.length; - }, - options: {}, - performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { - function strip(start, end) { - return (yy_.yytext = yy_.yytext.substring(start, yy_.yyleng - end + start)); - } - - var YYSTATE = YY_START; - switch ($avoiding_name_collisions) { - case 0: - if (yy_.yytext.slice(-2) === '\\\\') { - strip(0, 1); - this.begin('mu'); - } else if (yy_.yytext.slice(-1) === '\\') { - strip(0, 1); - this.begin('emu'); - } else { - this.begin('mu'); - } - if (yy_.yytext) return 15; - - break; - case 1: - return 15; - break; - case 2: - this.popState(); - return 15; - - break; - case 3: - this.begin('raw'); - return 15; - break; - case 4: - this.popState(); - // Should be using `this.topState()` below, but it currently - // returns the second top instead of the first top. Opened an - // issue about it at https://github.com/zaach/jison/issues/291 - if (this.conditionStack[this.conditionStack.length - 1] === 'raw') { - return 15; - } else { - strip(5, 9); - return 18; - } - - break; - case 5: - return 15; - break; - case 6: - this.popState(); - return 14; - - break; - case 7: - return 67; - break; - case 8: - return 68; - break; - case 9: - if (yy.syntax.square === 'string') { - this.unput(yy_.yytext); - // escaped literal - this.begin('escl'); - } else { - return 75; - } - - break; - case 10: - return 77; - break; - case 11: - return 19; - break; - case 12: - this.popState(); - this.begin('raw'); - return 23; - - break; - case 13: - return 57; - break; - case 14: - return 61; - break; - case 15: - return 29; - break; - case 16: - return 47; - break; - case 17: - this.popState(); - return 44; - break; - case 18: - this.popState(); - return 44; - break; - case 19: - return 34; - break; - case 20: - return 39; - break; - case 21: - return 53; - break; - case 22: - return 48; - break; - case 23: - this.unput(yy_.yytext); - this.popState(); - this.begin('com'); - - break; - case 24: - this.popState(); - return 14; - - break; - case 25: - return 48; - break; - case 26: - return 74; - break; - case 27: - return 73; - break; - case 28: - return 73; - break; - case 29: - return 93; - break; - case 30: - return 92; - break; - case 31: // ignore whitespace - break; - case 32: - this.popState(); - return 56; - break; - case 33: - this.popState(); - return 33; - break; - case 34: - yy_.yytext = strip(1, 2).replace(/\\"/g, '"'); - return 84; - break; - case 35: - yy_.yytext = strip(1, 2).replace(/\\'/g, "'"); - return 84; - break; - case 36: - return 89; - break; - case 37: - return 86; - break; - case 38: - return 86; - break; - case 39: - return 87; - break; - case 40: - return 88; - break; - case 41: - return 85; - break; - case 42: - return 79; - break; - case 43: - return 81; - break; - case 44: - return 73; - break; - case 45: - yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1'); - this.popState(); - return 73; - - break; - case 46: - return 'INVALID'; - break; - case 47: - return 5; - break; - } - }, - rules: [ - /^(?:[^\x00]*?(?=(\{\{)))/, - /^(?:[^\x00]+)/, - /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, - /^(?:\{\{\{\{(?=[^/]))/, - /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, - /^(?:[^\x00]+?(?=(\{\{\{\{)))/, - /^(?:[\s\S]*?--(~)?\}\})/, - /^(?:\()/, - /^(?:\))/, - /^(?:\[)/, - /^(?:\])/, - /^(?:\{\{\{\{)/, - /^(?:\}\}\}\})/, - /^(?:\{\{(~)?>)/, - /^(?:\{\{(~)?#>)/, - /^(?:\{\{(~)?#\*?)/, - /^(?:\{\{(~)?\/)/, - /^(?:\{\{(~)?\^\s*(~)?\}\})/, - /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, - /^(?:\{\{(~)?\^)/, - /^(?:\{\{(~)?\s*else\b)/, - /^(?:\{\{(~)?\{)/, - /^(?:\{\{(~)?&)/, - /^(?:\{\{(~)?!--)/, - /^(?:\{\{(~)?![\s\S]*?\}\})/, - /^(?:\{\{(~)?\*?)/, - /^(?:=)/, - /^(?:\.\.)/, - /^(?:\.(?=([=~}\s\/.)\]|])))/, - /^(?:\.#)/, - /^(?:[\/.])/, - /^(?:\s+)/, - /^(?:\}(~)?\}\})/, - /^(?:(~)?\}\})/, - /^(?:"(\\["]|[^"])*")/, - /^(?:'(\\[']|[^'])*')/, - /^(?:@)/, - /^(?:true(?=([~}\s)\]])))/, - /^(?:false(?=([~}\s)\]])))/, - /^(?:undefined(?=([~}\s)\]])))/, - /^(?:null(?=([~}\s)\]])))/, - /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)\]])))/, - /^(?:as\s+\|)/, - /^(?:\|)/, - /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)\]|]))))/, - /^(?:\[(\\\]|[^\]])*\])/, - /^(?:.)/, - /^(?:$)/, - ], - conditions: { - mu: { - rules: [ - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, - ], - inclusive: false, - }, - emu: { rules: [2], inclusive: false }, - com: { rules: [6], inclusive: false }, - raw: { rules: [3, 4, 5], inclusive: false }, - escl: { rules: [45], inclusive: false }, - INITIAL: { rules: [0, 1, 47], inclusive: true }, - }, - }; - return lexer; - })(); - parser.lexer = lexer; - function Parser() { - this.yy = {}; - } - Parser.prototype = parser; - parser.Parser = Parser; - return new Parser(); -})(); -export default parser; diff --git a/packages/@handlebars/parser/lib/printer.js b/packages/@handlebars/parser/lib/printer.js deleted file mode 100644 index bea44d3a6bf..00000000000 --- a/packages/@handlebars/parser/lib/printer.js +++ /dev/null @@ -1,204 +0,0 @@ -import Visitor from './visitor.js'; - -export function print(ast) { - return new PrintVisitor().accept(ast); -} - -export function PrintVisitor() { - this.padding = 0; -} - -PrintVisitor.prototype = new Visitor(); - -PrintVisitor.prototype.pad = function (string) { - let out = ''; - - for (let i = 0, l = this.padding; i < l; i++) { - out += ' '; - } - - out += string + '\n'; - return out; -}; - -PrintVisitor.prototype.Program = function (program) { - let out = '', - body = program.body, - i, - l; - - if (program.blockParams) { - let blockParams = 'BLOCK PARAMS: ['; - for (i = 0, l = program.blockParams.length; i < l; i++) { - blockParams += ' ' + program.blockParams[i]; - } - blockParams += ' ]'; - out += this.pad(blockParams); - } - - for (i = 0, l = body.length; i < l; i++) { - out += this.accept(body[i]); - } - - this.padding--; - - return out; -}; - -PrintVisitor.prototype.MustacheStatement = function (mustache) { - if (mustache.params.length > 0 || mustache.hash) { - return this.pad('{{ ' + this.callBody(mustache) + ' }}'); - } else { - return this.pad('{{ ' + this.accept(mustache.path) + ' }}'); - } -}; -PrintVisitor.prototype.Decorator = function (mustache) { - return this.pad('{{ DIRECTIVE ' + this.callBody(mustache) + ' }}'); -}; - -PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function (block) { - let out = ''; - - out += this.pad((block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:'); - this.padding++; - out += this.pad(this.callBody(block)); - if (block.program) { - out += this.pad('PROGRAM:'); - this.padding++; - out += this.accept(block.program); - this.padding--; - } - if (block.inverse) { - if (block.program) { - this.padding++; - } - out += this.pad('{{^}}'); - this.padding++; - out += this.accept(block.inverse); - this.padding--; - if (block.program) { - this.padding--; - } - } - this.padding--; - - return out; -}; - -PrintVisitor.prototype.PartialStatement = function (partial) { - let content = 'PARTIAL:' + partial.name.original; - if (partial.params[0]) { - content += ' ' + this.accept(partial.params[0]); - } - if (partial.hash) { - content += ' ' + this.accept(partial.hash); - } - return this.pad('{{> ' + content + ' }}'); -}; -PrintVisitor.prototype.PartialBlockStatement = function (partial) { - let content = 'PARTIAL BLOCK:' + partial.name.original; - if (partial.params[0]) { - content += ' ' + this.accept(partial.params[0]); - } - if (partial.hash) { - content += ' ' + this.accept(partial.hash); - } - - content += ' ' + this.pad('PROGRAM:'); - this.padding++; - content += this.accept(partial.program); - this.padding--; - - return this.pad('{{> ' + content + ' }}'); -}; - -PrintVisitor.prototype.ContentStatement = function (content) { - return this.pad("CONTENT[ '" + content.value + "' ]"); -}; - -PrintVisitor.prototype.CommentStatement = function (comment) { - return this.pad("{{! '" + comment.value + "' }}"); -}; - -PrintVisitor.prototype.SubExpression = function (sexpr) { - return `(${this.callBody(sexpr)})`; -}; - -PrintVisitor.prototype.callBody = function (callExpr) { - let params = callExpr.params, - paramStrings = [], - hash; - - for (let i = 0, l = params.length; i < l; i++) { - paramStrings.push(this.accept(params[i])); - } - - params = paramStrings.length === 0 ? '' : ' [' + paramStrings.join(', ') + ']'; - - hash = callExpr.hash ? ' ' + this.accept(callExpr.hash) : ''; - - return this.accept(callExpr.path) + params + hash; -}; - -PrintVisitor.prototype.PathExpression = function (id) { - let head = typeof id.head === 'string' ? id.head : `[${this.accept(id.head)}]`; - let path = [head, ...id.tail].join('/'); - return 'p%' + prefix(id) + path; -}; - -function prefix(path) { - if (path.data) { - return '@'; - } else if (path.this) { - return 'this.'; - } else { - return ''; - } -} - -PrintVisitor.prototype.StringLiteral = function (string) { - return '"' + string.value + '"'; -}; - -PrintVisitor.prototype.NumberLiteral = function (number) { - return 'n%' + number.value; -}; - -PrintVisitor.prototype.BooleanLiteral = function (bool) { - return 'b%' + bool.value; -}; - -PrintVisitor.prototype.UndefinedLiteral = function () { - return 'UNDEFINED'; -}; - -PrintVisitor.prototype.NullLiteral = function () { - return 'NULL'; -}; - -PrintVisitor.prototype.ArrayLiteral = function (array) { - return `Array[${array.items.map((item) => this.accept(item)).join(', ')}]`; -}; - -PrintVisitor.prototype.HashLiteral = function (hash) { - return `Hash{${this.hashPairs(hash)}}`; -}; - -PrintVisitor.prototype.Hash = function (hash) { - return `HASH{${this.hashPairs(hash)}}`; -}; - -PrintVisitor.prototype.hashPairs = function (hash) { - let pairs = hash.pairs, - joinedPairs = []; - - for (let i = 0, l = pairs.length; i < l; i++) { - joinedPairs.push(this.HashPair(pairs[i])); - } - - return joinedPairs.join(' '); -}; - -PrintVisitor.prototype.HashPair = function (pair) { - return pair.key + '=' + this.accept(pair.value); -}; diff --git a/packages/@handlebars/parser/lib/visitor.js b/packages/@handlebars/parser/lib/visitor.js deleted file mode 100644 index e9b5d6820af..00000000000 --- a/packages/@handlebars/parser/lib/visitor.js +++ /dev/null @@ -1,136 +0,0 @@ -import Exception from './exception.js'; - -function Visitor() { - this.parents = []; -} - -Visitor.prototype = { - constructor: Visitor, - mutating: false, - - // Visits a given value. If mutating, will replace the value if necessary. - acceptKey: function (node, name) { - let value = this.accept(node[name]); - if (this.mutating) { - // Hacky sanity check: This may have a few false positives for type for the helper - // methods but will generally do the right thing without a lot of overhead. - if (value && !Visitor.prototype[value.type]) { - throw new Exception( - 'Unexpected node type "' + - value.type + - '" found when accepting ' + - name + - ' on ' + - node.type - ); - } - node[name] = value; - } - }, - - // Performs an accept operation with added sanity check to ensure - // required keys are not removed. - acceptRequired: function (node, name) { - this.acceptKey(node, name); - - if (!node[name]) { - throw new Exception(node.type + ' requires ' + name); - } - }, - - // Traverses a given array. If mutating, empty responses will be removed - // for child elements. - acceptArray: function (array) { - for (let i = 0, l = array.length; i < l; i++) { - this.acceptKey(array, i); - - if (!array[i]) { - array.splice(i, 1); - i--; - l--; - } - } - }, - - accept: function (object) { - if (!object) { - return; - } - - /* istanbul ignore next: Sanity code */ - if (!this[object.type]) { - throw new Exception('Unknown type: ' + object.type, object); - } - - if (this.current) { - this.parents.unshift(this.current); - } - this.current = object; - - let ret = this[object.type](object); - - this.current = this.parents.shift(); - - if (!this.mutating || ret) { - return ret; - } else if (ret !== false) { - return object; - } - }, - - Program: function (program) { - this.acceptArray(program.body); - }, - - MustacheStatement: visitSubExpression, - Decorator: visitSubExpression, - - BlockStatement: visitBlock, - DecoratorBlock: visitBlock, - - PartialStatement: visitPartial, - PartialBlockStatement: function (partial) { - visitPartial.call(this, partial); - - this.acceptKey(partial, 'program'); - }, - - ContentStatement: function (/* content */) {}, - CommentStatement: function (/* comment */) {}, - - SubExpression: visitSubExpression, - - PathExpression: function (/* path */) {}, - - StringLiteral: function (/* string */) {}, - NumberLiteral: function (/* number */) {}, - BooleanLiteral: function (/* bool */) {}, - UndefinedLiteral: function (/* literal */) {}, - NullLiteral: function (/* literal */) {}, - - Hash: function (hash) { - this.acceptArray(hash.pairs); - }, - HashPair: function (pair) { - this.acceptRequired(pair, 'value'); - }, -}; - -function visitSubExpression(mustache) { - this.acceptRequired(mustache, 'path'); - this.acceptArray(mustache.params); - this.acceptKey(mustache, 'hash'); -} -function visitBlock(block) { - visitSubExpression.call(this, block); - - this.acceptKey(block, 'program'); - this.acceptKey(block, 'inverse'); -} -function visitPartial(partial) { - this.acceptRequired(partial, 'name'); - this.acceptArray(partial.params); - this.acceptKey(partial, 'hash'); -} - -export default Visitor; diff --git a/packages/@handlebars/parser/lib/whitespace-control.js b/packages/@handlebars/parser/lib/whitespace-control.js deleted file mode 100644 index c4a8ac0bba3..00000000000 --- a/packages/@handlebars/parser/lib/whitespace-control.js +++ /dev/null @@ -1,218 +0,0 @@ -import Visitor from './visitor.js'; - -function WhitespaceControl(options = {}) { - this.options = options; -} -WhitespaceControl.prototype = new Visitor(); - -WhitespaceControl.prototype.Program = function (program) { - const doStandalone = !this.options.ignoreStandalone; - - let isRoot = !this.isRootSeen; - this.isRootSeen = true; - - let body = program.body; - for (let i = 0, l = body.length; i < l; i++) { - let current = body[i], - strip = this.accept(current); - - if (!strip) { - continue; - } - - let _isPrevWhitespace = isPrevWhitespace(body, i, isRoot), - _isNextWhitespace = isNextWhitespace(body, i, isRoot), - openStandalone = strip.openStandalone && _isPrevWhitespace, - closeStandalone = strip.closeStandalone && _isNextWhitespace, - inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; - - if (strip.close) { - omitRight(body, i, true); - } - if (strip.open) { - omitLeft(body, i, true); - } - - if (doStandalone && inlineStandalone) { - omitRight(body, i); - - if (omitLeft(body, i)) { - // If we are on a standalone node, save the indent info for partials - if (current.type === 'PartialStatement') { - // Pull out the whitespace from the final line - current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1]; - } - } - } - if (doStandalone && openStandalone) { - omitRight((current.program || current.inverse).body); - - // Strip out the previous content node if it's whitespace only - omitLeft(body, i); - } - if (doStandalone && closeStandalone) { - // Always strip the next node - omitRight(body, i); - - omitLeft((current.inverse || current.program).body); - } - } - - return program; -}; - -WhitespaceControl.prototype.BlockStatement = - WhitespaceControl.prototype.DecoratorBlock = - WhitespaceControl.prototype.PartialBlockStatement = - function (block) { - this.accept(block.program); - this.accept(block.inverse); - - // Find the inverse program that is involved with whitespace stripping. - let program = block.program || block.inverse, - inverse = block.program && block.inverse, - firstInverse = inverse, - lastInverse = inverse; - - if (inverse && inverse.chained) { - firstInverse = inverse.body[0].program; - - // Walk the inverse chain to find the last inverse that is actually in the chain. - while (lastInverse.chained) { - lastInverse = lastInverse.body[lastInverse.body.length - 1].program; - } - } - - let strip = { - open: block.openStrip.open, - close: block.closeStrip.close, - - // Determine the standalone candidacy. Basically flag our content as being possibly standalone - // so our parent can determine if we actually are standalone - openStandalone: isNextWhitespace(program.body), - closeStandalone: isPrevWhitespace((firstInverse || program).body), - }; - - if (block.openStrip.close) { - omitRight(program.body, null, true); - } - - if (inverse) { - let inverseStrip = block.inverseStrip; - - if (inverseStrip.open) { - omitLeft(program.body, null, true); - } - - if (inverseStrip.close) { - omitRight(firstInverse.body, null, true); - } - if (block.closeStrip.open) { - omitLeft(lastInverse.body, null, true); - } - - // Find standalone else statements - if ( - !this.options.ignoreStandalone && - isPrevWhitespace(program.body) && - isNextWhitespace(firstInverse.body) - ) { - omitLeft(program.body); - omitRight(firstInverse.body); - } - } else if (block.closeStrip.open) { - omitLeft(program.body, null, true); - } - - return strip; - }; - -WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function ( - mustache -) { - return mustache.strip; -}; - -WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = - function (node) { - /* istanbul ignore next */ - let strip = node.strip || {}; - return { - inlineStandalone: true, - open: strip.open, - close: strip.close, - }; - }; - -function isPrevWhitespace(body, i, isRoot) { - if (i === undefined) { - i = body.length; - } - - // Nodes that end with newlines are considered whitespace (but are special - // cased for strip operations) - let prev = body[i - 1], - sibling = body[i - 2]; - if (!prev) { - return isRoot; - } - - if (prev.type === 'ContentStatement') { - return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original); - } -} -function isNextWhitespace(body, i, isRoot) { - if (i === undefined) { - i = -1; - } - - let next = body[i + 1], - sibling = body[i + 2]; - if (!next) { - return isRoot; - } - - if (next.type === 'ContentStatement') { - return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original); - } -} - -// Marks the node to the right of the position as omitted. -// I.e. {{foo}}' ' will mark the ' ' node as omitted. -// -// If i is undefined, then the first child will be marked as such. -// -// If multiple is truthy then all whitespace will be stripped out until non-whitespace -// content is met. -function omitRight(body, i, multiple) { - let current = body[i == null ? 0 : i + 1]; - if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) { - return; - } - - let original = current.value; - current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, ''); - current.rightStripped = current.value !== original; -} - -// Marks the node to the left of the position as omitted. -// I.e. ' '{{foo}} will mark the ' ' node as omitted. -// -// If i is undefined then the last child will be marked as such. -// -// If multiple is truthy then all whitespace will be stripped out until non-whitespace -// content is met. -function omitLeft(body, i, multiple) { - let current = body[i == null ? body.length - 1 : i - 1]; - if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) { - return; - } - - // We omit the last node if it's whitespace only and not preceded by a non-content node. - let original = current.value; - current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, ''); - current.leftStripped = current.value !== original; - return current.leftStripped; -} - -export default WhitespaceControl; diff --git a/packages/@handlebars/parser/package.json b/packages/@handlebars/parser/package.json deleted file mode 100644 index 4072441c423..00000000000 --- a/packages/@handlebars/parser/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "@handlebars/parser", - "version": "2.2.2", - "description": "The parser for the Handlebars language", - "homepage": "https://github.com/handlebars-lang/handlebars-parser#readme", - "bugs": { - "url": "https://github.com/handlebars-lang/handlebars-parser/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/handlebars-lang/handlebars-parser.git" - }, - "license": "ISC", - "author": "", - "private": true, - "type": "module", - "exports": { - ".": { - "types": "./types/index.d.ts", - "default": "./lib/index.js" - } - }, - "main": "lib/index.js", - "module": "lib/index.js", - "types": "types/index.d.ts", - "scripts": { - "build:jison": "jison -m js src/handlebars.yy src/handlebars.l -o lib/parser.js", - "build:parser": "npm-run-all build:jison build:parser-suffix build:parser-ts-nocheck", - "build:parser-suffix": "combine-files lib/parser.js,src/parser-suffix.js lib/parser.js", - "build:parser-ts-nocheck": "node -e \"const fs=require('fs');const f='lib/parser.js';fs.writeFileSync(f,'// @ts-nocheck\\n'+fs.readFileSync(f,'utf8'))\"", - "test": "mocha --inline-diffs spec" - }, - "devDependencies": { - "combine-files": "^1.1.8", - "jison": "^0.4.18", - "mocha": "^11.0.0", - "npm-run-all2": "^8.0.0" - } -} diff --git a/packages/@handlebars/parser/spec/ast.js b/packages/@handlebars/parser/spec/ast.js deleted file mode 100644 index aeb32a47cc3..00000000000 --- a/packages/@handlebars/parser/spec/ast.js +++ /dev/null @@ -1,291 +0,0 @@ -import { parse, parseWithoutProcessing } from '../lib/index.js'; -import { equals } from './utils.js'; - -describe('ast', function () { - describe('whitespace control', function () { - describe('parse', function () { - it('mustache', function () { - let ast = parse(' {{~comment~}} '); - - equals(ast.body[0].value, ''); - equals(ast.body[2].value, ''); - }); - - it('block statements', function () { - let ast = parse(' {{# comment~}} \nfoo\n {{~/comment}}'); - - equals(ast.body[0].value, ''); - equals(ast.body[1].program.body[0].value, 'foo'); - }); - }); - - describe('parseWithoutProcessing', function () { - it('mustache', function () { - let ast = parseWithoutProcessing(' {{~comment~}} '); - - equals(ast.body[0].value, ' '); - equals(ast.body[2].value, ' '); - }); - - it('block statements', function () { - let ast = parseWithoutProcessing(' {{# comment~}} \nfoo\n {{~/comment}}'); - - equals(ast.body[0].value, ' '); - equals(ast.body[1].program.body[0].value, ' \nfoo\n '); - }); - }); - }); - - describe('node details', function () { - describe('paths', function () { - it('{{this}}', function () { - let path = parse('{{this}}').body[0].path; - equals(path.original, 'this'); - equals(path.head, undefined); - equals(path.tail.length, 0); - equals(path.parts.length, 0); - }); - - it('{{this.bar}}', function () { - let path = parse('{{this.bar}}').body[0].path; - equals(path.original, 'this.bar'); - equals(path.head, 'bar'); - equals(path.tail.length, 0); - equals(path.parts.length, 1); - equals(path.parts[0], 'bar'); - }); - - it('{{this.#bar}}', function () { - let path = parse('{{this.#bar}}').body[0].path; - equals(path.original, 'this.#bar'); - equals(path.head, '#bar'); - equals(path.tail.length, 0); - equals(path.parts.length, 1); - equals(path.parts[0], '#bar'); - }); - - it('{{foo.bar}}', function () { - let path = parse('{{foo.bar}}').body[0].path; - equals(path.original, 'foo.bar'); - equals(path.head, 'foo'); - equals(path.tail.length, 1); - equals(path.tail[0], 'bar'); - equals(path.parts.length, 2); - equals(path.parts[0], 'foo'); - equals(path.parts[1], 'bar'); - }); - - it('{{foo.#bar}}', function () { - let path = parse('{{foo.#bar}}').body[0].path; - equals(path.original, 'foo.#bar'); - equals(path.head, 'foo'); - equals(path.tail.length, 1); - equals(path.tail[0], '#bar'); - equals(path.parts.length, 2); - equals(path.parts[0], 'foo'); - equals(path.parts[1], '#bar'); - }); - }); - }); - - describe('standalone flags', function () { - describe('mustache', function () { - it('does not mark mustaches as standalone', function () { - let ast = parse(' {{comment}} '); - equals(!!ast.body[0].value, true); - equals(!!ast.body[2].value, true); - }); - }); - describe('blocks - parseWithoutProcessing', function () { - it('block mustaches', function () { - let ast = parseWithoutProcessing( - ' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' - ), - block = ast.body[1]; - - equals(ast.body[0].value, ' '); - - equals(block.program.body[0].value, ' \nfoo\n '); - equals(block.inverse.body[0].value, ' \n bar \n '); - - equals(ast.body[2].value, ' '); - }); - it('initial block mustaches', function () { - let ast = parseWithoutProcessing('{{# comment}} \nfoo\n {{/comment}}'), - block = ast.body[0]; - - equals(block.program.body[0].value, ' \nfoo\n '); - }); - it('mustaches with children', function () { - let ast = parseWithoutProcessing('{{# comment}} \n{{foo}}\n {{/comment}}'), - block = ast.body[0]; - - equals(block.program.body[0].value, ' \n'); - equals(block.program.body[1].path.original, 'foo'); - equals(block.program.body[2].value, '\n '); - }); - it('nested block mustaches', function () { - let ast = parseWithoutProcessing( - '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} \n{{/foo}}' - ), - body = ast.body[0].program.body, - block = body[1]; - - equals(body[0].value, ' \n'); - - equals(block.program.body[0].value, ' \nfoo\n '); - equals(block.inverse.body[0].value, ' \n bar \n '); - }); - it('column 0 block mustaches', function () { - let ast = parseWithoutProcessing( - 'test\n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} ' - ), - block = ast.body[1]; - - equals(ast.body[0].omit, undefined); - - equals(block.program.body[0].value, ' \nfoo\n '); - equals(block.inverse.body[0].value, ' \n bar \n '); - - equals(ast.body[2].value, ' '); - }); - }); - describe('blocks', function () { - it('marks block mustaches as standalone', function () { - let ast = parse(' {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} '), - block = ast.body[1]; - - equals(ast.body[0].value, ''); - - equals(block.program.body[0].value, 'foo\n'); - equals(block.inverse.body[0].value, ' bar \n'); - - equals(ast.body[2].value, ''); - }); - it('marks initial block mustaches as standalone', function () { - let ast = parse('{{# comment}} \nfoo\n {{/comment}}'), - block = ast.body[0]; - - equals(block.program.body[0].value, 'foo\n'); - }); - it('marks mustaches with children as standalone', function () { - let ast = parse('{{# comment}} \n{{foo}}\n {{/comment}}'), - block = ast.body[0]; - - equals(block.program.body[0].value, ''); - equals(block.program.body[1].path.original, 'foo'); - equals(block.program.body[2].value, '\n'); - }); - it('marks nested block mustaches as standalone', function () { - let ast = parse( - '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} \n{{/foo}}' - ), - body = ast.body[0].program.body, - block = body[1]; - - equals(body[0].value, ''); - - equals(block.program.body[0].value, 'foo\n'); - equals(block.inverse.body[0].value, ' bar \n'); - - equals(body[0].value, ''); - }); - it('does not mark nested block mustaches as standalone', function () { - let ast = parse( - '{{#foo}} {{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} {{/foo}}' - ), - body = ast.body[0].program.body, - block = body[1]; - - equals(body[0].omit, undefined); - - equals(block.program.body[0].value, ' \nfoo\n'); - equals(block.inverse.body[0].value, ' bar \n '); - - equals(body[0].omit, undefined); - }); - it('does not mark nested initial block mustaches as standalone', function () { - let ast = parse('{{#foo}}{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}}{{/foo}}'), - body = ast.body[0].program.body, - block = body[0]; - - equals(block.program.body[0].value, ' \nfoo\n'); - equals(block.inverse.body[0].value, ' bar \n '); - - equals(body[0].omit, undefined); - }); - - it('marks column 0 block mustaches as standalone', function () { - let ast = parse('test\n{{# comment}} \nfoo\n {{else}} \n bar \n {{/comment}} '), - block = ast.body[1]; - - equals(ast.body[0].omit, undefined); - - equals(block.program.body[0].value, 'foo\n'); - equals(block.inverse.body[0].value, ' bar \n'); - - equals(ast.body[2].value, ''); - }); - }); - describe('partials - parseWithoutProcessing', function () { - it('simple partial', function () { - let ast = parseWithoutProcessing('{{> partial }} '); - equals(ast.body[1].value, ' '); - }); - it('indented partial', function () { - let ast = parseWithoutProcessing(' {{> partial }} '); - equals(ast.body[0].value, ' '); - equals(ast.body[1].indent, ''); - equals(ast.body[2].value, ' '); - }); - }); - describe('partials', function () { - it('marks partial as standalone', function () { - let ast = parse('{{> partial }} '); - equals(ast.body[1].value, ''); - }); - it('marks indented partial as standalone', function () { - let ast = parse(' {{> partial }} '); - equals(ast.body[0].value, ''); - equals(ast.body[1].indent, ' '); - equals(ast.body[2].value, ''); - }); - it('marks those around content as not standalone', function () { - let ast = parse('a{{> partial }}'); - equals(ast.body[0].omit, undefined); - - ast = parse('{{> partial }}a'); - equals(ast.body[1].omit, undefined); - }); - }); - describe('comments - parseWithoutProcessing', function () { - it('simple comment', function () { - let ast = parseWithoutProcessing('{{! comment }} '); - equals(ast.body[1].value, ' '); - }); - it('indented comment', function () { - let ast = parseWithoutProcessing(' {{! comment }} '); - equals(ast.body[0].value, ' '); - equals(ast.body[2].value, ' '); - }); - }); - describe('comments', function () { - it('marks comment as standalone', function () { - let ast = parse('{{! comment }} '); - equals(ast.body[1].value, ''); - }); - it('marks indented comment as standalone', function () { - let ast = parse(' {{! comment }} '); - equals(ast.body[0].value, ''); - equals(ast.body[2].value, ''); - }); - it('marks those around content as not standalone', function () { - let ast = parse('a{{! comment }}'); - equals(ast.body[0].omit, undefined); - - ast = parse('{{! comment }}a'); - equals(ast.body[1].omit, undefined); - }); - }); - }); -}); diff --git a/packages/@handlebars/parser/spec/parser.js b/packages/@handlebars/parser/spec/parser.js deleted file mode 100644 index 970b2350a4e..00000000000 --- a/packages/@handlebars/parser/spec/parser.js +++ /dev/null @@ -1,500 +0,0 @@ -import { parse, print } from '../lib/index.js'; -import { equals, equalsAst, shouldThrow } from './utils.js'; - -describe('parser', function () { - function astFor(template) { - let ast = parse(template); - return print(ast); - } - - it('parses simple mustaches', function () { - equalsAst('{{123}}', '{{ n%123 }}'); - equalsAst('{{"foo"}}', '{{ "foo" }}'); - equalsAst('{{false}}', '{{ b%false }}'); - equalsAst('{{true}}', '{{ b%true }}'); - equalsAst('{{foo}}', '{{ p%foo }}'); - equalsAst('{{foo?}}', '{{ p%foo? }}'); - equalsAst('{{foo_}}', '{{ p%foo_ }}'); - equalsAst('{{foo-}}', '{{ p%foo- }}'); - equalsAst('{{foo:}}', '{{ p%foo: }}'); - }); - - it('parses simple mustaches with data', function () { - equalsAst('{{@foo}}', '{{ p%@foo }}'); - }); - - it('parses simple mustaches with data paths', function () { - equalsAst('{{@../foo}}', '{{ p%@foo }}'); - }); - - it('parses mustaches with paths', function () { - equalsAst('{{foo/bar}}', '{{ p%foo/bar }}'); - equalsAst('{{foo.bar}}', '{{ p%foo/bar }}'); - equalsAst('{{foo.#bar}}', '{{ p%foo/#bar }}'); - equalsAst('{{@foo.#bar}}', '{{ p%@foo/#bar }}'); - - equalsAst('{{this/foo}}', '{{ p%foo }}'); - equalsAst('{{this.foo}}', '{{ p%this.foo }}'); - equalsAst('{{this.#foo}}', '{{ p%this.#foo }}'); - }); - - it('parses mustaches with - in a path', function () { - equalsAst('{{foo-bar}}', '{{ p%foo-bar }}'); - }); - - it('parses mustaches with escaped [] in a path', function () { - equalsAst('{{[foo[\\]]}}', '{{ p%foo[] }}'); - }); - - it('parses escaped \\\\ in path', function () { - equalsAst('{{[foo\\\\]}}', '{{ p%foo\\ }}'); - }); - - it('parses hash literals', function () { - equalsAst('{{(foo=bar)}}', '{{ Hash{foo=p%bar} }}'); - equalsAst('{{(foo=bar)}}', '{{ p%@hello }}', { - options: { - syntax: { - hash: (hash, loc, { yy }) => { - return yy.preparePath(true, false, [{ part: yy.id('hello'), original: 'hello' }], loc); - }, - }, - }, - }); - }); - - it('parses array literals', function () { - equalsAst('{{[foo bar]}}', '{{ Array[p%foo, p%bar] }}', { - options: { syntax: { square: 'node' } }, - }); - - equalsAst('{{[foo bar].baz}}', '{{ p%[Array[p%foo, p%bar]]/baz }}', { - options: { syntax: { square: 'node' } }, - }); - }); - - it('parses mustaches that are hash literals', function () { - equalsAst('{{foo=bar}}', '{{ Hash{foo=p%bar} }}'); - equalsAst('{{foo=bar}}', `{{ "HASH{foo=p%bar}" }}`, { - options: { - syntax: { - hash: (hash, loc) => { - return { - type: 'StringLiteral', - original: print(hash), - value: print(hash), - loc, - }; - }, - }, - }, - }); - }); - - it('parses mustaches with parameters', function () { - equalsAst('{{foo bar}}', '{{ p%foo [p%bar] }}'); - equalsAst('{{this.foo bar}}', '{{ p%this.foo [p%bar] }}'); - equalsAst('{{this.foo this.bar}}', '{{ p%this.foo [p%this.bar] }}'); - equalsAst('{{this.#foo this.#bar}}', '{{ p%this.#foo [p%this.#bar] }}'); - equalsAst('{{foo.#bar foo.#baz}}', '{{ p%foo/#bar [p%foo/#baz] }}'); - equalsAst('{{@foo.#bar @foo.#baz}}', '{{ p%@foo/#bar [p%@foo/#baz] }}'); - }); - - it('parses mustaches with string parameters', function () { - equalsAst('{{foo bar "baz" }}', '{{ p%foo [p%bar, "baz"] }}'); - equalsAst('{{this.foo bar "baz" }}', '{{ p%this.foo [p%bar, "baz"] }}'); - equalsAst('{{this.#foo bar "baz" }}', '{{ p%this.#foo [p%bar, "baz"] }}'); - equalsAst('{{@item.#foo bar "baz" }}', '{{ p%@item/#foo [p%bar, "baz"] }}'); - }); - - it('parses mustaches with NUMBER parameters', function () { - equalsAst('{{foo 1}}', '{{ p%foo [n%1] }}'); - equalsAst('{{this.foo 1}}', '{{ p%this.foo [n%1] }}'); - equalsAst('{{this.#foo 1}}', '{{ p%this.#foo [n%1] }}'); - }); - - it('parses mustaches with BOOLEAN parameters', function () { - equalsAst('{{foo true}}', '{{ p%foo [b%true] }}'); - equalsAst('{{foo false}}', '{{ p%foo [b%false] }}'); - }); - - it('parses mustaches with undefined and null paths', function () { - equalsAst('{{undefined}}', '{{ UNDEFINED }}'); - equalsAst('{{null}}', '{{ NULL }}'); - }); - - it('parses mustaches with undefined and null parameters', function () { - equalsAst('{{foo undefined null}}', '{{ p%foo [UNDEFINED, NULL] }}'); - }); - - it('parses mustaches with DATA parameters', function () { - equalsAst('{{foo @bar}}', '{{ p%foo [p%@bar] }}'); - }); - - it('parses mustaches with hash arguments', function () { - equalsAst('{{foo bar=baz}}', '{{ p%foo HASH{bar=p%baz} }}'); - equalsAst('{{foo bar=1}}', '{{ p%foo HASH{bar=n%1} }}'); - equalsAst('{{foo bar=true}}', '{{ p%foo HASH{bar=b%true} }}'); - equalsAst('{{foo bar=false}}', '{{ p%foo HASH{bar=b%false} }}'); - equalsAst('{{foo bar=@baz}}', '{{ p%foo HASH{bar=p%@baz} }}'); - - equalsAst('{{foo bar=baz bat=bam}}', '{{ p%foo HASH{bar=p%baz bat=p%bam} }}'); - equalsAst('{{foo bar=baz bat="bam"}}', '{{ p%foo HASH{bar=p%baz bat="bam"} }}'); - - equalsAst("{{foo bat='bam'}}", '{{ p%foo HASH{bat="bam"} }}'); - - equalsAst('{{foo omg bar=baz bat="bam"}}', '{{ p%foo [p%omg] HASH{bar=p%baz bat="bam"} }}'); - equalsAst( - '{{foo omg bar=baz bat="bam" baz=1}}', - '{{ p%foo [p%omg] HASH{bar=p%baz bat="bam" baz=n%1} }}' - ); - equalsAst( - '{{foo omg bar=baz bat="bam" baz=true}}', - '{{ p%foo [p%omg] HASH{bar=p%baz bat="bam" baz=b%true} }}' - ); - equalsAst( - '{{foo omg bar=baz bat="bam" baz=false}}', - '{{ p%foo [p%omg] HASH{bar=p%baz bat="bam" baz=b%false} }}' - ); - }); - - it('parses contents followed by a mustache', function () { - equalsAst('foo bar {{baz}}', "CONTENT[ 'foo bar ' ]\n{{ p%baz }}"); - }); - - it('parses a partial', function () { - equalsAst('{{> foo }}', '{{> PARTIAL:foo }}'); - equalsAst('{{> "foo" }}', '{{> PARTIAL:foo }}'); - equalsAst('{{> 1 }}', '{{> PARTIAL:1 }}'); - }); - - it('parses a partial with context', function () { - equalsAst('{{> foo bar}}', '{{> PARTIAL:foo p%bar }}'); - }); - - it('parses a partial with hash', function () { - equalsAst('{{> foo bar=bat}}', '{{> PARTIAL:foo HASH{bar=p%bat} }}'); - }); - - it('parses a partial with context and hash', function () { - equalsAst('{{> foo bar bat=baz}}', '{{> PARTIAL:foo p%bar HASH{bat=p%baz} }}'); - }); - - it('parses a partial with a complex name', function () { - equalsAst('{{> shared/partial?.bar}}', '{{> PARTIAL:shared/partial?.bar }}'); - }); - - it('parsers partial blocks', function () { - equalsAst('{{#> foo}}bar{{/foo}}', "{{> PARTIAL BLOCK:foo PROGRAM:\n CONTENT[ 'bar' ]\n }}"); - }); - it('should handle parser block mismatch', function () { - shouldThrow( - function () { - astFor('{{#> goodbyes}}{{/hellos}}'); - }, - Error, - /goodbyes doesn't match hellos/ - ); - }); - it('parsers partial blocks with arguments', function () { - equalsAst( - '{{#> foo context hash=value}}bar{{/foo}}', - "{{> PARTIAL BLOCK:foo p%context HASH{hash=p%value} PROGRAM:\n CONTENT[ 'bar' ]\n }}" - ); - }); - - it('parses a comment', function () { - equalsAst('{{! this is a comment }}', "{{! ' this is a comment ' }}"); - }); - - it('parses a multi-line comment', function () { - equalsAst('{{!\nthis is a multi-line comment\n}}', "{{! '\nthis is a multi-line comment\n' }}"); - }); - - it('parses an inverse section', function () { - equalsAst( - '{{#foo}} bar {{^}} baz {{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]" - ); - }); - - it('parses an inverse (else-style) section', function () { - equalsAst( - '{{#foo}} bar {{else}} baz {{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n CONTENT[ ' baz ' ]" - ); - }); - - it('parses multiple inverse sections', function () { - equalsAst( - '{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}\n BLOCK:\n p%if [p%bar]\n PROGRAM:\n {{^}}\n CONTENT[ ' baz ' ]" - ); - }); - - it('parses empty blocks', function () { - equalsAst('{{#foo}}{{/foo}}', 'BLOCK:\n p%foo\n PROGRAM:'); - }); - - it('parses empty blocks with empty inverse section', function () { - equalsAst('{{#foo}}{{^}}{{/foo}}', 'BLOCK:\n p%foo\n PROGRAM:\n {{^}}'); - }); - - it('parses empty blocks with empty inverse (else-style) section', function () { - equalsAst('{{#foo}}{{else}}{{/foo}}', 'BLOCK:\n p%foo\n PROGRAM:\n {{^}}'); - }); - - it('parses non-empty blocks with empty inverse section', function () { - equalsAst( - '{{#foo}} bar {{^}}{{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}" - ); - }); - - it('parses non-empty blocks with empty inverse (else-style) section', function () { - equalsAst( - '{{#foo}} bar {{else}}{{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n CONTENT[ ' bar ' ]\n {{^}}" - ); - }); - - it('parses empty blocks with non-empty inverse section', function () { - equalsAst( - '{{#foo}}{{^}} bar {{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]" - ); - }); - - it('parses empty blocks with non-empty inverse (else-style) section', function () { - equalsAst( - '{{#foo}}{{else}} bar {{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n {{^}}\n CONTENT[ ' bar ' ]" - ); - }); - - it('parses a standalone inverse section', function () { - equalsAst('{{^foo}}bar{{/foo}}', "BLOCK:\n p%foo\n {{^}}\n CONTENT[ 'bar' ]"); - }); - - it('throws on old inverse section', function () { - shouldThrow(function () { - astFor('{{else foo}}bar{{/foo}}'); - }, Error); - }); - - it('parses block with block params', function () { - equalsAst( - '{{#foo as |bar baz|}}content{{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]" - ); - }); - - it('parses mustaches with sub-expressions as the callable', function () { - equalsAst('{{(my-helper foo)}}', '{{ (p%my-helper [p%foo]) }}'); - }); - - it('parses mustaches with sub-expressions as the callable (with args)', function () { - equalsAst('{{(my-helper foo) bar}}', '{{ (p%my-helper [p%foo]) [p%bar] }}'); - }); - - it('parses sub-expressions with a sub-expression as the callable', function () { - equalsAst('{{((my-helper foo))}}', '{{ ((p%my-helper [p%foo])) }}'); - }); - - it('parses sub-expressions with a sub-expression as the callable (with args)', function () { - equalsAst('{{((my-helper foo) bar)}}', '{{ ((p%my-helper [p%foo]) [p%bar]) }}'); - }); - - it('parses arguments with a sub-expression as the callable (with args)', function () { - equalsAst( - '{{my-helper ((foo) bar) baz=((foo bar))}}', - '{{ p%my-helper [((p%foo) [p%bar])] HASH{baz=((p%foo [p%bar]))} }}' - ); - }); - - it('parses paths with sub-expressions as the root', function () { - equalsAst('{{(my-helper foo).bar}}', '{{ p%[(p%my-helper [p%foo])]/bar }}'); - }); - - it('parses paths with sub-expressions as the root as a callable', function () { - equalsAst('{{((my-helper foo).bar baz)}}', '{{ (p%[(p%my-helper [p%foo])]/bar [p%baz]) }}'); - }); - - it('parses paths with sub-expressions as the root as an argument', function () { - equalsAst('{{(foo (my-helper bar).baz)}}', '{{ (p%foo [p%[(p%my-helper [p%bar])]/baz]) }}'); - }); - - it('parses paths with sub-expressions as the root as a named argument', function () { - equalsAst( - '{{(foo bar=(my-helper baz).qux)}}', - '{{ (p%foo HASH{bar=p%[(p%my-helper [p%baz])]/qux}) }}' - ); - }); - - it('parses inverse block with block params', function () { - equalsAst( - '{{^foo as |bar baz|}}content{{/foo}}', - "BLOCK:\n p%foo\n {{^}}\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]" - ); - }); - it('parses chained inverse block with block params', function () { - equalsAst( - '{{#foo}}{{else foo as |bar baz|}}content{{/foo}}', - "BLOCK:\n p%foo\n PROGRAM:\n {{^}}\n BLOCK:\n p%foo\n PROGRAM:\n BLOCK PARAMS: [ bar baz ]\n CONTENT[ 'content' ]" - ); - }); - it("raises if there's a Parse error", function () { - shouldThrow( - function () { - astFor('foo{{^}}bar'); - }, - Error, - /Parse error on line 1/ - ); - shouldThrow( - function () { - astFor('{{foo}'); - }, - Error, - /Parse error on line 1/ - ); - shouldThrow( - function () { - astFor('{{foo &}}'); - }, - Error, - /Parse error on line 1/ - ); - shouldThrow( - function () { - astFor('{{#goodbyes}}{{/hellos}}'); - }, - Error, - /goodbyes doesn't match hellos/ - ); - - shouldThrow( - function () { - astFor('{{{{goodbyes}}}} {{{{/hellos}}}}'); - }, - Error, - /goodbyes doesn't match hellos/ - ); - }); - - it('should handle invalid paths', function () { - shouldThrow( - function () { - astFor('{{foo/../bar}}'); - }, - Error, - /Invalid path: foo\/\.\. - 1:2/ - ); - shouldThrow( - function () { - astFor('{{foo/./bar}}'); - }, - Error, - /Invalid path: foo\/\. - 1:2/ - ); - shouldThrow( - function () { - astFor('{{foo/this/bar}}'); - }, - Error, - /Invalid path: foo\/this - 1:2/ - ); - }); - - it('knows how to report the correct line number in errors', function () { - shouldThrow( - function () { - astFor('hello\nmy\n{{foo}'); - }, - Error, - /Parse error on line 3/ - ); - shouldThrow( - function () { - astFor('hello\n\nmy\n\n{{foo}'); - }, - Error, - /Parse error on line 5/ - ); - }); - - it('knows how to report the correct line number in errors when the first character is a newline', function () { - shouldThrow( - function () { - astFor('\n\nhello\n\nmy\n\n{{foo}'); - }, - Error, - /Parse error on line 7/ - ); - }); - - describe('externally compiled AST', function () { - it('can pass through an already-compiled AST', function () { - equals( - astFor({ - type: 'Program', - body: [{ type: 'ContentStatement', value: 'Hello' }], - }), - "CONTENT[ 'Hello' ]\n" - ); - }); - }); - - describe('directives', function () { - it('should parse block directives', function () { - equalsAst('{{#* foo}}{{/foo}}', 'DIRECTIVE BLOCK:\n p%foo\n PROGRAM:'); - }); - it('should parse directives', function () { - equalsAst('{{* foo}}', '{{ DIRECTIVE p%foo }}'); - }); - it('should fail if directives have inverse', function () { - shouldThrow( - function () { - astFor('{{#* foo}}{{^}}{{/foo}}'); - }, - Error, - /Unexpected inverse/ - ); - }); - }); - - it('GH1024 - should track program location properly', function () { - let p = parse( - '\n' + - ' {{#if foo}}\n' + - ' {{bar}}\n' + - ' {{else}} {{baz}}\n' + - '\n' + - ' {{/if}}\n' + - ' ' - ); - - // We really need a deep equals but for now this should be stable... - equals( - JSON.stringify(p.loc), - JSON.stringify({ - start: { line: 1, column: 0 }, - end: { line: 7, column: 4 }, - }) - ); - equals( - JSON.stringify(p.body[1].program.loc), - JSON.stringify({ - start: { line: 2, column: 13 }, - end: { line: 4, column: 7 }, - }) - ); - equals( - JSON.stringify(p.body[1].inverse.loc), - JSON.stringify({ - start: { line: 4, column: 15 }, - end: { line: 6, column: 5 }, - }) - ); - }); -}); diff --git a/packages/@handlebars/parser/spec/utils.js b/packages/@handlebars/parser/spec/utils.js deleted file mode 100644 index d3739bca271..00000000000 --- a/packages/@handlebars/parser/spec/utils.js +++ /dev/null @@ -1,107 +0,0 @@ -import { parse, print } from '../lib/index.js'; - -let AssertError; -if (Error.captureStackTrace) { - AssertError = function AssertError(message, caller) { - Error.prototype.constructor.call(this, message); - this.message = message; - - if (Error.captureStackTrace) { - Error.captureStackTrace(this, caller || AssertError); - } - }; - - AssertError.prototype = new Error(); -} else { - AssertError = Error; -} - -/** - * @todo Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`) - * @see https://www.chaijs.com/api/bdd/ - */ -export function equals(actual, expected, msg) { - if (actual !== expected) { - const error = new AssertError( - `\n Actual: ${actual} Expected: ${expected}` + (msg ? `\n${msg}` : ''), - equals - ); - error.expected = expected; - error.actual = actual; - throw error; - } -} - -export function equalsAst(source, expected, options) { - const msg = typeof options === 'string' ? options : options?.msg; - const parserOptions = typeof options === 'string' ? undefined : options?.options; - const ast = astFor(source, parserOptions); - const padding = ` `.repeat(8); - - if (ast !== `${expected}\n`) { - let sourceMsg = `${padding}Source: ${source}`; - if (parserOptions) { - let formattedOptions = printOptions(parserOptions).split('\n').join(`\n${padding}`); - - sourceMsg += `\n${padding}Options: ${formattedOptions}`; - } - const error = new AssertError(`\n${sourceMsg}${msg ? `\n${msg}` : ''}\n`, equalsAst); - - error.expected = expected; - error.actual = ast; - throw error; - } -} - -function printOptions(options) { - if (!options) { - return ''; - } - - let outOptions = {}; - - if (options.srcName) { - outOptions.srcName = options.srcName; - } - if (options.syntax) { - outOptions.syntax = {}; - - if (options.syntax.hash) { - outOptions.syntax.hash = `{function ${options.syntax.hash.name ?? 'anonymous'}}`; - } - if (options.syntax.square) { - outOptions.syntax.square = `{function ${options.syntax.square.name ?? 'anonymous'}}`; - } - } - - return JSON.stringify(outOptions, null, 2); -} - -/** - * @todo Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`) - * @see https://www.chaijs.com/api/bdd/#method_throw - */ -export function shouldThrow(callback, type, msg) { - let failed; - try { - callback(); - failed = true; - } catch (caught) { - if (type && !(caught instanceof type)) { - throw new AssertError('Type failure: ' + caught); - } - if (msg && !(msg.test ? msg.test(caught.message) : msg === caught.message)) { - throw new AssertError( - 'Throw mismatch: Expected ' + caught.message + ' to match ' + msg + '\n\n' + caught.stack, - shouldThrow - ); - } - } - if (failed) { - throw new AssertError('It failed to throw', shouldThrow); - } -} -function astFor(template, options = {}) { - let ast = parse(template, options); - return print(ast); -} diff --git a/packages/@handlebars/parser/spec/visitor.js b/packages/@handlebars/parser/spec/visitor.js deleted file mode 100644 index d72ad3e0edc..00000000000 --- a/packages/@handlebars/parser/spec/visitor.js +++ /dev/null @@ -1,155 +0,0 @@ -import { Visitor, parse, print, Exception } from '../lib/index.js'; -import { equals, shouldThrow } from './utils.js'; - -describe('Visitor', function () { - it('should provide coverage', function () { - // Simply run the thing and make sure it does not fail and that all of the - // stub methods are executed - let visitor = new Visitor(); - visitor.accept( - parse( - '{{foo}}{{#foo (bar 1 "1" true undefined null) foo=@data}}{{!comment}}{{> bar }} {{/foo}}' - ) - ); - visitor.accept(parse('{{#> bar }} {{/bar}}')); - visitor.accept(parse('{{#* bar }} {{/bar}}')); - visitor.accept(parse('{{* bar }}')); - }); - - it('should traverse to stubs', function () { - let visitor = new Visitor(); - - visitor.StringLiteral = function (string) { - equals(string.value, '2'); - }; - visitor.NumberLiteral = function (number) { - equals(number.value, 1); - }; - visitor.BooleanLiteral = function (bool) { - equals(bool.value, true); - - equals(this.parents.length, 3); - equals(this.parents[0].type, 'SubExpression'); - equals(this.parents[1].type, 'BlockStatement'); - equals(this.parents[2].type, 'Program'); - }; - visitor.PathExpression = function (id) { - equals(/(foo\.)?bar$/.test(id.original), true); - }; - visitor.ContentStatement = function (content) { - equals(content.value, ' '); - }; - visitor.CommentStatement = function (comment) { - equals(comment.value, 'comment'); - }; - - visitor.accept( - parse('{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}') - ); - }); - - describe('mutating', function () { - describe('fields', function () { - it('should replace value', function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.StringLiteral = function (string) { - return { type: 'NumberLiteral', value: 42, loc: string.loc }; - }; - - let ast = parse('{{foo foo="foo"}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo HASH{foo=n%42} }}\n'); - }); - it('should treat undefined resonse as identity', function () { - let visitor = new Visitor(); - visitor.mutating = true; - - let ast = parse('{{foo foo=42}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo HASH{foo=n%42} }}\n'); - }); - it('should remove false responses', function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.Hash = function () { - return false; - }; - - let ast = parse('{{foo foo=42}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo }}\n'); - }); - it('should throw when removing required values', function () { - shouldThrow( - function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.PathExpression = function () { - return false; - }; - - let ast = parse('{{foo 42}}'); - visitor.accept(ast); - }, - Exception, - 'MustacheStatement requires path' - ); - }); - it('should throw when returning non-node responses', function () { - shouldThrow( - function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.PathExpression = function () { - return {}; - }; - - let ast = parse('{{foo 42}}'); - visitor.accept(ast); - }, - Exception, - 'Unexpected node type "undefined" found when accepting path on MustacheStatement' - ); - }); - }); - describe('arrays', function () { - it('should replace value', function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.StringLiteral = function (string) { - return { type: 'NumberLiteral', value: 42, loc: string.locInfo }; - }; - - let ast = parse('{{foo "foo"}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo [n%42] }}\n'); - }); - it('should treat undefined resonse as identity', function () { - let visitor = new Visitor(); - visitor.mutating = true; - - let ast = parse('{{foo 42}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo [n%42] }}\n'); - }); - it('should remove false responses', function () { - let visitor = new Visitor(); - - visitor.mutating = true; - visitor.NumberLiteral = function () { - return false; - }; - - let ast = parse('{{foo 42}}'); - visitor.accept(ast); - equals(print(ast), '{{ p%foo }}\n'); - }); - }); - }); -}); diff --git a/packages/@handlebars/parser/src/handlebars.l b/packages/@handlebars/parser/src/handlebars.l deleted file mode 100644 index c23971f2968..00000000000 --- a/packages/@handlebars/parser/src/handlebars.l +++ /dev/null @@ -1,144 +0,0 @@ - -%x mu emu com raw escl - -%{ - -function strip(start, end) { - return yytext = yytext.substring(start, yyleng - end + start); -} - -%} - -LEFT_STRIP "~" -RIGHT_STRIP "~" - -LOOKAHEAD [=~}\s\/.)\]|] -LITERAL_LOOKAHEAD [~}\s)\]] - -/* -ID is the inverse of control characters. -Control characters ranges: - [\s] Whitespace - [!"#%-,\./] !, ", #, %, &, ', (, ), *, +, ,, ., /, Exceptions in range: $, - - [;->@] ;, <, =, >, @, Exceptions in range: :, ? - [\[-\^`] [, \, ], ^, `, Exceptions in range: _ - [\{-~] {, |, }, ~ -*/ -ID [^\s!"#%-,\.\/;->@\[-\^`\{-~]+/{LOOKAHEAD} - -%% - -[^\x00]*?/("{{") { - if(yytext.slice(-2) === "\\\\") { - strip(0,1); - this.begin("mu"); - } else if(yytext.slice(-1) === "\\") { - strip(0,1); - this.begin("emu"); - } else { - this.begin("mu"); - } - if(yytext) return 'CONTENT'; - } - -[^\x00]+ return 'CONTENT'; - -// marks CONTENT up to the next mustache or escaped mustache -[^\x00]{2,}?/("{{"|"\\{{"|"\\\\{{"|<>) { - this.popState(); - return 'CONTENT'; - } - -// nested raw block will create stacked 'raw' condition -"{{{{"/[^/] this.begin('raw'); return 'CONTENT'; -"{{{{/"[^\s!"#%-,\.\/;->@\[-\^`\{-~]+/[=}\s\/.]"}}}}" { - this.popState(); - // Should be using `this.topState()` below, but it currently - // returns the second top instead of the first top. Opened an - // issue about it at https://github.com/zaach/jison/issues/291 - if (this.conditionStack[this.conditionStack.length-1] === 'raw') { - return 'CONTENT'; - } else { - strip(5, 9); - return 'END_RAW_BLOCK'; - } - } -[^\x00]+?/("{{{{") { return 'CONTENT'; } - -[\s\S]*?"--"{RIGHT_STRIP}?"}}" { - this.popState(); - return 'COMMENT'; -} - -"(" return 'OPEN_SEXPR'; -")" return 'CLOSE_SEXPR'; - -"[" { - if (yy.syntax.square === 'string') { - this.unput(yytext); - // escaped literal - this.begin('escl'); - } else { - return 'OPEN_ARRAY'; - } -} -"]" return 'CLOSE_ARRAY'; - - -"{{{{" { return 'OPEN_RAW_BLOCK'; } -"}}}}" { - this.popState(); - this.begin('raw'); - return 'CLOSE_RAW_BLOCK'; - } -"{{"{LEFT_STRIP}?">" return 'OPEN_PARTIAL'; -"{{"{LEFT_STRIP}?"#>" return 'OPEN_PARTIAL_BLOCK'; -"{{"{LEFT_STRIP}?"#""*"? return 'OPEN_BLOCK'; -"{{"{LEFT_STRIP}?"/" return 'OPEN_ENDBLOCK'; -"{{"{LEFT_STRIP}?"^"\s*{RIGHT_STRIP}?"}}" this.popState(); return 'INVERSE'; -"{{"{LEFT_STRIP}?\s*"else"\s*{RIGHT_STRIP}?"}}" this.popState(); return 'INVERSE'; -"{{"{LEFT_STRIP}?"^" return 'OPEN_INVERSE'; -"{{"{LEFT_STRIP}?\s*"else" return 'OPEN_INVERSE_CHAIN'; -"{{"{LEFT_STRIP}?"{" return 'OPEN_UNESCAPED'; -"{{"{LEFT_STRIP}?"&" return 'OPEN'; -"{{"{LEFT_STRIP}?"!--" { - this.unput(yytext); - this.popState(); - this.begin('com'); -} -"{{"{LEFT_STRIP}?"!"[\s\S]*?"}}" { - this.popState(); - return 'COMMENT'; -} -"{{"{LEFT_STRIP}?"*"? return 'OPEN'; - -"=" return 'EQUALS'; -".." return 'ID'; -"."/{LOOKAHEAD} return 'ID'; -".#" return 'PRIVATE_SEP'; -[\/.] return 'SEP'; -\s+ // ignore whitespace -"}"{RIGHT_STRIP}?"}}" this.popState(); return 'CLOSE_UNESCAPED'; -{RIGHT_STRIP}?"}}" this.popState(); return 'CLOSE'; -'"'("\\"["]|[^"])*'"' yytext = strip(1,2).replace(/\\"/g,'"'); return 'STRING'; -"'"("\\"[']|[^'])*"'" yytext = strip(1,2).replace(/\\'/g,"'"); return 'STRING'; -"@" return 'DATA'; -"true"/{LITERAL_LOOKAHEAD} return 'BOOLEAN'; -"false"/{LITERAL_LOOKAHEAD} return 'BOOLEAN'; -"undefined"/{LITERAL_LOOKAHEAD} return 'UNDEFINED'; -"null"/{LITERAL_LOOKAHEAD} return 'NULL'; -\-?[0-9]+(?:\.[0-9]+)?/{LITERAL_LOOKAHEAD} return 'NUMBER'; -"as"\s+"|" return 'OPEN_BLOCK_PARAMS'; -"|" return 'CLOSE_BLOCK_PARAMS'; - -{ID} return 'ID'; - -'['('\\]'|[^\]])*']' { - yytext = yytext.replace(/\\([\\\]])/g,'$1'); - this.popState(); - return 'ID'; -} - -. return 'INVALID'; - -<> return 'EOF'; diff --git a/packages/@handlebars/parser/src/handlebars.yy b/packages/@handlebars/parser/src/handlebars.yy deleted file mode 100644 index ed26c2c5026..00000000000 --- a/packages/@handlebars/parser/src/handlebars.yy +++ /dev/null @@ -1,179 +0,0 @@ -%start root - -%ebnf - -%% - -root - : program EOF { return $1; } - ; - -program - : statement* -> yy.prepareProgram($1) - ; - -statement - : mustache -> $1 - | block -> $1 - | rawBlock -> $1 - | partial -> $1 - | partialBlock -> $1 - | content -> $1 - | COMMENT { - $$ = { - type: 'CommentStatement', - value: yy.stripComment($1), - strip: yy.stripFlags($1, $1), - loc: yy.locInfo(@$) - }; - }; - -content - : CONTENT { - $$ = { - type: 'ContentStatement', - original: $1, - value: $1, - loc: yy.locInfo(@$) - }; - }; - -rawBlock - : openRawBlock content* END_RAW_BLOCK -> yy.prepareRawBlock($1, $2, $3, @$) - ; - -openRawBlock - : OPEN_RAW_BLOCK helperName expr* hash? CLOSE_RAW_BLOCK -> { path: $2, params: $3, hash: $4 } - ; - -block - : openBlock program inverseChain? closeBlock -> yy.prepareBlock($1, $2, $3, $4, false, @$) - | openInverse program inverseAndProgram? closeBlock -> yy.prepareBlock($1, $2, $3, $4, true, @$) - ; - -openBlock - : OPEN_BLOCK helperName expr* hash? blockParams? CLOSE -> { open: $1, path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } - ; - -openInverse - : OPEN_INVERSE helperName expr* hash? blockParams? CLOSE -> { path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } - ; - -openInverseChain - : OPEN_INVERSE_CHAIN helperName expr* hash? blockParams? CLOSE -> { path: $2, params: $3, hash: $4, blockParams: $5, strip: yy.stripFlags($1, $6) } - ; - -inverseAndProgram - : INVERSE program -> { strip: yy.stripFlags($1, $1), program: $2 } - ; - -inverseChain - : openInverseChain program inverseChain? { - var inverse = yy.prepareBlock($1, $2, $3, $3, false, @$), - program = yy.prepareProgram([inverse], $2.loc); - program.chained = true; - - $$ = { strip: $1.strip, program: program, chain: true }; - } - | inverseAndProgram -> $1 - ; - -closeBlock - : OPEN_ENDBLOCK helperName CLOSE -> {path: $2, strip: yy.stripFlags($1, $3)} - ; - -mustache - // Parsing out the '&' escape token at AST level saves ~500 bytes after min due to the removal of one parser node. - // This also allows for handler unification as all mustache node instances can utilize the same handler - : OPEN hash CLOSE -> yy.prepareMustache(yy.syntax.hash($2, yy.locInfo(@$), { yy, syntax: 'expr' }), [], undefined, $1, yy.stripFlags($1, $3), @$) - | OPEN expr expr* hash? CLOSE -> yy.prepareMustache($2, $3, $4, $1, yy.stripFlags($1, $5), @$) - | OPEN_UNESCAPED expr expr* hash? CLOSE_UNESCAPED -> yy.prepareMustache($2, $3, $4, $1, yy.stripFlags($1, $5), @$) - ; - -partial - : OPEN_PARTIAL expr expr* hash? CLOSE { - $$ = { - type: 'PartialStatement', - name: $2, - params: $3, - hash: $4, - indent: '', - strip: yy.stripFlags($1, $5), - loc: yy.locInfo(@$) - }; - } - ; -partialBlock - : openPartialBlock program closeBlock -> yy.preparePartialBlock($1, $2, $3, @$) - ; -openPartialBlock - : OPEN_PARTIAL_BLOCK expr expr* hash? CLOSE -> { path: $2, params: $3, hash: $4, strip: yy.stripFlags($1, $5) } - ; - -expr - : helperName -> $1 - | exprHead -> $1 - ; - -exprHead - : arrayLiteral -> $1 - | sexpr -> $1 - ; - - -sexpr - : OPEN_SEXPR hash CLOSE_SEXPR -> yy.syntax.hash($2, yy.locInfo(@$), { yy, syntax: 'expr' }) - | OPEN_SEXPR expr expr* hash? CLOSE_SEXPR { - $$ = { - type: 'SubExpression', - path: $2, - params: $3, - hash: $4, - loc: yy.locInfo(@$) - }; - }; - -hash - : hashSegment+ -> {type: 'Hash', pairs: $1, loc: yy.locInfo(@$)} - ; - -hashSegment - : ID EQUALS expr -> {type: 'HashPair', key: yy.id($1), value: $3, loc: yy.locInfo(@$)} - ; - -arrayLiteral - : OPEN_ARRAY expr* CLOSE_ARRAY -> yy.syntax.square($2, yy.locInfo(@$), { yy, syntax: 'expr' }) - ; - -blockParams - : OPEN_BLOCK_PARAMS ID+ CLOSE_BLOCK_PARAMS -> yy.id($2) - ; - -helperName - : path -> $1 - | dataName -> $1 - | STRING -> {type: 'StringLiteral', value: $1, original: $1, loc: yy.locInfo(@$)} - | NUMBER -> {type: 'NumberLiteral', value: Number($1), original: Number($1), loc: yy.locInfo(@$)} - | BOOLEAN -> {type: 'BooleanLiteral', value: $1 === 'true', original: $1 === 'true', loc: yy.locInfo(@$)} - | UNDEFINED -> {type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(@$)} - | NULL -> {type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(@$)} - ; - -dataName - : DATA pathSegments -> yy.preparePath(true, false, $2, @$) - ; - -sep - : SEP -> $1 - | PRIVATE_SEP -> $1 - ; - -path - : exprHead sep pathSegments -> yy.preparePath(false, $1, $3, @$) - | pathSegments -> yy.preparePath(false, false, $1, @$) - ; - -pathSegments - : pathSegments sep ID { $1.push({part: yy.id($3), original: $3, separator: $2}); $$ = $1; } - | ID -> [{part: yy.id($1), original: $1}] - ; diff --git a/packages/@handlebars/parser/src/parser-suffix.js b/packages/@handlebars/parser/src/parser-suffix.js deleted file mode 100644 index ef471187e39..00000000000 --- a/packages/@handlebars/parser/src/parser-suffix.js +++ /dev/null @@ -1 +0,0 @@ -export default parser; diff --git a/packages/@handlebars/parser/tsconfig.json b/packages/@handlebars/parser/tsconfig.json deleted file mode 100644 index eb6cd98e79d..00000000000 --- a/packages/@handlebars/parser/tsconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "compilerOptions": { - // Compilation Configuration - "target": "es2017", - "inlineSources": true, - "inlineSourceMap": true, - "outDir": "dist", - "rootDir": "lib", - "esModuleInterop": true, - "moduleResolution": "bundler", - "verbatimModuleSyntax": true, - // Enhance Strictness - "strict": true, - "skipLibCheck": true, - "suppressImplicitAnyIndexErrors": false, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "newLine": "LF", - "allowJs": true - }, - "include": ["lib/**/*.js", "lib/**/*.d.ts"], - "exclude": ["lib/parser.js", "dist", "node_modules", ".vscode"] -} diff --git a/packages/@handlebars/parser/types/ast.d.ts b/packages/@handlebars/parser/types/ast.d.ts deleted file mode 100644 index b9bb2b6c3e7..00000000000 --- a/packages/@handlebars/parser/types/ast.d.ts +++ /dev/null @@ -1,146 +0,0 @@ -export interface Node { - type: string; - loc: SourceLocation; -} - -export interface SourceLocation { - source: string; - start: Position; - end: Position; -} - -export interface Position { - line: number; - column: number; -} - -export interface Program extends Node { - body: Statement[]; - blockParams: string[]; -} - -export interface Statement extends Node {} - -export interface MustacheStatement extends Statement { - type: 'MustacheStatement'; - path: SubExpression | PathExpression | Literal; - params: Expression[]; - hash: Hash; - escaped: boolean; - strip: StripFlags; -} - -export interface Decorator extends MustacheStatement { } - -export interface BlockStatement extends Statement { - type: 'BlockStatement'; - path: PathExpression; - params: Expression[]; - hash: Hash; - program: Program; - inverse: Program; - openStrip: StripFlags; - inverseStrip: StripFlags; - closeStrip: StripFlags; -} - -export interface DecoratorBlock extends BlockStatement { } - -export interface PartialStatement extends Statement { - type: 'PartialStatement'; - name: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; - indent: string; - strip: StripFlags; -} - -export interface PartialBlockStatement extends Statement { - type: 'PartialBlockStatement'; - name: PathExpression | SubExpression; - params: Expression[]; - hash: Hash; - program: Program; - openStrip: StripFlags; - closeStrip: StripFlags; -} - -export interface ContentStatement extends Statement { - type: 'ContentStatement'; - value: string; - original: StripFlags; -} - -export interface CommentStatement extends Statement { - type: 'CommentStatement'; - value: string; - strip: StripFlags; -} - -export interface Expression extends Node {} - -export interface SubExpression extends Expression { - type: 'SubExpression'; - path: SubExpression | PathExpression; - params: Expression[]; - hash: Hash; -} - -export interface PathExpression extends Expression { - type: 'PathExpression'; - data: boolean; - depth: number; - parts: (string | SubExpression)[]; - head: SubExpression | string; - tail: string[]; - original: string; -} - -export interface Literal extends Expression {} -export interface StringLiteral extends Literal { - type: 'StringLiteral'; - value: string; - original: string; -} - -export interface BooleanLiteral extends Literal { - type: 'BooleanLiteral'; - value: boolean; - original: boolean; -} - -export interface NumberLiteral extends Literal { - type: 'NumberLiteral'; - value: number; - original: number; -} - -export interface UndefinedLiteral extends Literal { - type: 'UndefinedLiteral'; -} - -export interface NullLiteral extends Literal { - type: 'NullLiteral'; -} - -export interface Hash extends Node { - type: 'Hash'; - pairs: HashPair[]; -} - -export interface HashPair extends Node { - type: 'HashPair'; - key: string; - value: Expression; -} - -export interface StripFlags { - open: boolean; - close: boolean; -} - -export interface helpers { - helperExpression(node: Node): boolean; - scopeId(path: PathExpression): boolean; - simpleId(path: PathExpression): boolean; -} diff --git a/packages/@handlebars/parser/types/index.d.ts b/packages/@handlebars/parser/types/index.d.ts deleted file mode 100644 index 88ed676ddcc..00000000000 --- a/packages/@handlebars/parser/types/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as AST from './ast'; - -export { AST }; - -export interface ParseOptions { - srcName?: string; - ignoreStandalone?: boolean; -} - -export function parse(input: string, options?: ParseOptions): AST.Program; -export function parseWithoutProcessing(input: string, options?: ParseOptions): AST.Program; diff --git a/packages/internal-test-helpers/lib/equal-tokens.ts b/packages/internal-test-helpers/lib/equal-tokens.ts index 8ff757992f1..63a6c4e8f45 100644 --- a/packages/internal-test-helpers/lib/equal-tokens.ts +++ b/packages/internal-test-helpers/lib/equal-tokens.ts @@ -1,33 +1,27 @@ -import { tokenize } from 'simple-html-tokenizer'; +// Compare two HTML fragments for semantic equivalence, ignoring attribute order. +// Uses the browser's DOM parser to normalize both sides. -function generateTokens(containerOrHTML: string | Element) { - if (typeof containerOrHTML === 'string') { - return { - tokens: tokenize(containerOrHTML), - html: containerOrHTML, - }; - } else { - return { - tokens: tokenize(containerOrHTML.innerHTML), - html: containerOrHTML.innerHTML, - }; - } +function normalizeHTML(html: string): string { + const container = document.createElement('div'); + container.innerHTML = html; + sortAttributes(container); + return container.innerHTML; } -function normalizeTokens(tokens: ReturnType) { - tokens.forEach((token) => { - if (token.type === 'StartTag') { - token.attributes = token.attributes.sort((a, b) => { - if (a[0] > b[0]) { - return 1; - } - if (a[0] < b[0]) { - return -1; - } - return 0; - }); +function sortAttributes(element: Element): void { + for (const child of Array.from(element.children)) { + if (child.attributes.length > 1) { + const attrs = Array.from(child.attributes).map((a) => [a.name, a.value] as const); + attrs.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)); + for (const [name] of attrs) { + child.removeAttribute(name); + } + for (const [name, value] of attrs) { + child.setAttribute(name, value); + } } - }); + sortAttributes(child); + } } export default function equalTokens( @@ -35,23 +29,16 @@ export default function equalTokens( expectedHTML: string, message: string | null = null ) { - let actual = generateTokens(actualContainer); - let expected = generateTokens(expectedHTML); - - normalizeTokens(actual.tokens); - normalizeTokens(expected.tokens); + const actualHTML = + typeof actualContainer === 'string' ? actualContainer : actualContainer.innerHTML; + const normalizedActual = normalizeHTML(actualHTML); + const normalizedExpected = normalizeHTML(expectedHTML); - let { assert } = QUnit.config.current; - let equiv = QUnit.equiv(actual.tokens, expected.tokens); - - if (equiv && expected.html !== actual.html) { - assert.deepEqual(actual.tokens, expected.tokens, message); - } else { - assert.pushResult({ - result: QUnit.equiv(actual.tokens, expected.tokens), - actual: actual.html, - expected: expected.html, - message, - }); - } + const { assert } = QUnit.config.current; + assert.pushResult({ + result: normalizedActual === normalizedExpected, + actual: actualHTML, + expected: expectedHTML, + message, + }); } diff --git a/packages/internal-test-helpers/package.json b/packages/internal-test-helpers/package.json index d09f8ef17c0..f42ccef025c 100644 --- a/packages/internal-test-helpers/package.json +++ b/packages/internal-test-helpers/package.json @@ -40,7 +40,6 @@ "ember": "workspace:*", "ember-template-compiler": "workspace:*", "router_js": "workspace:*", - "rsvp": "^4.8.5", - "simple-html-tokenizer": "^0.5.11" + "rsvp": "^4.8.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ce161c9c14..2fd831dad7e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -71,9 +71,6 @@ importers: silent-error: specifier: ^1.1.1 version: 1.1.1 - simple-html-tokenizer: - specifier: ^0.5.11 - version: 0.5.11 devDependencies: '@aws-sdk/client-s3': specifier: ^3.731.0 @@ -1378,9 +1375,6 @@ importers: qunit: specifier: ^2.24.1 version: 2.25.0 - simple-html-tokenizer: - specifier: ^0.5.11 - version: 0.5.11 devDependencies: '@ember/runloop': specifier: workspace:* @@ -2150,12 +2144,6 @@ importers: '@glimmer/wire-format': specifier: workspace:* version: link:../wire-format - '@handlebars/parser': - specifier: workspace:* - version: link:../../@handlebars/parser - simple-html-tokenizer: - specifier: ^0.5.11 - version: 0.5.11 devDependencies: '@glimmer/debug-util': specifier: workspace:* @@ -2325,21 +2313,6 @@ importers: specifier: ^5.7.3 version: 5.9.3 - packages/@handlebars/parser: - devDependencies: - combine-files: - specifier: ^1.1.8 - version: 1.1.8 - jison: - specifier: ^0.4.18 - version: 0.4.18 - mocha: - specifier: ^11.0.0 - version: 11.7.5 - npm-run-all2: - specifier: ^8.0.0 - version: 8.0.4 - packages/@types/js-reporters: {} packages/ember: @@ -2728,9 +2701,6 @@ importers: rsvp: specifier: ^4.8.5 version: 4.8.5 - simple-html-tokenizer: - specifier: ^0.5.11 - version: 0.5.11 packages/router_js: dependencies: @@ -5853,13 +5823,6 @@ packages: engines: {node: '>= 8'} hasBin: true - JSONSelect@0.4.0: - resolution: {integrity: sha512-VRLR3Su35MH+XV2lrvh9O7qWoug/TUyj9tLDjn9rtpUCNnILLrHjgd/tB0KrhugCxUpj3UqoLqfYb3fLJdIQQQ==} - engines: {node: '>=0.4.7'} - - JSV@4.0.2: - resolution: {integrity: sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==} - abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -6690,10 +6653,6 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} - cjson@0.3.0: - resolution: {integrity: sha512-bBRQcCIHzI1IVH59fR0bwGrFmi3Btb/JNwM/n401i1DnYgWndpsUBiQRAddLflkZage20A2d25OAWZZk0vBRlA==} - engines: {node: '>= 0.3.0'} - clean-base-url@1.0.0: resolution: {integrity: sha512-9q6ZvUAhbKOSRFY7A/irCQ/rF0KIpa3uXpx6izm8+fp7b2H4hLeUJ+F1YYk9+gDQ/X8Q0MEyYs+tG3cht//HTg==} @@ -6816,10 +6775,6 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - colors@0.5.1: - resolution: {integrity: sha512-XjsuUwpDeY98+yz959OlUK6m7mLBM+1MEG5oaenfuQnNnrQk1WvtcvFgN3FNDP3f2NmZ211t0mNEfSEN1h0eIg==} - engines: {node: '>=0.1.90'} - colors@1.0.3: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} @@ -6828,10 +6783,6 @@ packages: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} - combine-files@1.1.8: - resolution: {integrity: sha512-Ut/1sjySj6DyjyWZ5fQNThTTAZlj7968tozHqSGXFEcyaQeQUKFdb1HZDcNrzGRfAbKERw2S2m/+5x6zupBU6A==} - hasBin: true - combined-stream@0.0.7: resolution: {integrity: sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig==} engines: {node: '>= 0.8'} @@ -7408,9 +7359,6 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - ebnf-parser@0.1.10: - resolution: {integrity: sha512-urvSxVQ6XJcoTpc+/x2pWhhuOX4aljCNQpwzw+ifZvV1andZkAmiJc3Rq1oGEAQmcjiLceyMXOy1l8ms8qs2fQ==} - editions@1.3.4: resolution: {integrity: sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==} engines: {node: '>=0.8'} @@ -7730,11 +7678,6 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - escodegen@1.3.3: - resolution: {integrity: sha512-z9FWgKc48wjMlpzF5ymKS1AF8OIgnKLp9VyN7KbdtyrP/9lndwUFqCtMm+TAJmJf7KJFFYc4cFJfVTTGkKEwsA==} - engines: {node: '>=0.10.0'} - hasBin: true - eslint-compat-utils@0.5.1: resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} engines: {node: '>=12'} @@ -7876,11 +7819,6 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esprima@1.1.1: - resolution: {integrity: sha512-qxxB994/7NtERxgXdFgLHIs9M6bhLXc6qtUmWZ3L8+gTQ9qaoyki2887P2IqAYsoENyr8SUbTutStDniOHSDHg==} - engines: {node: '>=0.4.0'} - hasBin: true - esprima@3.0.0: resolution: {integrity: sha512-xoBq/MIShSydNZOkjkoCEjqod963yHNXTLC40ypBhop6yPqflPz/vTinmCfSrGcywVLnSftRf6a0kJLdFdzemw==} engines: {node: '>=0.10.0'} @@ -7899,10 +7837,6 @@ packages: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} - estraverse@1.5.1: - resolution: {integrity: sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ==} - engines: {node: '>=0.4.0'} - estraverse@4.3.0: resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} engines: {node: '>=4.0'} @@ -7914,10 +7848,6 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - esutils@1.0.0: - resolution: {integrity: sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg==} - engines: {node: '>=0.10.0'} - esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -9056,16 +8986,6 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} - jison-lex@0.3.4: - resolution: {integrity: sha512-EBh5wrXhls1cUwROd5DcDHR1sG7CdsCFSqY1027+YA1RGxz+BX2TDLAhdsQf40YEtFDGoiO0Qm8PpnBl2EzDJw==} - engines: {node: '>=0.4'} - hasBin: true - - jison@0.4.18: - resolution: {integrity: sha512-FKkCiJvozgC7VTHhMJ00a0/IApSxhlGsFIshLW6trWJ8ONX2TQJBBz6DlcO1Gffy4w9LT+uL+PA+CVnUSJMF7w==} - engines: {node: '>=0.4'} - hasBin: true - js-reporters@2.1.0: resolution: {integrity: sha512-Q4GcEcPSb6ovhqp91claM3WPbSntQxbIn+3JiJgEXturys2ttWgs31VC60Yja+2unpNOH2A2qyjWFU2thCQ8sg==} engines: {node: '>=10'} @@ -9164,11 +9084,6 @@ packages: jsonify@0.0.1: resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} - jsonlint@1.6.0: - resolution: {integrity: sha512-x6YLBe6NjdpmIeiklwQOxsZuYj/SOWkT33GlTpaG1UdFGjdWjPcxJ1CWZAX3wA7tarz8E2YHF6KiW5HTapPlXw==} - engines: {node: '>= 0.6'} - hasBin: true - jstat@1.9.6: resolution: {integrity: sha512-rPBkJbK2TnA8pzs93QcDDPlKcrtZWuuCo2dVR0TFLOJSxhqfWOVCSp8aV3/oSbn+4uY4yw1URtLpHQedtmXfug==} @@ -9215,9 +9130,6 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lex-parser@0.1.4: - resolution: {integrity: sha512-DuAEISsr1H4LOpmFLkyMc8YStiRWZCO8hMsoXAXSbgyfvs2WQhSt0+/FBv3ZU/JBFZMGcE+FWzEBSzwUU7U27w==} - lighthouse-logger@2.0.2: resolution: {integrity: sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==} @@ -9734,10 +9646,6 @@ packages: resolution: {integrity: sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==} engines: {node: '>=6'} - nomnom@1.5.2: - resolution: {integrity: sha512-fiVbT7BqxiQqjlR9U3FDGOSERFCKoXVCdxV2FwZuNN7/cmJ42iQx35nUFOAFDcyvemu9Adp+IlsCGlKQYLmBKw==} - deprecated: Package no longer supported. Contact support@npmjs.com for more info. - nopt@3.0.6: resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} hasBin: true @@ -10908,10 +10816,6 @@ packages: resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} deprecated: See https://github.com/lydell/source-map-url#deprecated - source-map@0.1.43: - resolution: {integrity: sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ==} - engines: {node: '>=0.8.0'} - source-map@0.4.4: resolution: {integrity: sha512-Y8nIfcb1s/7DcobUz1yOO1GSp7gyL+D9zLHDehT7iRESqGSxjJ448Sg7rvfgsRJCnKLdSl11uGf0s9X80cH0/A==} engines: {node: '>=0.8.0'} @@ -11503,9 +11407,6 @@ packages: underscore.string@3.3.6: resolution: {integrity: sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==} - underscore@1.1.7: - resolution: {integrity: sha512-w4QtCHoLBXw1mjofIDoMyexaEdWGMedWNDhlWTtT1V1lCRqi65Pnoygkh6+WRdr+Bm8ldkBNkNeCsXGMlQS9HQ==} - underscore@1.13.8: resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} @@ -15547,10 +15448,6 @@ snapshots: dependencies: isexe: 2.0.0 - JSONSelect@0.4.0: {} - - JSV@4.0.2: {} - abbrev@1.1.1: {} accepts@1.3.8: @@ -16763,10 +16660,6 @@ snapshots: ci-info@4.4.0: {} - cjson@0.3.0: - dependencies: - jsonlint: 1.6.0 - clean-base-url@1.0.0: {} clean-css@5.3.3: @@ -16878,14 +16771,10 @@ snapshots: colorette@2.0.20: {} - colors@0.5.1: {} - colors@1.0.3: {} colors@1.4.0: {} - combine-files@1.1.8: {} - combined-stream@0.0.7: dependencies: delayed-stream: 0.0.5 @@ -17317,8 +17206,6 @@ snapshots: eastasianwidth@0.2.0: {} - ebnf-parser@0.1.10: {} - editions@1.3.4: {} editions@2.3.1: @@ -18060,14 +17947,6 @@ snapshots: escape-string-regexp@4.0.0: {} - escodegen@1.3.3: - dependencies: - esprima: 1.1.1 - estraverse: 1.5.1 - esutils: 1.0.0 - optionalDependencies: - source-map: 0.1.43 - eslint-compat-utils@0.5.1(eslint@9.39.4): dependencies: eslint: 9.39.4 @@ -18257,8 +18136,6 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 - esprima@1.1.1: {} - esprima@3.0.0: {} esprima@4.0.1: {} @@ -18271,16 +18148,12 @@ snapshots: dependencies: estraverse: 5.3.0 - estraverse@1.5.1: {} - estraverse@4.3.0: {} estraverse@5.3.0: {} estree-walker@2.0.2: {} - esutils@1.0.0: {} - esutils@2.0.3: {} etag@1.8.1: {} @@ -19658,22 +19531,6 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jison-lex@0.3.4: - dependencies: - lex-parser: 0.1.4 - nomnom: 1.5.2 - - jison@0.4.18: - dependencies: - JSONSelect: 0.4.0 - cjson: 0.3.0 - ebnf-parser: 0.1.10 - escodegen: 1.3.3 - esprima: 1.1.1 - jison-lex: 0.3.4 - lex-parser: 0.1.4 - nomnom: 1.5.2 - js-reporters@2.1.0: {} js-string-escape@1.0.1: {} @@ -19796,11 +19653,6 @@ snapshots: jsonify@0.0.1: {} - jsonlint@1.6.0: - dependencies: - JSV: 4.0.2 - nomnom: 1.5.2 - jstat@1.9.6: {} keyv@3.1.0: @@ -19847,8 +19699,6 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lex-parser@0.1.4: {} - lighthouse-logger@2.0.2: dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -20370,11 +20220,6 @@ snapshots: node-watch@0.7.3: {} - nomnom@1.5.2: - dependencies: - colors: 0.5.1 - underscore: 1.1.7 - nopt@3.0.6: dependencies: abbrev: 1.1.1 @@ -21718,11 +21563,6 @@ snapshots: source-map-url@0.4.1: {} - source-map@0.1.43: - dependencies: - amdefine: 1.0.1 - optional: true - source-map@0.4.4: dependencies: amdefine: 1.0.1 @@ -22569,8 +22409,6 @@ snapshots: sprintf-js: 1.1.3 util-deprecate: 1.0.2 - underscore@1.1.7: {} - underscore@1.13.8: {} undici-types@6.21.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ea6c625d4b4..9814be2538d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,7 +3,6 @@ packages: - 'packages/@ember/*' - 'packages/@glimmer/*' - 'packages/@glimmer-workspace/*' - - 'packages/@handlebars/*' - 'packages/@types/*' - 'packages/*/*/test' - 'smoke-tests/*' diff --git a/rollup.config.mjs b/rollup.config.mjs index 3ab820dbdfa..9cbd0044bd1 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -216,9 +216,6 @@ function packages() { // "exposedDependencies" since they used to actually be dependencies. '@glimmer-workspace/**', '@glimmer/**', - - // @handlebars/parser is a hidden dependency, not an explicit entrypoint - '@handlebars/**', ], cwd: 'packages', }); @@ -279,11 +276,6 @@ export function exposedDependencies() { // expose to consumers export function hiddenDependencies() { return { - 'simple-html-tokenizer': entrypoint( - findFromProject('@glimmer/syntax', 'simple-html-tokenizer'), - 'module' - ).path, - '@handlebars/parser': resolve(packageCache.appRoot, 'packages/@handlebars/parser/lib/index.js'), ...walkGlimmerDeps(['@glimmer/compiler']), 'decorator-transforms/runtime': resolve( findFromProject('decorator-transforms').root,