OverviewFilesCommitsIssuesDocsReleasesPeers

codetree commits / 29e8c18

Initial commit — codetree
Structural code scanner — recursive mind map of a codebase. Exports JSON / DOT / Mermaid from a source tree; optional HTTP browser via bare-http1 for interactive drill-down. Bare-runtime first (import maps target bare-fs / bare-path / bare-url / bare-process / bare-http1 with Node fallbacks). CLI via paparam. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
29e8c1845f1917f197bc76610a49c857b2399dca
by plankatron <fleeky@gmail.com> · 2026-04-15T16:59:44.000Z

Changed files (53) +50399 -0

.gitignore +12 -0
……@@ -0,0 +1,12 @@
1# Dependencies
2node_modules/
3
4# Editor and OS cruft
5.DS_Store
6*.log
7*.swp
8.vscode/
9.idea/
10
11# Test artifacts
12coverage/
bin/profile-scan.mjs +57 -0
……@@ -0,0 +1,57 @@
1#!/usr/bin/env bare
2import process from 'process'
3import { scanStream } from '../lib/scan-stream.js'
4import { TreeReducer } from '../lib/reducers/tree-reducer.js'
5import { MetricsReducer } from '../lib/reducers/metrics-reducer.js'
6import { buildIgnoreMatcher } from '../lib/ignore.js'
7
8const rootDir = process.argv[2] || '.'
9const maxDepth = parseInt(process.argv[3] || '2', 10)
10const extraIgnores = (process.argv[4] || '').split(',').filter(Boolean)
11const shallow = process.argv.includes('--shallow')
12
13console.log('Profile-scan:', rootDir)
14console.log(' maxDepth:', maxDepth)
15console.log(' shallow: ', shallow)
16console.log(' ignore: ', extraIgnores.length ? extraIgnores.join(',') : '(builtins only)')
17console.log()
18
19const ignore = buildIgnoreMatcher(rootDir, extraIgnores)
20
21const source = scanStream(rootDir, { maxDepth, ignore, shallow })
22const tree = new TreeReducer().attach(source)
23const metrics = new MetricsReducer().attach(source)
24
25await new Promise((resolveP, reject) => {
26 source.once('scan-end', resolveP)
27 source.once('error', reject)
28})
29
30const graph = tree.finalize()
31const m = metrics.report()
32
33console.log('=== Results ===')
34console.log(` total duration: ${m.totalDuration}ms`)
35console.log(` modules: ${m.moduleCount}`)
36console.log(` files discovered: ${m.fileCount}`)
37console.log(` files parsed: ${m.parseCount}`)
38console.log(` parse errors: ${m.parseErrors}`)
39console.log(` import edges: ${m.importEdges} (${m.implicitEdges} implicit)`)
40console.log(` bytes read: ${(m.bytesRead / 1024 / 1024).toFixed(2)} MB`)
41console.log(` largest file: ${m.largestFile.path} (${(m.largestFile.size / 1024).toFixed(0)} KB)`)
42console.log()
43console.log(` throughput: ${m.throughputFilesPerSec} files/s, ${m.throughputMBPerSec} MB/s`)
44console.log(` parse time p50: ${m.parseTimeP50}ms`)
45console.log(` parse time p95: ${m.parseTimeP95}ms`)
46console.log(` parse time p99: ${m.parseTimeP99}ms`)
47console.log(` parse time total: ${m.parseTimeTotal}ms`)
48console.log()
49console.log('=== File extensions ===')
50for (const [ext, count] of m.topExtensions) {
51 console.log(` ${ext.padEnd(14)} ${count}`)
52}
53console.log()
54console.log('=== Slowest modules ===')
55for (const mod of m.slowestModules) {
56 console.log(` ${mod.name.padEnd(30)} ${mod.duration}ms`)
57}
index.js +460 -0
……@@ -0,0 +1,460 @@
1#!/usr/bin/env bare
2
3import process from 'process'
4import { resolve } from 'path'
5import { scan } from './lib/scanner.js'
6
7const args = process.argv.slice(2)
8const command = args[0]
9const pretty = args.includes('--pretty') || args.includes('-p')
10
11if (!command || command === '--help' || command === '-h') {
12 printUsage()
13 process.exit(0)
14}
15
16// Commands that take a module name as args[1]
17const MODULE_COMMANDS = ['module', 'exports', 'deps', 'file', 'imports']
18const positionalArgs = args.filter(a => !a.startsWith('-') && a !== command)
19const hasModuleArg = MODULE_COMMANDS.includes(command)
20const dir = resolve(hasModuleArg ? (positionalArgs[1] || '.') : (positionalArgs[0] || '.'))
21const opts = {}
22
23if (args.includes('--depth')) {
24 const idx = args.indexOf('--depth')
25 opts.maxDepth = parseInt(args[idx + 1], 10) || 2
26}
27
28// --ignore "pattern1,pattern2" — extra ignore patterns (in addition to .codetreeignore
29// and the built-in skip list). Commas separate patterns; use gitignore-style syntax.
30if (args.includes('--ignore')) {
31 const idx = args.indexOf('--ignore')
32 const raw = args[idx + 1] || ''
33 opts.ignore = raw.split(',').map(s => s.trim()).filter(Boolean)
34}
35
36// --shallow — parse only the entry file per module. Drops AST analysis of the
37// rest of the project; keeps module names, deps, and top-level exports.
38// For multi-project recursive scans this is 10-100x faster.
39if (args.includes('--shallow')) {
40 opts.shallow = true
41}
42
43// --no-watch — disable fs.watch in serve mode. Useful for huge trees that
44// exceed the inotify watch limit (ENOSPC). Server still serves the snapshot.
45if (args.includes('--no-watch')) {
46 opts.watch = false
47}
48
49async function main () {
50 switch (command) {
51 case 'scan': return cmdScan()
52 case 'module': return cmdModule()
53 case 'file': return cmdFile()
54 case 'exports': return cmdExports()
55 case 'deps': return cmdDeps()
56 case 'imports': return cmdImports()
57 case 'docs': return cmdDocs()
58 case 'categories': return cmdCategories()
59 case 'summary': return cmdSummary()
60 case 'serve': return cmdServe()
61 default:
62 console.error(`Unknown command: ${command}`)
63 printUsage()
64 process.exit(1)
65 }
66}
67
68async function cmdScan () {
69 const tree = await scan(dir, opts)
70 output(tree)
71}
72
73async function cmdModule () {
74 const name = args[1]
75 if (!name) {
76 console.error('Usage: codetree module <name> [dir]')
77 process.exit(1)
78 }
79
80 const tree = await scan(dir, opts)
81 const mod = tree.modules[name]
82
83 if (!mod) {
84 console.error(`Module not found: ${name}`)
85 console.error(`Available: ${tree.system.modules.join(', ')}`)
86 process.exit(1)
87 }
88
89 output(mod)
90}
91
92async function cmdFile () {
93 const filePath = args[1]
94 if (!filePath) {
95 console.error('Usage: codetree file <path> [dir]')
96 process.exit(1)
97 }
98
99 const tree = await scan(dir, opts)
100
101 for (const mod of Object.values(tree.modules)) {
102 if (mod.files[filePath]) {
103 output(mod.files[filePath])
104 return
105 }
106 }
107
108 console.error(`File not found: ${filePath}`)
109 process.exit(1)
110}
111
112async function cmdExports () {
113 const name = args[1]
114 if (!name) {
115 console.error('Usage: codetree exports <module> [dir]')
116 process.exit(1)
117 }
118
119 const tree = await scan(dir, opts)
120 const mod = tree.modules[name]
121
122 if (!mod) {
123 console.error(`Module not found: ${name}`)
124 process.exit(1)
125 }
126
127 if (pretty) {
128 console.log(`${mod.name}@${mod.version} public API:`)
129 for (const name of mod.publicAPI) {
130 console.log(` ${name}`)
131 }
132 console.log()
133 console.log('File exports:')
134 for (const [file, data] of Object.entries(mod.files)) {
135 if (data.exports.length === 0) continue
136 console.log(` ${file}:`)
137 for (const exp of data.exports) {
138 const type = exp.type ? ` (${exp.type})` : ''
139 const from = exp.from ? ` from ${exp.from}` : ''
140 console.log(` ${exp.name}${type}${from}`)
141 }
142 }
143 } else {
144 output({
145 module: mod.name,
146 publicAPI: mod.publicAPI,
147 fileExports: Object.fromEntries(
148 Object.entries(mod.files)
149 .filter(([_, f]) => f.exports.length > 0)
150 .map(([k, f]) => [k, f.exports])
151 )
152 })
153 }
154}
155
156async function cmdDeps () {
157 const name = args[1]
158 if (!name) {
159 console.error('Usage: codetree deps <module> [dir]')
160 process.exit(1)
161 }
162
163 const tree = await scan(dir, opts)
164 const mod = tree.modules[name]
165
166 if (!mod) {
167 console.error(`Module not found: ${name}`)
168 process.exit(1)
169 }
170
171 if (pretty) {
172 console.log(`${mod.name} dependencies:`)
173 for (const [dep, ver] of Object.entries(mod.dependencies)) {
174 const isLocal = tree.modules[dep] ? ' (local)' : ''
175 console.log(` ${dep}: ${ver}${isLocal}`)
176 }
177 console.log()
178
179 // Reverse deps
180 const reverseDeps = []
181 for (const [otherName, otherMod] of Object.entries(tree.modules)) {
182 if (otherMod.dependencies[name]) {
183 reverseDeps.push(otherName)
184 }
185 }
186 if (reverseDeps.length > 0) {
187 console.log(`Used by:`)
188 for (const rd of reverseDeps) {
189 console.log(` ${rd}`)
190 }
191 }
192 } else {
193 const reverseDeps = []
194 for (const [otherName, otherMod] of Object.entries(tree.modules)) {
195 if (otherMod.dependencies[name]) reverseDeps.push(otherName)
196 }
197 output({
198 module: mod.name,
199 dependencies: mod.dependencies,
200 usedBy: reverseDeps
201 })
202 }
203}
204
205async function cmdImports () {
206 const name = args[1]
207 if (!name) {
208 console.error('Usage: codetree imports <module> [dir]')
209 process.exit(1)
210 }
211
212 const tree = await scan(dir, opts)
213 const mod = tree.modules[name]
214
215 if (!mod) {
216 console.error(`Module not found: ${name}`)
217 console.error(`Available: ${tree.system.modules.join(', ')}`)
218 process.exit(1)
219 }
220
221 if (!mod.importGraph) {
222 console.error('No import graph data (no local imports found)')
223 process.exit(1)
224 }
225
226 if (pretty) {
227 const graph = mod.importGraph
228 console.log(`${mod.name} — internal architecture\n`)
229
230 // Directory dependency matrix
231 const dirs = Object.keys(graph.directories).sort()
232 if (dirs.length > 0) {
233 console.log('Directory dependency matrix:')
234 for (const srcDir of dirs) {
235 const targets = graph.directoryMatrix[srcDir]
236 if (!targets) continue
237 const pairs = Object.entries(targets)
238 .filter(([tgt]) => tgt !== srcDir)
239 .sort((a, b) => b[1] - a[1])
240 if (pairs.length === 0) continue
241 const targetStr = pairs.map(([tgt, count]) => `${tgt} (${count})`).join(', ')
242 console.log(` ${srcDir} -> ${targetStr}`)
243 }
244 console.log()
245
246 // Directory stats
247 console.log('Directory stats:')
248 for (const d of dirs) {
249 const s = graph.directories[d]
250 console.log(` ${d}: ${s.files} files, fan-in ${s.incomingEdges}, fan-out ${s.outgoingEdges}, internal ${s.internalEdges}`)
251 }
252 console.log()
253 }
254
255 // Sub-modules
256 if (mod.subModules && Object.keys(mod.subModules).length > 0) {
257 console.log('Discovered sub-modules:')
258 const sorted = Object.entries(mod.subModules).sort((a, b) => b[1].fanIn - a[1].fanIn)
259 for (const [dir, sm] of sorted) {
260 const idx = sm.indexFile ? ' [index.js]' : ''
261 const reexp = sm.hasReExports ? ' [re-exports]' : ''
262 console.log(` ${dir}${idx}${reexp}`)
263 console.log(` ${sm.files.length} files, fan-in ${sm.fanIn}, fan-out ${sm.fanOut}, cohesion ${sm.cohesion}`)
264 if (sm.publicExports.length > 0) {
265 console.log(` exports: ${sm.publicExports.join(', ')}`)
266 }
267 }
268 }
269 } else {
270 output({
271 module: mod.name,
272 importGraph: mod.importGraph,
273 subModules: mod.subModules
274 })
275 }
276}
277
278async function cmdDocs () {
279 const tree = await scan(dir, opts)
280
281 if (!tree.docCruft) {
282 console.error('No documentation found')
283 process.exit(1)
284 }
285
286 const cruft = tree.docCruft
287
288 if (pretty) {
289 console.log(`Documentation cruft report\n`)
290 console.log(`Total: ${cruft.summary.totalDocs} docs, ${cruft.summary.totalLines} lines`)
291 console.log(`Fresh (score <= 0.3): ${cruft.summary.freshDocs}`)
292 console.log(`Stale (score > 0.5): ${cruft.summary.staleDocs}`)
293 console.log(`References: ${cruft.summary.validReferences} valid, ${cruft.summary.missingReferences} missing`)
294 console.log()
295
296 for (const doc of cruft.docs) {
297 if (doc.references.total === 0 && doc.staleness.score < 0.3) continue
298
299 const icon = doc.staleness.score > 0.5 ? 'STALE' : doc.staleness.score > 0.3 ? 'WARN ' : 'FRESH'
300 console.log(`${icon} ${doc.path} (${doc.lines} lines, modified ${doc.lastModified}, score ${doc.staleness.score})`)
301
302 if (doc.references.missing > 0) {
303 const missing = doc.references.details.filter(d => d.status === 'missing')
304 for (const m of missing.slice(0, 5)) {
305 console.log(` missing: ${m.ref} (${m.type}, line ${m.line})`)
306 }
307 if (missing.length > 5) {
308 console.log(` ... and ${missing.length - 5} more`)
309 }
310 }
311 }
312 } else {
313 output(cruft)
314 }
315}
316
317async function cmdCategories () {
318 const tree = await scan(dir, opts)
319
320 // Build the same category mapping the visualization uses — see render.js initGraph().
321 // Start with SYSTEM.md categories (if any), then fall back to shared-dep clustering.
322 const categories = tree.categories || {}
323 const moduleToCategory = {}
324 for (const [cat, mods] of Object.entries(categories)) {
325 for (const m of mods) moduleToCategory[m] = cat
326 }
327
328 const shared = tree.system.sharedDeps || {}
329 const depToMostShared = {}
330 for (const [dep, users] of Object.entries(shared)) {
331 for (const u of users) {
332 const prev = depToMostShared[u]
333 if (!prev || users.length > shared[prev].length) depToMostShared[u] = dep
334 }
335 }
336 for (const name of tree.system.modules) {
337 if (moduleToCategory[name]) continue
338 const topDep = depToMostShared[name]
339 moduleToCategory[name] = topDep ? (topDep + ' users') : 'Other'
340 }
341
342 // Invert for display: category → [modules]
343 const byCategory = {}
344 for (const [name, cat] of Object.entries(moduleToCategory)) {
345 if (!byCategory[cat]) byCategory[cat] = []
346 byCategory[cat].push(name)
347 }
348
349 if (pretty) {
350 console.log(`Module categories for ${tree.root}\n`)
351 const sorted = Object.entries(byCategory).sort((a, b) => b[1].length - a[1].length)
352 for (const [cat, names] of sorted) {
353 console.log(` ${cat} (${names.length})`)
354 for (const n of names.sort()) console.log(` ${n}`)
355 }
356 console.log()
357 const specNames = new Set()
358 for (const mods of Object.values(categories)) for (const m of mods) specNames.add(m)
359 const total = Object.keys(moduleToCategory).length
360 const fromSpec = [...Object.keys(moduleToCategory)].filter(m => specNames.has(m)).length
361 const autoDerived = total - fromSpec
362 console.log(`Source: ${fromSpec} from SYSTEM.md, ${autoDerived} auto-derived from shared dependencies`)
363 } else {
364 output({
365 source: Object.keys(categories).length > 0 ? 'mixed' : 'auto',
366 fromSystemMd: categories,
367 assignments: moduleToCategory,
368 byCategory
369 })
370 }
371}
372
373async function cmdSummary () {
374 const tree = await scan(dir, opts)
375
376 console.log(`Scanned: ${tree.root}`)
377 console.log(`Modules: ${tree.system.modules.length}`)
378 console.log()
379
380 for (const name of tree.system.modules) {
381 const mod = tree.modules[name]
382 const fileCount = Object.keys(mod.files).length
383 const exportCount = mod.publicAPI.length
384 const deps = Object.keys(mod.dependencies).length
385
386 let classCount = 0
387 let methodCount = 0
388 for (const file of Object.values(mod.files)) {
389 if (file.classes) {
390 classCount += file.classes.length
391 for (const cls of file.classes) {
392 methodCount += cls.methods.length + cls.getters.length
393 }
394 }
395 }
396
397 console.log(` ${name}@${mod.version}`)
398 console.log(` ${fileCount} files, ${exportCount} exports, ${classCount} classes, ${methodCount} members, ${deps} deps`)
399 }
400
401 console.log()
402 const sharedCount = Object.keys(tree.system.sharedDeps || {}).length
403 console.log(`Shared dependencies: ${sharedCount}`)
404}
405
406async function cmdServe () {
407 // Defer to server module
408 const { startServer } = await import('./lib/server.js')
409 const tree = await scan(dir, opts)
410 const port = parseInt(args.find(a => /^\d{4,5}$/.test(a)) || '9078', 10)
411 const prefixIdx = args.indexOf('--prefix')
412 const prefix = prefixIdx >= 0 ? args[prefixIdx + 1] : ''
413 startServer(tree, { port, prefix, ignore: opts.ignore, graph: tree.__graph, watch: opts.watch })
414}
415
416function output (data) {
417 console.log(JSON.stringify(data, null, pretty ? 2 : undefined))
418}
419
420function printUsage () {
421 console.log(`codetree — structural code scanner
422
423Usage:
424 codetree scan [dir] Full scan, outputs JSON tree
425 codetree module <name> [dir] Show one module's structure
426 codetree file <path> [dir] Show one file's structure
427 codetree exports <module> [dir] List public API surface
428 codetree deps <module> [dir] Show dependency chain
429 codetree imports <module> [dir] Show internal import graph and sub-modules
430 codetree docs [dir] Documentation cruft report
431 codetree categories [dir] Show module categorization (SYSTEM.md + auto)
432 codetree summary [dir] Human-readable overview
433 codetree serve [dir] [port] Start HTTP visualization
434
435Options:
436 --pretty, -p Pretty-print JSON / human-readable output
437 --depth <n> Max directory depth for project discovery (default: 2)
438 --ignore <patterns> Extra ignore patterns, comma-separated, gitignore-style
439 --shallow Only parse each module's entry file (no cross-file analysis).
440 10-100x faster for multi-project/recursive scans.
441
442Ignore sources (merged, in this order):
443 built-in defaults (node_modules, .git, vendor, .pear-git, .claude, build, dist)
444 .codetreeignore file at scan root
445 any directory containing a .codetree-private marker
446 --ignore CLI flag (this takes effect last)
447
448Examples:
449 codetree scan . Scan current directory
450 codetree summary ../hyper-fleeky Summarize all modules
451 codetree exports hyper-orgs -p Show hyper-orgs public API
452 codetree imports pear-git -p Show pear-git internal architecture
453 codetree docs ../pear-git -p Find stale documentation
454 codetree serve . 9078 Serve visualization on port 9078`)
455}
456
457main().catch(err => {
458 console.error(err.message || err)
459 process.exit(1)
460})
lib/doc-cruft.js +313 -0
……@@ -0,0 +1,313 @@
1import { readFileSync, readdirSync, statSync, existsSync } from 'fs'
2import { join, relative, resolve, extname } from 'path'
3
4/**
5 * Detect documentation cruft by scanning all markdown files and
6 * cross-referencing their code references against the built tree.
7 *
8 * @param {string} rootDir - Project root directory
9 * @param {object} tree - Built code tree from buildTree()
10 * @param {Function} [ignore] - Ignore matcher from scanner.js
11 * @returns {object} Doc cruft report with per-doc details and summary
12 */
13export function detectDocCruft (rootDir, tree, ignore) {
14 const root = resolve(rootDir)
15 const ig = ignore || (() => false)
16 const mdFiles = findMarkdownFiles(root, ig)
17
18 // Build lookup indexes from the tree for fast cross-referencing
19 const index = buildCodeIndex(tree)
20
21 const docs = []
22 let totalMissing = 0
23 let totalValid = 0
24
25 for (const mdPath of mdFiles) {
26 const relPath = relative(root, mdPath)
27 let content
28 try { content = readFileSync(mdPath, 'utf-8') } catch { continue }
29
30 const lines = content.split('\n')
31 let mtime
32 try { mtime = statSync(mdPath).mtimeMs } catch { mtime = 0 }
33
34 // Extract code references
35 const refs = extractReferences(content, relPath)
36
37 // Cross-reference each against the code tree
38 const details = []
39 let valid = 0
40 let missing = 0
41
42 for (const ref of refs) {
43 const status = resolveReference(ref, index, root)
44 details.push({ ref: ref.value, type: ref.type, status, line: ref.line })
45 if (status === 'valid') valid++
46 else missing++
47 }
48
49 totalValid += valid
50 totalMissing += missing
51
52 // Staleness score: weighted combination of missing refs and age
53 const total = valid + missing
54 const missingRatio = total > 0 ? missing / total : 0
55 const ageDays = (Date.now() - mtime) / (1000 * 60 * 60 * 24)
56 const ageFactor = Math.min(ageDays / 90, 1) // caps at 90 days
57 const score = Math.round((missingRatio * 0.6 + ageFactor * 0.4) * 100) / 100
58
59 docs.push({
60 path: relPath,
61 lines: lines.length,
62 lastModified: new Date(mtime).toISOString().split('T')[0],
63 references: { total, valid, missing, details },
64 staleness: { score, missingRatio: Math.round(missingRatio * 100) / 100, ageDays: Math.round(ageDays) }
65 })
66 }
67
68 // Sort by staleness score descending (most stale first)
69 docs.sort((a, b) => b.staleness.score - a.staleness.score)
70
71 const staleDocs = docs.filter(d => d.staleness.score > 0.5).length
72 const freshDocs = docs.filter(d => d.staleness.score <= 0.3).length
73
74 return {
75 docs,
76 summary: {
77 totalDocs: docs.length,
78 totalLines: docs.reduce((sum, d) => sum + d.lines, 0),
79 freshDocs,
80 staleDocs,
81 validReferences: totalValid,
82 missingReferences: totalMissing
83 }
84 }
85}
86
87// --- Markdown file discovery ---
88
89function findMarkdownFiles (root, ignore) {
90 const files = []
91 walkForMd(root, files, 0, 6, ignore)
92 return files
93}
94
95function walkForMd (dir, files, depth, maxDepth, ignore) {
96 if (depth >= maxDepth) return
97
98 let entries
99 try { entries = readdirSync(dir) } catch { return }
100
101 for (const entry of entries) {
102 const full = join(dir, entry)
103 if (ignore(full)) continue
104
105 let stat
106 try { stat = statSync(full) } catch { continue }
107
108 if (stat.isDirectory()) {
109 walkForMd(full, files, depth + 1, maxDepth, ignore)
110 } else if (entry.endsWith('.md')) {
111 files.push(full)
112 }
113 }
114}
115
116// --- Code index construction ---
117
118function buildCodeIndex (tree) {
119 const filePaths = new Set()
120 const classNames = new Set()
121 const functionNames = new Set()
122 const exportNames = new Set()
123
124 for (const mod of Object.values(tree.modules)) {
125 for (const [filePath, file] of Object.entries(mod.files)) {
126 // Index file paths (both package-relative and with module prefix)
127 filePaths.add(filePath)
128 if (mod.path !== '.') filePaths.add(mod.path + '/' + filePath)
129
130 if (file.classes) {
131 for (const cls of file.classes) classNames.add(cls.name)
132 }
133 if (file.functions) {
134 for (const fn of file.functions) functionNames.add(fn.name)
135 }
136 if (file.exports) {
137 for (const exp of file.exports) {
138 if (exp.name && exp.name !== '*' && exp.name !== 'default') exportNames.add(exp.name)
139 if (exp.localName) exportNames.add(exp.localName)
140 }
141 }
142 }
143 }
144
145 return { filePaths, classNames, functionNames, exportNames }
146}
147
148// --- Reference extraction from markdown ---
149
150function extractReferences (content, docPath) {
151 const refs = []
152 const lines = content.split('\n')
153 const seen = new Set()
154
155 for (let i = 0; i < lines.length; i++) {
156 const line = lines[i]
157 const lineNum = i + 1
158
159 // Backtick identifiers: `SomeClass`, `lib/foo.js`, `someFunction()`
160 const backtickPattern = /`([^`\n]+)`/g
161 let m
162 while ((m = backtickPattern.exec(line)) !== null) {
163 const val = m[1].trim()
164 if (val.length < 2 || val.length > 120) continue
165 if (seen.has(val)) continue
166 seen.add(val)
167
168 const type = classifyReference(val)
169 if (type) refs.push({ value: val, type, line: lineNum })
170 }
171
172 // Markdown links to other files: [text](path.md) or [text](./path)
173 const linkPattern = /\[([^\]]*)\]\(([^)]+)\)/g
174 while ((m = linkPattern.exec(line)) !== null) {
175 const target = m[2].trim()
176 if (target.startsWith('http://') || target.startsWith('https://')) continue
177 if (target.startsWith('#')) continue // anchor links
178 if (seen.has('link:' + target)) continue
179 seen.add('link:' + target)
180 refs.push({ value: target, type: 'doc-link', line: lineNum })
181 }
182 }
183
184 // Code blocks: extract class names, imports, function names
185 // Recognize code blocks in any language we support. Leaving the language tag optional
186 // (and not restricting to js) lets us extract references from GDScript, C++, and GLSL
187 // snippets embedded in docs too.
188 const codeBlockPattern = /```(?:js|javascript|typescript|ts|gdscript|gd|cpp|c\+\+|c|glsl)?\n([\s\S]*?)```/g
189 let block
190 while ((block = codeBlockPattern.exec(content)) !== null) {
191 const code = block[1]
192 const blockStartLine = content.slice(0, block.index).split('\n').length
193
194 // import { X, Y } from 'module'
195 const importPattern = /import\s*\{([^}]+)\}\s*from\s*['"]([^'"]+)['"]/g
196 let imp
197 while ((imp = importPattern.exec(code)) !== null) {
198 const names = imp[1].split(',').map(n => n.trim()).filter(Boolean)
199 for (const name of names) {
200 if (seen.has(name)) continue
201 seen.add(name)
202 refs.push({ value: name, type: 'class-or-function', line: blockStartLine })
203 }
204 }
205
206 // new ClassName(
207 const ctorPattern = /new\s+([A-Z]\w+)\s*\(/g
208 let ctor
209 while ((ctor = ctorPattern.exec(code)) !== null) {
210 if (seen.has(ctor[1])) continue
211 seen.add(ctor[1])
212 refs.push({ value: ctor[1], type: 'class', line: blockStartLine })
213 }
214 }
215
216 return refs
217}
218
219const KNOWN_EXTENSIONS = new Set([
220 'js', 'mjs', 'cjs', 'json',
221 'gd', 'gdshader', 'tscn', 'tres',
222 'cpp', 'cc', 'cxx', 'c', 'h', 'hpp', 'hh', 'hxx',
223 'glsl', 'vert', 'frag', 'comp',
224 'md', 'txt', 'yaml', 'yml', 'toml'
225])
226
227function classifyReference (val) {
228 // File path: contains / or ends in a known source extension
229 const extMatch = val.match(/\.(\w{1,8})$/)
230 const hasKnownExt = extMatch && KNOWN_EXTENSIONS.has(extMatch[1].toLowerCase())
231 if (val.includes('/') || hasKnownExt) {
232 // Skip things that look like URLs, semver, or shell commands
233 if (val.includes('://') || /^\d+\.\d+/.test(val)) return null
234 if (val.startsWith('npm ') || val.startsWith('git ')) return null
235 return 'filepath'
236 }
237
238 // Class name: starts with uppercase letter
239 if (/^[A-Z][a-zA-Z0-9]+$/.test(val)) return 'class'
240
241 // Function/method call: ends with ()
242 if (val.endsWith('()') || val.endsWith('(...)')) {
243 return 'function'
244 }
245
246 // Property access: contains . like server.authManager
247 if (/^[a-z]\w+\.\w+/.test(val)) return 'property'
248
249 // Identifier: lowercase camelCase or snake_case, at least 4 chars to avoid noise
250 if (/^[a-z_]\w{3,}$/.test(val) && !isCommonWord(val)) return 'identifier'
251
252 return null
253}
254
255function isCommonWord (val) {
256 const common = new Set([
257 'true', 'false', 'null', 'undefined', 'async', 'await', 'const', 'function',
258 'return', 'export', 'import', 'class', 'this', 'super', 'default', 'string',
259 'number', 'boolean', 'object', 'array', 'error', 'open', 'closed', 'pending',
260 'active', 'admin', 'read', 'write', 'owner', 'mirror', 'user', 'name', 'value',
261 'type', 'status', 'title', 'body', 'path', 'data', 'test', 'node', 'bare',
262 'main', 'HEAD', 'master', 'refs'
263 ])
264 return common.has(val)
265}
266
267// --- Cross-referencing ---
268
269function resolveReference (ref, index, root) {
270 switch (ref.type) {
271 case 'filepath': {
272 // Clean up: remove trailing slashes, leading ./
273 let cleaned = ref.value.replace(/^\.\//, '').replace(/\/$/, '')
274 // Strip method call suffixes like lib/auth.js:authenticate()
275 cleaned = cleaned.replace(/:\w+\(.*\)$/, '')
276 // Check against indexed file paths
277 if (index.filePaths.has(cleaned)) return 'valid'
278 // Check if directory exists on disk
279 const absPath = resolve(root, cleaned)
280 if (existsSync(absPath)) return 'valid'
281 return 'missing'
282 }
283
284 case 'class':
285 return index.classNames.has(ref.value) || index.exportNames.has(ref.value) ? 'valid' : 'missing'
286
287 case 'function': {
288 const name = ref.value.replace(/\(.*\)$/, '')
289 return index.functionNames.has(name) || index.exportNames.has(name) ? 'valid' : 'missing'
290 }
291
292 case 'class-or-function':
293 return (index.classNames.has(ref.value) || index.functionNames.has(ref.value) || index.exportNames.has(ref.value))
294 ? 'valid' : 'missing'
295
296 case 'property':
297 case 'identifier':
298 // For identifiers, check if they appear as any known symbol
299 return (index.classNames.has(ref.value) || index.functionNames.has(ref.value) || index.exportNames.has(ref.value))
300 ? 'valid' : 'unknown'
301
302 case 'doc-link': {
303 // Check if linked document exists on disk (relative to the doc's directory or root)
304 const target = ref.value.replace(/^\.\//, '')
305 const absPath = resolve(root, target)
306 if (existsSync(absPath)) return 'valid'
307 return 'missing'
308 }
309
310 default:
311 return 'unknown'
312 }
313}
lib/doc-parser.js +281 -0
……@@ -0,0 +1,281 @@
1import { readFileSync, existsSync, readdirSync, statSync } from 'fs'
2import { resolve, join, basename, relative } from 'path'
3
4/**
5 * Parse spec files and SYSTEM.md to extract documented claims.
6 * Returns claims linked to module names that the validator can check
7 * against the code tree.
8 */
9
10export function parseSpecs (specDir) {
11 const result = {
12 system: null,
13 modules: {}
14 }
15
16 if (!existsSync(specDir)) return result
17
18 // Parse SYSTEM.md
19 const systemPath = join(specDir, 'SYSTEM.md')
20 if (existsSync(systemPath)) {
21 result.system = parseSystemSpec(readFileSync(systemPath, 'utf-8'))
22 }
23
24 // Parse module specs
25 const modulesDir = join(specDir, 'modules')
26 if (existsSync(modulesDir) && statSync(modulesDir).isDirectory()) {
27 for (const file of readdirSync(modulesDir)) {
28 if (!file.endsWith('.md')) continue
29 const content = readFileSync(join(modulesDir, file), 'utf-8')
30 const spec = parseModuleSpec(content, file)
31 if (spec.name) {
32 result.modules[spec.name] = spec
33 }
34 }
35 }
36
37 return result
38}
39
40// --- System spec parser ---
41
42function parseSystemSpec (content) {
43 const spec = {
44 lastVerified: null,
45 modules: [], // { name, location, purpose, category }
46 categories: {}, // category -> [module names]
47 builtItems: [],
48 missingItems: []
49 }
50
51 // Last verified date
52 const verifiedMatch = content.match(/\*\*Last verified:\*\*\s*(\d{4}-\d{2}-\d{2})/)
53 if (verifiedMatch) spec.lastVerified = verifiedMatch[1]
54
55 // Module inventory from markdown tables, grouped by category headers
56 // Categories are ### headings above the tables
57 const sections = content.split(/^### /m)
58 let currentCategory = 'Uncategorized'
59
60 for (const section of sections) {
61 const categoryMatch = section.match(/^([^\n]+)/)
62 if (categoryMatch && !section.startsWith('#')) {
63 currentCategory = categoryMatch[1].trim().replace(/\s*\(.*\)/, '')
64 }
65
66 const tablePattern = /\|\s*\*\*(\w[\w-]*)\*\*\s*\|\s*`([^`]*)`\s*\|\s*([^|]+)\|/g
67 let match
68 while ((match = tablePattern.exec(section)) !== null) {
69 const name = match[1]
70 spec.modules.push({
71 name,
72 location: match[2].trim(),
73 purpose: match[3].trim(),
74 category: currentCategory
75 })
76 if (!spec.categories[currentCategory]) spec.categories[currentCategory] = []
77 spec.categories[currentCategory].push(name)
78 }
79 }
80
81 // Built items (checkmarks)
82 const builtPattern = /- ✅\s*(.+)/g
83 let builtMatch
84 while ((builtMatch = builtPattern.exec(content)) !== null) {
85 spec.builtItems.push(builtMatch[1].trim())
86 }
87
88 // Missing items (x marks)
89 const missingPattern = /- ❌\s*(.+)/g
90 let missingMatch
91 while ((missingMatch = missingPattern.exec(content)) !== null) {
92 spec.missingItems.push(missingMatch[1].trim())
93 }
94
95 return spec
96}
97
98// --- Module spec parser ---
99
100function parseModuleSpec (content, filename) {
101 const spec = {
102 name: null,
103 filename,
104 location: null,
105 testCount: null,
106 sourceVerified: null,
107 fileLOC: {}, // filename -> claimed LOC
108 description: null,
109 notDescription: [],
110 dependencies: [],
111 dependents: [],
112 claimedMethods: [],
113 claimedGetters: [],
114 claimedExports: [],
115 claimedConstructorParams: [],
116 roleInSystem: null
117 }
118
119 // Module name from title: "# hyper-orgs -- Module Spec"
120 const titleMatch = content.match(/^#\s+(\S+)\s+--/m)
121 if (titleMatch) spec.name = titleMatch[1]
122
123 // Location
124 const locMatch = content.match(/\*\*Location:\*\*\s*`([^`]+)`/)
125 if (locMatch) spec.location = locMatch[1].replace(/\/$/, '')
126
127 // Test count
128 const testMatch = content.match(/\*\*Tests:\*\*\s*(\d+)\s*pass/)
129 if (testMatch) spec.testCount = parseInt(testMatch[1], 10)
130
131 // Source verified date + LOC claims
132 const verifiedMatch = content.match(/\*\*Source verified:\*\*\s*(\d{4}-\d{2}-\d{2})\s*\(([^)]+)\)/)
133 if (verifiedMatch) {
134 spec.sourceVerified = verifiedMatch[1]
135 // Parse "hyper-orgs.js 637 LOC, schema.js 515 LOC"
136 const locParts = verifiedMatch[2].split(',')
137 for (const part of locParts) {
138 const locPartMatch = part.trim().match(/(\S+)\s+(\d+)\s+LOC/)
139 if (locPartMatch) {
140 spec.fileLOC[locPartMatch[1]] = parseInt(locPartMatch[2], 10)
141 }
142 }
143 }
144
145 // Description (## What it is)
146 const whatMatch = content.match(/## What it is\n\n([\s\S]*?)(?=\n## |\n---|\n$)/)
147 if (whatMatch) spec.description = whatMatch[1].trim()
148
149 // Not description (## What it is NOT)
150 const notSection = content.match(/## What it is NOT\n\n([\s\S]*?)(?=\n## |\n---|\n$)/)
151 if (notSection) {
152 const lines = notSection[1].split('\n').filter(l => l.startsWith('- '))
153 spec.notDescription = lines.map(l => l.replace(/^- /, '').trim())
154 }
155
156 // Dependencies section
157 const depSection = content.match(/## Dependencies\n\n([\s\S]*?)(?=\n## |\n$)/)
158 if (depSection) {
159 const lines = depSection[1].split('\n').filter(l => l.startsWith('- '))
160 for (const line of lines) {
161 const depMatch = line.match(/`([^`]+)`/)
162 if (depMatch) spec.dependencies.push(depMatch[1])
163 }
164 }
165
166 // Dependents section
167 const deptsSection = content.match(/## What depends on this\n\n([\s\S]*?)(?=\n## |\n$)/)
168 if (deptsSection) {
169 const lines = deptsSection[1].split('\n').filter(l => l.startsWith('- '))
170 for (const line of lines) {
171 const deptMatch = line.match(/\*\*([^*]+)\*\*/)
172 if (deptMatch) spec.dependents.push(deptMatch[1])
173 }
174 }
175
176 // Role in pear-git
177 const roleSection = content.match(/## Role in pear-git\n\n([\s\S]*?)(?=\n## |\n$)/)
178 if (roleSection) spec.roleInSystem = roleSection[1].trim()
179
180 // Extract method names from API code block
181 const apiBlock = content.match(/## API[^\n]*\n\n```js\n([\s\S]*?)```/)
182 if (apiBlock) {
183 const code = apiBlock[1]
184
185 // Method calls: await orgs.methodName( or orgs.methodName(
186 const methodPattern = /(?:await\s+)?\w+\.(\w+)\s*\(/g
187 let m
188 while ((m = methodPattern.exec(code)) !== null) {
189 const name = m[1]
190 if (!spec.claimedMethods.includes(name) && name !== 'ready' && name !== 'close') {
191 spec.claimedMethods.push(name)
192 }
193 }
194
195 // Properties: orgs.key / keyHex / ...
196 const propPattern = /\w+\.(\w+)\s*[/\n]/g
197 while ((m = propPattern.exec(code)) !== null) {
198 if (!spec.claimedGetters.includes(m[1])) {
199 spec.claimedGetters.push(m[1])
200 }
201 }
202
203 // Constructor: new ClassName(param1, { ... })
204 const ctorMatch = code.match(/new\s+(\w+)\s*\(([^)]*)\)/)
205 if (ctorMatch) {
206 spec.claimedExports.push(ctorMatch[1])
207 // Extract param names
208 const params = ctorMatch[2].split(',').map(p => p.trim().replace(/[{}\s].*/g, '')).filter(Boolean)
209 spec.claimedConstructorParams = params
210 }
211
212 // Import: import { X } from 'module'
213 const importMatch = code.match(/import\s*\{([^}]+)\}\s*from/)
214 if (importMatch) {
215 const names = importMatch[1].split(',').map(n => n.trim())
216 for (const n of names) {
217 if (!spec.claimedExports.includes(n)) spec.claimedExports.push(n)
218 }
219 }
220 }
221
222 return spec
223}
224
225/**
226 * Scan a directory for all doc sources — specs, READMEs, JSDoc.
227 * Returns a unified doc inventory.
228 */
229export function findAllDocs (rootDir) {
230 const docs = {
231 specs: [], // spec/modules/*.md
232 system: null, // spec/SYSTEM.md
233 readmes: [], // */README.md
234 specDir: null
235 }
236
237 // Look for spec directory in common locations
238 const specLocations = [
239 join(rootDir, 'spec'),
240 join(rootDir, 'docs', 'spec')
241 ]
242
243 // Also check each module for its own spec dir
244 try {
245 for (const entry of readdirSync(rootDir)) {
246 const specPath = join(rootDir, entry, 'spec')
247 if (existsSync(specPath) && statSync(specPath).isDirectory()) {
248 specLocations.push(specPath)
249 }
250 }
251 } catch {}
252
253 for (const specDir of specLocations) {
254 if (!existsSync(specDir)) continue
255 docs.specDir = specDir
256
257 const systemPath = join(specDir, 'SYSTEM.md')
258 if (existsSync(systemPath)) docs.system = systemPath
259
260 const modulesDir = join(specDir, 'modules')
261 if (existsSync(modulesDir)) {
262 try {
263 for (const f of readdirSync(modulesDir)) {
264 if (f.endsWith('.md')) docs.specs.push(join(modulesDir, f))
265 }
266 } catch {}
267 }
268 }
269
270 // Find READMEs
271 try {
272 for (const entry of readdirSync(rootDir)) {
273 const readmePath = join(rootDir, entry, 'README.md')
274 if (existsSync(readmePath)) {
275 docs.readmes.push({ module: entry, path: readmePath })
276 }
277 }
278 } catch {}
279
280 return docs
281}
lib/fs-watcher.js +79 -0
……@@ -0,0 +1,79 @@
1import { watch, statSync } from 'fs'
2import { EventEmitter } from 'events'
3import { resolve, relative, join } from 'path'
4
5/**
6 * Wraps fs.watch for a project root and emits normalized `change` events.
7 *
8 * Honors the ignore matcher — hidden files don't produce events.
9 *
10 * const w = new FsWatcher(rootDir, ignore)
11 * w.on('change', path => ...)
12 * w.on('remove', path => ...)
13 * w.close()
14 *
15 * There are no timers here. bare-fs.watch is inotify-backed on Linux; every
16 * event is a real filesystem push from the kernel.
17 */
18export class FsWatcher extends EventEmitter {
19 constructor (rootDir, ignore, opts = {}) {
20 super()
21 this.rootDir = resolve(rootDir)
22 this.ignore = ignore || (() => false)
23 this._debounce = new Map() // path -> timer? No — we batch via a set.
24 this._pending = new Set() // coalesce rapid-fire events
25 this._flushScheduled = false
26 this._closed = false
27
28 try {
29 this._handle = watch(this.rootDir, { recursive: true }, (eventType, filename) => {
30 if (this._closed || !filename) return
31 // fs.watch gives a path relative to the watched root. Normalize to absolute.
32 const abs = join(this.rootDir, filename)
33 if (this.ignore(abs)) return
34 this._enqueue(abs)
35 })
36 // Errors from the underlying watcher (ENOSPC mid-stream, EBADF, etc.)
37 // must be caught — without a listener Node crashes the process.
38 this._handle.on('error', err => {
39 // Mark closed so we stop trying to enqueue events
40 this._closed = true
41 queueMicrotask(() => this.emit('error', err))
42 })
43 } catch (err) {
44 // Watching failed at construction (platform limit, permission, etc.). Emit error
45 // instead of crashing — server can still serve the initial tree.
46 queueMicrotask(() => this.emit('error', err))
47 }
48 }
49
50 // Coalesce bursts of events on the same path into a single `change` emission.
51 // Many editors rewrite files via temp + rename, which fires 2-3 events in
52 // the same tick. Batching with queueMicrotask merges them without a timer.
53 _enqueue (abs) {
54 this._pending.add(abs)
55 if (this._flushScheduled) return
56 this._flushScheduled = true
57 queueMicrotask(() => this._flush())
58 }
59
60 _flush () {
61 this._flushScheduled = false
62 for (const abs of this._pending) {
63 let exists = true
64 try { statSync(abs) } catch { exists = false }
65 const relPath = relative(this.rootDir, abs)
66 if (exists) this.emit('change', { absPath: abs, relPath })
67 else this.emit('remove', { absPath: abs, relPath })
68 }
69 this._pending.clear()
70 }
71
72 close () {
73 this._closed = true
74 if (this._handle) {
75 try { this._handle.close() } catch {}
76 this._handle = null
77 }
78 }
79}
lib/ignore.js +192 -0
……@@ -0,0 +1,192 @@
1import { readFileSync, existsSync, readdirSync, statSync, lstatSync } from 'fs'
2import { join, relative, resolve, basename } from 'path'
3
4/**
5 * Directory ignore system.
6 *
7 * Consolidates the previously-scattered skip logic in traverse/lang/doc-cruft/server
8 * into one matcher that all scan sites share.
9 *
10 * Pattern sources (in precedence order):
11 * 1. Built-in defaults (node_modules, .git, etc.)
12 * 2. .codetreeignore at rootDir (gitignore subset)
13 * 3. Nested .codetree-private markers (any dir containing this file is fully hidden)
14 * 4. extraPatterns (from --ignore CLI flag)
15 *
16 * Usage:
17 * const ignore = buildIgnoreMatcher(rootDir, ['*.secrets'])
18 * if (ignore(absolutePath)) continue // skip
19 */
20
21const BUILTIN_PATTERNS = [
22 'node_modules',
23 '.git',
24 '.pear-git',
25 '.claude',
26 'vendor', // codetree's own vendor dir + pear-git's
27 'thirdparty', // C++ convention
28 'third_party', // alternate spelling (Google / Chromium / etc.)
29 'deps', // common dep bundle name
30 'build',
31 'dist',
32 '.DS_Store'
33]
34
35const PRIVATE_MARKER = '.codetree-private'
36const IGNORE_FILE = '.codetreeignore'
37const PRIVATE_SCAN_MAX_DEPTH = 8
38
39export function buildIgnoreMatcher (rootDir, extraPatterns = []) {
40 const root = resolve(rootDir)
41
42 // Collect patterns from all sources
43 const patterns = [...BUILTIN_PATTERNS]
44
45 const ignoreFile = join(root, IGNORE_FILE)
46 if (existsSync(ignoreFile)) {
47 try {
48 const content = readFileSync(ignoreFile, 'utf-8')
49 for (const line of content.split('\n')) {
50 const trimmed = line.trim()
51 if (!trimmed || trimmed.startsWith('#')) continue
52 patterns.push(trimmed)
53 }
54 } catch {}
55 }
56
57 for (const p of extraPatterns) {
58 if (p && !p.startsWith('#')) patterns.push(p.trim())
59 }
60
61 const compiled = patterns.map(p => compilePattern(p, root)).filter(Boolean)
62
63 // Pre-scan for .codetree-private markers — any dir containing this file becomes a
64 // full-subtree exclusion prefix.
65 const privatePrefixes = findPrivateMarkers(root)
66
67 return function ignore (absPath) {
68 // Exclude anything under a privately-marked directory
69 for (const prefix of privatePrefixes) {
70 if (absPath === prefix || absPath.startsWith(prefix + '/')) return true
71 }
72
73 // Check each compiled pattern
74 const rel = relative(root, absPath)
75 if (rel === '' || rel.startsWith('..')) return false // outside the scan root
76 const name = basename(absPath)
77
78 for (const c of compiled) {
79 if (c.test(rel, name)) return true
80 }
81
82 return false
83 }
84}
85
86// --- Pattern compilation ---
87//
88// Supports a practical subset of gitignore:
89// name → matches a dir/file named "name" at ANY depth
90// name/ → matches a DIR named "name" at any depth
91// /name → matches a dir/file named "name" only at rootDir
92// path/to/name → matches at that exact relative path (anchored to rootDir)
93// name*.ext → simple glob: * in name segment matches anything except /
94// # comment → skipped by caller
95// (negation !foo → not yet supported in v1)
96
97function compilePattern (rawPattern, root) {
98 let pattern = rawPattern.trim()
99 if (!pattern) return null
100 if (pattern.startsWith('!')) return null // v1: no negation
101 if (pattern.startsWith('#')) return null
102
103 const dirOnly = pattern.endsWith('/')
104 if (dirOnly) pattern = pattern.slice(0, -1)
105
106 const anchored = pattern.startsWith('/')
107 if (anchored) pattern = pattern.slice(1)
108
109 // No slash (and not anchored) → name-only pattern, matches at any depth
110 const nameOnly = !anchored && !pattern.includes('/')
111
112 const regex = globToRegex(pattern)
113
114 return {
115 raw: rawPattern,
116 dirOnly,
117 test (relPath, name) {
118 // For a dirOnly pattern we can't reliably tell from the relPath whether the
119 // target is a directory; callers that know should pass the dirOnly check.
120 // In practice dirOnly is mostly a documentation hint here; real behavior is
121 // that dir exclusion propagates via prefix matching below.
122
123 if (nameOnly) {
124 // Match if ANY segment of relPath equals the pattern
125 const segments = relPath.split('/')
126 for (const seg of segments) {
127 if (regex.test(seg)) return true
128 }
129 return false
130 }
131
132 if (anchored) {
133 // Exact match against relPath, or prefix match if target is under this path
134 if (regex.test(relPath)) return true
135 if (relPath.startsWith(pattern + '/')) return true
136 return false
137 }
138
139 // Path with slash but not anchored → match against any suffix of relPath
140 if (regex.test(relPath)) return true
141 const segs = relPath.split('/')
142 for (let i = 1; i < segs.length; i++) {
143 const suffix = segs.slice(i).join('/')
144 if (regex.test(suffix)) return true
145 }
146 return false
147 }
148 }
149}
150
151function globToRegex (pattern) {
152 // Escape regex specials, then re-enable * as wildcard (not crossing /)
153 let re = ''
154 for (const ch of pattern) {
155 if (ch === '*') re += '[^/]*'
156 else if (ch === '?') re += '[^/]'
157 else if ('.+^$(){}|\\[]'.includes(ch)) re += '\\' + ch
158 else re += ch
159 }
160 return new RegExp('^' + re + '$')
161}
162
163// --- .codetree-private discovery ---
164
165function findPrivateMarkers (root) {
166 const prefixes = []
167 scan(root, 0)
168 return prefixes
169
170 function scan (dir, depth) {
171 if (depth > PRIVATE_SCAN_MAX_DEPTH) return
172 let entries
173 try { entries = readdirSync(dir) } catch { return }
174
175 // Check this dir first
176 if (entries.includes(PRIVATE_MARKER)) {
177 prefixes.push(dir)
178 return // don't recurse into a private dir — the whole subtree is excluded
179 }
180
181 // Quick built-in prune before recursing (avoids descending into node_modules etc.)
182 for (const entry of entries) {
183 if (BUILTIN_PATTERNS.includes(entry)) continue
184 if (entry.startsWith('.')) continue
185 const full = join(dir, entry)
186 let stat
187 try { stat = lstatSync(full) } catch { continue }
188 if (!stat.isDirectory() || stat.isSymbolicLink()) continue
189 scan(full, depth + 1)
190 }
191 }
192}
lib/lang.js +591 -0
……@@ -0,0 +1,591 @@
1import { existsSync, readdirSync, statSync, readFileSync } from 'fs'
2import { join, dirname, resolve, extname, relative } from 'path'
3
4import { parseFile as parseJS } from './parsers/js.js'
5import { parseFile as parseGDScript } from './parsers/gdscript.js'
6import { parseFile as parseCpp } from './parsers/cpp.js'
7import { parseFile as parseGLSL } from './parsers/glsl.js'
8
9/**
10 * Language registry.
11 *
12 * The single source of truth for all language-specific behavior.
13 * Replaces hardcoded assumptions that were previously scattered across
14 * traverse.js and tree.js.
15 *
16 * Adding a new language = add one descriptor to LANGUAGES below.
17 */
18
19// --- JS language descriptor ---
20
21const JS = {
22 id: 'js',
23 extensions: ['.js', '.mjs', '.cjs'],
24 projectMarkers: ['package.json'],
25 submoduleMarkers: ['package.json'],
26 defaultEntries: ['index.js', 'index.mjs'],
27
28 parse: parseJS,
29
30 extractImports (source) {
31 const specs = []
32
33 // ESM: import ... from 'specifier'
34 const esmPattern = /(?:import|export)\s+.*?\s+from\s+['"]([^'"]+)['"]/g
35 let match
36 while ((match = esmPattern.exec(source)) !== null) specs.push(match[1])
37
38 // ESM: import 'specifier' (side-effect)
39 const sideEffect = /import\s+['"]([^'"]+)['"]/g
40 while ((match = sideEffect.exec(source)) !== null) {
41 if (!specs.includes(match[1])) specs.push(match[1])
42 }
43
44 // CJS: require('specifier')
45 const cjsPattern = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g
46 while ((match = cjsPattern.exec(source)) !== null) {
47 if (!specs.includes(match[1])) specs.push(match[1])
48 }
49
50 return specs
51 },
52
53 // Resolve a relative import to an absolute file path (or null).
54 // For JS, only relative imports participate in the local graph.
55 resolveImport (fromFile, specifier /* ctx unused for JS */) {
56 if (!specifier.startsWith('.')) return null
57
58 const dir = dirname(fromFile)
59 const target = resolve(dir, specifier)
60
61 // Exact file
62 if (existsSync(target) && statSync(target).isFile()) return target
63
64 // Try extensions
65 for (const ext of ['.js', '.mjs', '.cjs', '.json']) {
66 const withExt = target + ext
67 if (existsSync(withExt) && statSync(withExt).isFile()) return withExt
68 }
69
70 // Try index.js in directory
71 if (existsSync(target) && statSync(target).isDirectory()) {
72 const idx = join(target, 'index.js')
73 if (existsSync(idx)) return idx
74 }
75
76 return null
77 }
78}
79
80// --- GDScript language descriptor ---
81
82const GDScript = {
83 id: 'gdscript',
84 extensions: ['.gd'],
85 projectMarkers: ['project.godot'],
86 submoduleMarkers: ['plugin.cfg', 'project.godot'],
87 defaultEntries: [], // Godot projects have no single entry point
88
89 parse: parseGDScript,
90
91 extractImports (source) {
92 // preload("res://path") or preload('res://path')
93 const specs = []
94 const preloadPattern = /preload\s*\(\s*['"]([^'"]+)['"]\s*\)/g
95 let match
96 while ((match = preloadPattern.exec(source)) !== null) {
97 specs.push(match[1])
98 }
99 // load("res://path") — runtime load, still a real dependency
100 const loadPattern = /\bload\s*\(\s*['"]([^'"]+)['"]\s*\)/g
101 while ((match = loadPattern.exec(source)) !== null) {
102 if (!specs.includes(match[1])) specs.push(match[1])
103 }
104 return specs
105 },
106
107 // Resolve a GDScript import.
108 // - class_name: specifiers map through the registry to an absolute path
109 // - res:// paths resolve to projectRoot + path
110 // - relative paths resolve from the including file's directory
111 resolveImport (fromFile, specifier, ctx) {
112 // Implicit class_name references — look up in the registry
113 if (specifier.startsWith('class_name:')) {
114 const className = specifier.slice('class_name:'.length)
115 const regPath = ctx && ctx.classNameRegistry && ctx.classNameRegistry[className]
116 if (regPath) {
117 const full = resolve(ctx.rootDir, regPath)
118 if (existsSync(full) && statSync(full).isFile()) return full
119 }
120 return null
121 }
122
123 if (specifier.startsWith('res://')) {
124 const rest = specifier.slice('res://'.length)
125 const root = (ctx && ctx.rootDir) || dirname(fromFile)
126 const full = resolve(root, rest)
127 if (existsSync(full) && statSync(full).isFile()) return full
128 return null
129 }
130
131 if (specifier.startsWith('.') || !specifier.includes('://')) {
132 const dir = dirname(fromFile)
133 const target = resolve(dir, specifier)
134 if (existsSync(target) && statSync(target).isFile()) return target
135 }
136
137 return null
138 },
139
140 // GDScript-specific: find implicit class_name references in the source.
141 // Returns an array of synthetic `class_name:X` specifiers for class names
142 // that exist in the project's registry. Called after extractImports().
143 extractImplicitImports (source, ctx) {
144 if (!ctx || !ctx.classNameRegistry) return []
145 const registry = ctx.classNameRegistry
146 const found = new Set()
147
148 // Patterns that reveal a type reference to a global class_name:
149 // extends ClassName
150 // var x: ClassName / const x: ClassName
151 // : ClassName = / -> ClassName : (function return type)
152 // ClassName.new()
153 // ClassName.STATIC_MEMBER
154 // func f(arg: ClassName, ...)
155 //
156 // Capture any identifier that starts with a capital letter after the relevant
157 // keyword or punctuation, then filter by the registry.
158 const patterns = [
159 /\bextends\s+([A-Z][\w]*)\b/g,
160 /:\s*([A-Z][\w]*)(?:\s*[=,)\]}\n])/g,
161 /->\s*([A-Z][\w]*)\s*:/g,
162 /\b([A-Z][\w]*)\s*\.\s*new\s*\(/g
163 ]
164
165 for (const p of patterns) {
166 let m
167 while ((m = p.exec(source)) !== null) {
168 const name = m[1]
169 if (registry[name]) found.add(name)
170 }
171 }
172
173 return [...found].map(name => 'class_name:' + name)
174 }
175}
176
177// --- C++ language descriptor ---
178
179const Cpp = {
180 id: 'cpp',
181 extensions: ['.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.hh', '.hxx'],
182 projectMarkers: ['SConstruct', 'CMakeLists.txt'],
183 submoduleMarkers: ['SConstruct', 'CMakeLists.txt'],
184 defaultEntries: [],
185
186 parse: parseCpp,
187
188 extractImports (source) {
189 // #include "local.h" — quoted only. System <...> includes are skipped.
190 const specs = []
191 const pattern = /^\s*#\s*include\s+"([^"]+)"/gm
192 let match
193 while ((match = pattern.exec(source)) !== null) {
194 specs.push(match[1])
195 }
196 return specs
197 },
198
199 resolveImport (fromFile, specifier, ctx) {
200 // Try relative to the including file's directory first
201 const fromDir = dirname(fromFile)
202 const relTarget = resolve(fromDir, specifier)
203 if (existsSync(relTarget) && statSync(relTarget).isFile()) return relTarget
204
205 // Then try the pre-built header map (convention-based include paths)
206 if (ctx && ctx.headerMap) {
207 if (specifier.includes('/')) {
208 // path-qualified specifier: try each include root + specifier
209 for (const root of ctx.includeRoots || []) {
210 const full = resolve(root, specifier)
211 if (existsSync(full) && statSync(full).isFile()) return full
212 }
213 } else {
214 // bare filename: direct lookup in header map
215 const abs = ctx.headerMap[specifier]
216 if (abs && existsSync(abs) && statSync(abs).isFile()) return abs
217 }
218 }
219
220 return null
221 }
222}
223
224// --- GLSL language descriptor ---
225// GLSL shaders have no project structure of their own — they piggyback on whatever
226// project contains them (Godot .gdshader or C++ GDExtension .glsl). No projectMarkers.
227
228const GLSL = {
229 id: 'glsl',
230 extensions: ['.glsl', '.gdshader', '.vert', '.frag', '.comp'],
231 projectMarkers: [], // shaders never define a project alone
232 submoduleMarkers: [],
233 defaultEntries: [],
234
235 parse: parseGLSL,
236
237 extractImports (source) {
238 // #include is uncommon but possible (Godot gdshader, some glsl preprocessors)
239 const specs = []
240 const pattern = /^\s*#\s*include\s+["<]([^">]+)[">]/gm
241 let match
242 while ((match = pattern.exec(source)) !== null) {
243 specs.push(match[1])
244 }
245 return specs
246 },
247
248 resolveImport (fromFile, specifier) {
249 if (specifier.startsWith('.') || !specifier.includes('://')) {
250 const target = resolve(dirname(fromFile), specifier)
251 if (existsSync(target) && statSync(target).isFile()) return target
252 }
253 return null
254 }
255}
256
257// --- Language registry ---
258// Order matters for detectProject(): most-specific markers first.
259// project.godot, SConstruct and CMakeLists.txt are more distinctive than package.json —
260// a Godot or GDExtension project may also have package.json (for dev tools) and we want
261// to classify it by its primary nature.
262
263const LANGUAGES = [GDScript, Cpp, JS, GLSL]
264
265const EXT_TO_LANG = (() => {
266 const map = new Map()
267 for (const lang of LANGUAGES) {
268 for (const ext of lang.extensions) map.set(ext, lang)
269 }
270 return map
271})()
272
273// --- Public API ---
274
275/**
276 * Map a file path to its language descriptor, or null if no registered language claims it.
277 */
278export function getLang (filePath) {
279 const ext = extname(filePath)
280 return EXT_TO_LANG.get(ext) || null
281}
282
283/**
284 * True if any registered language claims this file's extension.
285 * Replaces hardcoded .js/.mjs/.cjs checks.
286 */
287export function isSourceFile (filePath) {
288 return EXT_TO_LANG.has(extname(filePath))
289}
290
291/**
292 * Detect what type of project lives at rootDir by scanning for marker files.
293 * Returns { type, languages: [langId,...] } — the primary project type plus
294 * any other languages whose files are present.
295 */
296export function detectProject (rootDir) {
297 const markers = []
298
299 for (const lang of LANGUAGES) {
300 for (const marker of lang.projectMarkers || []) {
301 if (existsSync(join(rootDir, marker))) {
302 markers.push({ type: lang.id, marker })
303 }
304 }
305 }
306
307 // Primary type: first marker found.
308 const primary = markers[0] || { type: 'unknown', marker: null }
309
310 return {
311 type: primary.type,
312 marker: primary.marker,
313 languages: [...new Set(markers.map(m => m.type))]
314 }
315}
316
317/**
318 * Find module boundaries within a project.
319 *
320 * For JS projects this means: directories containing package.json.
321 * Other languages will plug in their own boundary detection.
322 *
323 * Returns: array of directory paths (absolute) representing module roots.
324 */
325export function findModuleBoundaries (rootDir, projectType, opts = {}) {
326 const maxDepth = opts.maxDepth || 2
327 const ignore = opts.ignore || (() => false)
328 const roots = []
329
330 let markers
331 const lang = LANGUAGES.find(l => l.id === projectType)
332 if (lang) {
333 markers = lang.submoduleMarkers || lang.projectMarkers || []
334 } else {
335 // Unknown root (e.g. a parent directory of several projects). Scan for
336 // any registered project marker — this makes codetree useful for monorepos
337 // that aren't themselves a single project.
338 markers = []
339 for (const l of LANGUAGES) {
340 for (const m of l.projectMarkers || []) markers.push(m)
341 }
342 }
343
344 if (markers.length === 0) return [rootDir]
345
346 // Root is always a module if it has any marker
347 if (markers.some(m => existsSync(join(rootDir, m)))) {
348 roots.push(rootDir)
349 }
350
351 scanForModuleMarkers(rootDir, markers, roots, 0, maxDepth, ignore)
352 return roots
353}
354
355function scanForModuleMarkers (dir, markers, roots, depth, maxDepth, ignore) {
356 if (depth >= maxDepth) return
357
358 let entries
359 try { entries = readdirSync(dir) } catch { return }
360
361 for (const entry of entries) {
362 // test/ directories aren't module roots — they're tests inside a module.
363 // Other skips come from the ignore matcher.
364 if (entry === 'test') continue
365 const full = join(dir, entry)
366 if (ignore(full)) continue
367
368 let stat
369 try { stat = statSync(full) } catch { continue }
370 if (!stat.isDirectory()) continue
371
372 if (markers.some(m => existsSync(join(full, m)))) {
373 roots.push(full)
374 }
375
376 scanForModuleMarkers(full, markers, roots, depth + 1, maxDepth, ignore)
377 }
378}
379
380/**
381 * Build a resolution context for a project.
382 *
383 * This is a language-specific data structure needed for import resolution.
384 * For JS: import maps (from package.json) — currently not populated here because
385 * JS resolution uses only relative paths.
386 * For GDScript (future): class_name registry.
387 * For C++ (future): header name → absolute path map.
388 */
389export function buildResolutionContext (rootDir, projectType, ignore, opts = {}) {
390 const ig = ignore || (() => false)
391 const ctx = { projectType, rootDir, ignore: ig, shallow: !!opts.shallow }
392
393 // Shallow scans don't resolve internal imports — skip the expensive project-wide
394 // pre-scans (class_name registry, C++ header map). These are the single biggest
395 // cost in buildResolutionContext for large projects.
396 if (opts.shallow) return ctx
397
398 if (projectType === 'gdscript') {
399 // Scan every .gd file in the project for `class_name X` declarations.
400 // This builds the global class registry that GDScript uses for implicit imports
401 // (type references like `extends Foo` or `var x: Foo` don't need an explicit preload
402 // when Foo is a class_name somewhere else in the project).
403 ctx.classNameRegistry = buildGDScriptClassNameRegistry(rootDir, ig)
404 }
405
406 if (projectType === 'cpp') {
407 // Build header-name → absolute-path map by scanning conventional include roots.
408 // This is a convention-based alternative to parsing SConstruct/CMakeLists.txt for CPPPATH.
409 const { headerMap, includeRoots } = buildCppHeaderMap(rootDir, ig)
410 ctx.headerMap = headerMap
411 ctx.includeRoots = includeRoots
412 }
413
414 return ctx
415}
416
417// --- C++ header map ---
418
419function buildCppHeaderMap (rootDir, ignore) {
420 const headerMap = {}
421 const includeRoots = []
422
423 // Always consider the root itself
424 includeRoots.push(rootDir)
425
426 // Find conventional include roots
427 scanForIncludeRoots(rootDir, rootDir, includeRoots, 0, 3, ignore)
428
429 // Walk each include root and build the header map
430 for (const root of includeRoots) {
431 scanForHeaders(root, root, headerMap, 0, 6, ignore)
432 }
433
434 return { headerMap, includeRoots }
435}
436
437function scanForIncludeRoots (dir, rootDir, roots, depth, maxDepth, ignore) {
438 if (depth >= maxDepth) return
439
440 let entries
441 try { entries = readdirSync(dir) } catch { return }
442
443 for (const entry of entries) {
444 if (entry.startsWith('.')) continue
445 const full = join(dir, entry)
446 if (ignore(full)) continue
447
448 let stat
449 try { stat = statSync(full) } catch { continue }
450 if (!stat.isDirectory()) continue
451
452 // Standard C++ include conventions
453 if (entry === 'include' || entry === 'src' || entry === 'thirdparty') {
454 roots.push(full)
455 // Also look for <lib>/include patterns inside these
456 const subInclude = join(full, 'include')
457 try {
458 if (existsSync(subInclude) && statSync(subInclude).isDirectory()) {
459 roots.push(subInclude)
460 }
461 } catch {}
462 }
463
464 // Recurse into thirdparty/{lib}/include patterns
465 if (depth < maxDepth - 1) {
466 scanForIncludeRoots(full, rootDir, roots, depth + 1, maxDepth, ignore)
467 }
468 }
469}
470
471const HEADER_EXTS = new Set(['.h', '.hpp', '.hh', '.hxx'])
472
473function scanForHeaders (dir, root, headerMap, depth, maxDepth, ignore) {
474 if (depth >= maxDepth) return
475
476 let entries
477 try { entries = readdirSync(dir) } catch { return }
478
479 for (const entry of entries) {
480 if (entry.startsWith('.')) continue
481 const full = join(dir, entry)
482 if (ignore(full)) continue
483
484 let stat
485 try { stat = statSync(full) } catch { continue }
486
487 if (stat.isDirectory()) {
488 scanForHeaders(full, root, headerMap, depth + 1, maxDepth, ignore)
489 } else {
490 const ext = extname(entry)
491 if (HEADER_EXTS.has(ext)) {
492 // Bare filename is the key; if collision, prefer first found (innermost include root wins)
493 if (!headerMap[entry]) headerMap[entry] = full
494 }
495 }
496 }
497}
498
499function buildGDScriptClassNameRegistry (rootDir, ignore) {
500 const registry = {}
501 scanForGDClassNames(rootDir, rootDir, registry, 0, 10, ignore)
502 return registry
503}
504
505function scanForGDClassNames (dir, rootDir, registry, depth, maxDepth, ignore) {
506 if (depth >= maxDepth) return
507
508 let entries
509 try { entries = readdirSync(dir) } catch { return }
510
511 for (const entry of entries) {
512 if (entry.startsWith('.')) continue
513 const full = join(dir, entry)
514 if (ignore(full)) continue
515
516 let stat
517 try { stat = statSync(full) } catch { continue }
518
519 if (stat.isDirectory()) {
520 scanForGDClassNames(full, rootDir, registry, depth + 1, maxDepth, ignore)
521 } else if (entry.endsWith('.gd')) {
522 // Only read the first ~500 bytes — class_name must be at the top per GDScript convention
523 try {
524 const fd = readFileSync(full, 'utf-8')
525 const head = fd.slice(0, 500)
526 const match = head.match(/^\s*class_name\s+([A-Za-z_][\w]*)/m)
527 if (match) {
528 registry[match[1]] = relative(rootDir, full)
529 }
530 } catch {}
531 }
532 }
533}
534
535/**
536 * Read a project's metadata file (language-appropriate).
537 * For JS: package.json. For Godot: project.godot. For C++: SConstruct (skipped).
538 */
539export function readProjectMeta (dir, projectType) {
540 if (projectType === 'js') {
541 const pkgPath = join(dir, 'package.json')
542 try { return JSON.parse(readFileSync(pkgPath, 'utf-8')) }
543 catch { return null }
544 }
545 return null
546}
547
548/**
549 * Resolve a project's entry point (language-appropriate).
550 */
551export function resolveEntry (pkgDir, meta, projectType) {
552 const lang = LANGUAGES.find(l => l.id === projectType)
553 if (!lang) return null
554
555 if (projectType === 'js' && meta) {
556 // exports field first
557 if (meta.exports) {
558 const entry = resolveJSExportsEntry(meta.exports)
559 if (entry) {
560 const full = resolve(pkgDir, entry)
561 if (existsSync(full)) return full
562 }
563 }
564 // main field
565 if (meta.main) {
566 const full = resolve(pkgDir, meta.main)
567 if (existsSync(full)) return full
568 }
569 }
570
571 // Fall back to language default entry names
572 for (const name of lang.defaultEntries || []) {
573 const full = resolve(pkgDir, name)
574 if (existsSync(full)) return full
575 }
576
577 return null
578}
579
580function resolveJSExportsEntry (exports) {
581 if (typeof exports === 'string') return exports
582 if (typeof exports === 'object' && exports !== null) {
583 const dot = exports['.']
584 if (!dot) return null
585 if (typeof dot === 'string') return dot
586 if (typeof dot === 'object') {
587 return dot.bare || dot.import || dot.require || dot.default || null
588 }
589 }
590 return null
591}
lib/live-store.js +220 -0
……@@ -0,0 +1,220 @@
1import { EventEmitter } from 'events'
2import { readFileSync } from 'fs'
3import { relative } from 'path'
4import { FsWatcher } from './fs-watcher.js'
5import { getLang, isSourceFile } from './lang.js'
6
7/**
8 * LiveStore — holds the current tree + broadcasts deltas.
9 *
10 * Built on the push model: file changes come in as fs.watch events, get
11 * re-parsed, and emit new file-parsed events into a live event stream. All
12 * connected clients (SSE consumers) receive the delta.
13 *
14 * Initial state replay: a newly-connected client receives the events that
15 * would rebuild the current tree — no full JSON dump needed.
16 *
17 * The store does NOT own the tree directly. It holds the graph produced by
18 * the initial scan and replays events to new subscribers. Incremental updates
19 * from the watcher amend the graph in place and emit the corresponding events.
20 */
21export class LiveStore extends EventEmitter {
22 constructor (graph, opts = {}) {
23 super()
24 this.graph = graph
25 this.rootDir = graph.root
26 this.resolutionContext = graph.resolutionContext || { ignore: () => false, projectType: graph.projectType }
27 this.ignore = this.resolutionContext.ignore
28 this._watcher = null
29 this._history = [] // append-only log of live events for replay
30 this._enabledWatcher = opts.watch !== false
31 }
32
33 start () {
34 if (!this._enabledWatcher) return
35 this._watcher = new FsWatcher(this.rootDir, this.ignore)
36 this._watcher.on('change', e => this._onChange(e))
37 this._watcher.on('remove', e => this._onRemove(e))
38 // Watcher failures (ENOSPC, EMFILE, EACCES) are recoverable — the snapshot
39 // is still served, just no live updates. Log and degrade rather than crash.
40 this._watcher.on('error', err => {
41 this.watcherError = err
42 console.warn('[live-store] fs.watch disabled:', err.code || err.message)
43 })
44 }
45
46 stop () {
47 if (this._watcher) {
48 this._watcher.close()
49 this._watcher = null
50 }
51 }
52
53 // --- Subscription ---
54
55 /**
56 * Attach a subscriber. Called with every historic event (to rebuild state),
57 * then with every future live event as it fires.
58 *
59 * Returns an unsubscribe function.
60 */
61 subscribe (handler) {
62 // Replay history (snapshot of the current state as events)
63 for (const ev of this._history) handler(ev)
64 this.on('event', handler)
65 return () => this.off('event', handler)
66 }
67
68 // --- Initial state replay ---
69
70 /**
71 * Seed the history from the initial graph. Converts the already-built tree
72 * back into the event sequence that would reconstruct it. A new subscriber
73 * then receives these as their "bootstrap" before live events start.
74 */
75 seedFromGraph () {
76 const g = this.graph
77 this._log({
78 type: 'scan-start',
79 root: g.root,
80 projectType: g.projectType,
81 languages: g.languages,
82 shallow: g.shallow || false
83 })
84 for (const [name, mod] of g.modules) {
85 this._log({
86 type: 'module-start',
87 name,
88 version: mod.version,
89 path: mod.path,
90 absPath: mod.absPath,
91 entry: mod.entry,
92 projectType: mod.projectType,
93 dependencies: mod.dependencies,
94 devDependencies: mod.devDependencies,
95 importMaps: mod.importMaps,
96 testCommand: mod.testCommand,
97 // mod.type is JS module type ('commonjs'/'module') — avoid the name
98 // collision with the SSE event type.
99 moduleType: mod.type
100 })
101 for (const [relInPkg, fileInfo] of mod.files) {
102 this._log({
103 type: 'file-discovered',
104 modName: name,
105 absPath: fileInfo.absPath,
106 relPath: fileInfo.relPath,
107 relInPkg,
108 size: fileInfo.size || 0
109 })
110 if (fileInfo.parsed) {
111 this._log({
112 type: 'file-parsed',
113 modName: name,
114 relInPkg,
115 relPath: fileInfo.relPath,
116 parsed: fileInfo.parsed
117 })
118 }
119 for (const imp of fileInfo.localImports || []) {
120 this._log({
121 type: 'import-edge',
122 modName: name,
123 fromRelInPkg: relInPkg,
124 specifier: imp.specifier,
125 resolvedRelPath: imp.resolved,
126 implicit: !!imp.implicit
127 })
128 }
129 }
130 this._log({ type: 'module-end', name })
131 }
132 this._log({ type: 'scan-end', root: g.root })
133 }
134
135 _log (ev) {
136 this._history.push(ev)
137 this.emit('event', ev)
138 }
139
140 // --- Change handlers ---
141
142 _onChange (e) {
143 // Which module does this file belong to? Find by absPath prefix.
144 const modEntry = this._findModuleForPath(e.absPath)
145 if (!modEntry) return // file in a dir we don't track (test output, new repo, etc.)
146
147 const [modName, mod] = modEntry
148 const relInPkg = relative(mod.absPath, e.absPath)
149
150 // Non-source files get a lightweight change event but no re-parse
151 if (!isSourceFile(e.absPath)) {
152 this._log({ type: 'file-changed', modName, absPath: e.absPath, relPath: e.relPath, relInPkg })
153 return
154 }
155
156 // Read + parse the file; emit file-parsed so subscribers can update their tree
157 let source
158 try { source = readFileSync(e.absPath, 'utf-8') } catch { return }
159
160 const lang = getLang(e.absPath)
161 if (!lang) return
162
163 let parsed
164 try { parsed = lang.parse(source, relInPkg) }
165 catch (err) { parsed = { error: err.message, filePath: relInPkg } }
166
167 // Update the in-memory graph for future subscribers / replay
168 let fileInfo = mod.files.get(relInPkg)
169 const isNew = !fileInfo
170 if (isNew) {
171 fileInfo = {
172 absPath: e.absPath,
173 relPath: e.relPath,
174 relInPkg,
175 size: source.length,
176 localImports: [],
177 parsed: null
178 }
179 mod.files.set(relInPkg, fileInfo)
180 this.graph.files.set(e.relPath, fileInfo)
181 this._log({
182 type: 'file-discovered',
183 modName, absPath: e.absPath, relPath: e.relPath, relInPkg, size: source.length
184 })
185 }
186 fileInfo.parsed = parsed
187 fileInfo.size = source.length
188
189 this._log({ type: 'file-parsed', modName, relInPkg, relPath: e.relPath, parsed })
190 }
191
192 _onRemove (e) {
193 const modEntry = this._findModuleForPath(e.absPath)
194 if (!modEntry) return
195 const [modName, mod] = modEntry
196 const relInPkg = relative(mod.absPath, e.absPath)
197
198 if (mod.files.has(relInPkg)) {
199 mod.files.delete(relInPkg)
200 this.graph.files.delete(e.relPath)
201 this._log({ type: 'file-removed', modName, relPath: e.relPath, relInPkg })
202 }
203 }
204
205 _findModuleForPath (absPath) {
206 // Linear scan — fine for now. Modules are typically <100. If this grows
207 // we can index by prefix.
208 let bestEntry = null
209 let bestLen = -1
210 for (const [name, mod] of this.graph.modules) {
211 if (absPath === mod.absPath || absPath.startsWith(mod.absPath + '/')) {
212 if (mod.absPath.length > bestLen) {
213 bestEntry = [name, mod]
214 bestLen = mod.absPath.length
215 }
216 }
217 }
218 return bestEntry
219 }
220}
lib/parsers/cpp.js +461 -0
……@@ -0,0 +1,461 @@
1import { parser } from '../../vendor/lezer-cpp/lezer-cpp.mjs'
2
3/**
4 * C++ parser — walks the Lezer concrete syntax tree to extract:
5 * - #include "local.h" → imports (quoted, not <angle-bracket>)
6 * - class / struct definitions → classes with methods, inheritance
7 * - free functions → functions
8 * - namespaces → namespaces array
9 * - enums → enums array
10 * - typedef / using aliases → constants
11 * - #define macros → constants
12 */
13
14export function parseFile (source, filePath) {
15 let tree
16 try { tree = parser.parse(source) }
17 catch (err) { return { error: err.message, filePath } }
18
19 const result = {
20 filePath,
21 imports: [],
22 exports: [],
23 classes: [],
24 functions: [],
25 constants: [],
26 namespaces: [],
27 enums: []
28 }
29
30 // Out-of-line definitions (Class::method) may appear before their class; track them
31 // and merge into the class if we encounter it.
32 const outOfLineMethods = {} // className -> [method,...]
33
34 const cursor = tree.cursor()
35 if (cursor.firstChild()) {
36 do {
37 visitTopLevel(cursor, source, result, outOfLineMethods)
38 } while (cursor.nextSibling())
39 }
40
41 // Attach any out-of-line methods to their classes (class may have been visited earlier)
42 for (const cls of result.classes) {
43 const extra = outOfLineMethods[cls.name]
44 if (extra) {
45 for (const m of extra) cls.methods.push(m)
46 }
47 }
48
49 return result
50}
51
52function visitTopLevel (cursor, source, result, outOfLineMethods) {
53 switch (cursor.name) {
54 case 'PreprocDirective':
55 handlePreproc(cursor, source, result)
56 return
57
58 case 'NamespaceDefinition':
59 handleNamespace(cursor, source, result, outOfLineMethods)
60 return
61
62 case 'ClassSpecifier':
63 case 'StructSpecifier': {
64 const cls = extractClass(cursor, source, cursor.name === 'StructSpecifier' ? 'struct' : 'class')
65 if (cls) {
66 result.classes.push(cls)
67 result.exports.push({ name: cls.name, type: cls.kind })
68 }
69 return
70 }
71
72 case 'FunctionDefinition':
73 handleFunctionDefinition(cursor, source, result, outOfLineMethods)
74 return
75
76 case 'EnumSpecifier':
77 handleEnum(cursor, source, result)
78 return
79
80 case 'TypeDefinition':
81 case 'AliasDeclaration': {
82 const name = findTypeIdentifier(cursor, source)
83 if (name) result.constants.push({ name, kind: 'typedef' })
84 return
85 }
86
87 case 'Declaration':
88 // GDCLASS(Name, Base); lives here. We can ignore most declarations but
89 // preserve top-level function declarations.
90 handleDeclaration(cursor, source, result)
91 return
92 }
93}
94
95// --- #include handling ---
96
97function handlePreproc (cursor, source, result) {
98 // #include followed by either SystemLibString (<...>) or String ("...")
99 if (!cursor.firstChild()) return
100 let isInclude = false
101 try {
102 do {
103 if (cursor.name === '#include') isInclude = true
104 else if (isInclude && cursor.name === 'String') {
105 // Quoted include — local dependency
106 const text = source.slice(cursor.from, cursor.to).replace(/^["<]|[">]$/g, '')
107 result.imports.push({ specifier: text, names: [] })
108 }
109 // SystemLibString (<...>) is skipped — system headers don't participate in the local graph
110 } while (cursor.nextSibling())
111 } finally {
112 cursor.parent()
113 }
114}
115
116// --- Namespace ---
117
118function handleNamespace (cursor, source, result, outOfLineMethods) {
119 if (!cursor.firstChild()) return
120 let nsName = null
121 try {
122 do {
123 if (cursor.name === 'Identifier' && !nsName) {
124 const text = source.slice(cursor.from, cursor.to)
125 if (text !== 'namespace') nsName = text
126 } else if (cursor.name === 'CompoundStatement') {
127 // Walk the body as if it were top-level
128 if (cursor.firstChild()) {
129 do { visitTopLevel(cursor, source, result, outOfLineMethods) } while (cursor.nextSibling())
130 cursor.parent()
131 }
132 }
133 } while (cursor.nextSibling())
134 } finally {
135 cursor.parent()
136 }
137 if (nsName && !result.namespaces.includes(nsName)) result.namespaces.push(nsName)
138}
139
140// --- Class / struct ---
141
142function extractClass (cursor, source, kind) {
143 const cls = {
144 name: null,
145 kind,
146 extends: null,
147 line: getLine(source, cursor.from),
148 methods: [],
149 getters: [],
150 staticMethods: [],
151 constructor: null
152 }
153
154 if (!cursor.firstChild()) return null
155 try {
156 do {
157 if (cursor.name === 'TypeIdentifier' && !cls.name) {
158 cls.name = source.slice(cursor.from, cursor.to)
159 } else if (cursor.name === 'BaseClassClause') {
160 cls.extends = extractBaseClass(cursor, source)
161 } else if (cursor.name === 'FieldDeclarationList') {
162 extractFieldDeclarations(cursor, source, cls)
163 }
164 } while (cursor.nextSibling())
165 } finally {
166 cursor.parent()
167 }
168
169 return cls.name ? cls : null
170}
171
172function extractBaseClass (cursor, source) {
173 // BaseClassClause contains Access + TypeIdentifier (or just TypeIdentifier)
174 if (!cursor.firstChild()) return null
175 try {
176 do {
177 if (cursor.name === 'TypeIdentifier') {
178 return source.slice(cursor.from, cursor.to)
179 }
180 } while (cursor.nextSibling())
181 } finally {
182 cursor.parent()
183 }
184 return null
185}
186
187function extractFieldDeclarations (cursor, source, cls) {
188 if (!cursor.firstChild()) return
189 let currentAccess = 'private' // default for class, public for struct — not enforced here
190 try {
191 do {
192 if (cursor.name === 'AccessSpecifier') {
193 const text = source.slice(cursor.from, cursor.to)
194 if (text.startsWith('public')) currentAccess = 'public'
195 else if (text.startsWith('protected')) currentAccess = 'protected'
196 else currentAccess = 'private'
197 } else if (cursor.name === 'FieldDeclaration' || cursor.name === 'FunctionDefinition') {
198 const isStatic = hasChildWithText(cursor, source, 'static')
199 const decl = extractFieldOrMethod(cursor, source, cls.name)
200 if (decl) {
201 decl.access = currentAccess
202 if (decl.isMethod) {
203 const m = { name: decl.name, params: decl.params, line: decl.line }
204 if (isStatic) {
205 m.static = true
206 cls.staticMethods.push(m)
207 } else if (decl.name === cls.name) {
208 cls.constructor = m
209 } else {
210 cls.methods.push(m)
211 }
212 }
213 // Data fields: not separately tracked in the common interface; could add to state later
214 }
215 }
216 } while (cursor.nextSibling())
217 } finally {
218 cursor.parent()
219 }
220}
221
222function hasChildWithText (cursor, source, text) {
223 if (!cursor.firstChild()) return false
224 try {
225 do {
226 const t = source.slice(cursor.from, cursor.to)
227 if (t === text) return true
228 } while (cursor.nextSibling())
229 } finally {
230 cursor.parent()
231 }
232 return false
233}
234
235function extractFieldOrMethod (cursor, source, className) {
236 // FieldDeclaration may contain a FunctionDeclarator (method) or just an identifier (data field).
237 // FunctionDefinition contains a FunctionDeclarator + CompoundStatement (inline method body).
238 // Return types like `Foo*` wrap the FunctionDeclarator in a PointerDeclarator — recurse through those.
239 let name = null
240 let params = []
241 let isMethod = false
242 const line = getLine(source, cursor.from)
243
244 function visit () {
245 if (!cursor.firstChild()) return
246 try {
247 do {
248 if (cursor.name === 'FunctionDeclarator') {
249 isMethod = true
250 const fd = extractFunctionDeclarator(cursor, source)
251 if (fd) { name = fd.name; params = fd.params }
252 } else if (cursor.name === 'PointerDeclarator' || cursor.name === 'ReferenceDeclarator') {
253 // Recurse: `Foo* create()` or `Foo& create()`
254 visit()
255 } else if ((cursor.name === 'FieldIdentifier' || cursor.name === 'Identifier') && !name) {
256 name = source.slice(cursor.from, cursor.to)
257 }
258 } while (cursor.nextSibling())
259 } finally {
260 cursor.parent()
261 }
262 }
263
264 visit()
265
266 if (!name) return null
267 return { name, params, isMethod, line }
268}
269
270function extractFunctionDeclarator (cursor, source) {
271 let name = null
272 const params = []
273 let classPart = null // for scoped names like ClassName::method
274
275 if (!cursor.firstChild()) return null
276 try {
277 do {
278 if (cursor.name === 'Identifier' && !name) {
279 name = source.slice(cursor.from, cursor.to)
280 } else if (cursor.name === 'FieldIdentifier' && !name) {
281 name = source.slice(cursor.from, cursor.to)
282 } else if (cursor.name === 'ScopedIdentifier') {
283 // ClassName::method — extract both halves
284 const parts = extractScoped(cursor, source)
285 if (parts) { classPart = parts.ns; name = parts.name }
286 } else if (cursor.name === 'ParameterList') {
287 extractParameterList(cursor, source, params)
288 }
289 } while (cursor.nextSibling())
290 } finally {
291 cursor.parent()
292 }
293
294 if (!name) return null
295 return { name, params, classPart }
296}
297
298function extractScoped (cursor, source) {
299 // ScopedIdentifier: NamespaceIdentifier :: Identifier
300 let ns = null
301 let name = null
302 if (!cursor.firstChild()) return null
303 try {
304 do {
305 if (cursor.name === 'NamespaceIdentifier' && !ns) {
306 ns = source.slice(cursor.from, cursor.to)
307 } else if (cursor.name === 'Identifier') {
308 name = source.slice(cursor.from, cursor.to)
309 }
310 } while (cursor.nextSibling())
311 } finally {
312 cursor.parent()
313 }
314 return (ns && name) ? { ns, name } : null
315}
316
317function extractParameterList (cursor, source, params) {
318 if (!cursor.firstChild()) return
319 try {
320 do {
321 if (cursor.name === 'ParameterDeclaration') {
322 // Get last Identifier as param name (after the type)
323 const pName = lastIdentifier(cursor, source)
324 if (pName) params.push(pName)
325 }
326 } while (cursor.nextSibling())
327 } finally {
328 cursor.parent()
329 }
330}
331
332function lastIdentifier (cursor, source) {
333 let name = null
334 if (!cursor.firstChild()) return null
335 try {
336 do {
337 if (cursor.name === 'Identifier') {
338 name = source.slice(cursor.from, cursor.to)
339 }
340 } while (cursor.nextSibling())
341 } finally {
342 cursor.parent()
343 }
344 return name
345}
346
347// --- Free function / out-of-line method definitions ---
348
349function handleFunctionDefinition (cursor, source, result, outOfLineMethods) {
350 // FunctionDefinition = return-type + FunctionDeclarator + CompoundStatement
351 if (!cursor.firstChild()) return
352 let fd = null
353 const line = getLine(source, cursor.from)
354 try {
355 do {
356 if (cursor.name === 'FunctionDeclarator') {
357 fd = extractFunctionDeclarator(cursor, source)
358 }
359 } while (cursor.nextSibling())
360 } finally {
361 cursor.parent()
362 }
363
364 if (!fd) return
365
366 if (fd.classPart) {
367 // Out-of-line method: buffer until we process its class
368 if (!outOfLineMethods[fd.classPart]) outOfLineMethods[fd.classPart] = []
369 outOfLineMethods[fd.classPart].push({ name: fd.name, params: fd.params, line })
370 } else {
371 result.functions.push({ name: fd.name, params: fd.params, line })
372 }
373}
374
375// --- Enum ---
376
377function handleEnum (cursor, source, result) {
378 let name = null
379 const values = []
380 if (!cursor.firstChild()) return
381 try {
382 do {
383 if (cursor.name === 'TypeIdentifier' && !name) {
384 name = source.slice(cursor.from, cursor.to)
385 } else if (cursor.name === 'EnumeratorList') {
386 if (cursor.firstChild()) {
387 do {
388 if (cursor.name === 'Enumerator') {
389 const v = firstIdentifier(cursor, source)
390 if (v) values.push(v)
391 }
392 } while (cursor.nextSibling())
393 cursor.parent()
394 }
395 }
396 } while (cursor.nextSibling())
397 } finally {
398 cursor.parent()
399 }
400 if (name) result.enums.push({ name, values })
401}
402
403// --- Declarations (catches #define macros via TypeDefinition, GDCLASS, etc.) ---
404
405function handleDeclaration (cursor, source, result) {
406 // Most non-function declarations are global variables or forward declarations.
407 // We care about free function declarations (not definitions) at top level.
408 if (!cursor.firstChild()) return
409 let fd = null
410 const line = getLine(source, cursor.from)
411 try {
412 do {
413 if (cursor.name === 'FunctionDeclarator') {
414 fd = extractFunctionDeclarator(cursor, source)
415 }
416 } while (cursor.nextSibling())
417 } finally {
418 cursor.parent()
419 }
420
421 if (fd && !fd.classPart) {
422 // Only add if not already defined (avoid double-counting with definitions)
423 if (!result.functions.find(f => f.name === fd.name)) {
424 result.functions.push({ name: fd.name, params: fd.params, line })
425 }
426 }
427}
428
429// --- Helpers ---
430
431function findTypeIdentifier (cursor, source) {
432 if (!cursor.firstChild()) return null
433 try {
434 do {
435 if (cursor.name === 'TypeIdentifier') {
436 return source.slice(cursor.from, cursor.to)
437 }
438 } while (cursor.nextSibling())
439 } finally {
440 cursor.parent()
441 }
442 return null
443}
444
445function firstIdentifier (cursor, source) {
446 if (!cursor.firstChild()) return null
447 try {
448 do {
449 if (cursor.name === 'Identifier') {
450 return source.slice(cursor.from, cursor.to)
451 }
452 } while (cursor.nextSibling())
453 } finally {
454 cursor.parent()
455 }
456 return null
457}
458
459function getLine (source, offset) {
460 return source.slice(0, offset).split('\n').length
461}
lib/parsers/gdscript.js +288 -0
……@@ -0,0 +1,288 @@
1import { parser } from '../../vendor/lezer-gdscript/lezer-gdscript.mjs'
2
3/**
4 * GDScript parser — walks the Lezer concrete syntax tree to extract:
5 * - class_name (treated as the file's exported class)
6 * - extends (base class)
7 * - signals (GDScript-specific)
8 * - functions / methods
9 * - constants and variables
10 * - preload() calls → imports
11 *
12 * A .gd file IS a class (the class_name declares its global identity).
13 * Top-level funcs are methods of that class; top-level vars are its state.
14 */
15
16export function parseFile (source, filePath) {
17 let tree
18 try { tree = parser.parse(source) }
19 catch (err) { return { error: err.message, filePath } }
20
21 const result = {
22 filePath,
23 imports: [],
24 exports: [],
25 classes: [],
26 functions: [],
27 constants: [],
28 signals: [],
29 enums: []
30 }
31
32 // Single implicit class for the file — filled in as we walk
33 const fileClass = {
34 name: null, // filled from class_name, or file basename
35 extends: null,
36 line: 1,
37 methods: [],
38 getters: [],
39 staticMethods: [],
40 constructor: null
41 }
42
43 const cursor = tree.cursor()
44
45 // Walk only top-level statements inside Script
46 if (cursor.firstChild()) {
47 do {
48 visitTopLevel(cursor, source, fileClass, result)
49 } while (cursor.nextSibling())
50 }
51
52 // Default name from filename if no class_name found
53 if (!fileClass.name) {
54 const base = filePath.split('/').pop().replace(/\.gd$/, '')
55 fileClass.name = base
56 }
57
58 // Emit the class unless the file is clearly not a class (no name, no body)
59 if (fileClass.methods.length > 0 || fileClass.getters.length > 0 ||
60 fileClass.staticMethods.length > 0 || fileClass.extends || result.exports.length > 0) {
61 result.classes.push(fileClass)
62 }
63
64 return result
65}
66
67function visitTopLevel (cursor, source, fileClass, result) {
68 const name = cursor.name
69
70 // SimpleStatement wraps most top-level statements
71 if (name === 'SimpleStatement' || name === 'SmallStatement') {
72 if (cursor.firstChild()) {
73 do { visitTopLevel(cursor, source, fileClass, result) } while (cursor.nextSibling())
74 cursor.parent()
75 }
76 return
77 }
78
79 // CompoundStatement wraps function/class bodies
80 if (name === 'CompoundStatement') {
81 if (cursor.firstChild()) {
82 do { visitTopLevel(cursor, source, fileClass, result) } while (cursor.nextSibling())
83 cursor.parent()
84 }
85 return
86 }
87
88 // class_name → file's class name + exported as a class
89 if (name === 'ClassNameStatement') {
90 const ident = identifierText(cursor, source)
91 if (ident) {
92 fileClass.name = ident
93 fileClass.line = getLine(source, cursor.from)
94 result.exports.push({ name: ident, type: 'class' })
95 }
96 return
97 }
98
99 // extends → base class
100 if (name === 'ExtendsStatement') {
101 const ident = identifierText(cursor, source)
102 if (ident) fileClass.extends = ident
103 return
104 }
105
106 // signal → signals array
107 if (name === 'SignalStatement') {
108 const sig = extractSignal(cursor, source)
109 if (sig) result.signals.push(sig)
110 return
111 }
112
113 // func / static func → method
114 if (name === 'FunctionNode') {
115 const fn = extractFunction(cursor, source)
116 if (fn) {
117 // Check if preceded by a "static" keyword (GDScript puts static before func)
118 const isStatic = isPrecededByStatic(source, cursor.from)
119 if (isStatic) fn.static = true
120 if (fn.name === '_init') {
121 fileClass.constructor = { params: fn.params, line: fn.line }
122 } else if (isStatic) {
123 fileClass.staticMethods.push(fn)
124 } else {
125 fileClass.methods.push(fn)
126 }
127 }
128 return
129 }
130
131 // AssignmentExpressionNode wraps var/const declarations
132 if (name === 'AssignmentExpressionNode') {
133 extractAssignment(cursor, source, result)
134 return
135 }
136}
137
138// --- Helpers ---
139
140function identifierText (cursor, source) {
141 if (!cursor.firstChild()) return null
142 try {
143 do {
144 if (cursor.name === 'Identifier') {
145 const text = source.slice(cursor.from, cursor.to)
146 // Skip keyword-like identifiers
147 if (text !== 'class_name' && text !== 'extends' && text !== 'signal' &&
148 text !== 'func' && text !== 'var' && text !== 'const' && text !== 'enum') {
149 return text
150 }
151 }
152 } while (cursor.nextSibling())
153 } finally {
154 cursor.parent()
155 }
156 return null
157}
158
159function extractSignal (cursor, source) {
160 const sig = { name: null, params: [] }
161 if (!cursor.firstChild()) return null
162 try {
163 do {
164 if (cursor.name === 'Identifier' && !sig.name) {
165 const text = source.slice(cursor.from, cursor.to)
166 if (text !== 'signal') sig.name = text
167 } else if (cursor.name === 'CallParamsExpressionNode') {
168 sig.params = extractParamsFromCall(cursor, source)
169 }
170 } while (cursor.nextSibling())
171 } finally {
172 cursor.parent()
173 }
174 return sig.name ? sig : null
175}
176
177function extractFunction (cursor, source) {
178 const fn = { name: null, params: [], line: getLine(source, cursor.from) }
179 if (!cursor.firstChild()) return null
180 try {
181 do {
182 if (cursor.name === 'Identifier' && !fn.name) {
183 const text = source.slice(cursor.from, cursor.to)
184 if (text !== 'func' && text !== 'static') fn.name = text
185 } else if (cursor.name === 'CallParamsParameterNode') {
186 fn.params = extractParamsFromCall(cursor, source)
187 }
188 } while (cursor.nextSibling())
189 } finally {
190 cursor.parent()
191 }
192 return fn.name ? fn : null
193}
194
195function extractParamsFromCall (cursor, source) {
196 // cursor is at CallParamsParameterNode or CallParamsExpressionNode
197 const params = []
198 if (!cursor.firstChild()) return params
199 try {
200 do {
201 if (cursor.name === 'ParameterNode' || cursor.name === 'AssignmentExpressionNode') {
202 // Grab first identifier as param name
203 const paramName = firstIdentifier(cursor, source)
204 if (paramName) params.push(paramName)
205 }
206 } while (cursor.nextSibling())
207 } finally {
208 cursor.parent()
209 }
210 return params
211}
212
213function firstIdentifier (cursor, source) {
214 if (!cursor.firstChild()) return null
215 try {
216 do {
217 if (cursor.name === 'Identifier') {
218 return source.slice(cursor.from, cursor.to)
219 }
220 } while (cursor.nextSibling())
221 } finally {
222 cursor.parent()
223 }
224 return null
225}
226
227function extractAssignment (cursor, source, result) {
228 // AssignmentExpressionNode may contain VariableNode, ConstantNode, and/or PreloadExpressionNode
229 if (!cursor.firstChild()) return
230 try {
231 do {
232 if (cursor.name === 'VariableNode' || cursor.name === 'ConstantNode') {
233 const kind = cursor.name === 'ConstantNode' ? 'const' : 'var'
234 const ident = firstIdentifier(cursor, source)
235 if (ident) result.constants.push({ name: ident, kind })
236 } else if (cursor.name === 'PreloadExpressionNode') {
237 const path = extractPreloadPath(cursor, source)
238 if (path) result.imports.push({ specifier: path, names: [] })
239 }
240 } while (cursor.nextSibling())
241 } finally {
242 cursor.parent()
243 }
244}
245
246function extractPreloadPath (cursor, source) {
247 // Find LiteralExpressionNode within CallParamsExpressionNode
248 if (!cursor.firstChild()) return null
249 try {
250 do {
251 if (cursor.name === 'CallParamsExpressionNode') {
252 const lit = findLiteralInCall(cursor, source)
253 if (lit) {
254 // Strip quotes
255 return lit.replace(/^['"]|['"]$/g, '')
256 }
257 }
258 } while (cursor.nextSibling())
259 } finally {
260 cursor.parent()
261 }
262 return null
263}
264
265function findLiteralInCall (cursor, source) {
266 if (!cursor.firstChild()) return null
267 try {
268 do {
269 if (cursor.name === 'LiteralExpressionNode') {
270 return source.slice(cursor.from, cursor.to)
271 }
272 } while (cursor.nextSibling())
273 } finally {
274 cursor.parent()
275 }
276 return null
277}
278
279function isPrecededByStatic (source, from) {
280 // Look backwards from `from` for the word 'static' before 'func'
281 // GDScript: `static func` — static appears on same line, before func
282 const before = source.slice(Math.max(0, from - 60), from)
283 return /\bstatic\s*$/.test(before) || /\bstatic\s+\n?\s*$/.test(before)
284}
285
286function getLine (source, offset) {
287 return source.slice(0, offset).split('\n').length
288}
lib/parsers/glsl.js +296 -0
……@@ -0,0 +1,296 @@
1import { parse } from '../../vendor/glsl-parser/glsl-parser.mjs'
2
3/**
4 * GLSL parser — walks the @shaderfrog/glsl-parser AST to extract:
5 * - Functions (void main, helpers)
6 * - Uniforms (regular uniform vars + uniform blocks)
7 * - Buffers (readonly/writeonly storage buffers)
8 * - Push constants (uniform blocks with push_constant layout)
9 * - Structs → classes
10 * - #defines → constants
11 *
12 * GLSL has no import system in the general case (dc-terrain shaders are monolithic),
13 * so imports[] is always empty. Godot .gdshader files may use `#include` but those
14 * are engine-specific and not modeled here yet.
15 */
16
17export function parseFile (source, filePath) {
18 // Always return these empty arrays so downstream consumers can `.length` safely even
19 // on parse failure.
20 const result = {
21 filePath,
22 imports: [],
23 exports: [],
24 classes: [],
25 functions: [],
26 constants: [],
27 uniforms: [],
28 buffers: [],
29 pushConstants: []
30 }
31
32 // Godot .gdshader files are a GLSL superset with editor hints that standard GLSL
33 // doesn't accept (e.g. `uniform sampler3D foo : filter_linear, repeat_enable;`).
34 // Strip these hints — they're purely presentational, not part of the shader logic.
35 const isGdShader = filePath && filePath.endsWith('.gdshader')
36 const processed = isGdShader ? stripGodotShaderHints(source) : source
37
38 // The parser emits warnings to console.warn for unknown identifiers (e.g. GLSL builtins
39 // like gl_GlobalInvocationID). Silence them during structural extraction.
40 const origWarn = console.warn
41 console.warn = () => {}
42 let ast
43 try { ast = parse(processed) }
44 catch (err) {
45 console.warn = origWarn
46 result.error = err.message
47 return result
48 }
49 console.warn = origWarn
50
51 if (!ast || !ast.program) return result
52
53 for (const node of ast.program) {
54 switch (node.type) {
55 case 'preprocessor':
56 handlePreprocessor(node, result)
57 break
58 case 'declaration_statement':
59 handleDeclarationStatement(node, result)
60 break
61 case 'function':
62 handleFunction(node, result)
63 break
64 }
65 }
66
67 return result
68}
69
70// --- Preprocessor (#define, #include) ---
71
72function handlePreprocessor (node, result) {
73 const line = node.line || ''
74
75 // #define NAME value — extract as constant
76 const defMatch = line.match(/^\s*#\s*define\s+(\w+)\b/)
77 if (defMatch) {
78 result.constants.push({ name: defMatch[1], kind: 'define' })
79 return
80 }
81
82 // #include "path" (Godot .gdshader style) — capture as import
83 const incMatch = line.match(/^\s*#\s*include\s+["<]([^">]+)[">]/)
84 if (incMatch) {
85 result.imports.push({ specifier: incMatch[1], names: [] })
86 }
87}
88
89// --- Declaration statements (uniforms, buffers, structs, layout) ---
90
91function handleDeclarationStatement (node, result) {
92 const decl = node.declaration
93 if (!decl) return
94
95 switch (decl.type) {
96 case 'interface_declarator':
97 handleInterfaceDeclarator(decl, result)
98 return
99 case 'declarator_list':
100 handleDeclaratorList(decl, result)
101 return
102 case 'qualifier_declarator':
103 // layout-only decls like `layout(local_size_x=256) in;` — no extraction needed
104 return
105 }
106}
107
108function handleInterfaceDeclarator (decl, result) {
109 // Used for: buffer blocks, uniform blocks, push constants
110 const qualTokens = extractQualifierTokens(decl.qualifiers || [])
111 const hasLayout = (decl.qualifiers || []).some(q => q.type === 'layout_qualifier')
112 const layoutIds = extractLayoutIds(decl.qualifiers || [])
113
114 const blockName = decl.interface_type && decl.interface_type.identifier
115 ? decl.interface_type.identifier
116 : null
117 const instanceName = decl.identifier && decl.identifier.identifier
118 ? decl.identifier.identifier
119 : null
120
121 if (!blockName) return
122
123 const isBuffer = qualTokens.includes('buffer')
124 const isUniform = qualTokens.includes('uniform')
125 const isPushConstant = layoutIds.some(id => id === 'push_constant')
126 const isReadonly = qualTokens.includes('readonly')
127 const isWriteonly = qualTokens.includes('writeonly')
128
129 const entry = {
130 name: blockName,
131 instance: instanceName,
132 binding: layoutIdValue(layoutIds, 'binding'),
133 set: layoutIdValue(layoutIds, 'set'),
134 std: layoutIds.find(id => id === 'std140' || id === 'std430') || null
135 }
136 if (isReadonly) entry.readonly = true
137 if (isWriteonly) entry.writeonly = true
138
139 if (isPushConstant) {
140 result.pushConstants.push(entry)
141 } else if (isBuffer) {
142 result.buffers.push(entry)
143 } else if (isUniform) {
144 result.uniforms.push(entry)
145 }
146}
147
148function handleDeclaratorList (decl, result) {
149 // Could be:
150 // - struct declaration: specifier.type === 'struct'
151 // - uniform sampler2D u_tex;
152 // - in/out variables
153 // - regular global variables
154 const specType = decl.specified_type && decl.specified_type.specifier
155 const quals = (decl.specified_type && decl.specified_type.qualifiers) || []
156 const qualTokens = extractQualifierTokens(quals)
157
158 // Struct declaration
159 if (specType && specType.specifier && specType.specifier.type === 'struct') {
160 const structNode = specType.specifier
161 const structName = structNode.typeName && structNode.typeName.identifier
162 ? structNode.typeName.identifier
163 : null
164 if (structName) {
165 const cls = {
166 name: structName,
167 kind: 'struct',
168 extends: null,
169 line: null,
170 methods: [],
171 getters: [],
172 staticMethods: [],
173 constructor: null,
174 fields: extractStructFields(structNode)
175 }
176 result.classes.push(cls)
177 result.exports.push({ name: structName, type: 'struct' })
178 }
179 return
180 }
181
182 // Regular variable declaration (uniform float u_time, in vec3 pos, etc.)
183 const declarations = decl.declarations || []
184 for (const d of declarations) {
185 if (d.type === 'declaration' && d.identifier && d.identifier.identifier) {
186 const name = d.identifier.identifier
187 const typeToken = specType && specType.specifier && specType.specifier.token
188 ? specType.specifier.token
189 : null
190 if (qualTokens.includes('uniform')) {
191 result.uniforms.push({ name, type: typeToken, binding: null, set: null })
192 } else if (qualTokens.includes('in') || qualTokens.includes('out')) {
193 result.constants.push({ name, kind: qualTokens.includes('out') ? 'out' : 'in' })
194 } else {
195 result.constants.push({ name, kind: 'var' })
196 }
197 }
198 }
199}
200
201function extractStructFields (structNode) {
202 const fields = []
203 for (const d of structNode.declarations || []) {
204 if (d.type !== 'struct_declaration') continue
205 const sd = d.declaration
206 if (!sd || !sd.declarations) continue
207 for (const q of sd.declarations) {
208 if (q.type === 'quantified_identifier' && q.identifier) {
209 fields.push(q.identifier.identifier)
210 }
211 }
212 }
213 return fields
214}
215
216// --- Function definitions ---
217
218function handleFunction (node, result) {
219 const proto = node.prototype
220 if (!proto || !proto.header) return
221 const header = proto.header
222 const name = header.name && header.name.identifier ? header.name.identifier : null
223 if (!name) return
224
225 const params = []
226 const pl = proto.parameters || []
227 for (const p of pl) {
228 if (p.type === 'parameter_declaration' && p.declaration && p.declaration.identifier) {
229 params.push(p.declaration.identifier.identifier)
230 }
231 }
232
233 result.functions.push({ name, params })
234 // GLSL `void main()` is the shader's entry point — export it so downstream tools
235 // can tell entry shaders from helpers.
236 if (name === 'main') result.exports.push({ name: 'main', type: 'function' })
237}
238
239// --- Helpers ---
240
241function extractQualifierTokens (quals) {
242 const tokens = []
243 for (const q of quals) {
244 if (q.type === 'keyword' && q.token) tokens.push(q.token)
245 }
246 return tokens
247}
248
249function extractLayoutIds (quals) {
250 const ids = []
251 for (const q of quals) {
252 if (q.type !== 'layout_qualifier') continue
253 for (const lq of q.qualifiers || []) {
254 if (lq.type === 'layout_qualifier_id' && lq.identifier && lq.identifier.identifier) {
255 const key = lq.identifier.identifier
256 const value = lq.expression && lq.expression.token ? lq.expression.token : null
257 ids.push(value ? key + '=' + value : key)
258 }
259 }
260 }
261 return ids
262}
263
264function layoutIdValue (ids, key) {
265 const match = ids.find(id => id.startsWith(key + '='))
266 if (!match) return null
267 return match.slice(key.length + 1)
268}
269
270// --- Godot .gdshader preprocessing ---
271
272function stripGodotShaderHints (source) {
273 // Remove:
274 // shader_type spatial; / shader_type canvas_item; / etc. (top-of-file directive)
275 // render_mode foo, bar; (mode modifiers)
276 // uniform T name : hint_name, other_hint; (editor hints)
277 // uniform T name : hint_name, other_hint = default; (same with default)
278 let s = source
279
280 // shader_type line
281 s = s.replace(/^\s*shader_type\s+\w+\s*;/gm, '')
282
283 // render_mode line (may span across commas)
284 s = s.replace(/^\s*render_mode\s+[^;]+;/gm, '')
285
286 // Uniform hints: `uniform T name : hint, hint_range(0.0, 1.0) = 0.5;`
287 // Strip the `: <hints>` portion while preserving any `= default` value.
288 // Process line by line to avoid greedy matches spanning multiple uniforms.
289 s = s.split('\n').map(line => {
290 const m = line.match(/^(\s*uniform\s+[^;=:]+?)\s*:\s*([\s\S]+?)(\s*(?:=[^;]*)?;)\s*$/)
291 if (!m) return line
292 return m[1] + m[3]
293 }).join('\n')
294
295 return s
296}
lib/parsers/js.js +491 -0
……@@ -0,0 +1,491 @@
1import { parse as acornParse } from '../../vendor/acorn/dist/acorn.mjs'
2
3const PARSE_OPTS = {
4 ecmaVersion: 'latest',
5 sourceType: 'module',
6 locations: true,
7 ranges: true,
8 allowHashBang: true
9}
10
11const CJS_PARSE_OPTS = {
12 ...PARSE_OPTS,
13 sourceType: 'script'
14}
15
16export function parseFile (source, filePath) {
17 const comments = []
18 const isESM = !filePath || !filePath.endsWith('.cjs')
19 const opts = {
20 ...(isESM ? PARSE_OPTS : CJS_PARSE_OPTS),
21 onComment: comments
22 }
23
24 let ast
25 try {
26 ast = acornParse(source, opts)
27 } catch (err) {
28 // Fall back to script mode if module parse fails (CJS files)
29 try {
30 ast = acornParse(source, { ...CJS_PARSE_OPTS, onComment: comments })
31 } catch {
32 return { error: err.message, filePath }
33 }
34 }
35
36 const result = {
37 filePath,
38 imports: [],
39 exports: [],
40 classes: [],
41 functions: [],
42 constants: [],
43 state: [],
44 errorContracts: [],
45 delegates: []
46 }
47
48 const commentMap = buildCommentMap(comments)
49
50 for (const node of ast.body) {
51 switch (node.type) {
52 case 'ImportDeclaration':
53 result.imports.push(extractImport(node))
54 break
55
56 case 'ExportNamedDeclaration':
57 extractNamedExport(node, result, commentMap)
58 break
59
60 case 'ExportDefaultDeclaration':
61 extractDefaultExport(node, result, commentMap)
62 break
63
64 case 'ExportAllDeclaration':
65 result.exports.push({
66 name: '*',
67 from: node.source ? node.source.value : null
68 })
69 break
70
71 case 'ClassDeclaration':
72 if (node.id) {
73 result.classes.push(extractClass(node, commentMap))
74 }
75 break
76
77 case 'FunctionDeclaration':
78 if (node.id) {
79 result.functions.push(extractFunction(node, commentMap))
80 }
81 break
82
83 case 'VariableDeclaration':
84 extractConstants(node, result, commentMap)
85 break
86
87 // CJS: module.exports = ...
88 case 'ExpressionStatement':
89 extractCJSExport(node, result, commentMap)
90 break
91 }
92 }
93
94 // Walk full AST for state, errors, delegation
95 walkDeep(ast, result)
96
97 return result
98}
99
100// --- Comment mapping ---
101
102function buildCommentMap (comments) {
103 // Map: endLine -> comment text (for block comments / JSDoc)
104 const map = []
105 for (const c of comments) {
106 if (c.type === 'Block' && c.value.startsWith('*')) {
107 map.push({
108 text: '/*' + c.value + '*/',
109 endLine: c.loc.end.line,
110 start: c.start,
111 end: c.end
112 })
113 }
114 }
115 return map
116}
117
118function findJSDoc (commentMap, node) {
119 if (!node.loc) return null
120 const nodeLine = node.loc.start.line
121 for (const c of commentMap) {
122 // JSDoc comment ends on the line before or same line as the node
123 if (c.endLine >= nodeLine - 2 && c.endLine < nodeLine) {
124 return c.text
125 }
126 }
127 return null
128}
129
130// --- Import extraction ---
131
132function extractImport (node) {
133 const result = {
134 specifier: node.source.value,
135 names: []
136 }
137 for (const spec of node.specifiers) {
138 switch (spec.type) {
139 case 'ImportSpecifier':
140 result.names.push(spec.imported.name)
141 break
142 case 'ImportDefaultSpecifier':
143 result.names.push(spec.local.name)
144 break
145 case 'ImportNamespaceSpecifier':
146 result.names.push('* as ' + spec.local.name)
147 break
148 }
149 }
150 return result
151}
152
153// --- Export extraction ---
154
155function extractNamedExport (node, result, commentMap) {
156 // Re-export: export { X } from './file.js'
157 if (node.source) {
158 for (const spec of node.specifiers) {
159 result.exports.push({
160 name: spec.exported.name || spec.exported.value,
161 from: node.source.value
162 })
163 }
164 return
165 }
166
167 // export class X { ... }
168 if (node.declaration) {
169 const decl = node.declaration
170 switch (decl.type) {
171 case 'ClassDeclaration': {
172 const cls = extractClass(decl, commentMap)
173 result.classes.push(cls)
174 result.exports.push({ name: cls.name, type: 'class' })
175 break
176 }
177 case 'FunctionDeclaration': {
178 const fn = extractFunction(decl, commentMap)
179 result.functions.push(fn)
180 result.exports.push({ name: fn.name, type: 'function' })
181 break
182 }
183 case 'VariableDeclaration': {
184 extractConstants(decl, result, commentMap)
185 for (const d of decl.declarations) {
186 if (d.id && d.id.name) {
187 result.exports.push({ name: d.id.name, type: 'const' })
188 }
189 }
190 break
191 }
192 }
193 return
194 }
195
196 // export { X, Y }
197 for (const spec of node.specifiers) {
198 result.exports.push({
199 name: spec.exported.name || spec.exported.value
200 })
201 }
202}
203
204function extractDefaultExport (node, result, commentMap) {
205 const decl = node.declaration
206 if (decl.type === 'ClassDeclaration' && decl.id) {
207 const cls = extractClass(decl, commentMap)
208 result.classes.push(cls)
209 result.exports.push({ name: 'default', type: 'class', localName: cls.name })
210 } else if (decl.type === 'FunctionDeclaration' && decl.id) {
211 const fn = extractFunction(decl, commentMap)
212 result.functions.push(fn)
213 result.exports.push({ name: 'default', type: 'function', localName: fn.name })
214 } else {
215 result.exports.push({ name: 'default', type: decl.type })
216 }
217}
218
219function extractCJSExport (node, result, commentMap) {
220 const expr = node.expression
221 if (!expr || expr.type !== 'AssignmentExpression') return
222
223 const left = expr.left
224 if (!left || left.type !== 'MemberExpression') return
225
226 // module.exports = class X { ... }
227 const isModuleExports = left.object &&
228 left.object.name === 'module' &&
229 left.property && left.property.name === 'exports'
230
231 // exports.X = ...
232 const isExportsProp = left.object &&
233 left.object.name === 'exports' &&
234 left.property
235
236 if (isModuleExports) {
237 const right = expr.right
238 if (right.type === 'ClassExpression' || right.type === 'ClassDeclaration') {
239 const cls = extractClass(right, commentMap)
240 result.classes.push(cls)
241 result.exports.push({ name: 'default', type: 'class', localName: cls.name, cjs: true })
242 } else if (right.type === 'FunctionExpression' || right.type === 'FunctionDeclaration') {
243 const fn = extractFunction(right, commentMap)
244 result.functions.push(fn)
245 result.exports.push({ name: 'default', type: 'function', localName: fn.name, cjs: true })
246 } else {
247 result.exports.push({ name: 'default', type: right.type, cjs: true })
248 }
249 } else if (isExportsProp) {
250 const name = left.property.name || left.property.value
251 result.exports.push({ name, cjs: true })
252 }
253}
254
255// --- Class extraction ---
256
257function extractClass (node, commentMap) {
258 const cls = {
259 name: node.id ? node.id.name : '(anonymous)',
260 extends: node.superClass ? nodeToString(node.superClass) : null,
261 line: node.loc ? node.loc.start.line : null,
262 constructor: null,
263 methods: [],
264 getters: [],
265 staticMethods: [],
266 jsdoc: findJSDoc(commentMap, node)
267 }
268
269 if (!node.body || !node.body.body) return cls
270
271 for (const member of node.body.body) {
272 if (member.type === 'MethodDefinition') {
273 const name = member.key.name || member.key.value || '(computed)'
274 const jsdoc = findJSDoc(commentMap, member)
275
276 if (member.kind === 'constructor') {
277 cls.constructor = {
278 params: extractParams(member.value.params),
279 line: member.loc ? member.loc.start.line : null,
280 jsdoc
281 }
282 } else if (member.kind === 'get') {
283 cls.getters.push({ name, static: member.static || false, line: member.loc ? member.loc.start.line : null })
284 } else if (member.kind === 'set') {
285 cls.getters.push({ name, kind: 'set', static: member.static || false })
286 } else if (member.static) {
287 cls.staticMethods.push({
288 name,
289 params: extractParams(member.value.params),
290 async: member.value.async || false,
291 line: member.loc ? member.loc.start.line : null,
292 jsdoc
293 })
294 } else {
295 cls.methods.push({
296 name,
297 params: extractParams(member.value.params),
298 async: member.value.async || false,
299 generator: member.value.generator || false,
300 line: member.loc ? member.loc.start.line : null,
301 jsdoc
302 })
303 }
304 } else if (member.type === 'PropertyDefinition') {
305 // Class fields (public or private)
306 const name = member.key.name || member.key.value || '(computed)'
307 cls.methods.push({
308 name,
309 kind: 'field',
310 static: member.static || false
311 })
312 }
313 }
314
315 return cls
316}
317
318// --- Function extraction ---
319
320function extractFunction (node, commentMap) {
321 return {
322 name: node.id ? node.id.name : '(anonymous)',
323 params: extractParams(node.params),
324 async: node.async || false,
325 generator: node.generator || false,
326 line: node.loc ? node.loc.start.line : null,
327 jsdoc: findJSDoc(commentMap, node)
328 }
329}
330
331// --- Constants ---
332
333function extractConstants (node, result, commentMap) {
334 for (const decl of node.declarations) {
335 if (!decl.id) continue
336
337 if (decl.id.type === 'Identifier') {
338 const entry = {
339 name: decl.id.name,
340 kind: node.kind,
341 jsdoc: findJSDoc(commentMap, node)
342 }
343
344 // If the init is a class or function, extract it
345 if (decl.init) {
346 if (decl.init.type === 'ClassExpression') {
347 const cls = extractClass(decl.init, commentMap)
348 cls.name = cls.name === '(anonymous)' ? decl.id.name : cls.name
349 result.classes.push(cls)
350 entry.type = 'class'
351 } else if (decl.init.type === 'ArrowFunctionExpression' || decl.init.type === 'FunctionExpression') {
352 result.functions.push({
353 name: decl.id.name,
354 params: extractParams(decl.init.params),
355 async: decl.init.async || false,
356 generator: decl.init.generator || false,
357 arrow: decl.init.type === 'ArrowFunctionExpression',
358 jsdoc: findJSDoc(commentMap, node)
359 })
360 entry.type = 'function'
361 }
362 }
363
364 result.constants.push(entry)
365 }
366 }
367}
368
369// --- Deep walk for state, errors, delegation ---
370
371function walkDeep (ast, result) {
372 const stateFields = new Set()
373 const delegateCalls = new Map() // field -> Set of methods
374 const errors = []
375
376 walk(ast, (node) => {
377 // this._field = ... (in constructor or methods)
378 if (
379 node.type === 'AssignmentExpression' &&
380 node.left.type === 'MemberExpression' &&
381 node.left.object.type === 'ThisExpression' &&
382 node.left.property.type === 'Identifier' &&
383 node.left.property.name.startsWith('_')
384 ) {
385 stateFields.add(node.left.property.name)
386 }
387
388 // throw new Error('...')
389 if (
390 node.type === 'ThrowStatement' &&
391 node.argument &&
392 node.argument.type === 'NewExpression' &&
393 node.argument.callee &&
394 node.argument.callee.name === 'Error' &&
395 node.argument.arguments.length > 0
396 ) {
397 const arg = node.argument.arguments[0]
398 if (arg.type === 'Literal') {
399 errors.push(arg.value)
400 } else if (arg.type === 'TemplateLiteral') {
401 errors.push(templateToPattern(arg))
402 }
403 }
404
405 // this._field.method() — delegation
406 if (
407 node.type === 'CallExpression' &&
408 node.callee.type === 'MemberExpression' &&
409 node.callee.object.type === 'MemberExpression' &&
410 node.callee.object.object.type === 'ThisExpression' &&
411 node.callee.object.property.type === 'Identifier' &&
412 node.callee.object.property.name.startsWith('_') &&
413 node.callee.property.type === 'Identifier'
414 ) {
415 const field = node.callee.object.property.name
416 const method = node.callee.property.name
417 if (!delegateCalls.has(field)) delegateCalls.set(field, new Set())
418 delegateCalls.get(field).add(method)
419 }
420 })
421
422 result.state = Array.from(stateFields)
423 result.errorContracts = errors
424
425 for (const [field, methods] of delegateCalls) {
426 result.delegates.push({
427 field,
428 methods: Array.from(methods)
429 })
430 }
431}
432
433// --- Helpers ---
434
435function extractParams (params) {
436 return params.map(paramToString)
437}
438
439function paramToString (param) {
440 switch (param.type) {
441 case 'Identifier':
442 return param.name
443 case 'AssignmentPattern':
444 return paramToString(param.left)
445 case 'RestElement':
446 return '...' + paramToString(param.argument)
447 case 'ObjectPattern':
448 return '{ ' + param.properties.map(p => {
449 if (p.type === 'RestElement') return '...' + paramToString(p.argument)
450 return p.key.name || p.key.value || '(computed)'
451 }).join(', ') + ' }'
452 case 'ArrayPattern':
453 return '[' + param.elements.map(e => e ? paramToString(e) : '').join(', ') + ']'
454 default:
455 return '(?)'
456 }
457}
458
459function nodeToString (node) {
460 if (node.type === 'Identifier') return node.name
461 if (node.type === 'MemberExpression') {
462 return nodeToString(node.object) + '.' + (node.property.name || node.property.value)
463 }
464 return '(?)'
465}
466
467function templateToPattern (node) {
468 let out = ''
469 for (let i = 0; i < node.quasis.length; i++) {
470 out += node.quasis[i].value.raw
471 if (i < node.expressions.length) {
472 out += '${...}'
473 }
474 }
475 return out
476}
477
478function walk (node, fn) {
479 if (!node || typeof node !== 'object') return
480 fn(node)
481 for (const key of Object.keys(node)) {
482 const val = node[key]
483 if (Array.isArray(val)) {
484 for (const child of val) {
485 if (child && typeof child.type === 'string') walk(child, fn)
486 }
487 } else if (val && typeof val.type === 'string') {
488 walk(val, fn)
489 }
490 }
491}
lib/reducers/metrics-reducer.js +110 -0
……@@ -0,0 +1,110 @@
1/**
2 * MetricsReducer — subscribes to scan-stream events and records counts + timing
3 * derived purely from event timestamps at boundaries. No setInterval, no sampling.
4 *
5 * Attach alongside TreeReducer to profile a scan without touching the scan code.
6 */
7export class MetricsReducer {
8 constructor () {
9 this.scanStart = null
10 this.scanEnd = null
11 this.moduleCount = 0
12 this.fileCount = 0
13 this.parseCount = 0
14 this.parseErrors = 0
15 this.importEdges = 0
16 this.implicitEdges = 0
17 this.moduleTimings = [] // [{ name, startedAt, endedAt, duration }]
18 this._currentModule = null
19 this.bytesRead = 0
20 this.largestFile = { path: null, size: 0 }
21 this.filesByExt = {} // ext -> count
22 this.parseTimeTotal = 0 // sum of time between file-discovered and file-parsed for the SAME file
23 this._pendingParse = new Map() // relPath -> discoveredAt
24 this.parseDurations = [] // per-file parse durations (ms) for percentiles
25 }
26
27 attach (emitter) {
28 emitter.on('scan-start', () => { this.scanStart = Date.now() })
29 emitter.on('module-start', e => {
30 this.moduleCount++
31 this._currentModule = { name: e.name, startedAt: Date.now() }
32 })
33 emitter.on('file-discovered', e => {
34 this.fileCount++
35 this.bytesRead += e.size
36 if (e.size > this.largestFile.size) {
37 this.largestFile = { path: e.relPath, size: e.size }
38 }
39 const dotIdx = e.relInPkg.lastIndexOf('.')
40 const ext = dotIdx > 0 ? e.relInPkg.slice(dotIdx) : '(none)'
41 this.filesByExt[ext] = (this.filesByExt[ext] || 0) + 1
42 this._pendingParse.set(e.relPath, Date.now())
43 })
44 emitter.on('file-parsed', e => {
45 this.parseCount++
46 if (e.parsed && e.parsed.error) this.parseErrors++
47 const startedAt = this._pendingParse.get(e.relPath)
48 if (startedAt) {
49 const dur = Date.now() - startedAt
50 this.parseTimeTotal += dur
51 this.parseDurations.push(dur)
52 this._pendingParse.delete(e.relPath)
53 }
54 })
55 emitter.on('import-edge', e => {
56 this.importEdges++
57 if (e.implicit) this.implicitEdges++
58 })
59 emitter.on('module-end', () => {
60 if (this._currentModule) {
61 const endedAt = Date.now()
62 this.moduleTimings.push({
63 name: this._currentModule.name,
64 startedAt: this._currentModule.startedAt,
65 endedAt,
66 duration: endedAt - this._currentModule.startedAt
67 })
68 this._currentModule = null
69 }
70 })
71 emitter.on('scan-end', () => { this.scanEnd = Date.now() })
72 return this
73 }
74
75 report () {
76 const duration = this.scanEnd - this.scanStart
77 const slowestModules = [...this.moduleTimings]
78 .sort((a, b) => b.duration - a.duration)
79 .slice(0, 5)
80
81 const sortedParses = [...this.parseDurations].sort((a, b) => a - b)
82 const p50 = sortedParses[Math.floor(sortedParses.length * 0.5)] || 0
83 const p95 = sortedParses[Math.floor(sortedParses.length * 0.95)] || 0
84 const p99 = sortedParses[Math.floor(sortedParses.length * 0.99)] || 0
85
86 const topExts = Object.entries(this.filesByExt)
87 .sort((a, b) => b[1] - a[1])
88 .slice(0, 10)
89
90 return {
91 totalDuration: duration,
92 moduleCount: this.moduleCount,
93 fileCount: this.fileCount,
94 parseCount: this.parseCount,
95 parseErrors: this.parseErrors,
96 importEdges: this.importEdges,
97 implicitEdges: this.implicitEdges,
98 bytesRead: this.bytesRead,
99 largestFile: this.largestFile,
100 parseTimeP50: p50,
101 parseTimeP95: p95,
102 parseTimeP99: p99,
103 parseTimeTotal: this.parseTimeTotal,
104 throughputFilesPerSec: (this.fileCount * 1000 / duration).toFixed(1),
105 throughputMBPerSec: ((this.bytesRead / 1024 / 1024) * 1000 / duration).toFixed(1),
106 slowestModules,
107 topExtensions: topExts
108 }
109 }
110}
lib/reducers/tree-reducer.js +109 -0
……@@ -0,0 +1,109 @@
1/**
2 * TreeReducer — subscribes to scan-stream events and builds the same graph
3 * structure that walkGraph() used to return synchronously.
4 *
5 * Stateful. Apply events in order. Call .finalize() after scan-end to get
6 * the same shape as before: { modules, files, root, dirTree, projectType,
7 * languages, resolutionContext }.
8 *
9 * Each reducer is a single subscriber — different reducers (doc-cruft,
10 * metrics, UI updaters) can listen to the same event source in parallel.
11 */
12export class TreeReducer {
13 constructor () {
14 this.root = null
15 this.projectType = null
16 this.languages = []
17 this.resolutionContext = null
18 this.modules = new Map() // modName -> mod
19 this.files = new Map() // rootRelPath -> fileInfo
20 this.dirTree = null
21 }
22
23 /** Attach this reducer to a scan-stream emitter. */
24 attach (emitter) {
25 emitter.on('scan-start', e => this.onScanStart(e))
26 emitter.on('module-start', e => this.onModuleStart(e))
27 emitter.on('file-discovered', e => this.onFileDiscovered(e))
28 emitter.on('file-parsed', e => this.onFileParsed(e))
29 emitter.on('import-edge', e => this.onImportEdge(e))
30 emitter.on('scan-end', e => this.onScanEnd(e))
31 return this
32 }
33
34 onScanStart (e) {
35 this.root = e.root
36 this.projectType = e.projectType
37 this.languages = e.languages
38 this.resolutionContext = e.resolutionContext
39 }
40
41 onModuleStart (e) {
42 this.modules.set(e.name, {
43 name: e.name,
44 version: e.version,
45 path: e.path,
46 absPath: e.absPath,
47 entry: e.entry,
48 dependencies: e.dependencies,
49 devDependencies: e.devDependencies,
50 importMaps: e.importMaps,
51 testCommand: e.testCommand,
52 type: e.type,
53 projectType: e.projectType,
54 files: new Map()
55 })
56 }
57
58 onFileDiscovered (e) {
59 // Intentionally NOT retaining e.source. That was the main memory leak that
60 // OOM'd recursive scans. Downstream consumers can re-read from absPath
61 // via /api/file if they actually need the bytes.
62 const fileInfo = {
63 absPath: e.absPath,
64 relPath: e.relPath,
65 relInPkg: e.relInPkg,
66 size: e.size,
67 localImports: [],
68 parsed: null // filled by onFileParsed
69 }
70 this.files.set(e.relPath, fileInfo)
71 const mod = this.modules.get(e.modName)
72 if (mod) mod.files.set(e.relInPkg, fileInfo)
73 }
74
75 onFileParsed (e) {
76 const mod = this.modules.get(e.modName)
77 if (!mod) return
78 const file = mod.files.get(e.relInPkg)
79 if (!file) return
80 file.parsed = e.parsed
81 }
82
83 onImportEdge (e) {
84 const mod = this.modules.get(e.modName)
85 if (!mod) return
86 const file = mod.files.get(e.fromRelInPkg)
87 if (!file) return
88 const edge = { specifier: e.specifier, resolved: e.resolvedRelPath }
89 if (e.implicit) edge.implicit = true
90 file.localImports.push(edge)
91 }
92
93 onScanEnd (e) {
94 this.dirTree = e.dirTree
95 }
96
97 /** Return the graph in the shape walkGraph() used to produce. */
98 finalize () {
99 return {
100 modules: this.modules,
101 files: this.files,
102 root: this.root,
103 dirTree: this.dirTree,
104 projectType: this.projectType,
105 languages: this.languages,
106 resolutionContext: this.resolutionContext
107 }
108 }
109}
lib/render.js +3525 -0
……@@ -0,0 +1,3525 @@
1export function renderPage (tree, prefix) {
2 const treeJSON = JSON.stringify(tree)
3 const apiPrefix = prefix || ''
4
5 return `<!DOCTYPE html>
6<html lang="en">
7<head>
8<meta charset="utf-8">
9<meta name="viewport" content="width=device-width, initial-scale=1">
10<title>codetree — ${tree.system.modules.length} modules</title>
11<style>
12* { margin: 0; padding: 0; box-sizing: border-box; }
13body {
14 font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
15 font-size: 13px;
16 line-height: 1.5;
17 background: #0d1117;
18 color: #c9d1d9;
19}
20#app { display: flex; height: 100vh; }
21
22/* Resizable panels */
23.panel {
24 overflow-y: auto;
25 flex-shrink: 0;
26 position: relative;
27 min-width: 100px;
28}
29.resize-handle {
30 width: 6px;
31 height: 100%;
32 cursor: col-resize;
33 z-index: 30;
34 background: #21262d;
35 flex-shrink: 0;
36 transition: background 0.15s;
37}
38.resize-handle:hover, .resize-handle.dragging {
39 background: #58a6ff;
40}
41
42#sidebar {
43 width: 340px;
44 border-right: 1px solid #21262d;
45 padding: 12px;
46 padding-right: 16px; /* extra space so scrollbar doesn't cover resize handle */
47 overflow-y: auto;
48 overflow-x: hidden;
49}
50#sidebar::-webkit-scrollbar { width: 6px; }
51#sidebar::-webkit-scrollbar-track { background: transparent; }
52#sidebar::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }
53#sidebar::-webkit-scrollbar-thumb:hover { background: #484f58; }
54#main {
55 flex: 1;
56 overflow-y: auto;
57 padding: 16px 24px;
58 position: relative;
59 min-width: 200px;
60}
61#right-panel {
62 width: 360px;
63 border-left: 1px solid #21262d;
64 padding: 12px;
65 padding-left: 16px;
66 overflow-y: auto;
67 overflow-x: hidden;
68 display: none;
69}
70#right-panel.active { display: block; }
71#right-panel::-webkit-scrollbar { width: 6px; }
72#right-panel::-webkit-scrollbar-track { background: transparent; }
73#right-panel::-webkit-scrollbar-thumb { background: #30363d; border-radius: 3px; }
74#right-panel::-webkit-scrollbar-thumb:hover { background: #484f58; }
75#right-panel h2 { font-size: 14px; color: #58a6ff; margin-bottom: 8px; }
76.val-summary {
77 display: flex; gap: 12px; margin-bottom: 12px; padding: 8px;
78 background: #161b22; border-radius: 6px; font-size: 12px;
79}
80.val-pass { color: #3fb950; }
81.val-fail { color: #ff7b72; }
82.val-warn { color: #d29922; }
83.val-count { font-weight: bold; font-size: 16px; display: block; }
84.val-check {
85 padding: 6px 8px;
86 margin: 2px 0;
87 border-radius: 4px;
88 font-size: 11px;
89 line-height: 1.4;
90 border-left: 3px solid transparent;
91}
92.val-check.pass { border-left-color: #3fb950; background: #0d1f12; }
93.val-check.fail { border-left-color: #ff7b72; background: #2d1014; }
94.val-check.warn { border-left-color: #d29922; background: #2d2200; }
95.val-check .val-claim { color: #c9d1d9; }
96.val-check .val-detail { color: #8b949e; font-size: 10px; margin-top: 2px; }
97.val-check .val-icon { margin-right: 4px; }
98.val-section { margin-top: 12px; }
99.val-section h3 {
100 font-size: 12px; color: #8b949e; margin-bottom: 4px;
101 text-transform: uppercase; letter-spacing: 0.5px;
102}
103.val-toggle {
104 font-size: 11px; color: #58a6ff; cursor: pointer; float: right;
105}
106.val-filter { display: flex; gap: 4px; margin-bottom: 8px; }
107.val-filter button {
108 font-size: 10px; padding: 2px 8px; border-radius: 4px; cursor: pointer;
109 font-family: inherit; border: 1px solid #30363d; background: #161b22; color: #8b949e;
110}
111.val-filter button.active { border-color: #58a6ff; color: #58a6ff; }
112
113/* File viewer */
114.file-viewer {
115 background: #0d1117;
116 border: 1px solid #21262d;
117 border-radius: 6px;
118 overflow: auto;
119 max-height: calc(100vh - 120px);
120 font-size: 12px;
121 line-height: 1.6;
122 margin-top: 8px;
123}
124#right-panel .file-viewer {
125 max-height: calc(100vh - 100px);
126}
127.file-viewer table { border-collapse: collapse; width: 100%; }
128.file-viewer tr:hover { background: #161b22; }
129.file-viewer tr.highlight { background: #1a2a3a; }
130.file-viewer tr.highlight .line-no { color: #00e5ff; }
131.file-viewer .line-no {
132 padding: 0 12px 0 8px;
133 text-align: right;
134 color: #484f58;
135 user-select: none;
136 vertical-align: top;
137 white-space: nowrap;
138 width: 1px;
139 border-right: 1px solid #21262d;
140}
141.file-viewer .line-code {
142 padding: 0 8px;
143 white-space: pre;
144 font-family: 'SF Mono', 'Fira Code', monospace;
145 color: #c9d1d9;
146}
147.file-viewer-header {
148 display: flex;
149 justify-content: space-between;
150 align-items: center;
151 padding: 6px 12px;
152 background: #161b22;
153 border-bottom: 1px solid #21262d;
154 border-radius: 6px 6px 0 0;
155 font-size: 12px;
156}
157.file-viewer-header .fv-path { color: #58a6ff; }
158.file-viewer-header .fv-info { color: #8b949e; }
159
160/* Syntax colors (basic) */
161.syn-kw { color: #ff7b72; }
162.syn-str { color: #a5d6ff; }
163.syn-num { color: #79c0ff; }
164.syn-cmt { color: #8b949e; font-style: italic; }
165.syn-fn { color: #d2a8ff; }
166.syn-cls { color: #ffa657; }
167h1 { font-size: 16px; color: #58a6ff; margin-bottom: 8px; }
168h2 { font-size: 14px; color: #8b949e; margin-bottom: 6px; font-weight: normal; }
169
170/* Tabs */
171.tabs {
172 display: flex;
173 gap: 2px;
174 margin-bottom: 10px;
175 border-bottom: 1px solid #21262d;
176 padding-bottom: 0;
177}
178.tab {
179 padding: 5px 14px;
180 cursor: pointer;
181 color: #8b949e;
182 border: 1px solid transparent;
183 border-bottom: none;
184 border-radius: 6px 6px 0 0;
185 font-family: inherit;
186 font-size: 12px;
187 background: none;
188}
189.tab:hover { color: #c9d1d9; }
190.tab.active {
191 color: #c9d1d9;
192 background: #161b22;
193 border-color: #21262d;
194 position: relative;
195}
196.tab.active::after {
197 content: '';
198 position: absolute;
199 bottom: -1px;
200 left: 0;
201 right: 0;
202 height: 1px;
203 background: #161b22;
204}
205.tab-content { display: none; }
206.tab-content.active { display: block; }
207
208.search {
209 width: 100%;
210 padding: 6px 10px;
211 background: #161b22;
212 border: 1px solid #30363d;
213 border-radius: 6px;
214 color: #c9d1d9;
215 font-family: inherit;
216 font-size: 13px;
217 margin-bottom: 12px;
218}
219.search:focus { outline: none; border-color: #58a6ff; }
220
221/* Tree */
222.tree { list-style: none; }
223.tree ul { list-style: none; padding-left: 16px; }
224.tree li { position: relative; }
225.tree-header {
226 display: flex;
227 align-items: center;
228 gap: 8px;
229 padding: 6px 8px;
230 border-bottom: 1px solid #21262d;
231 background: #161b22;
232 position: sticky;
233 top: 0;
234 z-index: 1;
235}
236.tree-header .tree-up {
237 background: #21262d;
238 border: 1px solid #30363d;
239 color: #c9d1d9;
240 cursor: pointer;
241 font-family: inherit;
242 font-size: 11px;
243 padding: 2px 8px;
244 border-radius: 3px;
245}
246.tree-header .tree-up:hover { background: #30363d; }
247.tree-header .tree-path {
248 color: #8b949e;
249 font-size: 11px;
250 white-space: nowrap;
251 overflow: hidden;
252 text-overflow: ellipsis;
253 flex: 1;
254}
255.node {
256 display: flex;
257 align-items: center;
258 padding: 2px 4px;
259 cursor: pointer;
260 border-radius: 4px;
261 gap: 6px;
262 white-space: nowrap;
263}
264.node:hover { background: #161b22; }
265.node.selected { background: #1f2937; }
266.toggle {
267 width: 14px; height: 14px;
268 display: inline-flex; align-items: center; justify-content: center;
269 color: #484f58; font-size: 10px; flex-shrink: 0;
270}
271.icon { width: 16px; text-align: center; flex-shrink: 0; }
272.name { color: #c9d1d9; }
273.badge {
274 font-size: 10px; padding: 0 5px; border-radius: 10px;
275 background: #21262d; color: #8b949e;
276}
277.collapsed > ul { display: none; }
278/* Validation badges on nodes */
279.val-badge {
280 font-size: 9px;
281 padding: 1px 5px;
282 border-radius: 4px;
283 margin-left: 3px;
284 font-weight: bold;
285}
286.val-badge-fail { background: #ff7b72; color: #0d1117; }
287.val-badge-warn { background: #d29922; color: #0d1117; }
288.val-badge-pass { background: #3fb950; color: #0d1117; }
289.val-badge-none { background: #21262d; color: #8b949e; }
290
291.node.selected-module {
292 background: #0a2a3a !important;
293 border: 1px solid #00e5ff;
294 margin: 1px 0;
295}
296.node.selected-module .name { color: #00e5ff !important; font-weight: bold; }
297.node.selected-module::after {
298 content: 'SELECTED';
299 font-size: 9px;
300 padding: 1px 5px;
301 border-radius: 4px;
302 background: #00e5ff;
303 color: #0d1117;
304 margin-left: 6px;
305 font-weight: bold;
306}
307.node.dep-highlight {
308 background: #1a3a0a !important;
309 border: 1px solid #39ff14;
310 margin: 1px 0;
311}
312.node.dep-highlight .name { color: #39ff14 !important; font-weight: bold; }
313.node.dep-highlight::after {
314 content: 'DEP';
315 font-size: 9px;
316 padding: 1px 5px;
317 border-radius: 4px;
318 background: #39ff14;
319 color: #0d1117;
320 margin-left: 6px;
321 font-weight: bold;
322}
323.node.used-by-highlight {
324 background: #3a3a0a !important;
325 border: 1px solid #ffff00;
326 margin: 1px 0;
327}
328.node.used-by-highlight .name { color: #ffff00 !important; font-weight: bold; }
329.node.used-by-highlight::after {
330 content: 'USES THIS';
331 font-size: 9px;
332 padding: 1px 5px;
333 border-radius: 4px;
334 background: #ffff00;
335 color: #0d1117;
336 margin-left: 6px;
337 font-weight: bold;
338}
339.icon-module { color: #f0883e; }
340.icon-file { color: #8b949e; }
341.icon-class { color: #d2a8ff; }
342.icon-method { color: #79c0ff; }
343.icon-getter { color: #7ee787; }
344.icon-function { color: #79c0ff; }
345.icon-const { color: #ffa657; }
346.icon-export { color: #3fb950; }
347
348/* Detail panel */
349.detail { margin-bottom: 16px; }
350.detail h3 {
351 font-size: 13px; color: #58a6ff; margin-bottom: 4px;
352 border-bottom: 1px solid #21262d; padding-bottom: 4px;
353}
354.detail pre {
355 background: #161b22; padding: 8px 12px; border-radius: 6px;
356 overflow-x: auto; margin: 4px 0 8px;
357}
358.detail code { font-family: inherit; }
359.tag {
360 display: inline-block; font-size: 11px; padding: 1px 6px;
361 border-radius: 4px; margin: 1px 2px;
362}
363.tag-async { background: #1f3a2d; color: #7ee787; }
364.tag-static { background: #2d1f3a; color: #d2a8ff; }
365.tag-generator { background: #3a2d1f; color: #ffa657; }
366.tag-arrow { background: #1f2d3a; color: #79c0ff; }
367.stats {
368 display: flex; gap: 16px; padding: 8px 0;
369 border-bottom: 1px solid #21262d; margin-bottom: 12px;
370 color: #8b949e; font-size: 12px;
371}
372.stat-value { color: #c9d1d9; font-weight: bold; }
373
374/* Graph */
375#graph-container {
376 position: absolute;
377 top: 0; left: 0; right: 0; bottom: 0;
378 display: none;
379 overflow: hidden;
380}
381#graph-container.active { display: block; }
382#graph-svg { width: 100%; height: 100%; cursor: grab; }
383#graph-svg.dragging { cursor: grabbing; }
384.graph-node { cursor: pointer; }
385.graph-node circle { transition: opacity 0.2s; }
386.graph-node.dimmed circle { opacity: 0.15; }
387.graph-node.dimmed text { opacity: 0.15; }
388.graph-node.focused circle { stroke: #f0883e; stroke-width: 3; filter: drop-shadow(0 0 6px rgba(240,136,62,0.5)); }
389.graph-node text {
390 font-family: 'SF Mono', monospace;
391 fill: #c9d1d9;
392 pointer-events: none;
393}
394.graph-edge { stroke: #30363d; stroke-width: 1.2; fill: none; marker-end: url(#arrowhead); }
395.graph-edge.dimmed { stroke: #161b22; stroke-width: 0.5; }
396.graph-edge.dep-of { stroke: #58a6ff; stroke-width: 2; }
397.graph-edge.depends-on { stroke: #3fb950; stroke-width: 2; }
398.graph-legend {
399 position: absolute;
400 bottom: 12px; left: 12px;
401 background: #161b22;
402 border: 1px solid #30363d;
403 border-radius: 6px;
404 padding: 8px 12px;
405 font-size: 11px;
406 color: #8b949e;
407 pointer-events: none;
408}
409.graph-legend .leg-item { display: flex; align-items: center; gap: 6px; padding: 2px 0; }
410.graph-legend .leg-line { width: 20px; height: 2px; display: inline-block; }
411.graph-controls {
412 position: absolute;
413 top: 12px; right: 12px;
414 display: flex; gap: 4px;
415}
416.graph-controls button {
417 background: #161b22; border: 1px solid #30363d; border-radius: 4px;
418 color: #c9d1d9; font-size: 14px; width: 28px; height: 28px;
419 cursor: pointer; font-family: inherit; display: flex; align-items: center; justify-content: center;
420}
421.graph-controls button:hover { background: #21262d; }
422.graph-tooltip {
423 position: absolute;
424 background: #161b22;
425 border: 1px solid #30363d;
426 border-radius: 6px;
427 padding: 8px 12px;
428 font-size: 12px;
429 pointer-events: none;
430 display: none;
431 z-index: 10;
432 max-width: 320px;
433 line-height: 1.6;
434}
435.graph-tooltip .tt-deps { color: #58a6ff; }
436.graph-tooltip .tt-used { color: #3fb950; }
437
438/* Graph settings panel */
439.graph-settings {
440 position: absolute;
441 bottom: 12px; right: 12px;
442 background: #161b22;
443 border: 1px solid #30363d;
444 border-radius: 6px;
445 padding: 10px 14px;
446 font-size: 11px;
447 color: #8b949e;
448 z-index: 5;
449 max-width: 240px;
450}
451.graph-settings h4 { color: #c9d1d9; margin-bottom: 6px; font-size: 11px; }
452.gs-row {
453 display: flex; align-items: center; gap: 6px;
454 padding: 3px 0;
455}
456.gs-row label { flex: 1; cursor: pointer; }
457.gs-row select, .gs-row input[type=range] {
458 background: #0d1117; border: 1px solid #30363d; border-radius: 3px;
459 color: #c9d1d9; font-size: 10px; padding: 2px 4px; font-family: inherit;
460}
461.gs-row select { width: 100px; }
462.gs-row input[type=range] { width: 80px; accent-color: #58a6ff; }
463.gs-row input[type=checkbox] { accent-color: #58a6ff; }
464.gs-divider { border-top: 1px solid #21262d; margin: 6px 0; }
465
466/* Category regions */
467.graph-region {
468 fill-opacity: 0.12;
469 stroke-opacity: 0.5;
470 stroke-width: 2;
471}
472.graph-region-label {
473 font-size: 14px;
474 fill-opacity: 0.9;
475 font-weight: bold;
476 pointer-events: none;
477 text-shadow: 0 0 8px #0d1117, 0 0 16px #0d1117;
478}
479
480/* Edge labels on hover */
481.edge-hover-label {
482 font-size: 9px;
483 fill: #58a6ff;
484 pointer-events: none;
485 display: none;
486}
487.edge-hover-label.visible { display: block; }
488.graph-breadcrumb {
489 position: absolute;
490 top: 12px; left: 12px;
491 display: flex; gap: 4px; align-items: center;
492 font-size: 13px; z-index: 5;
493}
494.graph-breadcrumb span {
495 color: #8b949e; cursor: pointer; padding: 4px 8px;
496 background: #161b22; border: 1px solid #30363d; border-radius: 4px;
497}
498.graph-breadcrumb span:hover { color: #c9d1d9; border-color: #58a6ff; }
499.graph-breadcrumb span.current { color: #00e5ff; border-color: #00e5ff; cursor: default; }
500.graph-breadcrumb .sep { background: none; border: none; color: #484f58; cursor: default; padding: 0; }
501</style>
502</head>
503<body>
504<div id="app">
505 <div id="sidebar" class="panel">
506 <h1 style="display:flex;justify-content:space-between;align-items:center">codetree</h1>
507 <div class="tabs">
508 <button class="tab main-tab active" data-tab="tree">Tree</button>
509 <button class="tab main-tab" data-tab="graph">Graph</button>
510 <button class="tab main-tab" data-tab="validate">Validate</button>
511 </div>
512 <input class="search" id="search" type="text" placeholder="Filter modules, files, symbols...">
513 <div style="display:flex;gap:4px;margin-bottom:8px">
514 <button style="background:#161b22;border:1px solid #30363d;border-radius:4px;color:#8b949e;font-size:10px;padding:2px 8px;cursor:pointer;font-family:inherit" onclick="expandAll()">Expand All</button>
515 <button style="background:#161b22;border:1px solid #30363d;border-radius:4px;color:#8b949e;font-size:10px;padding:2px 8px;cursor:pointer;font-family:inherit" onclick="collapseAll()">Collapse All</button>
516 </div>
517 <div id="tree-root"></div>
518 </div>
519 <div id="resize-left" class="resize-handle"></div>
520 <div id="main">
521 <div id="detail">
522 <div class="stats" id="stats"></div>
523 <div id="detail-content">
524 <h2>Select a node to view details</h2>
525 </div>
526 </div>
527 <div id="graph-container">
528 <svg id="graph-svg">
529 <defs>
530 <marker id="arrowhead" viewBox="0 0 10 7" refX="10" refY="3.5"
531 markerWidth="8" markerHeight="6" orient="auto-start-reverse">
532 <polygon points="0 0, 10 3.5, 0 7" fill="#30363d" />
533 </marker>
534 <marker id="arrowhead-blue" viewBox="0 0 10 7" refX="10" refY="3.5"
535 markerWidth="8" markerHeight="6" orient="auto-start-reverse">
536 <polygon points="0 0, 10 3.5, 0 7" fill="#58a6ff" />
537 </marker>
538 <marker id="arrowhead-green" viewBox="0 0 10 7" refX="10" refY="3.5"
539 markerWidth="8" markerHeight="6" orient="auto-start-reverse">
540 <polygon points="0 0, 10 3.5, 0 7" fill="#3fb950" />
541 </marker>
542 </defs>
543 </svg>
544 <div class="graph-breadcrumb" id="graph-breadcrumb"></div>
545 <div class="graph-controls">
546 <button id="zoom-in" title="Zoom in">+</button>
547 <button id="zoom-out" title="Zoom out">-</button>
548 <button id="zoom-reset" title="Reset view">R</button>
549 </div>
550 <div class="graph-legend">
551 <div class="leg-item"><span class="leg-line" style="background:#58a6ff"></span> depends on (selected)</div>
552 <div class="leg-item"><span class="leg-line" style="background:#3fb950"></span> used by (selected)</div>
553 <div class="leg-item"><span class="leg-line" style="background:#30363d"></span> other dependency</div>
554 <div style="margin-top:4px; font-size:10px">Click to focus. Double-click to drill in. Scroll to zoom. Drag to pan.</div>
555 </div>
556 <div class="graph-tooltip" id="graph-tooltip"></div>
557 </div>
558 </div>
559 <div id="resize-right" class="resize-handle" style="display:none"></div>
560 <div id="right-panel" class="panel" style="width:360px;border-left:1px solid #21262d;display:none;overflow-y:auto;padding:12px 12px 12px 16px">
561 <div id="right-panel-tabs" style="display:flex;gap:2px;margin-bottom:8px;border-bottom:1px solid #21262d">
562 <button class="tab active" data-rp="structure" onclick="switchRightPanel(&quot;structure&quot;)">Structure</button>
563 <button class="tab" data-rp="validation" onclick="switchRightPanel(&quot;validation&quot;)">Validation</button>
564 <button class="tab" data-rp="docs" onclick="switchRightPanel(&quot;docs&quot;)">Docs</button>
565 </div>
566 <div id="rp-structure" style="display:block">
567 <div id="structure-content"><h2 style="color:#8b949e">Select a file to see structure</h2></div>
568 </div>
569 <div id="rp-validation" style="display:none">
570 <div id="val-content">No validation data.</div>
571 </div>
572 <div id="rp-docs" style="display:none">
573 <div id="docs-content"><h2 style="color:#8b949e">No spec file for this module</h2></div>
574 </div>
575 </div>
576</div>
577
578<script>
579const tree = ${treeJSON};
580const API = '${apiPrefix}';
581let currentTab = 'tree'
582
583// ====== TAB SWITCHING ======
584document.querySelectorAll('.main-tab').forEach(tab => {
585 tab.addEventListener('click', () => {
586 document.querySelectorAll('.main-tab').forEach(t => t.classList.remove('active'))
587 tab.classList.add('active')
588 currentTab = tab.dataset.tab
589
590 const detail = document.getElementById('detail')
591 const graphContainer = document.getElementById('graph-container')
592 const valPanel = document.getElementById('right-panel')
593
594 // In graph mode, hide the detail/file-viewer panel — right panel handles everything
595 detail.style.display = currentTab === 'graph' ? 'none' : ''
596 graphContainer.classList.toggle('active', currentTab === 'graph')
597
598 const rightPanel = document.getElementById('right-panel')
599 const resizeRight = document.getElementById('resize-right')
600 if (currentTab === 'validate') {
601 // Validate tab = open right panel with validation, keep current center view
602 rightPanel.style.display = 'block'
603 resizeRight.style.display = ''
604 if (!valInitialized) initValidation()
605 switchRightPanel('validation')
606 // Don't change center content — revert to previous tab's center
607 detail.style.display = ''
608 graphContainer.classList.remove('active')
609 } else if (currentTab === 'graph') {
610 if (!graphInitialized) { initGraph(); updateBreadcrumb() }
611 }
612 })
613})
614
615// ====== TREE VIEW (File Manager) ======
616//
617// Flat current-path view. Mirrors the graph: shows ONLY what's at the current
618// location. Click a directory → descend; click a module → focus + show
619// details panel. Stays in sync with the graph (rebuildGraph calls buildTree).
620//
621// The previous implementation built a full nested DOM for every module + every
622// file at page load, which made monorepo-scale scans crawl. This avoids that
623// entirely — at any moment we only have N items in the DOM where N is the
624// number of children at the current path (typically 5-50).
625let selectedTreeNode = null
626
627function buildTree () {
628 const root = document.getElementById('tree-root')
629 root.innerHTML = ''
630
631 if (!tree.dirTree) {
632 // No dirTree (e.g. very small scan with no children) — fallback to flat module list.
633 const ul = el('ul', { className: 'tree' })
634 for (const name of tree.system.modules) {
635 ul.appendChild(buildModuleNode(name, tree.modules[name]))
636 }
637 root.appendChild(ul)
638 updateStats()
639 return
640 }
641
642 const path = (typeof getCurrentPath === 'function') ? getCurrentPath() : ''
643 const items = (typeof getNodesAtPath === 'function')
644 ? getNodesAtPath(path)
645 : tree.dirTree.children.filter(c => c.type !== 'file').map(c => ({
646 name: c.module || c.name,
647 type: c.module ? 'module' : 'dir',
648 dirEntry: c,
649 mod: c.module ? tree.modules[c.module] : null
650 }))
651
652 // Header: up button + path
653 const header = el('div', { className: 'tree-header' })
654 if (path) {
655 const upBtn = el('button', { className: 'tree-up', textContent: '↑ ..', title: 'Go up' })
656 upBtn.addEventListener('click', () => navigateGraph(graphStack.length - 1))
657 header.appendChild(upBtn)
658 }
659 const pathLabel = el('div', { className: 'tree-path' })
660 pathLabel.textContent = path ? '/' + path : '/'
661 header.appendChild(pathLabel)
662 root.appendChild(header)
663
664 // Flat list of items at this path
665 const ul = el('ul', { className: 'tree' })
666 for (const item of items) {
667 ul.appendChild(buildPathItemNode(item))
668 }
669 root.appendChild(ul)
670 updateStats()
671
672 // Click background to deselect
673 root.addEventListener('click', (e) => {
674 if (e.target === root || e.target === ul) deselectAll()
675 })
676}
677
678function buildPathItemNode (item) {
679 const li = el('li')
680 const node = el('div', { className: 'node', 'data-type': item.type, 'data-name': item.name })
681
682 if (item.type === 'dir') {
683 node.innerHTML = '<span class="icon" style="color:#8b949e">D</span>' +
684 '<span class="name" style="color:#8b949e">' + item.name + '/</span>' +
685 '<span class="badge">' + (item.packageCount || 0) + ' pkg</span>'
686 node.addEventListener('click', (e) => {
687 e.stopPropagation()
688 descendIntoDir(item.name)
689 })
690 } else {
691 const mod = item.mod
692 const fileCount = mod ? Object.keys(mod.files).length : 0
693 node.innerHTML = '<span class="icon icon-module">M</span>' +
694 '<span class="name">' + item.name + '</span>' +
695 '<span class="badge">' + (mod ? mod.version : '?') + '</span>' +
696 '<span class="badge">' + fileCount + ' files</span>' +
697 (mod ? '<span class="badge">' + mod.publicAPI.length + ' exports</span>' : '') +
698 valBadgeHTML(item.name)
699 node.addEventListener('click', (e) => {
700 e.stopPropagation()
701 if (mod) selectModule(item.name, mod, node)
702 })
703 }
704
705 li.appendChild(node)
706 return li
707}
708
709function deselectAll () {
710 if (selectedTreeNode) {
711 selectedTreeNode.classList.remove('selected-module')
712 }
713 selectedTreeNode = null
714 document.querySelectorAll('.dep-highlight, .used-by-highlight, .selected-module').forEach(el => {
715 el.classList.remove('dep-highlight', 'used-by-highlight', 'selected-module')
716 })
717 document.getElementById('detail-content').innerHTML = '<h2>Select a node to view details</h2>'
718 document.getElementById('right-panel').style.display = 'none'
719 document.getElementById('resize-right').style.display = 'none'
720}
721
722function buildDirNode (dirEntry) {
723 // Is this a module directory?
724 if (dirEntry.module && tree.modules[dirEntry.module]) {
725 return buildModuleNode(dirEntry.module, tree.modules[dirEntry.module], dirEntry)
726 }
727
728 // Plain directory
729 const li = el('li', { className: 'collapsed' })
730 const hasChildren = dirEntry.children && dirEntry.children.length > 0
731 const node = el('div', { className: 'node', 'data-type': 'dir', 'data-name': dirEntry.name })
732 node.innerHTML = '<span class="toggle">' + (hasChildren ? '+' : ' ') + '</span>' +
733 '<span class="icon" style="color:#8b949e">D</span>' +
734 '<span class="name" style="color:#8b949e">' + dirEntry.name + '/</span>'
735 li.appendChild(node)
736
737 // Lazy child population: build the child DOM only on first expansion. For a
738 // recursive monorepo scan this avoids creating tens of thousands of DOM
739 // elements at page load (the reason the page was sluggish).
740 let childrenBuilt = false
741 function buildChildrenIfNeeded () {
742 if (childrenBuilt || !hasChildren) return
743 childrenBuilt = true
744 const childUl = el('ul')
745 for (const child of dirEntry.children) {
746 if (child.type === 'dir' || child.type === 'module-dir') {
747 childUl.appendChild(buildDirNode(child))
748 }
749 }
750 for (const child of dirEntry.children) {
751 if (child.type === 'file') {
752 childUl.appendChild(buildFileNode(child.path, child, null))
753 }
754 }
755 li.appendChild(childUl)
756 }
757
758 node.addEventListener('click', (e) => {
759 e.stopPropagation()
760 if (!hasChildren) return
761 if (li.classList.contains('collapsed')) {
762 buildChildrenIfNeeded() // build on first expand
763 li.classList.remove('collapsed')
764 node.querySelector('.toggle').textContent = '-'
765 } else {
766 li.classList.add('collapsed')
767 node.querySelector('.toggle').textContent = '+'
768 }
769 })
770
771 return li
772}
773
774function buildModuleNode (name, mod, dirEntry) {
775 const li = el('li', { className: 'collapsed' })
776 const fileCount = Object.keys(mod.files).length
777 const node = el('div', { className: 'node', 'data-type': 'module', 'data-name': name })
778 node.innerHTML = '<span class="toggle">+</span><span class="icon icon-module">M</span>' +
779 '<span class="name">' + name + '</span>' +
780 '<span class="badge">' + mod.version + '</span>' +
781 '<span class="badge">' + fileCount + ' files</span>' +
782 '<span class="badge">' + mod.publicAPI.length + ' exports</span>' +
783 valBadgeHTML(name)
784 li.appendChild(node)
785
786 const childUl = el('ul')
787
788 // Merge non-JS files from dirTree into file list
789 const allFiles = Object.assign({}, mod.files)
790 if (dirEntry && dirEntry.children) {
791 addDirTreeFiles(dirEntry, '', allFiles)
792 }
793
794 // Show files grouped by directory structure within the module
795 const byDir = groupFilesByDir(allFiles)
796 for (const [dir, files] of byDir) {
797 if (dir === '.') {
798 // Root-level files
799 for (const [path, file] of files) {
800 childUl.appendChild(buildFileNode(path, file, name))
801 }
802 } else {
803 // Subdirectory
804 const dirLi = el('li', { className: 'collapsed' })
805 const dirNode = el('div', { className: 'node', 'data-type': 'dir' })
806 dirNode.innerHTML = '<span class="toggle">+</span>' +
807 '<span class="icon" style="color:#8b949e">D</span>' +
808 '<span class="name" style="color:#8b949e">' + dir + '/</span>' +
809 '<span class="badge">' + files.length + '</span>'
810 dirLi.appendChild(dirNode)
811
812 const subUl = el('ul')
813 for (const [path, file] of files) {
814 subUl.appendChild(buildFileNode(path, file, name))
815 }
816 dirLi.appendChild(subUl)
817
818 dirNode.addEventListener('click', (e) => {
819 e.stopPropagation()
820 dirLi.classList.toggle('collapsed')
821 dirNode.querySelector('.toggle').textContent = dirLi.classList.contains('collapsed') ? '+' : '-'
822 })
823
824 childUl.appendChild(dirLi)
825 }
826 }
827
828 li.appendChild(childUl)
829 node.addEventListener('click', (e) => {
830 e.stopPropagation()
831 if (selectedTreeNode === node) {
832 // Second click: deselect + collapse
833 deselectAll()
834 li.classList.add('collapsed')
835 node.querySelector('.toggle').textContent = '+'
836 } else {
837 // First click: select + expand
838 li.classList.remove('collapsed')
839 node.querySelector('.toggle').textContent = '-'
840 selectModule(name, mod, node)
841 }
842 })
843 return li
844}
845
846function selectModule (name, mod, nodeEl) {
847 deselectAll()
848 selectedTreeNode = nodeEl
849 nodeEl.classList.add('selected-module')
850 showDetail('module', { name, mod })
851 highlightTreeDeps(name)
852 showValidationForModule(name)
853}
854
855function addDirTreeFiles (dirNode, prefix, allFiles) {
856 if (!dirNode.children) return
857 for (const child of dirNode.children) {
858 if (child.type === 'file') {
859 const key = prefix ? prefix + '/' + child.name : child.name
860 if (!allFiles[key]) {
861 allFiles[key] = { name: child.name, ext: child.ext, size: child.size, role: null }
862 }
863 } else if (child.type === 'dir' && !['node_modules', '.git', 'vendor'].includes(child.name)) {
864 const subPrefix = prefix ? prefix + '/' + child.name : child.name
865 addDirTreeFiles(child, subPrefix, allFiles)
866 }
867 }
868}
869
870function groupFilesByDir (files) {
871 const dirs = new Map()
872 const entries = Object.entries(files).sort(([a], [b]) => a.localeCompare(b))
873
874 for (const [path, file] of entries) {
875 const parts = path.split('/')
876 const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : '.'
877 if (!dirs.has(dir)) dirs.set(dir, [])
878 dirs.get(dir).push([path, file])
879 }
880
881 // Sort: root first, then alphabetical
882 const sorted = new Map()
883 if (dirs.has('.')) sorted.set('.', dirs.get('.'))
884 for (const [dir, files] of [...dirs].sort(([a], [b]) => a.localeCompare(b))) {
885 if (dir !== '.') sorted.set(dir, files)
886 }
887 return sorted
888}
889
890function buildFileNode (path, file, moduleName) {
891 const li = el('li', { className: 'collapsed' })
892 const fileName = path.includes('/') ? path.split('/').pop() : path
893
894 // file might be a parsed JS file (with classes/functions) or a raw dirTree file entry
895 const isParsed = file.exports || file.classes || file.functions || file.signals || file.uniforms || file.buffers
896 const hasChildren = isParsed && ((file.classes && file.classes.length > 0) || (file.functions && file.functions.length > 0) || (file.signals && file.signals.length > 0))
897
898 const counts = []
899 if (file.classes) counts.push(file.classes.length + ' cls')
900 if (file.functions) counts.push(file.functions.length + ' fn')
901
902 const ext = fileName.includes('.') ? fileName.split('.').pop() : ''
903 const icon = fileIcon(ext, file.role)
904
905 const node = el('div', { className: 'node', 'data-type': 'file', 'data-name': path })
906 node.innerHTML = '<span class="toggle">' + (hasChildren ? '+' : ' ') + '</span>' +
907 '<span class="icon" style="color:' + icon.color + '">' + icon.char + '</span>' +
908 '<span class="name">' + fileName + '</span>' +
909 (counts.length ? '<span class="badge">' + counts.join(', ') + '</span>' : '') +
910 (file.size ? '<span class="badge" style="color:#484f58">' + formatSize(file.size) + '</span>' : '')
911 li.appendChild(node)
912
913 if (hasChildren) {
914 const childUl = el('ul')
915 if (file.classes) for (const cls of file.classes) childUl.appendChild(buildClassNode(cls))
916 if (file.functions) for (const fn of file.functions) childUl.appendChild(buildFunctionNode(fn))
917 li.appendChild(childUl)
918 }
919
920 node.addEventListener('click', (e) => {
921 e.stopPropagation()
922 if (hasChildren) {
923 li.classList.toggle('collapsed')
924 node.querySelector('.toggle').textContent = li.classList.contains('collapsed') ? '+' : '-'
925 }
926 currentFileContext = { path, moduleName }
927 const modPath = moduleName ? tree.modules[moduleName].path + '/' : ''
928 loadFileViewer(modPath + path, moduleName)
929 if (isParsed) showStructurePanel(path, file, moduleName)
930 })
931 return li
932}
933
934function fileIcon (ext, role) {
935 const icons = {
936 js: { char: 'JS', color: '#f0db4f' },
937 mjs: { char: 'JS', color: '#f0db4f' },
938 cjs: { char: 'CJ', color: '#f0db4f' },
939 json: { char: '{}', color: '#8b949e' },
940 md: { char: 'MD', color: '#58a6ff' },
941 yml: { char: 'YM', color: '#ff7b72' },
942 yaml: { char: 'YM', color: '#ff7b72' },
943 toml: { char: 'TM', color: '#ffa657' },
944 sh: { char: 'SH', color: '#3fb950' },
945 c: { char: 'C', color: '#79c0ff' },
946 h: { char: 'H', color: '#79c0ff' },
947 txt: { char: 'TX', color: '#8b949e' },
948 lock: { char: 'LK', color: '#484f58' },
949 css: { char: 'CS', color: '#d2a8ff' },
950 html: { char: 'HT', color: '#f0883e' }
951 }
952 if (role === 'entry') return { char: 'E', color: '#f0883e' }
953 return icons[ext] || { char: ext.slice(0, 2).toUpperCase() || 'F', color: '#484f58' }
954}
955
956function formatSize (bytes) {
957 if (bytes < 1024) return bytes + 'B'
958 if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + 'KB'
959 return (bytes / 1024 / 1024).toFixed(1) + 'MB'
960}
961
962// Track current file context for source viewing
963let currentFileContext = null // { path, moduleName }
964
965function buildClassNode (cls) {
966 const li = el('li', { className: 'collapsed' })
967 const memberCount = (cls.methods ? cls.methods.length : 0) + (cls.getters ? cls.getters.length : 0)
968 const node = el('div', { className: 'node', 'data-type': 'class', 'data-name': cls.name })
969 node.innerHTML = '<span class="toggle">' + (memberCount > 0 ? '+' : ' ') + '</span>' +
970 '<span class="icon icon-class">C</span>' +
971 '<span class="name">' + cls.name + '</span>' +
972 (cls.extends ? '<span class="badge">extends ' + cls.extends + '</span>' : '') +
973 '<span class="badge">' + memberCount + ' members</span>'
974 li.appendChild(node)
975
976 if (memberCount > 0) {
977 const childUl = el('ul')
978 if (cls.constructor) {
979 const cLi = el('li')
980 const cNode = el('div', { className: 'node' })
981 cNode.innerHTML = '<span class="toggle"> </span><span class="icon icon-method">f</span>' +
982 '<span class="name">constructor(' + cls.constructor.params.join(', ') + ')</span>'
983 cNode.addEventListener('click', (e) => {
984 e.stopPropagation()
985 if (currentFileContext && cls.constructor.line) {
986 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
987 loadFileViewer(modPath + currentFileContext.path, currentFileContext.moduleName, cls.constructor.line)
988 } else {
989 showDetail('constructor', { cls, constructor: cls.constructor })
990 }
991 })
992 cLi.appendChild(cNode)
993 childUl.appendChild(cLi)
994 }
995 if (cls.getters) for (const g of cls.getters) {
996 const gLi = el('li')
997 const gNode = el('div', { className: 'node' })
998 gNode.innerHTML = '<span class="toggle"> </span><span class="icon icon-getter">g</span><span class="name">get ' + g.name + '</span>'
999 gLi.appendChild(gNode)
1000 childUl.appendChild(gLi)
1001 }
1002 if (cls.methods) for (const m of cls.methods) {
1003 if (m.kind === 'field') continue
1004 const mLi = el('li')
1005 const mNode = el('div', { className: 'node', 'data-name': m.name })
1006 const tags = (m.async ? '<span class="tag tag-async">async</span>' : '') +
1007 (m.generator ? '<span class="tag tag-generator">*</span>' : '')
1008 mNode.innerHTML = '<span class="toggle"> </span><span class="icon icon-method">f</span>' +
1009 '<span class="name">' + m.name + '(' + m.params.join(', ') + ')</span>' + tags
1010 mNode.addEventListener('click', (e) => {
1011 e.stopPropagation()
1012 if (currentFileContext && m.line) {
1013 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
1014 loadFileViewer(modPath + currentFileContext.path, currentFileContext.moduleName, m.line)
1015 } else {
1016 showDetail('method', { cls, method: m })
1017 }
1018 })
1019 mLi.appendChild(mNode)
1020 childUl.appendChild(mLi)
1021 }
1022 li.appendChild(childUl)
1023 }
1024
1025 node.addEventListener('click', (e) => {
1026 e.stopPropagation()
1027 if (memberCount > 0) {
1028 li.classList.toggle('collapsed')
1029 node.querySelector('.toggle').textContent = li.classList.contains('collapsed') ? '+' : '-'
1030 }
1031 if (currentFileContext && cls.line) {
1032 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
1033 loadFileViewer(modPath + currentFileContext.path, currentFileContext.moduleName, cls.line)
1034 } else {
1035 showDetail('class', { cls })
1036 }
1037 })
1038 return li
1039}
1040
1041function buildFunctionNode (fn) {
1042 const li = el('li')
1043 const tags = (fn.async ? '<span class="tag tag-async">async</span>' : '') +
1044 (fn.arrow ? '<span class="tag tag-arrow">=&gt;</span>' : '')
1045 const node = el('div', { className: 'node', 'data-name': fn.name })
1046 node.innerHTML = '<span class="toggle"> </span><span class="icon icon-function">f</span>' +
1047 '<span class="name">' + fn.name + '(' + fn.params.join(', ') + ')</span>' + tags
1048 node.addEventListener('click', (e) => {
1049 e.stopPropagation()
1050 if (currentFileContext && fn.line) {
1051 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
1052 loadFileViewer(modPath + currentFileContext.path, currentFileContext.moduleName, fn.line)
1053 } else {
1054 showDetail('function', { fn })
1055 }
1056 })
1057 li.appendChild(node)
1058 return li
1059}
1060
1061// ====== DETAIL PANEL ======
1062function showDetail (type, data) {
1063 const panel = document.getElementById('detail-content')
1064 let html = ''
1065 switch (type) {
1066 case 'module': {
1067 const { name, mod } = data
1068 html = '<h2>' + name + '@' + mod.version + '</h2>'
1069 html += '<div class="detail"><h3>Public API</h3><pre><code>' + (mod.publicAPI.join('\\n') || '(none)') + '</code></pre></div>'
1070 html += '<div class="detail"><h3>Dependencies</h3><pre><code>' + (Object.entries(mod.dependencies).map(([k,v]) => k + ': ' + v).join('\\n') || '(none)') + '</code></pre></div>'
1071 if (mod.importMaps && Object.keys(mod.importMaps).length > 0) {
1072 html += '<div class="detail"><h3>Import Maps</h3><pre><code>' + JSON.stringify(mod.importMaps, null, 2) + '</code></pre></div>'
1073 }
1074 if (mod.testCommand) html += '<div class="detail"><h3>Test</h3><pre><code>' + mod.testCommand + '</code></pre></div>'
1075 break
1076 }
1077 case 'file': {
1078 const { path, file, moduleName } = data
1079 const modPath = moduleName ? tree.modules[moduleName].path + '/' : ''
1080 html = '<h2>' + moduleName + '/' + path + '</h2><div class="badge">' + file.role + '</div>'
1081 html += ' <span class="badge" style="cursor:pointer;color:#58a6ff;border:1px solid #58a6ff" onclick="loadFileViewer(&quot;' + modPath + path + '&quot;,&quot;' + (moduleName||'') + '&quot;)">View Source</span>'
1082 if (file.imports && file.imports.length) html += '<div class="detail"><h3>Imports</h3><pre><code>' + file.imports.map(i => i.names.join(', ') + ' from ' + i.specifier).join('\\n') + '</code></pre></div>'
1083 if (file.exports && file.exports.length) html += '<div class="detail"><h3>Exports</h3><pre><code>' + file.exports.map(e => e.name + (e.type ? ' (' + e.type + ')' : '') + (e.from ? ' from ' + e.from : '')).join('\\n') + '</code></pre></div>'
1084 if (file.state && file.state.length) html += '<div class="detail"><h3>State</h3><pre><code>' + file.state.join('\\n') + '</code></pre></div>'
1085 if (file.delegates && file.delegates.length) html += '<div class="detail"><h3>Delegation</h3><pre><code>' + file.delegates.map(d => d.field + ' -> ' + d.methods.join(', ')).join('\\n') + '</code></pre></div>'
1086 if (file.errorContracts && file.errorContracts.length) html += '<div class="detail"><h3>Errors</h3><pre><code>' + file.errorContracts.join('\\n') + '</code></pre></div>'
1087 break
1088 }
1089 case 'class': {
1090 const { cls } = data
1091 html = '<h2>class ' + cls.name + (cls.extends ? ' extends ' + cls.extends : '') + '</h2>'
1092 html += sourceLink(cls.line)
1093 if (cls.jsdoc) html += '<div class="detail"><h3>JSDoc</h3><pre><code>' + escapeHtml(cls.jsdoc) + '</code></pre></div>'
1094 if (cls.constructor) html += '<div class="detail"><h3>Constructor</h3><pre><code>constructor(' + cls.constructor.params.join(', ') + ')</code></pre></div>'
1095 html += '<div class="detail"><h3>Methods (' + cls.methods.length + ')</h3><pre><code>' + cls.methods.filter(m => m.kind !== 'field').map(m => (m.async ? 'async ' : '') + m.name + '(' + m.params.join(', ') + ')' + (m.line ? ' :' + m.line : '')).join('\\n') + '</code></pre></div>'
1096 if (cls.getters && cls.getters.length) html += '<div class="detail"><h3>Getters (' + cls.getters.length + ')</h3><pre><code>' + cls.getters.map(g => 'get ' + g.name + (g.line ? ' :' + g.line : '')).join('\\n') + '</code></pre></div>'
1097 break
1098 }
1099 case 'method': case 'constructor': {
1100 const m = data.method || data.constructor
1101 const label = data.method ? data.method.name : 'constructor'
1102 html = '<h2>' + data.cls.name + '.' + label + '</h2>'
1103 html += sourceLink(m.line)
1104 html += '<pre><code>' + (m.async ? 'async ' : '') + label + '(' + m.params.join(', ') + ')</code></pre>'
1105 if (m.jsdoc) html += '<div class="detail"><h3>JSDoc</h3><pre><code>' + escapeHtml(m.jsdoc) + '</code></pre></div>'
1106 break
1107 }
1108 case 'function': {
1109 const { fn } = data
1110 html = '<h2>' + fn.name + '</h2>'
1111 html += sourceLink(fn.line)
1112 html += '<pre><code>' + (fn.async ? 'async ' : '') + fn.name + '(' + fn.params.join(', ') + ')</code></pre>'
1113 if (fn.jsdoc) html += '<div class="detail"><h3>JSDoc</h3><pre><code>' + escapeHtml(fn.jsdoc) + '</code></pre></div>'
1114 break
1115 }
1116 case 'rawFile': {
1117 const { path, file } = data
1118 const ext = path.includes('.') ? path.split('.').pop() : ''
1119 html = '<h2>' + path + '</h2>'
1120 html += '<div class="badge">' + ext + '</div>'
1121 if (file.size) html += ' <span class="badge">' + formatSize(file.size) + '</span>'
1122 break
1123 }
1124 }
1125 panel.innerHTML = html
1126}
1127
1128// ====== GRAPH VIEW ======
1129let graphInitialized = false
1130const graphNodes = []
1131const graphEdges = []
1132let focusedNode = null
1133let zoom = 1, panX = 0, panY = 0
1134let isPanning = false, panStartX = 0, panStartY = 0
1135let graphGroup = null
1136
1137// --- Path-based navigation ---
1138//
1139// The graph shows ONLY what's at the current location in the directory tree.
1140// Navigate down by clicking a directory node; navigate up via the breadcrumb.
1141// This keeps each view bounded (typically 5-50 nodes) so force-directed
1142// simulation stays fast and the graph stays readable.
1143
1144function getCurrentPath () {
1145 // Path entries on the graphStack accumulate as the user descends.
1146 return graphStack.filter(e => e.type === 'path').map(e => e.name).join('/')
1147}
1148
1149function findDirTreeNode (path) {
1150 if (!path) return tree.dirTree
1151 const parts = path.split('/')
1152 let node = tree.dirTree
1153 for (const part of parts) {
1154 if (!node.children) return null
1155 const next = node.children.find(c => c.name === part)
1156 if (!next) return null
1157 node = next
1158 }
1159 return node
1160}
1161
1162function countPackagesUnder (dirEntry) {
1163 let count = 0
1164 function visit (n) {
1165 if (n.module) count++
1166 if (n.children) for (const c of n.children) visit(c)
1167 }
1168 visit(dirEntry)
1169 return count
1170}
1171
1172// Returns: array of { name, type: 'dir'|'module', mod?, dirEntry, packageCount? }
1173// Each entry is one node to render at the current location.
1174function getNodesAtPath (path) {
1175 const node = findDirTreeNode(path)
1176 if (!node || !node.children) return []
1177 const result = []
1178 for (const child of node.children) {
1179 if (child.type === 'file') continue
1180 if (child.module && tree.modules[child.module]) {
1181 result.push({
1182 name: child.module,
1183 type: 'module',
1184 dirEntry: child,
1185 mod: tree.modules[child.module]
1186 })
1187 } else if (child.children && child.children.length > 0) {
1188 // Pure directory with content
1189 result.push({
1190 name: child.name,
1191 type: 'dir',
1192 dirEntry: child,
1193 mod: null,
1194 packageCount: countPackagesUnder(child)
1195 })
1196 }
1197 }
1198 return result
1199}
1200
1201// Click handler for a directory node: descend into it.
1202window.descendIntoDir = function (dirName) {
1203 graphStack.push({ type: 'path', name: dirName, label: dirName })
1204 rebuildGraph()
1205 syncTreeWithGraph()
1206}
1207
1208function initGraph () {
1209 graphInitialized = true
1210 const svg = document.getElementById('graph-svg')
1211 const rect = svg.getBoundingClientRect()
1212 const W = rect.width
1213 const H = rect.height
1214 const cx = W / 2
1215 const cy = H / 2
1216
1217 // Compute category groups
1218 const categories = tree.categories || {}
1219 const moduleToCategory = {}
1220 for (const [cat, mods] of Object.entries(categories)) {
1221 for (const m of mods) moduleToCategory[m] = cat
1222 }
1223
1224 if (gfx.groupBy === 'deps') {
1225 // Override: cluster by most-shared dependency
1226 for (const k of Object.keys(moduleToCategory)) delete moduleToCategory[k]
1227 const shared = tree.system.sharedDeps || {}
1228 const topDeps = Object.entries(shared).sort((a, b) => b[1].length - a[1].length).slice(0, 6)
1229 for (const [dep, users] of topDeps) {
1230 for (const u of users) {
1231 if (!moduleToCategory[u]) moduleToCategory[u] = dep + ' users'
1232 }
1233 }
1234 for (const name of tree.system.modules) {
1235 if (!moduleToCategory[name]) moduleToCategory[name] = 'Other'
1236 }
1237 } else {
1238 // Default: use SYSTEM.md categories (already in moduleToCategory).
1239 // Uncategorized modules fall back to shared-dependency clustering — the
1240 // strongest data-driven signal we have for relatedness without hardcoded
1241 // module names. If no shared dep covers a module, it lands in "Other".
1242 const shared = tree.system.sharedDeps || {}
1243 const depToMostShared = {}
1244 for (const [dep, users] of Object.entries(shared)) {
1245 for (const u of users) {
1246 const prev = depToMostShared[u]
1247 if (!prev || users.length > shared[prev].length) depToMostShared[u] = dep
1248 }
1249 }
1250 for (const name of tree.system.modules) {
1251 if (moduleToCategory[name]) continue
1252 const topDep = depToMostShared[name]
1253 moduleToCategory[name] = topDep ? (topDep + ' users') : 'Other'
1254 }
1255 }
1256
1257 const categoryColors = {}
1258 const catColorList = ['#58a6ff', '#3fb950', '#d2a8ff', '#f0883e', '#ff7b72', '#ffa657', '#79c0ff', '#f778ba']
1259 let catIdx = 0
1260 for (const cat of Object.keys(categories)) {
1261 categoryColors[cat] = catColorList[catIdx % catColorList.length]
1262 catIdx++
1263 }
1264
1265 // Build nodes for what's at the current path. This is the file-manager
1266 // model: each level of the dir tree is a separate, bounded view.
1267 const items = getNodesAtPath(getCurrentPath())
1268 const nameToIdx = {}
1269
1270 // Categorization keeps the existing semantic data:
1271 // • SYSTEM.md categories (curated, e.g. "Crypto & Identity")
1272 // • Global shared-deps fallback (e.g. "hyperswarm users")
1273 // Pure directory nodes (no module entry) get a synthetic "Directories"
1274 // category so they cluster together visually.
1275 //
1276 // Only categories that actually apply to VISIBLE items are kept — labels
1277 // for off-screen modules don't pollute the legend.
1278 const catGroups = {}
1279 for (let i = 0; i < items.length; i++) {
1280 const item = items[i]
1281 let cat
1282 if (item.type === 'dir') {
1283 cat = 'Directories'
1284 } else {
1285 cat = (gfx.groupBy !== 'none' ? moduleToCategory[item.name] : null) || 'Other'
1286 }
1287 if (!catGroups[cat]) catGroups[cat] = []
1288 catGroups[cat].push(i)
1289 }
1290 const catList = Object.keys(catGroups)
1291
1292 for (let i = 0; i < items.length; i++) {
1293 const item = items[i]
1294 const isDir = item.type === 'dir'
1295 const name = item.name
1296 const mod = item.mod
1297
1298 const fileCount = mod ? Object.keys(mod.files).length : 0
1299 let memberCount = 0
1300 if (mod) {
1301 for (const f of Object.values(mod.files)) {
1302 if (f.classes) for (const c of f.classes) memberCount += c.methods.length + (c.getters ? c.getters.length : 0)
1303 }
1304 }
1305
1306 const cat = isDir ? 'Directories' : (moduleToCategory[name] || 'Other')
1307 const catI = catList.indexOf(cat)
1308 const group = catGroups[cat]
1309 const posInGroup = group.indexOf(i)
1310
1311 // Position: spread categories around the center
1312 const spaceMult = 0.5 + (gfx.spacing / 100) * 2
1313 const catAngle = (catI / catList.length) * Math.PI * 2 - Math.PI / 2
1314 const catRadius = (Math.min(W, H) * 0.2 + catList.length * 8) * spaceMult
1315 const catCx = cx + Math.cos(catAngle) * catRadius
1316 const catCy = cy + Math.sin(catAngle) * catRadius
1317 const nodeAngle = (posInGroup / group.length) * Math.PI * 2
1318 const nodeRadius = Math.min(80, 20 + group.length * 10) * (0.7 + spaceMult * 0.3)
1319
1320 // Dir nodes get a different size (based on how much they contain) and color.
1321 const exportCount = mod ? mod.publicAPI.length : 0
1322 const r = isDir
1323 ? Math.max(20, Math.min(50, 12 + Math.sqrt(item.packageCount) * 4))
1324 : calcNodeSize({ memberCount, usedBy: [], mod, exportCount })
1325
1326 graphNodes.push({
1327 idx: i, name, mod,
1328 type: isDir ? 'dir' : 'module',
1329 packageCount: item.packageCount,
1330 dirEntry: item.dirEntry,
1331 x: catCx + Math.cos(nodeAngle) * nodeRadius,
1332 y: catCy + Math.sin(nodeAngle) * nodeRadius,
1333 vx: 0, vy: 0,
1334 r,
1335 fileCount, memberCount,
1336 exportCount,
1337 color: isDir ? '#484f58' : (categoryColors[cat] || moduleColor(name)),
1338 category: cat
1339 })
1340 nameToIdx[name] = i
1341 }
1342
1343 // Build edges between visible MODULE nodes only. (Dir-to-dir aggregated edges
1344 // are a future enhancement; for now keep it simple.)
1345 for (let i = 0; i < graphNodes.length; i++) {
1346 const n = graphNodes[i]
1347 if (!n.mod) continue
1348 for (const dep of Object.keys(n.mod.dependencies)) {
1349 if (nameToIdx[dep] !== undefined) {
1350 graphEdges.push({ source: i, target: nameToIdx[dep] })
1351 }
1352 }
1353 }
1354
1355 for (const n of graphNodes) {
1356 n.dependsOn = graphEdges.filter(e => e.source === n.idx).map(e => e.target)
1357 n.usedBy = graphEdges.filter(e => e.target === n.idx).map(e => e.source)
1358 // Recalc size now that usedBy is known
1359 n.r = calcNodeSize(n)
1360 }
1361
1362 // SVG structure
1363 const defs = svg.querySelector('defs').outerHTML
1364 svg.innerHTML = defs + '<g id="graph-world"><g id="graph-regions"></g><g id="graph-edges"></g><g id="graph-nodes"></g></g>'
1365
1366 // Draw category region backgrounds. Categories are now derived from the
1367 // VISIBLE items only (see visibleCategoryFor above), so labels at any path
1368 // accurately reflect what's in the bubble. Bubbles appear at root + any
1369 // sub-path with mixed dirs/packages.
1370 if (gfx.showRegions && gfx.groupBy !== 'none' && catList.length > 1) {
1371 const regionGroup = document.getElementById('graph-regions')
1372 for (const cat of catList) {
1373 if (cat === 'Other' && catGroups[cat].length < 2) continue
1374 const nodes = catGroups[cat].map(i => graphNodes[i])
1375 const color = categoryColors[cat] || '#484f58'
1376
1377 // Compute bounding circle
1378 let avgX = 0, avgY = 0
1379 for (const n of nodes) { avgX += n.x; avgY += n.y }
1380 avgX /= nodes.length; avgY /= nodes.length
1381 let maxDist = 0
1382 for (const n of nodes) {
1383 const d = Math.sqrt((n.x - avgX) ** 2 + (n.y - avgY) ** 2) + n.r
1384 if (d > maxDist) maxDist = d
1385 }
1386
1387 const region = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
1388 region.classList.add('graph-region')
1389 region.setAttribute('cx', avgX)
1390 region.setAttribute('cy', avgY)
1391 region.setAttribute('r', maxDist + 30)
1392 region.setAttribute('fill', color)
1393 region.setAttribute('stroke', color)
1394 region.dataset.cat = cat
1395 regionGroup.appendChild(region)
1396
1397 // Label with background rect for readability
1398 const labelG = document.createElementNS('http://www.w3.org/2000/svg', 'g')
1399 labelG.classList.add('graph-region-label')
1400 labelG.dataset.cat = cat
1401
1402 const labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
1403 labelBg.setAttribute('fill', '#0d1117')
1404 labelBg.setAttribute('fill-opacity', '0.8')
1405 labelBg.setAttribute('rx', '4')
1406 const textWidth = cat.length * 8 + 16
1407 labelBg.setAttribute('x', avgX - textWidth / 2)
1408 labelBg.setAttribute('y', avgY - maxDist - 28)
1409 labelBg.setAttribute('width', textWidth)
1410 labelBg.setAttribute('height', 22)
1411 labelG.appendChild(labelBg)
1412
1413 const label = document.createElementNS('http://www.w3.org/2000/svg', 'text')
1414 label.textContent = cat
1415 label.setAttribute('x', avgX)
1416 label.setAttribute('y', avgY - maxDist - 12)
1417 label.setAttribute('text-anchor', 'middle')
1418 label.setAttribute('fill', color)
1419 label.setAttribute('font-size', '13')
1420 label.setAttribute('font-weight', 'bold')
1421 labelG.appendChild(label)
1422
1423 regionGroup.appendChild(labelG)
1424 }
1425 }
1426 graphGroup = document.getElementById('graph-world')
1427 const edgeGroup = document.getElementById('graph-edges')
1428 const nodeGroup = document.getElementById('graph-nodes')
1429
1430 // Draw edges as lines with arrows
1431 for (const edge of graphEdges) {
1432 const line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
1433 line.classList.add('graph-edge')
1434 line.dataset.source = edge.source
1435 line.dataset.target = edge.target
1436 edgeGroup.appendChild(line)
1437 edge.el = line
1438 }
1439
1440 // Draw nodes
1441 for (let i = 0; i < graphNodes.length; i++) {
1442 const n = graphNodes[i]
1443 const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
1444 g.classList.add('graph-node')
1445 g.dataset.idx = i
1446
1447 // Validation ring (outer glow)
1448 const valStatus = getModuleValidation(n.name)
1449 if (valStatus) {
1450 const ring = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
1451 ring.setAttribute('r', n.r + 4)
1452 ring.setAttribute('fill', 'none')
1453 const ringColor = valStatus.fail > 0 ? '#ff7b72' : valStatus.warn > 0 ? '#d29922' : '#3fb950'
1454 ring.setAttribute('stroke', ringColor)
1455 ring.setAttribute('stroke-width', '2.5')
1456 ring.setAttribute('stroke-dasharray', valStatus.fail > 0 ? 'none' : '4,3')
1457 ring.setAttribute('opacity', '0.7')
1458 g.appendChild(ring)
1459 }
1460
1461 const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
1462 circle.setAttribute('r', n.r)
1463 circle.setAttribute('fill', n.color)
1464 circle.setAttribute('stroke', '#30363d')
1465 circle.setAttribute('stroke-width', '1.5')
1466 g.appendChild(circle)
1467
1468 const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
1469 text.textContent = n.name
1470 text.setAttribute('dy', n.r + 14)
1471 text.setAttribute('text-anchor', 'middle')
1472 text.setAttribute('font-size', '11')
1473 if (!gfx.showLabels) text.style.display = 'none'
1474 g.appendChild(text)
1475 n.labelEl = text
1476
1477 // Validation count below name
1478 if (valStatus && (valStatus.fail > 0 || valStatus.warn > 0)) {
1479 const valText = document.createElementNS('http://www.w3.org/2000/svg', 'text')
1480 const parts = []
1481 if (valStatus.fail > 0) parts.push(valStatus.fail + 'F')
1482 if (valStatus.warn > 0) parts.push(valStatus.warn + 'W')
1483 valText.textContent = parts.join(' ')
1484 valText.setAttribute('dy', n.r + 25)
1485 valText.setAttribute('text-anchor', 'middle')
1486 valText.setAttribute('font-size', '9')
1487 valText.setAttribute('fill', valStatus.fail > 0 ? '#ff7b72' : '#d29922')
1488 g.appendChild(valText)
1489 }
1490
1491 // Inner label: "Nm" for module member count, "Np" for dir's package count
1492 const countText = document.createElementNS('http://www.w3.org/2000/svg', 'text')
1493 countText.textContent = n.type === 'dir' ? (n.packageCount + 'p') : (n.memberCount + 'm')
1494 countText.setAttribute('dy', '4')
1495 countText.setAttribute('text-anchor', 'middle')
1496 countText.setAttribute('font-size', '9')
1497 countText.setAttribute('fill', n.type === 'dir' ? '#c9d1d9' : '#0d1117')
1498 countText.setAttribute('font-weight', 'bold')
1499 g.appendChild(countText)
1500
1501 nodeGroup.appendChild(g)
1502 n.el = g
1503
1504 // Node drag
1505 let dragStarted = false
1506 let didDrag = false
1507 g.addEventListener('mousedown', (e) => {
1508 dragStarted = true
1509 didDrag = false
1510 n.fixed = true
1511 e.stopPropagation()
1512 e.preventDefault()
1513 })
1514
1515 // Click behaviour depends on node type:
1516 // directory → descend into it (single click)
1517 // module → toggle focus (single click), drill into files (double click)
1518 g.addEventListener('click', (e) => {
1519 e.stopPropagation()
1520 if (didDrag) return
1521 if (n.type === 'dir') {
1522 descendIntoDir(n.name)
1523 return
1524 }
1525 if (focusedNode === i) {
1526 unfocusAll()
1527 document.getElementById('right-panel').style.display = 'none'
1528 document.getElementById('resize-right').style.display = 'none'
1529 } else {
1530 focusModule(i)
1531 showGraphModulePanel(n.name, n.mod)
1532 }
1533 })
1534 g.addEventListener('dblclick', (e) => {
1535 e.stopPropagation()
1536 if (n.type === 'dir') {
1537 descendIntoDir(n.name)
1538 } else {
1539 drillIntoModule(n.name)
1540 }
1541 })
1542
1543 // Hover tooltip
1544 g.addEventListener('mouseenter', () => showTooltip(n))
1545 g.addEventListener('mouseleave', hideTooltip)
1546 }
1547
1548 // --- Zoom / Pan ---
1549 function updateTransform () {
1550 graphGroup.setAttribute('transform',
1551 'translate(' + panX.toFixed(1) + ',' + panY.toFixed(1) + ') scale(' + zoom.toFixed(3) + ')')
1552 }
1553
1554 // Scroll to zoom
1555 svg.addEventListener('wheel', (e) => {
1556 e.preventDefault()
1557 const delta = e.deltaY > 0 ? 0.9 : 1.1
1558 const newZoom = Math.max(0.1, Math.min(5, zoom * delta))
1559 // Zoom toward cursor
1560 const svgRect = svg.getBoundingClientRect()
1561 const mx = e.clientX - svgRect.left
1562 const my = e.clientY - svgRect.top
1563 panX = mx - (mx - panX) * (newZoom / zoom)
1564 panY = my - (my - panY) * (newZoom / zoom)
1565 zoom = newZoom
1566 updateTransform()
1567 }, { passive: false })
1568
1569 // Pan with mouse drag on background
1570 svg.addEventListener('mousedown', (e) => {
1571 if (e.target === svg || e.target.tagName === 'line') {
1572 isPanning = true
1573 panStartX = e.clientX - panX
1574 panStartY = e.clientY - panY
1575 svg.classList.add('dragging')
1576 }
1577 })
1578
1579 document.addEventListener('mousemove', (e) => {
1580 const tooltip = document.getElementById('graph-tooltip')
1581 tooltip.style.left = (e.clientX + 14) + 'px'
1582 tooltip.style.top = (e.clientY + 14) + 'px'
1583
1584 if (isPanning) {
1585 panX = e.clientX - panStartX
1586 panY = e.clientY - panStartY
1587 updateTransform()
1588 return
1589 }
1590
1591 // Node dragging (transform mouse coords to graph space)
1592 for (const n of graphNodes) {
1593 if (n.fixed) {
1594 const svgRect = svg.getBoundingClientRect()
1595 n.x = (e.clientX - svgRect.left - panX) / zoom
1596 n.y = (e.clientY - svgRect.top - panY) / zoom
1597 didDrag = true
1598 }
1599 }
1600 })
1601
1602 document.addEventListener('mouseup', () => {
1603 isPanning = false
1604 svg.classList.remove('dragging')
1605 for (const n of graphNodes) n.fixed = false
1606 })
1607
1608 // Click background to unfocus
1609 svg.addEventListener('click', (e) => {
1610 if (e.target === svg) unfocusAll()
1611 })
1612
1613 // Zoom buttons
1614 document.getElementById('zoom-in').addEventListener('click', () => {
1615 zoom = Math.min(5, zoom * 1.3)
1616 updateTransform()
1617 })
1618 document.getElementById('zoom-out').addEventListener('click', () => {
1619 zoom = Math.max(0.1, zoom * 0.7)
1620 updateTransform()
1621 })
1622 document.getElementById('zoom-reset').addEventListener('click', () => {
1623 zoom = 1; panX = 0; panY = 0
1624 updateTransform()
1625 unfocusAll()
1626 })
1627
1628 // --- Force simulation (label-aware) ---
1629 // Estimate label width per node
1630 for (const n of graphNodes) {
1631 n.labelW = n.name.length * 7 + n.r * 2 + 10
1632 }
1633
1634 // Simulation control: alpha cools the system over time. Below SIM_FREEZE
1635 // the simulation halts entirely. Without this, an N-node graph runs O(N^2)
1636 // every frame forever — at 400+ nodes that's 80k+ pair calcs per frame
1637 // and the graph "explodes" visually because forces never settle.
1638 let simAlpha = 1.0
1639 const SIM_DECAY = 0.985 // multiplies each frame, ~300 frames to settle
1640 const SIM_FREEZE = 0.02 // stop simulating below this
1641 let simRafId = null
1642
1643 // Re-heat on user interaction (drag, focus, restart). Cheap public hook.
1644 window.restartSim = function (alpha) {
1645 simAlpha = alpha != null ? alpha : Math.max(simAlpha, 0.6)
1646 if (simRafId === null) simRafId = requestAnimationFrame(simulate)
1647 }
1648
1649 function simulate () {
1650 simRafId = null
1651 const a = simAlpha
1652
1653 const attraction = 0.003 * a
1654 const damping = 0.85
1655 const centerForce = 0.006 * a
1656
1657 // Category-aware forces: same group attracts, different group repels more
1658 for (let i = 0; i < graphNodes.length; i++) {
1659 for (let j = i + 1; j < graphNodes.length; j++) {
1660 const na = graphNodes[i], nb = graphNodes[j]
1661 let dx = nb.x - na.x, dy = nb.y - na.y
1662 let dist = Math.sqrt(dx * dx + dy * dy) || 1
1663 const sameGroup = na.category && nb.category && na.category === nb.category
1664 const minDist = (na.labelW + nb.labelW) / 2 + (sameGroup ? 5 : 30)
1665
1666 let force
1667 if (dist < minDist) {
1668 // Overlap: push apart (stronger for different groups)
1669 force = (minDist - dist) * (sameGroup ? 0.06 : 0.15)
1670 } else if (sameGroup && dist > 80) {
1671 // Same group but far apart: pull together
1672 force = -(dist - 80) * 0.002
1673 } else {
1674 // General repulsion (stronger between groups)
1675 force = (sameGroup ? 1000 : 3000) / (dist * dist)
1676 }
1677 force *= a
1678 const fx = (dx / dist) * force, fy = (dy / dist) * force
1679 if (!na.fixed) { na.vx -= fx; na.vy -= fy }
1680 if (!nb.fixed) { nb.vx += fx; nb.vy += fy }
1681 }
1682 }
1683
1684 for (const edge of graphEdges) {
1685 const na = graphNodes[edge.source], nb = graphNodes[edge.target]
1686 const dx = nb.x - na.x, dy = nb.y - na.y
1687 const dist = Math.sqrt(dx * dx + dy * dy) || 1
1688 const force = (dist - 180) * attraction
1689 const fx = (dx / dist) * force, fy = (dy / dist) * force
1690 if (!na.fixed) { na.vx += fx; na.vy += fy }
1691 if (!nb.fixed) { nb.vx -= fx; nb.vy -= fy }
1692 }
1693
1694 for (const n of graphNodes) {
1695 if (n.fixed) continue
1696 n.vx += (cx - n.x) * centerForce
1697 n.vy += (cy - n.y) * centerForce
1698 n.vx *= damping; n.vy *= damping
1699 n.x += n.vx; n.y += n.vy
1700 }
1701
1702 // Update positions
1703 for (const n of graphNodes) {
1704 n.el.setAttribute('transform', 'translate(' + n.x.toFixed(1) + ',' + n.y.toFixed(1) + ')')
1705 }
1706 for (const edge of graphEdges) {
1707 const a = graphNodes[edge.source], b = graphNodes[edge.target]
1708 // Shorten line so arrow doesn't overlap circle
1709 const dx = b.x - a.x, dy = b.y - a.y
1710 const dist = Math.sqrt(dx * dx + dy * dy) || 1
1711 const offsetA = a.r + 2, offsetB = b.r + 6
1712 edge.el.setAttribute('x1', (a.x + dx / dist * offsetA).toFixed(1))
1713 edge.el.setAttribute('y1', (a.y + dy / dist * offsetA).toFixed(1))
1714 edge.el.setAttribute('x2', (b.x - dx / dist * offsetB).toFixed(1))
1715 edge.el.setAttribute('y2', (b.y - dy / dist * offsetB).toFixed(1))
1716 }
1717
1718 // Update region positions to follow their nodes
1719 if (gfx.showRegions) {
1720 document.querySelectorAll('.graph-region').forEach(region => {
1721 const cat = region.dataset.cat
1722 const group = catGroups[cat]
1723 if (!group) return
1724 const nodes = group.map(i => graphNodes[i])
1725 let ax = 0, ay = 0
1726 for (const n of nodes) { ax += n.x; ay += n.y }
1727 ax /= nodes.length; ay /= nodes.length
1728 let maxDist = 0
1729 for (const n of nodes) {
1730 const d = Math.sqrt((n.x - ax) ** 2 + (n.y - ay) ** 2) + n.r
1731 if (d > maxDist) maxDist = d
1732 }
1733 region.setAttribute('cx', ax)
1734 region.setAttribute('cy', ay)
1735 region.setAttribute('r', maxDist + 30)
1736 })
1737 document.querySelectorAll('g.graph-region-label').forEach(labelG => {
1738 const cat = labelG.dataset.cat
1739 const region = document.querySelector('.graph-region[data-cat="' + cat + '"]')
1740 if (!region) return
1741 const rcx = parseFloat(region.getAttribute('cx'))
1742 const rcy = parseFloat(region.getAttribute('cy'))
1743 const rr = parseFloat(region.getAttribute('r'))
1744 const textEl = labelG.querySelector('text')
1745 const bgEl = labelG.querySelector('rect')
1746 if (textEl) {
1747 textEl.setAttribute('x', rcx)
1748 textEl.setAttribute('y', rcy - rr - 12)
1749 }
1750 if (bgEl) {
1751 const tw = parseFloat(bgEl.getAttribute('width'))
1752 bgEl.setAttribute('x', rcx - tw / 2)
1753 bgEl.setAttribute('y', rcy - rr - 28)
1754 }
1755 })
1756 }
1757
1758 // Decay alpha and decide whether to keep simulating
1759 simAlpha *= SIM_DECAY
1760 if (simAlpha > SIM_FREEZE) {
1761 simRafId = requestAnimationFrame(simulate)
1762 } else {
1763 simAlpha = 0 // frozen — restartSim() will re-heat
1764 simRafId = null
1765 }
1766 }
1767
1768 // For large graphs, skip force simulation entirely. The O(N^2) pairwise
1769 // calculation per frame becomes unworkable above ~150 nodes (90k+ ops
1770 // per frame). The initial category-ring layout is good enough; users can
1771 // drag nodes to refine. Edges still render; nodes are just static.
1772 //
1773 // Adjust BIG_GRAPH_THRESHOLD if your machine is faster/slower.
1774 const BIG_GRAPH_THRESHOLD = 150
1775 if (graphNodes.length > BIG_GRAPH_THRESHOLD) {
1776 simAlpha = 0
1777 // Render once to position elements at their initial coordinates
1778 for (const n of graphNodes) {
1779 n.el.setAttribute('transform', 'translate(' + n.x.toFixed(1) + ',' + n.y.toFixed(1) + ')')
1780 }
1781 for (const edge of graphEdges) {
1782 const na = graphNodes[edge.source], nb = graphNodes[edge.target]
1783 const dx = nb.x - na.x, dy = nb.y - na.y
1784 const dist = Math.sqrt(dx * dx + dy * dy) || 1
1785 const offsetA = na.r + 2, offsetB = nb.r + 6
1786 edge.el.setAttribute('x1', (na.x + dx / dist * offsetA).toFixed(1))
1787 edge.el.setAttribute('y1', (na.y + dy / dist * offsetA).toFixed(1))
1788 edge.el.setAttribute('x2', (nb.x - dx / dist * offsetB).toFixed(1))
1789 edge.el.setAttribute('y2', (nb.y - dy / dist * offsetB).toFixed(1))
1790 }
1791 } else {
1792 simRafId = requestAnimationFrame(simulate)
1793 }
1794 showGraphSettings()
1795}
1796
1797// --- Focus a module: highlight its connections ---
1798function focusModule (idx) {
1799 focusedNode = idx
1800 const n = graphNodes[idx]
1801 const connected = new Set([idx])
1802 for (const t of n.dependsOn) connected.add(t)
1803 for (const s of n.usedBy) connected.add(s)
1804
1805 // Dim all nodes
1806 for (const node of graphNodes) {
1807 node.el.classList.toggle('dimmed', !connected.has(node.idx))
1808 node.el.classList.toggle('focused', node.idx === idx)
1809 }
1810
1811 // Color edges
1812 for (const edge of graphEdges) {
1813 const isDepOf = edge.source === idx // focused depends on target
1814 const isUsedBy = edge.target === idx // source depends on focused
1815 const isConnected = isDepOf || isUsedBy
1816
1817 edge.el.classList.toggle('dimmed', !isConnected)
1818 edge.el.classList.toggle('depends-on', isDepOf)
1819 edge.el.classList.toggle('dep-of', isUsedBy)
1820
1821 // Arrow color
1822 if (isDepOf) edge.el.setAttribute('marker-end', 'url(#arrowhead-green)')
1823 else if (isUsedBy) edge.el.setAttribute('marker-end', 'url(#arrowhead-blue)')
1824 else edge.el.setAttribute('marker-end', 'url(#arrowhead)')
1825 }
1826
1827 // Show detail
1828 showDetail('module', { name: n.name, mod: n.mod })
1829
1830 // Also show connections in detail panel
1831 const panel = document.getElementById('detail-content')
1832 let extra = ''
1833 if (n.dependsOn.length > 0) {
1834 extra += '<div class="detail"><h3 style="color:#3fb950">Depends on (' + n.dependsOn.length + ')</h3><pre><code>'
1835 extra += n.dependsOn.map(t => graphNodes[t].name).join('\\n')
1836 extra += '</code></pre></div>'
1837 }
1838 if (n.usedBy.length > 0) {
1839 extra += '<div class="detail"><h3 style="color:#58a6ff">Used by (' + n.usedBy.length + ')</h3><pre><code>'
1840 extra += n.usedBy.map(s => graphNodes[s].name).join('\\n')
1841 extra += '</code></pre></div>'
1842 }
1843 if (extra) panel.innerHTML += extra
1844}
1845
1846function unfocusAll () {
1847 focusedNode = null
1848 for (const node of graphNodes) {
1849 node.el.classList.remove('dimmed', 'focused')
1850 }
1851 for (const edge of graphEdges) {
1852 edge.el.classList.remove('dimmed', 'depends-on', 'dep-of')
1853 edge.el.setAttribute('marker-end', 'url(#arrowhead)')
1854 }
1855}
1856
1857function showTooltip (n) {
1858 const tooltip = document.getElementById('graph-tooltip')
1859 const depsOn = n.dependsOn.map(t => graphNodes[t].name)
1860 const usedBy = n.usedBy.map(s => graphNodes[s].name)
1861 tooltip.innerHTML = '<strong>' + n.name + '</strong> ' + n.mod.version +
1862 '<br>' + n.fileCount + ' files, ' + n.memberCount + ' members, ' + n.mod.publicAPI.length + ' exports' +
1863 (depsOn.length ? '<br><span class="tt-deps">depends on: ' + depsOn.join(', ') + '</span>' : '') +
1864 (usedBy.length ? '<br><span class="tt-used">used by: ' + usedBy.join(', ') + '</span>' : '') +
1865 (n.mod.publicAPI.length ? '<br>API: ' + n.mod.publicAPI.slice(0, 6).join(', ') + (n.mod.publicAPI.length > 6 ? '...' : '') : '')
1866 tooltip.style.display = 'block'
1867}
1868
1869function hideTooltip () {
1870 document.getElementById('graph-tooltip').style.display = 'none'
1871}
1872
1873function moduleColor (name) {
1874 const colors = ['#f0883e', '#58a6ff', '#d2a8ff', '#7ee787', '#ff7b72', '#79c0ff',
1875 '#ffa657', '#3fb950', '#bc8cff', '#f778ba', '#56d364', '#79c0ff']
1876 let hash = 0
1877 for (let i = 0; i < name.length; i++) hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0
1878 return colors[Math.abs(hash) % colors.length]
1879}
1880
1881// ====== GRAPH DRILL-DOWN ======
1882let graphLevel = 'system' // 'system' | 'module' | 'file'
1883let graphStack = [] // breadcrumb trail
1884
1885function updateBreadcrumb () {
1886 const bc = document.getElementById('graph-breadcrumb')
1887 let html = '<span onclick="navigateGraph(0)">System</span>'
1888 for (let i = 0; i < graphStack.length; i++) {
1889 html += '<span class="sep">&gt;</span>'
1890 const isFinal = i === graphStack.length - 1
1891 html += '<span class="' + (isFinal ? 'current' : '') + '" onclick="navigateGraph(' + (i + 1) + ')">' + graphStack[i].label + '</span>'
1892 }
1893 bc.innerHTML = html
1894}
1895
1896// Expose for onclick
1897window.navigateGraph = function (level) {
1898 if (level === 0) {
1899 graphStack = []
1900 graphLevel = 'system'
1901 rebuildGraph()
1902 syncTreeWithGraph()
1903 } else if (level <= graphStack.length) {
1904 graphStack = graphStack.slice(0, level)
1905 const entry = graphStack[graphStack.length - 1]
1906 if (entry.type === 'module') drillIntoModule(entry.name, true)
1907 else if (entry.type === 'file') drillIntoFile(entry.moduleName, entry.name, true)
1908 else if (entry.type === 'path') { rebuildGraph(); syncTreeWithGraph() }
1909 }
1910}
1911
1912function rebuildGraph () {
1913 graphInitialized = false
1914 graphNodes.length = 0
1915 graphEdges.length = 0
1916 focusedNode = null
1917 zoom = 1; panX = 0; panY = 0
1918 initGraph()
1919 updateBreadcrumb()
1920 // Note: tree sidebar is NOT re-synced here. Sliders (spacing, forceStrength,
1921 // groupBy) call rebuildGraph many times per second; tree sync would make
1922 // them chug. Call syncTreeWithGraph() instead when the PATH changes.
1923}
1924
1925// Throttle full rebuilds (e.g. groupBy change) to one per animation frame.
1926let pendingRebuild = false
1927function scheduleRebuild () {
1928 if (pendingRebuild) return
1929 pendingRebuild = true
1930 requestAnimationFrame(() => {
1931 pendingRebuild = false
1932 if (graphStack.length === 0) {
1933 rebuildGraph()
1934 } else {
1935 const top = graphStack[0]
1936 if (top.type === 'module') drillIntoModule(top.name, true)
1937 else rebuildGraph()
1938 }
1939 })
1940}
1941
1942// Fast reposition: recompute node coordinates from the current gfx.spacing
1943// value and update SVG transforms. No teardown, no rebuild. Throttled to rAF
1944// so a slider drag becomes one repaint per frame regardless of how many
1945// oninput events fire.
1946let pendingReposition = false
1947function repositionForSpacing () {
1948 if (pendingReposition) return
1949 pendingReposition = true
1950 requestAnimationFrame(() => {
1951 pendingReposition = false
1952 if (graphNodes.length === 0) return
1953
1954 const svg = document.getElementById('graph-svg')
1955 const rect = svg.getBoundingClientRect()
1956 const W = rect.width, H = rect.height
1957 const cx = W / 2, cy = H / 2
1958 const spaceMult = 0.5 + (gfx.spacing / 100) * 2
1959
1960 // Re-derive cat groups from current node categories
1961 const catGroups = {}
1962 for (const n of graphNodes) {
1963 if (!catGroups[n.category]) catGroups[n.category] = []
1964 catGroups[n.category].push(n)
1965 }
1966 const catList = Object.keys(catGroups)
1967
1968 for (const n of graphNodes) {
1969 const catI = catList.indexOf(n.category)
1970 const group = catGroups[n.category]
1971 const posInGroup = group.indexOf(n)
1972 const catAngle = (catI / catList.length) * Math.PI * 2 - Math.PI / 2
1973 const catRadius = (Math.min(W, H) * 0.2 + catList.length * 8) * spaceMult
1974 const nodeAngle = (posInGroup / group.length) * Math.PI * 2
1975 const nodeRadius = Math.min(80, 20 + group.length * 10) * (0.7 + spaceMult * 0.3)
1976 n.x = cx + Math.cos(catAngle) * catRadius + Math.cos(nodeAngle) * nodeRadius
1977 n.y = cy + Math.sin(catAngle) * catRadius + Math.sin(nodeAngle) * nodeRadius
1978 n.vx = 0; n.vy = 0
1979 if (n.el) n.el.setAttribute('transform', 'translate(' + n.x.toFixed(1) + ',' + n.y.toFixed(1) + ')')
1980 }
1981
1982 for (const edge of graphEdges) {
1983 const na = graphNodes[edge.source], nb = graphNodes[edge.target]
1984 const dx = nb.x - na.x, dy = nb.y - na.y
1985 const dist = Math.sqrt(dx * dx + dy * dy) || 1
1986 const offsetA = na.r + 2, offsetB = nb.r + 6
1987 if (edge.el) {
1988 edge.el.setAttribute('x1', (na.x + dx / dist * offsetA).toFixed(1))
1989 edge.el.setAttribute('y1', (na.y + dy / dist * offsetA).toFixed(1))
1990 edge.el.setAttribute('x2', (nb.x - dx / dist * offsetB).toFixed(1))
1991 edge.el.setAttribute('y2', (nb.y - dy / dist * offsetB).toFixed(1))
1992 }
1993 }
1994
1995 // Re-heat the simulation if it was running, so any post-spacing forces
1996 // settle naturally instead of snapping. No-op if sim is permanently off
1997 // (large-graph case).
1998 if (typeof window.restartSim === 'function') window.restartSim(0.4)
1999 })
2000}
2001
2002// Re-sync the file-tree sidebar with the current graph location. Called on
2003// path navigation, not on slider tweaks.
2004function syncTreeWithGraph () {
2005 buildTree()
2006}
2007
2008// --- Toggle state ---
2009// Graph settings — all toggleable
2010const gfx = {
2011 showLabels: true,
2012 dimTests: false,
2013 showRegions: true, // category background regions
2014 sizeBy: 'members', // 'members' | 'deps' | 'exports'
2015 groupBy: 'category', // 'category' | 'deps' | 'none'
2016 forceStrength: 0, // 0 = hierarchy, 100 = force
2017 spacing: 50, // 0 = tight, 100 = max spread
2018 showEdgeLabels: false, // show import names on edges
2019 labelPos: 'below', // 'below' | 'right' | 'radial'
2020}
2021let expandedNodes = new Set()
2022
2023function drillIntoModule (moduleName, fromNav) {
2024 const mod = tree.modules[moduleName]
2025 if (!mod) return
2026
2027 // If the module came from a shallow scan, fetch the deep version on demand.
2028 // Marker: shallow-scanned modules have only ~1 entry in files (the entry file)
2029 // and tree.shallow === true. Avoid re-fetching once we've already loaded deep.
2030 if (tree.shallow && !mod.__deepLoaded && Object.keys(mod.files).length <= 1) {
2031 fetch(API + '/api/deep-scan?module=' + encodeURIComponent(moduleName))
2032 .then(r => r.json())
2033 .then(data => {
2034 if (data && data.mod) {
2035 // Replace the placeholder with the full module data, mark loaded,
2036 // then re-enter drillIntoModule to render with the new data.
2037 data.mod.__deepLoaded = true
2038 tree.modules[moduleName] = data.mod
2039 drillIntoModule(moduleName, fromNav)
2040 }
2041 })
2042 .catch(() => {})
2043 // Render a "loading" stub immediately so user sees feedback
2044 }
2045
2046 if (!fromNav) {
2047 graphStack = [{ type: 'module', name: moduleName, label: moduleName }]
2048 }
2049 graphLevel = 'module'
2050 expandedNodes.clear()
2051
2052 const svg = document.getElementById('graph-svg')
2053 const rect = svg.getBoundingClientRect()
2054 const W = rect.width, H = rect.height
2055 const cx = W / 2, cy = H / 2
2056
2057 graphNodes.length = 0
2058 graphEdges.length = 0
2059 focusedNode = null
2060 zoom = 1; panX = 0; panY = 0
2061
2062 // Build file nodes with import-depth based radial layout
2063 const files = Object.entries(mod.files)
2064 const nameToIdx = {}
2065 const fileData = []
2066
2067 for (let i = 0; i < files.length; i++) {
2068 const [path, file] = files[i]
2069 nameToIdx[path] = i
2070 let memberCount = 0
2071 if (file.classes) for (const c of file.classes) memberCount += c.methods.length + (c.getters ? c.getters.length : 0)
2072 if (file.functions) memberCount += file.functions.length
2073 let exportCount = file.exports ? file.exports.length : 0
2074 fileData.push({ path, file, memberCount, exportCount, role: file.role || 'lib' })
2075 }
2076
2077 // Build edge list first to compute depths
2078 const edgeList = []
2079 for (let i = 0; i < files.length; i++) {
2080 const file = fileData[i].file
2081 if (!file.imports) continue
2082 for (const imp of file.imports) {
2083 for (let j = 0; j < files.length; j++) {
2084 if (i === j) continue
2085 const tp = fileData[j].path
2086 if (imp.specifier.endsWith(tp) || imp.specifier === './' + tp ||
2087 tp.endsWith(imp.specifier.replace('./', ''))) {
2088 edgeList.push({ source: i, target: j, labels: imp.names || [] })
2089 }
2090 }
2091 }
2092 }
2093
2094 // BFS from entry to compute depth
2095 const entryIdx = fileData.findIndex(f => f.role === 'entry')
2096 const depth = new Array(files.length).fill(-1)
2097 if (entryIdx >= 0) {
2098 depth[entryIdx] = 0
2099 const queue = [entryIdx]
2100 while (queue.length > 0) {
2101 const cur = queue.shift()
2102 for (const e of edgeList) {
2103 if (e.source === cur && depth[e.target] === -1) {
2104 depth[e.target] = depth[cur] + 1
2105 queue.push(e.target)
2106 }
2107 }
2108 }
2109 }
2110 // Assign unvisited nodes (tests, disconnected) to outer ring
2111 const maxDepth = Math.max(1, ...depth.filter(d => d >= 0))
2112 for (let i = 0; i < depth.length; i++) {
2113 if (depth[i] === -1) depth[i] = maxDepth + (fileData[i].role === 'test' ? 1 : 0) + 1
2114 }
2115
2116 // Group by depth
2117 const byDepth = {}
2118 for (let i = 0; i < files.length; i++) {
2119 const d = depth[i]
2120 if (!byDepth[d]) byDepth[d] = []
2121 byDepth[d].push(i)
2122 }
2123
2124 const depthLevels = Object.keys(byDepth).map(Number).sort((a, b) => a - b)
2125
2126 // Estimate label width: ~7px per char
2127 function labelWidth (name) {
2128 const short = name.includes('/') ? name.split('/').pop() : name
2129 return short.length * 7 + 30 // text + padding + node radius
2130 }
2131
2132 // Compute hierarchy positions (top-down layered)
2133 const rowHeight = 90
2134 const startY = 60
2135
2136 for (const d of depthLevels) {
2137 const group = byDepth[d]
2138 const widths = group.map(i => labelWidth(fileData[i].path))
2139 const totalWidth = widths.reduce((a, b) => a + b, 0) + (group.length - 1) * 20
2140 let xPos = cx - totalWidth / 2
2141
2142 for (let j = 0; j < group.length; j++) {
2143 const i = group[j]
2144 const fd = fileData[i]
2145 const nodeR = Math.max(8, Math.min(30, 6 + Math.sqrt(fd.memberCount) * 2.5))
2146 const w = widths[j]
2147 const hx = xPos + w / 2
2148 const hy = startY + d * rowHeight
2149
2150 graphNodes.push({
2151 idx: i, name: fd.path, path: fd.path, file: fd.file, moduleName,
2152 x: hx, y: hy,
2153 hierX: hx, hierY: hy, // stored hierarchy position
2154 vx: 0, vy: 0,
2155 r: nodeR,
2156 labelW: w,
2157 memberCount: fd.memberCount,
2158 exportCount: fd.exportCount,
2159 depth: d,
2160 color: roleColor(fd.role),
2161 role: fd.role,
2162 dependsOn: [], usedBy: []
2163 })
2164 xPos += w + 20
2165 }
2166 }
2167
2168 // Build edges with label info
2169 for (const e of edgeList) {
2170 graphEdges.push({ source: e.source, target: e.target, labels: e.labels })
2171 graphNodes[e.source].dependsOn.push(e.target)
2172 graphNodes[e.target].usedBy.push(e.source)
2173 }
2174
2175 renderSubGraph(svg, cx, cy, W, H, 'file')
2176 showGraphSettings()
2177 updateBreadcrumb()
2178}
2179
2180function showGraphSettings () {
2181 let panel = document.getElementById('graph-settings')
2182 if (!panel) {
2183 panel = document.createElement('div')
2184 panel.id = 'graph-settings'
2185 panel.className = 'graph-settings'
2186 document.getElementById('graph-container').appendChild(panel)
2187 }
2188
2189 panel.innerHTML =
2190 '<h4>Layout</h4>' +
2191 '<div class="gs-row"><label>Hierarchy</label>' +
2192 '<input type="range" min="0" max="100" value="' + gfx.forceStrength + '" oninput="gfxSet(&quot;forceStrength&quot;,+this.value)">' +
2193 '<label>Force</label></div>' +
2194
2195 '<div class="gs-row"><label>Spacing</label>' +
2196 '<input type="range" min="0" max="100" value="' + gfx.spacing + '" oninput="gfxSet(&quot;spacing&quot;,+this.value)">' +
2197 '</div>' +
2198
2199 '<div class="gs-divider"></div><h4>Grouping</h4>' +
2200 '<div class="gs-row"><label>Group by</label>' +
2201 '<select onchange="gfxSet(&quot;groupBy&quot;,this.value)">' +
2202 '<option value="category"' + (gfx.groupBy === 'category' ? ' selected' : '') + '>Spec Categories</option>' +
2203 '<option value="deps"' + (gfx.groupBy === 'deps' ? ' selected' : '') + '>Shared Dependencies</option>' +
2204 '<option value="none"' + (gfx.groupBy === 'none' ? ' selected' : '') + '>None</option>' +
2205 '</select></div>' +
2206 '<div class="gs-row"><input type="checkbox"' + (gfx.showRegions ? ' checked' : '') + ' onchange="gfxSet(&quot;showRegions&quot;,this.checked)"><label>Show region backgrounds</label></div>' +
2207
2208 '<div class="gs-divider"></div><h4>Node Size</h4>' +
2209 '<div class="gs-row"><label>Size by</label>' +
2210 '<select onchange="gfxSet(&quot;sizeBy&quot;,this.value)">' +
2211 '<option value="members"' + (gfx.sizeBy === 'members' ? ' selected' : '') + '>Member Count</option>' +
2212 '<option value="deps"' + (gfx.sizeBy === 'deps' ? ' selected' : '') + '>Dependents (who uses this)</option>' +
2213 '<option value="exports"' + (gfx.sizeBy === 'exports' ? ' selected' : '') + '>Export Count</option>' +
2214 '</select></div>' +
2215
2216 '<div class="gs-divider"></div><h4>Labels</h4>' +
2217 '<div class="gs-row"><label>Position</label>' +
2218 '<select onchange="gfxSet(&quot;labelPos&quot;,this.value)">' +
2219 '<option value="below"' + (gfx.labelPos === 'below' ? ' selected' : '') + '>Below</option>' +
2220 '<option value="right"' + (gfx.labelPos === 'right' ? ' selected' : '') + '>Right</option>' +
2221 '<option value="radial"' + (gfx.labelPos === 'radial' ? ' selected' : '') + '>Radial (outward)</option>' +
2222 '</select></div>' +
2223 '<div class="gs-row"><input type="checkbox"' + (gfx.showEdgeLabels ? ' checked' : '') + ' onchange="gfxSet(&quot;showEdgeLabels&quot;,this.checked)"><label>Show edge import names</label></div>' +
2224 '<div class="gs-row"><input type="checkbox"' + (gfx.showLabels ? ' checked' : '') + ' onchange="gfxSet(&quot;showLabels&quot;,this.checked)"><label>Show node labels</label></div>' +
2225 '<div class="gs-row"><input type="checkbox"' + (gfx.dimTests ? ' checked' : '') + ' onchange="gfxSet(&quot;dimTests&quot;,this.checked)"><label>Dim test files</label></div>'
2226}
2227
2228window.gfxSet = function (key, value) {
2229 gfx[key] = value
2230
2231 // Immediate effects
2232 if (key === 'forceStrength' && value === 0) {
2233 for (const n of graphNodes) {
2234 if (n.hierX !== undefined) { n.x = n.hierX; n.y = n.hierY; n.vx = 0; n.vy = 0 }
2235 }
2236 }
2237 if (key === 'showLabels') {
2238 for (const n of graphNodes) {
2239 if (n.labelEl) n.labelEl.style.display = value ? '' : 'none'
2240 }
2241 }
2242 if (key === 'dimTests') {
2243 for (const n of graphNodes) {
2244 if (n.role === 'test') n.el.style.opacity = value ? '0.2' : '1'
2245 }
2246 }
2247 if (key === 'showEdgeLabels') {
2248 document.querySelectorAll('.edge-label').forEach(el => {
2249 el.style.display = value ? '' : 'none'
2250 })
2251 }
2252 if (key === 'showRegions') {
2253 document.querySelectorAll('.graph-region, .graph-region-label').forEach(el => {
2254 el.style.display = value ? '' : 'none'
2255 })
2256 }
2257
2258 // Recalculate node sizes
2259 if (key === 'sizeBy') {
2260 for (const n of graphNodes) {
2261 const newR = calcNodeSize(n)
2262 n.r = newR
2263 const circle = n.el.querySelector('circle')
2264 if (circle) circle.setAttribute('r', newR)
2265 // Update label position
2266 if (n.labelEl) n.labelEl.setAttribute('dy', newR + 14)
2267 }
2268 }
2269
2270 // Spacing change: repositions existing nodes based on the new value. No
2271 // SVG teardown, no force sim rebuild. Just compute new x/y for each node
2272 // (the calculation that initGraph would do) and update the transform.
2273 // Slider input is decoupled from graph rebuild — input updates state,
2274 // state change triggers a cheap repaint.
2275 if (key === 'spacing') {
2276 repositionForSpacing()
2277 }
2278 // Regroup actually changes which nodes are in which group, so it needs
2279 // a real rebuild. Still throttled to rAF so rapid changes coalesce.
2280 if (key === 'groupBy') {
2281 scheduleRebuild()
2282 }
2283
2284 // Update label positions
2285 if (key === 'labelPos') updateLabelPositions()
2286
2287 // DON'T call showGraphSettings() here. It rebuilds the entire settings
2288 // panel HTML — including the slider input element. If the user is mid-drag,
2289 // their pointer capture is on the soon-to-be-destroyed input, so the
2290 // browser cancels the drag after one tick. That was the "barely slides"
2291 // regression. Settings panel only needs to re-render on initial graph
2292 // build (which still calls showGraphSettings).
2293}
2294
2295function calcNodeSize (n) {
2296 let val = 0
2297 if (gfx.sizeBy === 'members') val = n.memberCount || 0
2298 else if (gfx.sizeBy === 'deps') val = (n.usedBy ? n.usedBy.length : 0) * 5
2299 else if (gfx.sizeBy === 'exports') val = (n.mod ? n.mod.publicAPI.length : (n.exportCount || 0)) * 3
2300 return Math.max(8, Math.min(35, 6 + Math.sqrt(val) * 2))
2301}
2302
2303function updateLabelPositions () {
2304 const cx = document.getElementById('graph-svg').getBoundingClientRect().width / 2
2305 const cy = document.getElementById('graph-svg').getBoundingClientRect().height / 2
2306
2307 for (const n of graphNodes) {
2308 if (!n.labelEl) continue
2309 if (gfx.labelPos === 'below') {
2310 n.labelEl.setAttribute('dy', n.r + 14)
2311 n.labelEl.setAttribute('dx', '0')
2312 n.labelEl.setAttribute('text-anchor', 'middle')
2313 } else if (gfx.labelPos === 'right') {
2314 n.labelEl.setAttribute('dy', '4')
2315 n.labelEl.setAttribute('dx', n.r + 6)
2316 n.labelEl.setAttribute('text-anchor', 'start')
2317 } else if (gfx.labelPos === 'radial') {
2318 // Point outward from center
2319 const dx = n.x - cx
2320 const dy = n.y - cy
2321 const angle = Math.atan2(dy, dx)
2322 const dist = n.r + 10
2323 n.labelEl.setAttribute('dy', Math.sin(angle) * dist + 4)
2324 n.labelEl.setAttribute('dx', Math.cos(angle) * dist)
2325 n.labelEl.setAttribute('text-anchor', Math.cos(angle) > 0.3 ? 'start' : Math.cos(angle) < -0.3 ? 'end' : 'middle')
2326 }
2327 }
2328}
2329
2330function drillIntoFile (moduleName, filePath, fromNav) {
2331 const mod = tree.modules[moduleName]
2332 if (!mod || !mod.files[filePath]) return
2333 const file = mod.files[filePath]
2334
2335 if (!fromNav) {
2336 if (graphStack.length === 0 || graphStack[graphStack.length - 1].type !== 'module') {
2337 graphStack = [{ type: 'module', name: moduleName, label: moduleName }]
2338 }
2339 graphStack.push({ type: 'file', name: filePath, moduleName, label: filePath.split('/').pop() })
2340 }
2341 graphLevel = 'file'
2342
2343 const svg = document.getElementById('graph-svg')
2344 const rect = svg.getBoundingClientRect()
2345 const W = rect.width, H = rect.height
2346 const cx = W / 2, cy = H / 2
2347
2348 graphNodes.length = 0
2349 graphEdges.length = 0
2350 focusedNode = null
2351 zoom = 1; panX = 0; panY = 0
2352
2353 // Build nodes: classes, functions, constants
2354 let idx = 0
2355 const items = []
2356
2357 if (file.classes) for (const cls of file.classes) {
2358 items.push({ type: 'class', name: cls.name, data: cls, memberCount: cls.methods.length + (cls.getters ? cls.getters.length : 0), color: '#d2a8ff' })
2359 }
2360 if (file.functions) for (const fn of file.functions) {
2361 items.push({ type: 'function', name: fn.name, data: fn, memberCount: 0, color: '#79c0ff' })
2362 }
2363 if (file.constants) for (const c of file.constants) {
2364 if (c.type === 'class' || c.type === 'function') continue
2365 items.push({ type: 'const', name: c.name, data: c, memberCount: 0, color: '#ffa657' })
2366 }
2367
2368 for (let i = 0; i < items.length; i++) {
2369 const item = items[i]
2370 const angle = (i / items.length) * Math.PI * 2
2371 const radius = Math.min(W, H) * 0.25
2372
2373 graphNodes.push({
2374 idx: i, name: item.name, itemType: item.type, data: item.data,
2375 x: cx + Math.cos(angle) * radius,
2376 y: cy + Math.sin(angle) * radius,
2377 vx: 0, vy: 0,
2378 r: Math.max(8, Math.min(25, 8 + Math.sqrt(item.memberCount) * 3)),
2379 memberCount: item.memberCount,
2380 color: item.color,
2381 dependsOn: [], usedBy: []
2382 })
2383 }
2384
2385 // Edges: delegation relationships
2386 if (file.delegates) {
2387 for (const del of file.delegates) {
2388 // Find source class (the one with the delegate field)
2389 const srcIdx = graphNodes.findIndex(n => n.itemType === 'class' && n.data.state && n.data.state.includes(del.field))
2390 if (srcIdx < 0) continue
2391 // No target in same file usually, but mark delegation as self-edge label
2392 }
2393 }
2394
2395 renderSubGraph(svg, cx, cy, W, H, 'item')
2396 updateBreadcrumb()
2397}
2398
2399function renderSubGraph (svg, cx, cy, W, H, nodeType) {
2400 const defs = svg.querySelector('defs').outerHTML
2401 svg.innerHTML = defs + '<g id="graph-world"><g id="graph-edges"></g><g id="graph-edge-labels"></g><g id="graph-nodes"></g><g id="graph-expanded"></g></g>'
2402 graphGroup = document.getElementById('graph-world')
2403 const edgeGroup = document.getElementById('graph-edges')
2404 const labelGroup = document.getElementById('graph-edge-labels')
2405 const nodeGroup = document.getElementById('graph-nodes')
2406
2407 // Draw edges with labels
2408 for (const edge of graphEdges) {
2409 const line = document.createElementNS('http://www.w3.org/2000/svg', 'line')
2410 line.classList.add('graph-edge')
2411 edgeGroup.appendChild(line)
2412 edge.el = line
2413
2414 // Edge label showing imported names
2415 if (edge.labels && edge.labels.length > 0) {
2416 const label = document.createElementNS('http://www.w3.org/2000/svg', 'text')
2417 label.classList.add('edge-label')
2418 label.textContent = edge.labels.slice(0, 3).join(', ') + (edge.labels.length > 3 ? '...' : '')
2419 label.setAttribute('font-size', '9')
2420 label.setAttribute('fill', '#484f58')
2421 label.setAttribute('text-anchor', 'middle')
2422 label.style.display = gfx.showLabels ? '' : 'none'
2423 labelGroup.appendChild(label)
2424 edge.labelEl = label
2425 }
2426 }
2427
2428 // Draw nodes
2429 for (let i = 0; i < graphNodes.length; i++) {
2430 const n = graphNodes[i]
2431 const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
2432 g.classList.add('graph-node')
2433
2434 // Shape by role/type
2435 if (nodeType === 'file' && n.role === 'entry') {
2436 // Diamond for entry
2437 const d = n.r
2438 const poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon')
2439 poly.setAttribute('points', '0,-'+d+' '+d+',0 0,'+d+' -'+d+',0')
2440 poly.setAttribute('fill', n.color)
2441 poly.setAttribute('stroke', '#30363d')
2442 poly.setAttribute('stroke-width', '1.5')
2443 g.appendChild(poly)
2444 } else if (nodeType === 'file' && n.role === 'test') {
2445 // Square for test
2446 const s = n.r * 0.8
2447 const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
2448 rect.setAttribute('x', -s); rect.setAttribute('y', -s)
2449 rect.setAttribute('width', s*2); rect.setAttribute('height', s*2)
2450 rect.setAttribute('rx', '3')
2451 rect.setAttribute('fill', n.color)
2452 rect.setAttribute('stroke', '#30363d')
2453 rect.setAttribute('stroke-width', '1.5')
2454 g.appendChild(rect)
2455 } else {
2456 // Circle for everything else
2457 const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
2458 circle.setAttribute('r', n.r)
2459 circle.setAttribute('fill', n.color)
2460 circle.setAttribute('stroke', '#30363d')
2461 circle.setAttribute('stroke-width', '1.5')
2462 g.appendChild(circle)
2463 }
2464
2465 // Label
2466 const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
2467 const shortName = n.name.includes('/') ? n.name.split('/').pop() : n.name
2468 text.textContent = shortName
2469 text.setAttribute('dy', n.r + 14)
2470 text.setAttribute('text-anchor', 'middle')
2471 text.setAttribute('font-size', '11')
2472 g.appendChild(text)
2473
2474 // Member count inside node
2475 if (n.memberCount > 0) {
2476 const ct = document.createElementNS('http://www.w3.org/2000/svg', 'text')
2477 ct.textContent = n.memberCount
2478 ct.setAttribute('dy', '4')
2479 ct.setAttribute('text-anchor', 'middle')
2480 ct.setAttribute('font-size', '9')
2481 ct.setAttribute('fill', '#0d1117')
2482 ct.setAttribute('font-weight', 'bold')
2483 g.appendChild(ct)
2484 }
2485
2486 // Dim tests if toggle is on
2487 if (gfx.dimTests && n.role === 'test') g.style.opacity = '0.2'
2488
2489 nodeGroup.appendChild(g)
2490 n.el = g
2491
2492 // Drag
2493 let didDrag = false
2494 g.addEventListener('mousedown', (e) => {
2495 n.fixed = true; didDrag = false
2496 e.stopPropagation(); e.preventDefault()
2497 })
2498
2499 g.addEventListener('click', (e) => {
2500 e.stopPropagation()
2501 if (didDrag) return
2502
2503 if (nodeType === 'file') {
2504 currentFileContext = { path: n.path, moduleName: n.moduleName }
2505 // In graph mode: show structure in right panel, load file source in docs tab
2506 if (n.file && (n.file.classes || n.file.functions || n.file.exports)) {
2507 showStructurePanel(n.path, n.file, n.moduleName)
2508 }
2509 // Load file source into docs tab
2510 const modPath = n.moduleName ? tree.modules[n.moduleName].path + '/' : ''
2511 loadFileIntoDocsTab(modPath + n.path)
2512 toggleExpandNode(n, i)
2513 } else if (n.itemType === 'class') {
2514 showGraphItemPanel('class', n.data, n.name)
2515 } else if (n.itemType === 'function') {
2516 showGraphItemPanel('function', n.data, n.name)
2517 }
2518 focusModule(i)
2519 })
2520
2521 g.addEventListener('dblclick', (e) => {
2522 e.stopPropagation()
2523 if (nodeType === 'file' && n.file) {
2524 drillIntoFile(n.moduleName, n.path)
2525 }
2526 })
2527
2528 g.addEventListener('mouseenter', () => {
2529 const tooltip = document.getElementById('graph-tooltip')
2530 let html = '<strong>' + n.name + '</strong>'
2531 if (n.role) html += ' <span style="color:' + n.color + '">' + n.role + '</span>'
2532 if (n.memberCount) html += '<br>' + n.memberCount + ' members'
2533 if (n.exportCount) html += ', ' + n.exportCount + ' exports'
2534 if (n.file && n.file.classes) {
2535 html += '<br>Classes: ' + n.file.classes.map(c => c.name).join(', ')
2536 }
2537 if (n.file && n.file.functions) {
2538 html += '<br>Functions: ' + n.file.functions.slice(0, 5).map(f => f.name).join(', ')
2539 if (n.file.functions.length > 5) html += '...'
2540 }
2541 if (n.itemType) html += '<br>type: ' + n.itemType
2542 if (n.data && n.data.params) html += '<br>params: ' + n.data.params.join(', ')
2543 html += '<br><em style="color:#484f58">click to expand, dblclick to drill in</em>'
2544 tooltip.innerHTML = html
2545 tooltip.style.display = 'block'
2546 })
2547 g.addEventListener('mouseleave', hideTooltip)
2548 }
2549
2550 // Pan/zoom handler
2551 const svgEl = document.getElementById('graph-svg')
2552 const moveHandler = (e) => {
2553 const tooltip = document.getElementById('graph-tooltip')
2554 tooltip.style.left = (e.clientX + 14) + 'px'
2555 tooltip.style.top = (e.clientY + 14) + 'px'
2556
2557 if (isPanning) {
2558 panX = e.clientX - panStartX
2559 panY = e.clientY - panStartY
2560 graphGroup.setAttribute('transform', 'translate(' + panX.toFixed(1) + ',' + panY.toFixed(1) + ') scale(' + zoom.toFixed(3) + ')')
2561 return
2562 }
2563 for (const nd of graphNodes) {
2564 if (nd.fixed) {
2565 const sr = svgEl.getBoundingClientRect()
2566 nd.x = (e.clientX - sr.left - panX) / zoom
2567 nd.y = (e.clientY - sr.top - panY) / zoom
2568 didDrag = true
2569 }
2570 }
2571 }
2572 document.removeEventListener('mousemove', graphMoveHandler)
2573 document.addEventListener('mousemove', moveHandler)
2574 graphMoveHandler = moveHandler
2575
2576 // Force simulation — blends hierarchy pull vs force physics via slider
2577 function sim () {
2578 const damp = 0.8
2579 const t = gfx.forceStrength / 100 // 0 = pure hierarchy, 1 = full force
2580 const hierPull = 1 - t // how strongly to pull toward hierarchy positions
2581
2582 // Hierarchy spring: pull toward stored hierarchy positions
2583 if (hierPull > 0.01) {
2584 for (const n of graphNodes) {
2585 if (n.fixed || n.hierX === undefined) continue
2586 n.vx += (n.hierX - n.x) * hierPull * 0.15
2587 n.vy += (n.hierY - n.y) * hierPull * 0.15
2588 }
2589 }
2590
2591 // Force physics (scaled by t)
2592 if (t > 0.01) {
2593 // Label-aware repulsion
2594 for (let i = 0; i < graphNodes.length; i++) {
2595 for (let j = i + 1; j < graphNodes.length; j++) {
2596 const a = graphNodes[i], b = graphNodes[j]
2597 let dx = b.x - a.x, dy = b.y - a.y
2598 let dist = Math.sqrt(dx * dx + dy * dy) || 1
2599 const minDist = (a.labelW || a.r * 2) / 2 + (b.labelW || b.r * 2) / 2 + 15
2600 if (dist < minDist) {
2601 const f = (minDist - dist) * 0.08 * t
2602 if (!a.fixed) { a.vx -= (dx/dist)*f; a.vy -= (dy/dist)*f }
2603 if (!b.fixed) { b.vx += (dx/dist)*f; b.vy += (dy/dist)*f }
2604 }
2605 }
2606 }
2607
2608 // Edge attraction
2609 for (const edge of graphEdges) {
2610 const a = graphNodes[edge.source], b = graphNodes[edge.target]
2611 const dx = b.x-a.x, dy = b.y-a.y, dist = Math.sqrt(dx*dx+dy*dy)||1
2612 if (dist > 180) {
2613 const f = (dist - 180) * 0.001 * t
2614 if (!a.fixed) { a.vx += (dx/dist)*f; a.vy += (dy/dist)*f }
2615 if (!b.fixed) { b.vx -= (dx/dist)*f; b.vy -= (dy/dist)*f }
2616 }
2617 }
2618 }
2619
2620 // Always: overlap prevention (even in hierarchy mode)
2621 for (let i = 0; i < graphNodes.length; i++) {
2622 for (let j = i + 1; j < graphNodes.length; j++) {
2623 const a = graphNodes[i], b = graphNodes[j]
2624 let dx = b.x - a.x, dy = b.y - a.y
2625 let dist = Math.sqrt(dx * dx + dy * dy) || 1
2626 const minDist = (a.labelW || a.r * 2) / 2 + (b.labelW || b.r * 2) / 2 + 10
2627 if (dist < minDist) {
2628 const f = (minDist - dist) * 0.02
2629 if (!a.fixed) { a.vx -= (dx/dist)*f; a.vy -= (dy/dist)*f }
2630 if (!b.fixed) { b.vx += (dx/dist)*f; b.vy += (dy/dist)*f }
2631 }
2632 }
2633 }
2634
2635 for (const n of graphNodes) {
2636 if (n.fixed) continue
2637 n.vx *= damp; n.vy *= damp
2638 n.x += n.vx; n.y += n.vy
2639 }
2640
2641 // Update SVG
2642 for (const n of graphNodes) {
2643 n.el.setAttribute('transform', 'translate('+n.x.toFixed(1)+','+n.y.toFixed(1)+')')
2644 }
2645 for (const edge of graphEdges) {
2646 const a = graphNodes[edge.source], b = graphNodes[edge.target]
2647 const dx=b.x-a.x, dy=b.y-a.y, dist=Math.sqrt(dx*dx+dy*dy)||1
2648 const x1 = a.x+dx/dist*(a.r+2), y1 = a.y+dy/dist*(a.r+2)
2649 const x2 = b.x-dx/dist*(b.r+6), y2 = b.y-dy/dist*(b.r+6)
2650 edge.el.setAttribute('x1', x1.toFixed(1))
2651 edge.el.setAttribute('y1', y1.toFixed(1))
2652 edge.el.setAttribute('x2', x2.toFixed(1))
2653 edge.el.setAttribute('y2', y2.toFixed(1))
2654 // Position label at midpoint
2655 if (edge.labelEl) {
2656 edge.labelEl.setAttribute('x', ((x1+x2)/2).toFixed(1))
2657 edge.labelEl.setAttribute('y', ((y1+y2)/2 - 4).toFixed(1))
2658 }
2659 }
2660
2661 // Update expanded satellite positions
2662 for (const n of graphNodes) {
2663 if (n.satellites) {
2664 for (const sat of n.satellites) {
2665 sat.el.setAttribute('transform', 'translate('+(n.x+sat.ox).toFixed(1)+','+(n.y+sat.oy).toFixed(1)+')')
2666 }
2667 }
2668 }
2669
2670 requestAnimationFrame(sim)
2671 }
2672 sim()
2673}
2674
2675// --- Expand node in-place: show classes/methods as satellites ---
2676function toggleExpandNode (n, idx) {
2677 const expandGroup = document.getElementById('graph-expanded')
2678 if (!expandGroup) return
2679
2680 if (expandedNodes.has(idx)) {
2681 // Collapse
2682 expandedNodes.delete(idx)
2683 if (n.satellites) {
2684 for (const sat of n.satellites) sat.el.remove()
2685 n.satellites = null
2686 }
2687 return
2688 }
2689
2690 expandedNodes.add(idx)
2691 const file = n.file
2692 if (!file) return
2693
2694 const items = []
2695 if (file.classes) for (const cls of file.classes) {
2696 items.push({ name: cls.name, type: 'class', sub: cls.methods.slice(0, 5).map(m => m.name) })
2697 }
2698 if (file.functions) for (const fn of file.functions) {
2699 items.push({ name: fn.name, type: 'fn' })
2700 }
2701
2702 if (items.length === 0) return
2703
2704 n.satellites = []
2705 const satRadius = n.r + 35
2706
2707 for (let i = 0; i < items.length; i++) {
2708 const item = items[i]
2709 const angle = (i / items.length) * Math.PI * 2 - Math.PI / 2
2710 const ox = Math.cos(angle) * satRadius
2711 const oy = Math.sin(angle) * satRadius
2712
2713 const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
2714 g.classList.add('graph-node')
2715
2716 const r = item.type === 'class' ? 6 : 4
2717 const color = item.type === 'class' ? '#d2a8ff' : '#79c0ff'
2718 const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle')
2719 circle.setAttribute('r', r)
2720 circle.setAttribute('fill', color)
2721 circle.setAttribute('stroke', '#30363d')
2722 circle.setAttribute('stroke-width', '1')
2723 g.appendChild(circle)
2724
2725 const text = document.createElementNS('http://www.w3.org/2000/svg', 'text')
2726 text.textContent = item.name
2727 text.setAttribute('dx', r + 4)
2728 text.setAttribute('dy', '3')
2729 text.setAttribute('font-size', '9')
2730 text.setAttribute('fill', color)
2731 g.appendChild(text)
2732
2733 // Show methods as sub-text for classes
2734 if (item.sub && item.sub.length > 0) {
2735 for (let si = 0; si < item.sub.length; si++) {
2736 const st = document.createElementNS('http://www.w3.org/2000/svg', 'text')
2737 st.textContent = '.' + item.sub[si] + '()'
2738 st.setAttribute('dx', r + 8)
2739 st.setAttribute('dy', (si + 1) * 11 + 3)
2740 st.setAttribute('font-size', '8')
2741 st.setAttribute('fill', '#484f58')
2742 g.appendChild(st)
2743 }
2744 }
2745
2746 expandGroup.appendChild(g)
2747 n.satellites.push({ el: g, ox, oy })
2748 }
2749}
2750
2751let graphMoveHandler = () => {}
2752
2753function roleColor (role) {
2754 const colors = { entry: '#f0883e', lib: '#58a6ff', schema: '#d2a8ff', test: '#7ee787', bin: '#ff7b72', script: '#ffa657' }
2755 return colors[role] || '#8b949e'
2756}
2757
2758// ====== FILE VIEWER ======
2759async function loadFileViewer (filePath, moduleName, scrollToLine) {
2760 const panel = document.getElementById('detail-content')
2761 panel.innerHTML = '<h2>Loading...</h2>'
2762
2763 try {
2764 const resp = await fetch(API + '/api/file?path=' + encodeURIComponent(filePath))
2765 const data = await resp.json()
2766 if (data.error) {
2767 panel.innerHTML = '<h2>Error</h2><pre>' + escapeHtml(data.error) + '</pre>'
2768 return
2769 }
2770
2771 const lines = data.content.split('\\n')
2772 let html = '<div class="file-viewer-header">'
2773 html += '<span class="fv-path">' + (moduleName ? moduleName + '/' : '') + data.path + '</span>'
2774 html += '<span class="fv-info">' + lines.length + ' lines</span>'
2775 html += '</div>'
2776 html += '<div class="file-viewer"><table>'
2777
2778 for (let i = 0; i < lines.length; i++) {
2779 const lineNum = i + 1
2780 const highlighted = scrollToLine && lineNum === scrollToLine ? ' highlight' : ''
2781 html += '<tr id="L' + lineNum + '" class="' + highlighted + '">'
2782 html += '<td class="line-no">' + lineNum + '</td>'
2783 html += '<td class="line-code">' + syntaxHighlight(escapeHtml(lines[i])) + '</td>'
2784 html += '</tr>'
2785 }
2786
2787 html += '</table></div>'
2788 panel.innerHTML = html
2789
2790 // Scroll to highlighted line
2791 if (scrollToLine) {
2792 const row = document.getElementById('L' + scrollToLine)
2793 if (row) row.scrollIntoView({ block: 'center', behavior: 'smooth' })
2794 }
2795 } catch (err) {
2796 panel.innerHTML = '<h2>Error</h2><pre>' + escapeHtml(err.message) + '</pre>'
2797 }
2798}
2799
2800var synCmt = new RegExp('(' + '/' + '/.*$)')
2801var synStr = new RegExp("(&quot;[^&]*&quot;|&#39;[^&]*&#39;|'[^']*'|" + '"[^"]*")', 'g')
2802var synKw = new RegExp('\\\\b(import|export|from|const|let|var|function|class|extends|return|if|else|for|while|switch|case|break|continue|new|this|async|await|throw|try|catch|typeof|instanceof|default|yield)\\\\b', 'g')
2803var synNum = new RegExp('\\\\b(\\\\d+\\\\.?\\\\d*)\\\\b', 'g')
2804var synFn = new RegExp('\\\\b([a-zA-Z_]\\\\w*)\\\\s*\\\\(', 'g')
2805
2806function syntaxHighlight (line) {
2807 line = line.replace(synCmt, '<span class="syn-cmt">$1</span>')
2808 line = line.replace(synStr, '<span class="syn-str">$1</span>')
2809 line = line.replace(synKw, '<span class="syn-kw">$1</span>')
2810 line = line.replace(synNum, '<span class="syn-num">$1</span>')
2811 line = line.replace(synFn, '<span class="syn-fn">$1</span>(')
2812 return line
2813}
2814
2815// ====== GRAPH -> RIGHT PANEL INTEGRATION ======
2816function showGraphModulePanel (name, mod) {
2817 const rp = document.getElementById('right-panel')
2818 rp.style.display = 'block'
2819 document.getElementById('resize-right').style.display = ''
2820
2821 // Show structure tab with module overview
2822 const panel = document.getElementById('structure-content')
2823 let html = '<h2 style="font-size:13px;color:#f0883e;margin-bottom:8px">' + name + ' <span style="color:#8b949e">' + mod.version + '</span></h2>'
2824
2825 // Public API
2826 if (mod.publicAPI.length > 0) {
2827 html += '<div class="detail"><h3>Public API (' + mod.publicAPI.length + ')</h3>'
2828 for (const exp of mod.publicAPI) {
2829 html += '<div style="padding:1px 0;font-size:12px;color:#3fb950">' + exp + '</div>'
2830 }
2831 html += '</div>'
2832 }
2833
2834 // Dependencies (local only)
2835 const localDeps = Object.entries(mod.dependencies).filter(([d]) => tree.modules[d])
2836 const externalDeps = Object.entries(mod.dependencies).filter(([d]) => !tree.modules[d])
2837 if (localDeps.length > 0) {
2838 html += '<div class="detail"><h3 style="color:#3fb950">Local Dependencies</h3>'
2839 for (const [dep, ver] of localDeps) {
2840 html += '<div style="padding:1px 0;font-size:12px"><span style="color:#58a6ff">' + dep + '</span> <span style="color:#484f58">' + ver + '</span></div>'
2841 }
2842 html += '</div>'
2843 }
2844 if (externalDeps.length > 0) {
2845 html += '<div class="detail"><h3>External Dependencies (' + externalDeps.length + ')</h3>'
2846 for (const [dep, ver] of externalDeps) {
2847 html += '<div style="padding:1px 0;font-size:11px;color:#8b949e">' + dep + ' ' + ver + '</div>'
2848 }
2849 html += '</div>'
2850 }
2851
2852 // Files overview
2853 const files = Object.entries(mod.files)
2854 html += '<div class="detail"><h3>Files (' + files.length + ')</h3>'
2855 for (const [path, file] of files) {
2856 const counts = []
2857 if (file.classes) counts.push(file.classes.length + ' cls')
2858 if (file.functions) counts.push(file.functions.length + ' fn')
2859 html += '<div style="padding:1px 0;font-size:11px"><span style="color:#8b949e">' + path + '</span>' +
2860 (counts.length ? ' <span style="color:#484f58">' + counts.join(', ') + '</span>' : '') + '</div>'
2861 }
2862 html += '</div>'
2863
2864 // Test command
2865 if (mod.testCommand) {
2866 html += '<div class="detail"><h3>Test</h3><pre style="font-size:11px"><code>' + mod.testCommand + '</code></pre></div>'
2867 }
2868
2869 panel.innerHTML = html
2870 switchRightPanel('structure')
2871
2872 // Also populate validation if available
2873 if (tree.validation && tree.validation.modules[name]) {
2874 renderValidation(name)
2875 }
2876
2877 // Load spec file into docs tab
2878 loadSpecForModule(name)
2879}
2880
2881function showGraphItemPanel (type, data, name) {
2882 const rp = document.getElementById('right-panel')
2883 rp.style.display = 'block'
2884 document.getElementById('resize-right').style.display = ''
2885
2886 const panel = document.getElementById('structure-content')
2887 let html = ''
2888
2889 if (type === 'class') {
2890 const cls = data
2891 html = '<h2 style="font-size:13px;color:#d2a8ff;margin-bottom:8px">class ' + cls.name + (cls.extends ? ' <span style="color:#8b949e">extends ' + cls.extends + '</span>' : '') + '</h2>'
2892
2893 if (cls.jsdoc) {
2894 html += '<div class="detail"><h3>JSDoc</h3><pre style="font-size:11px"><code>' + escapeHtml(cls.jsdoc) + '</code></pre></div>'
2895 }
2896
2897 if (cls.constructor) {
2898 html += '<div class="detail"><h3 style="color:#ffa657">Constructor</h3>'
2899 html += '<div style="font-size:12px">constructor(' + cls.constructor.params.join(', ') + ')</div>'
2900 if (cls.constructor.jsdoc) html += '<pre style="font-size:10px;margin-top:4px"><code>' + escapeHtml(cls.constructor.jsdoc) + '</code></pre>'
2901 html += '</div>'
2902 }
2903
2904 if (cls.getters && cls.getters.length > 0) {
2905 html += '<div class="detail"><h3>Getters (' + cls.getters.length + ')</h3>'
2906 for (const g of cls.getters) html += '<div style="padding:1px 0;font-size:11px"><span style="color:#7ee787">get</span> ' + g.name + '</div>'
2907 html += '</div>'
2908 }
2909
2910 html += '<div class="detail"><h3>Methods (' + cls.methods.filter(m => m.kind !== 'field').length + ')</h3>'
2911 for (const m of cls.methods) {
2912 if (m.kind === 'field') continue
2913 const tags = m.async ? ' <span style="color:#7ee787;font-size:9px">async</span>' : ''
2914 const lineRef = m.line ? ' <span style="color:#484f58;font-size:9px;cursor:pointer" onclick="scrollFileToLine(' + m.line + ')">:' + m.line + '</span>' : ''
2915 html += '<div style="padding:2px 0;font-size:11px"><span style="color:#79c0ff">' + m.name + '</span>(' + m.params.join(', ') + ')' + tags + lineRef
2916 if (m.jsdoc) html += '<div style="font-size:9px;color:#484f58;margin:2px 0 4px;padding-left:8px">' + escapeHtml(m.jsdoc).slice(0, 120) + (m.jsdoc.length > 120 ? '...' : '') + '</div>'
2917 html += '</div>'
2918 }
2919 html += '</div>'
2920 } else if (type === 'function') {
2921 const fn = data
2922 html = '<h2 style="font-size:13px;color:#79c0ff;margin-bottom:8px">' + fn.name + '</h2>'
2923 const tags = (fn.async ? 'async ' : '') + (fn.arrow ? '=> ' : '')
2924 html += '<pre style="font-size:12px"><code>' + tags + fn.name + '(' + fn.params.join(', ') + ')</code></pre>'
2925 if (fn.jsdoc) {
2926 html += '<div class="detail"><h3>JSDoc</h3><pre style="font-size:11px"><code>' + escapeHtml(fn.jsdoc) + '</code></pre></div>'
2927 }
2928 }
2929
2930 panel.innerHTML = html
2931 switchRightPanel('structure')
2932
2933 // Also load file source into docs tab scrolled to the item
2934 if (currentFileContext && data.line) {
2935 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
2936 loadFileIntoDocsTab(modPath + currentFileContext.path, data.line)
2937 }
2938}
2939
2940// ====== DOCS LOADING ======
2941async function loadSpecForModule (moduleName) {
2942 const docsPanel = document.getElementById('docs-content')
2943
2944 // Build candidate spec locations. Prefer the discovered specDir (from scanner.js
2945 // findAllDocs()) — this is the project's actual spec directory, not a hardcoded path.
2946 const specPaths = []
2947 if (tree.docs && tree.docs.specDir) {
2948 // specDir is absolute; convert to project-relative for the /api/file endpoint
2949 const rel = tree.docs.specDir.startsWith(tree.root)
2950 ? tree.docs.specDir.slice(tree.root.length + 1)
2951 : tree.docs.specDir
2952 specPaths.push(rel + '/modules/' + moduleName + '.md')
2953 }
2954 // Conventional fallbacks (no hardcoded project names)
2955 specPaths.push(
2956 'spec/modules/' + moduleName + '.md',
2957 'docs/spec/modules/' + moduleName + '.md',
2958 moduleName + '/README.md'
2959 )
2960
2961 for (const specPath of specPaths) {
2962 try {
2963 const resp = await fetch(API + '/api/file?path=' + encodeURIComponent(specPath))
2964 const data = await resp.json()
2965 if (data.error) continue
2966
2967 let html = '<h2 style="font-size:12px;color:#58a6ff;margin-bottom:4px">' + specPath + '</h2>'
2968 html += '<div class="file-viewer" style="max-height:calc(100vh - 100px);font-size:11px"><table>'
2969 const lines = data.content.split('\\n')
2970 for (let i = 0; i < lines.length; i++) {
2971 html += '<tr><td class="line-no">' + (i + 1) + '</td><td class="line-code">' + renderMarkdownLine(escapeHtml(lines[i])) + '</td></tr>'
2972 }
2973 html += '</table></div>'
2974 docsPanel.innerHTML = html
2975 return
2976 } catch {}
2977 }
2978
2979 docsPanel.innerHTML = '<h2 style="color:#8b949e">No spec file found for ' + moduleName + '</h2>' +
2980 '<p style="color:#484f58;font-size:11px">Searched:<br>' + specPaths.join('<br>') + '</p>'
2981}
2982
2983function renderMarkdownLine (line) {
2984 // Minimal markdown rendering for spec files
2985 if (line.startsWith('# ')) return '<span style="color:#58a6ff;font-weight:bold;font-size:14px">' + line.slice(2) + '</span>'
2986 if (line.startsWith('## ')) return '<span style="color:#58a6ff;font-weight:bold;font-size:13px">' + line.slice(3) + '</span>'
2987 if (line.startsWith('### ')) return '<span style="color:#58a6ff;font-size:12px">' + line.slice(4) + '</span>'
2988 if (line.startsWith('- ')) return '<span style="color:#8b949e"> </span>' + line.slice(2)
2989 if (line.startsWith('**') && line.includes(':**')) {
2990 return line.replace(/\*\*([^*]+)\*\*/g, '<span style="color:#ffa657;font-weight:bold">$1</span>')
2991 }
2992 // Inline code (use char code to avoid backtick in template literal)
2993 var bt = String.fromCharCode(96)
2994 var inlineCodeRe = new RegExp(bt + '([^' + bt + ']+)' + bt, 'g')
2995 line = line.replace(inlineCodeRe, '<span style="color:#79c0ff;background:#161b22;padding:0 3px;border-radius:2px">$1</span>')
2996 // Bold
2997 line = line.replace(new RegExp('\\\\*\\\\*([^*]+)\\\\*\\\\*', 'g'), '<span style="font-weight:bold">$1</span>')
2998 return line
2999}
3000
3001async function loadFileIntoDocsTab (filePath, scrollToLine) {
3002 const docsPanel = document.getElementById('docs-content')
3003 try {
3004 const resp = await fetch(API + '/api/file?path=' + encodeURIComponent(filePath))
3005 const data = await resp.json()
3006 if (data.error) {
3007 docsPanel.innerHTML = '<p style="color:#ff7b72">' + data.error + '</p>'
3008 return
3009 }
3010 const lines = data.content.split('\\n')
3011 let html = '<h2 style="font-size:12px;color:#58a6ff;margin-bottom:4px">' + data.path + ' <span style="color:#484f58">' + lines.length + ' lines</span></h2>'
3012 html += '<div class="file-viewer" style="max-height:calc(100vh - 100px)"><table>'
3013 for (let i = 0; i < lines.length; i++) {
3014 const lineNum = i + 1
3015 const hl = scrollToLine && lineNum === scrollToLine ? ' highlight' : ''
3016 html += '<tr id="DL' + lineNum + '" class="' + hl + '"><td class="line-no">' + lineNum + '</td><td class="line-code">' + syntaxHighlight(escapeHtml(lines[i])) + '</td></tr>'
3017 }
3018 html += '</table></div>'
3019 docsPanel.innerHTML = html
3020 if (scrollToLine) {
3021 var row = document.getElementById('DL' + scrollToLine)
3022 if (row) row.scrollIntoView({ block: 'center' })
3023 }
3024 } catch (err) {
3025 docsPanel.innerHTML = '<p style="color:#ff7b72">' + err.message + '</p>'
3026 }
3027}
3028
3029// ====== RIGHT PANEL TABS ======
3030let rightPanelTab = 'structure'
3031
3032window.switchRightPanel = function (tab) {
3033 rightPanelTab = tab
3034 document.getElementById('rp-structure').style.display = tab === 'structure' ? 'block' : 'none'
3035 document.getElementById('rp-validation').style.display = tab === 'validation' ? 'block' : 'none'
3036 document.getElementById('rp-docs').style.display = tab === 'docs' ? 'block' : 'none'
3037 document.querySelectorAll('#right-panel-tabs .tab').forEach(t => {
3038 t.classList.toggle('active', t.dataset.rp === tab)
3039 })
3040}
3041
3042function showStructurePanel (filePath, file, moduleName) {
3043 const panel = document.getElementById('structure-content')
3044 const rp = document.getElementById('right-panel')
3045 rp.style.display = 'block'
3046 document.getElementById('resize-right').style.display = ''
3047 switchRightPanel('structure')
3048
3049 let html = '<h2 style="font-size:13px;color:#58a6ff;margin-bottom:8px">' + (filePath.includes('/') ? filePath.split('/').pop() : filePath) + '</h2>'
3050
3051 if (file.role) html += '<span class="badge" style="margin-bottom:8px;display:inline-block">' + file.role + '</span> '
3052
3053 // Exports
3054 if (file.exports && file.exports.length > 0) {
3055 html += '<div class="detail"><h3>Exports (' + file.exports.length + ')</h3>'
3056 for (const e of file.exports) {
3057 const type = e.type ? ' <span style="color:#8b949e">(' + e.type + ')</span>' : ''
3058 const from = e.from ? ' <span style="color:#484f58">from ' + e.from + '</span>' : ''
3059 html += '<div style="padding:1px 0;font-size:12px"><span style="color:#3fb950">' + e.name + '</span>' + type + from + '</div>'
3060 }
3061 html += '</div>'
3062 }
3063
3064 // Imports
3065 if (file.imports && file.imports.length > 0) {
3066 html += '<div class="detail"><h3>Imports (' + file.imports.length + ')</h3>'
3067 for (const i of file.imports) {
3068 html += '<div style="padding:1px 0;font-size:12px"><span style="color:#79c0ff">' + i.names.join(', ') + '</span> <span style="color:#484f58">from</span> <span style="color:#8b949e">' + i.specifier + '</span></div>'
3069 }
3070 html += '</div>'
3071 }
3072
3073 // Classes
3074 if (file.classes && file.classes.length > 0) {
3075 for (const cls of file.classes) {
3076 html += '<div class="detail"><h3 style="color:#d2a8ff">class ' + cls.name + (cls.extends ? ' extends ' + cls.extends : '') + '</h3>'
3077 if (cls.constructor) {
3078 html += '<div style="padding:2px 0;font-size:11px;color:#ffa657">constructor(' + cls.constructor.params.join(', ') + ')</div>'
3079 }
3080 if (cls.getters && cls.getters.length > 0) {
3081 html += '<div style="margin-top:4px;font-size:10px;color:#484f58;text-transform:uppercase">Getters</div>'
3082 for (const g of cls.getters) {
3083 html += '<div style="padding:1px 0;font-size:11px"><span style="color:#7ee787">get</span> ' + g.name + '</div>'
3084 }
3085 }
3086 html += '<div style="margin-top:4px;font-size:10px;color:#484f58;text-transform:uppercase">Methods (' + cls.methods.filter(m => m.kind !== 'field').length + ')</div>'
3087 for (const m of cls.methods) {
3088 if (m.kind === 'field') continue
3089 const tags = (m.async ? '<span style="color:#7ee787;font-size:9px"> async</span>' : '')
3090 const lineRef = m.line ? ' <span style="color:#484f58;font-size:9px;cursor:pointer" onclick="scrollFileToLine(' + m.line + ')">:' + m.line + '</span>' : ''
3091 html += '<div style="padding:1px 0;font-size:11px"><span style="color:#79c0ff">' + m.name + '</span>(' + m.params.join(', ') + ')' + tags + lineRef + '</div>'
3092 }
3093 html += '</div>'
3094 }
3095 }
3096
3097 // Functions
3098 if (file.functions && file.functions.length > 0) {
3099 html += '<div class="detail"><h3>Functions (' + file.functions.length + ')</h3>'
3100 for (const fn of file.functions) {
3101 const tags = (fn.async ? '<span style="color:#7ee787;font-size:9px"> async</span>' : '') +
3102 (fn.arrow ? '<span style="color:#79c0ff;font-size:9px"> =></span>' : '')
3103 const lineRef = fn.line ? ' <span style="color:#484f58;font-size:9px;cursor:pointer" onclick="scrollFileToLine(' + fn.line + ')">:' + fn.line + '</span>' : ''
3104 html += '<div style="padding:1px 0;font-size:11px"><span style="color:#79c0ff">' + fn.name + '</span>(' + fn.params.join(', ') + ')' + tags + lineRef + '</div>'
3105 }
3106 html += '</div>'
3107 }
3108
3109 // State
3110 if (file.state && file.state.length > 0) {
3111 html += '<div class="detail"><h3>State</h3>'
3112 for (const s of file.state) html += '<div style="padding:1px 0;font-size:11px;color:#ffa657">' + s + '</div>'
3113 html += '</div>'
3114 }
3115
3116 // Delegation
3117 if (file.delegates && file.delegates.length > 0) {
3118 html += '<div class="detail"><h3>Delegation</h3>'
3119 for (const d of file.delegates) {
3120 html += '<div style="padding:1px 0;font-size:11px">' + d.field + ' <span style="color:#484f58">-></span> ' + d.methods.join(', ') + '</div>'
3121 }
3122 html += '</div>'
3123 }
3124
3125 // Errors
3126 if (file.errorContracts && file.errorContracts.length > 0) {
3127 html += '<div class="detail"><h3>Error Contracts (' + file.errorContracts.length + ')</h3>'
3128 for (const e of file.errorContracts) {
3129 html += '<div style="padding:1px 0;font-size:11px;color:#ff7b72">' + escapeHtml(e) + '</div>'
3130 }
3131 html += '</div>'
3132 }
3133
3134 // GDScript signals
3135 if (file.signals && file.signals.length > 0) {
3136 html += '<div class="detail"><h3>Signals (' + file.signals.length + ')</h3>'
3137 for (const sig of file.signals) {
3138 html += '<div style="padding:1px 0;font-size:11px;color:#f0883e">' +
3139 escapeHtml(sig.name) + '(' + (sig.params || []).map(escapeHtml).join(', ') + ')</div>'
3140 }
3141 html += '</div>'
3142 }
3143
3144 // Enums (GDScript, C++)
3145 if (file.enums && file.enums.length > 0) {
3146 html += '<div class="detail"><h3>Enums (' + file.enums.length + ')</h3>'
3147 for (const e of file.enums) {
3148 html += '<div style="padding:2px 0;font-size:11px"><span style="color:#d2a8ff">' + escapeHtml(e.name) + '</span>'
3149 if (e.values && e.values.length > 0) {
3150 html += '<span style="color:#8b949e"> { ' + e.values.slice(0, 6).map(escapeHtml).join(', ') +
3151 (e.values.length > 6 ? ', ...' : '') + ' }</span>'
3152 }
3153 html += '</div>'
3154 }
3155 html += '</div>'
3156 }
3157
3158 // C++ namespaces
3159 if (file.namespaces && file.namespaces.length > 0) {
3160 html += '<div class="detail"><h3>Namespaces</h3>'
3161 html += '<div style="padding:2px 0;font-size:11px;color:#79c0ff">' +
3162 file.namespaces.map(escapeHtml).join(', ') + '</div>'
3163 html += '</div>'
3164 }
3165
3166 // GLSL shader resources
3167 if (file.uniforms && file.uniforms.length > 0) {
3168 html += '<div class="detail"><h3>Uniforms (' + file.uniforms.length + ')</h3>'
3169 for (const u of file.uniforms) {
3170 const binding = u.set !== null && u.binding !== null
3171 ? ' <span style="color:#8b949e">(set=' + u.set + ', binding=' + u.binding + ')</span>'
3172 : (u.type ? ' <span style="color:#8b949e">' + escapeHtml(u.type) + '</span>' : '')
3173 html += '<div style="padding:1px 0;font-size:11px;color:#3fb950">' +
3174 escapeHtml(u.name) + binding + '</div>'
3175 }
3176 html += '</div>'
3177 }
3178
3179 if (file.buffers && file.buffers.length > 0) {
3180 html += '<div class="detail"><h3>Buffers (' + file.buffers.length + ')</h3>'
3181 for (const b of file.buffers) {
3182 const mode = b.readonly ? 'RO' : b.writeonly ? 'WO' : 'RW'
3183 html += '<div style="padding:1px 0;font-size:11px;color:#ffa657">' +
3184 escapeHtml(b.name) + ' <span style="color:#8b949e">' + mode +
3185 ' (set=' + (b.set || '?') + ', binding=' + (b.binding || '?') + ')</span></div>'
3186 }
3187 html += '</div>'
3188 }
3189
3190 if (file.pushConstants && file.pushConstants.length > 0) {
3191 html += '<div class="detail"><h3>Push Constants (' + file.pushConstants.length + ')</h3>'
3192 for (const p of file.pushConstants) {
3193 html += '<div style="padding:1px 0;font-size:11px;color:#d2a8ff">' + escapeHtml(p.name) + '</div>'
3194 }
3195 html += '</div>'
3196 }
3197
3198 if (!file.exports && !file.classes && !file.functions && !file.signals && !file.uniforms && !file.buffers) {
3199 html += '<p style="color:#8b949e;font-size:12px">No structural data</p>'
3200 }
3201
3202 panel.innerHTML = html
3203}
3204
3205window.scrollFileToLine = function (line) {
3206 const row = document.getElementById('L' + line)
3207 if (row) {
3208 // Clear previous highlights
3209 document.querySelectorAll('.file-viewer tr.highlight').forEach(r => r.classList.remove('highlight'))
3210 row.classList.add('highlight')
3211 row.scrollIntoView({ block: 'center', behavior: 'smooth' })
3212 }
3213}
3214
3215// ====== VALIDATION PANEL ======
3216let valInitialized = false
3217let valFilter = 'all' // 'all' | 'fail' | 'warn' | 'pass'
3218
3219function initValidation () {
3220 valInitialized = true
3221 const panel = document.getElementById('val-content')
3222 const v = tree.validation
3223
3224 if (!v) {
3225 panel.innerHTML = '<p style="color:#8b949e">No spec directory found. Place specs in a <code>spec/</code> directory with <code>SYSTEM.md</code> and <code>modules/*.md</code> files.</p>'
3226 return
3227 }
3228
3229 renderValidation(null) // show all
3230}
3231
3232function renderValidation (moduleName) {
3233 const panel = document.getElementById('val-content')
3234 const v = tree.validation
3235 if (!v) return
3236
3237 let html = ''
3238
3239 // Summary bar
3240 html += '<div class="val-summary">'
3241 html += '<div class="val-pass"><span class="val-count">' + v.summary.pass + '</span>pass</div>'
3242 html += '<div class="val-fail"><span class="val-count">' + v.summary.fail + '</span>fail</div>'
3243 html += '<div class="val-warn"><span class="val-count">' + v.summary.warn + '</span>warn</div>'
3244 html += '<div style="color:#8b949e"><span class="val-count">' + v.summary.total + '</span>total</div>'
3245 html += '</div>'
3246
3247 // Filter buttons
3248 html += '<div class="val-filter">'
3249 html += '<button class="' + (valFilter === 'all' ? 'active' : '') + '" onclick="setValFilter(&quot;all&quot;)">All</button>'
3250 html += '<button class="' + (valFilter === 'fail' ? 'active' : '') + '" onclick="setValFilter(&quot;fail&quot;)">Fails</button>'
3251 html += '<button class="' + (valFilter === 'warn' ? 'active' : '') + '" onclick="setValFilter(&quot;warn&quot;)">Warns</button>'
3252 html += '<button class="' + (valFilter === 'pass' ? 'active' : '') + '" onclick="setValFilter(&quot;pass&quot;)">Pass</button>'
3253 html += '</div>'
3254
3255 // System checks
3256 if (v.system && (!moduleName || moduleName === 'system')) {
3257 const checks = filterChecks(v.system.checks)
3258 if (checks.length > 0) {
3259 html += '<div class="val-section"><h3>System</h3>'
3260 html += renderChecks(checks)
3261 html += '</div>'
3262 }
3263 }
3264
3265 // Module checks
3266 const modules = moduleName && moduleName !== 'system'
3267 ? [[moduleName, v.modules[moduleName]]]
3268 : Object.entries(v.modules)
3269
3270 for (const [name, modReport] of modules) {
3271 if (!modReport) continue
3272 const checks = filterChecks(modReport.checks)
3273 if (checks.length === 0) continue
3274
3275 const failCount = modReport.checks.filter(c => c.status === 'fail').length
3276 const warnCount = modReport.checks.filter(c => c.status === 'warn').length
3277 const passCount = modReport.checks.filter(c => c.status === 'pass').length
3278
3279 html += '<div class="val-section">'
3280 html += '<h3 onclick="renderValidation(&quot;' + name + '&quot;)" style="cursor:pointer">'
3281 html += name
3282 html += ' <span class="val-pass">' + passCount + '</span>'
3283 if (failCount) html += ' <span class="val-fail">' + failCount + ' fail</span>'
3284 if (warnCount) html += ' <span class="val-warn">' + warnCount + ' warn</span>'
3285 html += '</h3>'
3286 html += renderChecks(checks)
3287 html += '</div>'
3288 }
3289
3290 // Back button if filtered to one module
3291 if (moduleName) {
3292 html += '<div style="margin-top:12px"><button style="background:#161b22;border:1px solid #30363d;border-radius:4px;color:#58a6ff;padding:4px 12px;cursor:pointer;font-family:inherit;font-size:11px" onclick="renderValidation(null)">Show all modules</button></div>'
3293 }
3294
3295 panel.innerHTML = html
3296}
3297
3298function filterChecks (checks) {
3299 if (valFilter === 'all') return checks
3300 return checks.filter(c => c.status === valFilter)
3301}
3302
3303function renderChecks (checks) {
3304 let html = ''
3305 for (const c of checks) {
3306 const icon = c.status === 'pass' ? '&#10003;' : c.status === 'fail' ? '&#10007;' : '&#9888;'
3307 html += '<div class="val-check ' + c.status + '">'
3308 html += '<span class="val-icon">' + icon + '</span>'
3309 html += '<span class="val-claim">' + escapeHtml(c.claim) + '</span>'
3310 if (c.detail) html += '<div class="val-detail">' + escapeHtml(c.detail) + '</div>'
3311 html += '</div>'
3312 }
3313 return html
3314}
3315
3316window.setValFilter = function (f) {
3317 valFilter = f
3318 renderValidation(null)
3319}
3320
3321// Expose for onclick in rendered HTML
3322window.renderValidation = renderValidation
3323
3324// Also update validation when clicking modules in tree view
3325function showValidationForModule (name) {
3326 if (tree.validation && tree.validation.modules[name]) {
3327 document.getElementById('right-panel').style.display = 'block'
3328 document.getElementById('resize-right').style.display = ''
3329 switchRightPanel('validation')
3330 renderValidation(name)
3331 }
3332}
3333
3334// ====== TREE EXPAND/COLLAPSE ======
3335window.expandAll = function () {
3336 document.querySelectorAll('#tree-root li.collapsed').forEach(li => {
3337 li.classList.remove('collapsed')
3338 const toggle = li.querySelector(':scope > .node .toggle')
3339 if (toggle) toggle.textContent = '-'
3340 })
3341}
3342
3343window.collapseAll = function () {
3344 document.querySelectorAll('#tree-root li').forEach(li => {
3345 if (li.querySelector('ul')) {
3346 li.classList.add('collapsed')
3347 const toggle = li.querySelector(':scope > .node .toggle')
3348 if (toggle) toggle.textContent = '+'
3349 }
3350 })
3351}
3352
3353// ====== VALIDATION HELPERS ======
3354function getModuleValidation (name) {
3355 if (!tree.validation || !tree.validation.modules[name]) return null
3356 const checks = tree.validation.modules[name].checks
3357 return {
3358 pass: checks.filter(c => c.status === 'pass').length,
3359 fail: checks.filter(c => c.status === 'fail').length,
3360 warn: checks.filter(c => c.status === 'warn').length,
3361 total: checks.length
3362 }
3363}
3364
3365function valBadgeHTML (name) {
3366 const v = getModuleValidation(name)
3367 if (!v) return '<span class="val-badge val-badge-none">no spec</span>'
3368 if (v.fail > 0) return '<span class="val-badge val-badge-fail">' + v.fail + ' fail</span>' + (v.warn > 0 ? '<span class="val-badge val-badge-warn">' + v.warn + ' warn</span>' : '')
3369 if (v.warn > 0) return '<span class="val-badge val-badge-warn">' + v.warn + ' warn</span>'
3370 return '<span class="val-badge val-badge-pass">' + v.pass + ' ok</span>'
3371}
3372
3373// ====== TREE DEP HIGHLIGHTING ======
3374function highlightTreeDeps (moduleName) {
3375 // Clear previous highlights
3376 document.querySelectorAll('.dep-highlight, .used-by-highlight, .selected-module').forEach(el => {
3377 el.classList.remove('dep-highlight', 'used-by-highlight', 'selected-module')
3378 })
3379
3380 const mod = tree.modules[moduleName]
3381 if (!mod) return
3382
3383 // Find local deps (modules that exist in the scan)
3384 const localDeps = new Set()
3385 for (const dep of Object.keys(mod.dependencies)) {
3386 if (tree.modules[dep]) localDeps.add(dep)
3387 }
3388
3389 // Find reverse deps (modules that depend on this one)
3390 const usedBy = new Set()
3391 for (const [otherName, otherMod] of Object.entries(tree.modules)) {
3392 if (otherName === moduleName) continue
3393 if (otherMod.dependencies[moduleName]) usedBy.add(otherName)
3394 }
3395
3396 // Highlight matching module nodes in the tree
3397 document.querySelectorAll('#tree-root .node[data-type="module"]').forEach(node => {
3398 const name = node.dataset.name
3399 if (name === moduleName) node.classList.add('selected-module')
3400 else if (localDeps.has(name)) node.classList.add('dep-highlight')
3401 else if (usedBy.has(name)) node.classList.add('used-by-highlight')
3402 })
3403}
3404
3405// ====== SEARCH ======
3406document.getElementById('search').addEventListener('input', (e) => {
3407 const q = e.target.value.toLowerCase()
3408 const nodes = document.querySelectorAll('#tree-root .node')
3409 for (const node of nodes) {
3410 const name = (node.dataset.name || '').toLowerCase()
3411 const text = node.textContent.toLowerCase()
3412 const match = !q || name.includes(q) || text.includes(q)
3413 node.parentElement.style.display = match ? '' : 'none'
3414 if (match && q) {
3415 let parent = node.parentElement.parentElement
3416 while (parent) {
3417 if (parent.classList && parent.classList.contains('collapsed')) {
3418 parent.classList.remove('collapsed')
3419 const toggle = parent.querySelector(':scope > .node .toggle')
3420 if (toggle) toggle.textContent = '-'
3421 }
3422 parent = parent.parentElement
3423 }
3424 }
3425 }
3426})
3427
3428// ====== STATS ======
3429function updateStats () {
3430 const stats = document.getElementById('stats')
3431 let totalFiles = 0, totalClasses = 0, totalMethods = 0, totalExports = 0
3432 for (const mod of Object.values(tree.modules)) {
3433 totalFiles += Object.keys(mod.files).length
3434 totalExports += mod.publicAPI.length
3435 for (const file of Object.values(mod.files)) {
3436 if (file.classes) {
3437 totalClasses += file.classes.length
3438 for (const cls of file.classes) totalMethods += cls.methods.length + (cls.getters ? cls.getters.length : 0)
3439 }
3440 }
3441 }
3442 stats.innerHTML =
3443 '<span><span class="stat-value">' + tree.system.modules.length + '</span> modules</span>' +
3444 '<span><span class="stat-value">' + totalFiles + '</span> files</span>' +
3445 '<span><span class="stat-value">' + totalClasses + '</span> classes</span>' +
3446 '<span><span class="stat-value">' + totalMethods + '</span> members</span>' +
3447 '<span><span class="stat-value">' + totalExports + '</span> exports</span>'
3448}
3449
3450// ====== HELPERS ======
3451function el (tag, attrs) {
3452 const e = document.createElement(tag)
3453 if (attrs) for (const [k, v] of Object.entries(attrs)) {
3454 if (k.startsWith('data-')) e.setAttribute(k, v)
3455 else e[k] = v
3456 }
3457 return e
3458}
3459function sourceLink (line) {
3460 if (!currentFileContext) return ''
3461 const modPath = currentFileContext.moduleName ? tree.modules[currentFileContext.moduleName].path + '/' : ''
3462 const fullPath = modPath + currentFileContext.path
3463 return '<span class="badge" style="cursor:pointer;color:#58a6ff;border:1px solid #58a6ff;margin-bottom:8px;display:inline-block" ' +
3464 'onclick="loadFileViewer(&quot;' + fullPath + '&quot;,&quot;' + (currentFileContext.moduleName || '') + '&quot;,' + (line || 'null') + ')">' +
3465 'View Source' + (line ? ' :' + line : '') + '</span> '
3466}
3467
3468// Expose for onclick attributes
3469window.loadFileViewer = loadFileViewer
3470
3471function roleIcon (role) {
3472 return ({ entry: 'E', lib: 'L', test: 'T', schema: 'S', bin: 'B', script: 'X', example: 'x' })[role] || 'F'
3473}
3474function escapeHtml (s) {
3475 return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
3476}
3477
3478// ====== RESIZABLE PANELS ======
3479function initResizable () {
3480 makeResizable('resize-left', 'sidebar', 'right')
3481 makeResizable('resize-right', 'right-panel', 'left')
3482}
3483
3484function makeResizable (handleId, panelId, side) {
3485 const handle = document.getElementById(handleId)
3486 const panel = document.getElementById(panelId)
3487 if (!handle || !panel) return
3488
3489 let startX, startW
3490
3491 handle.addEventListener('mousedown', (e) => {
3492 e.preventDefault()
3493 e.stopPropagation()
3494 startX = e.clientX
3495 startW = panel.offsetWidth
3496 handle.classList.add('dragging')
3497 document.body.style.cursor = 'col-resize'
3498 document.body.style.userSelect = 'none'
3499
3500 const onMove = (e) => {
3501 const dx = e.clientX - startX
3502 const newW = side === 'right' ? startW + dx : startW - dx
3503 panel.style.width = Math.max(150, Math.min(800, newW)) + 'px'
3504 }
3505
3506 const onUp = () => {
3507 handle.classList.remove('dragging')
3508 document.body.style.cursor = ''
3509 document.body.style.userSelect = ''
3510 document.removeEventListener('mousemove', onMove)
3511 document.removeEventListener('mouseup', onUp)
3512 }
3513
3514 document.addEventListener('mousemove', onMove)
3515 document.addEventListener('mouseup', onUp)
3516 })
3517}
3518
3519// ====== INIT ======
3520buildTree()
3521initResizable()
3522</script>
3523</body>
3524</html>`
3525}
lib/scan-stream.js +311 -0
……@@ -0,0 +1,311 @@
1import { EventEmitter } from 'events'
2import { readFileSync, readdirSync, statSync } from 'fs'
3import { resolve, relative, join, basename, dirname } from 'path'
4
5import {
6 detectProject,
7 findModuleBoundaries,
8 buildResolutionContext,
9 readProjectMeta,
10 resolveEntry,
11 getLang,
12 isSourceFile
13} from './lang.js'
14import { buildIgnoreMatcher } from './ignore.js'
15
16/**
17 * Walk a project and emit events describing what was found.
18 *
19 * This is the push-based core of the scanner. Multiple consumers can
20 * subscribe to different events without forcing a second walk.
21 *
22 * const source = scanStream(rootDir, opts)
23 * source.on('file-parsed', e => ...)
24 * source.on('scan-end', e => ...)
25 *
26 * Events (all payload objects):
27 * scan-start { root, projectType, languages, resolutionContext }
28 * module-start { name, version, path, absPath, entry, meta, projectType,
29 * dependencies, devDependencies, importMaps, testCommand, type }
30 * file-discovered { modName, absPath, relPath, relInPkg, source, size }
31 * file-parsed { modName, relInPkg, relPath, parsed }
32 * import-edge { modName, fromRelInPkg, specifier, resolvedRelPath, implicit }
33 * module-end { name }
34 * scan-end { root, moduleCount, fileCount, dirTree }
35 * error Error
36 *
37 * The emitter returned from this function starts work on the next tick, giving
38 * callers a chance to attach listeners before the first event fires.
39 *
40 * There are NO timers anywhere in this file. Every async boundary is a
41 * promise/microtask or a listener callback.
42 */
43export function scanStream (rootDir, opts = {}) {
44 const emitter = new EventEmitter()
45 const root = resolve(rootDir)
46
47 // Defer the walk so callers can attach listeners first. queueMicrotask is
48 // push-based — no setTimeout, no Promise.resolve().then hack.
49 queueMicrotask(() => runScan(emitter, root, opts))
50
51 return emitter
52}
53
54function runScan (emitter, root, opts) {
55 try {
56 const ignore = opts.ignore || buildIgnoreMatcher(root)
57 const shallow = !!opts.shallow
58 const project = detectProject(root)
59 const resolutionContext = buildResolutionContext(root, project.type, ignore, { shallow })
60 resolutionContext.ignore = ignore
61
62 emitter.emit('scan-start', {
63 root,
64 projectType: project.type,
65 languages: project.languages,
66 shallow,
67 resolutionContext
68 })
69
70 const moduleDirs = findModuleBoundaries(root, project.type, {
71 maxDepth: opts.maxDepth || 2,
72 ignore
73 })
74
75 let moduleCount = 0
76 let fileCount = 0
77 const moduleAbsPaths = new Set(moduleDirs)
78
79 for (const pkgDir of moduleDirs) {
80 // Each module may be its own project type (monorepo case)
81 const modProject = detectProject(pkgDir)
82 const modType = modProject.type !== 'unknown' ? modProject.type : project.type
83 const meta = readProjectMeta(pkgDir, modType)
84 if (modType === 'js' && !meta) continue
85
86 const modName = (meta && meta.name) || basename(pkgDir)
87 const entry = resolveEntry(pkgDir, meta, modType)
88
89 emitter.emit('module-start', {
90 name: modName,
91 version: (meta && meta.version) || '0.0.0',
92 path: relative(root, pkgDir) || '.',
93 absPath: pkgDir,
94 entry,
95 meta,
96 projectType: modType,
97 dependencies: (meta && meta.dependencies) || {},
98 devDependencies: (meta && meta.devDependencies) || {},
99 importMaps: (meta && meta.imports) || {},
100 testCommand: meta && meta.scripts && meta.scripts.test ? meta.scripts.test : null,
101 type: (meta && meta.type) || 'commonjs'
102 })
103
104 if (shallow) {
105 // Shallow mode: parse ONLY the entry file (if any). No import resolution,
106 // no scanDir recursion, no cross-file analysis. This gives the UI enough
107 // to show every module + its public API without paying the full parse cost.
108 if (entry) {
109 fileCount += parseOneFile(emitter, entry, pkgDir, modName, root, ignore)
110 }
111 } else {
112 // Deep mode: walk entry + recursively scan module root, resolve imports.
113 const childModulePaths = new Set(
114 moduleDirs.filter(d => d !== pkgDir && d.startsWith(pkgDir + '/'))
115 )
116 const visited = new Set()
117
118 if (entry) {
119 fileCount += walkFile(emitter, entry, pkgDir, modName, visited, root, ignore, resolutionContext)
120 }
121 fileCount += scanDir(emitter, pkgDir, pkgDir, modName, visited, root, ignore, resolutionContext, childModulePaths)
122 }
123
124 emitter.emit('module-end', { name: modName })
125 moduleCount++
126 }
127
128 // Always build dirTree, even in shallow mode — the FS walk is cheap (just
129 // readdir+stat) compared to parsing, and the UI tree view needs structure.
130 // Without it the sidebar collapses to a flat list which is unreadable
131 // for monorepo-scale scans.
132 const dirTree = buildDirTree(root, moduleAbsPaths, ignore)
133
134 emitter.emit('scan-end', { root, moduleCount, fileCount, dirTree, shallow })
135 } catch (err) {
136 emitter.emit('error', err)
137 }
138}
139
140// Parse a single file (used by shallow mode). Emits file-discovered + file-parsed
141// but does NOT follow imports or recurse.
142function parseOneFile (emitter, filePath, pkgDir, modName, root, ignore) {
143 if (ignore(filePath)) return 0
144 let source
145 try { source = readFileSync(filePath, 'utf-8') } catch { return 0 }
146 const size = source.length
147 if (size > MAX_PARSE_SIZE) return 0
148
149 const relPath = relative(root, filePath)
150 const relInPkg = relative(pkgDir, filePath)
151
152 emitter.emit('file-discovered', { modName, absPath: filePath, relPath, relInPkg, size })
153
154 const lang = getLang(filePath)
155 if (!lang) return 1
156
157 try {
158 const parsed = lang.parse(source, relInPkg)
159 emitter.emit('file-parsed', { modName, relInPkg, relPath, parsed })
160 } catch (err) {
161 emitter.emit('file-parsed', { modName, relInPkg, relPath, parsed: { error: err.message, filePath: relInPkg } })
162 }
163 return 1
164}
165
166// --- Walking ---
167
168// Skip parsing files larger than this. Generated bindings and minified bundles
169// are almost always uninteresting for structural analysis, and their ASTs are
170// the dominant memory cost on large recursive scans.
171const MAX_PARSE_SIZE = 200 * 1024 // 200 KB
172
173function walkFile (emitter, filePath, pkgDir, modName, visited, root, ignore, ctx) {
174 if (visited.has(filePath)) return 0
175 visited.add(filePath)
176 if (ignore(filePath)) return 0
177
178 let source, size
179 try {
180 source = readFileSync(filePath, 'utf-8')
181 size = source.length
182 } catch {
183 return 0
184 }
185
186 const relPath = relative(root, filePath)
187 const relInPkg = relative(pkgDir, filePath)
188
189 // For oversized files, emit the discovery event so the tree knows the file
190 // exists, but skip parsing + import resolution. Saves memory and CPU.
191 if (size > MAX_PARSE_SIZE) {
192 emitter.emit('file-discovered', { modName, absPath: filePath, relPath, relInPkg, size })
193 emitter.emit('file-parsed', { modName, relInPkg, relPath, parsed: { error: 'file too large to parse', filePath: relInPkg } })
194 return 1
195 }
196
197 // Deliberately do NOT include source in the event — subscribers that actually
198 // need the bytes can readFileSync from absPath. Sending source by default
199 // means every listener retains it, which blew up memory on recursive scans.
200 emitter.emit('file-discovered', {
201 modName, absPath: filePath, relPath, relInPkg, size
202 })
203
204 const lang = getLang(filePath)
205 if (!lang) return 1
206
207 // Parse eagerly and emit. (Workers and mtime cache are future optimizations
208 // that plug in here — they just change who produces the file-parsed event.)
209 try {
210 const parsed = lang.parse(source, relInPkg)
211 emitter.emit('file-parsed', { modName, relInPkg, relPath, parsed })
212 } catch (err) {
213 emitter.emit('file-parsed', { modName, relInPkg, relPath, parsed: { error: err.message, filePath: relInPkg } })
214 }
215
216 // Resolve imports (explicit + implicit) and emit edges for each.
217 let count = 1
218 const explicit = lang.extractImports(source)
219 for (const spec of explicit) {
220 const resolved = lang.resolveImport(filePath, spec, ctx)
221 if (!resolved) continue
222 emitter.emit('import-edge', {
223 modName,
224 fromRelInPkg: relInPkg,
225 specifier: spec,
226 resolvedRelPath: relative(root, resolved),
227 implicit: false
228 })
229 count += walkFile(emitter, resolved, pkgDir, modName, visited, root, ignore, ctx)
230 }
231
232 if (lang.extractImplicitImports) {
233 const implicit = lang.extractImplicitImports(source, ctx)
234 for (const spec of implicit) {
235 const resolved = lang.resolveImport(filePath, spec, ctx)
236 if (!resolved || resolved === filePath) continue
237 emitter.emit('import-edge', {
238 modName,
239 fromRelInPkg: relInPkg,
240 specifier: spec,
241 resolvedRelPath: relative(root, resolved),
242 implicit: true
243 })
244 count += walkFile(emitter, resolved, pkgDir, modName, visited, root, ignore, ctx)
245 }
246 }
247
248 return count
249}
250
251function scanDir (emitter, dir, pkgDir, modName, visited, root, ignore, ctx, childModulePaths) {
252 let entries
253 try { entries = readdirSync(dir) } catch { return 0 }
254
255 let count = 0
256 for (const entry of entries) {
257 if (entry.startsWith('.')) continue
258 const full = join(dir, entry)
259 if (ignore(full)) continue
260 if (childModulePaths && childModulePaths.has(full)) continue
261
262 let stat
263 try { stat = statSync(full) } catch { continue }
264
265 if (stat.isDirectory()) {
266 count += scanDir(emitter, full, pkgDir, modName, visited, root, ignore, ctx, childModulePaths)
267 } else if (isSourceFile(full)) {
268 count += walkFile(emitter, full, pkgDir, modName, visited, root, ignore, ctx)
269 }
270 }
271 return count
272}
273
274// --- Directory tree ---
275
276function buildDirTree (root, moduleAbsPaths, ignore) {
277 return walkDir(root, root, moduleAbsPaths, 0, 8, ignore)
278}
279
280function walkDir (dir, root, moduleAbsPaths, depth, maxDepth, ignore) {
281 const name = basename(dir)
282 const relPath = relative(root, dir) || '.'
283 const node = {
284 name: depth === 0 ? basename(root) : name,
285 path: relPath,
286 type: moduleAbsPaths.has(dir) ? 'module-dir' : 'dir',
287 children: []
288 }
289 if (moduleAbsPaths.has(dir)) node.module = basename(dir)
290
291 if (depth >= maxDepth) return node
292
293 let entries
294 try { entries = readdirSync(dir).sort() } catch { return node }
295
296 // Only collect directories. File entries were a huge bloat in the dirTree
297 // payload (33 MB for /storage/projects/code/) and aren't used by the sidebar
298 // anymore — files for a focused module come from /api/file on demand.
299 for (const entry of entries) {
300 const full = join(dir, entry)
301 if (ignore(full)) continue
302 let stat
303 try { stat = statSync(full) } catch { continue }
304 if (!stat.isDirectory()) continue
305
306 const child = walkDir(full, root, moduleAbsPaths, depth + 1, maxDepth, ignore)
307 if (child.children.length > 0 || child.module) node.children.push(child)
308 }
309
310 return node
311}
lib/scanner.js +108 -0
……@@ -0,0 +1,108 @@
1import { existsSync } from 'fs'
2import { resolve, join } from 'path'
3
4import { scanStream } from './scan-stream.js'
5import { TreeReducer } from './reducers/tree-reducer.js'
6import { buildTree } from './tree.js'
7import { parseSpecs, findAllDocs } from './doc-parser.js'
8import { validate } from './validator.js'
9import { detectDocCruft } from './doc-cruft.js'
10import { buildIgnoreMatcher } from './ignore.js'
11
12// Re-export for consumers that want the push-based source directly
13export { scanStream } from './scan-stream.js'
14export { TreeReducer } from './reducers/tree-reducer.js'
15
16/**
17 * Scan a directory and produce the complete code tree + validation report.
18 *
19 * Internally this composes scanStream() with a TreeReducer. Other consumers
20 * (UI updaters, metrics, doc-cruft) can attach their own listeners to the
21 * stream — that's the whole point of the refactor. This function is one
22 * convenience consumer that returns the fully-built tree.
23 *
24 * opts:
25 * maxDepth: number — project-discovery depth (default 2)
26 * ignore: string[] — extra ignore patterns (from --ignore CLI flag)
27 * shallow: boolean — if true, only parse the entry file per module.
28 * No cross-file analysis, no doc-cruft, no
29 * resolution context. Orders of magnitude faster
30 * for multi-project / recursive scans.
31 */
32export async function scan (rootDir, opts = {}) {
33 // Build ignore matcher up front so every scan stage uses the same predicate.
34 const ignore = buildIgnoreMatcher(rootDir, opts.ignore || [])
35 const shallow = !!opts.shallow
36
37 // Drive the event source and reduce events into a graph.
38 const graph = await new Promise((resolve, reject) => {
39 const source = scanStream(rootDir, { ...opts, ignore, shallow })
40 const tree = new TreeReducer().attach(source)
41 source.once('scan-end', () => resolve(tree.finalize()))
42 source.once('error', reject)
43 })
44
45 const tree = buildTree(graph)
46
47 // Mark the tree so consumers know whether data is complete or shallow.
48 tree.shallow = shallow
49
50 // Attach the live graph as a non-enumerable property so consumers that need
51 // the incremental-update state (e.g. LiveStore in server.js) can reach it,
52 // but JSON serialization ignores it.
53 Object.defineProperty(tree, '__graph', { value: graph, enumerable: false })
54
55 // Doc cruft walks every .md file and cross-references against the tree.
56 // Skip in shallow mode — it's one of the most expensive steps and the
57 // tree doesn't have the structural detail needed for meaningful checks.
58 if (!shallow) {
59 tree.docCruft = detectDocCruft(rootDir, tree, ignore)
60 }
61
62 // Find and validate specs at the scan root (preserves existing behavior).
63 const docs = findAllDocs(rootDir)
64 let validation = null
65 let categories = null
66 if (docs.specDir) {
67 const specs = parseSpecs(docs.specDir)
68 validation = validate(tree, specs)
69 if (specs.system && specs.system.categories) {
70 categories = { ...specs.system.categories }
71 }
72 }
73
74 // Aggregate categories from spec/SYSTEM.md files nested INSIDE any discovered
75 // module. For a high-level scan like /storage/projects/code/, the curated
76 // SYSTEM.md sits 4+ levels deep (e.g. hypercore-kb/hyper-fleeky/pear-git-v3/
77 // spec/SYSTEM.md). Without this, the bubbles in the graph would lose all the
78 // semantic categories that were carefully defined in those spec files.
79 if (!categories) categories = {}
80 for (const mod of Object.values(tree.modules)) {
81 const modAbs = resolve(rootDir, mod.path)
82 const candidates = [join(modAbs, 'spec'), join(modAbs, 'docs', 'spec')]
83 for (const sd of candidates) {
84 if (!existsSync(join(sd, 'SYSTEM.md'))) continue
85 try {
86 const innerSpecs = parseSpecs(sd)
87 if (innerSpecs.system && innerSpecs.system.categories) {
88 for (const [cat, mods] of Object.entries(innerSpecs.system.categories)) {
89 if (!categories[cat]) categories[cat] = []
90 for (const m of mods) {
91 if (!categories[cat].includes(m)) categories[cat].push(m)
92 }
93 }
94 }
95 } catch {}
96 }
97 }
98
99 tree.validation = validation
100 tree.categories = Object.keys(categories).length > 0 ? categories : null
101 tree.docs = {
102 specDir: docs.specDir || null,
103 specCount: docs.specs.length,
104 readmeCount: docs.readmes.length
105 }
106
107 return tree
108}
lib/server.js +207 -0
……@@ -0,0 +1,207 @@
1import http from 'http'
2import { gzipSync } from 'zlib'
3import { readFileSync } from 'fs'
4import { resolve } from 'path'
5import { renderPage } from './render.js'
6import { buildIgnoreMatcher } from './ignore.js'
7import { LiveStore } from './live-store.js'
8
9export function startServer (tree, opts = {}) {
10 const port = opts.port || 9078
11 const prefix = opts.prefix || ''
12 const page = renderPage(tree, prefix)
13 const rootDir = tree.root
14
15 // Rebuild the ignore matcher so /api/file enforces the same hiding rules at runtime
16 // as the scan did at tree-build time. A file that wasn't in the tree won't have a
17 // request generated by the UI, but a crafted request could reach /api/file directly.
18 const ignore = buildIgnoreMatcher(rootDir, opts.ignore || [])
19
20 // Live store — subscribable event stream fed by fs.watch. opts.watch === false
21 // disables it (useful for one-shot CLI serve, or when the inotify limit
22 // would be exceeded by recursive watching of a huge tree).
23 const live = opts.graph
24 ? new LiveStore(opts.graph, { watch: opts.watch !== false })
25 : null
26 if (live) {
27 live.seedFromGraph()
28 live.start()
29 }
30
31 // --- Response helpers ---
32
33 // Compress the body with gzip if the client sent Accept-Encoding: gzip.
34 // Only compresses when the payload is worth it (>1KB). Below that the
35 // gzip overhead isn't worth the CPU.
36 function send (req, res, status, contentType, body) {
37 const accept = (req.headers['accept-encoding'] || '').toLowerCase()
38 const acceptsGzip = accept.includes('gzip')
39 const buf = typeof body === 'string' ? Buffer.from(body) : body
40
41 if (acceptsGzip && buf.length > 1024) {
42 const compressed = gzipSync(buf)
43 res.writeHead(status, {
44 'content-type': contentType,
45 'content-encoding': 'gzip',
46 'vary': 'Accept-Encoding'
47 })
48 res.end(compressed)
49 } else {
50 res.writeHead(status, { 'content-type': contentType })
51 res.end(buf)
52 }
53 }
54
55 function sendJSON (req, res, status, obj) {
56 send(req, res, status, 'application/json', JSON.stringify(obj))
57 }
58
59 const server = http.createServer((req, res) => {
60 // Strip prefix from URL
61 let reqUrl = req.url
62 if (prefix && reqUrl.startsWith(prefix)) {
63 reqUrl = reqUrl.slice(prefix.length) || '/'
64 }
65 const [url, query] = reqUrl.split('?')
66
67 if (url === '/' || url === '/index.html') {
68 send(req, res, 200, 'text/html; charset=utf-8', page)
69 return
70 }
71
72 if (url === '/api/tree') {
73 sendJSON(req, res, 200, tree)
74 return
75 }
76
77 // Server-Sent Events stream: replay current state as events, then push
78 // live events (file changes detected by fs.watch) as they happen.
79 //
80 // Clients: `new EventSource('/codetree/api/events')` and attach
81 // onmessage / addEventListener handlers per event type.
82 if (url === '/api/events') {
83 if (!live) {
84 sendJSON(req, res, 503, { error: 'Live event stream not available (no graph attached)' })
85 return
86 }
87 res.writeHead(200, {
88 'content-type': 'text/event-stream',
89 'cache-control': 'no-cache',
90 'connection': 'keep-alive',
91 'x-accel-buffering': 'no' // disable proxy buffering (nginx/apache)
92 })
93
94 const write = (ev) => {
95 // SSE frame: `event: <type>\ndata: <json>\n\n`
96 res.write('event: ' + ev.type + '\n')
97 res.write('data: ' + JSON.stringify(ev) + '\n\n')
98 }
99
100 const unsubscribe = live.subscribe(write)
101
102 // Flush on disconnect
103 req.on('close', unsubscribe)
104 req.on('error', unsubscribe)
105 return
106 }
107
108 // Lazy deep scan of a single module. Used by the UI when the user drills
109 // into a module that was originally captured shallow (only entry file
110 // parsed). Returns the fully-parsed module suitable for replacing the
111 // shallow placeholder client-side.
112 //
113 // GET /api/deep-scan?module=<name>
114 if (url === '/api/deep-scan' && query) {
115 const params = new URLSearchParams(query)
116 const name = params.get('module')
117 if (!name) {
118 sendJSON(req, res, 400, { error: 'module parameter required' })
119 return
120 }
121 const placeholder = tree.modules[name]
122 if (!placeholder) {
123 sendJSON(req, res, 404, { error: 'Module not found: ' + name })
124 return
125 }
126
127 // Resolve the module's filesystem path and security-check it.
128 const modAbsPath = resolve(rootDir, placeholder.path)
129 if (!modAbsPath.startsWith(rootDir)) {
130 sendJSON(req, res, 403, { error: 'Access denied' })
131 return
132 }
133 if (ignore(modAbsPath)) {
134 sendJSON(req, res, 404, { error: 'Module path is ignored' })
135 return
136 }
137
138 // Lazy-import scan() + buildTree() to avoid pulling them at server boot.
139 ;(async () => {
140 try {
141 const { scan } = await import('./scanner.js')
142 const deep = await scan(modAbsPath, { ignore: opts.ignore || [], shallow: false })
143 // Return only the module entry (the new tree's root module). Strip
144 // big sub-trees the client doesn't need.
145 const deepMod = deep.modules[name] || deep.modules[Object.keys(deep.modules)[0]]
146 sendJSON(req, res, 200, { name, mod: deepMod })
147 } catch (err) {
148 sendJSON(req, res, 500, { error: err.message || String(err) })
149 }
150 })()
151 return
152 }
153
154 if (url.startsWith('/api/module/')) {
155 const name = decodeURIComponent(url.slice('/api/module/'.length))
156 const mod = tree.modules[name]
157 if (mod) {
158 sendJSON(req, res, 200, mod)
159 } else {
160 sendJSON(req, res, 404, { error: 'Module not found' })
161 }
162 return
163 }
164
165 // File contents API: /api/file?path=relative/path.js
166 if (url === '/api/file' && query) {
167 const params = new URLSearchParams(query)
168 const filePath = params.get('path')
169 if (!filePath) {
170 sendJSON(req, res, 400, { error: 'path parameter required' })
171 return
172 }
173
174 // Security: prevent directory traversal
175 const absPath = resolve(rootDir, filePath)
176 if (!absPath.startsWith(rootDir)) {
177 sendJSON(req, res, 403, { error: 'Access denied' })
178 return
179 }
180
181 // Security: honor the ignore matcher — hidden files are not readable.
182 if (ignore(absPath)) {
183 sendJSON(req, res, 404, { error: 'File not found: ' + filePath })
184 return
185 }
186
187 try {
188 const content = readFileSync(absPath, 'utf-8')
189 sendJSON(req, res, 200, { path: filePath, content, lines: content.split('\n').length })
190 } catch (err) {
191 sendJSON(req, res, 404, { error: 'File not found: ' + filePath })
192 }
193 return
194 }
195
196 res.writeHead(404, { 'content-type': 'text/plain' })
197 res.end('Not found')
198 })
199
200 server.listen(port, () => {
201 console.log(`codetree visualization: http://localhost:${port}`)
202 console.log(`API: http://localhost:${port}/api/tree`)
203 console.log(`${tree.system.modules.length} modules loaded`)
204 })
205
206 return server
207}
lib/traverse.js +24 -0
……@@ -0,0 +1,24 @@
1import { scanStream } from './scan-stream.js'
2import { TreeReducer } from './reducers/tree-reducer.js'
3
4/**
5 * walkGraph — build a graph of modules and files for a project root.
6 *
7 * This is now a thin wrapper around scan-stream + TreeReducer. The returned
8 * shape is identical to the pre-refactor API so existing consumers (buildTree,
9 * tests) keep working unchanged.
10 *
11 * Callers who want push-based incremental updates should use scanStream()
12 * directly and attach their own reducer/listener.
13 *
14 * Returns: { modules, files, root, dirTree, projectType, languages, resolutionContext }
15 */
16export async function walkGraph (rootDir, opts = {}) {
17 return new Promise((resolve, reject) => {
18 const source = scanStream(rootDir, opts)
19 const tree = new TreeReducer().attach(source)
20
21 source.once('scan-end', () => resolve(tree.finalize()))
22 source.once('error', reject)
23 })
24}
lib/tree.js +326 -0
……@@ -0,0 +1,326 @@
1import { basename, dirname } from 'path'
2
3/**
4 * Build the complete JSON tree from a walk graph.
5 * Combines traverse output (module/file structure) with parser output (AST analysis).
6 */
7export function buildTree (graph) {
8 const tree = {
9 generated: new Date().toISOString(),
10 root: graph.root,
11 projectType: graph.projectType || 'unknown',
12 languages: graph.languages || [],
13 system: {
14 modules: [],
15 dependencies: {}
16 },
17 modules: {},
18 dirTree: graph.dirTree || null
19 }
20
21 for (const [name, mod] of graph.modules) {
22 tree.system.modules.push(name)
23
24 // Build dependency list (only local/known deps)
25 const deps = []
26 for (const dep of Object.keys(mod.dependencies)) {
27 deps.push(dep)
28 }
29 if (deps.length > 0) {
30 tree.system.dependencies[name] = deps
31 }
32
33 // Build module entry
34 const moduleEntry = {
35 path: mod.path,
36 name: mod.name,
37 version: mod.version,
38 type: mod.type,
39 entry: mod.entry ? basename(mod.entry) : null,
40 dependencies: mod.dependencies,
41 importMaps: Object.keys(mod.importMaps).length > 0 ? mod.importMaps : undefined,
42 testCommand: mod.testCommand,
43 publicAPI: [],
44 files: {}
45 }
46
47 // Build file entries from the parsed results already attached by scan-stream
48 // via the file-parsed event. This used to re-parse every file here, which
49 // was a ~2x CPU waste and caused OOM on large recursive scans.
50 for (const [relInPkg, fileInfo] of mod.files) {
51 const parsed = fileInfo.parsed
52 if (!parsed || parsed.error) continue
53
54 const fileEntry = {
55 role: classifyRole(relInPkg),
56 imports: parsed.imports,
57 exports: parsed.exports,
58 localImports: fileInfo.localImports || []
59 }
60
61 // Add structural data only if present (some fields are language-specific — may be undefined)
62 if (parsed.classes && parsed.classes.length > 0) fileEntry.classes = parsed.classes
63 if (parsed.functions && parsed.functions.length > 0) fileEntry.functions = parsed.functions
64 if (parsed.constants && parsed.constants.length > 0) fileEntry.constants = parsed.constants
65 if (parsed.state && parsed.state.length > 0) fileEntry.state = parsed.state
66 if (parsed.errorContracts && parsed.errorContracts.length > 0) fileEntry.errorContracts = parsed.errorContracts
67 if (parsed.delegates && parsed.delegates.length > 0) fileEntry.delegates = parsed.delegates
68 // Language-specific additional fields
69 if (parsed.signals && parsed.signals.length > 0) fileEntry.signals = parsed.signals
70 if (parsed.enums && parsed.enums.length > 0) fileEntry.enums = parsed.enums
71 if (parsed.namespaces && parsed.namespaces.length > 0) fileEntry.namespaces = parsed.namespaces
72 if (parsed.uniforms && parsed.uniforms.length > 0) fileEntry.uniforms = parsed.uniforms
73 if (parsed.buffers && parsed.buffers.length > 0) fileEntry.buffers = parsed.buffers
74
75 moduleEntry.files[relInPkg] = fileEntry
76 }
77
78 // Compute import graph (aggregates per-file localImports into directory-level architecture)
79 moduleEntry.importGraph = computeImportGraph(moduleEntry)
80
81 // Discover sub-modules from import graph (directory clusters that act as internal modules)
82 moduleEntry.subModules = discoverSubModules(moduleEntry)
83
84 // Compute public API from entry file
85 const entryKey = mod.entry ? findEntryKey(mod, moduleEntry.files) : null
86 if (entryKey && moduleEntry.files[entryKey]) {
87 moduleEntry.publicAPI = computePublicAPI(moduleEntry.files[entryKey])
88 }
89
90 tree.modules[name] = moduleEntry
91 }
92
93 // Sort module list
94 tree.system.modules.sort()
95
96 // Compute shared dependencies
97 tree.system.sharedDeps = computeSharedDeps(tree)
98
99 return tree
100}
101
102// --- File role classification ---
103
104function classifyRole (relPath) {
105 // JS conventions
106 if (relPath === 'index.js' || relPath === 'index.mjs') return 'entry'
107 if (relPath.startsWith('test/') || relPath.endsWith('.test.js')) return 'test'
108 if (relPath.includes('schema')) return 'schema'
109 if (relPath.startsWith('bin/')) return 'bin'
110
111 // Godot conventions
112 if (relPath.startsWith('autoloads/')) return 'autoload'
113 if (relPath.startsWith('scenes/')) return 'scene'
114 if (relPath.startsWith('addons/')) return 'addon'
115
116 // C++ conventions
117 if (relPath.startsWith('include/') || relPath.endsWith('.h') || relPath.endsWith('.hpp')) return 'header'
118 if (relPath.startsWith('src/')) return 'source'
119 if (relPath.startsWith('thirdparty/') || relPath.startsWith('vendor/')) return 'thirdparty'
120
121 // Shader conventions
122 if (relPath.startsWith('shaders/') || relPath.endsWith('.glsl') || relPath.endsWith('.gdshader')) return 'shader'
123
124 // Shared
125 if (relPath.startsWith('lib/')) return 'lib'
126 if (relPath.startsWith('scripts/')) return 'script'
127 if (relPath.startsWith('examples/') || relPath.startsWith('example/')) return 'example'
128
129 return 'lib'
130}
131
132// --- Entry point matching ---
133
134function findEntryKey (mod, files) {
135 const entryBase = mod.entry ? basename(mod.entry) : 'index.js'
136
137 // Try exact match
138 if (files[entryBase]) return entryBase
139
140 // Try index.js
141 if (files['index.js']) return 'index.js'
142
143 return null
144}
145
146// --- Public API computation ---
147
148function computePublicAPI (entryFile) {
149 const api = []
150 for (const exp of entryFile.exports) {
151 if (exp.name === '*') continue // Skip star re-exports for now
152 api.push(exp.name)
153 }
154 return api
155}
156
157// --- Import graph aggregation ---
158
159function computeImportGraph (moduleEntry) {
160 const modPath = moduleEntry.path
161 const edges = []
162 const dirEdgeCounts = {} // 'srcDir\0tgtDir' -> count
163 const dirFiles = {} // dir -> Set of file paths
164
165 // Build lookup: root-relative resolved path -> package-relative file key
166 const resolvedToKey = new Map()
167 for (const filePath of Object.keys(moduleEntry.files)) {
168 // root-relative = modPath/filePath (or just filePath if modPath is '.')
169 const rootRel = modPath === '.' ? filePath : modPath + '/' + filePath
170 resolvedToKey.set(rootRel, filePath)
171 }
172
173 for (const [filePath, file] of Object.entries(moduleEntry.files)) {
174 if (!file.localImports || file.localImports.length === 0) continue
175
176 const srcDir = fileDir(filePath)
177 if (!dirFiles[srcDir]) dirFiles[srcDir] = new Set()
178 dirFiles[srcDir].add(filePath)
179
180 for (const imp of file.localImports) {
181 // Convert root-relative resolved path to package-relative key
182 const targetKey = resolvedToKey.get(imp.resolved)
183 if (!targetKey) continue
184
185 // Find imported symbol names by matching specifier against parsed imports
186 const names = []
187 if (file.imports) {
188 const match = file.imports.find(i => i.specifier === imp.specifier)
189 if (match) names.push(...match.names)
190 }
191
192 edges.push({ from: filePath, to: targetKey, names })
193
194 const tgtDir = fileDir(targetKey)
195 if (!dirFiles[tgtDir]) dirFiles[tgtDir] = new Set()
196 dirFiles[tgtDir].add(targetKey)
197
198 // Aggregate directory-level edge
199 const pairKey = srcDir + '\0' + tgtDir
200 dirEdgeCounts[pairKey] = (dirEdgeCounts[pairKey] || 0) + 1
201 }
202 }
203
204 // Build directoryMatrix from aggregated pair counts
205 const directoryMatrix = {}
206 for (const [pairKey, count] of Object.entries(dirEdgeCounts)) {
207 const [srcDir, tgtDir] = pairKey.split('\0')
208 if (!directoryMatrix[srcDir]) directoryMatrix[srcDir] = {}
209 directoryMatrix[srcDir][tgtDir] = count
210 }
211
212 // Build per-directory stats
213 const directories = {}
214 const allDirs = new Set(Object.keys(dirFiles))
215
216 for (const dir of allDirs) {
217 let internalEdges = 0
218 let incomingEdges = 0
219 let outgoingEdges = 0
220
221 // Count edges from this dir (outgoing + internal)
222 for (const [pairKey, count] of Object.entries(dirEdgeCounts)) {
223 const [src, tgt] = pairKey.split('\0')
224 if (src === dir && tgt === dir) internalEdges += count
225 else if (src === dir && tgt !== dir) outgoingEdges += count
226 else if (tgt === dir && src !== dir) incomingEdges += count
227 }
228
229 directories[dir] = {
230 files: dirFiles[dir] ? dirFiles[dir].size : 0,
231 internalEdges,
232 incomingEdges,
233 outgoingEdges
234 }
235 }
236
237 return { edges, directoryMatrix, directories }
238}
239
240function fileDir (filePath) {
241 const dir = dirname(filePath)
242 return dir === '.' ? '.' : dir
243}
244
245// --- Sub-module discovery ---
246
247function discoverSubModules (moduleEntry) {
248 const graph = moduleEntry.importGraph
249 if (!graph) return {}
250
251 const subModules = {}
252
253 for (const [dir, stats] of Object.entries(graph.directories)) {
254 if (dir === '.') continue // root dir is the module itself, not a sub-module
255 if (stats.files < 2) continue // single-file dirs aren't sub-modules
256
257 // Check for an index file with re-exports (strong signal).
258 // Try common index filenames — language-agnostic lookup.
259 const INDEX_CANDIDATES = ['index.js', 'index.mjs', 'index.cjs', 'mod.rs', '__init__.py']
260 let indexKey = null
261 let indexFile = null
262 for (const candidate of INDEX_CANDIDATES) {
263 const key = dir + '/' + candidate
264 if (moduleEntry.files[key]) {
265 indexKey = key
266 indexFile = moduleEntry.files[key]
267 break
268 }
269 }
270 const hasIndex = indexFile && indexFile.exports && indexFile.exports.length > 0
271 const hasReExports = hasIndex && indexFile.exports.some(e => e.from)
272
273 // Collect files belonging to this directory
274 const files = []
275 for (const filePath of Object.keys(moduleEntry.files)) {
276 if (fileDir(filePath) === dir) files.push(filePath)
277 }
278
279 // Compute public exports (from index.js if it exists, otherwise union of all exports)
280 const publicExports = []
281 if (hasIndex) {
282 for (const exp of indexFile.exports) {
283 if (exp.name !== '*') publicExports.push(exp.name)
284 }
285 }
286
287 // Cohesion: ratio of internal edges to total edges involving this directory
288 const totalEdges = stats.internalEdges + stats.incomingEdges + stats.outgoingEdges
289 const cohesion = totalEdges > 0 ? stats.internalEdges / totalEdges : 0
290
291 subModules[dir] = {
292 indexFile: hasIndex ? indexKey : null,
293 hasReExports,
294 files,
295 publicExports,
296 fanIn: stats.incomingEdges,
297 fanOut: stats.outgoingEdges,
298 cohesion: Math.round(cohesion * 100) / 100
299 }
300 }
301
302 return subModules
303}
304
305// --- Shared dependency analysis ---
306
307function computeSharedDeps (tree) {
308 const depUsers = {} // dep -> [modules that use it]
309
310 for (const [name, mod] of Object.entries(tree.modules)) {
311 for (const dep of Object.keys(mod.dependencies || {})) {
312 if (!depUsers[dep]) depUsers[dep] = []
313 depUsers[dep].push(name)
314 }
315 }
316
317 // Only include deps used by 2+ modules
318 const shared = {}
319 for (const [dep, users] of Object.entries(depUsers)) {
320 if (users.length >= 2) {
321 shared[dep] = users.sort()
322 }
323 }
324
325 return shared
326}
lib/validator.js +493 -0
……@@ -0,0 +1,493 @@
1import { readFileSync, statSync } from 'fs'
2import { join, resolve } from 'path'
3
4/**
5 * Validate spec claims against the code tree.
6 * Returns a validation report with pass/fail/warn per claim.
7 */
8
9export function validate (tree, specs) {
10 const report = {
11 system: null,
12 modules: {},
13 docFreshness: null,
14 summary: { pass: 0, fail: 0, warn: 0, total: 0 }
15 }
16
17 // Validate system spec (pass module specs for cross-level checks)
18 if (specs.system) {
19 report.system = validateSystem(tree, specs.system, specs)
20 tally(report.summary, report.system.checks)
21 }
22
23 // Validate each module spec
24 for (const [name, spec] of Object.entries(specs.modules)) {
25 const mod = findModule(tree, spec)
26 report.modules[name] = validateModule(tree, mod, spec)
27 tally(report.summary, report.modules[name].checks)
28 }
29
30 // Validate documentation freshness (from doc cruft detection)
31 if (tree.docCruft) {
32 report.docFreshness = validateDocFreshness(tree.docCruft)
33 tally(report.summary, report.docFreshness.checks)
34 }
35
36 return report
37}
38
39// --- System-level validation ---
40
41function validateSystem (tree, systemSpec, specs) {
42 const result = { checks: [] }
43
44 // Check: each documented module exists in the code tree
45 for (const docMod of systemSpec.modules) {
46 const found = tree.modules[docMod.name]
47 const locationMatch = found && found.path && docMod.location.includes(found.path)
48
49 result.checks.push({
50 level: 'system',
51 canonicity: 'code-canonical',
52 claim: 'Module "' + docMod.name + '" exists at ' + docMod.location,
53 status: found ? (locationMatch ? 'pass' : 'warn') : 'fail',
54 expected: docMod.location,
55 actual: found ? found.path : null,
56 detail: !found ? 'Module not found in scan' :
57 (!locationMatch ? 'Location mismatch: spec says ' + docMod.location + ', found at ' + found.path : null)
58 })
59 }
60
61 // Check: modules in code that aren't documented
62 const documentedNames = new Set(systemSpec.modules.map(m => m.name))
63 for (const name of tree.system.modules) {
64 if (!documentedNames.has(name)) {
65 result.checks.push({
66 level: 'system',
67 claim: 'Module "' + name + '" is documented in SYSTEM.md',
68 status: 'warn',
69 detail: 'Module exists in code but not documented in system spec'
70 })
71 }
72 }
73
74 // --- Cross-level: orchestrator integration ---
75 // Find the orchestrator (pear-git-v3 or the "Applications" module)
76 // Find the orchestrator — the module whose purpose STARTS with "Orchestrator" or "Mounts all"
77 const orchestrators = systemSpec.modules.filter(m =>
78 m.purpose && (m.purpose.startsWith('Orchestrator') || m.purpose.startsWith('Mounts all'))
79 )
80
81 for (const orch of orchestrators) {
82 const orchMod = tree.modules[orch.name]
83 if (!orchMod) continue
84
85 const orchDeps = new Set(Object.keys(orchMod.dependencies))
86
87 // Every module in the system spec should be either:
88 // 1. A dependency of the orchestrator
89 // 2. A dependency of a dependency (transitive)
90 // 3. Explicitly marked as "not yet integrated" or "external"
91 for (const docMod of systemSpec.modules) {
92 if (docMod.name === orch.name) continue
93 if (docMod.location === 'external' || docMod.location.includes('npm dep')) continue
94
95 const isDirectDep = orchDeps.has(docMod.name)
96
97 // Check transitive: is it a dep of any of the orchestrator's deps? (2 levels deep)
98 let isTransitive = false
99 let transitiveVia = null
100 if (!isDirectDep) {
101 for (const depName of orchDeps) {
102 const depMod = tree.modules[depName]
103 if (!depMod) continue
104 if (depMod.dependencies[docMod.name]) {
105 isTransitive = true
106 transitiveVia = depName
107 break
108 }
109 // 2nd level
110 for (const dep2Name of Object.keys(depMod.dependencies)) {
111 const dep2Mod = tree.modules[dep2Name]
112 if (dep2Mod && dep2Mod.dependencies[docMod.name]) {
113 isTransitive = true
114 transitiveVia = depName + ' -> ' + dep2Name
115 break
116 }
117 }
118 if (isTransitive) break
119 }
120 }
121
122 if (!isDirectDep && !isTransitive) {
123 result.checks.push({
124 level: 'system',
125 claim: orch.name + ' integrates "' + docMod.name + '"',
126 status: 'fail',
127 detail: 'SYSTEM.md lists "' + docMod.name + '" as part of the system but ' + orch.name + ' does not depend on it (direct or transitive). Purpose: ' + (docMod.purpose || '').slice(0, 100)
128 })
129 } else {
130 result.checks.push({
131 level: 'system',
132 claim: orch.name + ' integrates "' + docMod.name + '"',
133 status: 'pass',
134 detail: isDirectDep ? 'Direct dependency' : 'Transitive via ' + transitiveVia
135 })
136 }
137 }
138 }
139
140 // --- Cross-level: dependency bidirectional consistency ---
141 // If module A's spec says "depends on B", and B's spec says "depended on by A",
142 // check that both match the actual code
143 for (const docMod of systemSpec.modules) {
144 const mod = tree.modules[docMod.name]
145 if (!mod) continue
146
147 // Check if module has any local deps that aren't in the system spec
148 for (const dep of Object.keys(mod.dependencies)) {
149 const depInSystem = systemSpec.modules.find(m => m.name === dep)
150 const depInCode = tree.modules[dep]
151 if (depInCode && !depInSystem) {
152 result.checks.push({
153 level: 'system',
154 claim: '"' + docMod.name + '" dependency "' + dep + '" is in system spec',
155 status: 'warn',
156 detail: docMod.name + ' depends on ' + dep + ' (found in code) but ' + dep + ' is not documented in SYSTEM.md'
157 })
158 }
159 }
160 }
161
162 // --- Cross-level: module spec dependency consistency ---
163 // Check that each module spec's "Dependencies" and "What depends on this"
164 // sections match actual code
165 if (specs && specs.modules) {
166 for (const [name, modSpec] of Object.entries(specs.modules)) {
167 const mod = findModuleBySpec(tree, modSpec)
168 if (!mod) continue
169
170 // Spec says "X depends on this" — verify X actually depends on this module
171 for (const dependent of modSpec.dependents) {
172 const depMod = tree.modules[dependent]
173 if (!depMod) {
174 result.checks.push({
175 level: 'system',
176 claim: '"' + dependent + '" depends on "' + name + '" (per ' + name + ' spec)',
177 status: 'warn',
178 detail: 'Module spec for ' + name + ' claims ' + dependent + ' depends on it, but ' + dependent + ' not found in scan'
179 })
180 continue
181 }
182 const actuallyDepends = depMod.dependencies[name] !== undefined
183 result.checks.push({
184 level: 'system',
185 claim: '"' + dependent + '" depends on "' + name + '"',
186 status: actuallyDepends ? 'pass' : 'fail',
187 detail: actuallyDepends ? null : name + ' spec says ' + dependent + ' depends on it, but ' + dependent + '/package.json does not list ' + name + ' as a dependency'
188 })
189 }
190 }
191 }
192
193 return result
194}
195
196function findModuleBySpec (tree, spec) {
197 if (tree.modules[spec.name]) return tree.modules[spec.name]
198 if (spec.location) {
199 for (const mod of Object.values(tree.modules)) {
200 if (spec.location.includes(mod.path)) return mod
201 }
202 }
203 return null
204}
205
206// --- Module-level validation ---
207
208function validateModule (tree, mod, spec) {
209 const result = {
210 specFile: spec.filename,
211 checks: []
212 }
213
214 if (!mod) {
215 result.checks.push({
216 level: 'module',
217 canonicity: 'code-canonical',
218 claim: 'Module "' + spec.name + '" exists',
219 status: 'fail',
220 detail: 'Spec references module at ' + spec.location + ' but it was not found in the scan'
221 })
222 return result
223 }
224
225 // --- LOC checks ---
226 for (const [filename, claimedLOC] of Object.entries(spec.fileLOC)) {
227 // Find the file in the module
228 const filePath = findFileInModule(mod, filename)
229 if (!filePath) {
230 result.checks.push({
231 level: 'file',
232 canonicity: 'code-canonical',
233 claim: 'File "' + filename + '" exists',
234 status: 'fail',
235 detail: 'Spec claims ' + filename + ' has ' + claimedLOC + ' LOC but file not found'
236 })
237 continue
238 }
239
240 const file = mod.files[filePath]
241 if (!file) continue
242
243 // Count actual LOC by finding the source
244 const absPath = resolve(tree.root, mod.path, filePath)
245 let actualLOC = null
246 try {
247 const source = readFileSync(absPath, 'utf-8')
248 actualLOC = source.split('\n').length
249 } catch {}
250
251 if (actualLOC !== null) {
252 const drift = Math.abs(actualLOC - claimedLOC)
253 const driftPct = (drift / claimedLOC * 100).toFixed(0)
254 result.checks.push({
255 level: 'file',
256 canonicity: 'code-canonical',
257 claim: filename + ' has ' + claimedLOC + ' LOC',
258 status: drift === 0 ? 'pass' : drift < 20 ? 'warn' : 'fail',
259 expected: claimedLOC,
260 actual: actualLOC,
261 detail: drift > 0 ? 'LOC drifted by ' + drift + ' lines (' + driftPct + '%). Spec says ' + claimedLOC + ', actual is ' + actualLOC : null
262 })
263 }
264 }
265
266 // --- Source verified staleness ---
267 if (spec.sourceVerified) {
268 const verifiedDate = new Date(spec.sourceVerified)
269 let newestMtime = 0
270 for (const filePath of Object.keys(mod.files)) {
271 try {
272 const absPath = resolve(tree.root, mod.path, filePath)
273 const stat = statSync(absPath)
274 if (stat.mtimeMs > newestMtime) newestMtime = stat.mtimeMs
275 } catch {}
276 }
277 if (newestMtime > 0) {
278 const codeDate = new Date(newestMtime)
279 const stale = codeDate > verifiedDate
280 result.checks.push({
281 level: 'module',
282 claim: 'Source verified on ' + spec.sourceVerified,
283 status: stale ? 'warn' : 'pass',
284 expected: spec.sourceVerified,
285 actual: codeDate.toISOString().split('T')[0],
286 detail: stale ? 'Code modified on ' + codeDate.toISOString().split('T')[0] + ', after spec verified on ' + spec.sourceVerified : null
287 })
288 }
289 }
290
291 // --- Dependency checks ---
292 for (const dep of spec.dependencies) {
293 const hasDep = mod.dependencies[dep] !== undefined
294 result.checks.push({
295 level: 'module',
296 canonicity: 'code-canonical',
297 claim: 'Depends on ' + dep,
298 status: hasDep ? 'pass' : 'fail',
299 detail: !hasDep ? 'Spec claims dependency on ' + dep + ' but not found in package.json' : null
300 })
301 }
302
303 // Check reverse: deps in package.json not documented
304 for (const dep of Object.keys(mod.dependencies)) {
305 // Only check local/known deps
306 if (!tree.modules[dep]) continue
307 if (!spec.dependencies.includes(dep)) {
308 result.checks.push({
309 level: 'module',
310 claim: 'Dependency "' + dep + '" is documented',
311 status: 'warn',
312 detail: 'package.json depends on ' + dep + ' but spec does not mention it'
313 })
314 }
315 }
316
317 // --- Export checks ---
318 for (const claimedExport of spec.claimedExports) {
319 const found = mod.publicAPI.includes(claimedExport)
320 result.checks.push({
321 level: 'module',
322 canonicity: 'code-canonical',
323 claim: 'Exports "' + claimedExport + '"',
324 status: found ? 'pass' : 'fail',
325 detail: !found ? 'Spec claims export "' + claimedExport + '" but not found in public API: [' + mod.publicAPI.join(', ') + ']' : null
326 })
327 }
328
329 // Undocumented exports
330 for (const exp of mod.publicAPI) {
331 if (!spec.claimedExports.includes(exp)) {
332 result.checks.push({
333 level: 'module',
334 claim: 'Export "' + exp + '" is documented',
335 status: 'warn',
336 detail: 'Module exports "' + exp + '" but spec does not document it'
337 })
338 }
339 }
340
341 // --- Method checks ---
342 const allMethods = getAllMethods(mod)
343 for (const method of spec.claimedMethods) {
344 const found = allMethods.has(method)
345 result.checks.push({
346 level: 'method',
347 canonicity: 'code-canonical',
348 claim: 'Method "' + method + '" exists',
349 status: found ? 'pass' : 'fail',
350 detail: !found ? 'Spec documents method "' + method + '" but not found in any class' : null
351 })
352 }
353
354 // Undocumented methods (only for primary class)
355 const primaryClass = findPrimaryClass(mod, spec)
356 if (primaryClass && spec.claimedMethods.length > 0) {
357 for (const m of primaryClass.methods) {
358 if (m.kind === 'field') continue
359 if (m.name.startsWith('_')) continue // skip private
360 if (!spec.claimedMethods.includes(m.name) && m.name !== 'ready' && m.name !== 'close' && m.name !== 'sync') {
361 result.checks.push({
362 level: 'method',
363 canonicity: 'code-canonical',
364 claim: 'Method "' + m.name + '" is documented',
365 status: 'warn',
366 detail: 'Class has public method "' + m.name + '(' + m.params.join(', ') + ')" but spec does not document it'
367 })
368 }
369 }
370 }
371
372 // --- Getter checks ---
373 for (const getter of spec.claimedGetters) {
374 const found = allGetters(mod).has(getter)
375 result.checks.push({
376 level: 'method',
377 canonicity: 'code-canonical',
378 claim: 'Getter "' + getter + '" exists',
379 status: found ? 'pass' : 'fail',
380 detail: !found ? 'Spec documents getter "' + getter + '" but not found' : null
381 })
382 }
383
384 return result
385}
386
387// --- Documentation freshness validation ---
388
389function validateDocFreshness (docCruft) {
390 const result = { checks: [] }
391
392 for (const doc of docCruft.docs) {
393 // Skip docs with no code references (pure prose)
394 if (doc.references.total === 0) continue
395
396 const missingRatio = doc.references.missing / doc.references.total
397 let status = 'pass'
398 if (missingRatio > 0.3) status = 'fail'
399 else if (missingRatio > 0.1) status = 'warn'
400
401 result.checks.push({
402 level: 'doc',
403 canonicity: 'narrative',
404 claim: doc.path + ' references are current',
405 status,
406 detail: doc.references.missing + ' of ' + doc.references.total + ' code references missing. Last modified ' + doc.lastModified + ' (staleness ' + doc.staleness.score + ')',
407 docPath: doc.path
408 })
409 }
410
411 return result
412}
413
414// --- Helpers ---
415
416function findModule (tree, spec) {
417 // Try by name first
418 if (tree.modules[spec.name]) return tree.modules[spec.name]
419
420 // Try by location path
421 if (spec.location) {
422 for (const mod of Object.values(tree.modules)) {
423 if (spec.location.includes(mod.path) || mod.path.includes(spec.location)) {
424 return mod
425 }
426 }
427 }
428
429 return null
430}
431
432function findFileInModule (mod, filename) {
433 // Exact match
434 if (mod.files[filename]) return filename
435
436 // Try with lib/ prefix
437 if (mod.files['lib/' + filename]) return 'lib/' + filename
438
439 // Search by basename
440 for (const path of Object.keys(mod.files)) {
441 if (path.endsWith('/' + filename) || path === filename) return path
442 }
443
444 return null
445}
446
447function getAllMethods (mod) {
448 const methods = new Set()
449 for (const file of Object.values(mod.files)) {
450 if (file.classes) {
451 for (const cls of file.classes) {
452 for (const m of cls.methods) methods.add(m.name)
453 }
454 }
455 if (file.functions) {
456 for (const fn of file.functions) methods.add(fn.name)
457 }
458 }
459 return methods
460}
461
462function allGetters (mod) {
463 const getters = new Set()
464 for (const file of Object.values(mod.files)) {
465 if (file.classes) {
466 for (const cls of file.classes) {
467 if (cls.getters) for (const g of cls.getters) getters.add(g.name)
468 }
469 }
470 }
471 return getters
472}
473
474function findPrimaryClass (mod, spec) {
475 // Find the main exported class
476 for (const file of Object.values(mod.files)) {
477 if (file.classes) {
478 for (const cls of file.classes) {
479 if (spec.claimedExports.includes(cls.name)) return cls
480 }
481 }
482 }
483 return null
484}
485
486function tally (summary, checks) {
487 for (const c of checks) {
488 summary.total++
489 if (c.status === 'pass') summary.pass++
490 else if (c.status === 'fail') summary.fail++
491 else if (c.status === 'warn') summary.warn++
492 }
493}
package-lock.json +1111 -0
……@@ -0,0 +1,1111 @@
1{
2 "name": "codetree",
3 "version": "0.1.0",
4 "lockfileVersion": 3,
5 "requires": true,
6 "packages": {
7 "": {
8 "name": "codetree",
9 "version": "0.1.0",
10 "dependencies": {
11 "paparam": "^1.8.6"
12 },
13 "bin": {
14 "codetree": "index.js"
15 },
16 "devDependencies": {
17 "brittle": "^3.0.0"
18 },
19 "optionalDependencies": {
20 "bare-events": "^2.5.0",
21 "bare-fs": "^4.5.0",
22 "bare-http1": "^4.0.0",
23 "bare-path": "^3.0.0",
24 "bare-process": "^3.0.0",
25 "bare-url": "^2.3.2",
26 "bare-zlib": "^1.3.0"
27 }
28 },
29 "node_modules/@jridgewell/resolve-uri": {
30 "version": "3.1.2",
31 "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
32 "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
33 "dev": true,
34 "license": "MIT",
35 "engines": {
36 "node": ">=6.0.0"
37 }
38 },
39 "node_modules/@jridgewell/sourcemap-codec": {
40 "version": "1.5.5",
41 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
42 "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
43 "dev": true,
44 "license": "MIT"
45 },
46 "node_modules/@jridgewell/trace-mapping": {
47 "version": "0.3.31",
48 "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
49 "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
50 "dev": true,
51 "license": "MIT",
52 "dependencies": {
53 "@jridgewell/resolve-uri": "^3.1.0",
54 "@jridgewell/sourcemap-codec": "^1.4.14"
55 }
56 },
57 "node_modules/@types/istanbul-lib-coverage": {
58 "version": "2.0.6",
59 "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
60 "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
61 "dev": true,
62 "license": "MIT"
63 },
64 "node_modules/b4a": {
65 "version": "1.8.0",
66 "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz",
67 "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==",
68 "devOptional": true,
69 "license": "Apache-2.0",
70 "peerDependencies": {
71 "react-native-b4a": "*"
72 },
73 "peerDependenciesMeta": {
74 "react-native-b4a": {
75 "optional": true
76 }
77 }
78 },
79 "node_modules/bare-abort": {
80 "version": "2.0.13",
81 "resolved": "https://registry.npmjs.org/bare-abort/-/bare-abort-2.0.13.tgz",
82 "integrity": "sha512-zdc8l88eB11Jsz5rDd6sCAgv2kUFXgdrZWoMlgU6JMkfAi1/uuGFC3IEHswKbIRQTk5H3T5CMuechsXYxiaHlQ==",
83 "dev": true,
84 "license": "Apache-2.0"
85 },
86 "node_modules/bare-addon-resolve": {
87 "version": "1.10.0",
88 "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.10.0.tgz",
89 "integrity": "sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA==",
90 "dev": true,
91 "license": "Apache-2.0",
92 "dependencies": {
93 "bare-module-resolve": "^1.10.0",
94 "bare-semver": "^1.0.0"
95 },
96 "peerDependencies": {
97 "bare-url": "*"
98 },
99 "peerDependenciesMeta": {
100 "bare-url": {
101 "optional": true
102 }
103 }
104 },
105 "node_modules/bare-ansi-escapes": {
106 "version": "2.2.3",
107 "resolved": "https://registry.npmjs.org/bare-ansi-escapes/-/bare-ansi-escapes-2.2.3.tgz",
108 "integrity": "sha512-02ES4/E2RbrtZSnHJ9LntBhYkLA6lPpSEeP8iqS3MccBIVhVBlEmruF1I7HZqx5Q8aiTeYfQVeqmrU9YO2yYoQ==",
109 "dev": true,
110 "license": "Apache-2.0",
111 "dependencies": {
112 "bare-stream": "^2.6.5"
113 },
114 "peerDependencies": {
115 "bare-buffer": "*"
116 },
117 "peerDependenciesMeta": {
118 "bare-buffer": {
119 "optional": true
120 }
121 }
122 },
123 "node_modules/bare-assert": {
124 "version": "1.2.0",
125 "resolved": "https://registry.npmjs.org/bare-assert/-/bare-assert-1.2.0.tgz",
126 "integrity": "sha512-c6uvgvTJBspTDxtVnPgrBKmLgcpW3Fp72NVKDLg6oT4QjQbhGtvrkHMhGYMK1sh4vjBHOBmuUalyt9hSzV37fQ==",
127 "dev": true,
128 "license": "Apache-2.0",
129 "dependencies": {
130 "bare-inspect": "^3.1.2"
131 }
132 },
133 "node_modules/bare-bundle": {
134 "version": "1.10.0",
135 "resolved": "https://registry.npmjs.org/bare-bundle/-/bare-bundle-1.10.0.tgz",
136 "integrity": "sha512-4LVlnJAHr00Hh6Vu6ZUJS38rcEtJT3b3vChXSsBsJ2mk1TN0lQ+gzd+Dw5L0aV7uqDZv84smuwW+O02X7PfDlw==",
137 "dev": true,
138 "license": "Apache-2.0",
139 "peerDependencies": {
140 "bare-buffer": "*",
141 "bare-url": "*"
142 },
143 "peerDependenciesMeta": {
144 "bare-buffer": {
145 "optional": true
146 },
147 "bare-url": {
148 "optional": true
149 }
150 }
151 },
152 "node_modules/bare-cov": {
153 "version": "1.2.1",
154 "resolved": "https://registry.npmjs.org/bare-cov/-/bare-cov-1.2.1.tgz",
155 "integrity": "sha512-SHNqb/WG9udUEj8m5qGSehoUQ9o0Xzv8nrf4HIdmG+KNU/XdhPLhTP5VPrHnSAMAXhAzEB4Q+2IYZ0x9qPzN1g==",
156 "dev": true,
157 "license": "Apache-2.0",
158 "dependencies": {
159 "bare-fs": "^4.1.2",
160 "bare-inspector": "^4.0.1",
161 "bare-path": "^3.0.0",
162 "bare-process": "^4.2.1",
163 "bare-url": "^2.1.5",
164 "bare-v8-to-istanbul": "^1.0.2",
165 "picomatch": "^4.0.2",
166 "which-runtime": "^1.2.1"
167 }
168 },
169 "node_modules/bare-cov/node_modules/bare-process": {
170 "version": "4.4.1",
171 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.4.1.tgz",
172 "integrity": "sha512-JfcTtymq6akqM2bdyTsP4A4GYJceBzb91k/ECmFps75uFf6uO33SM1bOZsRAqyRXExabsQJLn5S41NBl8HTM4A==",
173 "dev": true,
174 "license": "Apache-2.0",
175 "dependencies": {
176 "bare-abort": "^2.0.13",
177 "bare-env": "^3.0.0",
178 "bare-events": "^2.3.1",
179 "bare-hrtime": "^2.0.0",
180 "bare-os": "^3.7.1",
181 "bare-signals": "^4.0.0",
182 "bare-stdio": "^1.0.1"
183 }
184 },
185 "node_modules/bare-cov/node_modules/bare-signals": {
186 "version": "4.2.0",
187 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
188 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
189 "dev": true,
190 "license": "Apache-2.0",
191 "dependencies": {
192 "bare-events": "^2.5.3",
193 "bare-os": "^3.3.1"
194 },
195 "engines": {
196 "bare": ">=1.7.0"
197 }
198 },
199 "node_modules/bare-crypto": {
200 "version": "1.13.4",
201 "resolved": "https://registry.npmjs.org/bare-crypto/-/bare-crypto-1.13.4.tgz",
202 "integrity": "sha512-JiCZ5l2YOG1y8J7yy1BCAKTCZrPnHLb7pDRIdurBTOn5oIwBQDIv8iH5Pl2V85vzjl1NZXRfNY4HZLsE942jJA==",
203 "dev": true,
204 "license": "Apache-2.0",
205 "dependencies": {
206 "bare-assert": "^1.2.0",
207 "bare-stream": "^2.6.3"
208 },
209 "peerDependencies": {
210 "bare-buffer": "*"
211 },
212 "peerDependenciesMeta": {
213 "bare-buffer": {
214 "optional": true
215 }
216 }
217 },
218 "node_modules/bare-debug-log": {
219 "version": "2.0.0",
220 "resolved": "https://registry.npmjs.org/bare-debug-log/-/bare-debug-log-2.0.0.tgz",
221 "integrity": "sha512-Vi42PkMQsNV9PUpx2Gl1hikshx5O9FzMJ6o9Nnopseg7qLBBK7Nl31d0RHcfwLEAfmcPApytpc0ZFfq68u22FQ==",
222 "dev": true,
223 "license": "Apache-2.0",
224 "dependencies": {
225 "bare-os": "^3.0.1"
226 }
227 },
228 "node_modules/bare-dns": {
229 "version": "2.1.4",
230 "resolved": "https://registry.npmjs.org/bare-dns/-/bare-dns-2.1.4.tgz",
231 "integrity": "sha512-abwjHmpWqSRNB7V5615QxPH92L71AVzFm/kKTs8VYiNTAi2xVdonpv0BjJ0hwXLwomoW+xsSOPjW6PZPO14asg==",
232 "devOptional": true,
233 "license": "Apache-2.0",
234 "engines": {
235 "bare": ">=1.7.0"
236 }
237 },
238 "node_modules/bare-encoding": {
239 "version": "1.0.3",
240 "resolved": "https://registry.npmjs.org/bare-encoding/-/bare-encoding-1.0.3.tgz",
241 "integrity": "sha512-Kqf+t/azs13lUeyK4Tb7ha4wdLRXKWCXQ8w1rVmt7KtoPCPdHD/Xwt7LBIsCSwwGglrcmblo5VOLa5avkJqULA==",
242 "dev": true,
243 "license": "Apache-2.0",
244 "peerDependencies": {
245 "bare-buffer": "*"
246 },
247 "peerDependenciesMeta": {
248 "bare-buffer": {
249 "optional": true
250 }
251 }
252 },
253 "node_modules/bare-env": {
254 "version": "3.0.0",
255 "resolved": "https://registry.npmjs.org/bare-env/-/bare-env-3.0.0.tgz",
256 "integrity": "sha512-0u964P5ZLAxTi+lW4Kjp7YRJQ5gZr9ycYOtjLxsSrupgMz3sn5Z9n4SH/JIifHwvadsf1brA2JAjP+9IOWwTiw==",
257 "devOptional": true,
258 "license": "Apache-2.0",
259 "dependencies": {
260 "bare-os": "^3.0.1"
261 }
262 },
263 "node_modules/bare-events": {
264 "version": "2.8.2",
265 "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz",
266 "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==",
267 "devOptional": true,
268 "license": "Apache-2.0",
269 "peerDependencies": {
270 "bare-abort-controller": "*"
271 },
272 "peerDependenciesMeta": {
273 "bare-abort-controller": {
274 "optional": true
275 }
276 }
277 },
278 "node_modules/bare-format": {
279 "version": "1.0.2",
280 "resolved": "https://registry.npmjs.org/bare-format/-/bare-format-1.0.2.tgz",
281 "integrity": "sha512-GswdhnOnP9QtwRbrf4wLApw5widkaLMsLe2XOs35fQD2YfEN1ApoGka+cZ7PfvzxMgfYXmMhj/2OGlVn5/Dxgw==",
282 "dev": true,
283 "license": "Apache-2.0",
284 "dependencies": {
285 "bare-inspect": "^3.0.0"
286 }
287 },
288 "node_modules/bare-fs": {
289 "version": "4.7.0",
290 "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.0.tgz",
291 "integrity": "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA==",
292 "devOptional": true,
293 "license": "Apache-2.0",
294 "dependencies": {
295 "bare-events": "^2.5.4",
296 "bare-path": "^3.0.0",
297 "bare-stream": "^2.6.4",
298 "bare-url": "^2.2.2",
299 "fast-fifo": "^1.3.2"
300 },
301 "engines": {
302 "bare": ">=1.16.0"
303 },
304 "peerDependencies": {
305 "bare-buffer": "*"
306 },
307 "peerDependenciesMeta": {
308 "bare-buffer": {
309 "optional": true
310 }
311 }
312 },
313 "node_modules/bare-hrtime": {
314 "version": "2.1.1",
315 "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.1.1.tgz",
316 "integrity": "sha512-VMb3tHo05gsnbu3OXTmkDiwTjMlOsbQmKoysKqKEyR09m77TuDrYFbj3Q5GGk10dAKsUHrnXmwCaeJqzVpB5ZA==",
317 "devOptional": true,
318 "license": "Apache-2.0"
319 },
320 "node_modules/bare-http-parser": {
321 "version": "1.1.3",
322 "resolved": "https://registry.npmjs.org/bare-http-parser/-/bare-http-parser-1.1.3.tgz",
323 "integrity": "sha512-+dhVvQi6brHq14L/XHNRQ+TLuVE76VjRmMt61wVEtS+Od8xUslfMHWJN/ZjIIt3RtTG6vPuA+x9cOh7KrkBJsA==",
324 "devOptional": true,
325 "license": "Apache-2.0"
326 },
327 "node_modules/bare-http1": {
328 "version": "4.5.6",
329 "resolved": "https://registry.npmjs.org/bare-http1/-/bare-http1-4.5.6.tgz",
330 "integrity": "sha512-31OAwMkSU+z1VuUOCk65hx3aWQgzCfH/zQ6LGxbJtmiy2Czsw0+uvOBM9YkqaL6zUSTSYG2pLbL0v/TjME3Buw==",
331 "devOptional": true,
332 "license": "Apache-2.0",
333 "dependencies": {
334 "bare-events": "^2.6.0",
335 "bare-http-parser": "^1.1.1",
336 "bare-stream": "^2.10.0",
337 "bare-tcp": "^2.2.0"
338 },
339 "peerDependencies": {
340 "bare-buffer": "*",
341 "bare-url": "*"
342 },
343 "peerDependenciesMeta": {
344 "bare-buffer": {
345 "optional": true
346 },
347 "bare-url": {
348 "optional": true
349 }
350 }
351 },
352 "node_modules/bare-https": {
353 "version": "2.1.3",
354 "resolved": "https://registry.npmjs.org/bare-https/-/bare-https-2.1.3.tgz",
355 "integrity": "sha512-0TI/mJXQGYXmG7UUyWEG+KCJusayIAQLywUjFAskDoKuxfqVnGF+M/mTMrEV8J64DaIdU+5x761FvgmT7M68tA==",
356 "dev": true,
357 "license": "Apache-2.0",
358 "dependencies": {
359 "bare-http1": "^4.4.0",
360 "bare-tcp": "^2.2.0",
361 "bare-tls": "^2.0.0"
362 }
363 },
364 "node_modules/bare-inspect": {
365 "version": "3.1.4",
366 "resolved": "https://registry.npmjs.org/bare-inspect/-/bare-inspect-3.1.4.tgz",
367 "integrity": "sha512-jfW5KRA84o3REpI6Vr4nbvMn+hqVAw8GU1mMdRwUsY5yJovQamxYeKGVKGqdzs+8ZbG4jRzGUXP/3Ji/DnqfPg==",
368 "dev": true,
369 "license": "Apache-2.0",
370 "dependencies": {
371 "bare-ansi-escapes": "^2.1.0",
372 "bare-type": "^1.0.0"
373 },
374 "engines": {
375 "bare": ">=1.18.0"
376 }
377 },
378 "node_modules/bare-inspector": {
379 "version": "4.0.3",
380 "resolved": "https://registry.npmjs.org/bare-inspector/-/bare-inspector-4.0.3.tgz",
381 "integrity": "sha512-yYk6+7tTVKJKHOja5+QBn989ETv8oVsmwoH0nCM+QYC6w5MC03GC4aQNK+lipAZSz1EaAj42WZ8Wewjpy0L9TA==",
382 "dev": true,
383 "license": "Apache-2.0",
384 "dependencies": {
385 "bare-events": "^2.1.0",
386 "bare-http1": "^4.0.0",
387 "bare-stream": "^2.0.0",
388 "bare-url": "^2.0.0",
389 "bare-ws": "^2.0.0"
390 },
391 "engines": {
392 "bare": ">=1.2.0"
393 },
394 "peerDependencies": {
395 "bare-tcp": "*"
396 },
397 "peerDependenciesMeta": {
398 "bare-tcp": {
399 "optional": true
400 }
401 }
402 },
403 "node_modules/bare-module": {
404 "version": "6.1.3",
405 "resolved": "https://registry.npmjs.org/bare-module/-/bare-module-6.1.3.tgz",
406 "integrity": "sha512-5XWsVHsvtWMH4tK4DQWgpNTV0t/sg3ZrAaQLIxrwjrS5+u8Q9vEgc/zQ4QaDPWDse/y/5h+d+YG1Q0JfSMt0zA==",
407 "dev": true,
408 "license": "Apache-2.0",
409 "dependencies": {
410 "bare-bundle": "^1.3.0",
411 "bare-module-lexer": "^1.0.0",
412 "bare-module-resolve": "^1.8.0",
413 "bare-path": "^3.0.0",
414 "bare-url": "^2.0.1"
415 },
416 "engines": {
417 "bare": ">=1.23.0"
418 },
419 "peerDependencies": {
420 "bare-buffer": "*"
421 },
422 "peerDependenciesMeta": {
423 "bare-buffer": {
424 "optional": true
425 }
426 }
427 },
428 "node_modules/bare-module-lexer": {
429 "version": "1.4.7",
430 "resolved": "https://registry.npmjs.org/bare-module-lexer/-/bare-module-lexer-1.4.7.tgz",
431 "integrity": "sha512-0klU4eMsjh/wcxi8FdHmNom2j2F4kmkXOhyJFL9qTaSFp2lE3m6BtbKgMHY8R5miqC9r8/IfA8wzXnC5Os14WA==",
432 "dev": true,
433 "license": "Apache-2.0",
434 "dependencies": {
435 "require-addon": "^1.0.2"
436 },
437 "peerDependencies": {
438 "bare-buffer": "*"
439 },
440 "peerDependenciesMeta": {
441 "bare-buffer": {
442 "optional": true
443 }
444 }
445 },
446 "node_modules/bare-module-resolve": {
447 "version": "1.12.1",
448 "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.12.1.tgz",
449 "integrity": "sha512-hbmAPyFpEq8FoZMd5sFO3u6MC5feluWoGE8YKlA8fCrl6mNtx68Wjg4DTiDJcqRJaovTvOYKfYngoBUnbaT7eg==",
450 "dev": true,
451 "license": "Apache-2.0",
452 "dependencies": {
453 "bare-semver": "^1.0.0"
454 },
455 "peerDependencies": {
456 "bare-url": "*"
457 },
458 "peerDependenciesMeta": {
459 "bare-url": {
460 "optional": true
461 }
462 }
463 },
464 "node_modules/bare-net": {
465 "version": "2.3.1",
466 "resolved": "https://registry.npmjs.org/bare-net/-/bare-net-2.3.1.tgz",
467 "integrity": "sha512-MypSqDKpDU2Xt7FIfazn5yGvRnV09gFcIPHGWstW0gxuzA4tucTcwJSZeos97C4F89vtU5oGwXDN/HrGN6Y4Jw==",
468 "dev": true,
469 "license": "Apache-2.0",
470 "dependencies": {
471 "bare-events": "^2.2.2",
472 "bare-pipe": "^4.0.0",
473 "bare-stream": "^2.0.0",
474 "bare-tcp": "^2.0.0"
475 }
476 },
477 "node_modules/bare-os": {
478 "version": "3.8.7",
479 "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.8.7.tgz",
480 "integrity": "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w==",
481 "devOptional": true,
482 "license": "Apache-2.0",
483 "engines": {
484 "bare": ">=1.14.0"
485 }
486 },
487 "node_modules/bare-path": {
488 "version": "3.0.0",
489 "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz",
490 "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==",
491 "devOptional": true,
492 "license": "Apache-2.0",
493 "dependencies": {
494 "bare-os": "^3.0.1"
495 }
496 },
497 "node_modules/bare-pipe": {
498 "version": "4.1.5",
499 "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-4.1.5.tgz",
500 "integrity": "sha512-6OfxaG8JSkRh3Gc4hzHRsxNt+yu2PpN7lrv1V+T78GdknWQkVGwiEvu4m+1nbfk8cMVQ0TGxRvQ90XA4rhnTuw==",
501 "dev": true,
502 "license": "Apache-2.0",
503 "dependencies": {
504 "bare-events": "^2.0.0",
505 "bare-stream": "^2.0.0"
506 },
507 "engines": {
508 "bare": ">=1.16.0"
509 }
510 },
511 "node_modules/bare-process": {
512 "version": "3.1.1",
513 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-3.1.1.tgz",
514 "integrity": "sha512-lK9QBQT7PbPunay3Ee1gO45ANoXiObozh6y2nn8eK9MZ+zQwYw/XVWkQ4ixPb5v9/U/cHrAHYOXkwoN8wjPkVw==",
515 "license": "Apache-2.0",
516 "optional": true,
517 "dependencies": {
518 "bare-env": "^3.0.0",
519 "bare-events": "^2.3.1",
520 "bare-hrtime": "^2.0.0",
521 "bare-os": "^3.0.1",
522 "bare-pipe": "^3.1.0",
523 "bare-signals": "^3.0.0",
524 "bare-tty": "^4.0.0"
525 }
526 },
527 "node_modules/bare-process/node_modules/bare-pipe": {
528 "version": "3.3.8",
529 "resolved": "https://registry.npmjs.org/bare-pipe/-/bare-pipe-3.3.8.tgz",
530 "integrity": "sha512-X8Ulz/os6LR/cF5HBljq/tJ0NP7eNGjiripZF53EMtgkhJ9FVl1/WLZxwvUvcqbR82Ywaq6KYM+A6zS7DGPPUw==",
531 "license": "Apache-2.0",
532 "optional": true,
533 "dependencies": {
534 "bare-events": "^2.0.0",
535 "bare-stream": "^2.0.0"
536 }
537 },
538 "node_modules/bare-semver": {
539 "version": "1.0.3",
540 "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.3.tgz",
541 "integrity": "sha512-HS/A30bi2+PiRJfU6R4+Kp+6KeLSCSByjYM2iiobOKzLAvtu1CT+S8xWfiU7wz0erknjkUoC+yXy108tzIuP5Q==",
542 "dev": true,
543 "license": "Apache-2.0"
544 },
545 "node_modules/bare-signals": {
546 "version": "3.0.2",
547 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-3.0.2.tgz",
548 "integrity": "sha512-Jy0teXMTG+BPW/nJXIvd1ZY3Bnt0I/TL00Dd5T16JvY5dUK6GMsKSRW+YipGRMQssam+L/pBvSbHV6WsI3D9Qw==",
549 "license": "Apache-2.0",
550 "optional": true,
551 "dependencies": {
552 "bare-events": "^2.0.0",
553 "bare-os": "^3.0.1"
554 }
555 },
556 "node_modules/bare-stdio": {
557 "version": "1.0.2",
558 "resolved": "https://registry.npmjs.org/bare-stdio/-/bare-stdio-1.0.2.tgz",
559 "integrity": "sha512-3WJDqtvVGP4f+j68kyEC05umOYNwKJ1xG+YAXL8yZ605WgNqiRhVaFq+mVIhBt2eKNp7pa5vCQdhOt1pNh79SA==",
560 "dev": true,
561 "license": "Apache-2.0",
562 "dependencies": {
563 "bare-fs": "^4.5.2",
564 "bare-pipe": "^4.1.5",
565 "bare-tty": "^5.0.3"
566 }
567 },
568 "node_modules/bare-stdio/node_modules/bare-signals": {
569 "version": "4.2.0",
570 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
571 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
572 "dev": true,
573 "license": "Apache-2.0",
574 "dependencies": {
575 "bare-events": "^2.5.3",
576 "bare-os": "^3.3.1"
577 },
578 "engines": {
579 "bare": ">=1.7.0"
580 }
581 },
582 "node_modules/bare-stdio/node_modules/bare-tty": {
583 "version": "5.1.0",
584 "resolved": "https://registry.npmjs.org/bare-tty/-/bare-tty-5.1.0.tgz",
585 "integrity": "sha512-EZLvW4A+XiJgI3TW+e1pMME9PIJsfEXe/DA/WSKzIkq/v7Yarpv/rvG6Z5pGnpo4V/Bd+qopwnCLSR71hMMBYA==",
586 "dev": true,
587 "license": "Apache-2.0",
588 "dependencies": {
589 "bare-events": "^2.2.0",
590 "bare-signals": "^4.0.0",
591 "bare-stream": "^2.0.0"
592 },
593 "engines": {
594 "bare": ">=1.16.0"
595 }
596 },
597 "node_modules/bare-stream": {
598 "version": "2.13.0",
599 "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.0.tgz",
600 "integrity": "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA==",
601 "devOptional": true,
602 "license": "Apache-2.0",
603 "dependencies": {
604 "streamx": "^2.25.0",
605 "teex": "^1.0.1"
606 },
607 "peerDependencies": {
608 "bare-abort-controller": "*",
609 "bare-buffer": "*",
610 "bare-events": "*"
611 },
612 "peerDependenciesMeta": {
613 "bare-abort-controller": {
614 "optional": true
615 },
616 "bare-buffer": {
617 "optional": true
618 },
619 "bare-events": {
620 "optional": true
621 }
622 }
623 },
624 "node_modules/bare-stylize": {
625 "version": "0.0.1",
626 "resolved": "https://registry.npmjs.org/bare-stylize/-/bare-stylize-0.0.1.tgz",
627 "integrity": "sha512-l3MjmIl476bWijYWf3RbE+osl4iuXSOMudzp0vAqzIK7gPgn/+G3oAxp8Oin9CFF911KBP0LO9kts8Ci8mGZaQ==",
628 "dev": true,
629 "license": "Apache-2.0",
630 "dependencies": {
631 "bare-ansi-escapes": "^2.2.3",
632 "bare-process": "^4.2.1"
633 }
634 },
635 "node_modules/bare-stylize/node_modules/bare-process": {
636 "version": "4.4.1",
637 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.4.1.tgz",
638 "integrity": "sha512-JfcTtymq6akqM2bdyTsP4A4GYJceBzb91k/ECmFps75uFf6uO33SM1bOZsRAqyRXExabsQJLn5S41NBl8HTM4A==",
639 "dev": true,
640 "license": "Apache-2.0",
641 "dependencies": {
642 "bare-abort": "^2.0.13",
643 "bare-env": "^3.0.0",
644 "bare-events": "^2.3.1",
645 "bare-hrtime": "^2.0.0",
646 "bare-os": "^3.7.1",
647 "bare-signals": "^4.0.0",
648 "bare-stdio": "^1.0.1"
649 }
650 },
651 "node_modules/bare-stylize/node_modules/bare-signals": {
652 "version": "4.2.0",
653 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
654 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
655 "dev": true,
656 "license": "Apache-2.0",
657 "dependencies": {
658 "bare-events": "^2.5.3",
659 "bare-os": "^3.3.1"
660 },
661 "engines": {
662 "bare": ">=1.7.0"
663 }
664 },
665 "node_modules/bare-subprocess": {
666 "version": "5.2.3",
667 "resolved": "https://registry.npmjs.org/bare-subprocess/-/bare-subprocess-5.2.3.tgz",
668 "integrity": "sha512-07wwswlV7M3sC9IykbZRZ/jHAkrXFWVLqdBWGv1y0ojCimtRD9hGwxdHmR5FUFmDUZLNsBmTYJNQqgio5+A85Q==",
669 "dev": true,
670 "license": "Apache-2.0",
671 "dependencies": {
672 "bare-env": "^3.0.0",
673 "bare-events": "^2.5.4",
674 "bare-os": "^3.0.1",
675 "bare-pipe": "^4.0.0",
676 "bare-url": "^2.2.2"
677 },
678 "engines": {
679 "bare": ">=1.7.0"
680 },
681 "peerDependencies": {
682 "bare-buffer": "*"
683 },
684 "peerDependenciesMeta": {
685 "bare-buffer": {
686 "optional": true
687 }
688 }
689 },
690 "node_modules/bare-tcp": {
691 "version": "2.2.7",
692 "resolved": "https://registry.npmjs.org/bare-tcp/-/bare-tcp-2.2.7.tgz",
693 "integrity": "sha512-rjpqNQ2cOCkNo3NeYA/W4GTK3DRkl8sDHO3uos+AEswUjLC8XXMQF8WrJCSjlIowCbS6NUVxKE92X5RGXjyefg==",
694 "devOptional": true,
695 "license": "Apache-2.0",
696 "dependencies": {
697 "bare-dns": "^2.0.4",
698 "bare-events": "^2.5.4",
699 "bare-stream": "^2.6.4"
700 },
701 "engines": {
702 "bare": ">=1.16.0"
703 }
704 },
705 "node_modules/bare-tls": {
706 "version": "2.2.3",
707 "resolved": "https://registry.npmjs.org/bare-tls/-/bare-tls-2.2.3.tgz",
708 "integrity": "sha512-dPYBGEXtgLceRFMfGaF2/rqR86/xMxMyrM9ootO/gaRKL/z2uNHJs7aP7IOBtnJF8eUCt5qwMzbKfrKgDIxPLg==",
709 "dev": true,
710 "license": "Apache-2.0",
711 "dependencies": {
712 "bare-net": "^2.0.1",
713 "bare-stream": "^2.6.4"
714 },
715 "engines": {
716 "bare": ">=1.7.0"
717 }
718 },
719 "node_modules/bare-tty": {
720 "version": "4.0.2",
721 "resolved": "https://registry.npmjs.org/bare-tty/-/bare-tty-4.0.2.tgz",
722 "integrity": "sha512-MfNtmUx/FhZZKn+IAe9Sai5mYFg/m+LBF1pSY56cjX6j2vQFEnm8NNsWryiyB85haYeN7tDh66WTcbUDJnBVtQ==",
723 "license": "Apache-2.0",
724 "optional": true,
725 "dependencies": {
726 "bare-events": "^2.2.0",
727 "bare-signals": "^3.0.0",
728 "bare-stream": "^2.0.0"
729 }
730 },
731 "node_modules/bare-type": {
732 "version": "1.1.0",
733 "resolved": "https://registry.npmjs.org/bare-type/-/bare-type-1.1.0.tgz",
734 "integrity": "sha512-LdtnnEEYldOc87Dr4GpsKnStStZk3zfgoEMXy8yvEZkXrcCv9RtYDrUYWFsBQHtaB0s1EUWmcvS6XmEZYIj3Bw==",
735 "dev": true,
736 "license": "Apache-2.0",
737 "engines": {
738 "bare": ">=1.2.0"
739 }
740 },
741 "node_modules/bare-url": {
742 "version": "2.4.0",
743 "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.0.tgz",
744 "integrity": "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA==",
745 "devOptional": true,
746 "license": "Apache-2.0",
747 "peer": true,
748 "dependencies": {
749 "bare-path": "^3.0.0"
750 }
751 },
752 "node_modules/bare-utils": {
753 "version": "1.6.0",
754 "resolved": "https://registry.npmjs.org/bare-utils/-/bare-utils-1.6.0.tgz",
755 "integrity": "sha512-WhQEIkkAxkSnW7u1QgrI0AfNm5JpMruETXeYsb5qnkBJ0TTfNKygZmsh6rkoHBANaV+C/7Jed7bJP9OmEHG7rQ==",
756 "dev": true,
757 "license": "Apache-2.0",
758 "dependencies": {
759 "bare-debug-log": "^2.0.0",
760 "bare-encoding": "^1.0.0",
761 "bare-format": "^1.0.0",
762 "bare-inspect": "^3.0.0",
763 "bare-stylize": "^0.0.1",
764 "bare-type": "^1.0.6"
765 }
766 },
767 "node_modules/bare-v8-to-istanbul": {
768 "version": "1.0.2",
769 "resolved": "https://registry.npmjs.org/bare-v8-to-istanbul/-/bare-v8-to-istanbul-1.0.2.tgz",
770 "integrity": "sha512-CM0wPgyQtXTQ7h4q8NjbTZ/FH5he0Jkiwgpq0lFZZA5tkVZzmQ/9ul4R7E+cNlGZJIZlQZ9v4CwbgVaFG3zOAA==",
771 "dev": true,
772 "license": "Apache-2.0",
773 "dependencies": {
774 "bare-assert": "^1.0.2",
775 "bare-fs": "^4.1.2",
776 "bare-module": "^6.1.2",
777 "bare-path": "^3.0.0",
778 "bare-process": "^4.2.0",
779 "bare-url": "^2.1.5",
780 "bare-utils": "^1.2.0",
781 "v8-to-istanbul": "^9.3.0",
782 "which-runtime": "^1.2.1"
783 }
784 },
785 "node_modules/bare-v8-to-istanbul/node_modules/bare-process": {
786 "version": "4.4.1",
787 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.4.1.tgz",
788 "integrity": "sha512-JfcTtymq6akqM2bdyTsP4A4GYJceBzb91k/ECmFps75uFf6uO33SM1bOZsRAqyRXExabsQJLn5S41NBl8HTM4A==",
789 "dev": true,
790 "license": "Apache-2.0",
791 "dependencies": {
792 "bare-abort": "^2.0.13",
793 "bare-env": "^3.0.0",
794 "bare-events": "^2.3.1",
795 "bare-hrtime": "^2.0.0",
796 "bare-os": "^3.7.1",
797 "bare-signals": "^4.0.0",
798 "bare-stdio": "^1.0.1"
799 }
800 },
801 "node_modules/bare-v8-to-istanbul/node_modules/bare-signals": {
802 "version": "4.2.0",
803 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
804 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
805 "dev": true,
806 "license": "Apache-2.0",
807 "dependencies": {
808 "bare-events": "^2.5.3",
809 "bare-os": "^3.3.1"
810 },
811 "engines": {
812 "bare": ">=1.7.0"
813 }
814 },
815 "node_modules/bare-ws": {
816 "version": "2.1.0",
817 "resolved": "https://registry.npmjs.org/bare-ws/-/bare-ws-2.1.0.tgz",
818 "integrity": "sha512-2gEWlPK9iyBchACdIY6oQXgmDz3KLrChdwrPgmU3IVXOFTnxTqSUT27WE/+izd4QojHj/SsqDkQiD2HDvuTdAA==",
819 "dev": true,
820 "license": "Apache-2.0",
821 "dependencies": {
822 "bare-crypto": "^1.2.0",
823 "bare-events": "^2.3.1",
824 "bare-http1": "^4.0.0",
825 "bare-https": "^2.0.0",
826 "bare-stream": "^2.1.2"
827 },
828 "peerDependencies": {
829 "bare-buffer": "*",
830 "bare-url": "*"
831 },
832 "peerDependenciesMeta": {
833 "bare-buffer": {
834 "optional": true
835 },
836 "bare-url": {
837 "optional": true
838 }
839 }
840 },
841 "node_modules/bare-zlib": {
842 "version": "1.3.3",
843 "resolved": "https://registry.npmjs.org/bare-zlib/-/bare-zlib-1.3.3.tgz",
844 "integrity": "sha512-rXNczo+SQg6cn20olmh/mUiGeJK9maipFH/zI/QwYgwhEmOns1R7fl1GV5apNO+aAp4x2d4uUa7HLhO4mhOnBQ==",
845 "license": "Apache-2.0",
846 "optional": true,
847 "dependencies": {
848 "bare-stream": "^2.0.0"
849 }
850 },
851 "node_modules/brittle": {
852 "version": "3.19.1",
853 "resolved": "https://registry.npmjs.org/brittle/-/brittle-3.19.1.tgz",
854 "integrity": "sha512-4Ted1Mt9o9B6oIA6ImJJCtB/Fv++ZO3IDNQgRcHOXWSYGRUidgxchaGrUBaRn+4mlneXrgInPkCPzi0jO8qKbA==",
855 "dev": true,
856 "license": "Apache-2.0",
857 "dependencies": {
858 "b4a": "^1.6.0",
859 "bare-assert": "^1.0.2",
860 "bare-cov": "^1.1.0",
861 "bare-fs": "^4.1.6",
862 "bare-os": "^3.6.1",
863 "bare-path": "^3.0.0",
864 "bare-process": "^4.2.1",
865 "bare-subprocess": "^5.0.0",
866 "bare-url": "^2.1.6",
867 "error-stack-parser": "^2.1.4",
868 "globbie": "^1.0.2",
869 "paparam": "^1.6.2",
870 "same-object": "^1.0.2",
871 "test-tmp": "^1.4.0",
872 "tmatch": "^5.0.0"
873 },
874 "bin": {
875 "brittle": "bin/node.js",
876 "brittle-bare": "bin/bare.js",
877 "brittle-node": "bin/node.js",
878 "brittle-pear": "bin/pear.js"
879 }
880 },
881 "node_modules/brittle/node_modules/bare-process": {
882 "version": "4.4.1",
883 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.4.1.tgz",
884 "integrity": "sha512-JfcTtymq6akqM2bdyTsP4A4GYJceBzb91k/ECmFps75uFf6uO33SM1bOZsRAqyRXExabsQJLn5S41NBl8HTM4A==",
885 "dev": true,
886 "license": "Apache-2.0",
887 "dependencies": {
888 "bare-abort": "^2.0.13",
889 "bare-env": "^3.0.0",
890 "bare-events": "^2.3.1",
891 "bare-hrtime": "^2.0.0",
892 "bare-os": "^3.7.1",
893 "bare-signals": "^4.0.0",
894 "bare-stdio": "^1.0.1"
895 }
896 },
897 "node_modules/brittle/node_modules/bare-signals": {
898 "version": "4.2.0",
899 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
900 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
901 "dev": true,
902 "license": "Apache-2.0",
903 "dependencies": {
904 "bare-events": "^2.5.3",
905 "bare-os": "^3.3.1"
906 },
907 "engines": {
908 "bare": ">=1.7.0"
909 }
910 },
911 "node_modules/convert-source-map": {
912 "version": "2.0.0",
913 "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
914 "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
915 "dev": true,
916 "license": "MIT"
917 },
918 "node_modules/error-stack-parser": {
919 "version": "2.1.4",
920 "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
921 "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
922 "dev": true,
923 "license": "MIT",
924 "dependencies": {
925 "stackframe": "^1.3.4"
926 }
927 },
928 "node_modules/events-universal": {
929 "version": "1.0.1",
930 "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz",
931 "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==",
932 "devOptional": true,
933 "license": "Apache-2.0",
934 "dependencies": {
935 "bare-events": "^2.7.0"
936 }
937 },
938 "node_modules/fast-fifo": {
939 "version": "1.3.2",
940 "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
941 "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==",
942 "devOptional": true,
943 "license": "MIT"
944 },
945 "node_modules/globbie": {
946 "version": "1.0.3",
947 "resolved": "https://registry.npmjs.org/globbie/-/globbie-1.0.3.tgz",
948 "integrity": "sha512-hcryJmKcftf82xfBWTWxuUITWIIoYO3ec104V17SMHGFl6VLbm1d1Ju9LX9L+jyJTwICpemX/dmPI/HGYoKr1A==",
949 "dev": true,
950 "license": "Apache-2.0",
951 "dependencies": {
952 "bare-fs": "^4.1.2",
953 "bare-path": "^3.0.0",
954 "bare-process": "^4.2.1",
955 "picomatch": "^4.0.2"
956 }
957 },
958 "node_modules/globbie/node_modules/bare-process": {
959 "version": "4.4.1",
960 "resolved": "https://registry.npmjs.org/bare-process/-/bare-process-4.4.1.tgz",
961 "integrity": "sha512-JfcTtymq6akqM2bdyTsP4A4GYJceBzb91k/ECmFps75uFf6uO33SM1bOZsRAqyRXExabsQJLn5S41NBl8HTM4A==",
962 "dev": true,
963 "license": "Apache-2.0",
964 "dependencies": {
965 "bare-abort": "^2.0.13",
966 "bare-env": "^3.0.0",
967 "bare-events": "^2.3.1",
968 "bare-hrtime": "^2.0.0",
969 "bare-os": "^3.7.1",
970 "bare-signals": "^4.0.0",
971 "bare-stdio": "^1.0.1"
972 }
973 },
974 "node_modules/globbie/node_modules/bare-signals": {
975 "version": "4.2.0",
976 "resolved": "https://registry.npmjs.org/bare-signals/-/bare-signals-4.2.0.tgz",
977 "integrity": "sha512-fNHMOdQIlYuTvMB3Oh9Apk99hLKn351+Ir8vz+khiPTcOqIyGG4uWWjdLTzxWdYGsA0eT+We3y0K74hjj2nq7A==",
978 "dev": true,
979 "license": "Apache-2.0",
980 "dependencies": {
981 "bare-events": "^2.5.3",
982 "bare-os": "^3.3.1"
983 },
984 "engines": {
985 "bare": ">=1.7.0"
986 }
987 },
988 "node_modules/paparam": {
989 "version": "1.10.1",
990 "resolved": "https://registry.npmjs.org/paparam/-/paparam-1.10.1.tgz",
991 "integrity": "sha512-viyQI64VIja0Za3njIzhoEP8ZVkgPowhZPuG0E96NwBfYJ6ZIyrrlhWGtFPkdN7eYLl2L8CTWL+wla0evm1KKQ==",
992 "license": "Apache-2.0"
993 },
994 "node_modules/picomatch": {
995 "version": "4.0.4",
996 "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
997 "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
998 "dev": true,
999 "license": "MIT",
1000 "engines": {
1001 "node": ">=12"
1002 },
1003 "funding": {
1004 "url": "https://github.com/sponsors/jonschlinkert"
1005 }
1006 },
1007 "node_modules/require-addon": {
1008 "version": "1.2.0",
1009 "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.2.0.tgz",
1010 "integrity": "sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==",
1011 "dev": true,
1012 "license": "Apache-2.0",
1013 "dependencies": {
1014 "bare-addon-resolve": "^1.3.0"
1015 },
1016 "engines": {
1017 "bare": ">=1.10.0"
1018 }
1019 },
1020 "node_modules/same-object": {
1021 "version": "1.0.2",
1022 "resolved": "https://registry.npmjs.org/same-object/-/same-object-1.0.2.tgz",
1023 "integrity": "sha512-csHWhvUsLbIOHDM/nP+KHWM+BLPsIzWkFa8HbzaI0G7BqKXgx+7FJpKTGgLXyz5amfdY2OVBcmXTqYOMEk04og==",
1024 "dev": true,
1025 "license": "MIT"
1026 },
1027 "node_modules/stackframe": {
1028 "version": "1.3.4",
1029 "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
1030 "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
1031 "dev": true,
1032 "license": "MIT"
1033 },
1034 "node_modules/streamx": {
1035 "version": "2.25.0",
1036 "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.25.0.tgz",
1037 "integrity": "sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==",
1038 "devOptional": true,
1039 "license": "MIT",
1040 "dependencies": {
1041 "events-universal": "^1.0.0",
1042 "fast-fifo": "^1.3.2",
1043 "text-decoder": "^1.1.0"
1044 }
1045 },
1046 "node_modules/teex": {
1047 "version": "1.0.1",
1048 "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
1049 "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==",
1050 "devOptional": true,
1051 "license": "MIT",
1052 "dependencies": {
1053 "streamx": "^2.12.5"
1054 }
1055 },
1056 "node_modules/test-tmp": {
1057 "version": "1.4.0",
1058 "resolved": "https://registry.npmjs.org/test-tmp/-/test-tmp-1.4.0.tgz",
1059 "integrity": "sha512-GVggxGg+jXqP2Wbju50JVLo+9E+nIOPPyWqgr63EbOnNItIKu1cEbJpTWAJeflnyGqXOtcMI7ijHRp88GUkfDA==",
1060 "dev": true,
1061 "license": "MIT",
1062 "dependencies": {
1063 "bare-fs": "^4.0.1",
1064 "bare-os": "^3.3.0",
1065 "bare-path": "^3.0.0"
1066 }
1067 },
1068 "node_modules/text-decoder": {
1069 "version": "1.2.7",
1070 "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz",
1071 "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==",
1072 "devOptional": true,
1073 "license": "Apache-2.0",
1074 "dependencies": {
1075 "b4a": "^1.6.4"
1076 }
1077 },
1078 "node_modules/tmatch": {
1079 "version": "5.0.0",
1080 "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-5.0.0.tgz",
1081 "integrity": "sha512-Ib9OtBkpHn07tXP04SlN1SYRxFgTk6wSM2EBmjjxug4u5RXPRVLkdFJSS1PmrQidaSB8Lru9nRtViQBsbxzE5Q==",
1082 "dev": true,
1083 "license": "ISC",
1084 "engines": {
1085 "node": ">=8"
1086 }
1087 },
1088 "node_modules/v8-to-istanbul": {
1089 "version": "9.3.0",
1090 "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
1091 "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
1092 "dev": true,
1093 "license": "ISC",
1094 "dependencies": {
1095 "@jridgewell/trace-mapping": "^0.3.12",
1096 "@types/istanbul-lib-coverage": "^2.0.1",
1097 "convert-source-map": "^2.0.0"
1098 },
1099 "engines": {
1100 "node": ">=10.12.0"
1101 }
1102 },
1103 "node_modules/which-runtime": {
1104 "version": "1.3.2",
1105 "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.3.2.tgz",
1106 "integrity": "sha512-5kwCfWml7+b2NO7KrLMhYihjRx0teKkd3yGp1Xk5Vaf2JGdSh+rgVhEALAD9c/59dP+YwJHXoEO7e8QPy7gOkw==",
1107 "dev": true,
1108 "license": "Apache-2.0"
1109 }
1110 }
1111}
package.json +38 -0
……@@ -0,0 +1,38 @@
1{
2 "name": "codetree",
3 "version": "0.1.0",
4 "description": "Structural code scanner — recursive mind map of a codebase",
5 "type": "module",
6 "main": "index.js",
7 "bin": {
8 "codetree": "./index.js"
9 },
10 "scripts": {
11 "test": "brittle test/*.test.js"
12 },
13 "imports": {
14 "fs": { "bare": "bare-fs", "default": "fs" },
15 "fs/*": { "bare": "bare-fs/*", "default": "fs/*" },
16 "path": { "bare": "bare-path", "default": "path" },
17 "url": { "bare": "bare-url", "default": "url" },
18 "process": { "bare": "bare-process", "default": "process" },
19 "http": { "bare": "bare-http1", "default": "http" },
20 "events": { "bare": "bare-events", "default": "events" },
21 "zlib": { "bare": "bare-zlib", "default": "zlib" }
22 },
23 "dependencies": {
24 "paparam": "^1.8.6"
25 },
26 "optionalDependencies": {
27 "bare-fs": "^4.5.0",
28 "bare-path": "^3.0.0",
29 "bare-process": "^3.0.0",
30 "bare-url": "^2.3.2",
31 "bare-http1": "^4.0.0",
32 "bare-events": "^2.5.0",
33 "bare-zlib": "^1.3.0"
34 },
35 "devDependencies": {
36 "brittle": "^3.0.0"
37 }
38}
test/cpp.test.js +113 -0
……@@ -0,0 +1,113 @@
1import { test } from 'brittle'
2import { parseFile } from '../lib/parsers/cpp.js'
3
4test('cpp: includes — local vs system', (t) => {
5 const src = `#include <godot_cpp/classes/node3d.hpp>
6#include <memory>
7#include "dc_density.h"
8#include "dc_octree.h"
9
10int main() { return 0; }
11`
12
13 const result = parseFile(src, 'main.cpp')
14 t.is(result.imports.length, 2, '2 local includes (system ones skipped)')
15 t.is(result.imports[0].specifier, 'dc_density.h', 'first local include')
16 t.is(result.imports[1].specifier, 'dc_octree.h', 'second local include')
17})
18
19test('cpp: class with methods, inheritance, access specifiers', (t) => {
20 const src = `class DCTerrain : public Node3D {
21public:
22 void set_resolution(int res);
23 int get_resolution() const;
24 static DCTerrain* create();
25protected:
26 static void _bind_methods();
27private:
28 int _resolution = 256;
29};
30`
31
32 const result = parseFile(src, 'dc_terrain.h')
33 t.is(result.classes.length, 1, '1 class')
34 const cls = result.classes[0]
35 t.is(cls.name, 'DCTerrain', 'class name')
36 t.is(cls.extends, 'Node3D', 'base class')
37 t.is(cls.kind, 'class', 'kind is class')
38
39 const methodNames = cls.methods.map(m => m.name)
40 t.ok(methodNames.includes('set_resolution'), 'set_resolution method')
41 t.ok(methodNames.includes('get_resolution'), 'get_resolution method')
42
43 const staticNames = cls.staticMethods.map(m => m.name)
44 t.ok(staticNames.includes('create'), 'create static method')
45 t.ok(staticNames.includes('_bind_methods'), '_bind_methods static method')
46})
47
48test('cpp: namespaces', (t) => {
49 const src = `namespace dc {
50
51class Foo {
52public:
53 void bar();
54};
55
56} // namespace dc
57`
58
59 const result = parseFile(src, 'foo.h')
60 t.ok(result.namespaces.includes('dc'), 'dc namespace captured')
61 t.is(result.classes.length, 1, 'class inside namespace still found')
62})
63
64test('cpp: struct parsed as class with kind=struct', (t) => {
65 const src = `struct Point {
66 int x;
67 int y;
68 void translate(int dx, int dy);
69};
70`
71
72 const result = parseFile(src, 'point.h')
73 t.is(result.classes.length, 1, '1 struct')
74 t.is(result.classes[0].kind, 'struct', 'kind is struct')
75 t.is(result.classes[0].name, 'Point', 'struct name')
76})
77
78test('cpp: enum', (t) => {
79 const src = `enum class State { IDLE, RUNNING, DONE };
80enum Mode { READ, WRITE };
81`
82
83 const result = parseFile(src, 'state.h')
84 t.is(result.enums.length, 2, '2 enums')
85 t.is(result.enums[0].name, 'State', 'first enum')
86 t.ok(result.enums[0].values.includes('IDLE'), 'IDLE value')
87 t.ok(result.enums[0].values.includes('RUNNING'), 'RUNNING value')
88})
89
90test('cpp: out-of-line method definitions merge back into class', (t) => {
91 const src = `class Foo {
92public:
93 void bar();
94 void baz();
95};
96
97void Foo::bar() {
98 // implementation
99}
100
101void Foo::baz() {
102 // implementation
103}
104`
105
106 const result = parseFile(src, 'foo.cpp')
107 t.is(result.classes.length, 1, '1 class')
108 // Out-of-line definitions merge into class methods
109 const methodNames = result.classes[0].methods.map(m => m.name)
110 t.ok(methodNames.includes('bar'), 'bar method')
111 t.ok(methodNames.includes('baz'), 'baz method')
112 t.is(result.functions.length, 0, 'no free functions (all are methods)')
113})
test/gdscript.test.js +98 -0
……@@ -0,0 +1,98 @@
1import { test } from 'brittle'
2import { parseFile } from '../lib/parsers/gdscript.js'
3
4test('gdscript: class_name + extends + methods + signals', (t) => {
5 const src = `class_name KeetFeed
6extends Node
7
8signal room_selected(room_id: String)
9signal message_received(data: Dictionary)
10
11@export var max_messages: int = 100
12const MAX_CACHED := 100
13
14func _ready() -> void:
15 pass
16
17func send_message(text: String, room_id: String) -> bool:
18 return false
19
20static func create_from_config(config: Dictionary) -> KeetFeed:
21 return null
22`
23
24 const result = parseFile(src, 'keet_feed.gd')
25
26 t.is(result.error, undefined, 'no parse error')
27 t.is(result.classes.length, 1, '1 class')
28
29 const cls = result.classes[0]
30 t.is(cls.name, 'KeetFeed', 'class_name becomes class name')
31 t.is(cls.extends, 'Node', 'extends parsed')
32
33 t.is(cls.methods.length, 2, '2 instance methods')
34 const methodNames = cls.methods.map(m => m.name)
35 t.ok(methodNames.includes('_ready'), '_ready method')
36 t.ok(methodNames.includes('send_message'), 'send_message method')
37
38 t.is(cls.staticMethods.length, 1, '1 static method')
39 t.is(cls.staticMethods[0].name, 'create_from_config', 'static method name')
40
41 t.is(result.signals.length, 2, '2 signals')
42 t.is(result.signals[0].name, 'room_selected', 'first signal')
43
44 t.is(result.exports.length, 1, '1 export (the class_name)')
45 t.is(result.exports[0].name, 'KeetFeed', 'export name matches class_name')
46
47 t.ok(result.constants.length >= 2, 'has var + const constants')
48})
49
50test('gdscript: preload() extraction', (t) => {
51 const src = `class_name Game
52extends Node
53
54const PlayerScene := preload("res://scenes/player/player.tscn")
55const EnemyScene: PackedScene = preload("res://scenes/enemies/enemy.tscn")
56
57func _ready() -> void:
58 pass
59`
60
61 const result = parseFile(src, 'game.gd')
62 t.is(result.imports.length, 2, '2 preload imports')
63 t.is(result.imports[0].specifier, 'res://scenes/player/player.tscn', 'first preload path')
64 t.is(result.imports[1].specifier, 'res://scenes/enemies/enemy.tscn', 'second preload path')
65})
66
67test('gdscript: handles file without class_name', (t) => {
68 const src = `extends RefCounted
69
70func util_function(x: int) -> int:
71 return x * 2
72`
73
74 const result = parseFile(src, 'util.gd')
75 t.is(result.error, undefined, 'no parse error')
76 // Class name should default to filename (without .gd)
77 if (result.classes.length > 0) {
78 t.is(result.classes[0].name, 'util', 'class name defaults to filename')
79 }
80})
81
82test('gdscript: constructor (_init)', (t) => {
83 const src = `class_name MyClass
84extends Node
85
86func _init(name: String) -> void:
87 pass
88
89func do_thing():
90 pass
91`
92
93 const result = parseFile(src, 'my_class.gd')
94 const cls = result.classes[0]
95 t.ok(cls.constructor, 'has constructor')
96 t.is(cls.constructor.params.length, 1, 'constructor param count')
97 t.is(cls.methods.length, 1, '_init is not counted as a regular method')
98})
test/glsl.test.js +105 -0
……@@ -0,0 +1,105 @@
1import { test } from 'brittle'
2import { parseFile } from '../lib/parsers/glsl.js'
3
4test('glsl: compute shader with buffers and push constants', (t) => {
5 const src = `#version 450
6
7layout(local_size_x = 256) in;
8layout(set = 0, binding = 0, std430) readonly buffer DensityBuf { float density[]; };
9layout(set = 0, binding = 1, std430) writeonly buffer EdgeBuf { uint edges[]; };
10layout(push_constant) uniform PushConstants { uint grid_size; float iso_level; } pc;
11
12void main() {
13 uint idx = 0u;
14}
15`
16
17 const result = parseFile(src, 'compute.glsl')
18 t.is(result.error, undefined, 'no parse error')
19
20 t.is(result.buffers.length, 2, '2 buffers')
21 t.is(result.buffers[0].name, 'DensityBuf', 'first buffer name')
22 t.ok(result.buffers[0].readonly, 'first buffer is readonly')
23 t.ok(result.buffers[1].writeonly, 'second buffer is writeonly')
24 t.is(result.buffers[0].binding, '0', 'binding captured')
25 t.is(result.buffers[0].set, '0', 'set captured')
26
27 t.is(result.pushConstants.length, 1, '1 push constant block')
28 t.is(result.pushConstants[0].name, 'PushConstants', 'push constant name')
29
30 t.ok(result.functions.find(f => f.name === 'main'), 'main function found')
31 t.ok(result.exports.find(e => e.name === 'main'), 'main is exported (shader entry)')
32})
33
34test('glsl: regular uniforms', (t) => {
35 const src = `#version 330
36
37uniform float u_time;
38uniform sampler2D u_texture;
39uniform vec3 u_color;
40
41void main() { }
42`
43
44 const result = parseFile(src, 'frag.glsl')
45 t.is(result.uniforms.length, 3, '3 uniforms')
46 const names = result.uniforms.map(u => u.name)
47 t.ok(names.includes('u_time'), 'u_time uniform')
48 t.ok(names.includes('u_texture'), 'u_texture uniform')
49 t.ok(names.includes('u_color'), 'u_color uniform')
50})
51
52test('glsl: #define becomes constant', (t) => {
53 const src = `#define THREADS 256
54#define MAX_ITERATIONS 100
55
56void main() { }
57`
58
59 const result = parseFile(src, 'compute.glsl')
60 const names = result.constants.map(c => c.name)
61 t.ok(names.includes('THREADS'), 'THREADS define captured')
62 t.ok(names.includes('MAX_ITERATIONS'), 'MAX_ITERATIONS define captured')
63})
64
65test('glsl: struct becomes a class with kind=struct', (t) => {
66 const src = `struct Vertex {
67 vec3 position;
68 vec3 normal;
69 vec2 uv;
70};
71
72void main() { }
73`
74
75 const result = parseFile(src, 'vert.glsl')
76 t.is(result.classes.length, 1, '1 struct')
77 t.is(result.classes[0].name, 'Vertex', 'struct name')
78 t.is(result.classes[0].kind, 'struct', 'kind is struct')
79})
80
81test('glsl: Godot .gdshader hint syntax is stripped', (t) => {
82 const src = `shader_type spatial;
83render_mode unshaded, cull_disabled;
84
85uniform float density_scale : hint_range(0.0, 20.0) = 8.0;
86uniform sampler3D cloud_density : filter_linear_mipmap, repeat_enable;
87
88void fragment() {
89 ALBEDO = vec3(1.0);
90}
91`
92
93 const result = parseFile(src, 'cloud.gdshader')
94 t.is(result.error, undefined, 'no parse error after hint stripping')
95 t.is(result.uniforms.length, 2, '2 uniforms despite hints')
96 t.ok(result.functions.find(f => f.name === 'fragment'), 'fragment function')
97})
98
99test('glsl: parse error returns empty structure (no crash)', (t) => {
100 const src = `this is not valid glsl !!!`
101 const result = parseFile(src, 'broken.glsl')
102 t.ok(result.error, 'error reported')
103 t.is(result.functions.length, 0, 'functions is still an empty array')
104 t.is(result.classes.length, 0, 'classes is still an empty array')
105})
test/ignore.test.js +115 -0
……@@ -0,0 +1,115 @@
1import { test } from 'brittle'
2import { mkdirSync, writeFileSync, rmSync, existsSync } from 'fs'
3import { join, dirname, resolve } from 'path'
4import { fileURLToPath } from 'url'
5import { buildIgnoreMatcher } from '../lib/ignore.js'
6
7const HERE = dirname(fileURLToPath(import.meta.url))
8const FIXTURE = resolve(HERE, 'fixtures-ignore')
9
10function setupFixture () {
11 if (existsSync(FIXTURE)) rmSync(FIXTURE, { recursive: true, force: true })
12 mkdirSync(FIXTURE, { recursive: true })
13 return FIXTURE
14}
15
16function mk (root, relPath, content = '') {
17 const full = join(root, relPath)
18 mkdirSync(dirname(full), { recursive: true })
19 writeFileSync(full, content)
20 return full
21}
22
23test('ignore: built-in defaults skip node_modules/.git/vendor/etc', (t) => {
24 const root = setupFixture()
25 const ignore = buildIgnoreMatcher(root)
26
27 t.ok(ignore(join(root, 'node_modules')), 'node_modules hidden')
28 t.ok(ignore(join(root, 'node_modules/foo/index.js')), 'file under node_modules hidden')
29 t.ok(ignore(join(root, '.git/HEAD')), '.git contents hidden')
30 t.ok(ignore(join(root, 'vendor')), 'vendor hidden')
31 t.ok(ignore(join(root, 'build/output.js')), 'build hidden')
32 t.absent(ignore(join(root, 'src/index.js')), 'src/ not hidden')
33
34 rmSync(root, { recursive: true, force: true })
35})
36
37test('ignore: .codetreeignore file at rootDir', (t) => {
38 const root = setupFixture()
39 mk(root, '.codetreeignore', '# comment line\nsecrets\nclients/*.key\nbackup/\n')
40 const ignore = buildIgnoreMatcher(root)
41
42 t.ok(ignore(join(root, 'secrets')), 'pattern "secrets" hides dir')
43 t.ok(ignore(join(root, 'foo/secrets/bar.txt')), 'name pattern matches at any depth')
44 t.ok(ignore(join(root, 'clients/acme.key')), 'glob pattern works')
45 t.ok(ignore(join(root, 'backup')), 'trailing-slash dir pattern')
46 t.absent(ignore(join(root, 'public/index.html')), 'unrelated path not hidden')
47 t.absent(ignore(join(root, 'clients/readme.md')), 'non-matching glob not hidden')
48
49 rmSync(root, { recursive: true, force: true })
50})
51
52test('ignore: .codetree-private marker hides whole subtree', (t) => {
53 const root = setupFixture()
54 mk(root, 'public/foo.js')
55 mk(root, 'private-work/.codetree-private')
56 mk(root, 'private-work/src/secret.js')
57 mk(root, 'private-work/docs/plan.md')
58
59 const ignore = buildIgnoreMatcher(root)
60
61 t.absent(ignore(join(root, 'public/foo.js')), 'public path visible')
62 t.ok(ignore(join(root, 'private-work')), 'marked dir itself hidden')
63 t.ok(ignore(join(root, 'private-work/src/secret.js')), 'file deep under marker hidden')
64 t.ok(ignore(join(root, 'private-work/docs/plan.md')), 'another file deep under marker hidden')
65
66 rmSync(root, { recursive: true, force: true })
67})
68
69test('ignore: --ignore flag patterns', (t) => {
70 const root = setupFixture()
71 const ignore = buildIgnoreMatcher(root, ['my-custom', 'tmp-*'])
72
73 t.ok(ignore(join(root, 'my-custom')), 'extra pattern applied')
74 t.ok(ignore(join(root, 'some/path/my-custom')), 'extra pattern matches at any depth')
75 t.ok(ignore(join(root, 'tmp-scratch')), 'glob in extra pattern works')
76 t.absent(ignore(join(root, 'normal')), 'unrelated not hidden')
77
78 rmSync(root, { recursive: true, force: true })
79})
80
81test('ignore: .codetreeignore + --ignore stack', (t) => {
82 const root = setupFixture()
83 mk(root, '.codetreeignore', 'from-file\n')
84 const ignore = buildIgnoreMatcher(root, ['from-flag'])
85
86 t.ok(ignore(join(root, 'from-file')), 'file pattern applied')
87 t.ok(ignore(join(root, 'from-flag')), 'flag pattern applied')
88 t.ok(ignore(join(root, 'node_modules')), 'built-in still applied')
89
90 rmSync(root, { recursive: true, force: true })
91})
92
93test('ignore: anchored / pattern matches only at root', (t) => {
94 const root = setupFixture()
95 mk(root, '.codetreeignore', '/top-only\n')
96 const ignore = buildIgnoreMatcher(root)
97
98 t.ok(ignore(join(root, 'top-only')), 'anchored matches at root')
99 t.ok(ignore(join(root, 'top-only/child.js')), 'contents under anchored also hidden')
100 t.absent(ignore(join(root, 'nested/top-only')), 'anchored does NOT match deeper')
101
102 rmSync(root, { recursive: true, force: true })
103})
104
105test('ignore: comments and blank lines in .codetreeignore', (t) => {
106 const root = setupFixture()
107 mk(root, '.codetreeignore', '# this is a comment\n\n \nlegit\n')
108 const ignore = buildIgnoreMatcher(root)
109
110 t.ok(ignore(join(root, 'legit')), 'valid pattern applied')
111 t.absent(ignore(join(root, '# this is a comment')), 'comments not treated as patterns')
112 t.absent(ignore(join(root, 'unrelated')), 'unrelated not hidden')
113
114 rmSync(root, { recursive: true, force: true })
115})
test/live-store.test.js +85 -0
……@@ -0,0 +1,85 @@
1import { test } from 'brittle'
2import { writeFileSync, mkdirSync, rmSync, existsSync } from 'fs'
3import { join, resolve, dirname } from 'path'
4import { fileURLToPath } from 'url'
5import { LiveStore } from '../lib/live-store.js'
6import { scanStream } from '../lib/scan-stream.js'
7import { TreeReducer } from '../lib/reducers/tree-reducer.js'
8
9const HERE = dirname(fileURLToPath(import.meta.url))
10const FIXTURE = resolve(HERE, 'fixtures-live')
11
12function setup () {
13 if (existsSync(FIXTURE)) rmSync(FIXTURE, { recursive: true, force: true })
14 mkdirSync(FIXTURE, { recursive: true })
15 writeFileSync(join(FIXTURE, 'package.json'), JSON.stringify({ name: 'fixture-live', version: '0.1.0', main: 'index.js' }))
16 writeFileSync(join(FIXTURE, 'index.js'), 'export const x = 1\n')
17}
18
19async function buildGraph () {
20 return new Promise((resolveP, reject) => {
21 const src = scanStream(FIXTURE)
22 const tree = new TreeReducer().attach(src)
23 src.once('scan-end', () => resolveP(tree.finalize()))
24 src.once('error', reject)
25 })
26}
27
28test('live-store: subscribe receives current state on attach', async (t) => {
29 setup()
30 const graph = await buildGraph()
31 const store = new LiveStore(graph, { watch: false })
32 store.seedFromGraph()
33
34 const events = []
35 store.subscribe(ev => events.push(ev.type))
36
37 t.is(events[0], 'scan-start', 'first replayed event is scan-start')
38 t.ok(events.includes('module-start'), 'module-start replayed')
39 t.ok(events.includes('file-discovered'), 'file-discovered replayed')
40 t.ok(events.includes('file-parsed'), 'file-parsed replayed')
41 t.is(events[events.length - 1], 'scan-end', 'last replayed event is scan-end')
42
43 store.stop()
44 rmSync(FIXTURE, { recursive: true, force: true })
45})
46
47test('live-store: late subscribers also get full state', async (t) => {
48 setup()
49 const graph = await buildGraph()
50 const store = new LiveStore(graph, { watch: false })
51 store.seedFromGraph()
52
53 // First subscriber
54 const first = []
55 store.subscribe(ev => first.push(ev.type))
56
57 // Second subscriber attaches AFTER seeding — must still get the full replay
58 const second = []
59 store.subscribe(ev => second.push(ev.type))
60
61 t.is(first.length, second.length, 'both subscribers see same number of events')
62 t.alike(first, second, 'event sequences match')
63
64 store.stop()
65 rmSync(FIXTURE, { recursive: true, force: true })
66})
67
68test('live-store: module-start payload uses moduleType not type for JS module flavor', async (t) => {
69 setup()
70 const graph = await buildGraph()
71 const store = new LiveStore(graph, { watch: false })
72 store.seedFromGraph()
73
74 let modStart = null
75 store.subscribe(ev => {
76 if (ev.type === 'module-start' && !modStart) modStart = ev
77 })
78
79 t.ok(modStart, 'got module-start event')
80 t.is(modStart.type, 'module-start', 'event type is preserved (no name collision)')
81 t.ok('moduleType' in modStart, 'JS module type carried as moduleType field')
82
83 store.stop()
84 rmSync(FIXTURE, { recursive: true, force: true })
85})
test/parser.test.js +256 -0
……@@ -0,0 +1,256 @@
1import { test } from 'brittle'
2import { readFileSync } from 'fs'
3import { resolve, dirname } from 'path'
4import { fileURLToPath } from 'url'
5import { parseFile } from '../lib/parsers/js.js'
6
7const HERE = dirname(fileURLToPath(import.meta.url))
8const ROOT = resolve(HERE, '../../')
9
10function readSource (rel) {
11 return readFileSync(resolve(ROOT, rel), 'utf-8')
12}
13
14test('parser: hyper-orgs/index.js re-exports', (t) => {
15 const source = readSource('hyper-orgs/index.js')
16 const result = parseFile(source, 'hyper-orgs/index.js')
17
18 t.absent(result.error, 'no parse error')
19 t.is(result.exports.length, 4, '4 re-exports')
20
21 const names = result.exports.map(e => e.name)
22 t.ok(names.includes('HyperOrgs'), 'exports HyperOrgs')
23 t.ok(names.includes('orgsSchema'), 'exports orgsSchema')
24 t.ok(names.includes('RESERVED_NAMES'), 'exports RESERVED_NAMES')
25 t.ok(names.includes('validateName'), 'exports validateName')
26
27 // All are re-exports from other files
28 const hyperOrgsExport = result.exports.find(e => e.name === 'HyperOrgs')
29 t.is(hyperOrgsExport.from, './lib/hyper-orgs.js', 'HyperOrgs from lib/hyper-orgs.js')
30
31 const schemaExports = result.exports.filter(e => e.from === './lib/schema.js')
32 t.is(schemaExports.length, 3, '3 exports from schema.js')
33})
34
35test('parser: hyper-orgs/lib/hyper-orgs.js class structure', (t) => {
36 const source = readSource('hyper-orgs/lib/hyper-orgs.js')
37 const result = parseFile(source, 'hyper-orgs/lib/hyper-orgs.js')
38
39 t.absent(result.error, 'no parse error')
40
41 // Imports
42 t.is(result.imports.length, 2, '2 imports')
43 const roomImport = result.imports.find(i => i.specifier === 'hyper-rooms')
44 t.ok(roomImport, 'imports from hyper-rooms')
45 t.ok(roomImport.names.includes('Room'), 'imports Room')
46
47 const schemaImport = result.imports.find(i => i.specifier === './schema.js')
48 t.ok(schemaImport, 'imports from ./schema.js')
49
50 // Exports
51 t.is(result.exports.length, 1, '1 export')
52 t.is(result.exports[0].name, 'HyperOrgs', 'exports HyperOrgs')
53 t.is(result.exports[0].type, 'class', 'export type is class')
54
55 // Class
56 t.is(result.classes.length, 1, '1 class')
57 const cls = result.classes[0]
58 t.is(cls.name, 'HyperOrgs', 'class name')
59 t.absent(cls.extends, 'does not extend anything')
60
61 // Constructor
62 t.ok(cls.constructor, 'has constructor')
63 t.is(cls.constructor.params.length, 2, 'constructor has 2 params')
64 t.is(cls.constructor.params[0], 'corestore', 'first param is corestore')
65 t.is(cls.constructor.params[1], 'options', 'second param is options')
66 t.ok(cls.constructor.jsdoc, 'constructor has JSDoc')
67
68 // Methods
69 const methodNames = cls.methods.map(m => m.name)
70 t.ok(methodNames.includes('ready'), 'has ready()')
71 t.ok(methodNames.includes('create'), 'has create()')
72 t.ok(methodNames.includes('get'), 'has get()')
73 t.ok(methodNames.includes('update'), 'has update()')
74 t.ok(methodNames.includes('delete'), 'has delete()')
75 t.ok(methodNames.includes('list'), 'has list()')
76 t.ok(methodNames.includes('checkAccess'), 'has checkAccess()')
77 t.ok(methodNames.includes('addMember'), 'has addMember()')
78 t.ok(methodNames.includes('addResource'), 'has addResource()')
79 t.ok(methodNames.includes('createGrant'), 'has createGrant()')
80 t.ok(methodNames.includes('createInvite'), 'has createInvite()')
81 t.ok(methodNames.includes('addWriter'), 'has addWriter()')
82
83 // Async methods
84 const createMethod = cls.methods.find(m => m.name === 'create')
85 t.ok(createMethod.async, 'create is async')
86 t.is(createMethod.params.length, 3, 'create has 3 params')
87 t.is(createMethod.params[0], 'name', 'create param 1: name')
88 t.is(createMethod.params[1], 'type', 'create param 2: type')
89 t.is(createMethod.params[2], 'data', 'create param 3: data')
90
91 // Getters
92 const getterNames = cls.getters.map(g => g.name)
93 t.ok(getterNames.includes('key'), 'has key getter')
94 t.ok(getterNames.includes('keyHex'), 'has keyHex getter')
95 t.ok(getterNames.includes('writable'), 'has writable getter')
96 t.ok(getterNames.includes('view'), 'has view getter')
97 t.ok(getterNames.includes('base'), 'has base getter')
98 t.ok(getterNames.includes('room'), 'has room getter')
99
100 // State
101 t.ok(result.state.includes('_room'), 'has _room state')
102
103 // Delegation
104 t.ok(result.delegates.length > 0, 'has delegation patterns')
105 const roomDelegate = result.delegates.find(d => d.field === '_room')
106 t.ok(roomDelegate, 'delegates to _room')
107 t.ok(roomDelegate.methods.includes('ready'), 'delegates ready to _room')
108 t.ok(roomDelegate.methods.includes('close'), 'delegates close to _room')
109
110 // Error contracts
111 t.ok(result.errorContracts.length > 0, 'has error contracts')
112})
113
114test('parser: pear-git-v3 handler factory pattern', (t) => {
115 const source = readSource('pear-git-v3/lib/handlers/orgs.js')
116 const result = parseFile(source, 'pear-git-v3/lib/handlers/orgs.js')
117
118 t.absent(result.error, 'no parse error')
119
120 // Should have an exported function (the handler factory)
121 const exportedFns = result.exports.filter(e => e.type === 'function')
122 t.ok(exportedFns.length > 0, 'has exported function(s)')
123})
124
125test('parser: CJS module (hyper-sync)', (t) => {
126 const source = readSource('hyper-sync/index.js')
127 const result = parseFile(source, 'hyper-sync/index.js')
128
129 t.absent(result.error, 'no parse error')
130
131 // Should detect CJS exports
132 const hasExport = result.exports.length > 0
133 t.ok(hasExport, 'detected CJS exports')
134
135 // Should detect a class
136 t.ok(result.classes.length > 0, 'found class(es)')
137})
138
139test('parser: JSDoc comment attachment', (t) => {
140 const source = `
141/**
142 * Does something useful.
143 * @param {string} name - the name
144 * @returns {boolean}
145 */
146export function doSomething (name) {
147 return true
148}
149
150/**
151 * A useful class.
152 */
153export class MyClass {
154 /**
155 * Create one.
156 * @param {object} opts
157 */
158 constructor (opts) {
159 this._opts = opts
160 }
161
162 /**
163 * Run it.
164 * @param {number} n
165 */
166 async run (n) {
167 return n
168 }
169}
170`
171 const result = parseFile(source, 'test.js')
172
173 t.absent(result.error, 'no parse error')
174
175 const fn = result.functions.find(f => f.name === 'doSomething')
176 t.ok(fn, 'found doSomething')
177 t.ok(fn.jsdoc, 'function has JSDoc')
178 t.ok(fn.jsdoc.includes('@param'), 'JSDoc has @param')
179
180 const cls = result.classes.find(c => c.name === 'MyClass')
181 t.ok(cls, 'found MyClass')
182 t.ok(cls.jsdoc, 'class has JSDoc')
183 t.ok(cls.constructor.jsdoc, 'constructor has JSDoc')
184
185 const runMethod = cls.methods.find(m => m.name === 'run')
186 t.ok(runMethod, 'found run method')
187 t.ok(runMethod.jsdoc, 'method has JSDoc')
188})
189
190test('parser: destructured params', (t) => {
191 const source = `
192export function handler ({ name, type, ...rest }) {
193 return { name, type }
194}
195
196export function multi (a, [b, c], { d }) {
197 return a
198}
199`
200 const result = parseFile(source, 'test.js')
201
202 const handler = result.functions.find(f => f.name === 'handler')
203 t.ok(handler, 'found handler')
204 t.is(handler.params[0], '{ name, type, ...rest }', 'destructured params preserved')
205
206 const multi = result.functions.find(f => f.name === 'multi')
207 t.ok(multi, 'found multi')
208 t.is(multi.params[0], 'a', 'simple param')
209 t.is(multi.params[1], '[b, c]', 'array destructured')
210 t.is(multi.params[2], '{ d }', 'object destructured')
211})
212
213test('parser: arrow functions as const', (t) => {
214 const source = `
215export const add = (a, b) => a + b
216export const fetchData = async (url) => {
217 return fetch(url)
218}
219`
220 const result = parseFile(source, 'test.js')
221
222 t.is(result.functions.length, 2, '2 functions')
223
224 const add = result.functions.find(f => f.name === 'add')
225 t.ok(add, 'found add')
226 t.ok(add.arrow, 'is arrow function')
227 t.is(add.params.length, 2, '2 params')
228
229 const fetchData = result.functions.find(f => f.name === 'fetchData')
230 t.ok(fetchData, 'found fetchData')
231 t.ok(fetchData.async, 'is async')
232 t.ok(fetchData.arrow, 'is arrow function')
233})
234
235test('parser: error contracts from template literals', (t) => {
236 const source = `
237export function validate (name) {
238 if (!name) throw new Error('Name is required')
239 if (name.length > 64) throw new Error(\`Name too long: \${name.length}\`)
240}
241`
242 const result = parseFile(source, 'test.js')
243
244 t.is(result.errorContracts.length, 2, '2 error contracts')
245 t.is(result.errorContracts[0], 'Name is required', 'literal error')
246 t.ok(result.errorContracts[1].includes('Name too long'), 'template error')
247})
248
249test('parser: export all (*)', (t) => {
250 const source = `export * from './utils.js'`
251 const result = parseFile(source, 'test.js')
252
253 t.is(result.exports.length, 1, '1 export')
254 t.is(result.exports[0].name, '*', 'star export')
255 t.is(result.exports[0].from, './utils.js', 'from source')
256})
test/scan-stream.test.js +134 -0
……@@ -0,0 +1,134 @@
1import { test } from 'brittle'
2import { resolve, dirname } from 'path'
3import { fileURLToPath } from 'url'
4import { scanStream } from '../lib/scan-stream.js'
5import { TreeReducer } from '../lib/reducers/tree-reducer.js'
6
7const HERE = dirname(fileURLToPath(import.meta.url))
8const HYPER_FLEEKY = resolve(HERE, '../../')
9
10test('scan-stream: emits scan-start before any other event', async (t) => {
11 const seen = []
12 const target = resolve(HYPER_FLEEKY, 'hyper-orgs')
13 await new Promise((resolveP, reject) => {
14 const src = scanStream(target)
15 for (const ev of ['scan-start', 'module-start', 'file-discovered', 'file-parsed', 'import-edge', 'module-end', 'scan-end']) {
16 src.on(ev, () => { if (!seen.includes(ev)) seen.push(ev) })
17 }
18 src.once('scan-end', resolveP)
19 src.once('error', reject)
20 })
21
22 t.is(seen[0], 'scan-start', 'scan-start fires first')
23 t.ok(seen.includes('module-start'), 'module-start fired')
24 t.ok(seen.includes('file-discovered'), 'file-discovered fired')
25 t.ok(seen.includes('file-parsed'), 'file-parsed fired')
26 t.is(seen[seen.length - 1], 'scan-end', 'scan-end fires last')
27})
28
29test('scan-stream: caller can attach listeners before walk starts', async (t) => {
30 // The walk is deferred via queueMicrotask, so listeners attached synchronously
31 // after scanStream() returns must still see scan-start.
32 const src = scanStream(resolve(HYPER_FLEEKY, 'hyper-orgs'))
33 let gotStart = false
34
35 await new Promise((resolve) => {
36 src.on('scan-start', () => { gotStart = true })
37 src.once('scan-end', resolve)
38 })
39
40 t.ok(gotStart, 'listeners attached after scanStream() still see scan-start')
41})
42
43test('scan-stream: TreeReducer rebuilds the same shape as walkGraph', async (t) => {
44 const target = resolve(HYPER_FLEEKY, 'hyper-orgs')
45 const graph = await new Promise((resolveP, reject) => {
46 const src = scanStream(target)
47 const tree = new TreeReducer().attach(src)
48 src.once('scan-end', () => resolveP(tree.finalize()))
49 src.once('error', reject)
50 })
51
52 t.ok(graph.modules.size === 1, '1 module')
53 t.ok(graph.modules.has('hyper-orgs'), 'has hyper-orgs')
54 t.ok(graph.root.endsWith('hyper-orgs'), 'root is correct')
55 t.is(graph.projectType, 'js', 'project type detected')
56
57 const mod = graph.modules.get('hyper-orgs')
58 t.ok(mod.entry, 'has entry')
59 t.ok(mod.files.size > 0, 'has files')
60})
61
62test('scan-stream: multiple subscribers see the same events', async (t) => {
63 let aCount = 0
64 let bCount = 0
65
66 const target = resolve(HYPER_FLEEKY, 'hyper-orgs')
67 await new Promise((resolveP) => {
68 const src = scanStream(target)
69 src.on('file-discovered', () => aCount++)
70 src.on('file-discovered', () => bCount++)
71 src.once('scan-end', resolveP)
72 })
73
74 t.is(aCount, bCount, 'both subscribers received same number of events')
75 t.ok(aCount > 0, 'at least one file event fired')
76})
77
78test('scan-stream: shallow mode skips internal files and import resolution', async (t) => {
79 // hyper-orgs has several files in lib/; shallow mode should only emit events
80 // for the entry file (index.js) and emit no import edges.
81 const target = resolve(HYPER_FLEEKY, 'hyper-orgs')
82 const discoveredFiles = []
83 const edges = []
84 let shallowFlag = null
85
86 await new Promise((resolveP) => {
87 const src = scanStream(target, { shallow: true })
88 src.on('scan-start', e => { shallowFlag = e.shallow })
89 src.on('file-discovered', e => discoveredFiles.push(e.relInPkg))
90 src.on('import-edge', e => edges.push(e))
91 src.once('scan-end', resolveP)
92 })
93
94 t.is(shallowFlag, true, 'scan-start carries shallow: true')
95 t.is(edges.length, 0, 'no import edges in shallow mode')
96 t.ok(discoveredFiles.length <= 2, `at most 2 files discovered (got ${discoveredFiles.length}: ${discoveredFiles.join(', ')})`)
97 // The entry file should be among the discovered files
98 t.ok(discoveredFiles.some(f => f === 'index.js'), 'entry file (index.js) discovered')
99})
100
101test('scan-stream: shallow mode is fast on a multi-module scan', async (t) => {
102 // Rough timing assertion — shallow scans of a multi-project root should
103 // complete in well under 10s. This is the whole reason shallow exists.
104 const start = Date.now()
105 let moduleCount = 0
106
107 await new Promise((resolveP) => {
108 const src = scanStream(HYPER_FLEEKY, { shallow: true, maxDepth: 1 })
109 src.on('module-start', () => moduleCount++)
110 src.once('scan-end', resolveP)
111 })
112
113 const duration = Date.now() - start
114 t.ok(moduleCount > 10, `found ${moduleCount} modules`)
115 t.ok(duration < 10000, `shallow scan completed in ${duration}ms (< 10s)`)
116})
117
118test('scan-stream: emits import-edge events for resolved local imports', async (t) => {
119 const edges = []
120
121 const target = resolve(HYPER_FLEEKY, 'hyper-orgs')
122 await new Promise((resolveP) => {
123 const src = scanStream(target)
124 src.on('import-edge', e => edges.push(e))
125 src.once('scan-end', resolveP)
126 })
127
128 t.ok(edges.length > 0, `at least one import edge (got ${edges.length})`)
129 for (const e of edges) {
130 t.ok(e.fromRelInPkg, 'edge has from')
131 t.ok(e.resolvedRelPath, 'edge has resolved path')
132 t.ok(e.specifier, 'edge has specifier')
133 }
134})
test/traverse.test.js +97 -0
……@@ -0,0 +1,97 @@
1import { test } from 'brittle'
2import { resolve, dirname } from 'path'
3import { fileURLToPath } from 'url'
4import { walkGraph } from '../lib/traverse.js'
5
6const HERE = dirname(fileURLToPath(import.meta.url))
7const HYPER_FLEEKY = resolve(HERE, '../../')
8
9test('traverse: hyper-orgs module', async (t) => {
10 const graph = await walkGraph(resolve(HYPER_FLEEKY, 'hyper-orgs'))
11
12 t.is(graph.modules.size, 1, '1 module found')
13 t.ok(graph.modules.has('hyper-orgs'), 'found hyper-orgs')
14
15 const mod = graph.modules.get('hyper-orgs')
16 t.is(mod.version, '0.2.0', 'correct version')
17 t.ok(mod.entry.endsWith('index.js'), 'entry is index.js')
18 t.ok(mod.dependencies['hyper-rooms'], 'depends on hyper-rooms')
19 t.is(mod.testCommand, 'brittle test/*.test.js', 'test command')
20 t.is(mod.type, 'module', 'ESM module')
21
22 // Files
23 t.ok(mod.files.has('index.js'), 'has index.js')
24 t.ok(mod.files.has('lib/hyper-orgs.js'), 'has lib/hyper-orgs.js')
25 t.ok(mod.files.has('lib/schema.js'), 'has lib/schema.js')
26
27 // File is parsed (source no longer retained — see TreeReducer.onFileDiscovered)
28 const indexFile = mod.files.get('index.js')
29 t.ok(indexFile.parsed, 'index.js has parsed result')
30 t.ok(indexFile.parsed.exports.length > 0, 'index.js has exports')
31})
32
33test('traverse: hyper-orgs file relationships', async (t) => {
34 const graph = await walkGraph(resolve(HYPER_FLEEKY, 'hyper-orgs'))
35 const mod = graph.modules.get('hyper-orgs')
36
37 // index.js imports from lib/
38 const indexFile = mod.files.get('index.js')
39 t.ok(indexFile.localImports.length > 0, 'index.js has local imports')
40
41 const importPaths = indexFile.localImports.map(i => i.specifier)
42 t.ok(importPaths.includes('./lib/hyper-orgs.js'), 'imports from lib/hyper-orgs.js')
43 t.ok(importPaths.includes('./lib/schema.js'), 'imports from lib/schema.js')
44
45 // lib/hyper-orgs.js imports from schema.js
46 const mainFile = mod.files.get('lib/hyper-orgs.js')
47 const mainImports = mainFile.localImports.map(i => i.specifier)
48 t.ok(mainImports.includes('./schema.js'), 'hyper-orgs.js imports schema.js')
49})
50
51test('traverse: hyper-deploy import maps', async (t) => {
52 const graph = await walkGraph(resolve(HYPER_FLEEKY, 'hyper-deploy'))
53
54 t.ok(graph.modules.size >= 1, 'found module(s)')
55
56 const mod = graph.modules.get('hyper-deploy')
57 if (!mod) {
58 // Might be named differently
59 const first = graph.modules.values().next().value
60 t.ok(first.importMaps, 'module has importMaps field')
61 return
62 }
63
64 t.ok(mod.importMaps, 'has import maps')
65 // hyper-deploy uses #fs, #path, #os import maps
66 const hasImportMap = Object.keys(mod.importMaps).length > 0
67 t.ok(hasImportMap, 'import maps are populated')
68})
69
70test('traverse: multi-module scan', async (t) => {
71 // Scan a directory containing multiple modules
72 const graph = await walkGraph(HYPER_FLEEKY, { maxDepth: 1 })
73
74 // Should find multiple modules
75 t.ok(graph.modules.size > 5, `found ${graph.modules.size} modules`)
76
77 // Check some known modules exist
78 const names = Array.from(graph.modules.keys())
79 t.comment(`found modules: ${names.slice(0, 10).join(', ')}...`)
80
81 // Each module should have files
82 for (const [name, mod] of graph.modules) {
83 t.ok(mod.files.size > 0, `${name} has ${mod.files.size} files`)
84 }
85})
86
87test('traverse: CJS module (hyper-sync)', async (t) => {
88 const graph = await walkGraph(resolve(HYPER_FLEEKY, 'hyper-sync'))
89
90 t.ok(graph.modules.size >= 1, 'found module')
91
92 const mod = graph.modules.get('hyper-sync')
93 if (mod) {
94 t.is(mod.type, 'commonjs', 'detected as commonjs (no type field)')
95 t.ok(mod.files.has('index.js'), 'has index.js')
96 }
97})
test/tree.test.js +126 -0
……@@ -0,0 +1,126 @@
1import { test } from 'brittle'
2import { resolve, dirname } from 'path'
3import { fileURLToPath } from 'url'
4import { scan } from '../lib/scanner.js'
5
6const HERE = dirname(fileURLToPath(import.meta.url))
7const HYPER_FLEEKY = resolve(HERE, '../../')
8
9test('tree: single module (hyper-orgs)', async (t) => {
10 const tree = await scan(resolve(HYPER_FLEEKY, 'hyper-orgs'))
11
12 t.ok(tree.generated, 'has timestamp')
13 t.ok(tree.root, 'has root path')
14
15 // System level
16 t.ok(tree.system.modules.includes('hyper-orgs'), 'module listed')
17 t.ok(tree.system.dependencies['hyper-orgs'], 'has dependencies')
18
19 // Module level
20 const mod = tree.modules['hyper-orgs']
21 t.ok(mod, 'module entry exists')
22 t.is(mod.name, 'hyper-orgs', 'correct name')
23 t.is(mod.version, '0.2.0', 'correct version')
24 t.is(mod.type, 'module', 'ESM')
25 t.is(mod.entry, 'index.js', 'entry point')
26 t.ok(mod.testCommand, 'has test command')
27
28 // Public API
29 t.ok(mod.publicAPI.includes('HyperOrgs'), 'public API has HyperOrgs')
30 t.ok(mod.publicAPI.includes('orgsSchema'), 'public API has orgsSchema')
31 t.ok(mod.publicAPI.includes('validateName'), 'public API has validateName')
32 t.ok(mod.publicAPI.includes('RESERVED_NAMES'), 'public API has RESERVED_NAMES')
33
34 // Files
35 t.ok(mod.files['index.js'], 'has index.js')
36 t.is(mod.files['index.js'].role, 'entry', 'index.js is entry')
37 t.ok(mod.files['lib/hyper-orgs.js'], 'has lib/hyper-orgs.js')
38 t.is(mod.files['lib/hyper-orgs.js'].role, 'lib', 'hyper-orgs.js is lib')
39 t.ok(mod.files['lib/schema.js'], 'has lib/schema.js')
40 t.is(mod.files['lib/schema.js'].role, 'schema', 'schema.js is schema')
41})
42
43test('tree: file-level detail (hyper-orgs/lib/hyper-orgs.js)', async (t) => {
44 const tree = await scan(resolve(HYPER_FLEEKY, 'hyper-orgs'))
45 const file = tree.modules['hyper-orgs'].files['lib/hyper-orgs.js']
46
47 // Imports
48 t.ok(file.imports.length > 0, 'has imports')
49 const roomImport = file.imports.find(i => i.specifier === 'hyper-rooms')
50 t.ok(roomImport, 'imports hyper-rooms')
51
52 // Exports
53 t.is(file.exports.length, 1, '1 export')
54 t.is(file.exports[0].name, 'HyperOrgs', 'exports HyperOrgs')
55 t.is(file.exports[0].type, 'class', 'type is class')
56
57 // Class structure
58 t.ok(file.classes, 'has classes')
59 t.is(file.classes.length, 1, '1 class')
60
61 const cls = file.classes[0]
62 t.is(cls.name, 'HyperOrgs', 'class name')
63 t.ok(cls.constructor, 'has constructor')
64 t.ok(cls.methods.length > 10, `has ${cls.methods.length} methods`)
65 t.ok(cls.getters.length > 3, `has ${cls.getters.length} getters`)
66
67 // State and delegation
68 t.ok(file.state, 'has state')
69 t.ok(file.state.includes('_room'), 'state includes _room')
70 t.ok(file.delegates, 'has delegates')
71 t.ok(file.delegates.length > 0, 'has delegation patterns')
72
73 // Error contracts
74 t.ok(file.errorContracts, 'has error contracts')
75 t.ok(file.errorContracts.length > 0, 'has specific errors')
76})
77
78test('tree: multi-module scan with shared deps', async (t) => {
79 const tree = await scan(HYPER_FLEEKY, { maxDepth: 1 })
80
81 // System level
82 t.ok(tree.system.modules.length > 10, `${tree.system.modules.length} modules`)
83
84 // Shared deps
85 t.ok(tree.system.sharedDeps, 'has shared deps')
86 const sharedNames = Object.keys(tree.system.sharedDeps)
87 t.ok(sharedNames.length > 0, `${sharedNames.length} shared deps`)
88 t.comment(`shared deps: ${sharedNames.slice(0, 5).join(', ')}...`)
89
90 // Verify some modules have parsed file data
91 const orgs = tree.modules['hyper-orgs']
92 if (orgs) {
93 t.ok(orgs.files['lib/hyper-orgs.js'].classes, 'hyper-orgs has parsed class data')
94 }
95
96 const issues = tree.modules['hyper-issues']
97 if (issues) {
98 t.ok(issues.publicAPI.length > 0, `hyper-issues has public API: ${issues.publicAPI.join(', ')}`)
99 }
100})
101
102test('tree: dependency graph is populated', async (t) => {
103 const tree = await scan(HYPER_FLEEKY, { maxDepth: 1 })
104
105 const depsEntries = Object.entries(tree.system.dependencies)
106 t.ok(depsEntries.length > 0, `${depsEntries.length} modules have deps`)
107
108 // hyper-orgs depends on hyper-rooms
109 const orgDeps = tree.system.dependencies['hyper-orgs']
110 if (orgDeps) {
111 t.ok(orgDeps.includes('hyper-rooms'), 'hyper-orgs -> hyper-rooms')
112 }
113})
114
115test('tree: file roles are correctly classified', async (t) => {
116 const tree = await scan(resolve(HYPER_FLEEKY, 'hyper-orgs'))
117 const files = tree.modules['hyper-orgs'].files
118
119 t.is(files['index.js'].role, 'entry', 'index.js = entry')
120 t.is(files['lib/hyper-orgs.js'].role, 'lib', 'lib/*.js = lib')
121 t.is(files['lib/schema.js'].role, 'schema', 'schema.js = schema')
122
123 // Check for test files if they exist
124 const testFiles = Object.entries(files).filter(([_, f]) => f.role === 'test')
125 t.comment(`test files: ${testFiles.length}`)
126})
test/validator.test.js +98 -0
……@@ -0,0 +1,98 @@
1import { test } from 'brittle'
2import { resolve, dirname } from 'path'
3import { fileURLToPath } from 'url'
4import { scan } from '../lib/scanner.js'
5import { parseSpecs } from '../lib/doc-parser.js'
6import { validate } from '../lib/validator.js'
7
8const HERE = dirname(fileURLToPath(import.meta.url))
9const HYPER_FLEEKY = resolve(HERE, '../../')
10const SPEC_DIR = resolve(HYPER_FLEEKY, 'pear-git-v3/spec')
11
12test('doc-parser: parse hyper-orgs module spec', (t) => {
13 const specs = parseSpecs(SPEC_DIR)
14
15 t.ok(specs.modules['hyper-orgs'], 'found hyper-orgs spec')
16
17 const spec = specs.modules['hyper-orgs']
18 t.is(spec.location, 'hyper-fleeky/hyper-orgs', 'location parsed')
19 t.is(spec.testCount, 29, 'test count parsed')
20 t.is(spec.sourceVerified, '2026-04-10', 'source verified date parsed')
21 t.ok(spec.fileLOC['hyper-orgs.js'], 'LOC claim for hyper-orgs.js')
22 t.is(spec.fileLOC['hyper-orgs.js'], 637, 'LOC = 637')
23 t.ok(spec.fileLOC['schema.js'], 'LOC claim for schema.js')
24
25 t.ok(spec.description, 'has description')
26 t.ok(spec.dependencies.includes('hyper-rooms'), 'dependency on hyper-rooms')
27 t.ok(spec.dependents.includes('pear-git-v3'), 'dependent pear-git-v3')
28
29 t.ok(spec.claimedExports.includes('HyperOrgs'), 'claims HyperOrgs export')
30 t.ok(spec.claimedMethods.length > 10, spec.claimedMethods.length + ' claimed methods')
31 t.ok(spec.claimedMethods.includes('create'), 'claims create method')
32 t.ok(spec.claimedMethods.includes('checkAccess'), 'claims checkAccess method')
33})
34
35test('doc-parser: parse SYSTEM.md', (t) => {
36 const specs = parseSpecs(SPEC_DIR)
37
38 t.ok(specs.system, 'system spec parsed')
39 t.is(specs.system.lastVerified, '2026-04-12', 'last verified date')
40 t.ok(specs.system.modules.length > 5, specs.system.modules.length + ' modules documented')
41
42 const orgsEntry = specs.system.modules.find(m => m.name === 'hyper-orgs')
43 t.ok(orgsEntry, 'hyper-orgs in system module list')
44 t.ok(orgsEntry.location.includes('hyper-orgs'), 'location includes hyper-orgs')
45 t.ok(orgsEntry.purpose, 'has purpose')
46
47 t.ok(specs.system.builtItems.length > 0, 'has built items')
48 t.ok(specs.system.missingItems.length > 0, 'has missing items')
49})
50
51test('validator: hyper-orgs spec vs code', async (t) => {
52 const tree = await scan(HYPER_FLEEKY, { maxDepth: 1 })
53 const specs = parseSpecs(SPEC_DIR)
54 const report = validate(tree, specs)
55
56 t.ok(report.modules['hyper-orgs'], 'has hyper-orgs validation')
57
58 const modReport = report.modules['hyper-orgs']
59 t.ok(modReport.checks.length > 0, modReport.checks.length + ' checks performed')
60
61 // Print the report for inspection
62 for (const check of modReport.checks) {
63 const icon = check.status === 'pass' ? 'PASS' : check.status === 'fail' ? 'FAIL' : 'WARN'
64 t.comment(icon + ': ' + check.claim + (check.detail ? ' — ' + check.detail : ''))
65 }
66
67 // Should have some passes (the module exists, deps are correct)
68 const passes = modReport.checks.filter(c => c.status === 'pass')
69 t.ok(passes.length > 0, passes.length + ' checks passed')
70})
71
72test('validator: system spec vs code', async (t) => {
73 const tree = await scan(HYPER_FLEEKY, { maxDepth: 1 })
74 const specs = parseSpecs(SPEC_DIR)
75 const report = validate(tree, specs)
76
77 t.ok(report.system, 'has system validation')
78 t.ok(report.system.checks.length > 0, report.system.checks.length + ' system checks')
79
80 for (const check of report.system.checks) {
81 const icon = check.status === 'pass' ? 'PASS' : check.status === 'fail' ? 'FAIL' : 'WARN'
82 t.comment(icon + ': ' + check.claim + (check.detail ? ' — ' + check.detail : ''))
83 }
84})
85
86test('validator: summary counts', async (t) => {
87 const tree = await scan(HYPER_FLEEKY, { maxDepth: 1 })
88 const specs = parseSpecs(SPEC_DIR)
89 const report = validate(tree, specs)
90
91 t.comment('Total: ' + report.summary.total + ' checks')
92 t.comment('Pass: ' + report.summary.pass)
93 t.comment('Fail: ' + report.summary.fail)
94 t.comment('Warn: ' + report.summary.warn)
95
96 t.ok(report.summary.total > 0, 'has checks')
97 t.ok(report.summary.pass > 0, 'some passed')
98})
vendor/acorn/CHANGELOG.md +954 -0
……@@ -0,0 +1,954 @@
1## 8.15.0 (2025-06-08)
2
3### New features
4
5Support `using` and `await using` syntax.
6
7The `AnyNode` type is now defined in such a way that plugins can extend it.
8
9### Bug fixes
10
11Fix an issue where the `bigint` property of literal nodes for non-decimal bigints had the wrong format.
12
13The `acorn` CLI tool no longer crashes when emitting a tree that contains a bigint.
14
15## 8.14.1 (2025-03-05)
16
17### Bug fixes
18
19Fix an issue where `await` expressions in class field initializers were inappropriately allowed.
20
21Properly allow await inside an async arrow function inside a class field initializer.
22
23Mention the source file name in syntax error messages when given.
24
25Properly add an empty `attributes` property to every form of `ExportNamedDeclaration`.
26
27## 8.14.0 (2024-10-27)
28
29### New features
30
31Support ES2025 import attributes.
32
33Support ES2025 RegExp modifiers.
34
35### Bug fixes
36
37Support some missing Unicode properties.
38
39## 8.13.0 (2024-10-16)
40
41### New features
42
43Upgrade to Unicode 16.0.
44
45## 8.12.1 (2024-07-03)
46
47### Bug fixes
48
49Fix a regression that caused Acorn to no longer run on Node versions <8.10.
50
51## 8.12.0 (2024-06-14)
52
53### New features
54
55Support ES2025 duplicate capture group names in regular expressions.
56
57### Bug fixes
58
59Include `VariableDeclarator` in the `AnyNode` type so that walker objects can refer to it without getting a type error.
60
61Properly raise a parse error for invalid `for`/`of` statements using `async` as binding name.
62
63Properly recognize \"use strict\" when preceded by a string with an escaped newline.
64
65Mark the `Parser` constructor as protected, not private, so plugins can extend it without type errors.
66
67Fix a bug where some invalid `delete` expressions were let through when the operand was parenthesized and `preserveParens` was enabled.
68
69Properly normalize line endings in raw strings of invalid template tokens.
70
71Properly track line numbers for escaped newlines in strings.
72
73Fix a bug that broke line number accounting after a template literal with invalid escape sequences.
74
75## 8.11.3 (2023-12-29)
76
77### Bug fixes
78
79Add `Function` and `Class` to the `AggregateType` type, so that they can be used in walkers without raising a type error.
80
81Make sure `onToken` get an `import` keyword token when parsing `import.meta`.
82
83Fix a bug where `.loc.start` could be undefined for `new.target` `meta` nodes.
84
85## 8.11.2 (2023-10-27)
86
87### Bug fixes
88
89Fix a bug that caused regular expressions after colon tokens to not be properly tokenized in some circumstances.
90
91## 8.11.1 (2023-10-26)
92
93### Bug fixes
94
95Fix a regression where `onToken` would receive 'name' tokens for 'new' keyword tokens.
96
97## 8.11.0 (2023-10-26)
98
99### Bug fixes
100
101Fix an issue where tokenizing (without parsing) an object literal with a property named `class` or `function` could, in some circumstance, put the tokenizer into an invalid state.
102
103Fix an issue where a slash after a call to a propery named the same as some keywords would be tokenized as a regular expression.
104
105### New features
106
107Upgrade to Unicode 15.1.
108
109Use a set of new, much more precise, TypeScript types.
110
111## 8.10.0 (2023-07-05)
112
113### New features
114
115Add a `checkPrivateFields` option that disables strict checking of private property use.
116
117## 8.9.0 (2023-06-16)
118
119### Bug fixes
120
121Forbid dynamic import after `new`, even when part of a member expression.
122
123### New features
124
125Add Unicode properties for ES2023.
126
127Add support for the `v` flag to regular expressions.
128
129## 8.8.2 (2023-01-23)
130
131### Bug fixes
132
133Fix a bug that caused `allowHashBang` to be set to false when not provided, even with `ecmaVersion >= 14`.
134
135Fix an exception when passing no option object to `parse` or `new Parser`.
136
137Fix incorrect parse error on `if (0) let\n[astral identifier char]`.
138
139## 8.8.1 (2022-10-24)
140
141### Bug fixes
142
143Make type for `Comment` compatible with estree types.
144
145## 8.8.0 (2022-07-21)
146
147### Bug fixes
148
149Allow parentheses around spread args in destructuring object assignment.
150
151Fix an issue where the tree contained `directive` properties in when parsing with a language version that doesn't support them.
152
153### New features
154
155Support hashbang comments by default in ECMAScript 2023 and later.
156
157## 8.7.1 (2021-04-26)
158
159### Bug fixes
160
161Stop handling `"use strict"` directives in ECMAScript versions before 5.
162
163Fix an issue where duplicate quoted export names in `export *` syntax were incorrectly checked.
164
165Add missing type for `tokTypes`.
166
167## 8.7.0 (2021-12-27)
168
169### New features
170
171Support quoted export names.
172
173Upgrade to Unicode 14.
174
175Add support for Unicode 13 properties in regular expressions.
176
177### Bug fixes
178
179Use a loop to find line breaks, because the existing regexp search would overrun the end of the searched range and waste a lot of time in minified code.
180
181## 8.6.0 (2021-11-18)
182
183### Bug fixes
184
185Fix a bug where an object literal with multiple `__proto__` properties would incorrectly be accepted if a later property value held an assigment.
186
187### New features
188
189Support class private fields with the `in` operator.
190
191## 8.5.0 (2021-09-06)
192
193### Bug fixes
194
195Improve context-dependent tokenization in a number of corner cases.
196
197Fix location tracking after a 0x2028 or 0x2029 character in a string literal (which before did not increase the line number).
198
199Fix an issue where arrow function bodies in for loop context would inappropriately consume `in` operators.
200
201Fix wrong end locations stored on SequenceExpression nodes.
202
203Implement restriction that `for`/`of` loop LHS can't start with `let`.
204
205### New features
206
207Add support for ES2022 class static blocks.
208
209Allow multiple input files to be passed to the CLI tool.
210
211## 8.4.1 (2021-06-24)
212
213### Bug fixes
214
215Fix a bug where `allowAwaitOutsideFunction` would allow `await` in class field initializers, and setting `ecmaVersion` to 13 or higher would allow top-level await in non-module sources.
216
217## 8.4.0 (2021-06-11)
218
219### New features
220
221A new option, `allowSuperOutsideMethod`, can be used to suppress the error when `super` is used in the wrong context.
222
223## 8.3.0 (2021-05-31)
224
225### New features
226
227Default `allowAwaitOutsideFunction` to true for ECMAScript 2022 an higher.
228
229Add support for the `d` ([indices](https://github.com/tc39/proposal-regexp-match-indices)) regexp flag.
230
231## 8.2.4 (2021-05-04)
232
233### Bug fixes
234
235Fix spec conformity in corner case 'for await (async of ...)'.
236
237## 8.2.3 (2021-05-04)
238
239### Bug fixes
240
241Fix an issue where the library couldn't parse 'for (async of ...)'.
242
243Fix a bug in UTF-16 decoding that would read characters incorrectly in some circumstances.
244
245## 8.2.2 (2021-04-29)
246
247### Bug fixes
248
249Fix a bug where a class field initialized to an async arrow function wouldn't allow await inside it. Same issue existed for generator arrow functions with yield.
250
251## 8.2.1 (2021-04-24)
252
253### Bug fixes
254
255Fix a regression introduced in 8.2.0 where static or async class methods with keyword names fail to parse.
256
257## 8.2.0 (2021-04-24)
258
259### New features
260
261Add support for ES2022 class fields and private methods.
262
263## 8.1.1 (2021-04-12)
264
265### Various
266
267Stop shipping source maps in the NPM package.
268
269## 8.1.0 (2021-03-09)
270
271### Bug fixes
272
273Fix a spurious error in nested destructuring arrays.
274
275### New features
276
277Expose `allowAwaitOutsideFunction` in CLI interface.
278
279Make `allowImportExportAnywhere` also apply to `import.meta`.
280
281## 8.0.5 (2021-01-25)
282
283### Bug fixes
284
285Adjust package.json to work with Node 12.16.0 and 13.0-13.6.
286
287## 8.0.4 (2020-10-05)
288
289### Bug fixes
290
291Make `await x ** y` an error, following the spec.
292
293Fix potentially exponential regular expression.
294
295## 8.0.3 (2020-10-02)
296
297### Bug fixes
298
299Fix a wasteful loop during `Parser` creation when setting `ecmaVersion` to `"latest"`.
300
301## 8.0.2 (2020-09-30)
302
303### Bug fixes
304
305Make the TypeScript types reflect the current allowed values for `ecmaVersion`.
306
307Fix another regexp/division tokenizer issue.
308
309## 8.0.1 (2020-08-12)
310
311### Bug fixes
312
313Provide the correct value in the `version` export.
314
315## 8.0.0 (2020-08-12)
316
317### Bug fixes
318
319Disallow expressions like `(a = b) = c`.
320
321Make non-octal escape sequences a syntax error in strict mode.
322
323### New features
324
325The package can now be loaded directly as an ECMAScript module in node 13+.
326
327Update to the set of Unicode properties from ES2021.
328
329### Breaking changes
330
331The `ecmaVersion` option is now required. For the moment, omitting it will still work with a warning, but that will change in a future release.
332
333Some changes to method signatures that may be used by plugins.
334
335## 7.4.0 (2020-08-03)
336
337### New features
338
339Add support for logical assignment operators.
340
341Add support for numeric separators.
342
343## 7.3.1 (2020-06-11)
344
345### Bug fixes
346
347Make the string in the `version` export match the actual library version.
348
349## 7.3.0 (2020-06-11)
350
351### Bug fixes
352
353Fix a bug that caused parsing of object patterns with a property named `set` that had a default value to fail.
354
355### New features
356
357Add support for optional chaining (`?.`).
358
359## 7.2.0 (2020-05-09)
360
361### Bug fixes
362
363Fix precedence issue in parsing of async arrow functions.
364
365### New features
366
367Add support for nullish coalescing.
368
369Add support for `import.meta`.
370
371Support `export * as ...` syntax.
372
373Upgrade to Unicode 13.
374
375## 6.4.1 (2020-03-09)
376
377### Bug fixes
378
379More carefully check for valid UTF16 surrogate pairs in regexp validator.
380
381## 7.1.1 (2020-03-01)
382
383### Bug fixes
384
385Treat `\8` and `\9` as invalid escapes in template strings.
386
387Allow unicode escapes in property names that are keywords.
388
389Don't error on an exponential operator expression as argument to `await`.
390
391More carefully check for valid UTF16 surrogate pairs in regexp validator.
392
393## 7.1.0 (2019-09-24)
394
395### Bug fixes
396
397Disallow trailing object literal commas when ecmaVersion is less than 5.
398
399### New features
400
401Add a static `acorn` property to the `Parser` class that contains the entire module interface, to allow plugins to access the instance of the library that they are acting on.
402
403## 7.0.0 (2019-08-13)
404
405### Breaking changes
406
407Changes the node format for dynamic imports to use the `ImportExpression` node type, as defined in [ESTree](https://github.com/estree/estree/blob/master/es2020.md#importexpression).
408
409Makes 10 (ES2019) the default value for the `ecmaVersion` option.
410
411## 6.3.0 (2019-08-12)
412
413### New features
414
415`sourceType: "module"` can now be used even when `ecmaVersion` is less than 6, to parse module-style code that otherwise conforms to an older standard.
416
417## 6.2.1 (2019-07-21)
418
419### Bug fixes
420
421Fix bug causing Acorn to treat some characters as identifier characters that shouldn't be treated as such.
422
423Fix issue where setting the `allowReserved` option to `"never"` allowed reserved words in some circumstances.
424
425## 6.2.0 (2019-07-04)
426
427### Bug fixes
428
429Improve valid assignment checking in `for`/`in` and `for`/`of` loops.
430
431Disallow binding `let` in patterns.
432
433### New features
434
435Support bigint syntax with `ecmaVersion` >= 11.
436
437Support dynamic `import` syntax with `ecmaVersion` >= 11.
438
439Upgrade to Unicode version 12.
440
441## 6.1.1 (2019-02-27)
442
443### Bug fixes
444
445Fix bug that caused parsing default exports of with names to fail.
446
447## 6.1.0 (2019-02-08)
448
449### Bug fixes
450
451Fix scope checking when redefining a `var` as a lexical binding.
452
453### New features
454
455Split up `parseSubscripts` to use an internal `parseSubscript` method to make it easier to extend with plugins.
456
457## 6.0.7 (2019-02-04)
458
459### Bug fixes
460
461Check that exported bindings are defined.
462
463Don't treat `\u180e` as a whitespace character.
464
465Check for duplicate parameter names in methods.
466
467Don't allow shorthand properties when they are generators or async methods.
468
469Forbid binding `await` in async arrow function's parameter list.
470
471## 6.0.6 (2019-01-30)
472
473### Bug fixes
474
475The content of class declarations and expressions is now always parsed in strict mode.
476
477Don't allow `let` or `const` to bind the variable name `let`.
478
479Treat class declarations as lexical.
480
481Don't allow a generator function declaration as the sole body of an `if` or `else`.
482
483Ignore `"use strict"` when after an empty statement.
484
485Allow string line continuations with special line terminator characters.
486
487Treat `for` bodies as part of the `for` scope when checking for conflicting bindings.
488
489Fix bug with parsing `yield` in a `for` loop initializer.
490
491Implement special cases around scope checking for functions.
492
493## 6.0.5 (2019-01-02)
494
495### Bug fixes
496
497Fix TypeScript type for `Parser.extend` and add `allowAwaitOutsideFunction` to options type.
498
499Don't treat `let` as a keyword when the next token is `{` on the next line.
500
501Fix bug that broke checking for parentheses around an object pattern in a destructuring assignment when `preserveParens` was on.
502
503## 6.0.4 (2018-11-05)
504
505### Bug fixes
506
507Further improvements to tokenizing regular expressions in corner cases.
508
509## 6.0.3 (2018-11-04)
510
511### Bug fixes
512
513Fix bug in tokenizing an expression-less return followed by a function followed by a regular expression.
514
515Remove stray symlink in the package tarball.
516
517## 6.0.2 (2018-09-26)
518
519### Bug fixes
520
521Fix bug where default expressions could fail to parse inside an object destructuring assignment expression.
522
523## 6.0.1 (2018-09-14)
524
525### Bug fixes
526
527Fix wrong value in `version` export.
528
529## 6.0.0 (2018-09-14)
530
531### Bug fixes
532
533Better handle variable-redefinition checks for catch bindings and functions directly under if statements.
534
535Forbid `new.target` in top-level arrow functions.
536
537Fix issue with parsing a regexp after `yield` in some contexts.
538
539### New features
540
541The package now comes with TypeScript definitions.
542
543### Breaking changes
544
545The default value of the `ecmaVersion` option is now 9 (2018).
546
547Plugins work differently, and will have to be rewritten to work with this version.
548
549The loose parser and walker have been moved into separate packages (`acorn-loose` and `acorn-walk`).
550
551## 5.7.3 (2018-09-10)
552
553### Bug fixes
554
555Fix failure to tokenize regexps after expressions like `x.of`.
556
557Better error message for unterminated template literals.
558
559## 5.7.2 (2018-08-24)
560
561### Bug fixes
562
563Properly handle `allowAwaitOutsideFunction` in for statements.
564
565Treat function declarations at the top level of modules like let bindings.
566
567Don't allow async function declarations as the only statement under a label.
568
569## 5.7.0 (2018-06-15)
570
571### New features
572
573Upgraded to Unicode 11.
574
575## 5.6.0 (2018-05-31)
576
577### New features
578
579Allow U+2028 and U+2029 in string when ECMAVersion >= 10.
580
581Allow binding-less catch statements when ECMAVersion >= 10.
582
583Add `allowAwaitOutsideFunction` option for parsing top-level `await`.
584
585## 5.5.3 (2018-03-08)
586
587### Bug fixes
588
589A _second_ republish of the code in 5.5.1, this time with yarn, to hopefully get valid timestamps.
590
591## 5.5.2 (2018-03-08)
592
593### Bug fixes
594
595A republish of the code in 5.5.1 in an attempt to solve an issue with the file timestamps in the npm package being 0.
596
597## 5.5.1 (2018-03-06)
598
599### Bug fixes
600
601Fix misleading error message for octal escapes in template strings.
602
603## 5.5.0 (2018-02-27)
604
605### New features
606
607The identifier character categorization is now based on Unicode version 10.
608
609Acorn will now validate the content of regular expressions, including new ES9 features.
610
611## 5.4.0 (2018-02-01)
612
613### Bug fixes
614
615Disallow duplicate or escaped flags on regular expressions.
616
617Disallow octal escapes in strings in strict mode.
618
619### New features
620
621Add support for async iteration.
622
623Add support for object spread and rest.
624
625## 5.3.0 (2017-12-28)
626
627### Bug fixes
628
629Fix parsing of floating point literals with leading zeroes in loose mode.
630
631Allow duplicate property names in object patterns.
632
633Don't allow static class methods named `prototype`.
634
635Disallow async functions directly under `if` or `else`.
636
637Parse right-hand-side of `for`/`of` as an assignment expression.
638
639Stricter parsing of `for`/`in`.
640
641Don't allow unicode escapes in contextual keywords.
642
643### New features
644
645Parsing class members was factored into smaller methods to allow plugins to hook into it.
646
647## 5.2.1 (2017-10-30)
648
649### Bug fixes
650
651Fix a token context corruption bug.
652
653## 5.2.0 (2017-10-30)
654
655### Bug fixes
656
657Fix token context tracking for `class` and `function` in property-name position.
658
659Make sure `%*` isn't parsed as a valid operator.
660
661Allow shorthand properties `get` and `set` to be followed by default values.
662
663Disallow `super` when not in callee or object position.
664
665### New features
666
667Support [`directive` property](https://github.com/estree/estree/compare/b3de58c9997504d6fba04b72f76e6dd1619ee4eb...1da8e603237144f44710360f8feb7a9977e905e0) on directive expression statements.
668
669## 5.1.2 (2017-09-04)
670
671### Bug fixes
672
673Disable parsing of legacy HTML-style comments in modules.
674
675Fix parsing of async methods whose names are keywords.
676
677## 5.1.1 (2017-07-06)
678
679### Bug fixes
680
681Fix problem with disambiguating regexp and division after a class.
682
683## 5.1.0 (2017-07-05)
684
685### Bug fixes
686
687Fix tokenizing of regexps in an object-desctructuring `for`/`of` loop and after `yield`.
688
689Parse zero-prefixed numbers with non-octal digits as decimal.
690
691Allow object/array patterns in rest parameters.
692
693Don't error when `yield` is used as a property name.
694
695Allow `async` as a shorthand object property.
696
697### New features
698
699Implement the [template literal revision proposal](https://github.com/tc39/proposal-template-literal-revision) for ES9.
700
701## 5.0.3 (2017-04-01)
702
703### Bug fixes
704
705Fix spurious duplicate variable definition errors for named functions.
706
707## 5.0.2 (2017-03-30)
708
709### Bug fixes
710
711A binary operator after a parenthesized arrow expression is no longer incorrectly treated as an error.
712
713## 5.0.0 (2017-03-28)
714
715### Bug fixes
716
717Raise an error for duplicated lexical bindings.
718
719Fix spurious error when an assignement expression occurred after a spread expression.
720
721Accept regular expressions after `of` (in `for`/`of`), `yield` (in a generator), and braced arrow functions.
722
723Allow labels in front or `var` declarations, even in strict mode.
724
725### Breaking changes
726
727Parse declarations following `export default` as declaration nodes, not expressions. This means that class and function declarations nodes can now have `null` as their `id`.
728
729## 4.0.11 (2017-02-07)
730
731### Bug fixes
732
733Allow all forms of member expressions to be parenthesized as lvalue.
734
735## 4.0.10 (2017-02-07)
736
737### Bug fixes
738
739Don't expect semicolons after default-exported functions or classes, even when they are expressions.
740
741Check for use of `'use strict'` directives in non-simple parameter functions, even when already in strict mode.
742
743## 4.0.9 (2017-02-06)
744
745### Bug fixes
746
747Fix incorrect error raised for parenthesized simple assignment targets, so that `(x) = 1` parses again.
748
749## 4.0.8 (2017-02-03)
750
751### Bug fixes
752
753Solve spurious parenthesized pattern errors by temporarily erring on the side of accepting programs that our delayed errors don't handle correctly yet.
754
755## 4.0.7 (2017-02-02)
756
757### Bug fixes
758
759Accept invalidly rejected code like `(x).y = 2` again.
760
761Don't raise an error when a function _inside_ strict code has a non-simple parameter list.
762
763## 4.0.6 (2017-02-02)
764
765### Bug fixes
766
767Fix exponential behavior (manifesting itself as a complete hang for even relatively small source files) introduced by the new 'use strict' check.
768
769## 4.0.5 (2017-02-02)
770
771### Bug fixes
772
773Disallow parenthesized pattern expressions.
774
775Allow keywords as export names.
776
777Don't allow the `async` keyword to be parenthesized.
778
779Properly raise an error when a keyword contains a character escape.
780
781Allow `"use strict"` to appear after other string literal expressions.
782
783Disallow labeled declarations.
784
785## 4.0.4 (2016-12-19)
786
787### Bug fixes
788
789Fix crash when `export` was followed by a keyword that can't be
790exported.
791
792## 4.0.3 (2016-08-16)
793
794### Bug fixes
795
796Allow regular function declarations inside single-statement `if` branches in loose mode. Forbid them entirely in strict mode.
797
798Properly parse properties named `async` in ES2017 mode.
799
800Fix bug where reserved words were broken in ES2017 mode.
801
802## 4.0.2 (2016-08-11)
803
804### Bug fixes
805
806Don't ignore period or 'e' characters after octal numbers.
807
808Fix broken parsing for call expressions in default parameter values of arrow functions.
809
810## 4.0.1 (2016-08-08)
811
812### Bug fixes
813
814Fix false positives in duplicated export name errors.
815
816## 4.0.0 (2016-08-07)
817
818### Breaking changes
819
820The default `ecmaVersion` option value is now 7.
821
822A number of internal method signatures changed, so plugins might need to be updated.
823
824### Bug fixes
825
826The parser now raises errors on duplicated export names.
827
828`arguments` and `eval` can now be used in shorthand properties.
829
830Duplicate parameter names in non-simple argument lists now always produce an error.
831
832### New features
833
834The `ecmaVersion` option now also accepts year-style version numbers
835(2015, etc).
836
837Support for `async`/`await` syntax when `ecmaVersion` is >= 8.
838
839Support for trailing commas in call expressions when `ecmaVersion` is >= 8.
840
841## 3.3.0 (2016-07-25)
842
843### Bug fixes
844
845Fix bug in tokenizing of regexp operator after a function declaration.
846
847Fix parser crash when parsing an array pattern with a hole.
848
849### New features
850
851Implement check against complex argument lists in functions that enable strict mode in ES7.
852
853## 3.2.0 (2016-06-07)
854
855### Bug fixes
856
857Improve handling of lack of unicode regexp support in host
858environment.
859
860Properly reject shorthand properties whose name is a keyword.
861
862### New features
863
864Visitors created with `visit.make` now have their base as _prototype_, rather than copying properties into a fresh object.
865
866## 3.1.0 (2016-04-18)
867
868### Bug fixes
869
870Properly tokenize the division operator directly after a function expression.
871
872Allow trailing comma in destructuring arrays.
873
874## 3.0.4 (2016-02-25)
875
876### Fixes
877
878Allow update expressions as left-hand-side of the ES7 exponential operator.
879
880## 3.0.2 (2016-02-10)
881
882### Fixes
883
884Fix bug that accidentally made `undefined` a reserved word when parsing ES7.
885
886## 3.0.0 (2016-02-10)
887
888### Breaking changes
889
890The default value of the `ecmaVersion` option is now 6 (used to be 5).
891
892Support for comprehension syntax (which was dropped from the draft spec) has been removed.
893
894### Fixes
895
896`let` and `yield` are now “contextual keywords”, meaning you can mostly use them as identifiers in ES5 non-strict code.
897
898A parenthesized class or function expression after `export default` is now parsed correctly.
899
900### New features
901
902When `ecmaVersion` is set to 7, Acorn will parse the exponentiation operator (`**`).
903
904The identifier character ranges are now based on Unicode 8.0.0.
905
906Plugins can now override the `raiseRecoverable` method to override the way non-critical errors are handled.
907
908## 2.7.0 (2016-01-04)
909
910### Fixes
911
912Stop allowing rest parameters in setters.
913
914Disallow `y` rexexp flag in ES5.
915
916Disallow `\00` and `\000` escapes in strict mode.
917
918Raise an error when an import name is a reserved word.
919
920## 2.6.2 (2015-11-10)
921
922### Fixes
923
924Don't crash when no options object is passed.
925
926## 2.6.0 (2015-11-09)
927
928### Fixes
929
930Add `await` as a reserved word in module sources.
931
932Disallow `yield` in a parameter default value for a generator.
933
934Forbid using a comma after a rest pattern in an array destructuring.
935
936### New features
937
938Support parsing stdin in command-line tool.
939
940## 2.5.0 (2015-10-27)
941
942### Fixes
943
944Fix tokenizer support in the command-line tool.
945
946Stop allowing `new.target` outside of functions.
947
948Remove legacy `guard` and `guardedHandler` properties from try nodes.
949
950Stop allowing multiple `__proto__` properties on an object literal in strict mode.
951
952Don't allow rest parameters to be non-identifier patterns.
953
954Check for duplicate paramter names in arrow functions.
vendor/acorn/LICENSE +21 -0
……@@ -0,0 +1,21 @@
1MIT License
2
3Copyright (C) 2012-2022 by various contributors (see AUTHORS)
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
vendor/acorn/README.md +282 -0
……@@ -0,0 +1,282 @@
1# Acorn
2
3A tiny, fast JavaScript parser written in JavaScript.
4
5## Community
6
7Acorn is open source software released under an
8[MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).
9
10You are welcome to
11[report bugs](https://github.com/acornjs/acorn/issues) or create pull
12requests on [github](https://github.com/acornjs/acorn).
13
14## Installation
15
16The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
17
18```sh
19npm install acorn
20```
21
22Alternately, you can download the source and build acorn yourself:
23
24```sh
25git clone https://github.com/acornjs/acorn.git
26cd acorn
27npm install
28```
29
30## Interface
31
32**parse**`(input, options)` is the main interface to the library. The
33`input` parameter is a string, `options` must be an object setting
34some of the options listed below. The return value will be an abstract
35syntax tree object as specified by the [ESTree
36spec](https://github.com/estree/estree).
37
38```javascript
39let acorn = require("acorn");
40console.log(acorn.parse("1 + 1", {ecmaVersion: 2020}));
41```
42
43When encountering a syntax error, the parser will raise a
44`SyntaxError` object with a meaningful message. The error object will
45have a `pos` property that indicates the string offset at which the
46error occurred, and a `loc` object that contains a `{line, column}`
47object referring to that same position.
48
49Options are provided by in a second argument, which should be an
50object containing any of these fields (only `ecmaVersion` is
51required):
52
53- **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a
54 number, either in year (`2022`) or plain version number (`6`) form,
55 or `"latest"` (the latest the library supports). This influences
56 support for strict mode, the set of reserved words, and support for
57 new syntax features.
58
59 **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
60 implemented by Acorn. Other proposed new features must be
61 implemented through plugins.
62
63- **sourceType**: Indicate the mode the code should be parsed in. Can be
64 either `"script"` or `"module"`. This influences global strict mode
65 and parsing of `import` and `export` declarations.
66
67 **NOTE**: If set to `"module"`, then static `import` / `export` syntax
68 will be valid, even if `ecmaVersion` is less than 6.
69
70- **onInsertedSemicolon**: If given a callback, that callback will be
71 called whenever a missing semicolon is inserted by the parser. The
72 callback will be given the character offset of the point where the
73 semicolon is inserted as argument, and if `locations` is on, also a
74 `{line, column}` object representing this position.
75
76- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
77 commas.
78
79- **allowReserved**: If `false`, using a reserved word will generate
80 an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
81 versions. When given the value `"never"`, reserved words and
82 keywords can also not be used as property names (as in Internet
83 Explorer's old parser).
84
85- **allowReturnOutsideFunction**: By default, a return statement at
86 the top level raises an error. Set this to `true` to accept such
87 code.
88
89- **allowImportExportEverywhere**: By default, `import` and `export`
90 declarations can only appear at a program's top level. Setting this
91 option to `true` allows them anywhere where a statement is allowed,
92 and also allows `import.meta` expressions to appear in scripts
93 (when `sourceType` is not `"module"`).
94
95- **allowAwaitOutsideFunction**: If `false`, `await` expressions can
96 only appear inside `async` functions. Defaults to `true` in modules
97 for `ecmaVersion` 2022 and later, `false` for lower versions.
98 Setting this option to `true` allows to have top-level `await`
99 expressions. They are still not allowed in non-`async` functions,
100 though.
101
102- **allowSuperOutsideMethod**: By default, `super` outside a method
103 raises an error. Set this to `true` to accept such code.
104
105- **allowHashBang**: When this is enabled, if the code starts with the
106 characters `#!` (as in a shellscript), the first line will be
107 treated as a comment. Defaults to true when `ecmaVersion` >= 2023.
108
109- **checkPrivateFields**: By default, the parser will verify that
110 private properties are only used in places where they are valid and
111 have been declared. Set this to false to turn such checks off.
112
113- **locations**: When `true`, each node has a `loc` object attached
114 with `start` and `end` subobjects, each of which contains the
115 one-based line and zero-based column numbers in `{line, column}`
116 form. Default is `false`.
117
118- **onToken**: If a function is passed for this option, each found
119 token will be passed in same format as tokens returned from
120 `tokenizer().getToken()`.
121
122 If array is passed, each found token is pushed to it.
123
124 Note that you are not allowed to call the parser from the
125 callback—that will corrupt its internal state.
126
127- **onComment**: If a function is passed for this option, whenever a
128 comment is encountered the function will be called with the
129 following parameters:
130
131 - `block`: `true` if the comment is a block comment, false if it
132 is a line comment.
133 - `text`: The content of the comment.
134 - `start`: Character offset of the start of the comment.
135 - `end`: Character offset of the end of the comment.
136
137 When the `locations` options is on, the `{line, column}` locations
138 of the comment’s start and end are passed as two additional
139 parameters.
140
141 If array is passed for this option, each found comment is pushed
142 to it as object in Esprima format:
143
144 ```javascript
145 {
146 "type": "Line" | "Block",
147 "value": "comment text",
148 "start": Number,
149 "end": Number,
150 // If `locations` option is on:
151 "loc": {
152 "start": {line: Number, column: Number}
153 "end": {line: Number, column: Number}
154 },
155 // If `ranges` option is on:
156 "range": [Number, Number]
157 }
158 ```
159
160 Note that you are not allowed to call the parser from the
161 callback—that will corrupt its internal state.
162
163- **ranges**: Nodes have their start and end characters offsets
164 recorded in `start` and `end` properties (directly on the node,
165 rather than the `loc` object, which holds line/column data. To also
166 add a
167 [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
168 `range` property holding a `[start, end]` array with the same
169 numbers, set the `ranges` option to `true`.
170
171- **program**: It is possible to parse multiple files into a single
172 AST by passing the tree produced by parsing the first file as the
173 `program` option in subsequent parses. This will add the toplevel
174 forms of the parsed file to the "Program" (top) node of an existing
175 parse tree.
176
177- **sourceFile**: When the `locations` option is `true`, you can pass
178 this option to add a `source` attribute in every node’s `loc`
179 object. Note that the contents of this option are not examined or
180 processed in any way; you are free to use whatever format you
181 choose.
182
183- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
184 will be added (regardless of the `location` option) directly to the
185 nodes, rather than the `loc` object.
186
187- **preserveParens**: If this option is `true`, parenthesized expressions
188 are represented by (non-standard) `ParenthesizedExpression` nodes
189 that have a single `expression` property containing the expression
190 inside parentheses.
191
192**parseExpressionAt**`(input, offset, options)` will parse a single
193expression in a string, and return its AST. It will not complain if
194there is more of the string left after the expression.
195
196**tokenizer**`(input, options)` returns an object with a `getToken`
197method that can be called repeatedly to get the next token, a `{start,
198end, type, value}` object (with added `loc` property when the
199`locations` option is enabled and `range` property when the `ranges`
200option is enabled). When the token's type is `tokTypes.eof`, you
201should stop calling the method, since it will keep returning that same
202token forever.
203
204Note that tokenizing JavaScript without parsing it is, in modern
205versions of the language, not really possible due to the way syntax is
206overloaded in ways that can only be disambiguated by the parse
207context. This package applies a bunch of heuristics to try and do a
208reasonable job, but you are advised to use `parse` with the `onToken`
209option instead of this.
210
211In ES6 environment, returned result can be used as any other
212protocol-compliant iterable:
213
214```javascript
215for (let token of acorn.tokenizer(str)) {
216 // iterate over the tokens
217}
218
219// transform code to array of tokens:
220var tokens = [...acorn.tokenizer(str)];
221```
222
223**tokTypes** holds an object mapping names to the token type objects
224that end up in the `type` properties of tokens.
225
226**getLineInfo**`(input, offset)` can be used to get a `{line,
227column}` object for a given program string and offset.
228
229### The `Parser` class
230
231Instances of the **`Parser`** class contain all the state and logic
232that drives a parse. It has static methods `parse`,
233`parseExpressionAt`, and `tokenizer` that match the top-level
234functions by the same name.
235
236When extending the parser with plugins, you need to call these methods
237on the extended version of the class. To extend a parser with plugins,
238you can use its static `extend` method.
239
240```javascript
241var acorn = require("acorn");
242var jsx = require("acorn-jsx");
243var JSXParser = acorn.Parser.extend(jsx());
244JSXParser.parse("foo(<bar/>)", {ecmaVersion: 2020});
245```
246
247The `extend` method takes any number of plugin values, and returns a
248new `Parser` class that includes the extra parser logic provided by
249the plugins.
250
251## Command line interface
252
253The `bin/acorn` utility can be used to parse a file from the command
254line. It accepts as arguments its input file and the following
255options:
256
257- `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
258 to parse. Default is version 9.
259
260- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
261
262- `--locations`: Attaches a "loc" object to each node with "start" and
263 "end" subobjects, each of which contains the one-based line and
264 zero-based column numbers in `{line, column}` form.
265
266- `--allow-hash-bang`: If the code starts with the characters #! (as
267 in a shellscript), the first line will be treated as a comment.
268
269- `--allow-await-outside-function`: Allows top-level `await` expressions.
270 See the `allowAwaitOutsideFunction` option for more information.
271
272- `--compact`: No whitespace is used in the AST output.
273
274- `--silent`: Do not output the AST, just return the exit status.
275
276- `--help`: Print the usage information and quit.
277
278The utility spits out the syntax tree as JSON data.
279
280## Existing plugins
281
282 - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
vendor/acorn/bin/acorn +4 -0
……@@ -0,0 +1,4 @@
1#!/usr/bin/env node
2"use strict"
3
4require("../dist/bin.js")
vendor/acorn/dist/acorn.d.mts +883 -0
……@@ -0,0 +1,883 @@
1export interface Node {
2 start: number
3 end: number
4 type: string
5 range?: [number, number]
6 loc?: SourceLocation | null
7}
8
9export interface SourceLocation {
10 source?: string | null
11 start: Position
12 end: Position
13}
14
15export interface Position {
16 /** 1-based */
17 line: number
18 /** 0-based */
19 column: number
20}
21
22export interface Identifier extends Node {
23 type: "Identifier"
24 name: string
25}
26
27export interface Literal extends Node {
28 type: "Literal"
29 value?: string | boolean | null | number | RegExp | bigint
30 raw?: string
31 regex?: {
32 pattern: string
33 flags: string
34 }
35 bigint?: string
36}
37
38export interface Program extends Node {
39 type: "Program"
40 body: Array<Statement | ModuleDeclaration>
41 sourceType: "script" | "module"
42}
43
44export interface Function extends Node {
45 id?: Identifier | null
46 params: Array<Pattern>
47 body: BlockStatement | Expression
48 generator: boolean
49 expression: boolean
50 async: boolean
51}
52
53export interface ExpressionStatement extends Node {
54 type: "ExpressionStatement"
55 expression: Expression | Literal
56 directive?: string
57}
58
59export interface BlockStatement extends Node {
60 type: "BlockStatement"
61 body: Array<Statement>
62}
63
64export interface EmptyStatement extends Node {
65 type: "EmptyStatement"
66}
67
68export interface DebuggerStatement extends Node {
69 type: "DebuggerStatement"
70}
71
72export interface WithStatement extends Node {
73 type: "WithStatement"
74 object: Expression
75 body: Statement
76}
77
78export interface ReturnStatement extends Node {
79 type: "ReturnStatement"
80 argument?: Expression | null
81}
82
83export interface LabeledStatement extends Node {
84 type: "LabeledStatement"
85 label: Identifier
86 body: Statement
87}
88
89export interface BreakStatement extends Node {
90 type: "BreakStatement"
91 label?: Identifier | null
92}
93
94export interface ContinueStatement extends Node {
95 type: "ContinueStatement"
96 label?: Identifier | null
97}
98
99export interface IfStatement extends Node {
100 type: "IfStatement"
101 test: Expression
102 consequent: Statement
103 alternate?: Statement | null
104}
105
106export interface SwitchStatement extends Node {
107 type: "SwitchStatement"
108 discriminant: Expression
109 cases: Array<SwitchCase>
110}
111
112export interface SwitchCase extends Node {
113 type: "SwitchCase"
114 test?: Expression | null
115 consequent: Array<Statement>
116}
117
118export interface ThrowStatement extends Node {
119 type: "ThrowStatement"
120 argument: Expression
121}
122
123export interface TryStatement extends Node {
124 type: "TryStatement"
125 block: BlockStatement
126 handler?: CatchClause | null
127 finalizer?: BlockStatement | null
128}
129
130export interface CatchClause extends Node {
131 type: "CatchClause"
132 param?: Pattern | null
133 body: BlockStatement
134}
135
136export interface WhileStatement extends Node {
137 type: "WhileStatement"
138 test: Expression
139 body: Statement
140}
141
142export interface DoWhileStatement extends Node {
143 type: "DoWhileStatement"
144 body: Statement
145 test: Expression
146}
147
148export interface ForStatement extends Node {
149 type: "ForStatement"
150 init?: VariableDeclaration | Expression | null
151 test?: Expression | null
152 update?: Expression | null
153 body: Statement
154}
155
156export interface ForInStatement extends Node {
157 type: "ForInStatement"
158 left: VariableDeclaration | Pattern
159 right: Expression
160 body: Statement
161}
162
163export interface FunctionDeclaration extends Function {
164 type: "FunctionDeclaration"
165 id: Identifier
166 body: BlockStatement
167}
168
169export interface VariableDeclaration extends Node {
170 type: "VariableDeclaration"
171 declarations: Array<VariableDeclarator>
172 kind: "var" | "let" | "const" | "using" | "await using"
173}
174
175export interface VariableDeclarator extends Node {
176 type: "VariableDeclarator"
177 id: Pattern
178 init?: Expression | null
179}
180
181export interface ThisExpression extends Node {
182 type: "ThisExpression"
183}
184
185export interface ArrayExpression extends Node {
186 type: "ArrayExpression"
187 elements: Array<Expression | SpreadElement | null>
188}
189
190export interface ObjectExpression extends Node {
191 type: "ObjectExpression"
192 properties: Array<Property | SpreadElement>
193}
194
195export interface Property extends Node {
196 type: "Property"
197 key: Expression
198 value: Expression
199 kind: "init" | "get" | "set"
200 method: boolean
201 shorthand: boolean
202 computed: boolean
203}
204
205export interface FunctionExpression extends Function {
206 type: "FunctionExpression"
207 body: BlockStatement
208}
209
210export interface UnaryExpression extends Node {
211 type: "UnaryExpression"
212 operator: UnaryOperator
213 prefix: boolean
214 argument: Expression
215}
216
217export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"
218
219export interface UpdateExpression extends Node {
220 type: "UpdateExpression"
221 operator: UpdateOperator
222 argument: Expression
223 prefix: boolean
224}
225
226export type UpdateOperator = "++" | "--"
227
228export interface BinaryExpression extends Node {
229 type: "BinaryExpression"
230 operator: BinaryOperator
231 left: Expression | PrivateIdentifier
232 right: Expression
233}
234
235export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**"
236
237export interface AssignmentExpression extends Node {
238 type: "AssignmentExpression"
239 operator: AssignmentOperator
240 left: Pattern
241 right: Expression
242}
243
244export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??="
245
246export interface LogicalExpression extends Node {
247 type: "LogicalExpression"
248 operator: LogicalOperator
249 left: Expression
250 right: Expression
251}
252
253export type LogicalOperator = "||" | "&&" | "??"
254
255export interface MemberExpression extends Node {
256 type: "MemberExpression"
257 object: Expression | Super
258 property: Expression | PrivateIdentifier
259 computed: boolean
260 optional: boolean
261}
262
263export interface ConditionalExpression extends Node {
264 type: "ConditionalExpression"
265 test: Expression
266 alternate: Expression
267 consequent: Expression
268}
269
270export interface CallExpression extends Node {
271 type: "CallExpression"
272 callee: Expression | Super
273 arguments: Array<Expression | SpreadElement>
274 optional: boolean
275}
276
277export interface NewExpression extends Node {
278 type: "NewExpression"
279 callee: Expression
280 arguments: Array<Expression | SpreadElement>
281}
282
283export interface SequenceExpression extends Node {
284 type: "SequenceExpression"
285 expressions: Array<Expression>
286}
287
288export interface ForOfStatement extends Node {
289 type: "ForOfStatement"
290 left: VariableDeclaration | Pattern
291 right: Expression
292 body: Statement
293 await: boolean
294}
295
296export interface Super extends Node {
297 type: "Super"
298}
299
300export interface SpreadElement extends Node {
301 type: "SpreadElement"
302 argument: Expression
303}
304
305export interface ArrowFunctionExpression extends Function {
306 type: "ArrowFunctionExpression"
307}
308
309export interface YieldExpression extends Node {
310 type: "YieldExpression"
311 argument?: Expression | null
312 delegate: boolean
313}
314
315export interface TemplateLiteral extends Node {
316 type: "TemplateLiteral"
317 quasis: Array<TemplateElement>
318 expressions: Array<Expression>
319}
320
321export interface TaggedTemplateExpression extends Node {
322 type: "TaggedTemplateExpression"
323 tag: Expression
324 quasi: TemplateLiteral
325}
326
327export interface TemplateElement extends Node {
328 type: "TemplateElement"
329 tail: boolean
330 value: {
331 cooked?: string | null
332 raw: string
333 }
334}
335
336export interface AssignmentProperty extends Node {
337 type: "Property"
338 key: Expression
339 value: Pattern
340 kind: "init"
341 method: false
342 shorthand: boolean
343 computed: boolean
344}
345
346export interface ObjectPattern extends Node {
347 type: "ObjectPattern"
348 properties: Array<AssignmentProperty | RestElement>
349}
350
351export interface ArrayPattern extends Node {
352 type: "ArrayPattern"
353 elements: Array<Pattern | null>
354}
355
356export interface RestElement extends Node {
357 type: "RestElement"
358 argument: Pattern
359}
360
361export interface AssignmentPattern extends Node {
362 type: "AssignmentPattern"
363 left: Pattern
364 right: Expression
365}
366
367export interface Class extends Node {
368 id?: Identifier | null
369 superClass?: Expression | null
370 body: ClassBody
371}
372
373export interface ClassBody extends Node {
374 type: "ClassBody"
375 body: Array<MethodDefinition | PropertyDefinition | StaticBlock>
376}
377
378export interface MethodDefinition extends Node {
379 type: "MethodDefinition"
380 key: Expression | PrivateIdentifier
381 value: FunctionExpression
382 kind: "constructor" | "method" | "get" | "set"
383 computed: boolean
384 static: boolean
385}
386
387export interface ClassDeclaration extends Class {
388 type: "ClassDeclaration"
389 id: Identifier
390}
391
392export interface ClassExpression extends Class {
393 type: "ClassExpression"
394}
395
396export interface MetaProperty extends Node {
397 type: "MetaProperty"
398 meta: Identifier
399 property: Identifier
400}
401
402export interface ImportDeclaration extends Node {
403 type: "ImportDeclaration"
404 specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>
405 source: Literal
406 attributes: Array<ImportAttribute>
407}
408
409export interface ImportSpecifier extends Node {
410 type: "ImportSpecifier"
411 imported: Identifier | Literal
412 local: Identifier
413}
414
415export interface ImportDefaultSpecifier extends Node {
416 type: "ImportDefaultSpecifier"
417 local: Identifier
418}
419
420export interface ImportNamespaceSpecifier extends Node {
421 type: "ImportNamespaceSpecifier"
422 local: Identifier
423}
424
425export interface ImportAttribute extends Node {
426 type: "ImportAttribute"
427 key: Identifier | Literal
428 value: Literal
429}
430
431export interface ExportNamedDeclaration extends Node {
432 type: "ExportNamedDeclaration"
433 declaration?: Declaration | null
434 specifiers: Array<ExportSpecifier>
435 source?: Literal | null
436 attributes: Array<ImportAttribute>
437}
438
439export interface ExportSpecifier extends Node {
440 type: "ExportSpecifier"
441 exported: Identifier | Literal
442 local: Identifier | Literal
443}
444
445export interface AnonymousFunctionDeclaration extends Function {
446 type: "FunctionDeclaration"
447 id: null
448 body: BlockStatement
449}
450
451export interface AnonymousClassDeclaration extends Class {
452 type: "ClassDeclaration"
453 id: null
454}
455
456export interface ExportDefaultDeclaration extends Node {
457 type: "ExportDefaultDeclaration"
458 declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression
459}
460
461export interface ExportAllDeclaration extends Node {
462 type: "ExportAllDeclaration"
463 source: Literal
464 exported?: Identifier | Literal | null
465 attributes: Array<ImportAttribute>
466}
467
468export interface AwaitExpression extends Node {
469 type: "AwaitExpression"
470 argument: Expression
471}
472
473export interface ChainExpression extends Node {
474 type: "ChainExpression"
475 expression: MemberExpression | CallExpression
476}
477
478export interface ImportExpression extends Node {
479 type: "ImportExpression"
480 source: Expression
481 options: Expression | null
482}
483
484export interface ParenthesizedExpression extends Node {
485 type: "ParenthesizedExpression"
486 expression: Expression
487}
488
489export interface PropertyDefinition extends Node {
490 type: "PropertyDefinition"
491 key: Expression | PrivateIdentifier
492 value?: Expression | null
493 computed: boolean
494 static: boolean
495}
496
497export interface PrivateIdentifier extends Node {
498 type: "PrivateIdentifier"
499 name: string
500}
501
502export interface StaticBlock extends Node {
503 type: "StaticBlock"
504 body: Array<Statement>
505}
506
507export type Statement =
508| ExpressionStatement
509| BlockStatement
510| EmptyStatement
511| DebuggerStatement
512| WithStatement
513| ReturnStatement
514| LabeledStatement
515| BreakStatement
516| ContinueStatement
517| IfStatement
518| SwitchStatement
519| ThrowStatement
520| TryStatement
521| WhileStatement
522| DoWhileStatement
523| ForStatement
524| ForInStatement
525| ForOfStatement
526| Declaration
527
528export type Declaration =
529| FunctionDeclaration
530| VariableDeclaration
531| ClassDeclaration
532
533export type Expression =
534| Identifier
535| Literal
536| ThisExpression
537| ArrayExpression
538| ObjectExpression
539| FunctionExpression
540| UnaryExpression
541| UpdateExpression
542| BinaryExpression
543| AssignmentExpression
544| LogicalExpression
545| MemberExpression
546| ConditionalExpression
547| CallExpression
548| NewExpression
549| SequenceExpression
550| ArrowFunctionExpression
551| YieldExpression
552| TemplateLiteral
553| TaggedTemplateExpression
554| ClassExpression
555| MetaProperty
556| AwaitExpression
557| ChainExpression
558| ImportExpression
559| ParenthesizedExpression
560
561export type Pattern =
562| Identifier
563| MemberExpression
564| ObjectPattern
565| ArrayPattern
566| RestElement
567| AssignmentPattern
568
569export type ModuleDeclaration =
570| ImportDeclaration
571| ExportNamedDeclaration
572| ExportDefaultDeclaration
573| ExportAllDeclaration
574
575/**
576 * This interface is only used for defining {@link AnyNode}.
577 * It exists so that it can be extended by plugins:
578 *
579 * @example
580 * ```typescript
581 * declare module 'acorn' {
582 * interface NodeTypes {
583 * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode
584 * }
585 * }
586 * ```
587 */
588interface NodeTypes {
589 core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator
590}
591
592export type AnyNode = NodeTypes[keyof NodeTypes]
593
594export function parse(input: string, options: Options): Program
595
596export function parseExpressionAt(input: string, pos: number, options: Options): Expression
597
598export function tokenizer(input: string, options: Options): {
599 getToken(): Token
600 [Symbol.iterator](): Iterator<Token>
601}
602
603export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest"
604
605export interface Options {
606 /**
607 * `ecmaVersion` indicates the ECMAScript version to parse. Can be a
608 * number, either in year (`2022`) or plain version number (`6`) form,
609 * or `"latest"` (the latest the library supports). This influences
610 * support for strict mode, the set of reserved words, and support for
611 * new syntax features.
612 */
613 ecmaVersion: ecmaVersion
614
615 /**
616 * `sourceType` indicates the mode the code should be parsed in.
617 * Can be either `"script"` or `"module"`. This influences global
618 * strict mode and parsing of `import` and `export` declarations.
619 */
620 sourceType?: "script" | "module"
621
622 /**
623 * a callback that will be called when a semicolon is automatically inserted.
624 * @param lastTokEnd the position of the comma as an offset
625 * @param lastTokEndLoc location if {@link locations} is enabled
626 */
627 onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
628
629 /**
630 * similar to `onInsertedSemicolon`, but for trailing commas
631 * @param lastTokEnd the position of the comma as an offset
632 * @param lastTokEndLoc location if `locations` is enabled
633 */
634 onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
635
636 /**
637 * By default, reserved words are only enforced if ecmaVersion >= 5.
638 * Set `allowReserved` to a boolean value to explicitly turn this on
639 * an off. When this option has the value "never", reserved words
640 * and keywords can also not be used as property names.
641 */
642 allowReserved?: boolean | "never"
643
644 /**
645 * When enabled, a return at the top level is not considered an error.
646 */
647 allowReturnOutsideFunction?: boolean
648
649 /**
650 * When enabled, import/export statements are not constrained to
651 * appearing at the top of the program, and an import.meta expression
652 * in a script isn't considered an error.
653 */
654 allowImportExportEverywhere?: boolean
655
656 /**
657 * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022.
658 * When enabled, await identifiers are allowed to appear at the top-level scope,
659 * but they are still not allowed in non-async functions.
660 */
661 allowAwaitOutsideFunction?: boolean
662
663 /**
664 * When enabled, super identifiers are not constrained to
665 * appearing in methods and do not raise an error when they appear elsewhere.
666 */
667 allowSuperOutsideMethod?: boolean
668
669 /**
670 * When enabled, hashbang directive in the beginning of file is
671 * allowed and treated as a line comment. Enabled by default when
672 * {@link ecmaVersion} >= 2023.
673 */
674 allowHashBang?: boolean
675
676 /**
677 * By default, the parser will verify that private properties are
678 * only used in places where they are valid and have been declared.
679 * Set this to false to turn such checks off.
680 */
681 checkPrivateFields?: boolean
682
683 /**
684 * When `locations` is on, `loc` properties holding objects with
685 * `start` and `end` properties as {@link Position} objects will be attached to the
686 * nodes.
687 */
688 locations?: boolean
689
690 /**
691 * a callback that will cause Acorn to call that export function with object in the same
692 * format as tokens returned from `tokenizer().getToken()`. Note
693 * that you are not allowed to call the parser from the
694 * callback—that will corrupt its internal state.
695 */
696 onToken?: ((token: Token) => void) | Token[]
697
698
699 /**
700 * This takes a export function or an array.
701 *
702 * When a export function is passed, Acorn will call that export function with `(block, text, start,
703 * end)` parameters whenever a comment is skipped. `block` is a
704 * boolean indicating whether this is a block (`/* *\/`) comment,
705 * `text` is the content of the comment, and `start` and `end` are
706 * character offsets that denote the start and end of the comment.
707 * When the {@link locations} option is on, two more parameters are
708 * passed, the full locations of {@link Position} export type of the start and
709 * end of the comments.
710 *
711 * When a array is passed, each found comment of {@link Comment} export type is pushed to the array.
712 *
713 * Note that you are not allowed to call the
714 * parser from the callback—that will corrupt its internal state.
715 */
716 onComment?: ((
717 isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
718 endLoc?: Position
719 ) => void) | Comment[]
720
721 /**
722 * Nodes have their start and end characters offsets recorded in
723 * `start` and `end` properties (directly on the node, rather than
724 * the `loc` object, which holds line/column data. To also add a
725 * [semi-standardized][range] `range` property holding a `[start,
726 * end]` array with the same numbers, set the `ranges` option to
727 * `true`.
728 */
729 ranges?: boolean
730
731 /**
732 * It is possible to parse multiple files into a single AST by
733 * passing the tree produced by parsing the first file as
734 * `program` option in subsequent parses. This will add the
735 * toplevel forms of the parsed file to the `Program` (top) node
736 * of an existing parse tree.
737 */
738 program?: Node
739
740 /**
741 * When {@link locations} is on, you can pass this to record the source
742 * file in every node's `loc` object.
743 */
744 sourceFile?: string
745
746 /**
747 * This value, if given, is stored in every node, whether {@link locations} is on or off.
748 */
749 directSourceFile?: string
750
751 /**
752 * When enabled, parenthesized expressions are represented by
753 * (non-standard) ParenthesizedExpression nodes
754 */
755 preserveParens?: boolean
756}
757
758export class Parser {
759 options: Options
760 input: string
761
762 protected constructor(options: Options, input: string, startPos?: number)
763 parse(): Program
764
765 static parse(input: string, options: Options): Program
766 static parseExpressionAt(input: string, pos: number, options: Options): Expression
767 static tokenizer(input: string, options: Options): {
768 getToken(): Token
769 [Symbol.iterator](): Iterator<Token>
770 }
771 static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser
772}
773
774export const defaultOptions: Options
775
776export function getLineInfo(input: string, offset: number): Position
777
778export class TokenType {
779 label: string
780 keyword: string | undefined
781}
782
783export const tokTypes: {
784 num: TokenType
785 regexp: TokenType
786 string: TokenType
787 name: TokenType
788 privateId: TokenType
789 eof: TokenType
790
791 bracketL: TokenType
792 bracketR: TokenType
793 braceL: TokenType
794 braceR: TokenType
795 parenL: TokenType
796 parenR: TokenType
797 comma: TokenType
798 semi: TokenType
799 colon: TokenType
800 dot: TokenType
801 question: TokenType
802 questionDot: TokenType
803 arrow: TokenType
804 template: TokenType
805 invalidTemplate: TokenType
806 ellipsis: TokenType
807 backQuote: TokenType
808 dollarBraceL: TokenType
809
810 eq: TokenType
811 assign: TokenType
812 incDec: TokenType
813 prefix: TokenType
814 logicalOR: TokenType
815 logicalAND: TokenType
816 bitwiseOR: TokenType
817 bitwiseXOR: TokenType
818 bitwiseAND: TokenType
819 equality: TokenType
820 relational: TokenType
821 bitShift: TokenType
822 plusMin: TokenType
823 modulo: TokenType
824 star: TokenType
825 slash: TokenType
826 starstar: TokenType
827 coalesce: TokenType
828
829 _break: TokenType
830 _case: TokenType
831 _catch: TokenType
832 _continue: TokenType
833 _debugger: TokenType
834 _default: TokenType
835 _do: TokenType
836 _else: TokenType
837 _finally: TokenType
838 _for: TokenType
839 _function: TokenType
840 _if: TokenType
841 _return: TokenType
842 _switch: TokenType
843 _throw: TokenType
844 _try: TokenType
845 _var: TokenType
846 _const: TokenType
847 _while: TokenType
848 _with: TokenType
849 _new: TokenType
850 _this: TokenType
851 _super: TokenType
852 _class: TokenType
853 _extends: TokenType
854 _export: TokenType
855 _import: TokenType
856 _null: TokenType
857 _true: TokenType
858 _false: TokenType
859 _in: TokenType
860 _instanceof: TokenType
861 _typeof: TokenType
862 _void: TokenType
863 _delete: TokenType
864}
865
866export interface Comment {
867 type: "Line" | "Block"
868 value: string
869 start: number
870 end: number
871 loc?: SourceLocation
872 range?: [number, number]
873}
874
875export class Token {
876 type: TokenType
877 start: number
878 end: number
879 loc?: SourceLocation
880 range?: [number, number]
881}
882
883export const version: string
vendor/acorn/dist/acorn.d.ts +883 -0
……@@ -0,0 +1,883 @@
1export interface Node {
2 start: number
3 end: number
4 type: string
5 range?: [number, number]
6 loc?: SourceLocation | null
7}
8
9export interface SourceLocation {
10 source?: string | null
11 start: Position
12 end: Position
13}
14
15export interface Position {
16 /** 1-based */
17 line: number
18 /** 0-based */
19 column: number
20}
21
22export interface Identifier extends Node {
23 type: "Identifier"
24 name: string
25}
26
27export interface Literal extends Node {
28 type: "Literal"
29 value?: string | boolean | null | number | RegExp | bigint
30 raw?: string
31 regex?: {
32 pattern: string
33 flags: string
34 }
35 bigint?: string
36}
37
38export interface Program extends Node {
39 type: "Program"
40 body: Array<Statement | ModuleDeclaration>
41 sourceType: "script" | "module"
42}
43
44export interface Function extends Node {
45 id?: Identifier | null
46 params: Array<Pattern>
47 body: BlockStatement | Expression
48 generator: boolean
49 expression: boolean
50 async: boolean
51}
52
53export interface ExpressionStatement extends Node {
54 type: "ExpressionStatement"
55 expression: Expression | Literal
56 directive?: string
57}
58
59export interface BlockStatement extends Node {
60 type: "BlockStatement"
61 body: Array<Statement>
62}
63
64export interface EmptyStatement extends Node {
65 type: "EmptyStatement"
66}
67
68export interface DebuggerStatement extends Node {
69 type: "DebuggerStatement"
70}
71
72export interface WithStatement extends Node {
73 type: "WithStatement"
74 object: Expression
75 body: Statement
76}
77
78export interface ReturnStatement extends Node {
79 type: "ReturnStatement"
80 argument?: Expression | null
81}
82
83export interface LabeledStatement extends Node {
84 type: "LabeledStatement"
85 label: Identifier
86 body: Statement
87}
88
89export interface BreakStatement extends Node {
90 type: "BreakStatement"
91 label?: Identifier | null
92}
93
94export interface ContinueStatement extends Node {
95 type: "ContinueStatement"
96 label?: Identifier | null
97}
98
99export interface IfStatement extends Node {
100 type: "IfStatement"
101 test: Expression
102 consequent: Statement
103 alternate?: Statement | null
104}
105
106export interface SwitchStatement extends Node {
107 type: "SwitchStatement"
108 discriminant: Expression
109 cases: Array<SwitchCase>
110}
111
112export interface SwitchCase extends Node {
113 type: "SwitchCase"
114 test?: Expression | null
115 consequent: Array<Statement>
116}
117
118export interface ThrowStatement extends Node {
119 type: "ThrowStatement"
120 argument: Expression
121}
122
123export interface TryStatement extends Node {
124 type: "TryStatement"
125 block: BlockStatement
126 handler?: CatchClause | null
127 finalizer?: BlockStatement | null
128}
129
130export interface CatchClause extends Node {
131 type: "CatchClause"
132 param?: Pattern | null
133 body: BlockStatement
134}
135
136export interface WhileStatement extends Node {
137 type: "WhileStatement"
138 test: Expression
139 body: Statement
140}
141
142export interface DoWhileStatement extends Node {
143 type: "DoWhileStatement"
144 body: Statement
145 test: Expression
146}
147
148export interface ForStatement extends Node {
149 type: "ForStatement"
150 init?: VariableDeclaration | Expression | null
151 test?: Expression | null
152 update?: Expression | null
153 body: Statement
154}
155
156export interface ForInStatement extends Node {
157 type: "ForInStatement"
158 left: VariableDeclaration | Pattern
159 right: Expression
160 body: Statement
161}
162
163export interface FunctionDeclaration extends Function {
164 type: "FunctionDeclaration"
165 id: Identifier
166 body: BlockStatement
167}
168
169export interface VariableDeclaration extends Node {
170 type: "VariableDeclaration"
171 declarations: Array<VariableDeclarator>
172 kind: "var" | "let" | "const" | "using" | "await using"
173}
174
175export interface VariableDeclarator extends Node {
176 type: "VariableDeclarator"
177 id: Pattern
178 init?: Expression | null
179}
180
181export interface ThisExpression extends Node {
182 type: "ThisExpression"
183}
184
185export interface ArrayExpression extends Node {
186 type: "ArrayExpression"
187 elements: Array<Expression | SpreadElement | null>
188}
189
190export interface ObjectExpression extends Node {
191 type: "ObjectExpression"
192 properties: Array<Property | SpreadElement>
193}
194
195export interface Property extends Node {
196 type: "Property"
197 key: Expression
198 value: Expression
199 kind: "init" | "get" | "set"
200 method: boolean
201 shorthand: boolean
202 computed: boolean
203}
204
205export interface FunctionExpression extends Function {
206 type: "FunctionExpression"
207 body: BlockStatement
208}
209
210export interface UnaryExpression extends Node {
211 type: "UnaryExpression"
212 operator: UnaryOperator
213 prefix: boolean
214 argument: Expression
215}
216
217export type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete"
218
219export interface UpdateExpression extends Node {
220 type: "UpdateExpression"
221 operator: UpdateOperator
222 argument: Expression
223 prefix: boolean
224}
225
226export type UpdateOperator = "++" | "--"
227
228export interface BinaryExpression extends Node {
229 type: "BinaryExpression"
230 operator: BinaryOperator
231 left: Expression | PrivateIdentifier
232 right: Expression
233}
234
235export type BinaryOperator = "==" | "!=" | "===" | "!==" | "<" | "<=" | ">" | ">=" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "|" | "^" | "&" | "in" | "instanceof" | "**"
236
237export interface AssignmentExpression extends Node {
238 type: "AssignmentExpression"
239 operator: AssignmentOperator
240 left: Pattern
241 right: Expression
242}
243
244export type AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "<<=" | ">>=" | ">>>=" | "|=" | "^=" | "&=" | "**=" | "||=" | "&&=" | "??="
245
246export interface LogicalExpression extends Node {
247 type: "LogicalExpression"
248 operator: LogicalOperator
249 left: Expression
250 right: Expression
251}
252
253export type LogicalOperator = "||" | "&&" | "??"
254
255export interface MemberExpression extends Node {
256 type: "MemberExpression"
257 object: Expression | Super
258 property: Expression | PrivateIdentifier
259 computed: boolean
260 optional: boolean
261}
262
263export interface ConditionalExpression extends Node {
264 type: "ConditionalExpression"
265 test: Expression
266 alternate: Expression
267 consequent: Expression
268}
269
270export interface CallExpression extends Node {
271 type: "CallExpression"
272 callee: Expression | Super
273 arguments: Array<Expression | SpreadElement>
274 optional: boolean
275}
276
277export interface NewExpression extends Node {
278 type: "NewExpression"
279 callee: Expression
280 arguments: Array<Expression | SpreadElement>
281}
282
283export interface SequenceExpression extends Node {
284 type: "SequenceExpression"
285 expressions: Array<Expression>
286}
287
288export interface ForOfStatement extends Node {
289 type: "ForOfStatement"
290 left: VariableDeclaration | Pattern
291 right: Expression
292 body: Statement
293 await: boolean
294}
295
296export interface Super extends Node {
297 type: "Super"
298}
299
300export interface SpreadElement extends Node {
301 type: "SpreadElement"
302 argument: Expression
303}
304
305export interface ArrowFunctionExpression extends Function {
306 type: "ArrowFunctionExpression"
307}
308
309export interface YieldExpression extends Node {
310 type: "YieldExpression"
311 argument?: Expression | null
312 delegate: boolean
313}
314
315export interface TemplateLiteral extends Node {
316 type: "TemplateLiteral"
317 quasis: Array<TemplateElement>
318 expressions: Array<Expression>
319}
320
321export interface TaggedTemplateExpression extends Node {
322 type: "TaggedTemplateExpression"
323 tag: Expression
324 quasi: TemplateLiteral
325}
326
327export interface TemplateElement extends Node {
328 type: "TemplateElement"
329 tail: boolean
330 value: {
331 cooked?: string | null
332 raw: string
333 }
334}
335
336export interface AssignmentProperty extends Node {
337 type: "Property"
338 key: Expression
339 value: Pattern
340 kind: "init"
341 method: false
342 shorthand: boolean
343 computed: boolean
344}
345
346export interface ObjectPattern extends Node {
347 type: "ObjectPattern"
348 properties: Array<AssignmentProperty | RestElement>
349}
350
351export interface ArrayPattern extends Node {
352 type: "ArrayPattern"
353 elements: Array<Pattern | null>
354}
355
356export interface RestElement extends Node {
357 type: "RestElement"
358 argument: Pattern
359}
360
361export interface AssignmentPattern extends Node {
362 type: "AssignmentPattern"
363 left: Pattern
364 right: Expression
365}
366
367export interface Class extends Node {
368 id?: Identifier | null
369 superClass?: Expression | null
370 body: ClassBody
371}
372
373export interface ClassBody extends Node {
374 type: "ClassBody"
375 body: Array<MethodDefinition | PropertyDefinition | StaticBlock>
376}
377
378export interface MethodDefinition extends Node {
379 type: "MethodDefinition"
380 key: Expression | PrivateIdentifier
381 value: FunctionExpression
382 kind: "constructor" | "method" | "get" | "set"
383 computed: boolean
384 static: boolean
385}
386
387export interface ClassDeclaration extends Class {
388 type: "ClassDeclaration"
389 id: Identifier
390}
391
392export interface ClassExpression extends Class {
393 type: "ClassExpression"
394}
395
396export interface MetaProperty extends Node {
397 type: "MetaProperty"
398 meta: Identifier
399 property: Identifier
400}
401
402export interface ImportDeclaration extends Node {
403 type: "ImportDeclaration"
404 specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>
405 source: Literal
406 attributes: Array<ImportAttribute>
407}
408
409export interface ImportSpecifier extends Node {
410 type: "ImportSpecifier"
411 imported: Identifier | Literal
412 local: Identifier
413}
414
415export interface ImportDefaultSpecifier extends Node {
416 type: "ImportDefaultSpecifier"
417 local: Identifier
418}
419
420export interface ImportNamespaceSpecifier extends Node {
421 type: "ImportNamespaceSpecifier"
422 local: Identifier
423}
424
425export interface ImportAttribute extends Node {
426 type: "ImportAttribute"
427 key: Identifier | Literal
428 value: Literal
429}
430
431export interface ExportNamedDeclaration extends Node {
432 type: "ExportNamedDeclaration"
433 declaration?: Declaration | null
434 specifiers: Array<ExportSpecifier>
435 source?: Literal | null
436 attributes: Array<ImportAttribute>
437}
438
439export interface ExportSpecifier extends Node {
440 type: "ExportSpecifier"
441 exported: Identifier | Literal
442 local: Identifier | Literal
443}
444
445export interface AnonymousFunctionDeclaration extends Function {
446 type: "FunctionDeclaration"
447 id: null
448 body: BlockStatement
449}
450
451export interface AnonymousClassDeclaration extends Class {
452 type: "ClassDeclaration"
453 id: null
454}
455
456export interface ExportDefaultDeclaration extends Node {
457 type: "ExportDefaultDeclaration"
458 declaration: AnonymousFunctionDeclaration | FunctionDeclaration | AnonymousClassDeclaration | ClassDeclaration | Expression
459}
460
461export interface ExportAllDeclaration extends Node {
462 type: "ExportAllDeclaration"
463 source: Literal
464 exported?: Identifier | Literal | null
465 attributes: Array<ImportAttribute>
466}
467
468export interface AwaitExpression extends Node {
469 type: "AwaitExpression"
470 argument: Expression
471}
472
473export interface ChainExpression extends Node {
474 type: "ChainExpression"
475 expression: MemberExpression | CallExpression
476}
477
478export interface ImportExpression extends Node {
479 type: "ImportExpression"
480 source: Expression
481 options: Expression | null
482}
483
484export interface ParenthesizedExpression extends Node {
485 type: "ParenthesizedExpression"
486 expression: Expression
487}
488
489export interface PropertyDefinition extends Node {
490 type: "PropertyDefinition"
491 key: Expression | PrivateIdentifier
492 value?: Expression | null
493 computed: boolean
494 static: boolean
495}
496
497export interface PrivateIdentifier extends Node {
498 type: "PrivateIdentifier"
499 name: string
500}
501
502export interface StaticBlock extends Node {
503 type: "StaticBlock"
504 body: Array<Statement>
505}
506
507export type Statement =
508| ExpressionStatement
509| BlockStatement
510| EmptyStatement
511| DebuggerStatement
512| WithStatement
513| ReturnStatement
514| LabeledStatement
515| BreakStatement
516| ContinueStatement
517| IfStatement
518| SwitchStatement
519| ThrowStatement
520| TryStatement
521| WhileStatement
522| DoWhileStatement
523| ForStatement
524| ForInStatement
525| ForOfStatement
526| Declaration
527
528export type Declaration =
529| FunctionDeclaration
530| VariableDeclaration
531| ClassDeclaration
532
533export type Expression =
534| Identifier
535| Literal
536| ThisExpression
537| ArrayExpression
538| ObjectExpression
539| FunctionExpression
540| UnaryExpression
541| UpdateExpression
542| BinaryExpression
543| AssignmentExpression
544| LogicalExpression
545| MemberExpression
546| ConditionalExpression
547| CallExpression
548| NewExpression
549| SequenceExpression
550| ArrowFunctionExpression
551| YieldExpression
552| TemplateLiteral
553| TaggedTemplateExpression
554| ClassExpression
555| MetaProperty
556| AwaitExpression
557| ChainExpression
558| ImportExpression
559| ParenthesizedExpression
560
561export type Pattern =
562| Identifier
563| MemberExpression
564| ObjectPattern
565| ArrayPattern
566| RestElement
567| AssignmentPattern
568
569export type ModuleDeclaration =
570| ImportDeclaration
571| ExportNamedDeclaration
572| ExportDefaultDeclaration
573| ExportAllDeclaration
574
575/**
576 * This interface is only used for defining {@link AnyNode}.
577 * It exists so that it can be extended by plugins:
578 *
579 * @example
580 * ```typescript
581 * declare module 'acorn' {
582 * interface NodeTypes {
583 * pluginName: FirstNode | SecondNode | ThirdNode | ... | LastNode
584 * }
585 * }
586 * ```
587 */
588interface NodeTypes {
589 core: Statement | Expression | Declaration | ModuleDeclaration | Literal | Program | SwitchCase | CatchClause | Property | Super | SpreadElement | TemplateElement | AssignmentProperty | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | ClassBody | MethodDefinition | MetaProperty | ImportAttribute | ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier | AnonymousFunctionDeclaration | AnonymousClassDeclaration | PropertyDefinition | PrivateIdentifier | StaticBlock | VariableDeclarator
590}
591
592export type AnyNode = NodeTypes[keyof NodeTypes]
593
594export function parse(input: string, options: Options): Program
595
596export function parseExpressionAt(input: string, pos: number, options: Options): Expression
597
598export function tokenizer(input: string, options: Options): {
599 getToken(): Token
600 [Symbol.iterator](): Iterator<Token>
601}
602
603export type ecmaVersion = 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | "latest"
604
605export interface Options {
606 /**
607 * `ecmaVersion` indicates the ECMAScript version to parse. Can be a
608 * number, either in year (`2022`) or plain version number (`6`) form,
609 * or `"latest"` (the latest the library supports). This influences
610 * support for strict mode, the set of reserved words, and support for
611 * new syntax features.
612 */
613 ecmaVersion: ecmaVersion
614
615 /**
616 * `sourceType` indicates the mode the code should be parsed in.
617 * Can be either `"script"` or `"module"`. This influences global
618 * strict mode and parsing of `import` and `export` declarations.
619 */
620 sourceType?: "script" | "module"
621
622 /**
623 * a callback that will be called when a semicolon is automatically inserted.
624 * @param lastTokEnd the position of the comma as an offset
625 * @param lastTokEndLoc location if {@link locations} is enabled
626 */
627 onInsertedSemicolon?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
628
629 /**
630 * similar to `onInsertedSemicolon`, but for trailing commas
631 * @param lastTokEnd the position of the comma as an offset
632 * @param lastTokEndLoc location if `locations` is enabled
633 */
634 onTrailingComma?: (lastTokEnd: number, lastTokEndLoc?: Position) => void
635
636 /**
637 * By default, reserved words are only enforced if ecmaVersion >= 5.
638 * Set `allowReserved` to a boolean value to explicitly turn this on
639 * an off. When this option has the value "never", reserved words
640 * and keywords can also not be used as property names.
641 */
642 allowReserved?: boolean | "never"
643
644 /**
645 * When enabled, a return at the top level is not considered an error.
646 */
647 allowReturnOutsideFunction?: boolean
648
649 /**
650 * When enabled, import/export statements are not constrained to
651 * appearing at the top of the program, and an import.meta expression
652 * in a script isn't considered an error.
653 */
654 allowImportExportEverywhere?: boolean
655
656 /**
657 * By default, `await` identifiers are allowed to appear at the top-level scope only if {@link ecmaVersion} >= 2022.
658 * When enabled, await identifiers are allowed to appear at the top-level scope,
659 * but they are still not allowed in non-async functions.
660 */
661 allowAwaitOutsideFunction?: boolean
662
663 /**
664 * When enabled, super identifiers are not constrained to
665 * appearing in methods and do not raise an error when they appear elsewhere.
666 */
667 allowSuperOutsideMethod?: boolean
668
669 /**
670 * When enabled, hashbang directive in the beginning of file is
671 * allowed and treated as a line comment. Enabled by default when
672 * {@link ecmaVersion} >= 2023.
673 */
674 allowHashBang?: boolean
675
676 /**
677 * By default, the parser will verify that private properties are
678 * only used in places where they are valid and have been declared.
679 * Set this to false to turn such checks off.
680 */
681 checkPrivateFields?: boolean
682
683 /**
684 * When `locations` is on, `loc` properties holding objects with
685 * `start` and `end` properties as {@link Position} objects will be attached to the
686 * nodes.
687 */
688 locations?: boolean
689
690 /**
691 * a callback that will cause Acorn to call that export function with object in the same
692 * format as tokens returned from `tokenizer().getToken()`. Note
693 * that you are not allowed to call the parser from the
694 * callback—that will corrupt its internal state.
695 */
696 onToken?: ((token: Token) => void) | Token[]
697
698
699 /**
700 * This takes a export function or an array.
701 *
702 * When a export function is passed, Acorn will call that export function with `(block, text, start,
703 * end)` parameters whenever a comment is skipped. `block` is a
704 * boolean indicating whether this is a block (`/* *\/`) comment,
705 * `text` is the content of the comment, and `start` and `end` are
706 * character offsets that denote the start and end of the comment.
707 * When the {@link locations} option is on, two more parameters are
708 * passed, the full locations of {@link Position} export type of the start and
709 * end of the comments.
710 *
711 * When a array is passed, each found comment of {@link Comment} export type is pushed to the array.
712 *
713 * Note that you are not allowed to call the
714 * parser from the callback—that will corrupt its internal state.
715 */
716 onComment?: ((
717 isBlock: boolean, text: string, start: number, end: number, startLoc?: Position,
718 endLoc?: Position
719 ) => void) | Comment[]
720
721 /**
722 * Nodes have their start and end characters offsets recorded in
723 * `start` and `end` properties (directly on the node, rather than
724 * the `loc` object, which holds line/column data. To also add a
725 * [semi-standardized][range] `range` property holding a `[start,
726 * end]` array with the same numbers, set the `ranges` option to
727 * `true`.
728 */
729 ranges?: boolean
730
731 /**
732 * It is possible to parse multiple files into a single AST by
733 * passing the tree produced by parsing the first file as
734 * `program` option in subsequent parses. This will add the
735 * toplevel forms of the parsed file to the `Program` (top) node
736 * of an existing parse tree.
737 */
738 program?: Node
739
740 /**
741 * When {@link locations} is on, you can pass this to record the source
742 * file in every node's `loc` object.
743 */
744 sourceFile?: string
745
746 /**
747 * This value, if given, is stored in every node, whether {@link locations} is on or off.
748 */
749 directSourceFile?: string
750
751 /**
752 * When enabled, parenthesized expressions are represented by
753 * (non-standard) ParenthesizedExpression nodes
754 */
755 preserveParens?: boolean
756}
757
758export class Parser {
759 options: Options
760 input: string
761
762 protected constructor(options: Options, input: string, startPos?: number)
763 parse(): Program
764
765 static parse(input: string, options: Options): Program
766 static parseExpressionAt(input: string, pos: number, options: Options): Expression
767 static tokenizer(input: string, options: Options): {
768 getToken(): Token
769 [Symbol.iterator](): Iterator<Token>
770 }
771 static extend(...plugins: ((BaseParser: typeof Parser) => typeof Parser)[]): typeof Parser
772}
773
774export const defaultOptions: Options
775
776export function getLineInfo(input: string, offset: number): Position
777
778export class TokenType {
779 label: string
780 keyword: string | undefined
781}
782
783export const tokTypes: {
784 num: TokenType
785 regexp: TokenType
786 string: TokenType
787 name: TokenType
788 privateId: TokenType
789 eof: TokenType
790
791 bracketL: TokenType
792 bracketR: TokenType
793 braceL: TokenType
794 braceR: TokenType
795 parenL: TokenType
796 parenR: TokenType
797 comma: TokenType
798 semi: TokenType
799 colon: TokenType
800 dot: TokenType
801 question: TokenType
802 questionDot: TokenType
803 arrow: TokenType
804 template: TokenType
805 invalidTemplate: TokenType
806 ellipsis: TokenType
807 backQuote: TokenType
808 dollarBraceL: TokenType
809
810 eq: TokenType
811 assign: TokenType
812 incDec: TokenType
813 prefix: TokenType
814 logicalOR: TokenType
815 logicalAND: TokenType
816 bitwiseOR: TokenType
817 bitwiseXOR: TokenType
818 bitwiseAND: TokenType
819 equality: TokenType
820 relational: TokenType
821 bitShift: TokenType
822 plusMin: TokenType
823 modulo: TokenType
824 star: TokenType
825 slash: TokenType
826 starstar: TokenType
827 coalesce: TokenType
828
829 _break: TokenType
830 _case: TokenType
831 _catch: TokenType
832 _continue: TokenType
833 _debugger: TokenType
834 _default: TokenType
835 _do: TokenType
836 _else: TokenType
837 _finally: TokenType
838 _for: TokenType
839 _function: TokenType
840 _if: TokenType
841 _return: TokenType
842 _switch: TokenType
843 _throw: TokenType
844 _try: TokenType
845 _var: TokenType
846 _const: TokenType
847 _while: TokenType
848 _with: TokenType
849 _new: TokenType
850 _this: TokenType
851 _super: TokenType
852 _class: TokenType
853 _extends: TokenType
854 _export: TokenType
855 _import: TokenType
856 _null: TokenType
857 _true: TokenType
858 _false: TokenType
859 _in: TokenType
860 _instanceof: TokenType
861 _typeof: TokenType
862 _void: TokenType
863 _delete: TokenType
864}
865
866export interface Comment {
867 type: "Line" | "Block"
868 value: string
869 start: number
870 end: number
871 loc?: SourceLocation
872 range?: [number, number]
873}
874
875export class Token {
876 type: TokenType
877 start: number
878 end: number
879 loc?: SourceLocation
880 range?: [number, number]
881}
882
883export const version: string
vendor/acorn/dist/acorn.js +6262 -0
……@@ -0,0 +1,6262 @@
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.acorn = {}));
5})(this, (function (exports) { 'use strict';
6
7 // This file was generated. Do not modify manually!
8 var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 80, 3, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 343, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 726, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
9
10 // This file was generated. Do not modify manually!
11 var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 2, 60, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 42, 9, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 496, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191];
12
13 // This file was generated. Do not modify manually!
14 var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
15
16 // This file was generated. Do not modify manually!
17 var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
18
19 // These are a run-length and offset encoded representation of the
20 // >0xffff code points that are a valid part of identifiers. The
21 // offset starts at 0x10000, and each pair of numbers represents an
22 // offset to the next range, and then a size of the range.
23
24 // Reserved word lists for various dialects of the language
25
26 var reservedWords = {
27 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
28 5: "class enum extends super const export import",
29 6: "enum",
30 strict: "implements interface let package private protected public static yield",
31 strictBind: "eval arguments"
32 };
33
34 // And the keywords
35
36 var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
37
38 var keywords$1 = {
39 5: ecma5AndLessKeywords,
40 "5module": ecma5AndLessKeywords + " export import",
41 6: ecma5AndLessKeywords + " const class extends export import super"
42 };
43
44 var keywordRelationalOperator = /^in(stanceof)?$/;
45
46 // ## Character categories
47
48 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
49 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
50
51 // This has a complexity linear to the value of the code. The
52 // assumption is that looking up astral identifier characters is
53 // rare.
54 function isInAstralSet(code, set) {
55 var pos = 0x10000;
56 for (var i = 0; i < set.length; i += 2) {
57 pos += set[i];
58 if (pos > code) { return false }
59 pos += set[i + 1];
60 if (pos >= code) { return true }
61 }
62 return false
63 }
64
65 // Test whether a given character code starts an identifier.
66
67 function isIdentifierStart(code, astral) {
68 if (code < 65) { return code === 36 }
69 if (code < 91) { return true }
70 if (code < 97) { return code === 95 }
71 if (code < 123) { return true }
72 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
73 if (astral === false) { return false }
74 return isInAstralSet(code, astralIdentifierStartCodes)
75 }
76
77 // Test whether a given character is part of an identifier.
78
79 function isIdentifierChar(code, astral) {
80 if (code < 48) { return code === 36 }
81 if (code < 58) { return true }
82 if (code < 65) { return false }
83 if (code < 91) { return true }
84 if (code < 97) { return code === 95 }
85 if (code < 123) { return true }
86 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
87 if (astral === false) { return false }
88 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
89 }
90
91 // ## Token types
92
93 // The assignment of fine-grained, information-carrying type objects
94 // allows the tokenizer to store the information it has about a
95 // token in a way that is very cheap for the parser to look up.
96
97 // All token type variables start with an underscore, to make them
98 // easy to recognize.
99
100 // The `beforeExpr` property is used to disambiguate between regular
101 // expressions and divisions. It is set on all token types that can
102 // be followed by an expression (thus, a slash after them would be a
103 // regular expression).
104 //
105 // The `startsExpr` property is used to check if the token ends a
106 // `yield` expression. It is set on all token types that either can
107 // directly start an expression (like a quotation mark) or can
108 // continue an expression (like the body of a string).
109 //
110 // `isLoop` marks a keyword as starting a loop, which is important
111 // to know when parsing a label, in order to allow or disallow
112 // continue jumps to that label.
113
114 var TokenType = function TokenType(label, conf) {
115 if ( conf === void 0 ) conf = {};
116
117 this.label = label;
118 this.keyword = conf.keyword;
119 this.beforeExpr = !!conf.beforeExpr;
120 this.startsExpr = !!conf.startsExpr;
121 this.isLoop = !!conf.isLoop;
122 this.isAssign = !!conf.isAssign;
123 this.prefix = !!conf.prefix;
124 this.postfix = !!conf.postfix;
125 this.binop = conf.binop || null;
126 this.updateContext = null;
127 };
128
129 function binop(name, prec) {
130 return new TokenType(name, {beforeExpr: true, binop: prec})
131 }
132 var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
133
134 // Map keyword names to token types.
135
136 var keywords = {};
137
138 // Succinct definitions of keyword token types
139 function kw(name, options) {
140 if ( options === void 0 ) options = {};
141
142 options.keyword = name;
143 return keywords[name] = new TokenType(name, options)
144 }
145
146 var types$1 = {
147 num: new TokenType("num", startsExpr),
148 regexp: new TokenType("regexp", startsExpr),
149 string: new TokenType("string", startsExpr),
150 name: new TokenType("name", startsExpr),
151 privateId: new TokenType("privateId", startsExpr),
152 eof: new TokenType("eof"),
153
154 // Punctuation token types.
155 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
156 bracketR: new TokenType("]"),
157 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
158 braceR: new TokenType("}"),
159 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
160 parenR: new TokenType(")"),
161 comma: new TokenType(",", beforeExpr),
162 semi: new TokenType(";", beforeExpr),
163 colon: new TokenType(":", beforeExpr),
164 dot: new TokenType("."),
165 question: new TokenType("?", beforeExpr),
166 questionDot: new TokenType("?."),
167 arrow: new TokenType("=>", beforeExpr),
168 template: new TokenType("template"),
169 invalidTemplate: new TokenType("invalidTemplate"),
170 ellipsis: new TokenType("...", beforeExpr),
171 backQuote: new TokenType("`", startsExpr),
172 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
173
174 // Operators. These carry several kinds of properties to help the
175 // parser use them properly (the presence of these properties is
176 // what categorizes them as operators).
177 //
178 // `binop`, when present, specifies that this operator is a binary
179 // operator, and will refer to its precedence.
180 //
181 // `prefix` and `postfix` mark the operator as a prefix or postfix
182 // unary operator.
183 //
184 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
185 // binary operators with a very low precedence, that should result
186 // in AssignmentExpression nodes.
187
188 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
189 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
190 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
191 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
192 logicalOR: binop("||", 1),
193 logicalAND: binop("&&", 2),
194 bitwiseOR: binop("|", 3),
195 bitwiseXOR: binop("^", 4),
196 bitwiseAND: binop("&", 5),
197 equality: binop("==/!=/===/!==", 6),
198 relational: binop("</>/<=/>=", 7),
199 bitShift: binop("<</>>/>>>", 8),
200 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
201 modulo: binop("%", 10),
202 star: binop("*", 10),
203 slash: binop("/", 10),
204 starstar: new TokenType("**", {beforeExpr: true}),
205 coalesce: binop("??", 1),
206
207 // Keyword token types.
208 _break: kw("break"),
209 _case: kw("case", beforeExpr),
210 _catch: kw("catch"),
211 _continue: kw("continue"),
212 _debugger: kw("debugger"),
213 _default: kw("default", beforeExpr),
214 _do: kw("do", {isLoop: true, beforeExpr: true}),
215 _else: kw("else", beforeExpr),
216 _finally: kw("finally"),
217 _for: kw("for", {isLoop: true}),
218 _function: kw("function", startsExpr),
219 _if: kw("if"),
220 _return: kw("return", beforeExpr),
221 _switch: kw("switch"),
222 _throw: kw("throw", beforeExpr),
223 _try: kw("try"),
224 _var: kw("var"),
225 _const: kw("const"),
226 _while: kw("while", {isLoop: true}),
227 _with: kw("with"),
228 _new: kw("new", {beforeExpr: true, startsExpr: true}),
229 _this: kw("this", startsExpr),
230 _super: kw("super", startsExpr),
231 _class: kw("class", startsExpr),
232 _extends: kw("extends", beforeExpr),
233 _export: kw("export"),
234 _import: kw("import", startsExpr),
235 _null: kw("null", startsExpr),
236 _true: kw("true", startsExpr),
237 _false: kw("false", startsExpr),
238 _in: kw("in", {beforeExpr: true, binop: 7}),
239 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
240 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
241 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
242 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
243 };
244
245 // Matches a whole line break (where CRLF is considered a single
246 // line break). Used to count lines.
247
248 var lineBreak = /\r\n?|\n|\u2028|\u2029/;
249 var lineBreakG = new RegExp(lineBreak.source, "g");
250
251 function isNewLine(code) {
252 return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
253 }
254
255 function nextLineBreak(code, from, end) {
256 if ( end === void 0 ) end = code.length;
257
258 for (var i = from; i < end; i++) {
259 var next = code.charCodeAt(i);
260 if (isNewLine(next))
261 { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }
262 }
263 return -1
264 }
265
266 var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
267
268 var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
269
270 var ref = Object.prototype;
271 var hasOwnProperty = ref.hasOwnProperty;
272 var toString = ref.toString;
273
274 var hasOwn = Object.hasOwn || (function (obj, propName) { return (
275 hasOwnProperty.call(obj, propName)
276 ); });
277
278 var isArray = Array.isArray || (function (obj) { return (
279 toString.call(obj) === "[object Array]"
280 ); });
281
282 var regexpCache = Object.create(null);
283
284 function wordsRegexp(words) {
285 return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"))
286 }
287
288 function codePointToString(code) {
289 // UTF-16 Decoding
290 if (code <= 0xFFFF) { return String.fromCharCode(code) }
291 code -= 0x10000;
292 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
293 }
294
295 var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
296
297 // These are used when `options.locations` is on, for the
298 // `startLoc` and `endLoc` properties.
299
300 var Position = function Position(line, col) {
301 this.line = line;
302 this.column = col;
303 };
304
305 Position.prototype.offset = function offset (n) {
306 return new Position(this.line, this.column + n)
307 };
308
309 var SourceLocation = function SourceLocation(p, start, end) {
310 this.start = start;
311 this.end = end;
312 if (p.sourceFile !== null) { this.source = p.sourceFile; }
313 };
314
315 // The `getLineInfo` function is mostly useful when the
316 // `locations` option is off (for performance reasons) and you
317 // want to find the line/column position for a given character
318 // offset. `input` should be the code string that the offset refers
319 // into.
320
321 function getLineInfo(input, offset) {
322 for (var line = 1, cur = 0;;) {
323 var nextBreak = nextLineBreak(input, cur, offset);
324 if (nextBreak < 0) { return new Position(line, offset - cur) }
325 ++line;
326 cur = nextBreak;
327 }
328 }
329
330 // A second argument must be given to configure the parser process.
331 // These options are recognized (only `ecmaVersion` is required):
332
333 var defaultOptions = {
334 // `ecmaVersion` indicates the ECMAScript version to parse. Must be
335 // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10
336 // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"`
337 // (the latest version the library supports). This influences
338 // support for strict mode, the set of reserved words, and support
339 // for new syntax features.
340 ecmaVersion: null,
341 // `sourceType` indicates the mode the code should be parsed in.
342 // Can be either `"script"` or `"module"`. This influences global
343 // strict mode and parsing of `import` and `export` declarations.
344 sourceType: "script",
345 // `onInsertedSemicolon` can be a callback that will be called when
346 // a semicolon is automatically inserted. It will be passed the
347 // position of the inserted semicolon as an offset, and if
348 // `locations` is enabled, it is given the location as a `{line,
349 // column}` object as second argument.
350 onInsertedSemicolon: null,
351 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
352 // trailing commas.
353 onTrailingComma: null,
354 // By default, reserved words are only enforced if ecmaVersion >= 5.
355 // Set `allowReserved` to a boolean value to explicitly turn this on
356 // an off. When this option has the value "never", reserved words
357 // and keywords can also not be used as property names.
358 allowReserved: null,
359 // When enabled, a return at the top level is not considered an
360 // error.
361 allowReturnOutsideFunction: false,
362 // When enabled, import/export statements are not constrained to
363 // appearing at the top of the program, and an import.meta expression
364 // in a script isn't considered an error.
365 allowImportExportEverywhere: false,
366 // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.
367 // When enabled, await identifiers are allowed to appear at the top-level scope,
368 // but they are still not allowed in non-async functions.
369 allowAwaitOutsideFunction: null,
370 // When enabled, super identifiers are not constrained to
371 // appearing in methods and do not raise an error when they appear elsewhere.
372 allowSuperOutsideMethod: null,
373 // When enabled, hashbang directive in the beginning of file is
374 // allowed and treated as a line comment. Enabled by default when
375 // `ecmaVersion` >= 2023.
376 allowHashBang: false,
377 // By default, the parser will verify that private properties are
378 // only used in places where they are valid and have been declared.
379 // Set this to false to turn such checks off.
380 checkPrivateFields: true,
381 // When `locations` is on, `loc` properties holding objects with
382 // `start` and `end` properties in `{line, column}` form (with
383 // line being 1-based and column 0-based) will be attached to the
384 // nodes.
385 locations: false,
386 // A function can be passed as `onToken` option, which will
387 // cause Acorn to call that function with object in the same
388 // format as tokens returned from `tokenizer().getToken()`. Note
389 // that you are not allowed to call the parser from the
390 // callback—that will corrupt its internal state.
391 onToken: null,
392 // A function can be passed as `onComment` option, which will
393 // cause Acorn to call that function with `(block, text, start,
394 // end)` parameters whenever a comment is skipped. `block` is a
395 // boolean indicating whether this is a block (`/* */`) comment,
396 // `text` is the content of the comment, and `start` and `end` are
397 // character offsets that denote the start and end of the comment.
398 // When the `locations` option is on, two more parameters are
399 // passed, the full `{line, column}` locations of the start and
400 // end of the comments. Note that you are not allowed to call the
401 // parser from the callback—that will corrupt its internal state.
402 // When this option has an array as value, objects representing the
403 // comments are pushed to it.
404 onComment: null,
405 // Nodes have their start and end characters offsets recorded in
406 // `start` and `end` properties (directly on the node, rather than
407 // the `loc` object, which holds line/column data. To also add a
408 // [semi-standardized][range] `range` property holding a `[start,
409 // end]` array with the same numbers, set the `ranges` option to
410 // `true`.
411 //
412 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
413 ranges: false,
414 // It is possible to parse multiple files into a single AST by
415 // passing the tree produced by parsing the first file as
416 // `program` option in subsequent parses. This will add the
417 // toplevel forms of the parsed file to the `Program` (top) node
418 // of an existing parse tree.
419 program: null,
420 // When `locations` is on, you can pass this to record the source
421 // file in every node's `loc` object.
422 sourceFile: null,
423 // This value, if given, is stored in every node, whether
424 // `locations` is on or off.
425 directSourceFile: null,
426 // When enabled, parenthesized expressions are represented by
427 // (non-standard) ParenthesizedExpression nodes
428 preserveParens: false
429 };
430
431 // Interpret and default an options object
432
433 var warnedAboutEcmaVersion = false;
434
435 function getOptions(opts) {
436 var options = {};
437
438 for (var opt in defaultOptions)
439 { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }
440
441 if (options.ecmaVersion === "latest") {
442 options.ecmaVersion = 1e8;
443 } else if (options.ecmaVersion == null) {
444 if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) {
445 warnedAboutEcmaVersion = true;
446 console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.");
447 }
448 options.ecmaVersion = 11;
449 } else if (options.ecmaVersion >= 2015) {
450 options.ecmaVersion -= 2009;
451 }
452
453 if (options.allowReserved == null)
454 { options.allowReserved = options.ecmaVersion < 5; }
455
456 if (!opts || opts.allowHashBang == null)
457 { options.allowHashBang = options.ecmaVersion >= 14; }
458
459 if (isArray(options.onToken)) {
460 var tokens = options.onToken;
461 options.onToken = function (token) { return tokens.push(token); };
462 }
463 if (isArray(options.onComment))
464 { options.onComment = pushComment(options, options.onComment); }
465
466 return options
467 }
468
469 function pushComment(options, array) {
470 return function(block, text, start, end, startLoc, endLoc) {
471 var comment = {
472 type: block ? "Block" : "Line",
473 value: text,
474 start: start,
475 end: end
476 };
477 if (options.locations)
478 { comment.loc = new SourceLocation(this, startLoc, endLoc); }
479 if (options.ranges)
480 { comment.range = [start, end]; }
481 array.push(comment);
482 }
483 }
484
485 // Each scope gets a bitset that may contain these flags
486 var
487 SCOPE_TOP = 1,
488 SCOPE_FUNCTION = 2,
489 SCOPE_ASYNC = 4,
490 SCOPE_GENERATOR = 8,
491 SCOPE_ARROW = 16,
492 SCOPE_SIMPLE_CATCH = 32,
493 SCOPE_SUPER = 64,
494 SCOPE_DIRECT_SUPER = 128,
495 SCOPE_CLASS_STATIC_BLOCK = 256,
496 SCOPE_CLASS_FIELD_INIT = 512,
497 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK;
498
499 function functionFlags(async, generator) {
500 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
501 }
502
503 // Used in checkLVal* and declareName to determine the type of a binding
504 var
505 BIND_NONE = 0, // Not a binding
506 BIND_VAR = 1, // Var-style binding
507 BIND_LEXICAL = 2, // Let- or const-style binding
508 BIND_FUNCTION = 3, // Function declaration
509 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
510 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
511
512 var Parser = function Parser(options, input, startPos) {
513 this.options = options = getOptions(options);
514 this.sourceFile = options.sourceFile;
515 this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
516 var reserved = "";
517 if (options.allowReserved !== true) {
518 reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];
519 if (options.sourceType === "module") { reserved += " await"; }
520 }
521 this.reservedWords = wordsRegexp(reserved);
522 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
523 this.reservedWordsStrict = wordsRegexp(reservedStrict);
524 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
525 this.input = String(input);
526
527 // Used to signal to callers of `readWord1` whether the word
528 // contained any escape sequences. This is needed because words with
529 // escape sequences must not be interpreted as keywords.
530 this.containsEsc = false;
531
532 // Set up token state
533
534 // The current position of the tokenizer in the input.
535 if (startPos) {
536 this.pos = startPos;
537 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
538 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
539 } else {
540 this.pos = this.lineStart = 0;
541 this.curLine = 1;
542 }
543
544 // Properties of the current token:
545 // Its type
546 this.type = types$1.eof;
547 // For tokens that include more information than their type, the value
548 this.value = null;
549 // Its start and end offset
550 this.start = this.end = this.pos;
551 // And, if locations are used, the {line, column} object
552 // corresponding to those offsets
553 this.startLoc = this.endLoc = this.curPosition();
554
555 // Position information for the previous token
556 this.lastTokEndLoc = this.lastTokStartLoc = null;
557 this.lastTokStart = this.lastTokEnd = this.pos;
558
559 // The context stack is used to superficially track syntactic
560 // context to predict whether a regular expression is allowed in a
561 // given position.
562 this.context = this.initialContext();
563 this.exprAllowed = true;
564
565 // Figure out if it's a module code.
566 this.inModule = options.sourceType === "module";
567 this.strict = this.inModule || this.strictDirective(this.pos);
568
569 // Used to signify the start of a potential arrow function
570 this.potentialArrowAt = -1;
571 this.potentialArrowInForAwait = false;
572
573 // Positions to delayed-check that yield/await does not exist in default parameters.
574 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
575 // Labels in scope.
576 this.labels = [];
577 // Thus-far undefined exports.
578 this.undefinedExports = Object.create(null);
579
580 // If enabled, skip leading hashbang line.
581 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
582 { this.skipLineComment(2); }
583
584 // Scope tracking for duplicate variable names (see scope.js)
585 this.scopeStack = [];
586 this.enterScope(SCOPE_TOP);
587
588 // For RegExp validation
589 this.regexpState = null;
590
591 // The stack of private names.
592 // Each element has two properties: 'declared' and 'used'.
593 // When it exited from the outermost class definition, all used private names must be declared.
594 this.privateNameStack = [];
595 };
596
597 var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };
598
599 Parser.prototype.parse = function parse () {
600 var node = this.options.program || this.startNode();
601 this.nextToken();
602 return this.parseTopLevel(node)
603 };
604
605 prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
606
607 prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
608
609 prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
610
611 prototypeAccessors.canAwait.get = function () {
612 for (var i = this.scopeStack.length - 1; i >= 0; i--) {
613 var ref = this.scopeStack[i];
614 var flags = ref.flags;
615 if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT)) { return false }
616 if (flags & SCOPE_FUNCTION) { return (flags & SCOPE_ASYNC) > 0 }
617 }
618 return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
619 };
620
621 prototypeAccessors.allowSuper.get = function () {
622 var ref = this.currentThisScope();
623 var flags = ref.flags;
624 return (flags & SCOPE_SUPER) > 0 || this.options.allowSuperOutsideMethod
625 };
626
627 prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
628
629 prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
630
631 prototypeAccessors.allowNewDotTarget.get = function () {
632 for (var i = this.scopeStack.length - 1; i >= 0; i--) {
633 var ref = this.scopeStack[i];
634 var flags = ref.flags;
635 if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT) ||
636 ((flags & SCOPE_FUNCTION) && !(flags & SCOPE_ARROW))) { return true }
637 }
638 return false
639 };
640
641 prototypeAccessors.inClassStaticBlock.get = function () {
642 return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0
643 };
644
645 Parser.extend = function extend () {
646 var plugins = [], len = arguments.length;
647 while ( len-- ) plugins[ len ] = arguments[ len ];
648
649 var cls = this;
650 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
651 return cls
652 };
653
654 Parser.parse = function parse (input, options) {
655 return new this(options, input).parse()
656 };
657
658 Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
659 var parser = new this(options, input, pos);
660 parser.nextToken();
661 return parser.parseExpression()
662 };
663
664 Parser.tokenizer = function tokenizer (input, options) {
665 return new this(options, input)
666 };
667
668 Object.defineProperties( Parser.prototype, prototypeAccessors );
669
670 var pp$9 = Parser.prototype;
671
672 // ## Parser utilities
673
674 var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/;
675 pp$9.strictDirective = function(start) {
676 if (this.options.ecmaVersion < 5) { return false }
677 for (;;) {
678 // Try to find string literal.
679 skipWhiteSpace.lastIndex = start;
680 start += skipWhiteSpace.exec(this.input)[0].length;
681 var match = literal.exec(this.input.slice(start));
682 if (!match) { return false }
683 if ((match[1] || match[2]) === "use strict") {
684 skipWhiteSpace.lastIndex = start + match[0].length;
685 var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
686 var next = this.input.charAt(end);
687 return next === ";" || next === "}" ||
688 (lineBreak.test(spaceAfter[0]) &&
689 !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
690 }
691 start += match[0].length;
692
693 // Skip semicolon, if any.
694 skipWhiteSpace.lastIndex = start;
695 start += skipWhiteSpace.exec(this.input)[0].length;
696 if (this.input[start] === ";")
697 { start++; }
698 }
699 };
700
701 // Predicate that tests whether the next token is of the given
702 // type, and if yes, consumes it as a side effect.
703
704 pp$9.eat = function(type) {
705 if (this.type === type) {
706 this.next();
707 return true
708 } else {
709 return false
710 }
711 };
712
713 // Tests whether parsed token is a contextual keyword.
714
715 pp$9.isContextual = function(name) {
716 return this.type === types$1.name && this.value === name && !this.containsEsc
717 };
718
719 // Consumes contextual keyword if possible.
720
721 pp$9.eatContextual = function(name) {
722 if (!this.isContextual(name)) { return false }
723 this.next();
724 return true
725 };
726
727 // Asserts that following token is given contextual keyword.
728
729 pp$9.expectContextual = function(name) {
730 if (!this.eatContextual(name)) { this.unexpected(); }
731 };
732
733 // Test whether a semicolon can be inserted at the current position.
734
735 pp$9.canInsertSemicolon = function() {
736 return this.type === types$1.eof ||
737 this.type === types$1.braceR ||
738 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
739 };
740
741 pp$9.insertSemicolon = function() {
742 if (this.canInsertSemicolon()) {
743 if (this.options.onInsertedSemicolon)
744 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
745 return true
746 }
747 };
748
749 // Consume a semicolon, or, failing that, see if we are allowed to
750 // pretend that there is a semicolon at this position.
751
752 pp$9.semicolon = function() {
753 if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }
754 };
755
756 pp$9.afterTrailingComma = function(tokType, notNext) {
757 if (this.type === tokType) {
758 if (this.options.onTrailingComma)
759 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
760 if (!notNext)
761 { this.next(); }
762 return true
763 }
764 };
765
766 // Expect a token of a given type. If found, consume it, otherwise,
767 // raise an unexpected token error.
768
769 pp$9.expect = function(type) {
770 this.eat(type) || this.unexpected();
771 };
772
773 // Raise an unexpected token error.
774
775 pp$9.unexpected = function(pos) {
776 this.raise(pos != null ? pos : this.start, "Unexpected token");
777 };
778
779 var DestructuringErrors = function DestructuringErrors() {
780 this.shorthandAssign =
781 this.trailingComma =
782 this.parenthesizedAssign =
783 this.parenthesizedBind =
784 this.doubleProto =
785 -1;
786 };
787
788 pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {
789 if (!refDestructuringErrors) { return }
790 if (refDestructuringErrors.trailingComma > -1)
791 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
792 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
793 if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); }
794 };
795
796 pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
797 if (!refDestructuringErrors) { return false }
798 var shorthandAssign = refDestructuringErrors.shorthandAssign;
799 var doubleProto = refDestructuringErrors.doubleProto;
800 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
801 if (shorthandAssign >= 0)
802 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
803 if (doubleProto >= 0)
804 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
805 };
806
807 pp$9.checkYieldAwaitInDefaultParams = function() {
808 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
809 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
810 if (this.awaitPos)
811 { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
812 };
813
814 pp$9.isSimpleAssignTarget = function(expr) {
815 if (expr.type === "ParenthesizedExpression")
816 { return this.isSimpleAssignTarget(expr.expression) }
817 return expr.type === "Identifier" || expr.type === "MemberExpression"
818 };
819
820 var pp$8 = Parser.prototype;
821
822 // ### Statement parsing
823
824 // Parse a program. Initializes the parser, reads any number of
825 // statements, and wraps them in a Program node. Optionally takes a
826 // `program` argument. If present, the statements will be appended
827 // to its body instead of creating a new node.
828
829 pp$8.parseTopLevel = function(node) {
830 var exports = Object.create(null);
831 if (!node.body) { node.body = []; }
832 while (this.type !== types$1.eof) {
833 var stmt = this.parseStatement(null, true, exports);
834 node.body.push(stmt);
835 }
836 if (this.inModule)
837 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
838 {
839 var name = list[i];
840
841 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
842 } }
843 this.adaptDirectivePrologue(node.body);
844 this.next();
845 node.sourceType = this.options.sourceType;
846 return this.finishNode(node, "Program")
847 };
848
849 var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
850
851 pp$8.isLet = function(context) {
852 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
853 skipWhiteSpace.lastIndex = this.pos;
854 var skip = skipWhiteSpace.exec(this.input);
855 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
856 // For ambiguous cases, determine if a LexicalDeclaration (or only a
857 // Statement) is allowed here. If context is not empty then only a Statement
858 // is allowed. However, `let [` is an explicit negative lookahead for
859 // ExpressionStatement, so special-case it first.
860 if (nextCh === 91 || nextCh === 92) { return true } // '[', '\'
861 if (context) { return false }
862
863 if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral
864 if (isIdentifierStart(nextCh, true)) {
865 var pos = next + 1;
866 while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
867 if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
868 var ident = this.input.slice(next, pos);
869 if (!keywordRelationalOperator.test(ident)) { return true }
870 }
871 return false
872 };
873
874 // check 'async [no LineTerminator here] function'
875 // - 'async /*foo*/ function' is OK.
876 // - 'async /*\n*/ function' is invalid.
877 pp$8.isAsyncFunction = function() {
878 if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
879 { return false }
880
881 skipWhiteSpace.lastIndex = this.pos;
882 var skip = skipWhiteSpace.exec(this.input);
883 var next = this.pos + skip[0].length, after;
884 return !lineBreak.test(this.input.slice(this.pos, next)) &&
885 this.input.slice(next, next + 8) === "function" &&
886 (next + 8 === this.input.length ||
887 !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
888 };
889
890 pp$8.isUsingKeyword = function(isAwaitUsing, isFor) {
891 if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using"))
892 { return false }
893
894 skipWhiteSpace.lastIndex = this.pos;
895 var skip = skipWhiteSpace.exec(this.input);
896 var next = this.pos + skip[0].length;
897
898 if (lineBreak.test(this.input.slice(this.pos, next))) { return false }
899
900 if (isAwaitUsing) {
901 var awaitEndPos = next + 5 /* await */, after;
902 if (this.input.slice(next, awaitEndPos) !== "using" ||
903 awaitEndPos === this.input.length ||
904 isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) ||
905 (after > 0xd7ff && after < 0xdc00)
906 ) { return false }
907
908 skipWhiteSpace.lastIndex = awaitEndPos;
909 var skipAfterUsing = skipWhiteSpace.exec(this.input);
910 if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false }
911 }
912
913 if (isFor) {
914 var ofEndPos = next + 2 /* of */, after$1;
915 if (this.input.slice(next, ofEndPos) === "of") {
916 if (ofEndPos === this.input.length ||
917 (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false }
918 }
919 }
920
921 var ch = this.input.charCodeAt(next);
922 return isIdentifierStart(ch, true) || ch === 92 // '\'
923 };
924
925 pp$8.isAwaitUsing = function(isFor) {
926 return this.isUsingKeyword(true, isFor)
927 };
928
929 pp$8.isUsing = function(isFor) {
930 return this.isUsingKeyword(false, isFor)
931 };
932
933 // Parse a single statement.
934 //
935 // If expecting a statement and finding a slash operator, parse a
936 // regular expression literal. This is to handle cases like
937 // `if (foo) /blah/.exec(foo)`, where looking at the previous token
938 // does not help.
939
940 pp$8.parseStatement = function(context, topLevel, exports) {
941 var starttype = this.type, node = this.startNode(), kind;
942
943 if (this.isLet(context)) {
944 starttype = types$1._var;
945 kind = "let";
946 }
947
948 // Most types of statements are recognized by the keyword they
949 // start with. Many are trivial to parse, some require a bit of
950 // complexity.
951
952 switch (starttype) {
953 case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
954 case types$1._debugger: return this.parseDebuggerStatement(node)
955 case types$1._do: return this.parseDoStatement(node)
956 case types$1._for: return this.parseForStatement(node)
957 case types$1._function:
958 // Function as sole body of either an if statement or a labeled statement
959 // works, but not when it is part of a labeled statement that is the sole
960 // body of an if statement.
961 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
962 return this.parseFunctionStatement(node, false, !context)
963 case types$1._class:
964 if (context) { this.unexpected(); }
965 return this.parseClass(node, true)
966 case types$1._if: return this.parseIfStatement(node)
967 case types$1._return: return this.parseReturnStatement(node)
968 case types$1._switch: return this.parseSwitchStatement(node)
969 case types$1._throw: return this.parseThrowStatement(node)
970 case types$1._try: return this.parseTryStatement(node)
971 case types$1._const: case types$1._var:
972 kind = kind || this.value;
973 if (context && kind !== "var") { this.unexpected(); }
974 return this.parseVarStatement(node, kind)
975 case types$1._while: return this.parseWhileStatement(node)
976 case types$1._with: return this.parseWithStatement(node)
977 case types$1.braceL: return this.parseBlock(true, node)
978 case types$1.semi: return this.parseEmptyStatement(node)
979 case types$1._export:
980 case types$1._import:
981 if (this.options.ecmaVersion > 10 && starttype === types$1._import) {
982 skipWhiteSpace.lastIndex = this.pos;
983 var skip = skipWhiteSpace.exec(this.input);
984 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
985 if (nextCh === 40 || nextCh === 46) // '(' or '.'
986 { return this.parseExpressionStatement(node, this.parseExpression()) }
987 }
988
989 if (!this.options.allowImportExportEverywhere) {
990 if (!topLevel)
991 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
992 if (!this.inModule)
993 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
994 }
995 return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)
996
997 // If the statement does not start with a statement keyword or a
998 // brace, it's an ExpressionStatement or LabeledStatement. We
999 // simply start parsing an expression, and afterwards, if the
1000 // next token is a colon and the expression was a simple
1001 // Identifier node, we switch to interpreting it as a label.
1002 default:
1003 if (this.isAsyncFunction()) {
1004 if (context) { this.unexpected(); }
1005 this.next();
1006 return this.parseFunctionStatement(node, true, !context)
1007 }
1008
1009 var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null;
1010 if (usingKind) {
1011 if (topLevel && this.options.sourceType === "script") {
1012 this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`");
1013 }
1014 if (usingKind === "await using") {
1015 if (!this.canAwait) {
1016 this.raise(this.start, "Await using cannot appear outside of async function");
1017 }
1018 this.next();
1019 }
1020 this.next();
1021 this.parseVar(node, false, usingKind);
1022 this.semicolon();
1023 return this.finishNode(node, "VariableDeclaration")
1024 }
1025
1026 var maybeName = this.value, expr = this.parseExpression();
1027 if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon))
1028 { return this.parseLabeledStatement(node, maybeName, expr, context) }
1029 else { return this.parseExpressionStatement(node, expr) }
1030 }
1031 };
1032
1033 pp$8.parseBreakContinueStatement = function(node, keyword) {
1034 var isBreak = keyword === "break";
1035 this.next();
1036 if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }
1037 else if (this.type !== types$1.name) { this.unexpected(); }
1038 else {
1039 node.label = this.parseIdent();
1040 this.semicolon();
1041 }
1042
1043 // Verify that there is an actual destination to break or
1044 // continue to.
1045 var i = 0;
1046 for (; i < this.labels.length; ++i) {
1047 var lab = this.labels[i];
1048 if (node.label == null || lab.name === node.label.name) {
1049 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
1050 if (node.label && isBreak) { break }
1051 }
1052 }
1053 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
1054 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
1055 };
1056
1057 pp$8.parseDebuggerStatement = function(node) {
1058 this.next();
1059 this.semicolon();
1060 return this.finishNode(node, "DebuggerStatement")
1061 };
1062
1063 pp$8.parseDoStatement = function(node) {
1064 this.next();
1065 this.labels.push(loopLabel);
1066 node.body = this.parseStatement("do");
1067 this.labels.pop();
1068 this.expect(types$1._while);
1069 node.test = this.parseParenExpression();
1070 if (this.options.ecmaVersion >= 6)
1071 { this.eat(types$1.semi); }
1072 else
1073 { this.semicolon(); }
1074 return this.finishNode(node, "DoWhileStatement")
1075 };
1076
1077 // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
1078 // loop is non-trivial. Basically, we have to parse the init `var`
1079 // statement or expression, disallowing the `in` operator (see
1080 // the second parameter to `parseExpression`), and then check
1081 // whether the next token is `in` or `of`. When there is no init
1082 // part (semicolon immediately after the opening parenthesis), it
1083 // is a regular `for` loop.
1084
1085 pp$8.parseForStatement = function(node) {
1086 this.next();
1087 var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
1088 this.labels.push(loopLabel);
1089 this.enterScope(0);
1090 this.expect(types$1.parenL);
1091 if (this.type === types$1.semi) {
1092 if (awaitAt > -1) { this.unexpected(awaitAt); }
1093 return this.parseFor(node, null)
1094 }
1095 var isLet = this.isLet();
1096 if (this.type === types$1._var || this.type === types$1._const || isLet) {
1097 var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
1098 this.next();
1099 this.parseVar(init$1, true, kind);
1100 this.finishNode(init$1, "VariableDeclaration");
1101 return this.parseForAfterInit(node, init$1, awaitAt)
1102 }
1103 var startsWithLet = this.isContextual("let"), isForOf = false;
1104
1105 var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null;
1106 if (usingKind) {
1107 var init$2 = this.startNode();
1108 this.next();
1109 if (usingKind === "await using") { this.next(); }
1110 this.parseVar(init$2, true, usingKind);
1111 this.finishNode(init$2, "VariableDeclaration");
1112 return this.parseForAfterInit(node, init$2, awaitAt)
1113 }
1114 var containsEsc = this.containsEsc;
1115 var refDestructuringErrors = new DestructuringErrors;
1116 var initPos = this.start;
1117 var init = awaitAt > -1
1118 ? this.parseExprSubscripts(refDestructuringErrors, "await")
1119 : this.parseExpression(true, refDestructuringErrors);
1120 if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
1121 if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt)
1122 if (this.type === types$1._in) { this.unexpected(awaitAt); }
1123 node.await = true;
1124 } else if (isForOf && this.options.ecmaVersion >= 8) {
1125 if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); }
1126 else if (this.options.ecmaVersion >= 9) { node.await = false; }
1127 }
1128 if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); }
1129 this.toAssignable(init, false, refDestructuringErrors);
1130 this.checkLValPattern(init);
1131 return this.parseForIn(node, init)
1132 } else {
1133 this.checkExpressionErrors(refDestructuringErrors, true);
1134 }
1135 if (awaitAt > -1) { this.unexpected(awaitAt); }
1136 return this.parseFor(node, init)
1137 };
1138
1139 // Helper method to parse for loop after variable initialization
1140 pp$8.parseForAfterInit = function(node, init, awaitAt) {
1141 if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) {
1142 if (this.options.ecmaVersion >= 9) {
1143 if (this.type === types$1._in) {
1144 if (awaitAt > -1) { this.unexpected(awaitAt); }
1145 } else { node.await = awaitAt > -1; }
1146 }
1147 return this.parseForIn(node, init)
1148 }
1149 if (awaitAt > -1) { this.unexpected(awaitAt); }
1150 return this.parseFor(node, init)
1151 };
1152
1153 pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {
1154 this.next();
1155 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
1156 };
1157
1158 pp$8.parseIfStatement = function(node) {
1159 this.next();
1160 node.test = this.parseParenExpression();
1161 // allow function declarations in branches, but only in non-strict mode
1162 node.consequent = this.parseStatement("if");
1163 node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
1164 return this.finishNode(node, "IfStatement")
1165 };
1166
1167 pp$8.parseReturnStatement = function(node) {
1168 if (!this.inFunction && !this.options.allowReturnOutsideFunction)
1169 { this.raise(this.start, "'return' outside of function"); }
1170 this.next();
1171
1172 // In `return` (and `break`/`continue`), the keywords with
1173 // optional arguments, we eagerly look for a semicolon or the
1174 // possibility to insert one.
1175
1176 if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }
1177 else { node.argument = this.parseExpression(); this.semicolon(); }
1178 return this.finishNode(node, "ReturnStatement")
1179 };
1180
1181 pp$8.parseSwitchStatement = function(node) {
1182 this.next();
1183 node.discriminant = this.parseParenExpression();
1184 node.cases = [];
1185 this.expect(types$1.braceL);
1186 this.labels.push(switchLabel);
1187 this.enterScope(0);
1188
1189 // Statements under must be grouped (by label) in SwitchCase
1190 // nodes. `cur` is used to keep the node that we are currently
1191 // adding statements to.
1192
1193 var cur;
1194 for (var sawDefault = false; this.type !== types$1.braceR;) {
1195 if (this.type === types$1._case || this.type === types$1._default) {
1196 var isCase = this.type === types$1._case;
1197 if (cur) { this.finishNode(cur, "SwitchCase"); }
1198 node.cases.push(cur = this.startNode());
1199 cur.consequent = [];
1200 this.next();
1201 if (isCase) {
1202 cur.test = this.parseExpression();
1203 } else {
1204 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
1205 sawDefault = true;
1206 cur.test = null;
1207 }
1208 this.expect(types$1.colon);
1209 } else {
1210 if (!cur) { this.unexpected(); }
1211 cur.consequent.push(this.parseStatement(null));
1212 }
1213 }
1214 this.exitScope();
1215 if (cur) { this.finishNode(cur, "SwitchCase"); }
1216 this.next(); // Closing brace
1217 this.labels.pop();
1218 return this.finishNode(node, "SwitchStatement")
1219 };
1220
1221 pp$8.parseThrowStatement = function(node) {
1222 this.next();
1223 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
1224 { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
1225 node.argument = this.parseExpression();
1226 this.semicolon();
1227 return this.finishNode(node, "ThrowStatement")
1228 };
1229
1230 // Reused empty array added for node fields that are always empty.
1231
1232 var empty$1 = [];
1233
1234 pp$8.parseCatchClauseParam = function() {
1235 var param = this.parseBindingAtom();
1236 var simple = param.type === "Identifier";
1237 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
1238 this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
1239 this.expect(types$1.parenR);
1240
1241 return param
1242 };
1243
1244 pp$8.parseTryStatement = function(node) {
1245 this.next();
1246 node.block = this.parseBlock();
1247 node.handler = null;
1248 if (this.type === types$1._catch) {
1249 var clause = this.startNode();
1250 this.next();
1251 if (this.eat(types$1.parenL)) {
1252 clause.param = this.parseCatchClauseParam();
1253 } else {
1254 if (this.options.ecmaVersion < 10) { this.unexpected(); }
1255 clause.param = null;
1256 this.enterScope(0);
1257 }
1258 clause.body = this.parseBlock(false);
1259 this.exitScope();
1260 node.handler = this.finishNode(clause, "CatchClause");
1261 }
1262 node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;
1263 if (!node.handler && !node.finalizer)
1264 { this.raise(node.start, "Missing catch or finally clause"); }
1265 return this.finishNode(node, "TryStatement")
1266 };
1267
1268 pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) {
1269 this.next();
1270 this.parseVar(node, false, kind, allowMissingInitializer);
1271 this.semicolon();
1272 return this.finishNode(node, "VariableDeclaration")
1273 };
1274
1275 pp$8.parseWhileStatement = function(node) {
1276 this.next();
1277 node.test = this.parseParenExpression();
1278 this.labels.push(loopLabel);
1279 node.body = this.parseStatement("while");
1280 this.labels.pop();
1281 return this.finishNode(node, "WhileStatement")
1282 };
1283
1284 pp$8.parseWithStatement = function(node) {
1285 if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
1286 this.next();
1287 node.object = this.parseParenExpression();
1288 node.body = this.parseStatement("with");
1289 return this.finishNode(node, "WithStatement")
1290 };
1291
1292 pp$8.parseEmptyStatement = function(node) {
1293 this.next();
1294 return this.finishNode(node, "EmptyStatement")
1295 };
1296
1297 pp$8.parseLabeledStatement = function(node, maybeName, expr, context) {
1298 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
1299 {
1300 var label = list[i$1];
1301
1302 if (label.name === maybeName)
1303 { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
1304 } }
1305 var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null;
1306 for (var i = this.labels.length - 1; i >= 0; i--) {
1307 var label$1 = this.labels[i];
1308 if (label$1.statementStart === node.start) {
1309 // Update information about previous labels on this node
1310 label$1.statementStart = this.start;
1311 label$1.kind = kind;
1312 } else { break }
1313 }
1314 this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
1315 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
1316 this.labels.pop();
1317 node.label = expr;
1318 return this.finishNode(node, "LabeledStatement")
1319 };
1320
1321 pp$8.parseExpressionStatement = function(node, expr) {
1322 node.expression = expr;
1323 this.semicolon();
1324 return this.finishNode(node, "ExpressionStatement")
1325 };
1326
1327 // Parse a semicolon-enclosed block of statements, handling `"use
1328 // strict"` declarations when `allowStrict` is true (used for
1329 // function bodies).
1330
1331 pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {
1332 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
1333 if ( node === void 0 ) node = this.startNode();
1334
1335 node.body = [];
1336 this.expect(types$1.braceL);
1337 if (createNewLexicalScope) { this.enterScope(0); }
1338 while (this.type !== types$1.braceR) {
1339 var stmt = this.parseStatement(null);
1340 node.body.push(stmt);
1341 }
1342 if (exitStrict) { this.strict = false; }
1343 this.next();
1344 if (createNewLexicalScope) { this.exitScope(); }
1345 return this.finishNode(node, "BlockStatement")
1346 };
1347
1348 // Parse a regular `for` loop. The disambiguation code in
1349 // `parseStatement` will already have parsed the init statement or
1350 // expression.
1351
1352 pp$8.parseFor = function(node, init) {
1353 node.init = init;
1354 this.expect(types$1.semi);
1355 node.test = this.type === types$1.semi ? null : this.parseExpression();
1356 this.expect(types$1.semi);
1357 node.update = this.type === types$1.parenR ? null : this.parseExpression();
1358 this.expect(types$1.parenR);
1359 node.body = this.parseStatement("for");
1360 this.exitScope();
1361 this.labels.pop();
1362 return this.finishNode(node, "ForStatement")
1363 };
1364
1365 // Parse a `for`/`in` and `for`/`of` loop, which are almost
1366 // same from parser's perspective.
1367
1368 pp$8.parseForIn = function(node, init) {
1369 var isForIn = this.type === types$1._in;
1370 this.next();
1371
1372 if (
1373 init.type === "VariableDeclaration" &&
1374 init.declarations[0].init != null &&
1375 (
1376 !isForIn ||
1377 this.options.ecmaVersion < 8 ||
1378 this.strict ||
1379 init.kind !== "var" ||
1380 init.declarations[0].id.type !== "Identifier"
1381 )
1382 ) {
1383 this.raise(
1384 init.start,
1385 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
1386 );
1387 }
1388 node.left = init;
1389 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
1390 this.expect(types$1.parenR);
1391 node.body = this.parseStatement("for");
1392 this.exitScope();
1393 this.labels.pop();
1394 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
1395 };
1396
1397 // Parse a list of variable declarations.
1398
1399 pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) {
1400 node.declarations = [];
1401 node.kind = kind;
1402 for (;;) {
1403 var decl = this.startNode();
1404 this.parseVarId(decl, kind);
1405 if (this.eat(types$1.eq)) {
1406 decl.init = this.parseMaybeAssign(isFor);
1407 } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
1408 this.unexpected();
1409 } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) {
1410 this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration"));
1411 } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) {
1412 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
1413 } else {
1414 decl.init = null;
1415 }
1416 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
1417 if (!this.eat(types$1.comma)) { break }
1418 }
1419 return node
1420 };
1421
1422 pp$8.parseVarId = function(decl, kind) {
1423 decl.id = kind === "using" || kind === "await using"
1424 ? this.parseIdent()
1425 : this.parseBindingAtom();
1426
1427 this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
1428 };
1429
1430 var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
1431
1432 // Parse a function declaration or literal (depending on the
1433 // `statement & FUNC_STATEMENT`).
1434
1435 // Remove `allowExpressionBody` for 7.0.0, as it is only called with false
1436 pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {
1437 this.initFunction(node);
1438 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
1439 if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))
1440 { this.unexpected(); }
1441 node.generator = this.eat(types$1.star);
1442 }
1443 if (this.options.ecmaVersion >= 8)
1444 { node.async = !!isAsync; }
1445
1446 if (statement & FUNC_STATEMENT) {
1447 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();
1448 if (node.id && !(statement & FUNC_HANGING_STATEMENT))
1449 // If it is a regular function declaration in sloppy mode, then it is
1450 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
1451 // mode depends on properties of the current scope (see
1452 // treatFunctionsAsVar).
1453 { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
1454 }
1455
1456 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
1457 this.yieldPos = 0;
1458 this.awaitPos = 0;
1459 this.awaitIdentPos = 0;
1460 this.enterScope(functionFlags(node.async, node.generator));
1461
1462 if (!(statement & FUNC_STATEMENT))
1463 { node.id = this.type === types$1.name ? this.parseIdent() : null; }
1464
1465 this.parseFunctionParams(node);
1466 this.parseFunctionBody(node, allowExpressionBody, false, forInit);
1467
1468 this.yieldPos = oldYieldPos;
1469 this.awaitPos = oldAwaitPos;
1470 this.awaitIdentPos = oldAwaitIdentPos;
1471 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
1472 };
1473
1474 pp$8.parseFunctionParams = function(node) {
1475 this.expect(types$1.parenL);
1476 node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
1477 this.checkYieldAwaitInDefaultParams();
1478 };
1479
1480 // Parse a class declaration or literal (depending on the
1481 // `isStatement` parameter).
1482
1483 pp$8.parseClass = function(node, isStatement) {
1484 this.next();
1485
1486 // ecma-262 14.6 Class Definitions
1487 // A class definition is always strict mode code.
1488 var oldStrict = this.strict;
1489 this.strict = true;
1490
1491 this.parseClassId(node, isStatement);
1492 this.parseClassSuper(node);
1493 var privateNameMap = this.enterClassBody();
1494 var classBody = this.startNode();
1495 var hadConstructor = false;
1496 classBody.body = [];
1497 this.expect(types$1.braceL);
1498 while (this.type !== types$1.braceR) {
1499 var element = this.parseClassElement(node.superClass !== null);
1500 if (element) {
1501 classBody.body.push(element);
1502 if (element.type === "MethodDefinition" && element.kind === "constructor") {
1503 if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); }
1504 hadConstructor = true;
1505 } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
1506 this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
1507 }
1508 }
1509 }
1510 this.strict = oldStrict;
1511 this.next();
1512 node.body = this.finishNode(classBody, "ClassBody");
1513 this.exitClassBody();
1514 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
1515 };
1516
1517 pp$8.parseClassElement = function(constructorAllowsSuper) {
1518 if (this.eat(types$1.semi)) { return null }
1519
1520 var ecmaVersion = this.options.ecmaVersion;
1521 var node = this.startNode();
1522 var keyName = "";
1523 var isGenerator = false;
1524 var isAsync = false;
1525 var kind = "method";
1526 var isStatic = false;
1527
1528 if (this.eatContextual("static")) {
1529 // Parse static init block
1530 if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {
1531 this.parseClassStaticBlock(node);
1532 return node
1533 }
1534 if (this.isClassElementNameStart() || this.type === types$1.star) {
1535 isStatic = true;
1536 } else {
1537 keyName = "static";
1538 }
1539 }
1540 node.static = isStatic;
1541 if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
1542 if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {
1543 isAsync = true;
1544 } else {
1545 keyName = "async";
1546 }
1547 }
1548 if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {
1549 isGenerator = true;
1550 }
1551 if (!keyName && !isAsync && !isGenerator) {
1552 var lastValue = this.value;
1553 if (this.eatContextual("get") || this.eatContextual("set")) {
1554 if (this.isClassElementNameStart()) {
1555 kind = lastValue;
1556 } else {
1557 keyName = lastValue;
1558 }
1559 }
1560 }
1561
1562 // Parse element name
1563 if (keyName) {
1564 // 'async', 'get', 'set', or 'static' were not a keyword contextually.
1565 // The last token is any of those. Make it the element name.
1566 node.computed = false;
1567 node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
1568 node.key.name = keyName;
1569 this.finishNode(node.key, "Identifier");
1570 } else {
1571 this.parseClassElementName(node);
1572 }
1573
1574 // Parse element value
1575 if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) {
1576 var isConstructor = !node.static && checkKeyName(node, "constructor");
1577 var allowsDirectSuper = isConstructor && constructorAllowsSuper;
1578 // Couldn't move this check into the 'parseClassMethod' method for backward compatibility.
1579 if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
1580 node.kind = isConstructor ? "constructor" : kind;
1581 this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
1582 } else {
1583 this.parseClassField(node);
1584 }
1585
1586 return node
1587 };
1588
1589 pp$8.isClassElementNameStart = function() {
1590 return (
1591 this.type === types$1.name ||
1592 this.type === types$1.privateId ||
1593 this.type === types$1.num ||
1594 this.type === types$1.string ||
1595 this.type === types$1.bracketL ||
1596 this.type.keyword
1597 )
1598 };
1599
1600 pp$8.parseClassElementName = function(element) {
1601 if (this.type === types$1.privateId) {
1602 if (this.value === "constructor") {
1603 this.raise(this.start, "Classes can't have an element named '#constructor'");
1604 }
1605 element.computed = false;
1606 element.key = this.parsePrivateIdent();
1607 } else {
1608 this.parsePropertyName(element);
1609 }
1610 };
1611
1612 pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
1613 // Check key and flags
1614 var key = method.key;
1615 if (method.kind === "constructor") {
1616 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
1617 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
1618 } else if (method.static && checkKeyName(method, "prototype")) {
1619 this.raise(key.start, "Classes may not have a static property named prototype");
1620 }
1621
1622 // Parse value
1623 var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
1624
1625 // Check value
1626 if (method.kind === "get" && value.params.length !== 0)
1627 { this.raiseRecoverable(value.start, "getter should have no params"); }
1628 if (method.kind === "set" && value.params.length !== 1)
1629 { this.raiseRecoverable(value.start, "setter should have exactly one param"); }
1630 if (method.kind === "set" && value.params[0].type === "RestElement")
1631 { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
1632
1633 return this.finishNode(method, "MethodDefinition")
1634 };
1635
1636 pp$8.parseClassField = function(field) {
1637 if (checkKeyName(field, "constructor")) {
1638 this.raise(field.key.start, "Classes can't have a field named 'constructor'");
1639 } else if (field.static && checkKeyName(field, "prototype")) {
1640 this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
1641 }
1642
1643 if (this.eat(types$1.eq)) {
1644 // To raise SyntaxError if 'arguments' exists in the initializer.
1645 this.enterScope(SCOPE_CLASS_FIELD_INIT | SCOPE_SUPER);
1646 field.value = this.parseMaybeAssign();
1647 this.exitScope();
1648 } else {
1649 field.value = null;
1650 }
1651 this.semicolon();
1652
1653 return this.finishNode(field, "PropertyDefinition")
1654 };
1655
1656 pp$8.parseClassStaticBlock = function(node) {
1657 node.body = [];
1658
1659 var oldLabels = this.labels;
1660 this.labels = [];
1661 this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);
1662 while (this.type !== types$1.braceR) {
1663 var stmt = this.parseStatement(null);
1664 node.body.push(stmt);
1665 }
1666 this.next();
1667 this.exitScope();
1668 this.labels = oldLabels;
1669
1670 return this.finishNode(node, "StaticBlock")
1671 };
1672
1673 pp$8.parseClassId = function(node, isStatement) {
1674 if (this.type === types$1.name) {
1675 node.id = this.parseIdent();
1676 if (isStatement)
1677 { this.checkLValSimple(node.id, BIND_LEXICAL, false); }
1678 } else {
1679 if (isStatement === true)
1680 { this.unexpected(); }
1681 node.id = null;
1682 }
1683 };
1684
1685 pp$8.parseClassSuper = function(node) {
1686 node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null;
1687 };
1688
1689 pp$8.enterClassBody = function() {
1690 var element = {declared: Object.create(null), used: []};
1691 this.privateNameStack.push(element);
1692 return element.declared
1693 };
1694
1695 pp$8.exitClassBody = function() {
1696 var ref = this.privateNameStack.pop();
1697 var declared = ref.declared;
1698 var used = ref.used;
1699 if (!this.options.checkPrivateFields) { return }
1700 var len = this.privateNameStack.length;
1701 var parent = len === 0 ? null : this.privateNameStack[len - 1];
1702 for (var i = 0; i < used.length; ++i) {
1703 var id = used[i];
1704 if (!hasOwn(declared, id.name)) {
1705 if (parent) {
1706 parent.used.push(id);
1707 } else {
1708 this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
1709 }
1710 }
1711 }
1712 };
1713
1714 function isPrivateNameConflicted(privateNameMap, element) {
1715 var name = element.key.name;
1716 var curr = privateNameMap[name];
1717
1718 var next = "true";
1719 if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
1720 next = (element.static ? "s" : "i") + element.kind;
1721 }
1722
1723 // `class { get #a(){}; static set #a(_){} }` is also conflict.
1724 if (
1725 curr === "iget" && next === "iset" ||
1726 curr === "iset" && next === "iget" ||
1727 curr === "sget" && next === "sset" ||
1728 curr === "sset" && next === "sget"
1729 ) {
1730 privateNameMap[name] = "true";
1731 return false
1732 } else if (!curr) {
1733 privateNameMap[name] = next;
1734 return false
1735 } else {
1736 return true
1737 }
1738 }
1739
1740 function checkKeyName(node, name) {
1741 var computed = node.computed;
1742 var key = node.key;
1743 return !computed && (
1744 key.type === "Identifier" && key.name === name ||
1745 key.type === "Literal" && key.value === name
1746 )
1747 }
1748
1749 // Parses module export declaration.
1750
1751 pp$8.parseExportAllDeclaration = function(node, exports) {
1752 if (this.options.ecmaVersion >= 11) {
1753 if (this.eatContextual("as")) {
1754 node.exported = this.parseModuleExportName();
1755 this.checkExport(exports, node.exported, this.lastTokStart);
1756 } else {
1757 node.exported = null;
1758 }
1759 }
1760 this.expectContextual("from");
1761 if (this.type !== types$1.string) { this.unexpected(); }
1762 node.source = this.parseExprAtom();
1763 if (this.options.ecmaVersion >= 16)
1764 { node.attributes = this.parseWithClause(); }
1765 this.semicolon();
1766 return this.finishNode(node, "ExportAllDeclaration")
1767 };
1768
1769 pp$8.parseExport = function(node, exports) {
1770 this.next();
1771 // export * from '...'
1772 if (this.eat(types$1.star)) {
1773 return this.parseExportAllDeclaration(node, exports)
1774 }
1775 if (this.eat(types$1._default)) { // export default ...
1776 this.checkExport(exports, "default", this.lastTokStart);
1777 node.declaration = this.parseExportDefaultDeclaration();
1778 return this.finishNode(node, "ExportDefaultDeclaration")
1779 }
1780 // export var|const|let|function|class ...
1781 if (this.shouldParseExportStatement()) {
1782 node.declaration = this.parseExportDeclaration(node);
1783 if (node.declaration.type === "VariableDeclaration")
1784 { this.checkVariableExport(exports, node.declaration.declarations); }
1785 else
1786 { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }
1787 node.specifiers = [];
1788 node.source = null;
1789 if (this.options.ecmaVersion >= 16)
1790 { node.attributes = []; }
1791 } else { // export { x, y as z } [from '...']
1792 node.declaration = null;
1793 node.specifiers = this.parseExportSpecifiers(exports);
1794 if (this.eatContextual("from")) {
1795 if (this.type !== types$1.string) { this.unexpected(); }
1796 node.source = this.parseExprAtom();
1797 if (this.options.ecmaVersion >= 16)
1798 { node.attributes = this.parseWithClause(); }
1799 } else {
1800 for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
1801 // check for keywords used as local names
1802 var spec = list[i];
1803
1804 this.checkUnreserved(spec.local);
1805 // check if export is defined
1806 this.checkLocalExport(spec.local);
1807
1808 if (spec.local.type === "Literal") {
1809 this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`.");
1810 }
1811 }
1812
1813 node.source = null;
1814 if (this.options.ecmaVersion >= 16)
1815 { node.attributes = []; }
1816 }
1817 this.semicolon();
1818 }
1819 return this.finishNode(node, "ExportNamedDeclaration")
1820 };
1821
1822 pp$8.parseExportDeclaration = function(node) {
1823 return this.parseStatement(null)
1824 };
1825
1826 pp$8.parseExportDefaultDeclaration = function() {
1827 var isAsync;
1828 if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {
1829 var fNode = this.startNode();
1830 this.next();
1831 if (isAsync) { this.next(); }
1832 return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync)
1833 } else if (this.type === types$1._class) {
1834 var cNode = this.startNode();
1835 return this.parseClass(cNode, "nullableID")
1836 } else {
1837 var declaration = this.parseMaybeAssign();
1838 this.semicolon();
1839 return declaration
1840 }
1841 };
1842
1843 pp$8.checkExport = function(exports, name, pos) {
1844 if (!exports) { return }
1845 if (typeof name !== "string")
1846 { name = name.type === "Identifier" ? name.name : name.value; }
1847 if (hasOwn(exports, name))
1848 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
1849 exports[name] = true;
1850 };
1851
1852 pp$8.checkPatternExport = function(exports, pat) {
1853 var type = pat.type;
1854 if (type === "Identifier")
1855 { this.checkExport(exports, pat, pat.start); }
1856 else if (type === "ObjectPattern")
1857 { for (var i = 0, list = pat.properties; i < list.length; i += 1)
1858 {
1859 var prop = list[i];
1860
1861 this.checkPatternExport(exports, prop);
1862 } }
1863 else if (type === "ArrayPattern")
1864 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
1865 var elt = list$1[i$1];
1866
1867 if (elt) { this.checkPatternExport(exports, elt); }
1868 } }
1869 else if (type === "Property")
1870 { this.checkPatternExport(exports, pat.value); }
1871 else if (type === "AssignmentPattern")
1872 { this.checkPatternExport(exports, pat.left); }
1873 else if (type === "RestElement")
1874 { this.checkPatternExport(exports, pat.argument); }
1875 };
1876
1877 pp$8.checkVariableExport = function(exports, decls) {
1878 if (!exports) { return }
1879 for (var i = 0, list = decls; i < list.length; i += 1)
1880 {
1881 var decl = list[i];
1882
1883 this.checkPatternExport(exports, decl.id);
1884 }
1885 };
1886
1887 pp$8.shouldParseExportStatement = function() {
1888 return this.type.keyword === "var" ||
1889 this.type.keyword === "const" ||
1890 this.type.keyword === "class" ||
1891 this.type.keyword === "function" ||
1892 this.isLet() ||
1893 this.isAsyncFunction()
1894 };
1895
1896 // Parses a comma-separated list of module exports.
1897
1898 pp$8.parseExportSpecifier = function(exports) {
1899 var node = this.startNode();
1900 node.local = this.parseModuleExportName();
1901
1902 node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local;
1903 this.checkExport(
1904 exports,
1905 node.exported,
1906 node.exported.start
1907 );
1908
1909 return this.finishNode(node, "ExportSpecifier")
1910 };
1911
1912 pp$8.parseExportSpecifiers = function(exports) {
1913 var nodes = [], first = true;
1914 // export { x, y as z } [from '...']
1915 this.expect(types$1.braceL);
1916 while (!this.eat(types$1.braceR)) {
1917 if (!first) {
1918 this.expect(types$1.comma);
1919 if (this.afterTrailingComma(types$1.braceR)) { break }
1920 } else { first = false; }
1921
1922 nodes.push(this.parseExportSpecifier(exports));
1923 }
1924 return nodes
1925 };
1926
1927 // Parses import declaration.
1928
1929 pp$8.parseImport = function(node) {
1930 this.next();
1931
1932 // import '...'
1933 if (this.type === types$1.string) {
1934 node.specifiers = empty$1;
1935 node.source = this.parseExprAtom();
1936 } else {
1937 node.specifiers = this.parseImportSpecifiers();
1938 this.expectContextual("from");
1939 node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();
1940 }
1941 if (this.options.ecmaVersion >= 16)
1942 { node.attributes = this.parseWithClause(); }
1943 this.semicolon();
1944 return this.finishNode(node, "ImportDeclaration")
1945 };
1946
1947 // Parses a comma-separated list of module imports.
1948
1949 pp$8.parseImportSpecifier = function() {
1950 var node = this.startNode();
1951 node.imported = this.parseModuleExportName();
1952
1953 if (this.eatContextual("as")) {
1954 node.local = this.parseIdent();
1955 } else {
1956 this.checkUnreserved(node.imported);
1957 node.local = node.imported;
1958 }
1959 this.checkLValSimple(node.local, BIND_LEXICAL);
1960
1961 return this.finishNode(node, "ImportSpecifier")
1962 };
1963
1964 pp$8.parseImportDefaultSpecifier = function() {
1965 // import defaultObj, { x, y as z } from '...'
1966 var node = this.startNode();
1967 node.local = this.parseIdent();
1968 this.checkLValSimple(node.local, BIND_LEXICAL);
1969 return this.finishNode(node, "ImportDefaultSpecifier")
1970 };
1971
1972 pp$8.parseImportNamespaceSpecifier = function() {
1973 var node = this.startNode();
1974 this.next();
1975 this.expectContextual("as");
1976 node.local = this.parseIdent();
1977 this.checkLValSimple(node.local, BIND_LEXICAL);
1978 return this.finishNode(node, "ImportNamespaceSpecifier")
1979 };
1980
1981 pp$8.parseImportSpecifiers = function() {
1982 var nodes = [], first = true;
1983 if (this.type === types$1.name) {
1984 nodes.push(this.parseImportDefaultSpecifier());
1985 if (!this.eat(types$1.comma)) { return nodes }
1986 }
1987 if (this.type === types$1.star) {
1988 nodes.push(this.parseImportNamespaceSpecifier());
1989 return nodes
1990 }
1991 this.expect(types$1.braceL);
1992 while (!this.eat(types$1.braceR)) {
1993 if (!first) {
1994 this.expect(types$1.comma);
1995 if (this.afterTrailingComma(types$1.braceR)) { break }
1996 } else { first = false; }
1997
1998 nodes.push(this.parseImportSpecifier());
1999 }
2000 return nodes
2001 };
2002
2003 pp$8.parseWithClause = function() {
2004 var nodes = [];
2005 if (!this.eat(types$1._with)) {
2006 return nodes
2007 }
2008 this.expect(types$1.braceL);
2009 var attributeKeys = {};
2010 var first = true;
2011 while (!this.eat(types$1.braceR)) {
2012 if (!first) {
2013 this.expect(types$1.comma);
2014 if (this.afterTrailingComma(types$1.braceR)) { break }
2015 } else { first = false; }
2016
2017 var attr = this.parseImportAttribute();
2018 var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
2019 if (hasOwn(attributeKeys, keyName))
2020 { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); }
2021 attributeKeys[keyName] = true;
2022 nodes.push(attr);
2023 }
2024 return nodes
2025 };
2026
2027 pp$8.parseImportAttribute = function() {
2028 var node = this.startNode();
2029 node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never");
2030 this.expect(types$1.colon);
2031 if (this.type !== types$1.string) {
2032 this.unexpected();
2033 }
2034 node.value = this.parseExprAtom();
2035 return this.finishNode(node, "ImportAttribute")
2036 };
2037
2038 pp$8.parseModuleExportName = function() {
2039 if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {
2040 var stringLiteral = this.parseLiteral(this.value);
2041 if (loneSurrogate.test(stringLiteral.value)) {
2042 this.raise(stringLiteral.start, "An export name cannot include a lone surrogate.");
2043 }
2044 return stringLiteral
2045 }
2046 return this.parseIdent(true)
2047 };
2048
2049 // Set `ExpressionStatement#directive` property for directive prologues.
2050 pp$8.adaptDirectivePrologue = function(statements) {
2051 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
2052 statements[i].directive = statements[i].expression.raw.slice(1, -1);
2053 }
2054 };
2055 pp$8.isDirectiveCandidate = function(statement) {
2056 return (
2057 this.options.ecmaVersion >= 5 &&
2058 statement.type === "ExpressionStatement" &&
2059 statement.expression.type === "Literal" &&
2060 typeof statement.expression.value === "string" &&
2061 // Reject parenthesized strings.
2062 (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
2063 )
2064 };
2065
2066 var pp$7 = Parser.prototype;
2067
2068 // Convert existing expression atom to assignable pattern
2069 // if possible.
2070
2071 pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {
2072 if (this.options.ecmaVersion >= 6 && node) {
2073 switch (node.type) {
2074 case "Identifier":
2075 if (this.inAsync && node.name === "await")
2076 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
2077 break
2078
2079 case "ObjectPattern":
2080 case "ArrayPattern":
2081 case "AssignmentPattern":
2082 case "RestElement":
2083 break
2084
2085 case "ObjectExpression":
2086 node.type = "ObjectPattern";
2087 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2088 for (var i = 0, list = node.properties; i < list.length; i += 1) {
2089 var prop = list[i];
2090
2091 this.toAssignable(prop, isBinding);
2092 // Early error:
2093 // AssignmentRestProperty[Yield, Await] :
2094 // `...` DestructuringAssignmentTarget[Yield, Await]
2095 //
2096 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
2097 if (
2098 prop.type === "RestElement" &&
2099 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
2100 ) {
2101 this.raise(prop.argument.start, "Unexpected token");
2102 }
2103 }
2104 break
2105
2106 case "Property":
2107 // AssignmentProperty has type === "Property"
2108 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
2109 this.toAssignable(node.value, isBinding);
2110 break
2111
2112 case "ArrayExpression":
2113 node.type = "ArrayPattern";
2114 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2115 this.toAssignableList(node.elements, isBinding);
2116 break
2117
2118 case "SpreadElement":
2119 node.type = "RestElement";
2120 this.toAssignable(node.argument, isBinding);
2121 if (node.argument.type === "AssignmentPattern")
2122 { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
2123 break
2124
2125 case "AssignmentExpression":
2126 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
2127 node.type = "AssignmentPattern";
2128 delete node.operator;
2129 this.toAssignable(node.left, isBinding);
2130 break
2131
2132 case "ParenthesizedExpression":
2133 this.toAssignable(node.expression, isBinding, refDestructuringErrors);
2134 break
2135
2136 case "ChainExpression":
2137 this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
2138 break
2139
2140 case "MemberExpression":
2141 if (!isBinding) { break }
2142
2143 default:
2144 this.raise(node.start, "Assigning to rvalue");
2145 }
2146 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2147 return node
2148 };
2149
2150 // Convert list of expression atoms to binding list.
2151
2152 pp$7.toAssignableList = function(exprList, isBinding) {
2153 var end = exprList.length;
2154 for (var i = 0; i < end; i++) {
2155 var elt = exprList[i];
2156 if (elt) { this.toAssignable(elt, isBinding); }
2157 }
2158 if (end) {
2159 var last = exprList[end - 1];
2160 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
2161 { this.unexpected(last.argument.start); }
2162 }
2163 return exprList
2164 };
2165
2166 // Parses spread element.
2167
2168 pp$7.parseSpread = function(refDestructuringErrors) {
2169 var node = this.startNode();
2170 this.next();
2171 node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
2172 return this.finishNode(node, "SpreadElement")
2173 };
2174
2175 pp$7.parseRestBinding = function() {
2176 var node = this.startNode();
2177 this.next();
2178
2179 // RestElement inside of a function parameter must be an identifier
2180 if (this.options.ecmaVersion === 6 && this.type !== types$1.name)
2181 { this.unexpected(); }
2182
2183 node.argument = this.parseBindingAtom();
2184
2185 return this.finishNode(node, "RestElement")
2186 };
2187
2188 // Parses lvalue (assignable) atom.
2189
2190 pp$7.parseBindingAtom = function() {
2191 if (this.options.ecmaVersion >= 6) {
2192 switch (this.type) {
2193 case types$1.bracketL:
2194 var node = this.startNode();
2195 this.next();
2196 node.elements = this.parseBindingList(types$1.bracketR, true, true);
2197 return this.finishNode(node, "ArrayPattern")
2198
2199 case types$1.braceL:
2200 return this.parseObj(true)
2201 }
2202 }
2203 return this.parseIdent()
2204 };
2205
2206 pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) {
2207 var elts = [], first = true;
2208 while (!this.eat(close)) {
2209 if (first) { first = false; }
2210 else { this.expect(types$1.comma); }
2211 if (allowEmpty && this.type === types$1.comma) {
2212 elts.push(null);
2213 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
2214 break
2215 } else if (this.type === types$1.ellipsis) {
2216 var rest = this.parseRestBinding();
2217 this.parseBindingListItem(rest);
2218 elts.push(rest);
2219 if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); }
2220 this.expect(close);
2221 break
2222 } else {
2223 elts.push(this.parseAssignableListItem(allowModifiers));
2224 }
2225 }
2226 return elts
2227 };
2228
2229 pp$7.parseAssignableListItem = function(allowModifiers) {
2230 var elem = this.parseMaybeDefault(this.start, this.startLoc);
2231 this.parseBindingListItem(elem);
2232 return elem
2233 };
2234
2235 pp$7.parseBindingListItem = function(param) {
2236 return param
2237 };
2238
2239 // Parses assignment pattern around given atom if possible.
2240
2241 pp$7.parseMaybeDefault = function(startPos, startLoc, left) {
2242 left = left || this.parseBindingAtom();
2243 if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }
2244 var node = this.startNodeAt(startPos, startLoc);
2245 node.left = left;
2246 node.right = this.parseMaybeAssign();
2247 return this.finishNode(node, "AssignmentPattern")
2248 };
2249
2250 // The following three functions all verify that a node is an lvalue —
2251 // something that can be bound, or assigned to. In order to do so, they perform
2252 // a variety of checks:
2253 //
2254 // - Check that none of the bound/assigned-to identifiers are reserved words.
2255 // - Record name declarations for bindings in the appropriate scope.
2256 // - Check duplicate argument names, if checkClashes is set.
2257 //
2258 // If a complex binding pattern is encountered (e.g., object and array
2259 // destructuring), the entire pattern is recursively checked.
2260 //
2261 // There are three versions of checkLVal*() appropriate for different
2262 // circumstances:
2263 //
2264 // - checkLValSimple() shall be used if the syntactic construct supports
2265 // nothing other than identifiers and member expressions. Parenthesized
2266 // expressions are also correctly handled. This is generally appropriate for
2267 // constructs for which the spec says
2268 //
2269 // > It is a Syntax Error if AssignmentTargetType of [the production] is not
2270 // > simple.
2271 //
2272 // It is also appropriate for checking if an identifier is valid and not
2273 // defined elsewhere, like import declarations or function/class identifiers.
2274 //
2275 // Examples where this is used include:
2276 // a += …;
2277 // import a from '…';
2278 // where a is the node to be checked.
2279 //
2280 // - checkLValPattern() shall be used if the syntactic construct supports
2281 // anything checkLValSimple() supports, as well as object and array
2282 // destructuring patterns. This is generally appropriate for constructs for
2283 // which the spec says
2284 //
2285 // > It is a Syntax Error if [the production] is neither an ObjectLiteral nor
2286 // > an ArrayLiteral and AssignmentTargetType of [the production] is not
2287 // > simple.
2288 //
2289 // Examples where this is used include:
2290 // (a = …);
2291 // const a = …;
2292 // try { … } catch (a) { … }
2293 // where a is the node to be checked.
2294 //
2295 // - checkLValInnerPattern() shall be used if the syntactic construct supports
2296 // anything checkLValPattern() supports, as well as default assignment
2297 // patterns, rest elements, and other constructs that may appear within an
2298 // object or array destructuring pattern.
2299 //
2300 // As a special case, function parameters also use checkLValInnerPattern(),
2301 // as they also support defaults and rest constructs.
2302 //
2303 // These functions deliberately support both assignment and binding constructs,
2304 // as the logic for both is exceedingly similar. If the node is the target of
2305 // an assignment, then bindingType should be set to BIND_NONE. Otherwise, it
2306 // should be set to the appropriate BIND_* constant, like BIND_VAR or
2307 // BIND_LEXICAL.
2308 //
2309 // If the function is called with a non-BIND_NONE bindingType, then
2310 // additionally a checkClashes object may be specified to allow checking for
2311 // duplicate argument names. checkClashes is ignored if the provided construct
2312 // is an assignment (i.e., bindingType is BIND_NONE).
2313
2314 pp$7.checkLValSimple = function(expr, bindingType, checkClashes) {
2315 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2316
2317 var isBind = bindingType !== BIND_NONE;
2318
2319 switch (expr.type) {
2320 case "Identifier":
2321 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
2322 { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
2323 if (isBind) {
2324 if (bindingType === BIND_LEXICAL && expr.name === "let")
2325 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
2326 if (checkClashes) {
2327 if (hasOwn(checkClashes, expr.name))
2328 { this.raiseRecoverable(expr.start, "Argument name clash"); }
2329 checkClashes[expr.name] = true;
2330 }
2331 if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
2332 }
2333 break
2334
2335 case "ChainExpression":
2336 this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
2337 break
2338
2339 case "MemberExpression":
2340 if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); }
2341 break
2342
2343 case "ParenthesizedExpression":
2344 if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); }
2345 return this.checkLValSimple(expr.expression, bindingType, checkClashes)
2346
2347 default:
2348 this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue");
2349 }
2350 };
2351
2352 pp$7.checkLValPattern = function(expr, bindingType, checkClashes) {
2353 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2354
2355 switch (expr.type) {
2356 case "ObjectPattern":
2357 for (var i = 0, list = expr.properties; i < list.length; i += 1) {
2358 var prop = list[i];
2359
2360 this.checkLValInnerPattern(prop, bindingType, checkClashes);
2361 }
2362 break
2363
2364 case "ArrayPattern":
2365 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
2366 var elem = list$1[i$1];
2367
2368 if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }
2369 }
2370 break
2371
2372 default:
2373 this.checkLValSimple(expr, bindingType, checkClashes);
2374 }
2375 };
2376
2377 pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {
2378 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2379
2380 switch (expr.type) {
2381 case "Property":
2382 // AssignmentProperty has type === "Property"
2383 this.checkLValInnerPattern(expr.value, bindingType, checkClashes);
2384 break
2385
2386 case "AssignmentPattern":
2387 this.checkLValPattern(expr.left, bindingType, checkClashes);
2388 break
2389
2390 case "RestElement":
2391 this.checkLValPattern(expr.argument, bindingType, checkClashes);
2392 break
2393
2394 default:
2395 this.checkLValPattern(expr, bindingType, checkClashes);
2396 }
2397 };
2398
2399 // The algorithm used to determine whether a regexp can appear at a
2400 // given point in the program is loosely based on sweet.js' approach.
2401 // See https://github.com/mozilla/sweet.js/wiki/design
2402
2403
2404 var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
2405 this.token = token;
2406 this.isExpr = !!isExpr;
2407 this.preserveSpace = !!preserveSpace;
2408 this.override = override;
2409 this.generator = !!generator;
2410 };
2411
2412 var types = {
2413 b_stat: new TokContext("{", false),
2414 b_expr: new TokContext("{", true),
2415 b_tmpl: new TokContext("${", false),
2416 p_stat: new TokContext("(", false),
2417 p_expr: new TokContext("(", true),
2418 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
2419 f_stat: new TokContext("function", false),
2420 f_expr: new TokContext("function", true),
2421 f_expr_gen: new TokContext("function", true, false, null, true),
2422 f_gen: new TokContext("function", false, false, null, true)
2423 };
2424
2425 var pp$6 = Parser.prototype;
2426
2427 pp$6.initialContext = function() {
2428 return [types.b_stat]
2429 };
2430
2431 pp$6.curContext = function() {
2432 return this.context[this.context.length - 1]
2433 };
2434
2435 pp$6.braceIsBlock = function(prevType) {
2436 var parent = this.curContext();
2437 if (parent === types.f_expr || parent === types.f_stat)
2438 { return true }
2439 if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))
2440 { return !parent.isExpr }
2441
2442 // The check for `tt.name && exprAllowed` detects whether we are
2443 // after a `yield` or `of` construct. See the `updateContext` for
2444 // `tt.name`.
2445 if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)
2446 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
2447 if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)
2448 { return true }
2449 if (prevType === types$1.braceL)
2450 { return parent === types.b_stat }
2451 if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)
2452 { return false }
2453 return !this.exprAllowed
2454 };
2455
2456 pp$6.inGeneratorContext = function() {
2457 for (var i = this.context.length - 1; i >= 1; i--) {
2458 var context = this.context[i];
2459 if (context.token === "function")
2460 { return context.generator }
2461 }
2462 return false
2463 };
2464
2465 pp$6.updateContext = function(prevType) {
2466 var update, type = this.type;
2467 if (type.keyword && prevType === types$1.dot)
2468 { this.exprAllowed = false; }
2469 else if (update = type.updateContext)
2470 { update.call(this, prevType); }
2471 else
2472 { this.exprAllowed = type.beforeExpr; }
2473 };
2474
2475 // Used to handle edge cases when token context could not be inferred correctly during tokenization phase
2476
2477 pp$6.overrideContext = function(tokenCtx) {
2478 if (this.curContext() !== tokenCtx) {
2479 this.context[this.context.length - 1] = tokenCtx;
2480 }
2481 };
2482
2483 // Token-specific context update code
2484
2485 types$1.parenR.updateContext = types$1.braceR.updateContext = function() {
2486 if (this.context.length === 1) {
2487 this.exprAllowed = true;
2488 return
2489 }
2490 var out = this.context.pop();
2491 if (out === types.b_stat && this.curContext().token === "function") {
2492 out = this.context.pop();
2493 }
2494 this.exprAllowed = !out.isExpr;
2495 };
2496
2497 types$1.braceL.updateContext = function(prevType) {
2498 this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
2499 this.exprAllowed = true;
2500 };
2501
2502 types$1.dollarBraceL.updateContext = function() {
2503 this.context.push(types.b_tmpl);
2504 this.exprAllowed = true;
2505 };
2506
2507 types$1.parenL.updateContext = function(prevType) {
2508 var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;
2509 this.context.push(statementParens ? types.p_stat : types.p_expr);
2510 this.exprAllowed = true;
2511 };
2512
2513 types$1.incDec.updateContext = function() {
2514 // tokExprAllowed stays unchanged
2515 };
2516
2517 types$1._function.updateContext = types$1._class.updateContext = function(prevType) {
2518 if (prevType.beforeExpr && prevType !== types$1._else &&
2519 !(prevType === types$1.semi && this.curContext() !== types.p_stat) &&
2520 !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
2521 !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))
2522 { this.context.push(types.f_expr); }
2523 else
2524 { this.context.push(types.f_stat); }
2525 this.exprAllowed = false;
2526 };
2527
2528 types$1.colon.updateContext = function() {
2529 if (this.curContext().token === "function") { this.context.pop(); }
2530 this.exprAllowed = true;
2531 };
2532
2533 types$1.backQuote.updateContext = function() {
2534 if (this.curContext() === types.q_tmpl)
2535 { this.context.pop(); }
2536 else
2537 { this.context.push(types.q_tmpl); }
2538 this.exprAllowed = false;
2539 };
2540
2541 types$1.star.updateContext = function(prevType) {
2542 if (prevType === types$1._function) {
2543 var index = this.context.length - 1;
2544 if (this.context[index] === types.f_expr)
2545 { this.context[index] = types.f_expr_gen; }
2546 else
2547 { this.context[index] = types.f_gen; }
2548 }
2549 this.exprAllowed = true;
2550 };
2551
2552 types$1.name.updateContext = function(prevType) {
2553 var allowed = false;
2554 if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {
2555 if (this.value === "of" && !this.exprAllowed ||
2556 this.value === "yield" && this.inGeneratorContext())
2557 { allowed = true; }
2558 }
2559 this.exprAllowed = allowed;
2560 };
2561
2562 // A recursive descent parser operates by defining functions for all
2563 // syntactic elements, and recursively calling those, each function
2564 // advancing the input stream and returning an AST node. Precedence
2565 // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
2566 // instead of `(!x)[1]` is handled by the fact that the parser
2567 // function that parses unary prefix operators is called first, and
2568 // in turn calls the function that parses `[]` subscripts — that
2569 // way, it'll receive the node for `x[1]` already parsed, and wraps
2570 // *that* in the unary operator node.
2571 //
2572 // Acorn uses an [operator precedence parser][opp] to handle binary
2573 // operator precedence, because it is much more compact than using
2574 // the technique outlined above, which uses different, nesting
2575 // functions to specify precedence, for all of the ten binary
2576 // precedence levels that JavaScript defines.
2577 //
2578 // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
2579
2580
2581 var pp$5 = Parser.prototype;
2582
2583 // Check if property name clashes with already added.
2584 // Object/class getters and setters are not allowed to clash —
2585 // either with each other or with an init property — and in
2586 // strict mode, init properties are also not allowed to be repeated.
2587
2588 pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
2589 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
2590 { return }
2591 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
2592 { return }
2593 var key = prop.key;
2594 var name;
2595 switch (key.type) {
2596 case "Identifier": name = key.name; break
2597 case "Literal": name = String(key.value); break
2598 default: return
2599 }
2600 var kind = prop.kind;
2601 if (this.options.ecmaVersion >= 6) {
2602 if (name === "__proto__" && kind === "init") {
2603 if (propHash.proto) {
2604 if (refDestructuringErrors) {
2605 if (refDestructuringErrors.doubleProto < 0) {
2606 refDestructuringErrors.doubleProto = key.start;
2607 }
2608 } else {
2609 this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
2610 }
2611 }
2612 propHash.proto = true;
2613 }
2614 return
2615 }
2616 name = "$" + name;
2617 var other = propHash[name];
2618 if (other) {
2619 var redefinition;
2620 if (kind === "init") {
2621 redefinition = this.strict && other.init || other.get || other.set;
2622 } else {
2623 redefinition = other.init || other[kind];
2624 }
2625 if (redefinition)
2626 { this.raiseRecoverable(key.start, "Redefinition of property"); }
2627 } else {
2628 other = propHash[name] = {
2629 init: false,
2630 get: false,
2631 set: false
2632 };
2633 }
2634 other[kind] = true;
2635 };
2636
2637 // ### Expression parsing
2638
2639 // These nest, from the most general expression type at the top to
2640 // 'atomic', nondivisible expression types at the bottom. Most of
2641 // the functions will simply let the function(s) below them parse,
2642 // and, *if* the syntactic construct they handle is present, wrap
2643 // the AST node that the inner parser gave them in another node.
2644
2645 // Parse a full expression. The optional arguments are used to
2646 // forbid the `in` operator (in for loops initalization expressions)
2647 // and provide reference for storing '=' operator inside shorthand
2648 // property assignment in contexts where both object expression
2649 // and object pattern might appear (so it's possible to raise
2650 // delayed syntax error at correct position).
2651
2652 pp$5.parseExpression = function(forInit, refDestructuringErrors) {
2653 var startPos = this.start, startLoc = this.startLoc;
2654 var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
2655 if (this.type === types$1.comma) {
2656 var node = this.startNodeAt(startPos, startLoc);
2657 node.expressions = [expr];
2658 while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
2659 return this.finishNode(node, "SequenceExpression")
2660 }
2661 return expr
2662 };
2663
2664 // Parse an assignment expression. This includes applications of
2665 // operators like `+=`.
2666
2667 pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
2668 if (this.isContextual("yield")) {
2669 if (this.inGenerator) { return this.parseYield(forInit) }
2670 // The tokenizer will assume an expression is allowed after
2671 // `yield`, but this isn't that kind of yield
2672 else { this.exprAllowed = false; }
2673 }
2674
2675 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;
2676 if (refDestructuringErrors) {
2677 oldParenAssign = refDestructuringErrors.parenthesizedAssign;
2678 oldTrailingComma = refDestructuringErrors.trailingComma;
2679 oldDoubleProto = refDestructuringErrors.doubleProto;
2680 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
2681 } else {
2682 refDestructuringErrors = new DestructuringErrors;
2683 ownDestructuringErrors = true;
2684 }
2685
2686 var startPos = this.start, startLoc = this.startLoc;
2687 if (this.type === types$1.parenL || this.type === types$1.name) {
2688 this.potentialArrowAt = this.start;
2689 this.potentialArrowInForAwait = forInit === "await";
2690 }
2691 var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
2692 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
2693 if (this.type.isAssign) {
2694 var node = this.startNodeAt(startPos, startLoc);
2695 node.operator = this.value;
2696 if (this.type === types$1.eq)
2697 { left = this.toAssignable(left, false, refDestructuringErrors); }
2698 if (!ownDestructuringErrors) {
2699 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
2700 }
2701 if (refDestructuringErrors.shorthandAssign >= left.start)
2702 { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
2703 if (this.type === types$1.eq)
2704 { this.checkLValPattern(left); }
2705 else
2706 { this.checkLValSimple(left); }
2707 node.left = left;
2708 this.next();
2709 node.right = this.parseMaybeAssign(forInit);
2710 if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }
2711 return this.finishNode(node, "AssignmentExpression")
2712 } else {
2713 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
2714 }
2715 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
2716 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
2717 return left
2718 };
2719
2720 // Parse a ternary conditional (`?:`) operator.
2721
2722 pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {
2723 var startPos = this.start, startLoc = this.startLoc;
2724 var expr = this.parseExprOps(forInit, refDestructuringErrors);
2725 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2726 if (this.eat(types$1.question)) {
2727 var node = this.startNodeAt(startPos, startLoc);
2728 node.test = expr;
2729 node.consequent = this.parseMaybeAssign();
2730 this.expect(types$1.colon);
2731 node.alternate = this.parseMaybeAssign(forInit);
2732 return this.finishNode(node, "ConditionalExpression")
2733 }
2734 return expr
2735 };
2736
2737 // Start the precedence parser.
2738
2739 pp$5.parseExprOps = function(forInit, refDestructuringErrors) {
2740 var startPos = this.start, startLoc = this.startLoc;
2741 var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);
2742 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2743 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
2744 };
2745
2746 // Parse binary operators with the operator precedence parsing
2747 // algorithm. `left` is the left-hand side of the operator.
2748 // `minPrec` provides context that allows the function to stop and
2749 // defer further parser to one of its callers when it encounters an
2750 // operator that has a lower precedence than the set it is parsing.
2751
2752 pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
2753 var prec = this.type.binop;
2754 if (prec != null && (!forInit || this.type !== types$1._in)) {
2755 if (prec > minPrec) {
2756 var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;
2757 var coalesce = this.type === types$1.coalesce;
2758 if (coalesce) {
2759 // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
2760 // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
2761 prec = types$1.logicalAND.binop;
2762 }
2763 var op = this.value;
2764 this.next();
2765 var startPos = this.start, startLoc = this.startLoc;
2766 var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);
2767 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
2768 if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {
2769 this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
2770 }
2771 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
2772 }
2773 }
2774 return left
2775 };
2776
2777 pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {
2778 if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); }
2779 var node = this.startNodeAt(startPos, startLoc);
2780 node.left = left;
2781 node.operator = op;
2782 node.right = right;
2783 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
2784 };
2785
2786 // Parse unary operators, both prefix and postfix.
2787
2788 pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {
2789 var startPos = this.start, startLoc = this.startLoc, expr;
2790 if (this.isContextual("await") && this.canAwait) {
2791 expr = this.parseAwait(forInit);
2792 sawUnary = true;
2793 } else if (this.type.prefix) {
2794 var node = this.startNode(), update = this.type === types$1.incDec;
2795 node.operator = this.value;
2796 node.prefix = true;
2797 this.next();
2798 node.argument = this.parseMaybeUnary(null, true, update, forInit);
2799 this.checkExpressionErrors(refDestructuringErrors, true);
2800 if (update) { this.checkLValSimple(node.argument); }
2801 else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument))
2802 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
2803 else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
2804 { this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
2805 else { sawUnary = true; }
2806 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
2807 } else if (!sawUnary && this.type === types$1.privateId) {
2808 if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); }
2809 expr = this.parsePrivateIdent();
2810 // only could be private fields in 'in', such as #x in obj
2811 if (this.type !== types$1._in) { this.unexpected(); }
2812 } else {
2813 expr = this.parseExprSubscripts(refDestructuringErrors, forInit);
2814 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2815 while (this.type.postfix && !this.canInsertSemicolon()) {
2816 var node$1 = this.startNodeAt(startPos, startLoc);
2817 node$1.operator = this.value;
2818 node$1.prefix = false;
2819 node$1.argument = expr;
2820 this.checkLValSimple(expr);
2821 this.next();
2822 expr = this.finishNode(node$1, "UpdateExpression");
2823 }
2824 }
2825
2826 if (!incDec && this.eat(types$1.starstar)) {
2827 if (sawUnary)
2828 { this.unexpected(this.lastTokStart); }
2829 else
2830 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) }
2831 } else {
2832 return expr
2833 }
2834 };
2835
2836 function isLocalVariableAccess(node) {
2837 return (
2838 node.type === "Identifier" ||
2839 node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression)
2840 )
2841 }
2842
2843 function isPrivateFieldAccess(node) {
2844 return (
2845 node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
2846 node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) ||
2847 node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression)
2848 )
2849 }
2850
2851 // Parse call, dot, and `[]`-subscript expressions.
2852
2853 pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {
2854 var startPos = this.start, startLoc = this.startLoc;
2855 var expr = this.parseExprAtom(refDestructuringErrors, forInit);
2856 if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
2857 { return expr }
2858 var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);
2859 if (refDestructuringErrors && result.type === "MemberExpression") {
2860 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
2861 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
2862 if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
2863 }
2864 return result
2865 };
2866
2867 pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {
2868 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
2869 this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
2870 this.potentialArrowAt === base.start;
2871 var optionalChained = false;
2872
2873 while (true) {
2874 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
2875
2876 if (element.optional) { optionalChained = true; }
2877 if (element === base || element.type === "ArrowFunctionExpression") {
2878 if (optionalChained) {
2879 var chainNode = this.startNodeAt(startPos, startLoc);
2880 chainNode.expression = element;
2881 element = this.finishNode(chainNode, "ChainExpression");
2882 }
2883 return element
2884 }
2885
2886 base = element;
2887 }
2888 };
2889
2890 pp$5.shouldParseAsyncArrow = function() {
2891 return !this.canInsertSemicolon() && this.eat(types$1.arrow)
2892 };
2893
2894 pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) {
2895 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)
2896 };
2897
2898 pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
2899 var optionalSupported = this.options.ecmaVersion >= 11;
2900 var optional = optionalSupported && this.eat(types$1.questionDot);
2901 if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
2902
2903 var computed = this.eat(types$1.bracketL);
2904 if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {
2905 var node = this.startNodeAt(startPos, startLoc);
2906 node.object = base;
2907 if (computed) {
2908 node.property = this.parseExpression();
2909 this.expect(types$1.bracketR);
2910 } else if (this.type === types$1.privateId && base.type !== "Super") {
2911 node.property = this.parsePrivateIdent();
2912 } else {
2913 node.property = this.parseIdent(this.options.allowReserved !== "never");
2914 }
2915 node.computed = !!computed;
2916 if (optionalSupported) {
2917 node.optional = optional;
2918 }
2919 base = this.finishNode(node, "MemberExpression");
2920 } else if (!noCalls && this.eat(types$1.parenL)) {
2921 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2922 this.yieldPos = 0;
2923 this.awaitPos = 0;
2924 this.awaitIdentPos = 0;
2925 var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
2926 if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) {
2927 this.checkPatternErrors(refDestructuringErrors, false);
2928 this.checkYieldAwaitInDefaultParams();
2929 if (this.awaitIdentPos > 0)
2930 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
2931 this.yieldPos = oldYieldPos;
2932 this.awaitPos = oldAwaitPos;
2933 this.awaitIdentPos = oldAwaitIdentPos;
2934 return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit)
2935 }
2936 this.checkExpressionErrors(refDestructuringErrors, true);
2937 this.yieldPos = oldYieldPos || this.yieldPos;
2938 this.awaitPos = oldAwaitPos || this.awaitPos;
2939 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
2940 var node$1 = this.startNodeAt(startPos, startLoc);
2941 node$1.callee = base;
2942 node$1.arguments = exprList;
2943 if (optionalSupported) {
2944 node$1.optional = optional;
2945 }
2946 base = this.finishNode(node$1, "CallExpression");
2947 } else if (this.type === types$1.backQuote) {
2948 if (optional || optionalChained) {
2949 this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
2950 }
2951 var node$2 = this.startNodeAt(startPos, startLoc);
2952 node$2.tag = base;
2953 node$2.quasi = this.parseTemplate({isTagged: true});
2954 base = this.finishNode(node$2, "TaggedTemplateExpression");
2955 }
2956 return base
2957 };
2958
2959 // Parse an atomic expression — either a single token that is an
2960 // expression, an expression started by a keyword like `function` or
2961 // `new`, or an expression wrapped in punctuation like `()`, `[]`,
2962 // or `{}`.
2963
2964 pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) {
2965 // If a division operator appears in an expression position, the
2966 // tokenizer got confused, and we force it to read a regexp instead.
2967 if (this.type === types$1.slash) { this.readRegexp(); }
2968
2969 var node, canBeArrow = this.potentialArrowAt === this.start;
2970 switch (this.type) {
2971 case types$1._super:
2972 if (!this.allowSuper)
2973 { this.raise(this.start, "'super' keyword outside a method"); }
2974 node = this.startNode();
2975 this.next();
2976 if (this.type === types$1.parenL && !this.allowDirectSuper)
2977 { this.raise(node.start, "super() call outside constructor of a subclass"); }
2978 // The `super` keyword can appear at below:
2979 // SuperProperty:
2980 // super [ Expression ]
2981 // super . IdentifierName
2982 // SuperCall:
2983 // super ( Arguments )
2984 if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)
2985 { this.unexpected(); }
2986 return this.finishNode(node, "Super")
2987
2988 case types$1._this:
2989 node = this.startNode();
2990 this.next();
2991 return this.finishNode(node, "ThisExpression")
2992
2993 case types$1.name:
2994 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
2995 var id = this.parseIdent(false);
2996 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) {
2997 this.overrideContext(types.f_expr);
2998 return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)
2999 }
3000 if (canBeArrow && !this.canInsertSemicolon()) {
3001 if (this.eat(types$1.arrow))
3002 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }
3003 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc &&
3004 (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
3005 id = this.parseIdent(false);
3006 if (this.canInsertSemicolon() || !this.eat(types$1.arrow))
3007 { this.unexpected(); }
3008 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)
3009 }
3010 }
3011 return id
3012
3013 case types$1.regexp:
3014 var value = this.value;
3015 node = this.parseLiteral(value.value);
3016 node.regex = {pattern: value.pattern, flags: value.flags};
3017 return node
3018
3019 case types$1.num: case types$1.string:
3020 return this.parseLiteral(this.value)
3021
3022 case types$1._null: case types$1._true: case types$1._false:
3023 node = this.startNode();
3024 node.value = this.type === types$1._null ? null : this.type === types$1._true;
3025 node.raw = this.type.keyword;
3026 this.next();
3027 return this.finishNode(node, "Literal")
3028
3029 case types$1.parenL:
3030 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);
3031 if (refDestructuringErrors) {
3032 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
3033 { refDestructuringErrors.parenthesizedAssign = start; }
3034 if (refDestructuringErrors.parenthesizedBind < 0)
3035 { refDestructuringErrors.parenthesizedBind = start; }
3036 }
3037 return expr
3038
3039 case types$1.bracketL:
3040 node = this.startNode();
3041 this.next();
3042 node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);
3043 return this.finishNode(node, "ArrayExpression")
3044
3045 case types$1.braceL:
3046 this.overrideContext(types.b_expr);
3047 return this.parseObj(false, refDestructuringErrors)
3048
3049 case types$1._function:
3050 node = this.startNode();
3051 this.next();
3052 return this.parseFunction(node, 0)
3053
3054 case types$1._class:
3055 return this.parseClass(this.startNode(), false)
3056
3057 case types$1._new:
3058 return this.parseNew()
3059
3060 case types$1.backQuote:
3061 return this.parseTemplate()
3062
3063 case types$1._import:
3064 if (this.options.ecmaVersion >= 11) {
3065 return this.parseExprImport(forNew)
3066 } else {
3067 return this.unexpected()
3068 }
3069
3070 default:
3071 return this.parseExprAtomDefault()
3072 }
3073 };
3074
3075 pp$5.parseExprAtomDefault = function() {
3076 this.unexpected();
3077 };
3078
3079 pp$5.parseExprImport = function(forNew) {
3080 var node = this.startNode();
3081
3082 // Consume `import` as an identifier for `import.meta`.
3083 // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
3084 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
3085 this.next();
3086
3087 if (this.type === types$1.parenL && !forNew) {
3088 return this.parseDynamicImport(node)
3089 } else if (this.type === types$1.dot) {
3090 var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
3091 meta.name = "import";
3092 node.meta = this.finishNode(meta, "Identifier");
3093 return this.parseImportMeta(node)
3094 } else {
3095 this.unexpected();
3096 }
3097 };
3098
3099 pp$5.parseDynamicImport = function(node) {
3100 this.next(); // skip `(`
3101
3102 // Parse node.source.
3103 node.source = this.parseMaybeAssign();
3104
3105 if (this.options.ecmaVersion >= 16) {
3106 if (!this.eat(types$1.parenR)) {
3107 this.expect(types$1.comma);
3108 if (!this.afterTrailingComma(types$1.parenR)) {
3109 node.options = this.parseMaybeAssign();
3110 if (!this.eat(types$1.parenR)) {
3111 this.expect(types$1.comma);
3112 if (!this.afterTrailingComma(types$1.parenR)) {
3113 this.unexpected();
3114 }
3115 }
3116 } else {
3117 node.options = null;
3118 }
3119 } else {
3120 node.options = null;
3121 }
3122 } else {
3123 // Verify ending.
3124 if (!this.eat(types$1.parenR)) {
3125 var errorPos = this.start;
3126 if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {
3127 this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
3128 } else {
3129 this.unexpected(errorPos);
3130 }
3131 }
3132 }
3133
3134 return this.finishNode(node, "ImportExpression")
3135 };
3136
3137 pp$5.parseImportMeta = function(node) {
3138 this.next(); // skip `.`
3139
3140 var containsEsc = this.containsEsc;
3141 node.property = this.parseIdent(true);
3142
3143 if (node.property.name !== "meta")
3144 { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
3145 if (containsEsc)
3146 { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
3147 if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
3148 { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
3149
3150 return this.finishNode(node, "MetaProperty")
3151 };
3152
3153 pp$5.parseLiteral = function(value) {
3154 var node = this.startNode();
3155 node.value = value;
3156 node.raw = this.input.slice(this.start, this.end);
3157 if (node.raw.charCodeAt(node.raw.length - 1) === 110)
3158 { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); }
3159 this.next();
3160 return this.finishNode(node, "Literal")
3161 };
3162
3163 pp$5.parseParenExpression = function() {
3164 this.expect(types$1.parenL);
3165 var val = this.parseExpression();
3166 this.expect(types$1.parenR);
3167 return val
3168 };
3169
3170 pp$5.shouldParseArrow = function(exprList) {
3171 return !this.canInsertSemicolon()
3172 };
3173
3174 pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {
3175 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
3176 if (this.options.ecmaVersion >= 6) {
3177 this.next();
3178
3179 var innerStartPos = this.start, innerStartLoc = this.startLoc;
3180 var exprList = [], first = true, lastIsComma = false;
3181 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
3182 this.yieldPos = 0;
3183 this.awaitPos = 0;
3184 // Do not save awaitIdentPos to allow checking awaits nested in parameters
3185 while (this.type !== types$1.parenR) {
3186 first ? first = false : this.expect(types$1.comma);
3187 if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {
3188 lastIsComma = true;
3189 break
3190 } else if (this.type === types$1.ellipsis) {
3191 spreadStart = this.start;
3192 exprList.push(this.parseParenItem(this.parseRestBinding()));
3193 if (this.type === types$1.comma) {
3194 this.raiseRecoverable(
3195 this.start,
3196 "Comma is not permitted after the rest element"
3197 );
3198 }
3199 break
3200 } else {
3201 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
3202 }
3203 }
3204 var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;
3205 this.expect(types$1.parenR);
3206
3207 if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) {
3208 this.checkPatternErrors(refDestructuringErrors, false);
3209 this.checkYieldAwaitInDefaultParams();
3210 this.yieldPos = oldYieldPos;
3211 this.awaitPos = oldAwaitPos;
3212 return this.parseParenArrowList(startPos, startLoc, exprList, forInit)
3213 }
3214
3215 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
3216 if (spreadStart) { this.unexpected(spreadStart); }
3217 this.checkExpressionErrors(refDestructuringErrors, true);
3218 this.yieldPos = oldYieldPos || this.yieldPos;
3219 this.awaitPos = oldAwaitPos || this.awaitPos;
3220
3221 if (exprList.length > 1) {
3222 val = this.startNodeAt(innerStartPos, innerStartLoc);
3223 val.expressions = exprList;
3224 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
3225 } else {
3226 val = exprList[0];
3227 }
3228 } else {
3229 val = this.parseParenExpression();
3230 }
3231
3232 if (this.options.preserveParens) {
3233 var par = this.startNodeAt(startPos, startLoc);
3234 par.expression = val;
3235 return this.finishNode(par, "ParenthesizedExpression")
3236 } else {
3237 return val
3238 }
3239 };
3240
3241 pp$5.parseParenItem = function(item) {
3242 return item
3243 };
3244
3245 pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {
3246 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)
3247 };
3248
3249 // New's precedence is slightly tricky. It must allow its argument to
3250 // be a `[]` or dot subscript expression, but not a call — at least,
3251 // not without wrapping it in parentheses. Thus, it uses the noCalls
3252 // argument to parseSubscripts to prevent it from consuming the
3253 // argument list.
3254
3255 var empty = [];
3256
3257 pp$5.parseNew = function() {
3258 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
3259 var node = this.startNode();
3260 this.next();
3261 if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) {
3262 var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
3263 meta.name = "new";
3264 node.meta = this.finishNode(meta, "Identifier");
3265 this.next();
3266 var containsEsc = this.containsEsc;
3267 node.property = this.parseIdent(true);
3268 if (node.property.name !== "target")
3269 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
3270 if (containsEsc)
3271 { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
3272 if (!this.allowNewDotTarget)
3273 { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); }
3274 return this.finishNode(node, "MetaProperty")
3275 }
3276 var startPos = this.start, startLoc = this.startLoc;
3277 node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false);
3278 if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }
3279 else { node.arguments = empty; }
3280 return this.finishNode(node, "NewExpression")
3281 };
3282
3283 // Parse template expression.
3284
3285 pp$5.parseTemplateElement = function(ref) {
3286 var isTagged = ref.isTagged;
3287
3288 var elem = this.startNode();
3289 if (this.type === types$1.invalidTemplate) {
3290 if (!isTagged) {
3291 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
3292 }
3293 elem.value = {
3294 raw: this.value.replace(/\r\n?/g, "\n"),
3295 cooked: null
3296 };
3297 } else {
3298 elem.value = {
3299 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
3300 cooked: this.value
3301 };
3302 }
3303 this.next();
3304 elem.tail = this.type === types$1.backQuote;
3305 return this.finishNode(elem, "TemplateElement")
3306 };
3307
3308 pp$5.parseTemplate = function(ref) {
3309 if ( ref === void 0 ) ref = {};
3310 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
3311
3312 var node = this.startNode();
3313 this.next();
3314 node.expressions = [];
3315 var curElt = this.parseTemplateElement({isTagged: isTagged});
3316 node.quasis = [curElt];
3317 while (!curElt.tail) {
3318 if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); }
3319 this.expect(types$1.dollarBraceL);
3320 node.expressions.push(this.parseExpression());
3321 this.expect(types$1.braceR);
3322 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
3323 }
3324 this.next();
3325 return this.finishNode(node, "TemplateLiteral")
3326 };
3327
3328 pp$5.isAsyncProp = function(prop) {
3329 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
3330 (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&
3331 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
3332 };
3333
3334 // Parse an object literal or binding pattern.
3335
3336 pp$5.parseObj = function(isPattern, refDestructuringErrors) {
3337 var node = this.startNode(), first = true, propHash = {};
3338 node.properties = [];
3339 this.next();
3340 while (!this.eat(types$1.braceR)) {
3341 if (!first) {
3342 this.expect(types$1.comma);
3343 if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }
3344 } else { first = false; }
3345
3346 var prop = this.parseProperty(isPattern, refDestructuringErrors);
3347 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
3348 node.properties.push(prop);
3349 }
3350 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
3351 };
3352
3353 pp$5.parseProperty = function(isPattern, refDestructuringErrors) {
3354 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
3355 if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {
3356 if (isPattern) {
3357 prop.argument = this.parseIdent(false);
3358 if (this.type === types$1.comma) {
3359 this.raiseRecoverable(this.start, "Comma is not permitted after the rest element");
3360 }
3361 return this.finishNode(prop, "RestElement")
3362 }
3363 // Parse argument.
3364 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
3365 // To disallow trailing comma via `this.toAssignable()`.
3366 if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
3367 refDestructuringErrors.trailingComma = this.start;
3368 }
3369 // Finish
3370 return this.finishNode(prop, "SpreadElement")
3371 }
3372 if (this.options.ecmaVersion >= 6) {
3373 prop.method = false;
3374 prop.shorthand = false;
3375 if (isPattern || refDestructuringErrors) {
3376 startPos = this.start;
3377 startLoc = this.startLoc;
3378 }
3379 if (!isPattern)
3380 { isGenerator = this.eat(types$1.star); }
3381 }
3382 var containsEsc = this.containsEsc;
3383 this.parsePropertyName(prop);
3384 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
3385 isAsync = true;
3386 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);
3387 this.parsePropertyName(prop);
3388 } else {
3389 isAsync = false;
3390 }
3391 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
3392 return this.finishNode(prop, "Property")
3393 };
3394
3395 pp$5.parseGetterSetter = function(prop) {
3396 var kind = prop.key.name;
3397 this.parsePropertyName(prop);
3398 prop.value = this.parseMethod(false);
3399 prop.kind = kind;
3400 var paramCount = prop.kind === "get" ? 0 : 1;
3401 if (prop.value.params.length !== paramCount) {
3402 var start = prop.value.start;
3403 if (prop.kind === "get")
3404 { this.raiseRecoverable(start, "getter should have no params"); }
3405 else
3406 { this.raiseRecoverable(start, "setter should have exactly one param"); }
3407 } else {
3408 if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
3409 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
3410 }
3411 };
3412
3413 pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
3414 if ((isGenerator || isAsync) && this.type === types$1.colon)
3415 { this.unexpected(); }
3416
3417 if (this.eat(types$1.colon)) {
3418 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
3419 prop.kind = "init";
3420 } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {
3421 if (isPattern) { this.unexpected(); }
3422 prop.method = true;
3423 prop.value = this.parseMethod(isGenerator, isAsync);
3424 prop.kind = "init";
3425 } else if (!isPattern && !containsEsc &&
3426 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
3427 (prop.key.name === "get" || prop.key.name === "set") &&
3428 (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {
3429 if (isGenerator || isAsync) { this.unexpected(); }
3430 this.parseGetterSetter(prop);
3431 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
3432 if (isGenerator || isAsync) { this.unexpected(); }
3433 this.checkUnreserved(prop.key);
3434 if (prop.key.name === "await" && !this.awaitIdentPos)
3435 { this.awaitIdentPos = startPos; }
3436 if (isPattern) {
3437 prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
3438 } else if (this.type === types$1.eq && refDestructuringErrors) {
3439 if (refDestructuringErrors.shorthandAssign < 0)
3440 { refDestructuringErrors.shorthandAssign = this.start; }
3441 prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
3442 } else {
3443 prop.value = this.copyNode(prop.key);
3444 }
3445 prop.kind = "init";
3446 prop.shorthand = true;
3447 } else { this.unexpected(); }
3448 };
3449
3450 pp$5.parsePropertyName = function(prop) {
3451 if (this.options.ecmaVersion >= 6) {
3452 if (this.eat(types$1.bracketL)) {
3453 prop.computed = true;
3454 prop.key = this.parseMaybeAssign();
3455 this.expect(types$1.bracketR);
3456 return prop.key
3457 } else {
3458 prop.computed = false;
3459 }
3460 }
3461 return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
3462 };
3463
3464 // Initialize empty function node.
3465
3466 pp$5.initFunction = function(node) {
3467 node.id = null;
3468 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
3469 if (this.options.ecmaVersion >= 8) { node.async = false; }
3470 };
3471
3472 // Parse object or class method.
3473
3474 pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
3475 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
3476
3477 this.initFunction(node);
3478 if (this.options.ecmaVersion >= 6)
3479 { node.generator = isGenerator; }
3480 if (this.options.ecmaVersion >= 8)
3481 { node.async = !!isAsync; }
3482
3483 this.yieldPos = 0;
3484 this.awaitPos = 0;
3485 this.awaitIdentPos = 0;
3486 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
3487
3488 this.expect(types$1.parenL);
3489 node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
3490 this.checkYieldAwaitInDefaultParams();
3491 this.parseFunctionBody(node, false, true, false);
3492
3493 this.yieldPos = oldYieldPos;
3494 this.awaitPos = oldAwaitPos;
3495 this.awaitIdentPos = oldAwaitIdentPos;
3496 return this.finishNode(node, "FunctionExpression")
3497 };
3498
3499 // Parse arrow function expression with given parameters.
3500
3501 pp$5.parseArrowExpression = function(node, params, isAsync, forInit) {
3502 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
3503
3504 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
3505 this.initFunction(node);
3506 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
3507
3508 this.yieldPos = 0;
3509 this.awaitPos = 0;
3510 this.awaitIdentPos = 0;
3511
3512 node.params = this.toAssignableList(params, true);
3513 this.parseFunctionBody(node, true, false, forInit);
3514
3515 this.yieldPos = oldYieldPos;
3516 this.awaitPos = oldAwaitPos;
3517 this.awaitIdentPos = oldAwaitIdentPos;
3518 return this.finishNode(node, "ArrowFunctionExpression")
3519 };
3520
3521 // Parse function body and check parameters.
3522
3523 pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {
3524 var isExpression = isArrowFunction && this.type !== types$1.braceL;
3525 var oldStrict = this.strict, useStrict = false;
3526
3527 if (isExpression) {
3528 node.body = this.parseMaybeAssign(forInit);
3529 node.expression = true;
3530 this.checkParams(node, false);
3531 } else {
3532 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
3533 if (!oldStrict || nonSimple) {
3534 useStrict = this.strictDirective(this.end);
3535 // If this is a strict mode function, verify that argument names
3536 // are not repeated, and it does not try to bind the words `eval`
3537 // or `arguments`.
3538 if (useStrict && nonSimple)
3539 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
3540 }
3541 // Start a new scope with regard to labels and the `inFunction`
3542 // flag (restore them to their old value afterwards).
3543 var oldLabels = this.labels;
3544 this.labels = [];
3545 if (useStrict) { this.strict = true; }
3546
3547 // Add the params to varDeclaredNames to ensure that an error is thrown
3548 // if a let/const declaration in the function clashes with one of the params.
3549 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
3550 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
3551 if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }
3552 node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
3553 node.expression = false;
3554 this.adaptDirectivePrologue(node.body.body);
3555 this.labels = oldLabels;
3556 }
3557 this.exitScope();
3558 };
3559
3560 pp$5.isSimpleParamList = function(params) {
3561 for (var i = 0, list = params; i < list.length; i += 1)
3562 {
3563 var param = list[i];
3564
3565 if (param.type !== "Identifier") { return false
3566 } }
3567 return true
3568 };
3569
3570 // Checks function params for various disallowed patterns such as using "eval"
3571 // or "arguments" and duplicate parameters.
3572
3573 pp$5.checkParams = function(node, allowDuplicates) {
3574 var nameHash = Object.create(null);
3575 for (var i = 0, list = node.params; i < list.length; i += 1)
3576 {
3577 var param = list[i];
3578
3579 this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);
3580 }
3581 };
3582
3583 // Parses a comma-separated list of expressions, and returns them as
3584 // an array. `close` is the token type that ends the list, and
3585 // `allowEmpty` can be turned on to allow subsequent commas with
3586 // nothing in between them to be parsed as `null` (which is needed
3587 // for array literals).
3588
3589 pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
3590 var elts = [], first = true;
3591 while (!this.eat(close)) {
3592 if (!first) {
3593 this.expect(types$1.comma);
3594 if (allowTrailingComma && this.afterTrailingComma(close)) { break }
3595 } else { first = false; }
3596
3597 var elt = (void 0);
3598 if (allowEmpty && this.type === types$1.comma)
3599 { elt = null; }
3600 else if (this.type === types$1.ellipsis) {
3601 elt = this.parseSpread(refDestructuringErrors);
3602 if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)
3603 { refDestructuringErrors.trailingComma = this.start; }
3604 } else {
3605 elt = this.parseMaybeAssign(false, refDestructuringErrors);
3606 }
3607 elts.push(elt);
3608 }
3609 return elts
3610 };
3611
3612 pp$5.checkUnreserved = function(ref) {
3613 var start = ref.start;
3614 var end = ref.end;
3615 var name = ref.name;
3616
3617 if (this.inGenerator && name === "yield")
3618 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
3619 if (this.inAsync && name === "await")
3620 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
3621 if (!(this.currentThisScope().flags & SCOPE_VAR) && name === "arguments")
3622 { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
3623 if (this.inClassStaticBlock && (name === "arguments" || name === "await"))
3624 { this.raise(start, ("Cannot use " + name + " in class static initialization block")); }
3625 if (this.keywords.test(name))
3626 { this.raise(start, ("Unexpected keyword '" + name + "'")); }
3627 if (this.options.ecmaVersion < 6 &&
3628 this.input.slice(start, end).indexOf("\\") !== -1) { return }
3629 var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
3630 if (re.test(name)) {
3631 if (!this.inAsync && name === "await")
3632 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
3633 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
3634 }
3635 };
3636
3637 // Parse the next token as an identifier. If `liberal` is true (used
3638 // when parsing properties), it will also convert keywords into
3639 // identifiers.
3640
3641 pp$5.parseIdent = function(liberal) {
3642 var node = this.parseIdentNode();
3643 this.next(!!liberal);
3644 this.finishNode(node, "Identifier");
3645 if (!liberal) {
3646 this.checkUnreserved(node);
3647 if (node.name === "await" && !this.awaitIdentPos)
3648 { this.awaitIdentPos = node.start; }
3649 }
3650 return node
3651 };
3652
3653 pp$5.parseIdentNode = function() {
3654 var node = this.startNode();
3655 if (this.type === types$1.name) {
3656 node.name = this.value;
3657 } else if (this.type.keyword) {
3658 node.name = this.type.keyword;
3659
3660 // To fix https://github.com/acornjs/acorn/issues/575
3661 // `class` and `function` keywords push new context into this.context.
3662 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
3663 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
3664 if ((node.name === "class" || node.name === "function") &&
3665 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
3666 this.context.pop();
3667 }
3668 this.type = types$1.name;
3669 } else {
3670 this.unexpected();
3671 }
3672 return node
3673 };
3674
3675 pp$5.parsePrivateIdent = function() {
3676 var node = this.startNode();
3677 if (this.type === types$1.privateId) {
3678 node.name = this.value;
3679 } else {
3680 this.unexpected();
3681 }
3682 this.next();
3683 this.finishNode(node, "PrivateIdentifier");
3684
3685 // For validating existence
3686 if (this.options.checkPrivateFields) {
3687 if (this.privateNameStack.length === 0) {
3688 this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
3689 } else {
3690 this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
3691 }
3692 }
3693
3694 return node
3695 };
3696
3697 // Parses yield expression inside generator.
3698
3699 pp$5.parseYield = function(forInit) {
3700 if (!this.yieldPos) { this.yieldPos = this.start; }
3701
3702 var node = this.startNode();
3703 this.next();
3704 if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {
3705 node.delegate = false;
3706 node.argument = null;
3707 } else {
3708 node.delegate = this.eat(types$1.star);
3709 node.argument = this.parseMaybeAssign(forInit);
3710 }
3711 return this.finishNode(node, "YieldExpression")
3712 };
3713
3714 pp$5.parseAwait = function(forInit) {
3715 if (!this.awaitPos) { this.awaitPos = this.start; }
3716
3717 var node = this.startNode();
3718 this.next();
3719 node.argument = this.parseMaybeUnary(null, true, false, forInit);
3720 return this.finishNode(node, "AwaitExpression")
3721 };
3722
3723 var pp$4 = Parser.prototype;
3724
3725 // This function is used to raise exceptions on parse errors. It
3726 // takes an offset integer (into the current `input`) to indicate
3727 // the location of the error, attaches the position to the end
3728 // of the error message, and then raises a `SyntaxError` with that
3729 // message.
3730
3731 pp$4.raise = function(pos, message) {
3732 var loc = getLineInfo(this.input, pos);
3733 message += " (" + loc.line + ":" + loc.column + ")";
3734 if (this.sourceFile) {
3735 message += " in " + this.sourceFile;
3736 }
3737 var err = new SyntaxError(message);
3738 err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
3739 throw err
3740 };
3741
3742 pp$4.raiseRecoverable = pp$4.raise;
3743
3744 pp$4.curPosition = function() {
3745 if (this.options.locations) {
3746 return new Position(this.curLine, this.pos - this.lineStart)
3747 }
3748 };
3749
3750 var pp$3 = Parser.prototype;
3751
3752 var Scope = function Scope(flags) {
3753 this.flags = flags;
3754 // A list of var-declared names in the current lexical scope
3755 this.var = [];
3756 // A list of lexically-declared names in the current lexical scope
3757 this.lexical = [];
3758 // A list of lexically-declared FunctionDeclaration names in the current lexical scope
3759 this.functions = [];
3760 };
3761
3762 // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
3763
3764 pp$3.enterScope = function(flags) {
3765 this.scopeStack.push(new Scope(flags));
3766 };
3767
3768 pp$3.exitScope = function() {
3769 this.scopeStack.pop();
3770 };
3771
3772 // The spec says:
3773 // > At the top level of a function, or script, function declarations are
3774 // > treated like var declarations rather than like lexical declarations.
3775 pp$3.treatFunctionsAsVarInScope = function(scope) {
3776 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
3777 };
3778
3779 pp$3.declareName = function(name, bindingType, pos) {
3780 var redeclared = false;
3781 if (bindingType === BIND_LEXICAL) {
3782 var scope = this.currentScope();
3783 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
3784 scope.lexical.push(name);
3785 if (this.inModule && (scope.flags & SCOPE_TOP))
3786 { delete this.undefinedExports[name]; }
3787 } else if (bindingType === BIND_SIMPLE_CATCH) {
3788 var scope$1 = this.currentScope();
3789 scope$1.lexical.push(name);
3790 } else if (bindingType === BIND_FUNCTION) {
3791 var scope$2 = this.currentScope();
3792 if (this.treatFunctionsAsVar)
3793 { redeclared = scope$2.lexical.indexOf(name) > -1; }
3794 else
3795 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
3796 scope$2.functions.push(name);
3797 } else {
3798 for (var i = this.scopeStack.length - 1; i >= 0; --i) {
3799 var scope$3 = this.scopeStack[i];
3800 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
3801 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
3802 redeclared = true;
3803 break
3804 }
3805 scope$3.var.push(name);
3806 if (this.inModule && (scope$3.flags & SCOPE_TOP))
3807 { delete this.undefinedExports[name]; }
3808 if (scope$3.flags & SCOPE_VAR) { break }
3809 }
3810 }
3811 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
3812 };
3813
3814 pp$3.checkLocalExport = function(id) {
3815 // scope.functions must be empty as Module code is always strict.
3816 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
3817 this.scopeStack[0].var.indexOf(id.name) === -1) {
3818 this.undefinedExports[id.name] = id;
3819 }
3820 };
3821
3822 pp$3.currentScope = function() {
3823 return this.scopeStack[this.scopeStack.length - 1]
3824 };
3825
3826 pp$3.currentVarScope = function() {
3827 for (var i = this.scopeStack.length - 1;; i--) {
3828 var scope = this.scopeStack[i];
3829 if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK)) { return scope }
3830 }
3831 };
3832
3833 // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
3834 pp$3.currentThisScope = function() {
3835 for (var i = this.scopeStack.length - 1;; i--) {
3836 var scope = this.scopeStack[i];
3837 if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK) &&
3838 !(scope.flags & SCOPE_ARROW)) { return scope }
3839 }
3840 };
3841
3842 var Node = function Node(parser, pos, loc) {
3843 this.type = "";
3844 this.start = pos;
3845 this.end = 0;
3846 if (parser.options.locations)
3847 { this.loc = new SourceLocation(parser, loc); }
3848 if (parser.options.directSourceFile)
3849 { this.sourceFile = parser.options.directSourceFile; }
3850 if (parser.options.ranges)
3851 { this.range = [pos, 0]; }
3852 };
3853
3854 // Start an AST node, attaching a start offset.
3855
3856 var pp$2 = Parser.prototype;
3857
3858 pp$2.startNode = function() {
3859 return new Node(this, this.start, this.startLoc)
3860 };
3861
3862 pp$2.startNodeAt = function(pos, loc) {
3863 return new Node(this, pos, loc)
3864 };
3865
3866 // Finish an AST node, adding `type` and `end` properties.
3867
3868 function finishNodeAt(node, type, pos, loc) {
3869 node.type = type;
3870 node.end = pos;
3871 if (this.options.locations)
3872 { node.loc.end = loc; }
3873 if (this.options.ranges)
3874 { node.range[1] = pos; }
3875 return node
3876 }
3877
3878 pp$2.finishNode = function(node, type) {
3879 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
3880 };
3881
3882 // Finish node at given position
3883
3884 pp$2.finishNodeAt = function(node, type, pos, loc) {
3885 return finishNodeAt.call(this, node, type, pos, loc)
3886 };
3887
3888 pp$2.copyNode = function(node) {
3889 var newNode = new Node(this, node.start, this.startLoc);
3890 for (var prop in node) { newNode[prop] = node[prop]; }
3891 return newNode
3892 };
3893
3894 // This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually!
3895 var scriptValuesAddedInUnicode = "Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz";
3896
3897 // This file contains Unicode properties extracted from the ECMAScript specification.
3898 // The lists are extracted like so:
3899 // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
3900
3901 // #table-binary-unicode-properties
3902 var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";
3903 var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
3904 var ecma11BinaryProperties = ecma10BinaryProperties;
3905 var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict";
3906 var ecma13BinaryProperties = ecma12BinaryProperties;
3907 var ecma14BinaryProperties = ecma13BinaryProperties;
3908
3909 var unicodeBinaryProperties = {
3910 9: ecma9BinaryProperties,
3911 10: ecma10BinaryProperties,
3912 11: ecma11BinaryProperties,
3913 12: ecma12BinaryProperties,
3914 13: ecma13BinaryProperties,
3915 14: ecma14BinaryProperties
3916 };
3917
3918 // #table-binary-unicode-properties-of-strings
3919 var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji";
3920
3921 var unicodeBinaryPropertiesOfStrings = {
3922 9: "",
3923 10: "",
3924 11: "",
3925 12: "",
3926 13: "",
3927 14: ecma14BinaryPropertiesOfStrings
3928 };
3929
3930 // #table-unicode-general-category-values
3931 var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";
3932
3933 // #table-unicode-script-values
3934 var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";
3935 var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
3936 var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
3937 var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi";
3938 var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith";
3939 var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode;
3940
3941 var unicodeScriptValues = {
3942 9: ecma9ScriptValues,
3943 10: ecma10ScriptValues,
3944 11: ecma11ScriptValues,
3945 12: ecma12ScriptValues,
3946 13: ecma13ScriptValues,
3947 14: ecma14ScriptValues
3948 };
3949
3950 var data = {};
3951 function buildUnicodeData(ecmaVersion) {
3952 var d = data[ecmaVersion] = {
3953 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
3954 binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]),
3955 nonBinary: {
3956 General_Category: wordsRegexp(unicodeGeneralCategoryValues),
3957 Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
3958 }
3959 };
3960 d.nonBinary.Script_Extensions = d.nonBinary.Script;
3961
3962 d.nonBinary.gc = d.nonBinary.General_Category;
3963 d.nonBinary.sc = d.nonBinary.Script;
3964 d.nonBinary.scx = d.nonBinary.Script_Extensions;
3965 }
3966
3967 for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) {
3968 var ecmaVersion = list[i];
3969
3970 buildUnicodeData(ecmaVersion);
3971 }
3972
3973 var pp$1 = Parser.prototype;
3974
3975 // Track disjunction structure to determine whether a duplicate
3976 // capture group name is allowed because it is in a separate branch.
3977 var BranchID = function BranchID(parent, base) {
3978 // Parent disjunction branch
3979 this.parent = parent;
3980 // Identifies this set of sibling branches
3981 this.base = base || this;
3982 };
3983
3984 BranchID.prototype.separatedFrom = function separatedFrom (alt) {
3985 // A branch is separate from another branch if they or any of
3986 // their parents are siblings in a given disjunction
3987 for (var self = this; self; self = self.parent) {
3988 for (var other = alt; other; other = other.parent) {
3989 if (self.base === other.base && self !== other) { return true }
3990 }
3991 }
3992 return false
3993 };
3994
3995 BranchID.prototype.sibling = function sibling () {
3996 return new BranchID(this.parent, this.base)
3997 };
3998
3999 var RegExpValidationState = function RegExpValidationState(parser) {
4000 this.parser = parser;
4001 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : "");
4002 this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];
4003 this.source = "";
4004 this.flags = "";
4005 this.start = 0;
4006 this.switchU = false;
4007 this.switchV = false;
4008 this.switchN = false;
4009 this.pos = 0;
4010 this.lastIntValue = 0;
4011 this.lastStringValue = "";
4012 this.lastAssertionIsQuantifiable = false;
4013 this.numCapturingParens = 0;
4014 this.maxBackReference = 0;
4015 this.groupNames = Object.create(null);
4016 this.backReferenceNames = [];
4017 this.branchID = null;
4018 };
4019
4020 RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
4021 var unicodeSets = flags.indexOf("v") !== -1;
4022 var unicode = flags.indexOf("u") !== -1;
4023 this.start = start | 0;
4024 this.source = pattern + "";
4025 this.flags = flags;
4026 if (unicodeSets && this.parser.options.ecmaVersion >= 15) {
4027 this.switchU = true;
4028 this.switchV = true;
4029 this.switchN = true;
4030 } else {
4031 this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
4032 this.switchV = false;
4033 this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
4034 }
4035 };
4036
4037 RegExpValidationState.prototype.raise = function raise (message) {
4038 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
4039 };
4040
4041 // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
4042 // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
4043 RegExpValidationState.prototype.at = function at (i, forceU) {
4044 if ( forceU === void 0 ) forceU = false;
4045
4046 var s = this.source;
4047 var l = s.length;
4048 if (i >= l) {
4049 return -1
4050 }
4051 var c = s.charCodeAt(i);
4052 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
4053 return c
4054 }
4055 var next = s.charCodeAt(i + 1);
4056 return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
4057 };
4058
4059 RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
4060 if ( forceU === void 0 ) forceU = false;
4061
4062 var s = this.source;
4063 var l = s.length;
4064 if (i >= l) {
4065 return l
4066 }
4067 var c = s.charCodeAt(i), next;
4068 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
4069 (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
4070 return i + 1
4071 }
4072 return i + 2
4073 };
4074
4075 RegExpValidationState.prototype.current = function current (forceU) {
4076 if ( forceU === void 0 ) forceU = false;
4077
4078 return this.at(this.pos, forceU)
4079 };
4080
4081 RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
4082 if ( forceU === void 0 ) forceU = false;
4083
4084 return this.at(this.nextIndex(this.pos, forceU), forceU)
4085 };
4086
4087 RegExpValidationState.prototype.advance = function advance (forceU) {
4088 if ( forceU === void 0 ) forceU = false;
4089
4090 this.pos = this.nextIndex(this.pos, forceU);
4091 };
4092
4093 RegExpValidationState.prototype.eat = function eat (ch, forceU) {
4094 if ( forceU === void 0 ) forceU = false;
4095
4096 if (this.current(forceU) === ch) {
4097 this.advance(forceU);
4098 return true
4099 }
4100 return false
4101 };
4102
4103 RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) {
4104 if ( forceU === void 0 ) forceU = false;
4105
4106 var pos = this.pos;
4107 for (var i = 0, list = chs; i < list.length; i += 1) {
4108 var ch = list[i];
4109
4110 var current = this.at(pos, forceU);
4111 if (current === -1 || current !== ch) {
4112 return false
4113 }
4114 pos = this.nextIndex(pos, forceU);
4115 }
4116 this.pos = pos;
4117 return true
4118 };
4119
4120 /**
4121 * Validate the flags part of a given RegExpLiteral.
4122 *
4123 * @param {RegExpValidationState} state The state to validate RegExp.
4124 * @returns {void}
4125 */
4126 pp$1.validateRegExpFlags = function(state) {
4127 var validFlags = state.validFlags;
4128 var flags = state.flags;
4129
4130 var u = false;
4131 var v = false;
4132
4133 for (var i = 0; i < flags.length; i++) {
4134 var flag = flags.charAt(i);
4135 if (validFlags.indexOf(flag) === -1) {
4136 this.raise(state.start, "Invalid regular expression flag");
4137 }
4138 if (flags.indexOf(flag, i + 1) > -1) {
4139 this.raise(state.start, "Duplicate regular expression flag");
4140 }
4141 if (flag === "u") { u = true; }
4142 if (flag === "v") { v = true; }
4143 }
4144 if (this.options.ecmaVersion >= 15 && u && v) {
4145 this.raise(state.start, "Invalid regular expression flag");
4146 }
4147 };
4148
4149 function hasProp(obj) {
4150 for (var _ in obj) { return true }
4151 return false
4152 }
4153
4154 /**
4155 * Validate the pattern part of a given RegExpLiteral.
4156 *
4157 * @param {RegExpValidationState} state The state to validate RegExp.
4158 * @returns {void}
4159 */
4160 pp$1.validateRegExpPattern = function(state) {
4161 this.regexp_pattern(state);
4162
4163 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
4164 // parsing contains a |GroupName|, reparse with the goal symbol
4165 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
4166 // exception if _P_ did not conform to the grammar, if any elements of _P_
4167 // were not matched by the parse, or if any Early Error conditions exist.
4168 if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) {
4169 state.switchN = true;
4170 this.regexp_pattern(state);
4171 }
4172 };
4173
4174 // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
4175 pp$1.regexp_pattern = function(state) {
4176 state.pos = 0;
4177 state.lastIntValue = 0;
4178 state.lastStringValue = "";
4179 state.lastAssertionIsQuantifiable = false;
4180 state.numCapturingParens = 0;
4181 state.maxBackReference = 0;
4182 state.groupNames = Object.create(null);
4183 state.backReferenceNames.length = 0;
4184 state.branchID = null;
4185
4186 this.regexp_disjunction(state);
4187
4188 if (state.pos !== state.source.length) {
4189 // Make the same messages as V8.
4190 if (state.eat(0x29 /* ) */)) {
4191 state.raise("Unmatched ')'");
4192 }
4193 if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
4194 state.raise("Lone quantifier brackets");
4195 }
4196 }
4197 if (state.maxBackReference > state.numCapturingParens) {
4198 state.raise("Invalid escape");
4199 }
4200 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
4201 var name = list[i];
4202
4203 if (!state.groupNames[name]) {
4204 state.raise("Invalid named capture referenced");
4205 }
4206 }
4207 };
4208
4209 // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
4210 pp$1.regexp_disjunction = function(state) {
4211 var trackDisjunction = this.options.ecmaVersion >= 16;
4212 if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); }
4213 this.regexp_alternative(state);
4214 while (state.eat(0x7C /* | */)) {
4215 if (trackDisjunction) { state.branchID = state.branchID.sibling(); }
4216 this.regexp_alternative(state);
4217 }
4218 if (trackDisjunction) { state.branchID = state.branchID.parent; }
4219
4220 // Make the same message as V8.
4221 if (this.regexp_eatQuantifier(state, true)) {
4222 state.raise("Nothing to repeat");
4223 }
4224 if (state.eat(0x7B /* { */)) {
4225 state.raise("Lone quantifier brackets");
4226 }
4227 };
4228
4229 // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
4230 pp$1.regexp_alternative = function(state) {
4231 while (state.pos < state.source.length && this.regexp_eatTerm(state)) {}
4232 };
4233
4234 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
4235 pp$1.regexp_eatTerm = function(state) {
4236 if (this.regexp_eatAssertion(state)) {
4237 // Handle `QuantifiableAssertion Quantifier` alternative.
4238 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
4239 // is a QuantifiableAssertion.
4240 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
4241 // Make the same message as V8.
4242 if (state.switchU) {
4243 state.raise("Invalid quantifier");
4244 }
4245 }
4246 return true
4247 }
4248
4249 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
4250 this.regexp_eatQuantifier(state);
4251 return true
4252 }
4253
4254 return false
4255 };
4256
4257 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
4258 pp$1.regexp_eatAssertion = function(state) {
4259 var start = state.pos;
4260 state.lastAssertionIsQuantifiable = false;
4261
4262 // ^, $
4263 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
4264 return true
4265 }
4266
4267 // \b \B
4268 if (state.eat(0x5C /* \ */)) {
4269 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
4270 return true
4271 }
4272 state.pos = start;
4273 }
4274
4275 // Lookahead / Lookbehind
4276 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
4277 var lookbehind = false;
4278 if (this.options.ecmaVersion >= 9) {
4279 lookbehind = state.eat(0x3C /* < */);
4280 }
4281 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
4282 this.regexp_disjunction(state);
4283 if (!state.eat(0x29 /* ) */)) {
4284 state.raise("Unterminated group");
4285 }
4286 state.lastAssertionIsQuantifiable = !lookbehind;
4287 return true
4288 }
4289 }
4290
4291 state.pos = start;
4292 return false
4293 };
4294
4295 // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
4296 pp$1.regexp_eatQuantifier = function(state, noError) {
4297 if ( noError === void 0 ) noError = false;
4298
4299 if (this.regexp_eatQuantifierPrefix(state, noError)) {
4300 state.eat(0x3F /* ? */);
4301 return true
4302 }
4303 return false
4304 };
4305
4306 // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
4307 pp$1.regexp_eatQuantifierPrefix = function(state, noError) {
4308 return (
4309 state.eat(0x2A /* * */) ||
4310 state.eat(0x2B /* + */) ||
4311 state.eat(0x3F /* ? */) ||
4312 this.regexp_eatBracedQuantifier(state, noError)
4313 )
4314 };
4315 pp$1.regexp_eatBracedQuantifier = function(state, noError) {
4316 var start = state.pos;
4317 if (state.eat(0x7B /* { */)) {
4318 var min = 0, max = -1;
4319 if (this.regexp_eatDecimalDigits(state)) {
4320 min = state.lastIntValue;
4321 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
4322 max = state.lastIntValue;
4323 }
4324 if (state.eat(0x7D /* } */)) {
4325 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
4326 if (max !== -1 && max < min && !noError) {
4327 state.raise("numbers out of order in {} quantifier");
4328 }
4329 return true
4330 }
4331 }
4332 if (state.switchU && !noError) {
4333 state.raise("Incomplete quantifier");
4334 }
4335 state.pos = start;
4336 }
4337 return false
4338 };
4339
4340 // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
4341 pp$1.regexp_eatAtom = function(state) {
4342 return (
4343 this.regexp_eatPatternCharacters(state) ||
4344 state.eat(0x2E /* . */) ||
4345 this.regexp_eatReverseSolidusAtomEscape(state) ||
4346 this.regexp_eatCharacterClass(state) ||
4347 this.regexp_eatUncapturingGroup(state) ||
4348 this.regexp_eatCapturingGroup(state)
4349 )
4350 };
4351 pp$1.regexp_eatReverseSolidusAtomEscape = function(state) {
4352 var start = state.pos;
4353 if (state.eat(0x5C /* \ */)) {
4354 if (this.regexp_eatAtomEscape(state)) {
4355 return true
4356 }
4357 state.pos = start;
4358 }
4359 return false
4360 };
4361 pp$1.regexp_eatUncapturingGroup = function(state) {
4362 var start = state.pos;
4363 if (state.eat(0x28 /* ( */)) {
4364 if (state.eat(0x3F /* ? */)) {
4365 if (this.options.ecmaVersion >= 16) {
4366 var addModifiers = this.regexp_eatModifiers(state);
4367 var hasHyphen = state.eat(0x2D /* - */);
4368 if (addModifiers || hasHyphen) {
4369 for (var i = 0; i < addModifiers.length; i++) {
4370 var modifier = addModifiers.charAt(i);
4371 if (addModifiers.indexOf(modifier, i + 1) > -1) {
4372 state.raise("Duplicate regular expression modifiers");
4373 }
4374 }
4375 if (hasHyphen) {
4376 var removeModifiers = this.regexp_eatModifiers(state);
4377 if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) {
4378 state.raise("Invalid regular expression modifiers");
4379 }
4380 for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) {
4381 var modifier$1 = removeModifiers.charAt(i$1);
4382 if (
4383 removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 ||
4384 addModifiers.indexOf(modifier$1) > -1
4385 ) {
4386 state.raise("Duplicate regular expression modifiers");
4387 }
4388 }
4389 }
4390 }
4391 }
4392 if (state.eat(0x3A /* : */)) {
4393 this.regexp_disjunction(state);
4394 if (state.eat(0x29 /* ) */)) {
4395 return true
4396 }
4397 state.raise("Unterminated group");
4398 }
4399 }
4400 state.pos = start;
4401 }
4402 return false
4403 };
4404 pp$1.regexp_eatCapturingGroup = function(state) {
4405 if (state.eat(0x28 /* ( */)) {
4406 if (this.options.ecmaVersion >= 9) {
4407 this.regexp_groupSpecifier(state);
4408 } else if (state.current() === 0x3F /* ? */) {
4409 state.raise("Invalid group");
4410 }
4411 this.regexp_disjunction(state);
4412 if (state.eat(0x29 /* ) */)) {
4413 state.numCapturingParens += 1;
4414 return true
4415 }
4416 state.raise("Unterminated group");
4417 }
4418 return false
4419 };
4420 // RegularExpressionModifiers ::
4421 // [empty]
4422 // RegularExpressionModifiers RegularExpressionModifier
4423 pp$1.regexp_eatModifiers = function(state) {
4424 var modifiers = "";
4425 var ch = 0;
4426 while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) {
4427 modifiers += codePointToString(ch);
4428 state.advance();
4429 }
4430 return modifiers
4431 };
4432 // RegularExpressionModifier :: one of
4433 // `i` `m` `s`
4434 function isRegularExpressionModifier(ch) {
4435 return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */
4436 }
4437
4438 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
4439 pp$1.regexp_eatExtendedAtom = function(state) {
4440 return (
4441 state.eat(0x2E /* . */) ||
4442 this.regexp_eatReverseSolidusAtomEscape(state) ||
4443 this.regexp_eatCharacterClass(state) ||
4444 this.regexp_eatUncapturingGroup(state) ||
4445 this.regexp_eatCapturingGroup(state) ||
4446 this.regexp_eatInvalidBracedQuantifier(state) ||
4447 this.regexp_eatExtendedPatternCharacter(state)
4448 )
4449 };
4450
4451 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
4452 pp$1.regexp_eatInvalidBracedQuantifier = function(state) {
4453 if (this.regexp_eatBracedQuantifier(state, true)) {
4454 state.raise("Nothing to repeat");
4455 }
4456 return false
4457 };
4458
4459 // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
4460 pp$1.regexp_eatSyntaxCharacter = function(state) {
4461 var ch = state.current();
4462 if (isSyntaxCharacter(ch)) {
4463 state.lastIntValue = ch;
4464 state.advance();
4465 return true
4466 }
4467 return false
4468 };
4469 function isSyntaxCharacter(ch) {
4470 return (
4471 ch === 0x24 /* $ */ ||
4472 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
4473 ch === 0x2E /* . */ ||
4474 ch === 0x3F /* ? */ ||
4475 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
4476 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
4477 )
4478 }
4479
4480 // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
4481 // But eat eager.
4482 pp$1.regexp_eatPatternCharacters = function(state) {
4483 var start = state.pos;
4484 var ch = 0;
4485 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
4486 state.advance();
4487 }
4488 return state.pos !== start
4489 };
4490
4491 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
4492 pp$1.regexp_eatExtendedPatternCharacter = function(state) {
4493 var ch = state.current();
4494 if (
4495 ch !== -1 &&
4496 ch !== 0x24 /* $ */ &&
4497 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
4498 ch !== 0x2E /* . */ &&
4499 ch !== 0x3F /* ? */ &&
4500 ch !== 0x5B /* [ */ &&
4501 ch !== 0x5E /* ^ */ &&
4502 ch !== 0x7C /* | */
4503 ) {
4504 state.advance();
4505 return true
4506 }
4507 return false
4508 };
4509
4510 // GroupSpecifier ::
4511 // [empty]
4512 // `?` GroupName
4513 pp$1.regexp_groupSpecifier = function(state) {
4514 if (state.eat(0x3F /* ? */)) {
4515 if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); }
4516 var trackDisjunction = this.options.ecmaVersion >= 16;
4517 var known = state.groupNames[state.lastStringValue];
4518 if (known) {
4519 if (trackDisjunction) {
4520 for (var i = 0, list = known; i < list.length; i += 1) {
4521 var altID = list[i];
4522
4523 if (!altID.separatedFrom(state.branchID))
4524 { state.raise("Duplicate capture group name"); }
4525 }
4526 } else {
4527 state.raise("Duplicate capture group name");
4528 }
4529 }
4530 if (trackDisjunction) {
4531 (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID);
4532 } else {
4533 state.groupNames[state.lastStringValue] = true;
4534 }
4535 }
4536 };
4537
4538 // GroupName ::
4539 // `<` RegExpIdentifierName `>`
4540 // Note: this updates `state.lastStringValue` property with the eaten name.
4541 pp$1.regexp_eatGroupName = function(state) {
4542 state.lastStringValue = "";
4543 if (state.eat(0x3C /* < */)) {
4544 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
4545 return true
4546 }
4547 state.raise("Invalid capture group name");
4548 }
4549 return false
4550 };
4551
4552 // RegExpIdentifierName ::
4553 // RegExpIdentifierStart
4554 // RegExpIdentifierName RegExpIdentifierPart
4555 // Note: this updates `state.lastStringValue` property with the eaten name.
4556 pp$1.regexp_eatRegExpIdentifierName = function(state) {
4557 state.lastStringValue = "";
4558 if (this.regexp_eatRegExpIdentifierStart(state)) {
4559 state.lastStringValue += codePointToString(state.lastIntValue);
4560 while (this.regexp_eatRegExpIdentifierPart(state)) {
4561 state.lastStringValue += codePointToString(state.lastIntValue);
4562 }
4563 return true
4564 }
4565 return false
4566 };
4567
4568 // RegExpIdentifierStart ::
4569 // UnicodeIDStart
4570 // `$`
4571 // `_`
4572 // `\` RegExpUnicodeEscapeSequence[+U]
4573 pp$1.regexp_eatRegExpIdentifierStart = function(state) {
4574 var start = state.pos;
4575 var forceU = this.options.ecmaVersion >= 11;
4576 var ch = state.current(forceU);
4577 state.advance(forceU);
4578
4579 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
4580 ch = state.lastIntValue;
4581 }
4582 if (isRegExpIdentifierStart(ch)) {
4583 state.lastIntValue = ch;
4584 return true
4585 }
4586
4587 state.pos = start;
4588 return false
4589 };
4590 function isRegExpIdentifierStart(ch) {
4591 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
4592 }
4593
4594 // RegExpIdentifierPart ::
4595 // UnicodeIDContinue
4596 // `$`
4597 // `_`
4598 // `\` RegExpUnicodeEscapeSequence[+U]
4599 // <ZWNJ>
4600 // <ZWJ>
4601 pp$1.regexp_eatRegExpIdentifierPart = function(state) {
4602 var start = state.pos;
4603 var forceU = this.options.ecmaVersion >= 11;
4604 var ch = state.current(forceU);
4605 state.advance(forceU);
4606
4607 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
4608 ch = state.lastIntValue;
4609 }
4610 if (isRegExpIdentifierPart(ch)) {
4611 state.lastIntValue = ch;
4612 return true
4613 }
4614
4615 state.pos = start;
4616 return false
4617 };
4618 function isRegExpIdentifierPart(ch) {
4619 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
4620 }
4621
4622 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
4623 pp$1.regexp_eatAtomEscape = function(state) {
4624 if (
4625 this.regexp_eatBackReference(state) ||
4626 this.regexp_eatCharacterClassEscape(state) ||
4627 this.regexp_eatCharacterEscape(state) ||
4628 (state.switchN && this.regexp_eatKGroupName(state))
4629 ) {
4630 return true
4631 }
4632 if (state.switchU) {
4633 // Make the same message as V8.
4634 if (state.current() === 0x63 /* c */) {
4635 state.raise("Invalid unicode escape");
4636 }
4637 state.raise("Invalid escape");
4638 }
4639 return false
4640 };
4641 pp$1.regexp_eatBackReference = function(state) {
4642 var start = state.pos;
4643 if (this.regexp_eatDecimalEscape(state)) {
4644 var n = state.lastIntValue;
4645 if (state.switchU) {
4646 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
4647 if (n > state.maxBackReference) {
4648 state.maxBackReference = n;
4649 }
4650 return true
4651 }
4652 if (n <= state.numCapturingParens) {
4653 return true
4654 }
4655 state.pos = start;
4656 }
4657 return false
4658 };
4659 pp$1.regexp_eatKGroupName = function(state) {
4660 if (state.eat(0x6B /* k */)) {
4661 if (this.regexp_eatGroupName(state)) {
4662 state.backReferenceNames.push(state.lastStringValue);
4663 return true
4664 }
4665 state.raise("Invalid named reference");
4666 }
4667 return false
4668 };
4669
4670 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
4671 pp$1.regexp_eatCharacterEscape = function(state) {
4672 return (
4673 this.regexp_eatControlEscape(state) ||
4674 this.regexp_eatCControlLetter(state) ||
4675 this.regexp_eatZero(state) ||
4676 this.regexp_eatHexEscapeSequence(state) ||
4677 this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
4678 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
4679 this.regexp_eatIdentityEscape(state)
4680 )
4681 };
4682 pp$1.regexp_eatCControlLetter = function(state) {
4683 var start = state.pos;
4684 if (state.eat(0x63 /* c */)) {
4685 if (this.regexp_eatControlLetter(state)) {
4686 return true
4687 }
4688 state.pos = start;
4689 }
4690 return false
4691 };
4692 pp$1.regexp_eatZero = function(state) {
4693 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
4694 state.lastIntValue = 0;
4695 state.advance();
4696 return true
4697 }
4698 return false
4699 };
4700
4701 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
4702 pp$1.regexp_eatControlEscape = function(state) {
4703 var ch = state.current();
4704 if (ch === 0x74 /* t */) {
4705 state.lastIntValue = 0x09; /* \t */
4706 state.advance();
4707 return true
4708 }
4709 if (ch === 0x6E /* n */) {
4710 state.lastIntValue = 0x0A; /* \n */
4711 state.advance();
4712 return true
4713 }
4714 if (ch === 0x76 /* v */) {
4715 state.lastIntValue = 0x0B; /* \v */
4716 state.advance();
4717 return true
4718 }
4719 if (ch === 0x66 /* f */) {
4720 state.lastIntValue = 0x0C; /* \f */
4721 state.advance();
4722 return true
4723 }
4724 if (ch === 0x72 /* r */) {
4725 state.lastIntValue = 0x0D; /* \r */
4726 state.advance();
4727 return true
4728 }
4729 return false
4730 };
4731
4732 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
4733 pp$1.regexp_eatControlLetter = function(state) {
4734 var ch = state.current();
4735 if (isControlLetter(ch)) {
4736 state.lastIntValue = ch % 0x20;
4737 state.advance();
4738 return true
4739 }
4740 return false
4741 };
4742 function isControlLetter(ch) {
4743 return (
4744 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
4745 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
4746 )
4747 }
4748
4749 // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
4750 pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
4751 if ( forceU === void 0 ) forceU = false;
4752
4753 var start = state.pos;
4754 var switchU = forceU || state.switchU;
4755
4756 if (state.eat(0x75 /* u */)) {
4757 if (this.regexp_eatFixedHexDigits(state, 4)) {
4758 var lead = state.lastIntValue;
4759 if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
4760 var leadSurrogateEnd = state.pos;
4761 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
4762 var trail = state.lastIntValue;
4763 if (trail >= 0xDC00 && trail <= 0xDFFF) {
4764 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
4765 return true
4766 }
4767 }
4768 state.pos = leadSurrogateEnd;
4769 state.lastIntValue = lead;
4770 }
4771 return true
4772 }
4773 if (
4774 switchU &&
4775 state.eat(0x7B /* { */) &&
4776 this.regexp_eatHexDigits(state) &&
4777 state.eat(0x7D /* } */) &&
4778 isValidUnicode(state.lastIntValue)
4779 ) {
4780 return true
4781 }
4782 if (switchU) {
4783 state.raise("Invalid unicode escape");
4784 }
4785 state.pos = start;
4786 }
4787
4788 return false
4789 };
4790 function isValidUnicode(ch) {
4791 return ch >= 0 && ch <= 0x10FFFF
4792 }
4793
4794 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
4795 pp$1.regexp_eatIdentityEscape = function(state) {
4796 if (state.switchU) {
4797 if (this.regexp_eatSyntaxCharacter(state)) {
4798 return true
4799 }
4800 if (state.eat(0x2F /* / */)) {
4801 state.lastIntValue = 0x2F; /* / */
4802 return true
4803 }
4804 return false
4805 }
4806
4807 var ch = state.current();
4808 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
4809 state.lastIntValue = ch;
4810 state.advance();
4811 return true
4812 }
4813
4814 return false
4815 };
4816
4817 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
4818 pp$1.regexp_eatDecimalEscape = function(state) {
4819 state.lastIntValue = 0;
4820 var ch = state.current();
4821 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
4822 do {
4823 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
4824 state.advance();
4825 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
4826 return true
4827 }
4828 return false
4829 };
4830
4831 // Return values used by character set parsing methods, needed to
4832 // forbid negation of sets that can match strings.
4833 var CharSetNone = 0; // Nothing parsed
4834 var CharSetOk = 1; // Construct parsed, cannot contain strings
4835 var CharSetString = 2; // Construct parsed, can contain strings
4836
4837 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
4838 pp$1.regexp_eatCharacterClassEscape = function(state) {
4839 var ch = state.current();
4840
4841 if (isCharacterClassEscape(ch)) {
4842 state.lastIntValue = -1;
4843 state.advance();
4844 return CharSetOk
4845 }
4846
4847 var negate = false;
4848 if (
4849 state.switchU &&
4850 this.options.ecmaVersion >= 9 &&
4851 ((negate = ch === 0x50 /* P */) || ch === 0x70 /* p */)
4852 ) {
4853 state.lastIntValue = -1;
4854 state.advance();
4855 var result;
4856 if (
4857 state.eat(0x7B /* { */) &&
4858 (result = this.regexp_eatUnicodePropertyValueExpression(state)) &&
4859 state.eat(0x7D /* } */)
4860 ) {
4861 if (negate && result === CharSetString) { state.raise("Invalid property name"); }
4862 return result
4863 }
4864 state.raise("Invalid property name");
4865 }
4866
4867 return CharSetNone
4868 };
4869
4870 function isCharacterClassEscape(ch) {
4871 return (
4872 ch === 0x64 /* d */ ||
4873 ch === 0x44 /* D */ ||
4874 ch === 0x73 /* s */ ||
4875 ch === 0x53 /* S */ ||
4876 ch === 0x77 /* w */ ||
4877 ch === 0x57 /* W */
4878 )
4879 }
4880
4881 // UnicodePropertyValueExpression ::
4882 // UnicodePropertyName `=` UnicodePropertyValue
4883 // LoneUnicodePropertyNameOrValue
4884 pp$1.regexp_eatUnicodePropertyValueExpression = function(state) {
4885 var start = state.pos;
4886
4887 // UnicodePropertyName `=` UnicodePropertyValue
4888 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
4889 var name = state.lastStringValue;
4890 if (this.regexp_eatUnicodePropertyValue(state)) {
4891 var value = state.lastStringValue;
4892 this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
4893 return CharSetOk
4894 }
4895 }
4896 state.pos = start;
4897
4898 // LoneUnicodePropertyNameOrValue
4899 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
4900 var nameOrValue = state.lastStringValue;
4901 return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue)
4902 }
4903 return CharSetNone
4904 };
4905
4906 pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
4907 if (!hasOwn(state.unicodeProperties.nonBinary, name))
4908 { state.raise("Invalid property name"); }
4909 if (!state.unicodeProperties.nonBinary[name].test(value))
4910 { state.raise("Invalid property value"); }
4911 };
4912
4913 pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
4914 if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk }
4915 if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString }
4916 state.raise("Invalid property name");
4917 };
4918
4919 // UnicodePropertyName ::
4920 // UnicodePropertyNameCharacters
4921 pp$1.regexp_eatUnicodePropertyName = function(state) {
4922 var ch = 0;
4923 state.lastStringValue = "";
4924 while (isUnicodePropertyNameCharacter(ch = state.current())) {
4925 state.lastStringValue += codePointToString(ch);
4926 state.advance();
4927 }
4928 return state.lastStringValue !== ""
4929 };
4930
4931 function isUnicodePropertyNameCharacter(ch) {
4932 return isControlLetter(ch) || ch === 0x5F /* _ */
4933 }
4934
4935 // UnicodePropertyValue ::
4936 // UnicodePropertyValueCharacters
4937 pp$1.regexp_eatUnicodePropertyValue = function(state) {
4938 var ch = 0;
4939 state.lastStringValue = "";
4940 while (isUnicodePropertyValueCharacter(ch = state.current())) {
4941 state.lastStringValue += codePointToString(ch);
4942 state.advance();
4943 }
4944 return state.lastStringValue !== ""
4945 };
4946 function isUnicodePropertyValueCharacter(ch) {
4947 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
4948 }
4949
4950 // LoneUnicodePropertyNameOrValue ::
4951 // UnicodePropertyValueCharacters
4952 pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
4953 return this.regexp_eatUnicodePropertyValue(state)
4954 };
4955
4956 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
4957 pp$1.regexp_eatCharacterClass = function(state) {
4958 if (state.eat(0x5B /* [ */)) {
4959 var negate = state.eat(0x5E /* ^ */);
4960 var result = this.regexp_classContents(state);
4961 if (!state.eat(0x5D /* ] */))
4962 { state.raise("Unterminated character class"); }
4963 if (negate && result === CharSetString)
4964 { state.raise("Negated character class may contain strings"); }
4965 return true
4966 }
4967 return false
4968 };
4969
4970 // https://tc39.es/ecma262/#prod-ClassContents
4971 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
4972 pp$1.regexp_classContents = function(state) {
4973 if (state.current() === 0x5D /* ] */) { return CharSetOk }
4974 if (state.switchV) { return this.regexp_classSetExpression(state) }
4975 this.regexp_nonEmptyClassRanges(state);
4976 return CharSetOk
4977 };
4978
4979 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
4980 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
4981 pp$1.regexp_nonEmptyClassRanges = function(state) {
4982 while (this.regexp_eatClassAtom(state)) {
4983 var left = state.lastIntValue;
4984 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
4985 var right = state.lastIntValue;
4986 if (state.switchU && (left === -1 || right === -1)) {
4987 state.raise("Invalid character class");
4988 }
4989 if (left !== -1 && right !== -1 && left > right) {
4990 state.raise("Range out of order in character class");
4991 }
4992 }
4993 }
4994 };
4995
4996 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
4997 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
4998 pp$1.regexp_eatClassAtom = function(state) {
4999 var start = state.pos;
5000
5001 if (state.eat(0x5C /* \ */)) {
5002 if (this.regexp_eatClassEscape(state)) {
5003 return true
5004 }
5005 if (state.switchU) {
5006 // Make the same message as V8.
5007 var ch$1 = state.current();
5008 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
5009 state.raise("Invalid class escape");
5010 }
5011 state.raise("Invalid escape");
5012 }
5013 state.pos = start;
5014 }
5015
5016 var ch = state.current();
5017 if (ch !== 0x5D /* ] */) {
5018 state.lastIntValue = ch;
5019 state.advance();
5020 return true
5021 }
5022
5023 return false
5024 };
5025
5026 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
5027 pp$1.regexp_eatClassEscape = function(state) {
5028 var start = state.pos;
5029
5030 if (state.eat(0x62 /* b */)) {
5031 state.lastIntValue = 0x08; /* <BS> */
5032 return true
5033 }
5034
5035 if (state.switchU && state.eat(0x2D /* - */)) {
5036 state.lastIntValue = 0x2D; /* - */
5037 return true
5038 }
5039
5040 if (!state.switchU && state.eat(0x63 /* c */)) {
5041 if (this.regexp_eatClassControlLetter(state)) {
5042 return true
5043 }
5044 state.pos = start;
5045 }
5046
5047 return (
5048 this.regexp_eatCharacterClassEscape(state) ||
5049 this.regexp_eatCharacterEscape(state)
5050 )
5051 };
5052
5053 // https://tc39.es/ecma262/#prod-ClassSetExpression
5054 // https://tc39.es/ecma262/#prod-ClassUnion
5055 // https://tc39.es/ecma262/#prod-ClassIntersection
5056 // https://tc39.es/ecma262/#prod-ClassSubtraction
5057 pp$1.regexp_classSetExpression = function(state) {
5058 var result = CharSetOk, subResult;
5059 if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) {
5060 if (subResult === CharSetString) { result = CharSetString; }
5061 // https://tc39.es/ecma262/#prod-ClassIntersection
5062 var start = state.pos;
5063 while (state.eatChars([0x26, 0x26] /* && */)) {
5064 if (
5065 state.current() !== 0x26 /* & */ &&
5066 (subResult = this.regexp_eatClassSetOperand(state))
5067 ) {
5068 if (subResult !== CharSetString) { result = CharSetOk; }
5069 continue
5070 }
5071 state.raise("Invalid character in character class");
5072 }
5073 if (start !== state.pos) { return result }
5074 // https://tc39.es/ecma262/#prod-ClassSubtraction
5075 while (state.eatChars([0x2D, 0x2D] /* -- */)) {
5076 if (this.regexp_eatClassSetOperand(state)) { continue }
5077 state.raise("Invalid character in character class");
5078 }
5079 if (start !== state.pos) { return result }
5080 } else {
5081 state.raise("Invalid character in character class");
5082 }
5083 // https://tc39.es/ecma262/#prod-ClassUnion
5084 for (;;) {
5085 if (this.regexp_eatClassSetRange(state)) { continue }
5086 subResult = this.regexp_eatClassSetOperand(state);
5087 if (!subResult) { return result }
5088 if (subResult === CharSetString) { result = CharSetString; }
5089 }
5090 };
5091
5092 // https://tc39.es/ecma262/#prod-ClassSetRange
5093 pp$1.regexp_eatClassSetRange = function(state) {
5094 var start = state.pos;
5095 if (this.regexp_eatClassSetCharacter(state)) {
5096 var left = state.lastIntValue;
5097 if (state.eat(0x2D /* - */) && this.regexp_eatClassSetCharacter(state)) {
5098 var right = state.lastIntValue;
5099 if (left !== -1 && right !== -1 && left > right) {
5100 state.raise("Range out of order in character class");
5101 }
5102 return true
5103 }
5104 state.pos = start;
5105 }
5106 return false
5107 };
5108
5109 // https://tc39.es/ecma262/#prod-ClassSetOperand
5110 pp$1.regexp_eatClassSetOperand = function(state) {
5111 if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk }
5112 return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state)
5113 };
5114
5115 // https://tc39.es/ecma262/#prod-NestedClass
5116 pp$1.regexp_eatNestedClass = function(state) {
5117 var start = state.pos;
5118 if (state.eat(0x5B /* [ */)) {
5119 var negate = state.eat(0x5E /* ^ */);
5120 var result = this.regexp_classContents(state);
5121 if (state.eat(0x5D /* ] */)) {
5122 if (negate && result === CharSetString) {
5123 state.raise("Negated character class may contain strings");
5124 }
5125 return result
5126 }
5127 state.pos = start;
5128 }
5129 if (state.eat(0x5C /* \ */)) {
5130 var result$1 = this.regexp_eatCharacterClassEscape(state);
5131 if (result$1) {
5132 return result$1
5133 }
5134 state.pos = start;
5135 }
5136 return null
5137 };
5138
5139 // https://tc39.es/ecma262/#prod-ClassStringDisjunction
5140 pp$1.regexp_eatClassStringDisjunction = function(state) {
5141 var start = state.pos;
5142 if (state.eatChars([0x5C, 0x71] /* \q */)) {
5143 if (state.eat(0x7B /* { */)) {
5144 var result = this.regexp_classStringDisjunctionContents(state);
5145 if (state.eat(0x7D /* } */)) {
5146 return result
5147 }
5148 } else {
5149 // Make the same message as V8.
5150 state.raise("Invalid escape");
5151 }
5152 state.pos = start;
5153 }
5154 return null
5155 };
5156
5157 // https://tc39.es/ecma262/#prod-ClassStringDisjunctionContents
5158 pp$1.regexp_classStringDisjunctionContents = function(state) {
5159 var result = this.regexp_classString(state);
5160 while (state.eat(0x7C /* | */)) {
5161 if (this.regexp_classString(state) === CharSetString) { result = CharSetString; }
5162 }
5163 return result
5164 };
5165
5166 // https://tc39.es/ecma262/#prod-ClassString
5167 // https://tc39.es/ecma262/#prod-NonEmptyClassString
5168 pp$1.regexp_classString = function(state) {
5169 var count = 0;
5170 while (this.regexp_eatClassSetCharacter(state)) { count++; }
5171 return count === 1 ? CharSetOk : CharSetString
5172 };
5173
5174 // https://tc39.es/ecma262/#prod-ClassSetCharacter
5175 pp$1.regexp_eatClassSetCharacter = function(state) {
5176 var start = state.pos;
5177 if (state.eat(0x5C /* \ */)) {
5178 if (
5179 this.regexp_eatCharacterEscape(state) ||
5180 this.regexp_eatClassSetReservedPunctuator(state)
5181 ) {
5182 return true
5183 }
5184 if (state.eat(0x62 /* b */)) {
5185 state.lastIntValue = 0x08; /* <BS> */
5186 return true
5187 }
5188 state.pos = start;
5189 return false
5190 }
5191 var ch = state.current();
5192 if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false }
5193 if (isClassSetSyntaxCharacter(ch)) { return false }
5194 state.advance();
5195 state.lastIntValue = ch;
5196 return true
5197 };
5198
5199 // https://tc39.es/ecma262/#prod-ClassSetReservedDoublePunctuator
5200 function isClassSetReservedDoublePunctuatorCharacter(ch) {
5201 return (
5202 ch === 0x21 /* ! */ ||
5203 ch >= 0x23 /* # */ && ch <= 0x26 /* & */ ||
5204 ch >= 0x2A /* * */ && ch <= 0x2C /* , */ ||
5205 ch === 0x2E /* . */ ||
5206 ch >= 0x3A /* : */ && ch <= 0x40 /* @ */ ||
5207 ch === 0x5E /* ^ */ ||
5208 ch === 0x60 /* ` */ ||
5209 ch === 0x7E /* ~ */
5210 )
5211 }
5212
5213 // https://tc39.es/ecma262/#prod-ClassSetSyntaxCharacter
5214 function isClassSetSyntaxCharacter(ch) {
5215 return (
5216 ch === 0x28 /* ( */ ||
5217 ch === 0x29 /* ) */ ||
5218 ch === 0x2D /* - */ ||
5219 ch === 0x2F /* / */ ||
5220 ch >= 0x5B /* [ */ && ch <= 0x5D /* ] */ ||
5221 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
5222 )
5223 }
5224
5225 // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator
5226 pp$1.regexp_eatClassSetReservedPunctuator = function(state) {
5227 var ch = state.current();
5228 if (isClassSetReservedPunctuator(ch)) {
5229 state.lastIntValue = ch;
5230 state.advance();
5231 return true
5232 }
5233 return false
5234 };
5235
5236 // https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator
5237 function isClassSetReservedPunctuator(ch) {
5238 return (
5239 ch === 0x21 /* ! */ ||
5240 ch === 0x23 /* # */ ||
5241 ch === 0x25 /* % */ ||
5242 ch === 0x26 /* & */ ||
5243 ch === 0x2C /* , */ ||
5244 ch === 0x2D /* - */ ||
5245 ch >= 0x3A /* : */ && ch <= 0x3E /* > */ ||
5246 ch === 0x40 /* @ */ ||
5247 ch === 0x60 /* ` */ ||
5248 ch === 0x7E /* ~ */
5249 )
5250 }
5251
5252 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
5253 pp$1.regexp_eatClassControlLetter = function(state) {
5254 var ch = state.current();
5255 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
5256 state.lastIntValue = ch % 0x20;
5257 state.advance();
5258 return true
5259 }
5260 return false
5261 };
5262
5263 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
5264 pp$1.regexp_eatHexEscapeSequence = function(state) {
5265 var start = state.pos;
5266 if (state.eat(0x78 /* x */)) {
5267 if (this.regexp_eatFixedHexDigits(state, 2)) {
5268 return true
5269 }
5270 if (state.switchU) {
5271 state.raise("Invalid escape");
5272 }
5273 state.pos = start;
5274 }
5275 return false
5276 };
5277
5278 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
5279 pp$1.regexp_eatDecimalDigits = function(state) {
5280 var start = state.pos;
5281 var ch = 0;
5282 state.lastIntValue = 0;
5283 while (isDecimalDigit(ch = state.current())) {
5284 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
5285 state.advance();
5286 }
5287 return state.pos !== start
5288 };
5289 function isDecimalDigit(ch) {
5290 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
5291 }
5292
5293 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
5294 pp$1.regexp_eatHexDigits = function(state) {
5295 var start = state.pos;
5296 var ch = 0;
5297 state.lastIntValue = 0;
5298 while (isHexDigit(ch = state.current())) {
5299 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
5300 state.advance();
5301 }
5302 return state.pos !== start
5303 };
5304 function isHexDigit(ch) {
5305 return (
5306 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
5307 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
5308 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
5309 )
5310 }
5311 function hexToInt(ch) {
5312 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
5313 return 10 + (ch - 0x41 /* A */)
5314 }
5315 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
5316 return 10 + (ch - 0x61 /* a */)
5317 }
5318 return ch - 0x30 /* 0 */
5319 }
5320
5321 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
5322 // Allows only 0-377(octal) i.e. 0-255(decimal).
5323 pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {
5324 if (this.regexp_eatOctalDigit(state)) {
5325 var n1 = state.lastIntValue;
5326 if (this.regexp_eatOctalDigit(state)) {
5327 var n2 = state.lastIntValue;
5328 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
5329 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
5330 } else {
5331 state.lastIntValue = n1 * 8 + n2;
5332 }
5333 } else {
5334 state.lastIntValue = n1;
5335 }
5336 return true
5337 }
5338 return false
5339 };
5340
5341 // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
5342 pp$1.regexp_eatOctalDigit = function(state) {
5343 var ch = state.current();
5344 if (isOctalDigit(ch)) {
5345 state.lastIntValue = ch - 0x30; /* 0 */
5346 state.advance();
5347 return true
5348 }
5349 state.lastIntValue = 0;
5350 return false
5351 };
5352 function isOctalDigit(ch) {
5353 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
5354 }
5355
5356 // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
5357 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
5358 // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
5359 pp$1.regexp_eatFixedHexDigits = function(state, length) {
5360 var start = state.pos;
5361 state.lastIntValue = 0;
5362 for (var i = 0; i < length; ++i) {
5363 var ch = state.current();
5364 if (!isHexDigit(ch)) {
5365 state.pos = start;
5366 return false
5367 }
5368 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
5369 state.advance();
5370 }
5371 return true
5372 };
5373
5374 // Object type used to represent tokens. Note that normally, tokens
5375 // simply exist as properties on the parser object. This is only
5376 // used for the onToken callback and the external tokenizer.
5377
5378 var Token = function Token(p) {
5379 this.type = p.type;
5380 this.value = p.value;
5381 this.start = p.start;
5382 this.end = p.end;
5383 if (p.options.locations)
5384 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
5385 if (p.options.ranges)
5386 { this.range = [p.start, p.end]; }
5387 };
5388
5389 // ## Tokenizer
5390
5391 var pp = Parser.prototype;
5392
5393 // Move to the next token
5394
5395 pp.next = function(ignoreEscapeSequenceInKeyword) {
5396 if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
5397 { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
5398 if (this.options.onToken)
5399 { this.options.onToken(new Token(this)); }
5400
5401 this.lastTokEnd = this.end;
5402 this.lastTokStart = this.start;
5403 this.lastTokEndLoc = this.endLoc;
5404 this.lastTokStartLoc = this.startLoc;
5405 this.nextToken();
5406 };
5407
5408 pp.getToken = function() {
5409 this.next();
5410 return new Token(this)
5411 };
5412
5413 // If we're in an ES6 environment, make parsers iterable
5414 if (typeof Symbol !== "undefined")
5415 { pp[Symbol.iterator] = function() {
5416 var this$1$1 = this;
5417
5418 return {
5419 next: function () {
5420 var token = this$1$1.getToken();
5421 return {
5422 done: token.type === types$1.eof,
5423 value: token
5424 }
5425 }
5426 }
5427 }; }
5428
5429 // Toggle strict mode. Re-reads the next number or string to please
5430 // pedantic tests (`"use strict"; 010;` should fail).
5431
5432 // Read a single token, updating the parser object's token-related
5433 // properties.
5434
5435 pp.nextToken = function() {
5436 var curContext = this.curContext();
5437 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
5438
5439 this.start = this.pos;
5440 if (this.options.locations) { this.startLoc = this.curPosition(); }
5441 if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }
5442
5443 if (curContext.override) { return curContext.override(this) }
5444 else { this.readToken(this.fullCharCodeAtPos()); }
5445 };
5446
5447 pp.readToken = function(code) {
5448 // Identifier or keyword. '\uXXXX' sequences are allowed in
5449 // identifiers, so '\' also dispatches to that.
5450 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
5451 { return this.readWord() }
5452
5453 return this.getTokenFromCode(code)
5454 };
5455
5456 pp.fullCharCodeAtPos = function() {
5457 var code = this.input.charCodeAt(this.pos);
5458 if (code <= 0xd7ff || code >= 0xdc00) { return code }
5459 var next = this.input.charCodeAt(this.pos + 1);
5460 return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
5461 };
5462
5463 pp.skipBlockComment = function() {
5464 var startLoc = this.options.onComment && this.curPosition();
5465 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
5466 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
5467 this.pos = end + 2;
5468 if (this.options.locations) {
5469 for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {
5470 ++this.curLine;
5471 pos = this.lineStart = nextBreak;
5472 }
5473 }
5474 if (this.options.onComment)
5475 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
5476 startLoc, this.curPosition()); }
5477 };
5478
5479 pp.skipLineComment = function(startSkip) {
5480 var start = this.pos;
5481 var startLoc = this.options.onComment && this.curPosition();
5482 var ch = this.input.charCodeAt(this.pos += startSkip);
5483 while (this.pos < this.input.length && !isNewLine(ch)) {
5484 ch = this.input.charCodeAt(++this.pos);
5485 }
5486 if (this.options.onComment)
5487 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
5488 startLoc, this.curPosition()); }
5489 };
5490
5491 // Called at the start of the parse and after every token. Skips
5492 // whitespace and comments, and.
5493
5494 pp.skipSpace = function() {
5495 loop: while (this.pos < this.input.length) {
5496 var ch = this.input.charCodeAt(this.pos);
5497 switch (ch) {
5498 case 32: case 160: // ' '
5499 ++this.pos;
5500 break
5501 case 13:
5502 if (this.input.charCodeAt(this.pos + 1) === 10) {
5503 ++this.pos;
5504 }
5505 case 10: case 8232: case 8233:
5506 ++this.pos;
5507 if (this.options.locations) {
5508 ++this.curLine;
5509 this.lineStart = this.pos;
5510 }
5511 break
5512 case 47: // '/'
5513 switch (this.input.charCodeAt(this.pos + 1)) {
5514 case 42: // '*'
5515 this.skipBlockComment();
5516 break
5517 case 47:
5518 this.skipLineComment(2);
5519 break
5520 default:
5521 break loop
5522 }
5523 break
5524 default:
5525 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
5526 ++this.pos;
5527 } else {
5528 break loop
5529 }
5530 }
5531 }
5532 };
5533
5534 // Called at the end of every token. Sets `end`, `val`, and
5535 // maintains `context` and `exprAllowed`, and skips the space after
5536 // the token, so that the next one's `start` will point at the
5537 // right position.
5538
5539 pp.finishToken = function(type, val) {
5540 this.end = this.pos;
5541 if (this.options.locations) { this.endLoc = this.curPosition(); }
5542 var prevType = this.type;
5543 this.type = type;
5544 this.value = val;
5545
5546 this.updateContext(prevType);
5547 };
5548
5549 // ### Token reading
5550
5551 // This is the function that is called to fetch the next token. It
5552 // is somewhat obscure, because it works in character codes rather
5553 // than characters, and because operator parsing has been inlined
5554 // into it.
5555 //
5556 // All in the name of speed.
5557 //
5558 pp.readToken_dot = function() {
5559 var next = this.input.charCodeAt(this.pos + 1);
5560 if (next >= 48 && next <= 57) { return this.readNumber(true) }
5561 var next2 = this.input.charCodeAt(this.pos + 2);
5562 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
5563 this.pos += 3;
5564 return this.finishToken(types$1.ellipsis)
5565 } else {
5566 ++this.pos;
5567 return this.finishToken(types$1.dot)
5568 }
5569 };
5570
5571 pp.readToken_slash = function() { // '/'
5572 var next = this.input.charCodeAt(this.pos + 1);
5573 if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
5574 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5575 return this.finishOp(types$1.slash, 1)
5576 };
5577
5578 pp.readToken_mult_modulo_exp = function(code) { // '%*'
5579 var next = this.input.charCodeAt(this.pos + 1);
5580 var size = 1;
5581 var tokentype = code === 42 ? types$1.star : types$1.modulo;
5582
5583 // exponentiation operator ** and **=
5584 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
5585 ++size;
5586 tokentype = types$1.starstar;
5587 next = this.input.charCodeAt(this.pos + 2);
5588 }
5589
5590 if (next === 61) { return this.finishOp(types$1.assign, size + 1) }
5591 return this.finishOp(tokentype, size)
5592 };
5593
5594 pp.readToken_pipe_amp = function(code) { // '|&'
5595 var next = this.input.charCodeAt(this.pos + 1);
5596 if (next === code) {
5597 if (this.options.ecmaVersion >= 12) {
5598 var next2 = this.input.charCodeAt(this.pos + 2);
5599 if (next2 === 61) { return this.finishOp(types$1.assign, 3) }
5600 }
5601 return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)
5602 }
5603 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5604 return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)
5605 };
5606
5607 pp.readToken_caret = function() { // '^'
5608 var next = this.input.charCodeAt(this.pos + 1);
5609 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5610 return this.finishOp(types$1.bitwiseXOR, 1)
5611 };
5612
5613 pp.readToken_plus_min = function(code) { // '+-'
5614 var next = this.input.charCodeAt(this.pos + 1);
5615 if (next === code) {
5616 if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
5617 (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
5618 // A `-->` line comment
5619 this.skipLineComment(3);
5620 this.skipSpace();
5621 return this.nextToken()
5622 }
5623 return this.finishOp(types$1.incDec, 2)
5624 }
5625 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5626 return this.finishOp(types$1.plusMin, 1)
5627 };
5628
5629 pp.readToken_lt_gt = function(code) { // '<>'
5630 var next = this.input.charCodeAt(this.pos + 1);
5631 var size = 1;
5632 if (next === code) {
5633 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
5634 if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }
5635 return this.finishOp(types$1.bitShift, size)
5636 }
5637 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
5638 this.input.charCodeAt(this.pos + 3) === 45) {
5639 // `<!--`, an XML-style comment that should be interpreted as a line comment
5640 this.skipLineComment(4);
5641 this.skipSpace();
5642 return this.nextToken()
5643 }
5644 if (next === 61) { size = 2; }
5645 return this.finishOp(types$1.relational, size)
5646 };
5647
5648 pp.readToken_eq_excl = function(code) { // '=!'
5649 var next = this.input.charCodeAt(this.pos + 1);
5650 if (next === 61) { return this.finishOp(types$1.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
5651 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
5652 this.pos += 2;
5653 return this.finishToken(types$1.arrow)
5654 }
5655 return this.finishOp(code === 61 ? types$1.eq : types$1.prefix, 1)
5656 };
5657
5658 pp.readToken_question = function() { // '?'
5659 var ecmaVersion = this.options.ecmaVersion;
5660 if (ecmaVersion >= 11) {
5661 var next = this.input.charCodeAt(this.pos + 1);
5662 if (next === 46) {
5663 var next2 = this.input.charCodeAt(this.pos + 2);
5664 if (next2 < 48 || next2 > 57) { return this.finishOp(types$1.questionDot, 2) }
5665 }
5666 if (next === 63) {
5667 if (ecmaVersion >= 12) {
5668 var next2$1 = this.input.charCodeAt(this.pos + 2);
5669 if (next2$1 === 61) { return this.finishOp(types$1.assign, 3) }
5670 }
5671 return this.finishOp(types$1.coalesce, 2)
5672 }
5673 }
5674 return this.finishOp(types$1.question, 1)
5675 };
5676
5677 pp.readToken_numberSign = function() { // '#'
5678 var ecmaVersion = this.options.ecmaVersion;
5679 var code = 35; // '#'
5680 if (ecmaVersion >= 13) {
5681 ++this.pos;
5682 code = this.fullCharCodeAtPos();
5683 if (isIdentifierStart(code, true) || code === 92 /* '\' */) {
5684 return this.finishToken(types$1.privateId, this.readWord1())
5685 }
5686 }
5687
5688 this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
5689 };
5690
5691 pp.getTokenFromCode = function(code) {
5692 switch (code) {
5693 // The interpretation of a dot depends on whether it is followed
5694 // by a digit or another two dots.
5695 case 46: // '.'
5696 return this.readToken_dot()
5697
5698 // Punctuation tokens.
5699 case 40: ++this.pos; return this.finishToken(types$1.parenL)
5700 case 41: ++this.pos; return this.finishToken(types$1.parenR)
5701 case 59: ++this.pos; return this.finishToken(types$1.semi)
5702 case 44: ++this.pos; return this.finishToken(types$1.comma)
5703 case 91: ++this.pos; return this.finishToken(types$1.bracketL)
5704 case 93: ++this.pos; return this.finishToken(types$1.bracketR)
5705 case 123: ++this.pos; return this.finishToken(types$1.braceL)
5706 case 125: ++this.pos; return this.finishToken(types$1.braceR)
5707 case 58: ++this.pos; return this.finishToken(types$1.colon)
5708
5709 case 96: // '`'
5710 if (this.options.ecmaVersion < 6) { break }
5711 ++this.pos;
5712 return this.finishToken(types$1.backQuote)
5713
5714 case 48: // '0'
5715 var next = this.input.charCodeAt(this.pos + 1);
5716 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
5717 if (this.options.ecmaVersion >= 6) {
5718 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
5719 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
5720 }
5721
5722 // Anything else beginning with a digit is an integer, octal
5723 // number, or float.
5724 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
5725 return this.readNumber(false)
5726
5727 // Quotes produce strings.
5728 case 34: case 39: // '"', "'"
5729 return this.readString(code)
5730
5731 // Operators are parsed inline in tiny state machines. '=' (61) is
5732 // often referred to. `finishOp` simply skips the amount of
5733 // characters it is given as second argument, and returns a token
5734 // of the type given by its first argument.
5735 case 47: // '/'
5736 return this.readToken_slash()
5737
5738 case 37: case 42: // '%*'
5739 return this.readToken_mult_modulo_exp(code)
5740
5741 case 124: case 38: // '|&'
5742 return this.readToken_pipe_amp(code)
5743
5744 case 94: // '^'
5745 return this.readToken_caret()
5746
5747 case 43: case 45: // '+-'
5748 return this.readToken_plus_min(code)
5749
5750 case 60: case 62: // '<>'
5751 return this.readToken_lt_gt(code)
5752
5753 case 61: case 33: // '=!'
5754 return this.readToken_eq_excl(code)
5755
5756 case 63: // '?'
5757 return this.readToken_question()
5758
5759 case 126: // '~'
5760 return this.finishOp(types$1.prefix, 1)
5761
5762 case 35: // '#'
5763 return this.readToken_numberSign()
5764 }
5765
5766 this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
5767 };
5768
5769 pp.finishOp = function(type, size) {
5770 var str = this.input.slice(this.pos, this.pos + size);
5771 this.pos += size;
5772 return this.finishToken(type, str)
5773 };
5774
5775 pp.readRegexp = function() {
5776 var escaped, inClass, start = this.pos;
5777 for (;;) {
5778 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
5779 var ch = this.input.charAt(this.pos);
5780 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
5781 if (!escaped) {
5782 if (ch === "[") { inClass = true; }
5783 else if (ch === "]" && inClass) { inClass = false; }
5784 else if (ch === "/" && !inClass) { break }
5785 escaped = ch === "\\";
5786 } else { escaped = false; }
5787 ++this.pos;
5788 }
5789 var pattern = this.input.slice(start, this.pos);
5790 ++this.pos;
5791 var flagsStart = this.pos;
5792 var flags = this.readWord1();
5793 if (this.containsEsc) { this.unexpected(flagsStart); }
5794
5795 // Validate pattern
5796 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
5797 state.reset(start, pattern, flags);
5798 this.validateRegExpFlags(state);
5799 this.validateRegExpPattern(state);
5800
5801 // Create Literal#value property value.
5802 var value = null;
5803 try {
5804 value = new RegExp(pattern, flags);
5805 } catch (e) {
5806 // ESTree requires null if it failed to instantiate RegExp object.
5807 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
5808 }
5809
5810 return this.finishToken(types$1.regexp, {pattern: pattern, flags: flags, value: value})
5811 };
5812
5813 // Read an integer in the given radix. Return null if zero digits
5814 // were read, the integer value otherwise. When `len` is given, this
5815 // will return `null` unless the integer has exactly `len` digits.
5816
5817 pp.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
5818 // `len` is used for character escape sequences. In that case, disallow separators.
5819 var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
5820
5821 // `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b)
5822 // and isn't fraction part nor exponent part. In that case, if the first digit
5823 // is zero then disallow separators.
5824 var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
5825
5826 var start = this.pos, total = 0, lastCode = 0;
5827 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
5828 var code = this.input.charCodeAt(this.pos), val = (void 0);
5829
5830 if (allowSeparators && code === 95) {
5831 if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
5832 if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
5833 if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
5834 lastCode = code;
5835 continue
5836 }
5837
5838 if (code >= 97) { val = code - 97 + 10; } // a
5839 else if (code >= 65) { val = code - 65 + 10; } // A
5840 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
5841 else { val = Infinity; }
5842 if (val >= radix) { break }
5843 lastCode = code;
5844 total = total * radix + val;
5845 }
5846
5847 if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
5848 if (this.pos === start || len != null && this.pos - start !== len) { return null }
5849
5850 return total
5851 };
5852
5853 function stringToNumber(str, isLegacyOctalNumericLiteral) {
5854 if (isLegacyOctalNumericLiteral) {
5855 return parseInt(str, 8)
5856 }
5857
5858 // `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value.
5859 return parseFloat(str.replace(/_/g, ""))
5860 }
5861
5862 function stringToBigInt(str) {
5863 if (typeof BigInt !== "function") {
5864 return null
5865 }
5866
5867 // `BigInt(value)` throws syntax error if the string contains numeric separators.
5868 return BigInt(str.replace(/_/g, ""))
5869 }
5870
5871 pp.readRadixNumber = function(radix) {
5872 var start = this.pos;
5873 this.pos += 2; // 0x
5874 var val = this.readInt(radix);
5875 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
5876 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
5877 val = stringToBigInt(this.input.slice(start, this.pos));
5878 ++this.pos;
5879 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5880 return this.finishToken(types$1.num, val)
5881 };
5882
5883 // Read an integer, octal integer, or floating-point number.
5884
5885 pp.readNumber = function(startsWithDot) {
5886 var start = this.pos;
5887 if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
5888 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
5889 if (octal && this.strict) { this.raise(start, "Invalid number"); }
5890 var next = this.input.charCodeAt(this.pos);
5891 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
5892 var val$1 = stringToBigInt(this.input.slice(start, this.pos));
5893 ++this.pos;
5894 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5895 return this.finishToken(types$1.num, val$1)
5896 }
5897 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
5898 if (next === 46 && !octal) { // '.'
5899 ++this.pos;
5900 this.readInt(10);
5901 next = this.input.charCodeAt(this.pos);
5902 }
5903 if ((next === 69 || next === 101) && !octal) { // 'eE'
5904 next = this.input.charCodeAt(++this.pos);
5905 if (next === 43 || next === 45) { ++this.pos; } // '+-'
5906 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
5907 }
5908 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5909
5910 var val = stringToNumber(this.input.slice(start, this.pos), octal);
5911 return this.finishToken(types$1.num, val)
5912 };
5913
5914 // Read a string value, interpreting backslash-escapes.
5915
5916 pp.readCodePoint = function() {
5917 var ch = this.input.charCodeAt(this.pos), code;
5918
5919 if (ch === 123) { // '{'
5920 if (this.options.ecmaVersion < 6) { this.unexpected(); }
5921 var codePos = ++this.pos;
5922 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
5923 ++this.pos;
5924 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
5925 } else {
5926 code = this.readHexChar(4);
5927 }
5928 return code
5929 };
5930
5931 pp.readString = function(quote) {
5932 var out = "", chunkStart = ++this.pos;
5933 for (;;) {
5934 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
5935 var ch = this.input.charCodeAt(this.pos);
5936 if (ch === quote) { break }
5937 if (ch === 92) { // '\'
5938 out += this.input.slice(chunkStart, this.pos);
5939 out += this.readEscapedChar(false);
5940 chunkStart = this.pos;
5941 } else if (ch === 0x2028 || ch === 0x2029) {
5942 if (this.options.ecmaVersion < 10) { this.raise(this.start, "Unterminated string constant"); }
5943 ++this.pos;
5944 if (this.options.locations) {
5945 this.curLine++;
5946 this.lineStart = this.pos;
5947 }
5948 } else {
5949 if (isNewLine(ch)) { this.raise(this.start, "Unterminated string constant"); }
5950 ++this.pos;
5951 }
5952 }
5953 out += this.input.slice(chunkStart, this.pos++);
5954 return this.finishToken(types$1.string, out)
5955 };
5956
5957 // Reads template string tokens.
5958
5959 var INVALID_TEMPLATE_ESCAPE_ERROR = {};
5960
5961 pp.tryReadTemplateToken = function() {
5962 this.inTemplateElement = true;
5963 try {
5964 this.readTmplToken();
5965 } catch (err) {
5966 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
5967 this.readInvalidTemplateToken();
5968 } else {
5969 throw err
5970 }
5971 }
5972
5973 this.inTemplateElement = false;
5974 };
5975
5976 pp.invalidStringToken = function(position, message) {
5977 if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
5978 throw INVALID_TEMPLATE_ESCAPE_ERROR
5979 } else {
5980 this.raise(position, message);
5981 }
5982 };
5983
5984 pp.readTmplToken = function() {
5985 var out = "", chunkStart = this.pos;
5986 for (;;) {
5987 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
5988 var ch = this.input.charCodeAt(this.pos);
5989 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
5990 if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) {
5991 if (ch === 36) {
5992 this.pos += 2;
5993 return this.finishToken(types$1.dollarBraceL)
5994 } else {
5995 ++this.pos;
5996 return this.finishToken(types$1.backQuote)
5997 }
5998 }
5999 out += this.input.slice(chunkStart, this.pos);
6000 return this.finishToken(types$1.template, out)
6001 }
6002 if (ch === 92) { // '\'
6003 out += this.input.slice(chunkStart, this.pos);
6004 out += this.readEscapedChar(true);
6005 chunkStart = this.pos;
6006 } else if (isNewLine(ch)) {
6007 out += this.input.slice(chunkStart, this.pos);
6008 ++this.pos;
6009 switch (ch) {
6010 case 13:
6011 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
6012 case 10:
6013 out += "\n";
6014 break
6015 default:
6016 out += String.fromCharCode(ch);
6017 break
6018 }
6019 if (this.options.locations) {
6020 ++this.curLine;
6021 this.lineStart = this.pos;
6022 }
6023 chunkStart = this.pos;
6024 } else {
6025 ++this.pos;
6026 }
6027 }
6028 };
6029
6030 // Reads a template token to search for the end, without validating any escape sequences
6031 pp.readInvalidTemplateToken = function() {
6032 for (; this.pos < this.input.length; this.pos++) {
6033 switch (this.input[this.pos]) {
6034 case "\\":
6035 ++this.pos;
6036 break
6037
6038 case "$":
6039 if (this.input[this.pos + 1] !== "{") { break }
6040 // fall through
6041 case "`":
6042 return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos))
6043
6044 case "\r":
6045 if (this.input[this.pos + 1] === "\n") { ++this.pos; }
6046 // fall through
6047 case "\n": case "\u2028": case "\u2029":
6048 ++this.curLine;
6049 this.lineStart = this.pos + 1;
6050 break
6051 }
6052 }
6053 this.raise(this.start, "Unterminated template");
6054 };
6055
6056 // Used to read escaped characters
6057
6058 pp.readEscapedChar = function(inTemplate) {
6059 var ch = this.input.charCodeAt(++this.pos);
6060 ++this.pos;
6061 switch (ch) {
6062 case 110: return "\n" // 'n' -> '\n'
6063 case 114: return "\r" // 'r' -> '\r'
6064 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
6065 case 117: return codePointToString(this.readCodePoint()) // 'u'
6066 case 116: return "\t" // 't' -> '\t'
6067 case 98: return "\b" // 'b' -> '\b'
6068 case 118: return "\u000b" // 'v' -> '\u000b'
6069 case 102: return "\f" // 'f' -> '\f'
6070 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
6071 case 10: // ' \n'
6072 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
6073 return ""
6074 case 56:
6075 case 57:
6076 if (this.strict) {
6077 this.invalidStringToken(
6078 this.pos - 1,
6079 "Invalid escape sequence"
6080 );
6081 }
6082 if (inTemplate) {
6083 var codePos = this.pos - 1;
6084
6085 this.invalidStringToken(
6086 codePos,
6087 "Invalid escape sequence in template string"
6088 );
6089 }
6090 default:
6091 if (ch >= 48 && ch <= 55) {
6092 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
6093 var octal = parseInt(octalStr, 8);
6094 if (octal > 255) {
6095 octalStr = octalStr.slice(0, -1);
6096 octal = parseInt(octalStr, 8);
6097 }
6098 this.pos += octalStr.length - 1;
6099 ch = this.input.charCodeAt(this.pos);
6100 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
6101 this.invalidStringToken(
6102 this.pos - 1 - octalStr.length,
6103 inTemplate
6104 ? "Octal literal in template string"
6105 : "Octal literal in strict mode"
6106 );
6107 }
6108 return String.fromCharCode(octal)
6109 }
6110 if (isNewLine(ch)) {
6111 // Unicode new line characters after \ get removed from output in both
6112 // template literals and strings
6113 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
6114 return ""
6115 }
6116 return String.fromCharCode(ch)
6117 }
6118 };
6119
6120 // Used to read character escape sequences ('\x', '\u', '\U').
6121
6122 pp.readHexChar = function(len) {
6123 var codePos = this.pos;
6124 var n = this.readInt(16, len);
6125 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
6126 return n
6127 };
6128
6129 // Read an identifier, and return it as a string. Sets `this.containsEsc`
6130 // to whether the word contained a '\u' escape.
6131 //
6132 // Incrementally adds only escaped chars, adding other chunks as-is
6133 // as a micro-optimization.
6134
6135 pp.readWord1 = function() {
6136 this.containsEsc = false;
6137 var word = "", first = true, chunkStart = this.pos;
6138 var astral = this.options.ecmaVersion >= 6;
6139 while (this.pos < this.input.length) {
6140 var ch = this.fullCharCodeAtPos();
6141 if (isIdentifierChar(ch, astral)) {
6142 this.pos += ch <= 0xffff ? 1 : 2;
6143 } else if (ch === 92) { // "\"
6144 this.containsEsc = true;
6145 word += this.input.slice(chunkStart, this.pos);
6146 var escStart = this.pos;
6147 if (this.input.charCodeAt(++this.pos) !== 117) // "u"
6148 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
6149 ++this.pos;
6150 var esc = this.readCodePoint();
6151 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
6152 { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
6153 word += codePointToString(esc);
6154 chunkStart = this.pos;
6155 } else {
6156 break
6157 }
6158 first = false;
6159 }
6160 return word + this.input.slice(chunkStart, this.pos)
6161 };
6162
6163 // Read an identifier or keyword token. Will check for reserved
6164 // words when necessary.
6165
6166 pp.readWord = function() {
6167 var word = this.readWord1();
6168 var type = types$1.name;
6169 if (this.keywords.test(word)) {
6170 type = keywords[word];
6171 }
6172 return this.finishToken(type, word)
6173 };
6174
6175 // Acorn is a tiny, fast JavaScript parser written in JavaScript.
6176 //
6177 // Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
6178 // various contributors and released under an MIT license.
6179 //
6180 // Git repositories for Acorn are available at
6181 //
6182 // http://marijnhaverbeke.nl/git/acorn
6183 // https://github.com/acornjs/acorn.git
6184 //
6185 // Please use the [github bug tracker][ghbt] to report issues.
6186 //
6187 // [ghbt]: https://github.com/acornjs/acorn/issues
6188
6189
6190 var version = "8.15.0";
6191
6192 Parser.acorn = {
6193 Parser: Parser,
6194 version: version,
6195 defaultOptions: defaultOptions,
6196 Position: Position,
6197 SourceLocation: SourceLocation,
6198 getLineInfo: getLineInfo,
6199 Node: Node,
6200 TokenType: TokenType,
6201 tokTypes: types$1,
6202 keywordTypes: keywords,
6203 TokContext: TokContext,
6204 tokContexts: types,
6205 isIdentifierChar: isIdentifierChar,
6206 isIdentifierStart: isIdentifierStart,
6207 Token: Token,
6208 isNewLine: isNewLine,
6209 lineBreak: lineBreak,
6210 lineBreakG: lineBreakG,
6211 nonASCIIwhitespace: nonASCIIwhitespace
6212 };
6213
6214 // The main exported interface (under `self.acorn` when in the
6215 // browser) is a `parse` function that takes a code string and returns
6216 // an abstract syntax tree as specified by the [ESTree spec][estree].
6217 //
6218 // [estree]: https://github.com/estree/estree
6219
6220 function parse(input, options) {
6221 return Parser.parse(input, options)
6222 }
6223
6224 // This function tries to parse a single expression at a given
6225 // offset in a string. Useful for parsing mixed-language formats
6226 // that embed JavaScript expressions.
6227
6228 function parseExpressionAt(input, pos, options) {
6229 return Parser.parseExpressionAt(input, pos, options)
6230 }
6231
6232 // Acorn is organized as a tokenizer and a recursive-descent parser.
6233 // The `tokenizer` export provides an interface to the tokenizer.
6234
6235 function tokenizer(input, options) {
6236 return Parser.tokenizer(input, options)
6237 }
6238
6239 exports.Node = Node;
6240 exports.Parser = Parser;
6241 exports.Position = Position;
6242 exports.SourceLocation = SourceLocation;
6243 exports.TokContext = TokContext;
6244 exports.Token = Token;
6245 exports.TokenType = TokenType;
6246 exports.defaultOptions = defaultOptions;
6247 exports.getLineInfo = getLineInfo;
6248 exports.isIdentifierChar = isIdentifierChar;
6249 exports.isIdentifierStart = isIdentifierStart;
6250 exports.isNewLine = isNewLine;
6251 exports.keywordTypes = keywords;
6252 exports.lineBreak = lineBreak;
6253 exports.lineBreakG = lineBreakG;
6254 exports.nonASCIIwhitespace = nonASCIIwhitespace;
6255 exports.parse = parse;
6256 exports.parseExpressionAt = parseExpressionAt;
6257 exports.tokContexts = types;
6258 exports.tokTypes = types$1;
6259 exports.tokenizer = tokenizer;
6260 exports.version = version;
6261
6262}));
vendor/acorn/dist/acorn.mjs +6233 -0
……@@ -0,0 +1,6233 @@
1// This file was generated. Do not modify manually!
2var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 80, 3, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 343, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 726, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
3
4// This file was generated. Do not modify manually!
5var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 2, 60, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 42, 9, 8936, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 496, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4153, 7, 221, 3, 5761, 15, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 4191];
6
7// This file was generated. Do not modify manually!
8var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0897-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0cf3\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ece\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\u30fb\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f\uff65";
9
10// This file was generated. Do not modify manually!
11var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c8a\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7cd\ua7d0\ua7d1\ua7d3\ua7d5-\ua7dc\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
12
13// These are a run-length and offset encoded representation of the
14// >0xffff code points that are a valid part of identifiers. The
15// offset starts at 0x10000, and each pair of numbers represents an
16// offset to the next range, and then a size of the range.
17
18// Reserved word lists for various dialects of the language
19
20var reservedWords = {
21 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
22 5: "class enum extends super const export import",
23 6: "enum",
24 strict: "implements interface let package private protected public static yield",
25 strictBind: "eval arguments"
26};
27
28// And the keywords
29
30var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
31
32var keywords$1 = {
33 5: ecma5AndLessKeywords,
34 "5module": ecma5AndLessKeywords + " export import",
35 6: ecma5AndLessKeywords + " const class extends export import super"
36};
37
38var keywordRelationalOperator = /^in(stanceof)?$/;
39
40// ## Character categories
41
42var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
43var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
44
45// This has a complexity linear to the value of the code. The
46// assumption is that looking up astral identifier characters is
47// rare.
48function isInAstralSet(code, set) {
49 var pos = 0x10000;
50 for (var i = 0; i < set.length; i += 2) {
51 pos += set[i];
52 if (pos > code) { return false }
53 pos += set[i + 1];
54 if (pos >= code) { return true }
55 }
56 return false
57}
58
59// Test whether a given character code starts an identifier.
60
61function isIdentifierStart(code, astral) {
62 if (code < 65) { return code === 36 }
63 if (code < 91) { return true }
64 if (code < 97) { return code === 95 }
65 if (code < 123) { return true }
66 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
67 if (astral === false) { return false }
68 return isInAstralSet(code, astralIdentifierStartCodes)
69}
70
71// Test whether a given character is part of an identifier.
72
73function isIdentifierChar(code, astral) {
74 if (code < 48) { return code === 36 }
75 if (code < 58) { return true }
76 if (code < 65) { return false }
77 if (code < 91) { return true }
78 if (code < 97) { return code === 95 }
79 if (code < 123) { return true }
80 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
81 if (astral === false) { return false }
82 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
83}
84
85// ## Token types
86
87// The assignment of fine-grained, information-carrying type objects
88// allows the tokenizer to store the information it has about a
89// token in a way that is very cheap for the parser to look up.
90
91// All token type variables start with an underscore, to make them
92// easy to recognize.
93
94// The `beforeExpr` property is used to disambiguate between regular
95// expressions and divisions. It is set on all token types that can
96// be followed by an expression (thus, a slash after them would be a
97// regular expression).
98//
99// The `startsExpr` property is used to check if the token ends a
100// `yield` expression. It is set on all token types that either can
101// directly start an expression (like a quotation mark) or can
102// continue an expression (like the body of a string).
103//
104// `isLoop` marks a keyword as starting a loop, which is important
105// to know when parsing a label, in order to allow or disallow
106// continue jumps to that label.
107
108var TokenType = function TokenType(label, conf) {
109 if ( conf === void 0 ) conf = {};
110
111 this.label = label;
112 this.keyword = conf.keyword;
113 this.beforeExpr = !!conf.beforeExpr;
114 this.startsExpr = !!conf.startsExpr;
115 this.isLoop = !!conf.isLoop;
116 this.isAssign = !!conf.isAssign;
117 this.prefix = !!conf.prefix;
118 this.postfix = !!conf.postfix;
119 this.binop = conf.binop || null;
120 this.updateContext = null;
121};
122
123function binop(name, prec) {
124 return new TokenType(name, {beforeExpr: true, binop: prec})
125}
126var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
127
128// Map keyword names to token types.
129
130var keywords = {};
131
132// Succinct definitions of keyword token types
133function kw(name, options) {
134 if ( options === void 0 ) options = {};
135
136 options.keyword = name;
137 return keywords[name] = new TokenType(name, options)
138}
139
140var types$1 = {
141 num: new TokenType("num", startsExpr),
142 regexp: new TokenType("regexp", startsExpr),
143 string: new TokenType("string", startsExpr),
144 name: new TokenType("name", startsExpr),
145 privateId: new TokenType("privateId", startsExpr),
146 eof: new TokenType("eof"),
147
148 // Punctuation token types.
149 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
150 bracketR: new TokenType("]"),
151 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
152 braceR: new TokenType("}"),
153 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
154 parenR: new TokenType(")"),
155 comma: new TokenType(",", beforeExpr),
156 semi: new TokenType(";", beforeExpr),
157 colon: new TokenType(":", beforeExpr),
158 dot: new TokenType("."),
159 question: new TokenType("?", beforeExpr),
160 questionDot: new TokenType("?."),
161 arrow: new TokenType("=>", beforeExpr),
162 template: new TokenType("template"),
163 invalidTemplate: new TokenType("invalidTemplate"),
164 ellipsis: new TokenType("...", beforeExpr),
165 backQuote: new TokenType("`", startsExpr),
166 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
167
168 // Operators. These carry several kinds of properties to help the
169 // parser use them properly (the presence of these properties is
170 // what categorizes them as operators).
171 //
172 // `binop`, when present, specifies that this operator is a binary
173 // operator, and will refer to its precedence.
174 //
175 // `prefix` and `postfix` mark the operator as a prefix or postfix
176 // unary operator.
177 //
178 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
179 // binary operators with a very low precedence, that should result
180 // in AssignmentExpression nodes.
181
182 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
183 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
184 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
185 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
186 logicalOR: binop("||", 1),
187 logicalAND: binop("&&", 2),
188 bitwiseOR: binop("|", 3),
189 bitwiseXOR: binop("^", 4),
190 bitwiseAND: binop("&", 5),
191 equality: binop("==/!=/===/!==", 6),
192 relational: binop("</>/<=/>=", 7),
193 bitShift: binop("<</>>/>>>", 8),
194 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
195 modulo: binop("%", 10),
196 star: binop("*", 10),
197 slash: binop("/", 10),
198 starstar: new TokenType("**", {beforeExpr: true}),
199 coalesce: binop("??", 1),
200
201 // Keyword token types.
202 _break: kw("break"),
203 _case: kw("case", beforeExpr),
204 _catch: kw("catch"),
205 _continue: kw("continue"),
206 _debugger: kw("debugger"),
207 _default: kw("default", beforeExpr),
208 _do: kw("do", {isLoop: true, beforeExpr: true}),
209 _else: kw("else", beforeExpr),
210 _finally: kw("finally"),
211 _for: kw("for", {isLoop: true}),
212 _function: kw("function", startsExpr),
213 _if: kw("if"),
214 _return: kw("return", beforeExpr),
215 _switch: kw("switch"),
216 _throw: kw("throw", beforeExpr),
217 _try: kw("try"),
218 _var: kw("var"),
219 _const: kw("const"),
220 _while: kw("while", {isLoop: true}),
221 _with: kw("with"),
222 _new: kw("new", {beforeExpr: true, startsExpr: true}),
223 _this: kw("this", startsExpr),
224 _super: kw("super", startsExpr),
225 _class: kw("class", startsExpr),
226 _extends: kw("extends", beforeExpr),
227 _export: kw("export"),
228 _import: kw("import", startsExpr),
229 _null: kw("null", startsExpr),
230 _true: kw("true", startsExpr),
231 _false: kw("false", startsExpr),
232 _in: kw("in", {beforeExpr: true, binop: 7}),
233 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
234 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
235 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
236 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
237};
238
239// Matches a whole line break (where CRLF is considered a single
240// line break). Used to count lines.
241
242var lineBreak = /\r\n?|\n|\u2028|\u2029/;
243var lineBreakG = new RegExp(lineBreak.source, "g");
244
245function isNewLine(code) {
246 return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
247}
248
249function nextLineBreak(code, from, end) {
250 if ( end === void 0 ) end = code.length;
251
252 for (var i = from; i < end; i++) {
253 var next = code.charCodeAt(i);
254 if (isNewLine(next))
255 { return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }
256 }
257 return -1
258}
259
260var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
261
262var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
263
264var ref = Object.prototype;
265var hasOwnProperty = ref.hasOwnProperty;
266var toString = ref.toString;
267
268var hasOwn = Object.hasOwn || (function (obj, propName) { return (
269 hasOwnProperty.call(obj, propName)
270); });
271
272var isArray = Array.isArray || (function (obj) { return (
273 toString.call(obj) === "[object Array]"
274); });
275
276var regexpCache = Object.create(null);
277
278function wordsRegexp(words) {
279 return regexpCache[words] || (regexpCache[words] = new RegExp("^(?:" + words.replace(/ /g, "|") + ")$"))
280}
281
282function codePointToString(code) {
283 // UTF-16 Decoding
284 if (code <= 0xFFFF) { return String.fromCharCode(code) }
285 code -= 0x10000;
286 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
287}
288
289var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
290
291// These are used when `options.locations` is on, for the
292// `startLoc` and `endLoc` properties.
293
294var Position = function Position(line, col) {
295 this.line = line;
296 this.column = col;
297};
298
299Position.prototype.offset = function offset (n) {
300 return new Position(this.line, this.column + n)
301};
302
303var SourceLocation = function SourceLocation(p, start, end) {
304 this.start = start;
305 this.end = end;
306 if (p.sourceFile !== null) { this.source = p.sourceFile; }
307};
308
309// The `getLineInfo` function is mostly useful when the
310// `locations` option is off (for performance reasons) and you
311// want to find the line/column position for a given character
312// offset. `input` should be the code string that the offset refers
313// into.
314
315function getLineInfo(input, offset) {
316 for (var line = 1, cur = 0;;) {
317 var nextBreak = nextLineBreak(input, cur, offset);
318 if (nextBreak < 0) { return new Position(line, offset - cur) }
319 ++line;
320 cur = nextBreak;
321 }
322}
323
324// A second argument must be given to configure the parser process.
325// These options are recognized (only `ecmaVersion` is required):
326
327var defaultOptions = {
328 // `ecmaVersion` indicates the ECMAScript version to parse. Must be
329 // either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10
330 // (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"`
331 // (the latest version the library supports). This influences
332 // support for strict mode, the set of reserved words, and support
333 // for new syntax features.
334 ecmaVersion: null,
335 // `sourceType` indicates the mode the code should be parsed in.
336 // Can be either `"script"` or `"module"`. This influences global
337 // strict mode and parsing of `import` and `export` declarations.
338 sourceType: "script",
339 // `onInsertedSemicolon` can be a callback that will be called when
340 // a semicolon is automatically inserted. It will be passed the
341 // position of the inserted semicolon as an offset, and if
342 // `locations` is enabled, it is given the location as a `{line,
343 // column}` object as second argument.
344 onInsertedSemicolon: null,
345 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
346 // trailing commas.
347 onTrailingComma: null,
348 // By default, reserved words are only enforced if ecmaVersion >= 5.
349 // Set `allowReserved` to a boolean value to explicitly turn this on
350 // an off. When this option has the value "never", reserved words
351 // and keywords can also not be used as property names.
352 allowReserved: null,
353 // When enabled, a return at the top level is not considered an
354 // error.
355 allowReturnOutsideFunction: false,
356 // When enabled, import/export statements are not constrained to
357 // appearing at the top of the program, and an import.meta expression
358 // in a script isn't considered an error.
359 allowImportExportEverywhere: false,
360 // By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.
361 // When enabled, await identifiers are allowed to appear at the top-level scope,
362 // but they are still not allowed in non-async functions.
363 allowAwaitOutsideFunction: null,
364 // When enabled, super identifiers are not constrained to
365 // appearing in methods and do not raise an error when they appear elsewhere.
366 allowSuperOutsideMethod: null,
367 // When enabled, hashbang directive in the beginning of file is
368 // allowed and treated as a line comment. Enabled by default when
369 // `ecmaVersion` >= 2023.
370 allowHashBang: false,
371 // By default, the parser will verify that private properties are
372 // only used in places where they are valid and have been declared.
373 // Set this to false to turn such checks off.
374 checkPrivateFields: true,
375 // When `locations` is on, `loc` properties holding objects with
376 // `start` and `end` properties in `{line, column}` form (with
377 // line being 1-based and column 0-based) will be attached to the
378 // nodes.
379 locations: false,
380 // A function can be passed as `onToken` option, which will
381 // cause Acorn to call that function with object in the same
382 // format as tokens returned from `tokenizer().getToken()`. Note
383 // that you are not allowed to call the parser from the
384 // callback—that will corrupt its internal state.
385 onToken: null,
386 // A function can be passed as `onComment` option, which will
387 // cause Acorn to call that function with `(block, text, start,
388 // end)` parameters whenever a comment is skipped. `block` is a
389 // boolean indicating whether this is a block (`/* */`) comment,
390 // `text` is the content of the comment, and `start` and `end` are
391 // character offsets that denote the start and end of the comment.
392 // When the `locations` option is on, two more parameters are
393 // passed, the full `{line, column}` locations of the start and
394 // end of the comments. Note that you are not allowed to call the
395 // parser from the callback—that will corrupt its internal state.
396 // When this option has an array as value, objects representing the
397 // comments are pushed to it.
398 onComment: null,
399 // Nodes have their start and end characters offsets recorded in
400 // `start` and `end` properties (directly on the node, rather than
401 // the `loc` object, which holds line/column data. To also add a
402 // [semi-standardized][range] `range` property holding a `[start,
403 // end]` array with the same numbers, set the `ranges` option to
404 // `true`.
405 //
406 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
407 ranges: false,
408 // It is possible to parse multiple files into a single AST by
409 // passing the tree produced by parsing the first file as
410 // `program` option in subsequent parses. This will add the
411 // toplevel forms of the parsed file to the `Program` (top) node
412 // of an existing parse tree.
413 program: null,
414 // When `locations` is on, you can pass this to record the source
415 // file in every node's `loc` object.
416 sourceFile: null,
417 // This value, if given, is stored in every node, whether
418 // `locations` is on or off.
419 directSourceFile: null,
420 // When enabled, parenthesized expressions are represented by
421 // (non-standard) ParenthesizedExpression nodes
422 preserveParens: false
423};
424
425// Interpret and default an options object
426
427var warnedAboutEcmaVersion = false;
428
429function getOptions(opts) {
430 var options = {};
431
432 for (var opt in defaultOptions)
433 { options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }
434
435 if (options.ecmaVersion === "latest") {
436 options.ecmaVersion = 1e8;
437 } else if (options.ecmaVersion == null) {
438 if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) {
439 warnedAboutEcmaVersion = true;
440 console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.");
441 }
442 options.ecmaVersion = 11;
443 } else if (options.ecmaVersion >= 2015) {
444 options.ecmaVersion -= 2009;
445 }
446
447 if (options.allowReserved == null)
448 { options.allowReserved = options.ecmaVersion < 5; }
449
450 if (!opts || opts.allowHashBang == null)
451 { options.allowHashBang = options.ecmaVersion >= 14; }
452
453 if (isArray(options.onToken)) {
454 var tokens = options.onToken;
455 options.onToken = function (token) { return tokens.push(token); };
456 }
457 if (isArray(options.onComment))
458 { options.onComment = pushComment(options, options.onComment); }
459
460 return options
461}
462
463function pushComment(options, array) {
464 return function(block, text, start, end, startLoc, endLoc) {
465 var comment = {
466 type: block ? "Block" : "Line",
467 value: text,
468 start: start,
469 end: end
470 };
471 if (options.locations)
472 { comment.loc = new SourceLocation(this, startLoc, endLoc); }
473 if (options.ranges)
474 { comment.range = [start, end]; }
475 array.push(comment);
476 }
477}
478
479// Each scope gets a bitset that may contain these flags
480var
481 SCOPE_TOP = 1,
482 SCOPE_FUNCTION = 2,
483 SCOPE_ASYNC = 4,
484 SCOPE_GENERATOR = 8,
485 SCOPE_ARROW = 16,
486 SCOPE_SIMPLE_CATCH = 32,
487 SCOPE_SUPER = 64,
488 SCOPE_DIRECT_SUPER = 128,
489 SCOPE_CLASS_STATIC_BLOCK = 256,
490 SCOPE_CLASS_FIELD_INIT = 512,
491 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION | SCOPE_CLASS_STATIC_BLOCK;
492
493function functionFlags(async, generator) {
494 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
495}
496
497// Used in checkLVal* and declareName to determine the type of a binding
498var
499 BIND_NONE = 0, // Not a binding
500 BIND_VAR = 1, // Var-style binding
501 BIND_LEXICAL = 2, // Let- or const-style binding
502 BIND_FUNCTION = 3, // Function declaration
503 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
504 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
505
506var Parser = function Parser(options, input, startPos) {
507 this.options = options = getOptions(options);
508 this.sourceFile = options.sourceFile;
509 this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
510 var reserved = "";
511 if (options.allowReserved !== true) {
512 reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];
513 if (options.sourceType === "module") { reserved += " await"; }
514 }
515 this.reservedWords = wordsRegexp(reserved);
516 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
517 this.reservedWordsStrict = wordsRegexp(reservedStrict);
518 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
519 this.input = String(input);
520
521 // Used to signal to callers of `readWord1` whether the word
522 // contained any escape sequences. This is needed because words with
523 // escape sequences must not be interpreted as keywords.
524 this.containsEsc = false;
525
526 // Set up token state
527
528 // The current position of the tokenizer in the input.
529 if (startPos) {
530 this.pos = startPos;
531 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
532 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
533 } else {
534 this.pos = this.lineStart = 0;
535 this.curLine = 1;
536 }
537
538 // Properties of the current token:
539 // Its type
540 this.type = types$1.eof;
541 // For tokens that include more information than their type, the value
542 this.value = null;
543 // Its start and end offset
544 this.start = this.end = this.pos;
545 // And, if locations are used, the {line, column} object
546 // corresponding to those offsets
547 this.startLoc = this.endLoc = this.curPosition();
548
549 // Position information for the previous token
550 this.lastTokEndLoc = this.lastTokStartLoc = null;
551 this.lastTokStart = this.lastTokEnd = this.pos;
552
553 // The context stack is used to superficially track syntactic
554 // context to predict whether a regular expression is allowed in a
555 // given position.
556 this.context = this.initialContext();
557 this.exprAllowed = true;
558
559 // Figure out if it's a module code.
560 this.inModule = options.sourceType === "module";
561 this.strict = this.inModule || this.strictDirective(this.pos);
562
563 // Used to signify the start of a potential arrow function
564 this.potentialArrowAt = -1;
565 this.potentialArrowInForAwait = false;
566
567 // Positions to delayed-check that yield/await does not exist in default parameters.
568 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
569 // Labels in scope.
570 this.labels = [];
571 // Thus-far undefined exports.
572 this.undefinedExports = Object.create(null);
573
574 // If enabled, skip leading hashbang line.
575 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
576 { this.skipLineComment(2); }
577
578 // Scope tracking for duplicate variable names (see scope.js)
579 this.scopeStack = [];
580 this.enterScope(SCOPE_TOP);
581
582 // For RegExp validation
583 this.regexpState = null;
584
585 // The stack of private names.
586 // Each element has two properties: 'declared' and 'used'.
587 // When it exited from the outermost class definition, all used private names must be declared.
588 this.privateNameStack = [];
589};
590
591var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };
592
593Parser.prototype.parse = function parse () {
594 var node = this.options.program || this.startNode();
595 this.nextToken();
596 return this.parseTopLevel(node)
597};
598
599prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
600
601prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
602
603prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
604
605prototypeAccessors.canAwait.get = function () {
606 for (var i = this.scopeStack.length - 1; i >= 0; i--) {
607 var ref = this.scopeStack[i];
608 var flags = ref.flags;
609 if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT)) { return false }
610 if (flags & SCOPE_FUNCTION) { return (flags & SCOPE_ASYNC) > 0 }
611 }
612 return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
613};
614
615prototypeAccessors.allowSuper.get = function () {
616 var ref = this.currentThisScope();
617 var flags = ref.flags;
618 return (flags & SCOPE_SUPER) > 0 || this.options.allowSuperOutsideMethod
619};
620
621prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
622
623prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
624
625prototypeAccessors.allowNewDotTarget.get = function () {
626 for (var i = this.scopeStack.length - 1; i >= 0; i--) {
627 var ref = this.scopeStack[i];
628 var flags = ref.flags;
629 if (flags & (SCOPE_CLASS_STATIC_BLOCK | SCOPE_CLASS_FIELD_INIT) ||
630 ((flags & SCOPE_FUNCTION) && !(flags & SCOPE_ARROW))) { return true }
631 }
632 return false
633};
634
635prototypeAccessors.inClassStaticBlock.get = function () {
636 return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0
637};
638
639Parser.extend = function extend () {
640 var plugins = [], len = arguments.length;
641 while ( len-- ) plugins[ len ] = arguments[ len ];
642
643 var cls = this;
644 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
645 return cls
646};
647
648Parser.parse = function parse (input, options) {
649 return new this(options, input).parse()
650};
651
652Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
653 var parser = new this(options, input, pos);
654 parser.nextToken();
655 return parser.parseExpression()
656};
657
658Parser.tokenizer = function tokenizer (input, options) {
659 return new this(options, input)
660};
661
662Object.defineProperties( Parser.prototype, prototypeAccessors );
663
664var pp$9 = Parser.prototype;
665
666// ## Parser utilities
667
668var literal = /^(?:'((?:\\[^]|[^'\\])*?)'|"((?:\\[^]|[^"\\])*?)")/;
669pp$9.strictDirective = function(start) {
670 if (this.options.ecmaVersion < 5) { return false }
671 for (;;) {
672 // Try to find string literal.
673 skipWhiteSpace.lastIndex = start;
674 start += skipWhiteSpace.exec(this.input)[0].length;
675 var match = literal.exec(this.input.slice(start));
676 if (!match) { return false }
677 if ((match[1] || match[2]) === "use strict") {
678 skipWhiteSpace.lastIndex = start + match[0].length;
679 var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
680 var next = this.input.charAt(end);
681 return next === ";" || next === "}" ||
682 (lineBreak.test(spaceAfter[0]) &&
683 !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
684 }
685 start += match[0].length;
686
687 // Skip semicolon, if any.
688 skipWhiteSpace.lastIndex = start;
689 start += skipWhiteSpace.exec(this.input)[0].length;
690 if (this.input[start] === ";")
691 { start++; }
692 }
693};
694
695// Predicate that tests whether the next token is of the given
696// type, and if yes, consumes it as a side effect.
697
698pp$9.eat = function(type) {
699 if (this.type === type) {
700 this.next();
701 return true
702 } else {
703 return false
704 }
705};
706
707// Tests whether parsed token is a contextual keyword.
708
709pp$9.isContextual = function(name) {
710 return this.type === types$1.name && this.value === name && !this.containsEsc
711};
712
713// Consumes contextual keyword if possible.
714
715pp$9.eatContextual = function(name) {
716 if (!this.isContextual(name)) { return false }
717 this.next();
718 return true
719};
720
721// Asserts that following token is given contextual keyword.
722
723pp$9.expectContextual = function(name) {
724 if (!this.eatContextual(name)) { this.unexpected(); }
725};
726
727// Test whether a semicolon can be inserted at the current position.
728
729pp$9.canInsertSemicolon = function() {
730 return this.type === types$1.eof ||
731 this.type === types$1.braceR ||
732 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
733};
734
735pp$9.insertSemicolon = function() {
736 if (this.canInsertSemicolon()) {
737 if (this.options.onInsertedSemicolon)
738 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
739 return true
740 }
741};
742
743// Consume a semicolon, or, failing that, see if we are allowed to
744// pretend that there is a semicolon at this position.
745
746pp$9.semicolon = function() {
747 if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }
748};
749
750pp$9.afterTrailingComma = function(tokType, notNext) {
751 if (this.type === tokType) {
752 if (this.options.onTrailingComma)
753 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
754 if (!notNext)
755 { this.next(); }
756 return true
757 }
758};
759
760// Expect a token of a given type. If found, consume it, otherwise,
761// raise an unexpected token error.
762
763pp$9.expect = function(type) {
764 this.eat(type) || this.unexpected();
765};
766
767// Raise an unexpected token error.
768
769pp$9.unexpected = function(pos) {
770 this.raise(pos != null ? pos : this.start, "Unexpected token");
771};
772
773var DestructuringErrors = function DestructuringErrors() {
774 this.shorthandAssign =
775 this.trailingComma =
776 this.parenthesizedAssign =
777 this.parenthesizedBind =
778 this.doubleProto =
779 -1;
780};
781
782pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {
783 if (!refDestructuringErrors) { return }
784 if (refDestructuringErrors.trailingComma > -1)
785 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
786 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
787 if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); }
788};
789
790pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
791 if (!refDestructuringErrors) { return false }
792 var shorthandAssign = refDestructuringErrors.shorthandAssign;
793 var doubleProto = refDestructuringErrors.doubleProto;
794 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
795 if (shorthandAssign >= 0)
796 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
797 if (doubleProto >= 0)
798 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
799};
800
801pp$9.checkYieldAwaitInDefaultParams = function() {
802 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
803 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
804 if (this.awaitPos)
805 { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
806};
807
808pp$9.isSimpleAssignTarget = function(expr) {
809 if (expr.type === "ParenthesizedExpression")
810 { return this.isSimpleAssignTarget(expr.expression) }
811 return expr.type === "Identifier" || expr.type === "MemberExpression"
812};
813
814var pp$8 = Parser.prototype;
815
816// ### Statement parsing
817
818// Parse a program. Initializes the parser, reads any number of
819// statements, and wraps them in a Program node. Optionally takes a
820// `program` argument. If present, the statements will be appended
821// to its body instead of creating a new node.
822
823pp$8.parseTopLevel = function(node) {
824 var exports = Object.create(null);
825 if (!node.body) { node.body = []; }
826 while (this.type !== types$1.eof) {
827 var stmt = this.parseStatement(null, true, exports);
828 node.body.push(stmt);
829 }
830 if (this.inModule)
831 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
832 {
833 var name = list[i];
834
835 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
836 } }
837 this.adaptDirectivePrologue(node.body);
838 this.next();
839 node.sourceType = this.options.sourceType;
840 return this.finishNode(node, "Program")
841};
842
843var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
844
845pp$8.isLet = function(context) {
846 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
847 skipWhiteSpace.lastIndex = this.pos;
848 var skip = skipWhiteSpace.exec(this.input);
849 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
850 // For ambiguous cases, determine if a LexicalDeclaration (or only a
851 // Statement) is allowed here. If context is not empty then only a Statement
852 // is allowed. However, `let [` is an explicit negative lookahead for
853 // ExpressionStatement, so special-case it first.
854 if (nextCh === 91 || nextCh === 92) { return true } // '[', '\'
855 if (context) { return false }
856
857 if (nextCh === 123 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '{', astral
858 if (isIdentifierStart(nextCh, true)) {
859 var pos = next + 1;
860 while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
861 if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
862 var ident = this.input.slice(next, pos);
863 if (!keywordRelationalOperator.test(ident)) { return true }
864 }
865 return false
866};
867
868// check 'async [no LineTerminator here] function'
869// - 'async /*foo*/ function' is OK.
870// - 'async /*\n*/ function' is invalid.
871pp$8.isAsyncFunction = function() {
872 if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
873 { return false }
874
875 skipWhiteSpace.lastIndex = this.pos;
876 var skip = skipWhiteSpace.exec(this.input);
877 var next = this.pos + skip[0].length, after;
878 return !lineBreak.test(this.input.slice(this.pos, next)) &&
879 this.input.slice(next, next + 8) === "function" &&
880 (next + 8 === this.input.length ||
881 !(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
882};
883
884pp$8.isUsingKeyword = function(isAwaitUsing, isFor) {
885 if (this.options.ecmaVersion < 17 || !this.isContextual(isAwaitUsing ? "await" : "using"))
886 { return false }
887
888 skipWhiteSpace.lastIndex = this.pos;
889 var skip = skipWhiteSpace.exec(this.input);
890 var next = this.pos + skip[0].length;
891
892 if (lineBreak.test(this.input.slice(this.pos, next))) { return false }
893
894 if (isAwaitUsing) {
895 var awaitEndPos = next + 5 /* await */, after;
896 if (this.input.slice(next, awaitEndPos) !== "using" ||
897 awaitEndPos === this.input.length ||
898 isIdentifierChar(after = this.input.charCodeAt(awaitEndPos)) ||
899 (after > 0xd7ff && after < 0xdc00)
900 ) { return false }
901
902 skipWhiteSpace.lastIndex = awaitEndPos;
903 var skipAfterUsing = skipWhiteSpace.exec(this.input);
904 if (skipAfterUsing && lineBreak.test(this.input.slice(awaitEndPos, awaitEndPos + skipAfterUsing[0].length))) { return false }
905 }
906
907 if (isFor) {
908 var ofEndPos = next + 2 /* of */, after$1;
909 if (this.input.slice(next, ofEndPos) === "of") {
910 if (ofEndPos === this.input.length ||
911 (!isIdentifierChar(after$1 = this.input.charCodeAt(ofEndPos)) && !(after$1 > 0xd7ff && after$1 < 0xdc00))) { return false }
912 }
913 }
914
915 var ch = this.input.charCodeAt(next);
916 return isIdentifierStart(ch, true) || ch === 92 // '\'
917};
918
919pp$8.isAwaitUsing = function(isFor) {
920 return this.isUsingKeyword(true, isFor)
921};
922
923pp$8.isUsing = function(isFor) {
924 return this.isUsingKeyword(false, isFor)
925};
926
927// Parse a single statement.
928//
929// If expecting a statement and finding a slash operator, parse a
930// regular expression literal. This is to handle cases like
931// `if (foo) /blah/.exec(foo)`, where looking at the previous token
932// does not help.
933
934pp$8.parseStatement = function(context, topLevel, exports) {
935 var starttype = this.type, node = this.startNode(), kind;
936
937 if (this.isLet(context)) {
938 starttype = types$1._var;
939 kind = "let";
940 }
941
942 // Most types of statements are recognized by the keyword they
943 // start with. Many are trivial to parse, some require a bit of
944 // complexity.
945
946 switch (starttype) {
947 case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
948 case types$1._debugger: return this.parseDebuggerStatement(node)
949 case types$1._do: return this.parseDoStatement(node)
950 case types$1._for: return this.parseForStatement(node)
951 case types$1._function:
952 // Function as sole body of either an if statement or a labeled statement
953 // works, but not when it is part of a labeled statement that is the sole
954 // body of an if statement.
955 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
956 return this.parseFunctionStatement(node, false, !context)
957 case types$1._class:
958 if (context) { this.unexpected(); }
959 return this.parseClass(node, true)
960 case types$1._if: return this.parseIfStatement(node)
961 case types$1._return: return this.parseReturnStatement(node)
962 case types$1._switch: return this.parseSwitchStatement(node)
963 case types$1._throw: return this.parseThrowStatement(node)
964 case types$1._try: return this.parseTryStatement(node)
965 case types$1._const: case types$1._var:
966 kind = kind || this.value;
967 if (context && kind !== "var") { this.unexpected(); }
968 return this.parseVarStatement(node, kind)
969 case types$1._while: return this.parseWhileStatement(node)
970 case types$1._with: return this.parseWithStatement(node)
971 case types$1.braceL: return this.parseBlock(true, node)
972 case types$1.semi: return this.parseEmptyStatement(node)
973 case types$1._export:
974 case types$1._import:
975 if (this.options.ecmaVersion > 10 && starttype === types$1._import) {
976 skipWhiteSpace.lastIndex = this.pos;
977 var skip = skipWhiteSpace.exec(this.input);
978 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
979 if (nextCh === 40 || nextCh === 46) // '(' or '.'
980 { return this.parseExpressionStatement(node, this.parseExpression()) }
981 }
982
983 if (!this.options.allowImportExportEverywhere) {
984 if (!topLevel)
985 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
986 if (!this.inModule)
987 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
988 }
989 return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)
990
991 // If the statement does not start with a statement keyword or a
992 // brace, it's an ExpressionStatement or LabeledStatement. We
993 // simply start parsing an expression, and afterwards, if the
994 // next token is a colon and the expression was a simple
995 // Identifier node, we switch to interpreting it as a label.
996 default:
997 if (this.isAsyncFunction()) {
998 if (context) { this.unexpected(); }
999 this.next();
1000 return this.parseFunctionStatement(node, true, !context)
1001 }
1002
1003 var usingKind = this.isAwaitUsing(false) ? "await using" : this.isUsing(false) ? "using" : null;
1004 if (usingKind) {
1005 if (topLevel && this.options.sourceType === "script") {
1006 this.raise(this.start, "Using declaration cannot appear in the top level when source type is `script`");
1007 }
1008 if (usingKind === "await using") {
1009 if (!this.canAwait) {
1010 this.raise(this.start, "Await using cannot appear outside of async function");
1011 }
1012 this.next();
1013 }
1014 this.next();
1015 this.parseVar(node, false, usingKind);
1016 this.semicolon();
1017 return this.finishNode(node, "VariableDeclaration")
1018 }
1019
1020 var maybeName = this.value, expr = this.parseExpression();
1021 if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon))
1022 { return this.parseLabeledStatement(node, maybeName, expr, context) }
1023 else { return this.parseExpressionStatement(node, expr) }
1024 }
1025};
1026
1027pp$8.parseBreakContinueStatement = function(node, keyword) {
1028 var isBreak = keyword === "break";
1029 this.next();
1030 if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }
1031 else if (this.type !== types$1.name) { this.unexpected(); }
1032 else {
1033 node.label = this.parseIdent();
1034 this.semicolon();
1035 }
1036
1037 // Verify that there is an actual destination to break or
1038 // continue to.
1039 var i = 0;
1040 for (; i < this.labels.length; ++i) {
1041 var lab = this.labels[i];
1042 if (node.label == null || lab.name === node.label.name) {
1043 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
1044 if (node.label && isBreak) { break }
1045 }
1046 }
1047 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
1048 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
1049};
1050
1051pp$8.parseDebuggerStatement = function(node) {
1052 this.next();
1053 this.semicolon();
1054 return this.finishNode(node, "DebuggerStatement")
1055};
1056
1057pp$8.parseDoStatement = function(node) {
1058 this.next();
1059 this.labels.push(loopLabel);
1060 node.body = this.parseStatement("do");
1061 this.labels.pop();
1062 this.expect(types$1._while);
1063 node.test = this.parseParenExpression();
1064 if (this.options.ecmaVersion >= 6)
1065 { this.eat(types$1.semi); }
1066 else
1067 { this.semicolon(); }
1068 return this.finishNode(node, "DoWhileStatement")
1069};
1070
1071// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
1072// loop is non-trivial. Basically, we have to parse the init `var`
1073// statement or expression, disallowing the `in` operator (see
1074// the second parameter to `parseExpression`), and then check
1075// whether the next token is `in` or `of`. When there is no init
1076// part (semicolon immediately after the opening parenthesis), it
1077// is a regular `for` loop.
1078
1079pp$8.parseForStatement = function(node) {
1080 this.next();
1081 var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
1082 this.labels.push(loopLabel);
1083 this.enterScope(0);
1084 this.expect(types$1.parenL);
1085 if (this.type === types$1.semi) {
1086 if (awaitAt > -1) { this.unexpected(awaitAt); }
1087 return this.parseFor(node, null)
1088 }
1089 var isLet = this.isLet();
1090 if (this.type === types$1._var || this.type === types$1._const || isLet) {
1091 var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
1092 this.next();
1093 this.parseVar(init$1, true, kind);
1094 this.finishNode(init$1, "VariableDeclaration");
1095 return this.parseForAfterInit(node, init$1, awaitAt)
1096 }
1097 var startsWithLet = this.isContextual("let"), isForOf = false;
1098
1099 var usingKind = this.isUsing(true) ? "using" : this.isAwaitUsing(true) ? "await using" : null;
1100 if (usingKind) {
1101 var init$2 = this.startNode();
1102 this.next();
1103 if (usingKind === "await using") { this.next(); }
1104 this.parseVar(init$2, true, usingKind);
1105 this.finishNode(init$2, "VariableDeclaration");
1106 return this.parseForAfterInit(node, init$2, awaitAt)
1107 }
1108 var containsEsc = this.containsEsc;
1109 var refDestructuringErrors = new DestructuringErrors;
1110 var initPos = this.start;
1111 var init = awaitAt > -1
1112 ? this.parseExprSubscripts(refDestructuringErrors, "await")
1113 : this.parseExpression(true, refDestructuringErrors);
1114 if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
1115 if (awaitAt > -1) { // implies `ecmaVersion >= 9` (see declaration of awaitAt)
1116 if (this.type === types$1._in) { this.unexpected(awaitAt); }
1117 node.await = true;
1118 } else if (isForOf && this.options.ecmaVersion >= 8) {
1119 if (init.start === initPos && !containsEsc && init.type === "Identifier" && init.name === "async") { this.unexpected(); }
1120 else if (this.options.ecmaVersion >= 9) { node.await = false; }
1121 }
1122 if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); }
1123 this.toAssignable(init, false, refDestructuringErrors);
1124 this.checkLValPattern(init);
1125 return this.parseForIn(node, init)
1126 } else {
1127 this.checkExpressionErrors(refDestructuringErrors, true);
1128 }
1129 if (awaitAt > -1) { this.unexpected(awaitAt); }
1130 return this.parseFor(node, init)
1131};
1132
1133// Helper method to parse for loop after variable initialization
1134pp$8.parseForAfterInit = function(node, init, awaitAt) {
1135 if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1) {
1136 if (this.options.ecmaVersion >= 9) {
1137 if (this.type === types$1._in) {
1138 if (awaitAt > -1) { this.unexpected(awaitAt); }
1139 } else { node.await = awaitAt > -1; }
1140 }
1141 return this.parseForIn(node, init)
1142 }
1143 if (awaitAt > -1) { this.unexpected(awaitAt); }
1144 return this.parseFor(node, init)
1145};
1146
1147pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {
1148 this.next();
1149 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
1150};
1151
1152pp$8.parseIfStatement = function(node) {
1153 this.next();
1154 node.test = this.parseParenExpression();
1155 // allow function declarations in branches, but only in non-strict mode
1156 node.consequent = this.parseStatement("if");
1157 node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
1158 return this.finishNode(node, "IfStatement")
1159};
1160
1161pp$8.parseReturnStatement = function(node) {
1162 if (!this.inFunction && !this.options.allowReturnOutsideFunction)
1163 { this.raise(this.start, "'return' outside of function"); }
1164 this.next();
1165
1166 // In `return` (and `break`/`continue`), the keywords with
1167 // optional arguments, we eagerly look for a semicolon or the
1168 // possibility to insert one.
1169
1170 if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }
1171 else { node.argument = this.parseExpression(); this.semicolon(); }
1172 return this.finishNode(node, "ReturnStatement")
1173};
1174
1175pp$8.parseSwitchStatement = function(node) {
1176 this.next();
1177 node.discriminant = this.parseParenExpression();
1178 node.cases = [];
1179 this.expect(types$1.braceL);
1180 this.labels.push(switchLabel);
1181 this.enterScope(0);
1182
1183 // Statements under must be grouped (by label) in SwitchCase
1184 // nodes. `cur` is used to keep the node that we are currently
1185 // adding statements to.
1186
1187 var cur;
1188 for (var sawDefault = false; this.type !== types$1.braceR;) {
1189 if (this.type === types$1._case || this.type === types$1._default) {
1190 var isCase = this.type === types$1._case;
1191 if (cur) { this.finishNode(cur, "SwitchCase"); }
1192 node.cases.push(cur = this.startNode());
1193 cur.consequent = [];
1194 this.next();
1195 if (isCase) {
1196 cur.test = this.parseExpression();
1197 } else {
1198 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
1199 sawDefault = true;
1200 cur.test = null;
1201 }
1202 this.expect(types$1.colon);
1203 } else {
1204 if (!cur) { this.unexpected(); }
1205 cur.consequent.push(this.parseStatement(null));
1206 }
1207 }
1208 this.exitScope();
1209 if (cur) { this.finishNode(cur, "SwitchCase"); }
1210 this.next(); // Closing brace
1211 this.labels.pop();
1212 return this.finishNode(node, "SwitchStatement")
1213};
1214
1215pp$8.parseThrowStatement = function(node) {
1216 this.next();
1217 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
1218 { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
1219 node.argument = this.parseExpression();
1220 this.semicolon();
1221 return this.finishNode(node, "ThrowStatement")
1222};
1223
1224// Reused empty array added for node fields that are always empty.
1225
1226var empty$1 = [];
1227
1228pp$8.parseCatchClauseParam = function() {
1229 var param = this.parseBindingAtom();
1230 var simple = param.type === "Identifier";
1231 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
1232 this.checkLValPattern(param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
1233 this.expect(types$1.parenR);
1234
1235 return param
1236};
1237
1238pp$8.parseTryStatement = function(node) {
1239 this.next();
1240 node.block = this.parseBlock();
1241 node.handler = null;
1242 if (this.type === types$1._catch) {
1243 var clause = this.startNode();
1244 this.next();
1245 if (this.eat(types$1.parenL)) {
1246 clause.param = this.parseCatchClauseParam();
1247 } else {
1248 if (this.options.ecmaVersion < 10) { this.unexpected(); }
1249 clause.param = null;
1250 this.enterScope(0);
1251 }
1252 clause.body = this.parseBlock(false);
1253 this.exitScope();
1254 node.handler = this.finishNode(clause, "CatchClause");
1255 }
1256 node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;
1257 if (!node.handler && !node.finalizer)
1258 { this.raise(node.start, "Missing catch or finally clause"); }
1259 return this.finishNode(node, "TryStatement")
1260};
1261
1262pp$8.parseVarStatement = function(node, kind, allowMissingInitializer) {
1263 this.next();
1264 this.parseVar(node, false, kind, allowMissingInitializer);
1265 this.semicolon();
1266 return this.finishNode(node, "VariableDeclaration")
1267};
1268
1269pp$8.parseWhileStatement = function(node) {
1270 this.next();
1271 node.test = this.parseParenExpression();
1272 this.labels.push(loopLabel);
1273 node.body = this.parseStatement("while");
1274 this.labels.pop();
1275 return this.finishNode(node, "WhileStatement")
1276};
1277
1278pp$8.parseWithStatement = function(node) {
1279 if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
1280 this.next();
1281 node.object = this.parseParenExpression();
1282 node.body = this.parseStatement("with");
1283 return this.finishNode(node, "WithStatement")
1284};
1285
1286pp$8.parseEmptyStatement = function(node) {
1287 this.next();
1288 return this.finishNode(node, "EmptyStatement")
1289};
1290
1291pp$8.parseLabeledStatement = function(node, maybeName, expr, context) {
1292 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
1293 {
1294 var label = list[i$1];
1295
1296 if (label.name === maybeName)
1297 { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
1298 } }
1299 var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null;
1300 for (var i = this.labels.length - 1; i >= 0; i--) {
1301 var label$1 = this.labels[i];
1302 if (label$1.statementStart === node.start) {
1303 // Update information about previous labels on this node
1304 label$1.statementStart = this.start;
1305 label$1.kind = kind;
1306 } else { break }
1307 }
1308 this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
1309 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
1310 this.labels.pop();
1311 node.label = expr;
1312 return this.finishNode(node, "LabeledStatement")
1313};
1314
1315pp$8.parseExpressionStatement = function(node, expr) {
1316 node.expression = expr;
1317 this.semicolon();
1318 return this.finishNode(node, "ExpressionStatement")
1319};
1320
1321// Parse a semicolon-enclosed block of statements, handling `"use
1322// strict"` declarations when `allowStrict` is true (used for
1323// function bodies).
1324
1325pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {
1326 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
1327 if ( node === void 0 ) node = this.startNode();
1328
1329 node.body = [];
1330 this.expect(types$1.braceL);
1331 if (createNewLexicalScope) { this.enterScope(0); }
1332 while (this.type !== types$1.braceR) {
1333 var stmt = this.parseStatement(null);
1334 node.body.push(stmt);
1335 }
1336 if (exitStrict) { this.strict = false; }
1337 this.next();
1338 if (createNewLexicalScope) { this.exitScope(); }
1339 return this.finishNode(node, "BlockStatement")
1340};
1341
1342// Parse a regular `for` loop. The disambiguation code in
1343// `parseStatement` will already have parsed the init statement or
1344// expression.
1345
1346pp$8.parseFor = function(node, init) {
1347 node.init = init;
1348 this.expect(types$1.semi);
1349 node.test = this.type === types$1.semi ? null : this.parseExpression();
1350 this.expect(types$1.semi);
1351 node.update = this.type === types$1.parenR ? null : this.parseExpression();
1352 this.expect(types$1.parenR);
1353 node.body = this.parseStatement("for");
1354 this.exitScope();
1355 this.labels.pop();
1356 return this.finishNode(node, "ForStatement")
1357};
1358
1359// Parse a `for`/`in` and `for`/`of` loop, which are almost
1360// same from parser's perspective.
1361
1362pp$8.parseForIn = function(node, init) {
1363 var isForIn = this.type === types$1._in;
1364 this.next();
1365
1366 if (
1367 init.type === "VariableDeclaration" &&
1368 init.declarations[0].init != null &&
1369 (
1370 !isForIn ||
1371 this.options.ecmaVersion < 8 ||
1372 this.strict ||
1373 init.kind !== "var" ||
1374 init.declarations[0].id.type !== "Identifier"
1375 )
1376 ) {
1377 this.raise(
1378 init.start,
1379 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
1380 );
1381 }
1382 node.left = init;
1383 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
1384 this.expect(types$1.parenR);
1385 node.body = this.parseStatement("for");
1386 this.exitScope();
1387 this.labels.pop();
1388 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
1389};
1390
1391// Parse a list of variable declarations.
1392
1393pp$8.parseVar = function(node, isFor, kind, allowMissingInitializer) {
1394 node.declarations = [];
1395 node.kind = kind;
1396 for (;;) {
1397 var decl = this.startNode();
1398 this.parseVarId(decl, kind);
1399 if (this.eat(types$1.eq)) {
1400 decl.init = this.parseMaybeAssign(isFor);
1401 } else if (!allowMissingInitializer && kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
1402 this.unexpected();
1403 } else if (!allowMissingInitializer && (kind === "using" || kind === "await using") && this.options.ecmaVersion >= 17 && this.type !== types$1._in && !this.isContextual("of")) {
1404 this.raise(this.lastTokEnd, ("Missing initializer in " + kind + " declaration"));
1405 } else if (!allowMissingInitializer && decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) {
1406 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
1407 } else {
1408 decl.init = null;
1409 }
1410 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
1411 if (!this.eat(types$1.comma)) { break }
1412 }
1413 return node
1414};
1415
1416pp$8.parseVarId = function(decl, kind) {
1417 decl.id = kind === "using" || kind === "await using"
1418 ? this.parseIdent()
1419 : this.parseBindingAtom();
1420
1421 this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
1422};
1423
1424var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
1425
1426// Parse a function declaration or literal (depending on the
1427// `statement & FUNC_STATEMENT`).
1428
1429// Remove `allowExpressionBody` for 7.0.0, as it is only called with false
1430pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {
1431 this.initFunction(node);
1432 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
1433 if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))
1434 { this.unexpected(); }
1435 node.generator = this.eat(types$1.star);
1436 }
1437 if (this.options.ecmaVersion >= 8)
1438 { node.async = !!isAsync; }
1439
1440 if (statement & FUNC_STATEMENT) {
1441 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();
1442 if (node.id && !(statement & FUNC_HANGING_STATEMENT))
1443 // If it is a regular function declaration in sloppy mode, then it is
1444 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
1445 // mode depends on properties of the current scope (see
1446 // treatFunctionsAsVar).
1447 { this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
1448 }
1449
1450 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
1451 this.yieldPos = 0;
1452 this.awaitPos = 0;
1453 this.awaitIdentPos = 0;
1454 this.enterScope(functionFlags(node.async, node.generator));
1455
1456 if (!(statement & FUNC_STATEMENT))
1457 { node.id = this.type === types$1.name ? this.parseIdent() : null; }
1458
1459 this.parseFunctionParams(node);
1460 this.parseFunctionBody(node, allowExpressionBody, false, forInit);
1461
1462 this.yieldPos = oldYieldPos;
1463 this.awaitPos = oldAwaitPos;
1464 this.awaitIdentPos = oldAwaitIdentPos;
1465 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
1466};
1467
1468pp$8.parseFunctionParams = function(node) {
1469 this.expect(types$1.parenL);
1470 node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
1471 this.checkYieldAwaitInDefaultParams();
1472};
1473
1474// Parse a class declaration or literal (depending on the
1475// `isStatement` parameter).
1476
1477pp$8.parseClass = function(node, isStatement) {
1478 this.next();
1479
1480 // ecma-262 14.6 Class Definitions
1481 // A class definition is always strict mode code.
1482 var oldStrict = this.strict;
1483 this.strict = true;
1484
1485 this.parseClassId(node, isStatement);
1486 this.parseClassSuper(node);
1487 var privateNameMap = this.enterClassBody();
1488 var classBody = this.startNode();
1489 var hadConstructor = false;
1490 classBody.body = [];
1491 this.expect(types$1.braceL);
1492 while (this.type !== types$1.braceR) {
1493 var element = this.parseClassElement(node.superClass !== null);
1494 if (element) {
1495 classBody.body.push(element);
1496 if (element.type === "MethodDefinition" && element.kind === "constructor") {
1497 if (hadConstructor) { this.raiseRecoverable(element.start, "Duplicate constructor in the same class"); }
1498 hadConstructor = true;
1499 } else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
1500 this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
1501 }
1502 }
1503 }
1504 this.strict = oldStrict;
1505 this.next();
1506 node.body = this.finishNode(classBody, "ClassBody");
1507 this.exitClassBody();
1508 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
1509};
1510
1511pp$8.parseClassElement = function(constructorAllowsSuper) {
1512 if (this.eat(types$1.semi)) { return null }
1513
1514 var ecmaVersion = this.options.ecmaVersion;
1515 var node = this.startNode();
1516 var keyName = "";
1517 var isGenerator = false;
1518 var isAsync = false;
1519 var kind = "method";
1520 var isStatic = false;
1521
1522 if (this.eatContextual("static")) {
1523 // Parse static init block
1524 if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {
1525 this.parseClassStaticBlock(node);
1526 return node
1527 }
1528 if (this.isClassElementNameStart() || this.type === types$1.star) {
1529 isStatic = true;
1530 } else {
1531 keyName = "static";
1532 }
1533 }
1534 node.static = isStatic;
1535 if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
1536 if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {
1537 isAsync = true;
1538 } else {
1539 keyName = "async";
1540 }
1541 }
1542 if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {
1543 isGenerator = true;
1544 }
1545 if (!keyName && !isAsync && !isGenerator) {
1546 var lastValue = this.value;
1547 if (this.eatContextual("get") || this.eatContextual("set")) {
1548 if (this.isClassElementNameStart()) {
1549 kind = lastValue;
1550 } else {
1551 keyName = lastValue;
1552 }
1553 }
1554 }
1555
1556 // Parse element name
1557 if (keyName) {
1558 // 'async', 'get', 'set', or 'static' were not a keyword contextually.
1559 // The last token is any of those. Make it the element name.
1560 node.computed = false;
1561 node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
1562 node.key.name = keyName;
1563 this.finishNode(node.key, "Identifier");
1564 } else {
1565 this.parseClassElementName(node);
1566 }
1567
1568 // Parse element value
1569 if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) {
1570 var isConstructor = !node.static && checkKeyName(node, "constructor");
1571 var allowsDirectSuper = isConstructor && constructorAllowsSuper;
1572 // Couldn't move this check into the 'parseClassMethod' method for backward compatibility.
1573 if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
1574 node.kind = isConstructor ? "constructor" : kind;
1575 this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
1576 } else {
1577 this.parseClassField(node);
1578 }
1579
1580 return node
1581};
1582
1583pp$8.isClassElementNameStart = function() {
1584 return (
1585 this.type === types$1.name ||
1586 this.type === types$1.privateId ||
1587 this.type === types$1.num ||
1588 this.type === types$1.string ||
1589 this.type === types$1.bracketL ||
1590 this.type.keyword
1591 )
1592};
1593
1594pp$8.parseClassElementName = function(element) {
1595 if (this.type === types$1.privateId) {
1596 if (this.value === "constructor") {
1597 this.raise(this.start, "Classes can't have an element named '#constructor'");
1598 }
1599 element.computed = false;
1600 element.key = this.parsePrivateIdent();
1601 } else {
1602 this.parsePropertyName(element);
1603 }
1604};
1605
1606pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
1607 // Check key and flags
1608 var key = method.key;
1609 if (method.kind === "constructor") {
1610 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
1611 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
1612 } else if (method.static && checkKeyName(method, "prototype")) {
1613 this.raise(key.start, "Classes may not have a static property named prototype");
1614 }
1615
1616 // Parse value
1617 var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
1618
1619 // Check value
1620 if (method.kind === "get" && value.params.length !== 0)
1621 { this.raiseRecoverable(value.start, "getter should have no params"); }
1622 if (method.kind === "set" && value.params.length !== 1)
1623 { this.raiseRecoverable(value.start, "setter should have exactly one param"); }
1624 if (method.kind === "set" && value.params[0].type === "RestElement")
1625 { this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
1626
1627 return this.finishNode(method, "MethodDefinition")
1628};
1629
1630pp$8.parseClassField = function(field) {
1631 if (checkKeyName(field, "constructor")) {
1632 this.raise(field.key.start, "Classes can't have a field named 'constructor'");
1633 } else if (field.static && checkKeyName(field, "prototype")) {
1634 this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
1635 }
1636
1637 if (this.eat(types$1.eq)) {
1638 // To raise SyntaxError if 'arguments' exists in the initializer.
1639 this.enterScope(SCOPE_CLASS_FIELD_INIT | SCOPE_SUPER);
1640 field.value = this.parseMaybeAssign();
1641 this.exitScope();
1642 } else {
1643 field.value = null;
1644 }
1645 this.semicolon();
1646
1647 return this.finishNode(field, "PropertyDefinition")
1648};
1649
1650pp$8.parseClassStaticBlock = function(node) {
1651 node.body = [];
1652
1653 var oldLabels = this.labels;
1654 this.labels = [];
1655 this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);
1656 while (this.type !== types$1.braceR) {
1657 var stmt = this.parseStatement(null);
1658 node.body.push(stmt);
1659 }
1660 this.next();
1661 this.exitScope();
1662 this.labels = oldLabels;
1663
1664 return this.finishNode(node, "StaticBlock")
1665};
1666
1667pp$8.parseClassId = function(node, isStatement) {
1668 if (this.type === types$1.name) {
1669 node.id = this.parseIdent();
1670 if (isStatement)
1671 { this.checkLValSimple(node.id, BIND_LEXICAL, false); }
1672 } else {
1673 if (isStatement === true)
1674 { this.unexpected(); }
1675 node.id = null;
1676 }
1677};
1678
1679pp$8.parseClassSuper = function(node) {
1680 node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(null, false) : null;
1681};
1682
1683pp$8.enterClassBody = function() {
1684 var element = {declared: Object.create(null), used: []};
1685 this.privateNameStack.push(element);
1686 return element.declared
1687};
1688
1689pp$8.exitClassBody = function() {
1690 var ref = this.privateNameStack.pop();
1691 var declared = ref.declared;
1692 var used = ref.used;
1693 if (!this.options.checkPrivateFields) { return }
1694 var len = this.privateNameStack.length;
1695 var parent = len === 0 ? null : this.privateNameStack[len - 1];
1696 for (var i = 0; i < used.length; ++i) {
1697 var id = used[i];
1698 if (!hasOwn(declared, id.name)) {
1699 if (parent) {
1700 parent.used.push(id);
1701 } else {
1702 this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
1703 }
1704 }
1705 }
1706};
1707
1708function isPrivateNameConflicted(privateNameMap, element) {
1709 var name = element.key.name;
1710 var curr = privateNameMap[name];
1711
1712 var next = "true";
1713 if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
1714 next = (element.static ? "s" : "i") + element.kind;
1715 }
1716
1717 // `class { get #a(){}; static set #a(_){} }` is also conflict.
1718 if (
1719 curr === "iget" && next === "iset" ||
1720 curr === "iset" && next === "iget" ||
1721 curr === "sget" && next === "sset" ||
1722 curr === "sset" && next === "sget"
1723 ) {
1724 privateNameMap[name] = "true";
1725 return false
1726 } else if (!curr) {
1727 privateNameMap[name] = next;
1728 return false
1729 } else {
1730 return true
1731 }
1732}
1733
1734function checkKeyName(node, name) {
1735 var computed = node.computed;
1736 var key = node.key;
1737 return !computed && (
1738 key.type === "Identifier" && key.name === name ||
1739 key.type === "Literal" && key.value === name
1740 )
1741}
1742
1743// Parses module export declaration.
1744
1745pp$8.parseExportAllDeclaration = function(node, exports) {
1746 if (this.options.ecmaVersion >= 11) {
1747 if (this.eatContextual("as")) {
1748 node.exported = this.parseModuleExportName();
1749 this.checkExport(exports, node.exported, this.lastTokStart);
1750 } else {
1751 node.exported = null;
1752 }
1753 }
1754 this.expectContextual("from");
1755 if (this.type !== types$1.string) { this.unexpected(); }
1756 node.source = this.parseExprAtom();
1757 if (this.options.ecmaVersion >= 16)
1758 { node.attributes = this.parseWithClause(); }
1759 this.semicolon();
1760 return this.finishNode(node, "ExportAllDeclaration")
1761};
1762
1763pp$8.parseExport = function(node, exports) {
1764 this.next();
1765 // export * from '...'
1766 if (this.eat(types$1.star)) {
1767 return this.parseExportAllDeclaration(node, exports)
1768 }
1769 if (this.eat(types$1._default)) { // export default ...
1770 this.checkExport(exports, "default", this.lastTokStart);
1771 node.declaration = this.parseExportDefaultDeclaration();
1772 return this.finishNode(node, "ExportDefaultDeclaration")
1773 }
1774 // export var|const|let|function|class ...
1775 if (this.shouldParseExportStatement()) {
1776 node.declaration = this.parseExportDeclaration(node);
1777 if (node.declaration.type === "VariableDeclaration")
1778 { this.checkVariableExport(exports, node.declaration.declarations); }
1779 else
1780 { this.checkExport(exports, node.declaration.id, node.declaration.id.start); }
1781 node.specifiers = [];
1782 node.source = null;
1783 if (this.options.ecmaVersion >= 16)
1784 { node.attributes = []; }
1785 } else { // export { x, y as z } [from '...']
1786 node.declaration = null;
1787 node.specifiers = this.parseExportSpecifiers(exports);
1788 if (this.eatContextual("from")) {
1789 if (this.type !== types$1.string) { this.unexpected(); }
1790 node.source = this.parseExprAtom();
1791 if (this.options.ecmaVersion >= 16)
1792 { node.attributes = this.parseWithClause(); }
1793 } else {
1794 for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
1795 // check for keywords used as local names
1796 var spec = list[i];
1797
1798 this.checkUnreserved(spec.local);
1799 // check if export is defined
1800 this.checkLocalExport(spec.local);
1801
1802 if (spec.local.type === "Literal") {
1803 this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`.");
1804 }
1805 }
1806
1807 node.source = null;
1808 if (this.options.ecmaVersion >= 16)
1809 { node.attributes = []; }
1810 }
1811 this.semicolon();
1812 }
1813 return this.finishNode(node, "ExportNamedDeclaration")
1814};
1815
1816pp$8.parseExportDeclaration = function(node) {
1817 return this.parseStatement(null)
1818};
1819
1820pp$8.parseExportDefaultDeclaration = function() {
1821 var isAsync;
1822 if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {
1823 var fNode = this.startNode();
1824 this.next();
1825 if (isAsync) { this.next(); }
1826 return this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync)
1827 } else if (this.type === types$1._class) {
1828 var cNode = this.startNode();
1829 return this.parseClass(cNode, "nullableID")
1830 } else {
1831 var declaration = this.parseMaybeAssign();
1832 this.semicolon();
1833 return declaration
1834 }
1835};
1836
1837pp$8.checkExport = function(exports, name, pos) {
1838 if (!exports) { return }
1839 if (typeof name !== "string")
1840 { name = name.type === "Identifier" ? name.name : name.value; }
1841 if (hasOwn(exports, name))
1842 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
1843 exports[name] = true;
1844};
1845
1846pp$8.checkPatternExport = function(exports, pat) {
1847 var type = pat.type;
1848 if (type === "Identifier")
1849 { this.checkExport(exports, pat, pat.start); }
1850 else if (type === "ObjectPattern")
1851 { for (var i = 0, list = pat.properties; i < list.length; i += 1)
1852 {
1853 var prop = list[i];
1854
1855 this.checkPatternExport(exports, prop);
1856 } }
1857 else if (type === "ArrayPattern")
1858 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
1859 var elt = list$1[i$1];
1860
1861 if (elt) { this.checkPatternExport(exports, elt); }
1862 } }
1863 else if (type === "Property")
1864 { this.checkPatternExport(exports, pat.value); }
1865 else if (type === "AssignmentPattern")
1866 { this.checkPatternExport(exports, pat.left); }
1867 else if (type === "RestElement")
1868 { this.checkPatternExport(exports, pat.argument); }
1869};
1870
1871pp$8.checkVariableExport = function(exports, decls) {
1872 if (!exports) { return }
1873 for (var i = 0, list = decls; i < list.length; i += 1)
1874 {
1875 var decl = list[i];
1876
1877 this.checkPatternExport(exports, decl.id);
1878 }
1879};
1880
1881pp$8.shouldParseExportStatement = function() {
1882 return this.type.keyword === "var" ||
1883 this.type.keyword === "const" ||
1884 this.type.keyword === "class" ||
1885 this.type.keyword === "function" ||
1886 this.isLet() ||
1887 this.isAsyncFunction()
1888};
1889
1890// Parses a comma-separated list of module exports.
1891
1892pp$8.parseExportSpecifier = function(exports) {
1893 var node = this.startNode();
1894 node.local = this.parseModuleExportName();
1895
1896 node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local;
1897 this.checkExport(
1898 exports,
1899 node.exported,
1900 node.exported.start
1901 );
1902
1903 return this.finishNode(node, "ExportSpecifier")
1904};
1905
1906pp$8.parseExportSpecifiers = function(exports) {
1907 var nodes = [], first = true;
1908 // export { x, y as z } [from '...']
1909 this.expect(types$1.braceL);
1910 while (!this.eat(types$1.braceR)) {
1911 if (!first) {
1912 this.expect(types$1.comma);
1913 if (this.afterTrailingComma(types$1.braceR)) { break }
1914 } else { first = false; }
1915
1916 nodes.push(this.parseExportSpecifier(exports));
1917 }
1918 return nodes
1919};
1920
1921// Parses import declaration.
1922
1923pp$8.parseImport = function(node) {
1924 this.next();
1925
1926 // import '...'
1927 if (this.type === types$1.string) {
1928 node.specifiers = empty$1;
1929 node.source = this.parseExprAtom();
1930 } else {
1931 node.specifiers = this.parseImportSpecifiers();
1932 this.expectContextual("from");
1933 node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();
1934 }
1935 if (this.options.ecmaVersion >= 16)
1936 { node.attributes = this.parseWithClause(); }
1937 this.semicolon();
1938 return this.finishNode(node, "ImportDeclaration")
1939};
1940
1941// Parses a comma-separated list of module imports.
1942
1943pp$8.parseImportSpecifier = function() {
1944 var node = this.startNode();
1945 node.imported = this.parseModuleExportName();
1946
1947 if (this.eatContextual("as")) {
1948 node.local = this.parseIdent();
1949 } else {
1950 this.checkUnreserved(node.imported);
1951 node.local = node.imported;
1952 }
1953 this.checkLValSimple(node.local, BIND_LEXICAL);
1954
1955 return this.finishNode(node, "ImportSpecifier")
1956};
1957
1958pp$8.parseImportDefaultSpecifier = function() {
1959 // import defaultObj, { x, y as z } from '...'
1960 var node = this.startNode();
1961 node.local = this.parseIdent();
1962 this.checkLValSimple(node.local, BIND_LEXICAL);
1963 return this.finishNode(node, "ImportDefaultSpecifier")
1964};
1965
1966pp$8.parseImportNamespaceSpecifier = function() {
1967 var node = this.startNode();
1968 this.next();
1969 this.expectContextual("as");
1970 node.local = this.parseIdent();
1971 this.checkLValSimple(node.local, BIND_LEXICAL);
1972 return this.finishNode(node, "ImportNamespaceSpecifier")
1973};
1974
1975pp$8.parseImportSpecifiers = function() {
1976 var nodes = [], first = true;
1977 if (this.type === types$1.name) {
1978 nodes.push(this.parseImportDefaultSpecifier());
1979 if (!this.eat(types$1.comma)) { return nodes }
1980 }
1981 if (this.type === types$1.star) {
1982 nodes.push(this.parseImportNamespaceSpecifier());
1983 return nodes
1984 }
1985 this.expect(types$1.braceL);
1986 while (!this.eat(types$1.braceR)) {
1987 if (!first) {
1988 this.expect(types$1.comma);
1989 if (this.afterTrailingComma(types$1.braceR)) { break }
1990 } else { first = false; }
1991
1992 nodes.push(this.parseImportSpecifier());
1993 }
1994 return nodes
1995};
1996
1997pp$8.parseWithClause = function() {
1998 var nodes = [];
1999 if (!this.eat(types$1._with)) {
2000 return nodes
2001 }
2002 this.expect(types$1.braceL);
2003 var attributeKeys = {};
2004 var first = true;
2005 while (!this.eat(types$1.braceR)) {
2006 if (!first) {
2007 this.expect(types$1.comma);
2008 if (this.afterTrailingComma(types$1.braceR)) { break }
2009 } else { first = false; }
2010
2011 var attr = this.parseImportAttribute();
2012 var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
2013 if (hasOwn(attributeKeys, keyName))
2014 { this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'"); }
2015 attributeKeys[keyName] = true;
2016 nodes.push(attr);
2017 }
2018 return nodes
2019};
2020
2021pp$8.parseImportAttribute = function() {
2022 var node = this.startNode();
2023 node.key = this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never");
2024 this.expect(types$1.colon);
2025 if (this.type !== types$1.string) {
2026 this.unexpected();
2027 }
2028 node.value = this.parseExprAtom();
2029 return this.finishNode(node, "ImportAttribute")
2030};
2031
2032pp$8.parseModuleExportName = function() {
2033 if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {
2034 var stringLiteral = this.parseLiteral(this.value);
2035 if (loneSurrogate.test(stringLiteral.value)) {
2036 this.raise(stringLiteral.start, "An export name cannot include a lone surrogate.");
2037 }
2038 return stringLiteral
2039 }
2040 return this.parseIdent(true)
2041};
2042
2043// Set `ExpressionStatement#directive` property for directive prologues.
2044pp$8.adaptDirectivePrologue = function(statements) {
2045 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
2046 statements[i].directive = statements[i].expression.raw.slice(1, -1);
2047 }
2048};
2049pp$8.isDirectiveCandidate = function(statement) {
2050 return (
2051 this.options.ecmaVersion >= 5 &&
2052 statement.type === "ExpressionStatement" &&
2053 statement.expression.type === "Literal" &&
2054 typeof statement.expression.value === "string" &&
2055 // Reject parenthesized strings.
2056 (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
2057 )
2058};
2059
2060var pp$7 = Parser.prototype;
2061
2062// Convert existing expression atom to assignable pattern
2063// if possible.
2064
2065pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {
2066 if (this.options.ecmaVersion >= 6 && node) {
2067 switch (node.type) {
2068 case "Identifier":
2069 if (this.inAsync && node.name === "await")
2070 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
2071 break
2072
2073 case "ObjectPattern":
2074 case "ArrayPattern":
2075 case "AssignmentPattern":
2076 case "RestElement":
2077 break
2078
2079 case "ObjectExpression":
2080 node.type = "ObjectPattern";
2081 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2082 for (var i = 0, list = node.properties; i < list.length; i += 1) {
2083 var prop = list[i];
2084
2085 this.toAssignable(prop, isBinding);
2086 // Early error:
2087 // AssignmentRestProperty[Yield, Await] :
2088 // `...` DestructuringAssignmentTarget[Yield, Await]
2089 //
2090 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
2091 if (
2092 prop.type === "RestElement" &&
2093 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
2094 ) {
2095 this.raise(prop.argument.start, "Unexpected token");
2096 }
2097 }
2098 break
2099
2100 case "Property":
2101 // AssignmentProperty has type === "Property"
2102 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
2103 this.toAssignable(node.value, isBinding);
2104 break
2105
2106 case "ArrayExpression":
2107 node.type = "ArrayPattern";
2108 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2109 this.toAssignableList(node.elements, isBinding);
2110 break
2111
2112 case "SpreadElement":
2113 node.type = "RestElement";
2114 this.toAssignable(node.argument, isBinding);
2115 if (node.argument.type === "AssignmentPattern")
2116 { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
2117 break
2118
2119 case "AssignmentExpression":
2120 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
2121 node.type = "AssignmentPattern";
2122 delete node.operator;
2123 this.toAssignable(node.left, isBinding);
2124 break
2125
2126 case "ParenthesizedExpression":
2127 this.toAssignable(node.expression, isBinding, refDestructuringErrors);
2128 break
2129
2130 case "ChainExpression":
2131 this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
2132 break
2133
2134 case "MemberExpression":
2135 if (!isBinding) { break }
2136
2137 default:
2138 this.raise(node.start, "Assigning to rvalue");
2139 }
2140 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
2141 return node
2142};
2143
2144// Convert list of expression atoms to binding list.
2145
2146pp$7.toAssignableList = function(exprList, isBinding) {
2147 var end = exprList.length;
2148 for (var i = 0; i < end; i++) {
2149 var elt = exprList[i];
2150 if (elt) { this.toAssignable(elt, isBinding); }
2151 }
2152 if (end) {
2153 var last = exprList[end - 1];
2154 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
2155 { this.unexpected(last.argument.start); }
2156 }
2157 return exprList
2158};
2159
2160// Parses spread element.
2161
2162pp$7.parseSpread = function(refDestructuringErrors) {
2163 var node = this.startNode();
2164 this.next();
2165 node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
2166 return this.finishNode(node, "SpreadElement")
2167};
2168
2169pp$7.parseRestBinding = function() {
2170 var node = this.startNode();
2171 this.next();
2172
2173 // RestElement inside of a function parameter must be an identifier
2174 if (this.options.ecmaVersion === 6 && this.type !== types$1.name)
2175 { this.unexpected(); }
2176
2177 node.argument = this.parseBindingAtom();
2178
2179 return this.finishNode(node, "RestElement")
2180};
2181
2182// Parses lvalue (assignable) atom.
2183
2184pp$7.parseBindingAtom = function() {
2185 if (this.options.ecmaVersion >= 6) {
2186 switch (this.type) {
2187 case types$1.bracketL:
2188 var node = this.startNode();
2189 this.next();
2190 node.elements = this.parseBindingList(types$1.bracketR, true, true);
2191 return this.finishNode(node, "ArrayPattern")
2192
2193 case types$1.braceL:
2194 return this.parseObj(true)
2195 }
2196 }
2197 return this.parseIdent()
2198};
2199
2200pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowModifiers) {
2201 var elts = [], first = true;
2202 while (!this.eat(close)) {
2203 if (first) { first = false; }
2204 else { this.expect(types$1.comma); }
2205 if (allowEmpty && this.type === types$1.comma) {
2206 elts.push(null);
2207 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
2208 break
2209 } else if (this.type === types$1.ellipsis) {
2210 var rest = this.parseRestBinding();
2211 this.parseBindingListItem(rest);
2212 elts.push(rest);
2213 if (this.type === types$1.comma) { this.raiseRecoverable(this.start, "Comma is not permitted after the rest element"); }
2214 this.expect(close);
2215 break
2216 } else {
2217 elts.push(this.parseAssignableListItem(allowModifiers));
2218 }
2219 }
2220 return elts
2221};
2222
2223pp$7.parseAssignableListItem = function(allowModifiers) {
2224 var elem = this.parseMaybeDefault(this.start, this.startLoc);
2225 this.parseBindingListItem(elem);
2226 return elem
2227};
2228
2229pp$7.parseBindingListItem = function(param) {
2230 return param
2231};
2232
2233// Parses assignment pattern around given atom if possible.
2234
2235pp$7.parseMaybeDefault = function(startPos, startLoc, left) {
2236 left = left || this.parseBindingAtom();
2237 if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }
2238 var node = this.startNodeAt(startPos, startLoc);
2239 node.left = left;
2240 node.right = this.parseMaybeAssign();
2241 return this.finishNode(node, "AssignmentPattern")
2242};
2243
2244// The following three functions all verify that a node is an lvalue —
2245// something that can be bound, or assigned to. In order to do so, they perform
2246// a variety of checks:
2247//
2248// - Check that none of the bound/assigned-to identifiers are reserved words.
2249// - Record name declarations for bindings in the appropriate scope.
2250// - Check duplicate argument names, if checkClashes is set.
2251//
2252// If a complex binding pattern is encountered (e.g., object and array
2253// destructuring), the entire pattern is recursively checked.
2254//
2255// There are three versions of checkLVal*() appropriate for different
2256// circumstances:
2257//
2258// - checkLValSimple() shall be used if the syntactic construct supports
2259// nothing other than identifiers and member expressions. Parenthesized
2260// expressions are also correctly handled. This is generally appropriate for
2261// constructs for which the spec says
2262//
2263// > It is a Syntax Error if AssignmentTargetType of [the production] is not
2264// > simple.
2265//
2266// It is also appropriate for checking if an identifier is valid and not
2267// defined elsewhere, like import declarations or function/class identifiers.
2268//
2269// Examples where this is used include:
2270// a += …;
2271// import a from '…';
2272// where a is the node to be checked.
2273//
2274// - checkLValPattern() shall be used if the syntactic construct supports
2275// anything checkLValSimple() supports, as well as object and array
2276// destructuring patterns. This is generally appropriate for constructs for
2277// which the spec says
2278//
2279// > It is a Syntax Error if [the production] is neither an ObjectLiteral nor
2280// > an ArrayLiteral and AssignmentTargetType of [the production] is not
2281// > simple.
2282//
2283// Examples where this is used include:
2284// (a = …);
2285// const a = …;
2286// try { … } catch (a) { … }
2287// where a is the node to be checked.
2288//
2289// - checkLValInnerPattern() shall be used if the syntactic construct supports
2290// anything checkLValPattern() supports, as well as default assignment
2291// patterns, rest elements, and other constructs that may appear within an
2292// object or array destructuring pattern.
2293//
2294// As a special case, function parameters also use checkLValInnerPattern(),
2295// as they also support defaults and rest constructs.
2296//
2297// These functions deliberately support both assignment and binding constructs,
2298// as the logic for both is exceedingly similar. If the node is the target of
2299// an assignment, then bindingType should be set to BIND_NONE. Otherwise, it
2300// should be set to the appropriate BIND_* constant, like BIND_VAR or
2301// BIND_LEXICAL.
2302//
2303// If the function is called with a non-BIND_NONE bindingType, then
2304// additionally a checkClashes object may be specified to allow checking for
2305// duplicate argument names. checkClashes is ignored if the provided construct
2306// is an assignment (i.e., bindingType is BIND_NONE).
2307
2308pp$7.checkLValSimple = function(expr, bindingType, checkClashes) {
2309 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2310
2311 var isBind = bindingType !== BIND_NONE;
2312
2313 switch (expr.type) {
2314 case "Identifier":
2315 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
2316 { this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
2317 if (isBind) {
2318 if (bindingType === BIND_LEXICAL && expr.name === "let")
2319 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
2320 if (checkClashes) {
2321 if (hasOwn(checkClashes, expr.name))
2322 { this.raiseRecoverable(expr.start, "Argument name clash"); }
2323 checkClashes[expr.name] = true;
2324 }
2325 if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
2326 }
2327 break
2328
2329 case "ChainExpression":
2330 this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
2331 break
2332
2333 case "MemberExpression":
2334 if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); }
2335 break
2336
2337 case "ParenthesizedExpression":
2338 if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); }
2339 return this.checkLValSimple(expr.expression, bindingType, checkClashes)
2340
2341 default:
2342 this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue");
2343 }
2344};
2345
2346pp$7.checkLValPattern = function(expr, bindingType, checkClashes) {
2347 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2348
2349 switch (expr.type) {
2350 case "ObjectPattern":
2351 for (var i = 0, list = expr.properties; i < list.length; i += 1) {
2352 var prop = list[i];
2353
2354 this.checkLValInnerPattern(prop, bindingType, checkClashes);
2355 }
2356 break
2357
2358 case "ArrayPattern":
2359 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
2360 var elem = list$1[i$1];
2361
2362 if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }
2363 }
2364 break
2365
2366 default:
2367 this.checkLValSimple(expr, bindingType, checkClashes);
2368 }
2369};
2370
2371pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {
2372 if ( bindingType === void 0 ) bindingType = BIND_NONE;
2373
2374 switch (expr.type) {
2375 case "Property":
2376 // AssignmentProperty has type === "Property"
2377 this.checkLValInnerPattern(expr.value, bindingType, checkClashes);
2378 break
2379
2380 case "AssignmentPattern":
2381 this.checkLValPattern(expr.left, bindingType, checkClashes);
2382 break
2383
2384 case "RestElement":
2385 this.checkLValPattern(expr.argument, bindingType, checkClashes);
2386 break
2387
2388 default:
2389 this.checkLValPattern(expr, bindingType, checkClashes);
2390 }
2391};
2392
2393// The algorithm used to determine whether a regexp can appear at a
2394// given point in the program is loosely based on sweet.js' approach.
2395// See https://github.com/mozilla/sweet.js/wiki/design
2396
2397
2398var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
2399 this.token = token;
2400 this.isExpr = !!isExpr;
2401 this.preserveSpace = !!preserveSpace;
2402 this.override = override;
2403 this.generator = !!generator;
2404};
2405
2406var types = {
2407 b_stat: new TokContext("{", false),
2408 b_expr: new TokContext("{", true),
2409 b_tmpl: new TokContext("${", false),
2410 p_stat: new TokContext("(", false),
2411 p_expr: new TokContext("(", true),
2412 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
2413 f_stat: new TokContext("function", false),
2414 f_expr: new TokContext("function", true),
2415 f_expr_gen: new TokContext("function", true, false, null, true),
2416 f_gen: new TokContext("function", false, false, null, true)
2417};
2418
2419var pp$6 = Parser.prototype;
2420
2421pp$6.initialContext = function() {
2422 return [types.b_stat]
2423};
2424
2425pp$6.curContext = function() {
2426 return this.context[this.context.length - 1]
2427};
2428
2429pp$6.braceIsBlock = function(prevType) {
2430 var parent = this.curContext();
2431 if (parent === types.f_expr || parent === types.f_stat)
2432 { return true }
2433 if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))
2434 { return !parent.isExpr }
2435
2436 // The check for `tt.name && exprAllowed` detects whether we are
2437 // after a `yield` or `of` construct. See the `updateContext` for
2438 // `tt.name`.
2439 if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)
2440 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
2441 if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)
2442 { return true }
2443 if (prevType === types$1.braceL)
2444 { return parent === types.b_stat }
2445 if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)
2446 { return false }
2447 return !this.exprAllowed
2448};
2449
2450pp$6.inGeneratorContext = function() {
2451 for (var i = this.context.length - 1; i >= 1; i--) {
2452 var context = this.context[i];
2453 if (context.token === "function")
2454 { return context.generator }
2455 }
2456 return false
2457};
2458
2459pp$6.updateContext = function(prevType) {
2460 var update, type = this.type;
2461 if (type.keyword && prevType === types$1.dot)
2462 { this.exprAllowed = false; }
2463 else if (update = type.updateContext)
2464 { update.call(this, prevType); }
2465 else
2466 { this.exprAllowed = type.beforeExpr; }
2467};
2468
2469// Used to handle edge cases when token context could not be inferred correctly during tokenization phase
2470
2471pp$6.overrideContext = function(tokenCtx) {
2472 if (this.curContext() !== tokenCtx) {
2473 this.context[this.context.length - 1] = tokenCtx;
2474 }
2475};
2476
2477// Token-specific context update code
2478
2479types$1.parenR.updateContext = types$1.braceR.updateContext = function() {
2480 if (this.context.length === 1) {
2481 this.exprAllowed = true;
2482 return
2483 }
2484 var out = this.context.pop();
2485 if (out === types.b_stat && this.curContext().token === "function") {
2486 out = this.context.pop();
2487 }
2488 this.exprAllowed = !out.isExpr;
2489};
2490
2491types$1.braceL.updateContext = function(prevType) {
2492 this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
2493 this.exprAllowed = true;
2494};
2495
2496types$1.dollarBraceL.updateContext = function() {
2497 this.context.push(types.b_tmpl);
2498 this.exprAllowed = true;
2499};
2500
2501types$1.parenL.updateContext = function(prevType) {
2502 var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;
2503 this.context.push(statementParens ? types.p_stat : types.p_expr);
2504 this.exprAllowed = true;
2505};
2506
2507types$1.incDec.updateContext = function() {
2508 // tokExprAllowed stays unchanged
2509};
2510
2511types$1._function.updateContext = types$1._class.updateContext = function(prevType) {
2512 if (prevType.beforeExpr && prevType !== types$1._else &&
2513 !(prevType === types$1.semi && this.curContext() !== types.p_stat) &&
2514 !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
2515 !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))
2516 { this.context.push(types.f_expr); }
2517 else
2518 { this.context.push(types.f_stat); }
2519 this.exprAllowed = false;
2520};
2521
2522types$1.colon.updateContext = function() {
2523 if (this.curContext().token === "function") { this.context.pop(); }
2524 this.exprAllowed = true;
2525};
2526
2527types$1.backQuote.updateContext = function() {
2528 if (this.curContext() === types.q_tmpl)
2529 { this.context.pop(); }
2530 else
2531 { this.context.push(types.q_tmpl); }
2532 this.exprAllowed = false;
2533};
2534
2535types$1.star.updateContext = function(prevType) {
2536 if (prevType === types$1._function) {
2537 var index = this.context.length - 1;
2538 if (this.context[index] === types.f_expr)
2539 { this.context[index] = types.f_expr_gen; }
2540 else
2541 { this.context[index] = types.f_gen; }
2542 }
2543 this.exprAllowed = true;
2544};
2545
2546types$1.name.updateContext = function(prevType) {
2547 var allowed = false;
2548 if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {
2549 if (this.value === "of" && !this.exprAllowed ||
2550 this.value === "yield" && this.inGeneratorContext())
2551 { allowed = true; }
2552 }
2553 this.exprAllowed = allowed;
2554};
2555
2556// A recursive descent parser operates by defining functions for all
2557// syntactic elements, and recursively calling those, each function
2558// advancing the input stream and returning an AST node. Precedence
2559// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
2560// instead of `(!x)[1]` is handled by the fact that the parser
2561// function that parses unary prefix operators is called first, and
2562// in turn calls the function that parses `[]` subscripts — that
2563// way, it'll receive the node for `x[1]` already parsed, and wraps
2564// *that* in the unary operator node.
2565//
2566// Acorn uses an [operator precedence parser][opp] to handle binary
2567// operator precedence, because it is much more compact than using
2568// the technique outlined above, which uses different, nesting
2569// functions to specify precedence, for all of the ten binary
2570// precedence levels that JavaScript defines.
2571//
2572// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
2573
2574
2575var pp$5 = Parser.prototype;
2576
2577// Check if property name clashes with already added.
2578// Object/class getters and setters are not allowed to clash —
2579// either with each other or with an init property — and in
2580// strict mode, init properties are also not allowed to be repeated.
2581
2582pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
2583 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
2584 { return }
2585 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
2586 { return }
2587 var key = prop.key;
2588 var name;
2589 switch (key.type) {
2590 case "Identifier": name = key.name; break
2591 case "Literal": name = String(key.value); break
2592 default: return
2593 }
2594 var kind = prop.kind;
2595 if (this.options.ecmaVersion >= 6) {
2596 if (name === "__proto__" && kind === "init") {
2597 if (propHash.proto) {
2598 if (refDestructuringErrors) {
2599 if (refDestructuringErrors.doubleProto < 0) {
2600 refDestructuringErrors.doubleProto = key.start;
2601 }
2602 } else {
2603 this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
2604 }
2605 }
2606 propHash.proto = true;
2607 }
2608 return
2609 }
2610 name = "$" + name;
2611 var other = propHash[name];
2612 if (other) {
2613 var redefinition;
2614 if (kind === "init") {
2615 redefinition = this.strict && other.init || other.get || other.set;
2616 } else {
2617 redefinition = other.init || other[kind];
2618 }
2619 if (redefinition)
2620 { this.raiseRecoverable(key.start, "Redefinition of property"); }
2621 } else {
2622 other = propHash[name] = {
2623 init: false,
2624 get: false,
2625 set: false
2626 };
2627 }
2628 other[kind] = true;
2629};
2630
2631// ### Expression parsing
2632
2633// These nest, from the most general expression type at the top to
2634// 'atomic', nondivisible expression types at the bottom. Most of
2635// the functions will simply let the function(s) below them parse,
2636// and, *if* the syntactic construct they handle is present, wrap
2637// the AST node that the inner parser gave them in another node.
2638
2639// Parse a full expression. The optional arguments are used to
2640// forbid the `in` operator (in for loops initalization expressions)
2641// and provide reference for storing '=' operator inside shorthand
2642// property assignment in contexts where both object expression
2643// and object pattern might appear (so it's possible to raise
2644// delayed syntax error at correct position).
2645
2646pp$5.parseExpression = function(forInit, refDestructuringErrors) {
2647 var startPos = this.start, startLoc = this.startLoc;
2648 var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
2649 if (this.type === types$1.comma) {
2650 var node = this.startNodeAt(startPos, startLoc);
2651 node.expressions = [expr];
2652 while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
2653 return this.finishNode(node, "SequenceExpression")
2654 }
2655 return expr
2656};
2657
2658// Parse an assignment expression. This includes applications of
2659// operators like `+=`.
2660
2661pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
2662 if (this.isContextual("yield")) {
2663 if (this.inGenerator) { return this.parseYield(forInit) }
2664 // The tokenizer will assume an expression is allowed after
2665 // `yield`, but this isn't that kind of yield
2666 else { this.exprAllowed = false; }
2667 }
2668
2669 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;
2670 if (refDestructuringErrors) {
2671 oldParenAssign = refDestructuringErrors.parenthesizedAssign;
2672 oldTrailingComma = refDestructuringErrors.trailingComma;
2673 oldDoubleProto = refDestructuringErrors.doubleProto;
2674 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
2675 } else {
2676 refDestructuringErrors = new DestructuringErrors;
2677 ownDestructuringErrors = true;
2678 }
2679
2680 var startPos = this.start, startLoc = this.startLoc;
2681 if (this.type === types$1.parenL || this.type === types$1.name) {
2682 this.potentialArrowAt = this.start;
2683 this.potentialArrowInForAwait = forInit === "await";
2684 }
2685 var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
2686 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
2687 if (this.type.isAssign) {
2688 var node = this.startNodeAt(startPos, startLoc);
2689 node.operator = this.value;
2690 if (this.type === types$1.eq)
2691 { left = this.toAssignable(left, false, refDestructuringErrors); }
2692 if (!ownDestructuringErrors) {
2693 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
2694 }
2695 if (refDestructuringErrors.shorthandAssign >= left.start)
2696 { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
2697 if (this.type === types$1.eq)
2698 { this.checkLValPattern(left); }
2699 else
2700 { this.checkLValSimple(left); }
2701 node.left = left;
2702 this.next();
2703 node.right = this.parseMaybeAssign(forInit);
2704 if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }
2705 return this.finishNode(node, "AssignmentExpression")
2706 } else {
2707 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
2708 }
2709 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
2710 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
2711 return left
2712};
2713
2714// Parse a ternary conditional (`?:`) operator.
2715
2716pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {
2717 var startPos = this.start, startLoc = this.startLoc;
2718 var expr = this.parseExprOps(forInit, refDestructuringErrors);
2719 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2720 if (this.eat(types$1.question)) {
2721 var node = this.startNodeAt(startPos, startLoc);
2722 node.test = expr;
2723 node.consequent = this.parseMaybeAssign();
2724 this.expect(types$1.colon);
2725 node.alternate = this.parseMaybeAssign(forInit);
2726 return this.finishNode(node, "ConditionalExpression")
2727 }
2728 return expr
2729};
2730
2731// Start the precedence parser.
2732
2733pp$5.parseExprOps = function(forInit, refDestructuringErrors) {
2734 var startPos = this.start, startLoc = this.startLoc;
2735 var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);
2736 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2737 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
2738};
2739
2740// Parse binary operators with the operator precedence parsing
2741// algorithm. `left` is the left-hand side of the operator.
2742// `minPrec` provides context that allows the function to stop and
2743// defer further parser to one of its callers when it encounters an
2744// operator that has a lower precedence than the set it is parsing.
2745
2746pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
2747 var prec = this.type.binop;
2748 if (prec != null && (!forInit || this.type !== types$1._in)) {
2749 if (prec > minPrec) {
2750 var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;
2751 var coalesce = this.type === types$1.coalesce;
2752 if (coalesce) {
2753 // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
2754 // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
2755 prec = types$1.logicalAND.binop;
2756 }
2757 var op = this.value;
2758 this.next();
2759 var startPos = this.start, startLoc = this.startLoc;
2760 var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);
2761 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
2762 if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {
2763 this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
2764 }
2765 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
2766 }
2767 }
2768 return left
2769};
2770
2771pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {
2772 if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); }
2773 var node = this.startNodeAt(startPos, startLoc);
2774 node.left = left;
2775 node.operator = op;
2776 node.right = right;
2777 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
2778};
2779
2780// Parse unary operators, both prefix and postfix.
2781
2782pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {
2783 var startPos = this.start, startLoc = this.startLoc, expr;
2784 if (this.isContextual("await") && this.canAwait) {
2785 expr = this.parseAwait(forInit);
2786 sawUnary = true;
2787 } else if (this.type.prefix) {
2788 var node = this.startNode(), update = this.type === types$1.incDec;
2789 node.operator = this.value;
2790 node.prefix = true;
2791 this.next();
2792 node.argument = this.parseMaybeUnary(null, true, update, forInit);
2793 this.checkExpressionErrors(refDestructuringErrors, true);
2794 if (update) { this.checkLValSimple(node.argument); }
2795 else if (this.strict && node.operator === "delete" && isLocalVariableAccess(node.argument))
2796 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
2797 else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
2798 { this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
2799 else { sawUnary = true; }
2800 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
2801 } else if (!sawUnary && this.type === types$1.privateId) {
2802 if ((forInit || this.privateNameStack.length === 0) && this.options.checkPrivateFields) { this.unexpected(); }
2803 expr = this.parsePrivateIdent();
2804 // only could be private fields in 'in', such as #x in obj
2805 if (this.type !== types$1._in) { this.unexpected(); }
2806 } else {
2807 expr = this.parseExprSubscripts(refDestructuringErrors, forInit);
2808 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2809 while (this.type.postfix && !this.canInsertSemicolon()) {
2810 var node$1 = this.startNodeAt(startPos, startLoc);
2811 node$1.operator = this.value;
2812 node$1.prefix = false;
2813 node$1.argument = expr;
2814 this.checkLValSimple(expr);
2815 this.next();
2816 expr = this.finishNode(node$1, "UpdateExpression");
2817 }
2818 }
2819
2820 if (!incDec && this.eat(types$1.starstar)) {
2821 if (sawUnary)
2822 { this.unexpected(this.lastTokStart); }
2823 else
2824 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) }
2825 } else {
2826 return expr
2827 }
2828};
2829
2830function isLocalVariableAccess(node) {
2831 return (
2832 node.type === "Identifier" ||
2833 node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression)
2834 )
2835}
2836
2837function isPrivateFieldAccess(node) {
2838 return (
2839 node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
2840 node.type === "ChainExpression" && isPrivateFieldAccess(node.expression) ||
2841 node.type === "ParenthesizedExpression" && isPrivateFieldAccess(node.expression)
2842 )
2843}
2844
2845// Parse call, dot, and `[]`-subscript expressions.
2846
2847pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {
2848 var startPos = this.start, startLoc = this.startLoc;
2849 var expr = this.parseExprAtom(refDestructuringErrors, forInit);
2850 if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
2851 { return expr }
2852 var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);
2853 if (refDestructuringErrors && result.type === "MemberExpression") {
2854 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
2855 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
2856 if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
2857 }
2858 return result
2859};
2860
2861pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {
2862 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
2863 this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
2864 this.potentialArrowAt === base.start;
2865 var optionalChained = false;
2866
2867 while (true) {
2868 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
2869
2870 if (element.optional) { optionalChained = true; }
2871 if (element === base || element.type === "ArrowFunctionExpression") {
2872 if (optionalChained) {
2873 var chainNode = this.startNodeAt(startPos, startLoc);
2874 chainNode.expression = element;
2875 element = this.finishNode(chainNode, "ChainExpression");
2876 }
2877 return element
2878 }
2879
2880 base = element;
2881 }
2882};
2883
2884pp$5.shouldParseAsyncArrow = function() {
2885 return !this.canInsertSemicolon() && this.eat(types$1.arrow)
2886};
2887
2888pp$5.parseSubscriptAsyncArrow = function(startPos, startLoc, exprList, forInit) {
2889 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)
2890};
2891
2892pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
2893 var optionalSupported = this.options.ecmaVersion >= 11;
2894 var optional = optionalSupported && this.eat(types$1.questionDot);
2895 if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
2896
2897 var computed = this.eat(types$1.bracketL);
2898 if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {
2899 var node = this.startNodeAt(startPos, startLoc);
2900 node.object = base;
2901 if (computed) {
2902 node.property = this.parseExpression();
2903 this.expect(types$1.bracketR);
2904 } else if (this.type === types$1.privateId && base.type !== "Super") {
2905 node.property = this.parsePrivateIdent();
2906 } else {
2907 node.property = this.parseIdent(this.options.allowReserved !== "never");
2908 }
2909 node.computed = !!computed;
2910 if (optionalSupported) {
2911 node.optional = optional;
2912 }
2913 base = this.finishNode(node, "MemberExpression");
2914 } else if (!noCalls && this.eat(types$1.parenL)) {
2915 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2916 this.yieldPos = 0;
2917 this.awaitPos = 0;
2918 this.awaitIdentPos = 0;
2919 var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
2920 if (maybeAsyncArrow && !optional && this.shouldParseAsyncArrow()) {
2921 this.checkPatternErrors(refDestructuringErrors, false);
2922 this.checkYieldAwaitInDefaultParams();
2923 if (this.awaitIdentPos > 0)
2924 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
2925 this.yieldPos = oldYieldPos;
2926 this.awaitPos = oldAwaitPos;
2927 this.awaitIdentPos = oldAwaitIdentPos;
2928 return this.parseSubscriptAsyncArrow(startPos, startLoc, exprList, forInit)
2929 }
2930 this.checkExpressionErrors(refDestructuringErrors, true);
2931 this.yieldPos = oldYieldPos || this.yieldPos;
2932 this.awaitPos = oldAwaitPos || this.awaitPos;
2933 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
2934 var node$1 = this.startNodeAt(startPos, startLoc);
2935 node$1.callee = base;
2936 node$1.arguments = exprList;
2937 if (optionalSupported) {
2938 node$1.optional = optional;
2939 }
2940 base = this.finishNode(node$1, "CallExpression");
2941 } else if (this.type === types$1.backQuote) {
2942 if (optional || optionalChained) {
2943 this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
2944 }
2945 var node$2 = this.startNodeAt(startPos, startLoc);
2946 node$2.tag = base;
2947 node$2.quasi = this.parseTemplate({isTagged: true});
2948 base = this.finishNode(node$2, "TaggedTemplateExpression");
2949 }
2950 return base
2951};
2952
2953// Parse an atomic expression — either a single token that is an
2954// expression, an expression started by a keyword like `function` or
2955// `new`, or an expression wrapped in punctuation like `()`, `[]`,
2956// or `{}`.
2957
2958pp$5.parseExprAtom = function(refDestructuringErrors, forInit, forNew) {
2959 // If a division operator appears in an expression position, the
2960 // tokenizer got confused, and we force it to read a regexp instead.
2961 if (this.type === types$1.slash) { this.readRegexp(); }
2962
2963 var node, canBeArrow = this.potentialArrowAt === this.start;
2964 switch (this.type) {
2965 case types$1._super:
2966 if (!this.allowSuper)
2967 { this.raise(this.start, "'super' keyword outside a method"); }
2968 node = this.startNode();
2969 this.next();
2970 if (this.type === types$1.parenL && !this.allowDirectSuper)
2971 { this.raise(node.start, "super() call outside constructor of a subclass"); }
2972 // The `super` keyword can appear at below:
2973 // SuperProperty:
2974 // super [ Expression ]
2975 // super . IdentifierName
2976 // SuperCall:
2977 // super ( Arguments )
2978 if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)
2979 { this.unexpected(); }
2980 return this.finishNode(node, "Super")
2981
2982 case types$1._this:
2983 node = this.startNode();
2984 this.next();
2985 return this.finishNode(node, "ThisExpression")
2986
2987 case types$1.name:
2988 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
2989 var id = this.parseIdent(false);
2990 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) {
2991 this.overrideContext(types.f_expr);
2992 return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)
2993 }
2994 if (canBeArrow && !this.canInsertSemicolon()) {
2995 if (this.eat(types$1.arrow))
2996 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }
2997 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc &&
2998 (!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
2999 id = this.parseIdent(false);
3000 if (this.canInsertSemicolon() || !this.eat(types$1.arrow))
3001 { this.unexpected(); }
3002 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)
3003 }
3004 }
3005 return id
3006
3007 case types$1.regexp:
3008 var value = this.value;
3009 node = this.parseLiteral(value.value);
3010 node.regex = {pattern: value.pattern, flags: value.flags};
3011 return node
3012
3013 case types$1.num: case types$1.string:
3014 return this.parseLiteral(this.value)
3015
3016 case types$1._null: case types$1._true: case types$1._false:
3017 node = this.startNode();
3018 node.value = this.type === types$1._null ? null : this.type === types$1._true;
3019 node.raw = this.type.keyword;
3020 this.next();
3021 return this.finishNode(node, "Literal")
3022
3023 case types$1.parenL:
3024 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);
3025 if (refDestructuringErrors) {
3026 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
3027 { refDestructuringErrors.parenthesizedAssign = start; }
3028 if (refDestructuringErrors.parenthesizedBind < 0)
3029 { refDestructuringErrors.parenthesizedBind = start; }
3030 }
3031 return expr
3032
3033 case types$1.bracketL:
3034 node = this.startNode();
3035 this.next();
3036 node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);
3037 return this.finishNode(node, "ArrayExpression")
3038
3039 case types$1.braceL:
3040 this.overrideContext(types.b_expr);
3041 return this.parseObj(false, refDestructuringErrors)
3042
3043 case types$1._function:
3044 node = this.startNode();
3045 this.next();
3046 return this.parseFunction(node, 0)
3047
3048 case types$1._class:
3049 return this.parseClass(this.startNode(), false)
3050
3051 case types$1._new:
3052 return this.parseNew()
3053
3054 case types$1.backQuote:
3055 return this.parseTemplate()
3056
3057 case types$1._import:
3058 if (this.options.ecmaVersion >= 11) {
3059 return this.parseExprImport(forNew)
3060 } else {
3061 return this.unexpected()
3062 }
3063
3064 default:
3065 return this.parseExprAtomDefault()
3066 }
3067};
3068
3069pp$5.parseExprAtomDefault = function() {
3070 this.unexpected();
3071};
3072
3073pp$5.parseExprImport = function(forNew) {
3074 var node = this.startNode();
3075
3076 // Consume `import` as an identifier for `import.meta`.
3077 // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
3078 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
3079 this.next();
3080
3081 if (this.type === types$1.parenL && !forNew) {
3082 return this.parseDynamicImport(node)
3083 } else if (this.type === types$1.dot) {
3084 var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
3085 meta.name = "import";
3086 node.meta = this.finishNode(meta, "Identifier");
3087 return this.parseImportMeta(node)
3088 } else {
3089 this.unexpected();
3090 }
3091};
3092
3093pp$5.parseDynamicImport = function(node) {
3094 this.next(); // skip `(`
3095
3096 // Parse node.source.
3097 node.source = this.parseMaybeAssign();
3098
3099 if (this.options.ecmaVersion >= 16) {
3100 if (!this.eat(types$1.parenR)) {
3101 this.expect(types$1.comma);
3102 if (!this.afterTrailingComma(types$1.parenR)) {
3103 node.options = this.parseMaybeAssign();
3104 if (!this.eat(types$1.parenR)) {
3105 this.expect(types$1.comma);
3106 if (!this.afterTrailingComma(types$1.parenR)) {
3107 this.unexpected();
3108 }
3109 }
3110 } else {
3111 node.options = null;
3112 }
3113 } else {
3114 node.options = null;
3115 }
3116 } else {
3117 // Verify ending.
3118 if (!this.eat(types$1.parenR)) {
3119 var errorPos = this.start;
3120 if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {
3121 this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
3122 } else {
3123 this.unexpected(errorPos);
3124 }
3125 }
3126 }
3127
3128 return this.finishNode(node, "ImportExpression")
3129};
3130
3131pp$5.parseImportMeta = function(node) {
3132 this.next(); // skip `.`
3133
3134 var containsEsc = this.containsEsc;
3135 node.property = this.parseIdent(true);
3136
3137 if (node.property.name !== "meta")
3138 { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
3139 if (containsEsc)
3140 { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
3141 if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
3142 { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
3143
3144 return this.finishNode(node, "MetaProperty")
3145};
3146
3147pp$5.parseLiteral = function(value) {
3148 var node = this.startNode();
3149 node.value = value;
3150 node.raw = this.input.slice(this.start, this.end);
3151 if (node.raw.charCodeAt(node.raw.length - 1) === 110)
3152 { node.bigint = node.value != null ? node.value.toString() : node.raw.slice(0, -1).replace(/_/g, ""); }
3153 this.next();
3154 return this.finishNode(node, "Literal")
3155};
3156
3157pp$5.parseParenExpression = function() {
3158 this.expect(types$1.parenL);
3159 var val = this.parseExpression();
3160 this.expect(types$1.parenR);
3161 return val
3162};
3163
3164pp$5.shouldParseArrow = function(exprList) {
3165 return !this.canInsertSemicolon()
3166};
3167
3168pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {
3169 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
3170 if (this.options.ecmaVersion >= 6) {
3171 this.next();
3172
3173 var innerStartPos = this.start, innerStartLoc = this.startLoc;
3174 var exprList = [], first = true, lastIsComma = false;
3175 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
3176 this.yieldPos = 0;
3177 this.awaitPos = 0;
3178 // Do not save awaitIdentPos to allow checking awaits nested in parameters
3179 while (this.type !== types$1.parenR) {
3180 first ? first = false : this.expect(types$1.comma);
3181 if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {
3182 lastIsComma = true;
3183 break
3184 } else if (this.type === types$1.ellipsis) {
3185 spreadStart = this.start;
3186 exprList.push(this.parseParenItem(this.parseRestBinding()));
3187 if (this.type === types$1.comma) {
3188 this.raiseRecoverable(
3189 this.start,
3190 "Comma is not permitted after the rest element"
3191 );
3192 }
3193 break
3194 } else {
3195 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
3196 }
3197 }
3198 var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;
3199 this.expect(types$1.parenR);
3200
3201 if (canBeArrow && this.shouldParseArrow(exprList) && this.eat(types$1.arrow)) {
3202 this.checkPatternErrors(refDestructuringErrors, false);
3203 this.checkYieldAwaitInDefaultParams();
3204 this.yieldPos = oldYieldPos;
3205 this.awaitPos = oldAwaitPos;
3206 return this.parseParenArrowList(startPos, startLoc, exprList, forInit)
3207 }
3208
3209 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
3210 if (spreadStart) { this.unexpected(spreadStart); }
3211 this.checkExpressionErrors(refDestructuringErrors, true);
3212 this.yieldPos = oldYieldPos || this.yieldPos;
3213 this.awaitPos = oldAwaitPos || this.awaitPos;
3214
3215 if (exprList.length > 1) {
3216 val = this.startNodeAt(innerStartPos, innerStartLoc);
3217 val.expressions = exprList;
3218 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
3219 } else {
3220 val = exprList[0];
3221 }
3222 } else {
3223 val = this.parseParenExpression();
3224 }
3225
3226 if (this.options.preserveParens) {
3227 var par = this.startNodeAt(startPos, startLoc);
3228 par.expression = val;
3229 return this.finishNode(par, "ParenthesizedExpression")
3230 } else {
3231 return val
3232 }
3233};
3234
3235pp$5.parseParenItem = function(item) {
3236 return item
3237};
3238
3239pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {
3240 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)
3241};
3242
3243// New's precedence is slightly tricky. It must allow its argument to
3244// be a `[]` or dot subscript expression, but not a call — at least,
3245// not without wrapping it in parentheses. Thus, it uses the noCalls
3246// argument to parseSubscripts to prevent it from consuming the
3247// argument list.
3248
3249var empty = [];
3250
3251pp$5.parseNew = function() {
3252 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
3253 var node = this.startNode();
3254 this.next();
3255 if (this.options.ecmaVersion >= 6 && this.type === types$1.dot) {
3256 var meta = this.startNodeAt(node.start, node.loc && node.loc.start);
3257 meta.name = "new";
3258 node.meta = this.finishNode(meta, "Identifier");
3259 this.next();
3260 var containsEsc = this.containsEsc;
3261 node.property = this.parseIdent(true);
3262 if (node.property.name !== "target")
3263 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
3264 if (containsEsc)
3265 { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
3266 if (!this.allowNewDotTarget)
3267 { this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); }
3268 return this.finishNode(node, "MetaProperty")
3269 }
3270 var startPos = this.start, startLoc = this.startLoc;
3271 node.callee = this.parseSubscripts(this.parseExprAtom(null, false, true), startPos, startLoc, true, false);
3272 if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }
3273 else { node.arguments = empty; }
3274 return this.finishNode(node, "NewExpression")
3275};
3276
3277// Parse template expression.
3278
3279pp$5.parseTemplateElement = function(ref) {
3280 var isTagged = ref.isTagged;
3281
3282 var elem = this.startNode();
3283 if (this.type === types$1.invalidTemplate) {
3284 if (!isTagged) {
3285 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
3286 }
3287 elem.value = {
3288 raw: this.value.replace(/\r\n?/g, "\n"),
3289 cooked: null
3290 };
3291 } else {
3292 elem.value = {
3293 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
3294 cooked: this.value
3295 };
3296 }
3297 this.next();
3298 elem.tail = this.type === types$1.backQuote;
3299 return this.finishNode(elem, "TemplateElement")
3300};
3301
3302pp$5.parseTemplate = function(ref) {
3303 if ( ref === void 0 ) ref = {};
3304 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
3305
3306 var node = this.startNode();
3307 this.next();
3308 node.expressions = [];
3309 var curElt = this.parseTemplateElement({isTagged: isTagged});
3310 node.quasis = [curElt];
3311 while (!curElt.tail) {
3312 if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); }
3313 this.expect(types$1.dollarBraceL);
3314 node.expressions.push(this.parseExpression());
3315 this.expect(types$1.braceR);
3316 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
3317 }
3318 this.next();
3319 return this.finishNode(node, "TemplateLiteral")
3320};
3321
3322pp$5.isAsyncProp = function(prop) {
3323 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
3324 (this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&
3325 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
3326};
3327
3328// Parse an object literal or binding pattern.
3329
3330pp$5.parseObj = function(isPattern, refDestructuringErrors) {
3331 var node = this.startNode(), first = true, propHash = {};
3332 node.properties = [];
3333 this.next();
3334 while (!this.eat(types$1.braceR)) {
3335 if (!first) {
3336 this.expect(types$1.comma);
3337 if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }
3338 } else { first = false; }
3339
3340 var prop = this.parseProperty(isPattern, refDestructuringErrors);
3341 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
3342 node.properties.push(prop);
3343 }
3344 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
3345};
3346
3347pp$5.parseProperty = function(isPattern, refDestructuringErrors) {
3348 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
3349 if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {
3350 if (isPattern) {
3351 prop.argument = this.parseIdent(false);
3352 if (this.type === types$1.comma) {
3353 this.raiseRecoverable(this.start, "Comma is not permitted after the rest element");
3354 }
3355 return this.finishNode(prop, "RestElement")
3356 }
3357 // Parse argument.
3358 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
3359 // To disallow trailing comma via `this.toAssignable()`.
3360 if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
3361 refDestructuringErrors.trailingComma = this.start;
3362 }
3363 // Finish
3364 return this.finishNode(prop, "SpreadElement")
3365 }
3366 if (this.options.ecmaVersion >= 6) {
3367 prop.method = false;
3368 prop.shorthand = false;
3369 if (isPattern || refDestructuringErrors) {
3370 startPos = this.start;
3371 startLoc = this.startLoc;
3372 }
3373 if (!isPattern)
3374 { isGenerator = this.eat(types$1.star); }
3375 }
3376 var containsEsc = this.containsEsc;
3377 this.parsePropertyName(prop);
3378 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
3379 isAsync = true;
3380 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);
3381 this.parsePropertyName(prop);
3382 } else {
3383 isAsync = false;
3384 }
3385 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
3386 return this.finishNode(prop, "Property")
3387};
3388
3389pp$5.parseGetterSetter = function(prop) {
3390 var kind = prop.key.name;
3391 this.parsePropertyName(prop);
3392 prop.value = this.parseMethod(false);
3393 prop.kind = kind;
3394 var paramCount = prop.kind === "get" ? 0 : 1;
3395 if (prop.value.params.length !== paramCount) {
3396 var start = prop.value.start;
3397 if (prop.kind === "get")
3398 { this.raiseRecoverable(start, "getter should have no params"); }
3399 else
3400 { this.raiseRecoverable(start, "setter should have exactly one param"); }
3401 } else {
3402 if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
3403 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
3404 }
3405};
3406
3407pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
3408 if ((isGenerator || isAsync) && this.type === types$1.colon)
3409 { this.unexpected(); }
3410
3411 if (this.eat(types$1.colon)) {
3412 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
3413 prop.kind = "init";
3414 } else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {
3415 if (isPattern) { this.unexpected(); }
3416 prop.method = true;
3417 prop.value = this.parseMethod(isGenerator, isAsync);
3418 prop.kind = "init";
3419 } else if (!isPattern && !containsEsc &&
3420 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
3421 (prop.key.name === "get" || prop.key.name === "set") &&
3422 (this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {
3423 if (isGenerator || isAsync) { this.unexpected(); }
3424 this.parseGetterSetter(prop);
3425 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
3426 if (isGenerator || isAsync) { this.unexpected(); }
3427 this.checkUnreserved(prop.key);
3428 if (prop.key.name === "await" && !this.awaitIdentPos)
3429 { this.awaitIdentPos = startPos; }
3430 if (isPattern) {
3431 prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
3432 } else if (this.type === types$1.eq && refDestructuringErrors) {
3433 if (refDestructuringErrors.shorthandAssign < 0)
3434 { refDestructuringErrors.shorthandAssign = this.start; }
3435 prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
3436 } else {
3437 prop.value = this.copyNode(prop.key);
3438 }
3439 prop.kind = "init";
3440 prop.shorthand = true;
3441 } else { this.unexpected(); }
3442};
3443
3444pp$5.parsePropertyName = function(prop) {
3445 if (this.options.ecmaVersion >= 6) {
3446 if (this.eat(types$1.bracketL)) {
3447 prop.computed = true;
3448 prop.key = this.parseMaybeAssign();
3449 this.expect(types$1.bracketR);
3450 return prop.key
3451 } else {
3452 prop.computed = false;
3453 }
3454 }
3455 return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
3456};
3457
3458// Initialize empty function node.
3459
3460pp$5.initFunction = function(node) {
3461 node.id = null;
3462 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
3463 if (this.options.ecmaVersion >= 8) { node.async = false; }
3464};
3465
3466// Parse object or class method.
3467
3468pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
3469 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
3470
3471 this.initFunction(node);
3472 if (this.options.ecmaVersion >= 6)
3473 { node.generator = isGenerator; }
3474 if (this.options.ecmaVersion >= 8)
3475 { node.async = !!isAsync; }
3476
3477 this.yieldPos = 0;
3478 this.awaitPos = 0;
3479 this.awaitIdentPos = 0;
3480 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
3481
3482 this.expect(types$1.parenL);
3483 node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
3484 this.checkYieldAwaitInDefaultParams();
3485 this.parseFunctionBody(node, false, true, false);
3486
3487 this.yieldPos = oldYieldPos;
3488 this.awaitPos = oldAwaitPos;
3489 this.awaitIdentPos = oldAwaitIdentPos;
3490 return this.finishNode(node, "FunctionExpression")
3491};
3492
3493// Parse arrow function expression with given parameters.
3494
3495pp$5.parseArrowExpression = function(node, params, isAsync, forInit) {
3496 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
3497
3498 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
3499 this.initFunction(node);
3500 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
3501
3502 this.yieldPos = 0;
3503 this.awaitPos = 0;
3504 this.awaitIdentPos = 0;
3505
3506 node.params = this.toAssignableList(params, true);
3507 this.parseFunctionBody(node, true, false, forInit);
3508
3509 this.yieldPos = oldYieldPos;
3510 this.awaitPos = oldAwaitPos;
3511 this.awaitIdentPos = oldAwaitIdentPos;
3512 return this.finishNode(node, "ArrowFunctionExpression")
3513};
3514
3515// Parse function body and check parameters.
3516
3517pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {
3518 var isExpression = isArrowFunction && this.type !== types$1.braceL;
3519 var oldStrict = this.strict, useStrict = false;
3520
3521 if (isExpression) {
3522 node.body = this.parseMaybeAssign(forInit);
3523 node.expression = true;
3524 this.checkParams(node, false);
3525 } else {
3526 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
3527 if (!oldStrict || nonSimple) {
3528 useStrict = this.strictDirective(this.end);
3529 // If this is a strict mode function, verify that argument names
3530 // are not repeated, and it does not try to bind the words `eval`
3531 // or `arguments`.
3532 if (useStrict && nonSimple)
3533 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
3534 }
3535 // Start a new scope with regard to labels and the `inFunction`
3536 // flag (restore them to their old value afterwards).
3537 var oldLabels = this.labels;
3538 this.labels = [];
3539 if (useStrict) { this.strict = true; }
3540
3541 // Add the params to varDeclaredNames to ensure that an error is thrown
3542 // if a let/const declaration in the function clashes with one of the params.
3543 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
3544 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
3545 if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }
3546 node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
3547 node.expression = false;
3548 this.adaptDirectivePrologue(node.body.body);
3549 this.labels = oldLabels;
3550 }
3551 this.exitScope();
3552};
3553
3554pp$5.isSimpleParamList = function(params) {
3555 for (var i = 0, list = params; i < list.length; i += 1)
3556 {
3557 var param = list[i];
3558
3559 if (param.type !== "Identifier") { return false
3560 } }
3561 return true
3562};
3563
3564// Checks function params for various disallowed patterns such as using "eval"
3565// or "arguments" and duplicate parameters.
3566
3567pp$5.checkParams = function(node, allowDuplicates) {
3568 var nameHash = Object.create(null);
3569 for (var i = 0, list = node.params; i < list.length; i += 1)
3570 {
3571 var param = list[i];
3572
3573 this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);
3574 }
3575};
3576
3577// Parses a comma-separated list of expressions, and returns them as
3578// an array. `close` is the token type that ends the list, and
3579// `allowEmpty` can be turned on to allow subsequent commas with
3580// nothing in between them to be parsed as `null` (which is needed
3581// for array literals).
3582
3583pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
3584 var elts = [], first = true;
3585 while (!this.eat(close)) {
3586 if (!first) {
3587 this.expect(types$1.comma);
3588 if (allowTrailingComma && this.afterTrailingComma(close)) { break }
3589 } else { first = false; }
3590
3591 var elt = (void 0);
3592 if (allowEmpty && this.type === types$1.comma)
3593 { elt = null; }
3594 else if (this.type === types$1.ellipsis) {
3595 elt = this.parseSpread(refDestructuringErrors);
3596 if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)
3597 { refDestructuringErrors.trailingComma = this.start; }
3598 } else {
3599 elt = this.parseMaybeAssign(false, refDestructuringErrors);
3600 }
3601 elts.push(elt);
3602 }
3603 return elts
3604};
3605
3606pp$5.checkUnreserved = function(ref) {
3607 var start = ref.start;
3608 var end = ref.end;
3609 var name = ref.name;
3610
3611 if (this.inGenerator && name === "yield")
3612 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
3613 if (this.inAsync && name === "await")
3614 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
3615 if (!(this.currentThisScope().flags & SCOPE_VAR) && name === "arguments")
3616 { this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
3617 if (this.inClassStaticBlock && (name === "arguments" || name === "await"))
3618 { this.raise(start, ("Cannot use " + name + " in class static initialization block")); }
3619 if (this.keywords.test(name))
3620 { this.raise(start, ("Unexpected keyword '" + name + "'")); }
3621 if (this.options.ecmaVersion < 6 &&
3622 this.input.slice(start, end).indexOf("\\") !== -1) { return }
3623 var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
3624 if (re.test(name)) {
3625 if (!this.inAsync && name === "await")
3626 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
3627 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
3628 }
3629};
3630
3631// Parse the next token as an identifier. If `liberal` is true (used
3632// when parsing properties), it will also convert keywords into
3633// identifiers.
3634
3635pp$5.parseIdent = function(liberal) {
3636 var node = this.parseIdentNode();
3637 this.next(!!liberal);
3638 this.finishNode(node, "Identifier");
3639 if (!liberal) {
3640 this.checkUnreserved(node);
3641 if (node.name === "await" && !this.awaitIdentPos)
3642 { this.awaitIdentPos = node.start; }
3643 }
3644 return node
3645};
3646
3647pp$5.parseIdentNode = function() {
3648 var node = this.startNode();
3649 if (this.type === types$1.name) {
3650 node.name = this.value;
3651 } else if (this.type.keyword) {
3652 node.name = this.type.keyword;
3653
3654 // To fix https://github.com/acornjs/acorn/issues/575
3655 // `class` and `function` keywords push new context into this.context.
3656 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
3657 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
3658 if ((node.name === "class" || node.name === "function") &&
3659 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
3660 this.context.pop();
3661 }
3662 this.type = types$1.name;
3663 } else {
3664 this.unexpected();
3665 }
3666 return node
3667};
3668
3669pp$5.parsePrivateIdent = function() {
3670 var node = this.startNode();
3671 if (this.type === types$1.privateId) {
3672 node.name = this.value;
3673 } else {
3674 this.unexpected();
3675 }
3676 this.next();
3677 this.finishNode(node, "PrivateIdentifier");
3678
3679 // For validating existence
3680 if (this.options.checkPrivateFields) {
3681 if (this.privateNameStack.length === 0) {
3682 this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
3683 } else {
3684 this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
3685 }
3686 }
3687
3688 return node
3689};
3690
3691// Parses yield expression inside generator.
3692
3693pp$5.parseYield = function(forInit) {
3694 if (!this.yieldPos) { this.yieldPos = this.start; }
3695
3696 var node = this.startNode();
3697 this.next();
3698 if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {
3699 node.delegate = false;
3700 node.argument = null;
3701 } else {
3702 node.delegate = this.eat(types$1.star);
3703 node.argument = this.parseMaybeAssign(forInit);
3704 }
3705 return this.finishNode(node, "YieldExpression")
3706};
3707
3708pp$5.parseAwait = function(forInit) {
3709 if (!this.awaitPos) { this.awaitPos = this.start; }
3710
3711 var node = this.startNode();
3712 this.next();
3713 node.argument = this.parseMaybeUnary(null, true, false, forInit);
3714 return this.finishNode(node, "AwaitExpression")
3715};
3716
3717var pp$4 = Parser.prototype;
3718
3719// This function is used to raise exceptions on parse errors. It
3720// takes an offset integer (into the current `input`) to indicate
3721// the location of the error, attaches the position to the end
3722// of the error message, and then raises a `SyntaxError` with that
3723// message.
3724
3725pp$4.raise = function(pos, message) {
3726 var loc = getLineInfo(this.input, pos);
3727 message += " (" + loc.line + ":" + loc.column + ")";
3728 if (this.sourceFile) {
3729 message += " in " + this.sourceFile;
3730 }
3731 var err = new SyntaxError(message);
3732 err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
3733 throw err
3734};
3735
3736pp$4.raiseRecoverable = pp$4.raise;
3737
3738pp$4.curPosition = function() {
3739 if (this.options.locations) {
3740 return new Position(this.curLine, this.pos - this.lineStart)
3741 }
3742};
3743
3744var pp$3 = Parser.prototype;
3745
3746var Scope = function Scope(flags) {
3747 this.flags = flags;
3748 // A list of var-declared names in the current lexical scope
3749 this.var = [];
3750 // A list of lexically-declared names in the current lexical scope
3751 this.lexical = [];
3752 // A list of lexically-declared FunctionDeclaration names in the current lexical scope
3753 this.functions = [];
3754};
3755
3756// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
3757
3758pp$3.enterScope = function(flags) {
3759 this.scopeStack.push(new Scope(flags));
3760};
3761
3762pp$3.exitScope = function() {
3763 this.scopeStack.pop();
3764};
3765
3766// The spec says:
3767// > At the top level of a function, or script, function declarations are
3768// > treated like var declarations rather than like lexical declarations.
3769pp$3.treatFunctionsAsVarInScope = function(scope) {
3770 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
3771};
3772
3773pp$3.declareName = function(name, bindingType, pos) {
3774 var redeclared = false;
3775 if (bindingType === BIND_LEXICAL) {
3776 var scope = this.currentScope();
3777 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
3778 scope.lexical.push(name);
3779 if (this.inModule && (scope.flags & SCOPE_TOP))
3780 { delete this.undefinedExports[name]; }
3781 } else if (bindingType === BIND_SIMPLE_CATCH) {
3782 var scope$1 = this.currentScope();
3783 scope$1.lexical.push(name);
3784 } else if (bindingType === BIND_FUNCTION) {
3785 var scope$2 = this.currentScope();
3786 if (this.treatFunctionsAsVar)
3787 { redeclared = scope$2.lexical.indexOf(name) > -1; }
3788 else
3789 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
3790 scope$2.functions.push(name);
3791 } else {
3792 for (var i = this.scopeStack.length - 1; i >= 0; --i) {
3793 var scope$3 = this.scopeStack[i];
3794 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
3795 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
3796 redeclared = true;
3797 break
3798 }
3799 scope$3.var.push(name);
3800 if (this.inModule && (scope$3.flags & SCOPE_TOP))
3801 { delete this.undefinedExports[name]; }
3802 if (scope$3.flags & SCOPE_VAR) { break }
3803 }
3804 }
3805 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
3806};
3807
3808pp$3.checkLocalExport = function(id) {
3809 // scope.functions must be empty as Module code is always strict.
3810 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
3811 this.scopeStack[0].var.indexOf(id.name) === -1) {
3812 this.undefinedExports[id.name] = id;
3813 }
3814};
3815
3816pp$3.currentScope = function() {
3817 return this.scopeStack[this.scopeStack.length - 1]
3818};
3819
3820pp$3.currentVarScope = function() {
3821 for (var i = this.scopeStack.length - 1;; i--) {
3822 var scope = this.scopeStack[i];
3823 if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK)) { return scope }
3824 }
3825};
3826
3827// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
3828pp$3.currentThisScope = function() {
3829 for (var i = this.scopeStack.length - 1;; i--) {
3830 var scope = this.scopeStack[i];
3831 if (scope.flags & (SCOPE_VAR | SCOPE_CLASS_FIELD_INIT | SCOPE_CLASS_STATIC_BLOCK) &&
3832 !(scope.flags & SCOPE_ARROW)) { return scope }
3833 }
3834};
3835
3836var Node = function Node(parser, pos, loc) {
3837 this.type = "";
3838 this.start = pos;
3839 this.end = 0;
3840 if (parser.options.locations)
3841 { this.loc = new SourceLocation(parser, loc); }
3842 if (parser.options.directSourceFile)
3843 { this.sourceFile = parser.options.directSourceFile; }
3844 if (parser.options.ranges)
3845 { this.range = [pos, 0]; }
3846};
3847
3848// Start an AST node, attaching a start offset.
3849
3850var pp$2 = Parser.prototype;
3851
3852pp$2.startNode = function() {
3853 return new Node(this, this.start, this.startLoc)
3854};
3855
3856pp$2.startNodeAt = function(pos, loc) {
3857 return new Node(this, pos, loc)
3858};
3859
3860// Finish an AST node, adding `type` and `end` properties.
3861
3862function finishNodeAt(node, type, pos, loc) {
3863 node.type = type;
3864 node.end = pos;
3865 if (this.options.locations)
3866 { node.loc.end = loc; }
3867 if (this.options.ranges)
3868 { node.range[1] = pos; }
3869 return node
3870}
3871
3872pp$2.finishNode = function(node, type) {
3873 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
3874};
3875
3876// Finish node at given position
3877
3878pp$2.finishNodeAt = function(node, type, pos, loc) {
3879 return finishNodeAt.call(this, node, type, pos, loc)
3880};
3881
3882pp$2.copyNode = function(node) {
3883 var newNode = new Node(this, node.start, this.startLoc);
3884 for (var prop in node) { newNode[prop] = node[prop]; }
3885 return newNode
3886};
3887
3888// This file was generated by "bin/generate-unicode-script-values.js". Do not modify manually!
3889var scriptValuesAddedInUnicode = "Gara Garay Gukh Gurung_Khema Hrkt Katakana_Or_Hiragana Kawi Kirat_Rai Krai Nag_Mundari Nagm Ol_Onal Onao Sunu Sunuwar Todhri Todr Tulu_Tigalari Tutg Unknown Zzzz";
3890
3891// This file contains Unicode properties extracted from the ECMAScript specification.
3892// The lists are extracted like so:
3893// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
3894
3895// #table-binary-unicode-properties
3896var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";
3897var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
3898var ecma11BinaryProperties = ecma10BinaryProperties;
3899var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict";
3900var ecma13BinaryProperties = ecma12BinaryProperties;
3901var ecma14BinaryProperties = ecma13BinaryProperties;
3902
3903var unicodeBinaryProperties = {
3904 9: ecma9BinaryProperties,
3905 10: ecma10BinaryProperties,
3906 11: ecma11BinaryProperties,
3907 12: ecma12BinaryProperties,
3908 13: ecma13BinaryProperties,
3909 14: ecma14BinaryProperties
3910};
3911
3912// #table-binary-unicode-properties-of-strings
3913var ecma14BinaryPropertiesOfStrings = "Basic_Emoji Emoji_Keycap_Sequence RGI_Emoji_Modifier_Sequence RGI_Emoji_Flag_Sequence RGI_Emoji_Tag_Sequence RGI_Emoji_ZWJ_Sequence RGI_Emoji";
3914
3915var unicodeBinaryPropertiesOfStrings = {
3916 9: "",
3917 10: "",
3918 11: "",
3919 12: "",
3920 13: "",
3921 14: ecma14BinaryPropertiesOfStrings
3922};
3923
3924// #table-unicode-general-category-values
3925var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";
3926
3927// #table-unicode-script-values
3928var ecma9ScriptValues = "Adlam Adlm Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";
3929var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
3930var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
3931var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi";
3932var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith";
3933var ecma14ScriptValues = ecma13ScriptValues + " " + scriptValuesAddedInUnicode;
3934
3935var unicodeScriptValues = {
3936 9: ecma9ScriptValues,
3937 10: ecma10ScriptValues,
3938 11: ecma11ScriptValues,
3939 12: ecma12ScriptValues,
3940 13: ecma13ScriptValues,
3941 14: ecma14ScriptValues
3942};
3943
3944var data = {};
3945function buildUnicodeData(ecmaVersion) {
3946 var d = data[ecmaVersion] = {
3947 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
3948 binaryOfStrings: wordsRegexp(unicodeBinaryPropertiesOfStrings[ecmaVersion]),
3949 nonBinary: {
3950 General_Category: wordsRegexp(unicodeGeneralCategoryValues),
3951 Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
3952 }
3953 };
3954 d.nonBinary.Script_Extensions = d.nonBinary.Script;
3955
3956 d.nonBinary.gc = d.nonBinary.General_Category;
3957 d.nonBinary.sc = d.nonBinary.Script;
3958 d.nonBinary.scx = d.nonBinary.Script_Extensions;
3959}
3960
3961for (var i = 0, list = [9, 10, 11, 12, 13, 14]; i < list.length; i += 1) {
3962 var ecmaVersion = list[i];
3963
3964 buildUnicodeData(ecmaVersion);
3965}
3966
3967var pp$1 = Parser.prototype;
3968
3969// Track disjunction structure to determine whether a duplicate
3970// capture group name is allowed because it is in a separate branch.
3971var BranchID = function BranchID(parent, base) {
3972 // Parent disjunction branch
3973 this.parent = parent;
3974 // Identifies this set of sibling branches
3975 this.base = base || this;
3976};
3977
3978BranchID.prototype.separatedFrom = function separatedFrom (alt) {
3979 // A branch is separate from another branch if they or any of
3980 // their parents are siblings in a given disjunction
3981 for (var self = this; self; self = self.parent) {
3982 for (var other = alt; other; other = other.parent) {
3983 if (self.base === other.base && self !== other) { return true }
3984 }
3985 }
3986 return false
3987};
3988
3989BranchID.prototype.sibling = function sibling () {
3990 return new BranchID(this.parent, this.base)
3991};
3992
3993var RegExpValidationState = function RegExpValidationState(parser) {
3994 this.parser = parser;
3995 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : "");
3996 this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];
3997 this.source = "";
3998 this.flags = "";
3999 this.start = 0;
4000 this.switchU = false;
4001 this.switchV = false;
4002 this.switchN = false;
4003 this.pos = 0;
4004 this.lastIntValue = 0;
4005 this.lastStringValue = "";
4006 this.lastAssertionIsQuantifiable = false;
4007 this.numCapturingParens = 0;
4008 this.maxBackReference = 0;
4009 this.groupNames = Object.create(null);
4010 this.backReferenceNames = [];
4011 this.branchID = null;
4012};
4013
4014RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
4015 var unicodeSets = flags.indexOf("v") !== -1;
4016 var unicode = flags.indexOf("u") !== -1;
4017 this.start = start | 0;
4018 this.source = pattern + "";
4019 this.flags = flags;
4020 if (unicodeSets && this.parser.options.ecmaVersion >= 15) {
4021 this.switchU = true;
4022 this.switchV = true;
4023 this.switchN = true;
4024 } else {
4025 this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
4026 this.switchV = false;
4027 this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
4028 }
4029};
4030
4031RegExpValidationState.prototype.raise = function raise (message) {
4032 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
4033};
4034
4035// If u flag is given, this returns the code point at the index (it combines a surrogate pair).
4036// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
4037RegExpValidationState.prototype.at = function at (i, forceU) {
4038 if ( forceU === void 0 ) forceU = false;
4039
4040 var s = this.source;
4041 var l = s.length;
4042 if (i >= l) {
4043 return -1
4044 }
4045 var c = s.charCodeAt(i);
4046 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
4047 return c
4048 }
4049 var next = s.charCodeAt(i + 1);
4050 return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
4051};
4052
4053RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
4054 if ( forceU === void 0 ) forceU = false;
4055
4056 var s = this.source;
4057 var l = s.length;
4058 if (i >= l) {
4059 return l
4060 }
4061 var c = s.charCodeAt(i), next;
4062 if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
4063 (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
4064 return i + 1
4065 }
4066 return i + 2
4067};
4068
4069RegExpValidationState.prototype.current = function current (forceU) {
4070 if ( forceU === void 0 ) forceU = false;
4071
4072 return this.at(this.pos, forceU)
4073};
4074
4075RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
4076 if ( forceU === void 0 ) forceU = false;
4077
4078 return this.at(this.nextIndex(this.pos, forceU), forceU)
4079};
4080
4081RegExpValidationState.prototype.advance = function advance (forceU) {
4082 if ( forceU === void 0 ) forceU = false;
4083
4084 this.pos = this.nextIndex(this.pos, forceU);
4085};
4086
4087RegExpValidationState.prototype.eat = function eat (ch, forceU) {
4088 if ( forceU === void 0 ) forceU = false;
4089
4090 if (this.current(forceU) === ch) {
4091 this.advance(forceU);
4092 return true
4093 }
4094 return false
4095};
4096
4097RegExpValidationState.prototype.eatChars = function eatChars (chs, forceU) {
4098 if ( forceU === void 0 ) forceU = false;
4099
4100 var pos = this.pos;
4101 for (var i = 0, list = chs; i < list.length; i += 1) {
4102 var ch = list[i];
4103
4104 var current = this.at(pos, forceU);
4105 if (current === -1 || current !== ch) {
4106 return false
4107 }
4108 pos = this.nextIndex(pos, forceU);
4109 }
4110 this.pos = pos;
4111 return true
4112};
4113
4114/**
4115 * Validate the flags part of a given RegExpLiteral.
4116 *
4117 * @param {RegExpValidationState} state The state to validate RegExp.
4118 * @returns {void}
4119 */
4120pp$1.validateRegExpFlags = function(state) {
4121 var validFlags = state.validFlags;
4122 var flags = state.flags;
4123
4124 var u = false;
4125 var v = false;
4126
4127 for (var i = 0; i < flags.length; i++) {
4128 var flag = flags.charAt(i);
4129 if (validFlags.indexOf(flag) === -1) {
4130 this.raise(state.start, "Invalid regular expression flag");
4131 }
4132 if (flags.indexOf(flag, i + 1) > -1) {
4133 this.raise(state.start, "Duplicate regular expression flag");
4134 }
4135 if (flag === "u") { u = true; }
4136 if (flag === "v") { v = true; }
4137 }
4138 if (this.options.ecmaVersion >= 15 && u && v) {
4139 this.raise(state.start, "Invalid regular expression flag");
4140 }
4141};
4142
4143function hasProp(obj) {
4144 for (var _ in obj) { return true }
4145 return false
4146}
4147
4148/**
4149 * Validate the pattern part of a given RegExpLiteral.
4150 *
4151 * @param {RegExpValidationState} state The state to validate RegExp.
4152 * @returns {void}
4153 */
4154pp$1.validateRegExpPattern = function(state) {
4155 this.regexp_pattern(state);
4156
4157 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
4158 // parsing contains a |GroupName|, reparse with the goal symbol
4159 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
4160 // exception if _P_ did not conform to the grammar, if any elements of _P_
4161 // were not matched by the parse, or if any Early Error conditions exist.
4162 if (!state.switchN && this.options.ecmaVersion >= 9 && hasProp(state.groupNames)) {
4163 state.switchN = true;
4164 this.regexp_pattern(state);
4165 }
4166};
4167
4168// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
4169pp$1.regexp_pattern = function(state) {
4170 state.pos = 0;
4171 state.lastIntValue = 0;
4172 state.lastStringValue = "";
4173 state.lastAssertionIsQuantifiable = false;
4174 state.numCapturingParens = 0;
4175 state.maxBackReference = 0;
4176 state.groupNames = Object.create(null);
4177 state.backReferenceNames.length = 0;
4178 state.branchID = null;
4179
4180 this.regexp_disjunction(state);
4181
4182 if (state.pos !== state.source.length) {
4183 // Make the same messages as V8.
4184 if (state.eat(0x29 /* ) */)) {
4185 state.raise("Unmatched ')'");
4186 }
4187 if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
4188 state.raise("Lone quantifier brackets");
4189 }
4190 }
4191 if (state.maxBackReference > state.numCapturingParens) {
4192 state.raise("Invalid escape");
4193 }
4194 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
4195 var name = list[i];
4196
4197 if (!state.groupNames[name]) {
4198 state.raise("Invalid named capture referenced");
4199 }
4200 }
4201};
4202
4203// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
4204pp$1.regexp_disjunction = function(state) {
4205 var trackDisjunction = this.options.ecmaVersion >= 16;
4206 if (trackDisjunction) { state.branchID = new BranchID(state.branchID, null); }
4207 this.regexp_alternative(state);
4208 while (state.eat(0x7C /* | */)) {
4209 if (trackDisjunction) { state.branchID = state.branchID.sibling(); }
4210 this.regexp_alternative(state);
4211 }
4212 if (trackDisjunction) { state.branchID = state.branchID.parent; }
4213
4214 // Make the same message as V8.
4215 if (this.regexp_eatQuantifier(state, true)) {
4216 state.raise("Nothing to repeat");
4217 }
4218 if (state.eat(0x7B /* { */)) {
4219 state.raise("Lone quantifier brackets");
4220 }
4221};
4222
4223// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
4224pp$1.regexp_alternative = function(state) {
4225 while (state.pos < state.source.length && this.regexp_eatTerm(state)) {}
4226};
4227
4228// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
4229pp$1.regexp_eatTerm = function(state) {
4230 if (this.regexp_eatAssertion(state)) {
4231 // Handle `QuantifiableAssertion Quantifier` alternative.
4232 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
4233 // is a QuantifiableAssertion.
4234 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
4235 // Make the same message as V8.
4236 if (state.switchU) {
4237 state.raise("Invalid quantifier");
4238 }
4239 }
4240 return true
4241 }
4242
4243 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
4244 this.regexp_eatQuantifier(state);
4245 return true
4246 }
4247
4248 return false
4249};
4250
4251// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
4252pp$1.regexp_eatAssertion = function(state) {
4253 var start = state.pos;
4254 state.lastAssertionIsQuantifiable = false;
4255
4256 // ^, $
4257 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
4258 return true
4259 }
4260
4261 // \b \B
4262 if (state.eat(0x5C /* \ */)) {
4263 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
4264 return true
4265 }
4266 state.pos = start;
4267 }
4268
4269 // Lookahead / Lookbehind
4270 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
4271 var lookbehind = false;
4272 if (this.options.ecmaVersion >= 9) {
4273 lookbehind = state.eat(0x3C /* < */);
4274 }
4275 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
4276 this.regexp_disjunction(state);
4277 if (!state.eat(0x29 /* ) */)) {
4278 state.raise("Unterminated group");
4279 }
4280 state.lastAssertionIsQuantifiable = !lookbehind;
4281 return true
4282 }
4283 }
4284
4285 state.pos = start;
4286 return false
4287};
4288
4289// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
4290pp$1.regexp_eatQuantifier = function(state, noError) {
4291 if ( noError === void 0 ) noError = false;
4292
4293 if (this.regexp_eatQuantifierPrefix(state, noError)) {
4294 state.eat(0x3F /* ? */);
4295 return true
4296 }
4297 return false
4298};
4299
4300// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
4301pp$1.regexp_eatQuantifierPrefix = function(state, noError) {
4302 return (
4303 state.eat(0x2A /* * */) ||
4304 state.eat(0x2B /* + */) ||
4305 state.eat(0x3F /* ? */) ||
4306 this.regexp_eatBracedQuantifier(state, noError)
4307 )
4308};
4309pp$1.regexp_eatBracedQuantifier = function(state, noError) {
4310 var start = state.pos;
4311 if (state.eat(0x7B /* { */)) {
4312 var min = 0, max = -1;
4313 if (this.regexp_eatDecimalDigits(state)) {
4314 min = state.lastIntValue;
4315 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
4316 max = state.lastIntValue;
4317 }
4318 if (state.eat(0x7D /* } */)) {
4319 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
4320 if (max !== -1 && max < min && !noError) {
4321 state.raise("numbers out of order in {} quantifier");
4322 }
4323 return true
4324 }
4325 }
4326 if (state.switchU && !noError) {
4327 state.raise("Incomplete quantifier");
4328 }
4329 state.pos = start;
4330 }
4331 return false
4332};
4333
4334// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
4335pp$1.regexp_eatAtom = function(state) {
4336 return (
4337 this.regexp_eatPatternCharacters(state) ||
4338 state.eat(0x2E /* . */) ||
4339 this.regexp_eatReverseSolidusAtomEscape(state) ||
4340 this.regexp_eatCharacterClass(state) ||
4341 this.regexp_eatUncapturingGroup(state) ||
4342 this.regexp_eatCapturingGroup(state)
4343 )
4344};
4345pp$1.regexp_eatReverseSolidusAtomEscape = function(state) {
4346 var start = state.pos;
4347 if (state.eat(0x5C /* \ */)) {
4348 if (this.regexp_eatAtomEscape(state)) {
4349 return true
4350 }
4351 state.pos = start;
4352 }
4353 return false
4354};
4355pp$1.regexp_eatUncapturingGroup = function(state) {
4356 var start = state.pos;
4357 if (state.eat(0x28 /* ( */)) {
4358 if (state.eat(0x3F /* ? */)) {
4359 if (this.options.ecmaVersion >= 16) {
4360 var addModifiers = this.regexp_eatModifiers(state);
4361 var hasHyphen = state.eat(0x2D /* - */);
4362 if (addModifiers || hasHyphen) {
4363 for (var i = 0; i < addModifiers.length; i++) {
4364 var modifier = addModifiers.charAt(i);
4365 if (addModifiers.indexOf(modifier, i + 1) > -1) {
4366 state.raise("Duplicate regular expression modifiers");
4367 }
4368 }
4369 if (hasHyphen) {
4370 var removeModifiers = this.regexp_eatModifiers(state);
4371 if (!addModifiers && !removeModifiers && state.current() === 0x3A /* : */) {
4372 state.raise("Invalid regular expression modifiers");
4373 }
4374 for (var i$1 = 0; i$1 < removeModifiers.length; i$1++) {
4375 var modifier$1 = removeModifiers.charAt(i$1);
4376 if (
4377 removeModifiers.indexOf(modifier$1, i$1 + 1) > -1 ||
4378 addModifiers.indexOf(modifier$1) > -1
4379 ) {
4380 state.raise("Duplicate regular expression modifiers");
4381 }
4382 }
4383 }
4384 }
4385 }
4386 if (state.eat(0x3A /* : */)) {
4387 this.regexp_disjunction(state);
4388 if (state.eat(0x29 /* ) */)) {
4389 return true
4390 }
4391 state.raise("Unterminated group");
4392 }
4393 }
4394 state.pos = start;
4395 }
4396 return false
4397};
4398pp$1.regexp_eatCapturingGroup = function(state) {
4399 if (state.eat(0x28 /* ( */)) {
4400 if (this.options.ecmaVersion >= 9) {
4401 this.regexp_groupSpecifier(state);
4402 } else if (state.current() === 0x3F /* ? */) {
4403 state.raise("Invalid group");
4404 }
4405 this.regexp_disjunction(state);
4406 if (state.eat(0x29 /* ) */)) {
4407 state.numCapturingParens += 1;
4408 return true
4409 }
4410 state.raise("Unterminated group");
4411 }
4412 return false
4413};
4414// RegularExpressionModifiers ::
4415// [empty]
4416// RegularExpressionModifiers RegularExpressionModifier
4417pp$1.regexp_eatModifiers = function(state) {
4418 var modifiers = "";
4419 var ch = 0;
4420 while ((ch = state.current()) !== -1 && isRegularExpressionModifier(ch)) {
4421 modifiers += codePointToString(ch);
4422 state.advance();
4423 }
4424 return modifiers
4425};
4426// RegularExpressionModifier :: one of
4427// `i` `m` `s`
4428function isRegularExpressionModifier(ch) {
4429 return ch === 0x69 /* i */ || ch === 0x6d /* m */ || ch === 0x73 /* s */
4430}
4431
4432// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
4433pp$1.regexp_eatExtendedAtom = function(state) {
4434 return (
4435 state.eat(0x2E /* . */) ||
4436 this.regexp_eatReverseSolidusAtomEscape(state) ||
4437 this.regexp_eatCharacterClass(state) ||
4438 this.regexp_eatUncapturingGroup(state) ||
4439 this.regexp_eatCapturingGroup(state) ||
4440 this.regexp_eatInvalidBracedQuantifier(state) ||
4441 this.regexp_eatExtendedPatternCharacter(state)
4442 )
4443};
4444
4445// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
4446pp$1.regexp_eatInvalidBracedQuantifier = function(state) {
4447 if (this.regexp_eatBracedQuantifier(state, true)) {
4448 state.raise("Nothing to repeat");
4449 }
4450 return false
4451};
4452
4453// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
4454pp$1.regexp_eatSyntaxCharacter = function(state) {
4455 var ch = state.current();
4456 if (isSyntaxCharacter(ch)) {
4457 state.lastIntValue = ch;
4458 state.advance();
4459 return true
4460 }
4461 return false
4462};
4463function isSyntaxCharacter(ch) {
4464 return (
4465 ch === 0x24 /* $ */ ||
4466 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
4467 ch === 0x2E /* . */ ||
4468 ch === 0x3F /* ? */ ||
4469 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
4470 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
4471 )
4472}
4473
4474// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
4475// But eat eager.
4476pp$1.regexp_eatPatternCharacters = function(state) {
4477 var start = state.pos;
4478 var ch = 0;
4479 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
4480 state.advance();
4481 }
4482 return state.pos !== start
4483};
4484
4485// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
4486pp$1.regexp_eatExtendedPatternCharacter = function(state) {
4487 var ch = state.current();
4488 if (
4489 ch !== -1 &&
4490 ch !== 0x24 /* $ */ &&
4491 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
4492 ch !== 0x2E /* . */ &&
4493 ch !== 0x3F /* ? */ &&
4494 ch !== 0x5B /* [ */ &&
4495 ch !== 0x5E /* ^ */ &&
4496 ch !== 0x7C /* | */
4497 ) {
4498 state.advance();
4499 return true
4500 }
4501 return false
4502};
4503
4504// GroupSpecifier ::
4505// [empty]
4506// `?` GroupName
4507pp$1.regexp_groupSpecifier = function(state) {
4508 if (state.eat(0x3F /* ? */)) {
4509 if (!this.regexp_eatGroupName(state)) { state.raise("Invalid group"); }
4510 var trackDisjunction = this.options.ecmaVersion >= 16;
4511 var known = state.groupNames[state.lastStringValue];
4512 if (known) {
4513 if (trackDisjunction) {
4514 for (var i = 0, list = known; i < list.length; i += 1) {
4515 var altID = list[i];
4516
4517 if (!altID.separatedFrom(state.branchID))
4518 { state.raise("Duplicate capture group name"); }
4519 }
4520 } else {
4521 state.raise("Duplicate capture group name");
4522 }
4523 }
4524 if (trackDisjunction) {
4525 (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID);
4526 } else {
4527 state.groupNames[state.lastStringValue] = true;
4528 }
4529 }
4530};
4531
4532// GroupName ::
4533// `<` RegExpIdentifierName `>`
4534// Note: this updates `state.lastStringValue` property with the eaten name.
4535pp$1.regexp_eatGroupName = function(state) {
4536 state.lastStringValue = "";
4537 if (state.eat(0x3C /* < */)) {
4538 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
4539 return true
4540 }
4541 state.raise("Invalid capture group name");
4542 }
4543 return false
4544};
4545
4546// RegExpIdentifierName ::
4547// RegExpIdentifierStart
4548// RegExpIdentifierName RegExpIdentifierPart
4549// Note: this updates `state.lastStringValue` property with the eaten name.
4550pp$1.regexp_eatRegExpIdentifierName = function(state) {
4551 state.lastStringValue = "";
4552 if (this.regexp_eatRegExpIdentifierStart(state)) {
4553 state.lastStringValue += codePointToString(state.lastIntValue);
4554 while (this.regexp_eatRegExpIdentifierPart(state)) {
4555 state.lastStringValue += codePointToString(state.lastIntValue);
4556 }
4557 return true
4558 }
4559 return false
4560};
4561
4562// RegExpIdentifierStart ::
4563// UnicodeIDStart
4564// `$`
4565// `_`
4566// `\` RegExpUnicodeEscapeSequence[+U]
4567pp$1.regexp_eatRegExpIdentifierStart = function(state) {
4568 var start = state.pos;
4569 var forceU = this.options.ecmaVersion >= 11;
4570 var ch = state.current(forceU);
4571 state.advance(forceU);
4572
4573 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
4574 ch = state.lastIntValue;
4575 }
4576 if (isRegExpIdentifierStart(ch)) {
4577 state.lastIntValue = ch;
4578 return true
4579 }
4580
4581 state.pos = start;
4582 return false
4583};
4584function isRegExpIdentifierStart(ch) {
4585 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
4586}
4587
4588// RegExpIdentifierPart ::
4589// UnicodeIDContinue
4590// `$`
4591// `_`
4592// `\` RegExpUnicodeEscapeSequence[+U]
4593// <ZWNJ>
4594// <ZWJ>
4595pp$1.regexp_eatRegExpIdentifierPart = function(state) {
4596 var start = state.pos;
4597 var forceU = this.options.ecmaVersion >= 11;
4598 var ch = state.current(forceU);
4599 state.advance(forceU);
4600
4601 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
4602 ch = state.lastIntValue;
4603 }
4604 if (isRegExpIdentifierPart(ch)) {
4605 state.lastIntValue = ch;
4606 return true
4607 }
4608
4609 state.pos = start;
4610 return false
4611};
4612function isRegExpIdentifierPart(ch) {
4613 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
4614}
4615
4616// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
4617pp$1.regexp_eatAtomEscape = function(state) {
4618 if (
4619 this.regexp_eatBackReference(state) ||
4620 this.regexp_eatCharacterClassEscape(state) ||
4621 this.regexp_eatCharacterEscape(state) ||
4622 (state.switchN && this.regexp_eatKGroupName(state))
4623 ) {
4624 return true
4625 }
4626 if (state.switchU) {
4627 // Make the same message as V8.
4628 if (state.current() === 0x63 /* c */) {
4629 state.raise("Invalid unicode escape");
4630 }
4631 state.raise("Invalid escape");
4632 }
4633 return false
4634};
4635pp$1.regexp_eatBackReference = function(state) {
4636 var start = state.pos;
4637 if (this.regexp_eatDecimalEscape(state)) {
4638 var n = state.lastIntValue;
4639 if (state.switchU) {
4640 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
4641 if (n > state.maxBackReference) {
4642 state.maxBackReference = n;
4643 }
4644 return true
4645 }
4646 if (n <= state.numCapturingParens) {
4647 return true
4648 }
4649 state.pos = start;
4650 }
4651 return false
4652};
4653pp$1.regexp_eatKGroupName = function(state) {
4654 if (state.eat(0x6B /* k */)) {
4655 if (this.regexp_eatGroupName(state)) {
4656 state.backReferenceNames.push(state.lastStringValue);
4657 return true
4658 }
4659 state.raise("Invalid named reference");
4660 }
4661 return false
4662};
4663
4664// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
4665pp$1.regexp_eatCharacterEscape = function(state) {
4666 return (
4667 this.regexp_eatControlEscape(state) ||
4668 this.regexp_eatCControlLetter(state) ||
4669 this.regexp_eatZero(state) ||
4670 this.regexp_eatHexEscapeSequence(state) ||
4671 this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
4672 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
4673 this.regexp_eatIdentityEscape(state)
4674 )
4675};
4676pp$1.regexp_eatCControlLetter = function(state) {
4677 var start = state.pos;
4678 if (state.eat(0x63 /* c */)) {
4679 if (this.regexp_eatControlLetter(state)) {
4680 return true
4681 }
4682 state.pos = start;
4683 }
4684 return false
4685};
4686pp$1.regexp_eatZero = function(state) {
4687 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
4688 state.lastIntValue = 0;
4689 state.advance();
4690 return true
4691 }
4692 return false
4693};
4694
4695// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
4696pp$1.regexp_eatControlEscape = function(state) {
4697 var ch = state.current();
4698 if (ch === 0x74 /* t */) {
4699 state.lastIntValue = 0x09; /* \t */
4700 state.advance();
4701 return true
4702 }
4703 if (ch === 0x6E /* n */) {
4704 state.lastIntValue = 0x0A; /* \n */
4705 state.advance();
4706 return true
4707 }
4708 if (ch === 0x76 /* v */) {
4709 state.lastIntValue = 0x0B; /* \v */
4710 state.advance();
4711 return true
4712 }
4713 if (ch === 0x66 /* f */) {
4714 state.lastIntValue = 0x0C; /* \f */
4715 state.advance();
4716 return true
4717 }
4718 if (ch === 0x72 /* r */) {
4719 state.lastIntValue = 0x0D; /* \r */
4720 state.advance();
4721 return true
4722 }
4723 return false
4724};
4725
4726// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
4727pp$1.regexp_eatControlLetter = function(state) {
4728 var ch = state.current();
4729 if (isControlLetter(ch)) {
4730 state.lastIntValue = ch % 0x20;
4731 state.advance();
4732 return true
4733 }
4734 return false
4735};
4736function isControlLetter(ch) {
4737 return (
4738 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
4739 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
4740 )
4741}
4742
4743// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
4744pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
4745 if ( forceU === void 0 ) forceU = false;
4746
4747 var start = state.pos;
4748 var switchU = forceU || state.switchU;
4749
4750 if (state.eat(0x75 /* u */)) {
4751 if (this.regexp_eatFixedHexDigits(state, 4)) {
4752 var lead = state.lastIntValue;
4753 if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
4754 var leadSurrogateEnd = state.pos;
4755 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
4756 var trail = state.lastIntValue;
4757 if (trail >= 0xDC00 && trail <= 0xDFFF) {
4758 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
4759 return true
4760 }
4761 }
4762 state.pos = leadSurrogateEnd;
4763 state.lastIntValue = lead;
4764 }
4765 return true
4766 }
4767 if (
4768 switchU &&
4769 state.eat(0x7B /* { */) &&
4770 this.regexp_eatHexDigits(state) &&
4771 state.eat(0x7D /* } */) &&
4772 isValidUnicode(state.lastIntValue)
4773 ) {
4774 return true
4775 }
4776 if (switchU) {
4777 state.raise("Invalid unicode escape");
4778 }
4779 state.pos = start;
4780 }
4781
4782 return false
4783};
4784function isValidUnicode(ch) {
4785 return ch >= 0 && ch <= 0x10FFFF
4786}
4787
4788// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
4789pp$1.regexp_eatIdentityEscape = function(state) {
4790 if (state.switchU) {
4791 if (this.regexp_eatSyntaxCharacter(state)) {
4792 return true
4793 }
4794 if (state.eat(0x2F /* / */)) {
4795 state.lastIntValue = 0x2F; /* / */
4796 return true
4797 }
4798 return false
4799 }
4800
4801 var ch = state.current();
4802 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
4803 state.lastIntValue = ch;
4804 state.advance();
4805 return true
4806 }
4807
4808 return false
4809};
4810
4811// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
4812pp$1.regexp_eatDecimalEscape = function(state) {
4813 state.lastIntValue = 0;
4814 var ch = state.current();
4815 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
4816 do {
4817 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
4818 state.advance();
4819 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
4820 return true
4821 }
4822 return false
4823};
4824
4825// Return values used by character set parsing methods, needed to
4826// forbid negation of sets that can match strings.
4827var CharSetNone = 0; // Nothing parsed
4828var CharSetOk = 1; // Construct parsed, cannot contain strings
4829var CharSetString = 2; // Construct parsed, can contain strings
4830
4831// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
4832pp$1.regexp_eatCharacterClassEscape = function(state) {
4833 var ch = state.current();
4834
4835 if (isCharacterClassEscape(ch)) {
4836 state.lastIntValue = -1;
4837 state.advance();
4838 return CharSetOk
4839 }
4840
4841 var negate = false;
4842 if (
4843 state.switchU &&
4844 this.options.ecmaVersion >= 9 &&
4845 ((negate = ch === 0x50 /* P */) || ch === 0x70 /* p */)
4846 ) {
4847 state.lastIntValue = -1;
4848 state.advance();
4849 var result;
4850 if (
4851 state.eat(0x7B /* { */) &&
4852 (result = this.regexp_eatUnicodePropertyValueExpression(state)) &&
4853 state.eat(0x7D /* } */)
4854 ) {
4855 if (negate && result === CharSetString) { state.raise("Invalid property name"); }
4856 return result
4857 }
4858 state.raise("Invalid property name");
4859 }
4860
4861 return CharSetNone
4862};
4863
4864function isCharacterClassEscape(ch) {
4865 return (
4866 ch === 0x64 /* d */ ||
4867 ch === 0x44 /* D */ ||
4868 ch === 0x73 /* s */ ||
4869 ch === 0x53 /* S */ ||
4870 ch === 0x77 /* w */ ||
4871 ch === 0x57 /* W */
4872 )
4873}
4874
4875// UnicodePropertyValueExpression ::
4876// UnicodePropertyName `=` UnicodePropertyValue
4877// LoneUnicodePropertyNameOrValue
4878pp$1.regexp_eatUnicodePropertyValueExpression = function(state) {
4879 var start = state.pos;
4880
4881 // UnicodePropertyName `=` UnicodePropertyValue
4882 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
4883 var name = state.lastStringValue;
4884 if (this.regexp_eatUnicodePropertyValue(state)) {
4885 var value = state.lastStringValue;
4886 this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
4887 return CharSetOk
4888 }
4889 }
4890 state.pos = start;
4891
4892 // LoneUnicodePropertyNameOrValue
4893 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
4894 var nameOrValue = state.lastStringValue;
4895 return this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue)
4896 }
4897 return CharSetNone
4898};
4899
4900pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
4901 if (!hasOwn(state.unicodeProperties.nonBinary, name))
4902 { state.raise("Invalid property name"); }
4903 if (!state.unicodeProperties.nonBinary[name].test(value))
4904 { state.raise("Invalid property value"); }
4905};
4906
4907pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
4908 if (state.unicodeProperties.binary.test(nameOrValue)) { return CharSetOk }
4909 if (state.switchV && state.unicodeProperties.binaryOfStrings.test(nameOrValue)) { return CharSetString }
4910 state.raise("Invalid property name");
4911};
4912
4913// UnicodePropertyName ::
4914// UnicodePropertyNameCharacters
4915pp$1.regexp_eatUnicodePropertyName = function(state) {
4916 var ch = 0;
4917 state.lastStringValue = "";
4918 while (isUnicodePropertyNameCharacter(ch = state.current())) {
4919 state.lastStringValue += codePointToString(ch);
4920 state.advance();
4921 }
4922 return state.lastStringValue !== ""
4923};
4924
4925function isUnicodePropertyNameCharacter(ch) {
4926 return isControlLetter(ch) || ch === 0x5F /* _ */
4927}
4928
4929// UnicodePropertyValue ::
4930// UnicodePropertyValueCharacters
4931pp$1.regexp_eatUnicodePropertyValue = function(state) {
4932 var ch = 0;
4933 state.lastStringValue = "";
4934 while (isUnicodePropertyValueCharacter(ch = state.current())) {
4935 state.lastStringValue += codePointToString(ch);
4936 state.advance();
4937 }
4938 return state.lastStringValue !== ""
4939};
4940function isUnicodePropertyValueCharacter(ch) {
4941 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
4942}
4943
4944// LoneUnicodePropertyNameOrValue ::
4945// UnicodePropertyValueCharacters
4946pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
4947 return this.regexp_eatUnicodePropertyValue(state)
4948};
4949
4950// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
4951pp$1.regexp_eatCharacterClass = function(state) {
4952 if (state.eat(0x5B /* [ */)) {
4953 var negate = state.eat(0x5E /* ^ */);
4954 var result = this.regexp_classContents(state);
4955 if (!state.eat(0x5D /* ] */))
4956 { state.raise("Unterminated character class"); }
4957 if (negate && result === CharSetString)
4958 { state.raise("Negated character class may contain strings"); }
4959 return true
4960 }
4961 return false
4962};
4963
4964// https://tc39.es/ecma262/#prod-ClassContents
4965// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
4966pp$1.regexp_classContents = function(state) {
4967 if (state.current() === 0x5D /* ] */) { return CharSetOk }
4968 if (state.switchV) { return this.regexp_classSetExpression(state) }
4969 this.regexp_nonEmptyClassRanges(state);
4970 return CharSetOk
4971};
4972
4973// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
4974// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
4975pp$1.regexp_nonEmptyClassRanges = function(state) {
4976 while (this.regexp_eatClassAtom(state)) {
4977 var left = state.lastIntValue;
4978 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
4979 var right = state.lastIntValue;
4980 if (state.switchU && (left === -1 || right === -1)) {
4981 state.raise("Invalid character class");
4982 }
4983 if (left !== -1 && right !== -1 && left > right) {
4984 state.raise("Range out of order in character class");
4985 }
4986 }
4987 }
4988};
4989
4990// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
4991// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
4992pp$1.regexp_eatClassAtom = function(state) {
4993 var start = state.pos;
4994
4995 if (state.eat(0x5C /* \ */)) {
4996 if (this.regexp_eatClassEscape(state)) {
4997 return true
4998 }
4999 if (state.switchU) {
5000 // Make the same message as V8.
5001 var ch$1 = state.current();
5002 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
5003 state.raise("Invalid class escape");
5004 }
5005 state.raise("Invalid escape");
5006 }
5007 state.pos = start;
5008 }
5009
5010 var ch = state.current();
5011 if (ch !== 0x5D /* ] */) {
5012 state.lastIntValue = ch;
5013 state.advance();
5014 return true
5015 }
5016
5017 return false
5018};
5019
5020// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
5021pp$1.regexp_eatClassEscape = function(state) {
5022 var start = state.pos;
5023
5024 if (state.eat(0x62 /* b */)) {
5025 state.lastIntValue = 0x08; /* <BS> */
5026 return true
5027 }
5028
5029 if (state.switchU && state.eat(0x2D /* - */)) {
5030 state.lastIntValue = 0x2D; /* - */
5031 return true
5032 }
5033
5034 if (!state.switchU && state.eat(0x63 /* c */)) {
5035 if (this.regexp_eatClassControlLetter(state)) {
5036 return true
5037 }
5038 state.pos = start;
5039 }
5040
5041 return (
5042 this.regexp_eatCharacterClassEscape(state) ||
5043 this.regexp_eatCharacterEscape(state)
5044 )
5045};
5046
5047// https://tc39.es/ecma262/#prod-ClassSetExpression
5048// https://tc39.es/ecma262/#prod-ClassUnion
5049// https://tc39.es/ecma262/#prod-ClassIntersection
5050// https://tc39.es/ecma262/#prod-ClassSubtraction
5051pp$1.regexp_classSetExpression = function(state) {
5052 var result = CharSetOk, subResult;
5053 if (this.regexp_eatClassSetRange(state)) ; else if (subResult = this.regexp_eatClassSetOperand(state)) {
5054 if (subResult === CharSetString) { result = CharSetString; }
5055 // https://tc39.es/ecma262/#prod-ClassIntersection
5056 var start = state.pos;
5057 while (state.eatChars([0x26, 0x26] /* && */)) {
5058 if (
5059 state.current() !== 0x26 /* & */ &&
5060 (subResult = this.regexp_eatClassSetOperand(state))
5061 ) {
5062 if (subResult !== CharSetString) { result = CharSetOk; }
5063 continue
5064 }
5065 state.raise("Invalid character in character class");
5066 }
5067 if (start !== state.pos) { return result }
5068 // https://tc39.es/ecma262/#prod-ClassSubtraction
5069 while (state.eatChars([0x2D, 0x2D] /* -- */)) {
5070 if (this.regexp_eatClassSetOperand(state)) { continue }
5071 state.raise("Invalid character in character class");
5072 }
5073 if (start !== state.pos) { return result }
5074 } else {
5075 state.raise("Invalid character in character class");
5076 }
5077 // https://tc39.es/ecma262/#prod-ClassUnion
5078 for (;;) {
5079 if (this.regexp_eatClassSetRange(state)) { continue }
5080 subResult = this.regexp_eatClassSetOperand(state);
5081 if (!subResult) { return result }
5082 if (subResult === CharSetString) { result = CharSetString; }
5083 }
5084};
5085
5086// https://tc39.es/ecma262/#prod-ClassSetRange
5087pp$1.regexp_eatClassSetRange = function(state) {
5088 var start = state.pos;
5089 if (this.regexp_eatClassSetCharacter(state)) {
5090 var left = state.lastIntValue;
5091 if (state.eat(0x2D /* - */) && this.regexp_eatClassSetCharacter(state)) {
5092 var right = state.lastIntValue;
5093 if (left !== -1 && right !== -1 && left > right) {
5094 state.raise("Range out of order in character class");
5095 }
5096 return true
5097 }
5098 state.pos = start;
5099 }
5100 return false
5101};
5102
5103// https://tc39.es/ecma262/#prod-ClassSetOperand
5104pp$1.regexp_eatClassSetOperand = function(state) {
5105 if (this.regexp_eatClassSetCharacter(state)) { return CharSetOk }
5106 return this.regexp_eatClassStringDisjunction(state) || this.regexp_eatNestedClass(state)
5107};
5108
5109// https://tc39.es/ecma262/#prod-NestedClass
5110pp$1.regexp_eatNestedClass = function(state) {
5111 var start = state.pos;
5112 if (state.eat(0x5B /* [ */)) {
5113 var negate = state.eat(0x5E /* ^ */);
5114 var result = this.regexp_classContents(state);
5115 if (state.eat(0x5D /* ] */)) {
5116 if (negate && result === CharSetString) {
5117 state.raise("Negated character class may contain strings");
5118 }
5119 return result
5120 }
5121 state.pos = start;
5122 }
5123 if (state.eat(0x5C /* \ */)) {
5124 var result$1 = this.regexp_eatCharacterClassEscape(state);
5125 if (result$1) {
5126 return result$1
5127 }
5128 state.pos = start;
5129 }
5130 return null
5131};
5132
5133// https://tc39.es/ecma262/#prod-ClassStringDisjunction
5134pp$1.regexp_eatClassStringDisjunction = function(state) {
5135 var start = state.pos;
5136 if (state.eatChars([0x5C, 0x71] /* \q */)) {
5137 if (state.eat(0x7B /* { */)) {
5138 var result = this.regexp_classStringDisjunctionContents(state);
5139 if (state.eat(0x7D /* } */)) {
5140 return result
5141 }
5142 } else {
5143 // Make the same message as V8.
5144 state.raise("Invalid escape");
5145 }
5146 state.pos = start;
5147 }
5148 return null
5149};
5150
5151// https://tc39.es/ecma262/#prod-ClassStringDisjunctionContents
5152pp$1.regexp_classStringDisjunctionContents = function(state) {
5153 var result = this.regexp_classString(state);
5154 while (state.eat(0x7C /* | */)) {
5155 if (this.regexp_classString(state) === CharSetString) { result = CharSetString; }
5156 }
5157 return result
5158};
5159
5160// https://tc39.es/ecma262/#prod-ClassString
5161// https://tc39.es/ecma262/#prod-NonEmptyClassString
5162pp$1.regexp_classString = function(state) {
5163 var count = 0;
5164 while (this.regexp_eatClassSetCharacter(state)) { count++; }
5165 return count === 1 ? CharSetOk : CharSetString
5166};
5167
5168// https://tc39.es/ecma262/#prod-ClassSetCharacter
5169pp$1.regexp_eatClassSetCharacter = function(state) {
5170 var start = state.pos;
5171 if (state.eat(0x5C /* \ */)) {
5172 if (
5173 this.regexp_eatCharacterEscape(state) ||
5174 this.regexp_eatClassSetReservedPunctuator(state)
5175 ) {
5176 return true
5177 }
5178 if (state.eat(0x62 /* b */)) {
5179 state.lastIntValue = 0x08; /* <BS> */
5180 return true
5181 }
5182 state.pos = start;
5183 return false
5184 }
5185 var ch = state.current();
5186 if (ch < 0 || ch === state.lookahead() && isClassSetReservedDoublePunctuatorCharacter(ch)) { return false }
5187 if (isClassSetSyntaxCharacter(ch)) { return false }
5188 state.advance();
5189 state.lastIntValue = ch;
5190 return true
5191};
5192
5193// https://tc39.es/ecma262/#prod-ClassSetReservedDoublePunctuator
5194function isClassSetReservedDoublePunctuatorCharacter(ch) {
5195 return (
5196 ch === 0x21 /* ! */ ||
5197 ch >= 0x23 /* # */ && ch <= 0x26 /* & */ ||
5198 ch >= 0x2A /* * */ && ch <= 0x2C /* , */ ||
5199 ch === 0x2E /* . */ ||
5200 ch >= 0x3A /* : */ && ch <= 0x40 /* @ */ ||
5201 ch === 0x5E /* ^ */ ||
5202 ch === 0x60 /* ` */ ||
5203 ch === 0x7E /* ~ */
5204 )
5205}
5206
5207// https://tc39.es/ecma262/#prod-ClassSetSyntaxCharacter
5208function isClassSetSyntaxCharacter(ch) {
5209 return (
5210 ch === 0x28 /* ( */ ||
5211 ch === 0x29 /* ) */ ||
5212 ch === 0x2D /* - */ ||
5213 ch === 0x2F /* / */ ||
5214 ch >= 0x5B /* [ */ && ch <= 0x5D /* ] */ ||
5215 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
5216 )
5217}
5218
5219// https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator
5220pp$1.regexp_eatClassSetReservedPunctuator = function(state) {
5221 var ch = state.current();
5222 if (isClassSetReservedPunctuator(ch)) {
5223 state.lastIntValue = ch;
5224 state.advance();
5225 return true
5226 }
5227 return false
5228};
5229
5230// https://tc39.es/ecma262/#prod-ClassSetReservedPunctuator
5231function isClassSetReservedPunctuator(ch) {
5232 return (
5233 ch === 0x21 /* ! */ ||
5234 ch === 0x23 /* # */ ||
5235 ch === 0x25 /* % */ ||
5236 ch === 0x26 /* & */ ||
5237 ch === 0x2C /* , */ ||
5238 ch === 0x2D /* - */ ||
5239 ch >= 0x3A /* : */ && ch <= 0x3E /* > */ ||
5240 ch === 0x40 /* @ */ ||
5241 ch === 0x60 /* ` */ ||
5242 ch === 0x7E /* ~ */
5243 )
5244}
5245
5246// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
5247pp$1.regexp_eatClassControlLetter = function(state) {
5248 var ch = state.current();
5249 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
5250 state.lastIntValue = ch % 0x20;
5251 state.advance();
5252 return true
5253 }
5254 return false
5255};
5256
5257// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
5258pp$1.regexp_eatHexEscapeSequence = function(state) {
5259 var start = state.pos;
5260 if (state.eat(0x78 /* x */)) {
5261 if (this.regexp_eatFixedHexDigits(state, 2)) {
5262 return true
5263 }
5264 if (state.switchU) {
5265 state.raise("Invalid escape");
5266 }
5267 state.pos = start;
5268 }
5269 return false
5270};
5271
5272// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
5273pp$1.regexp_eatDecimalDigits = function(state) {
5274 var start = state.pos;
5275 var ch = 0;
5276 state.lastIntValue = 0;
5277 while (isDecimalDigit(ch = state.current())) {
5278 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
5279 state.advance();
5280 }
5281 return state.pos !== start
5282};
5283function isDecimalDigit(ch) {
5284 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
5285}
5286
5287// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
5288pp$1.regexp_eatHexDigits = function(state) {
5289 var start = state.pos;
5290 var ch = 0;
5291 state.lastIntValue = 0;
5292 while (isHexDigit(ch = state.current())) {
5293 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
5294 state.advance();
5295 }
5296 return state.pos !== start
5297};
5298function isHexDigit(ch) {
5299 return (
5300 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
5301 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
5302 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
5303 )
5304}
5305function hexToInt(ch) {
5306 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
5307 return 10 + (ch - 0x41 /* A */)
5308 }
5309 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
5310 return 10 + (ch - 0x61 /* a */)
5311 }
5312 return ch - 0x30 /* 0 */
5313}
5314
5315// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
5316// Allows only 0-377(octal) i.e. 0-255(decimal).
5317pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {
5318 if (this.regexp_eatOctalDigit(state)) {
5319 var n1 = state.lastIntValue;
5320 if (this.regexp_eatOctalDigit(state)) {
5321 var n2 = state.lastIntValue;
5322 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
5323 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
5324 } else {
5325 state.lastIntValue = n1 * 8 + n2;
5326 }
5327 } else {
5328 state.lastIntValue = n1;
5329 }
5330 return true
5331 }
5332 return false
5333};
5334
5335// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
5336pp$1.regexp_eatOctalDigit = function(state) {
5337 var ch = state.current();
5338 if (isOctalDigit(ch)) {
5339 state.lastIntValue = ch - 0x30; /* 0 */
5340 state.advance();
5341 return true
5342 }
5343 state.lastIntValue = 0;
5344 return false
5345};
5346function isOctalDigit(ch) {
5347 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
5348}
5349
5350// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
5351// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
5352// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
5353pp$1.regexp_eatFixedHexDigits = function(state, length) {
5354 var start = state.pos;
5355 state.lastIntValue = 0;
5356 for (var i = 0; i < length; ++i) {
5357 var ch = state.current();
5358 if (!isHexDigit(ch)) {
5359 state.pos = start;
5360 return false
5361 }
5362 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
5363 state.advance();
5364 }
5365 return true
5366};
5367
5368// Object type used to represent tokens. Note that normally, tokens
5369// simply exist as properties on the parser object. This is only
5370// used for the onToken callback and the external tokenizer.
5371
5372var Token = function Token(p) {
5373 this.type = p.type;
5374 this.value = p.value;
5375 this.start = p.start;
5376 this.end = p.end;
5377 if (p.options.locations)
5378 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
5379 if (p.options.ranges)
5380 { this.range = [p.start, p.end]; }
5381};
5382
5383// ## Tokenizer
5384
5385var pp = Parser.prototype;
5386
5387// Move to the next token
5388
5389pp.next = function(ignoreEscapeSequenceInKeyword) {
5390 if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
5391 { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
5392 if (this.options.onToken)
5393 { this.options.onToken(new Token(this)); }
5394
5395 this.lastTokEnd = this.end;
5396 this.lastTokStart = this.start;
5397 this.lastTokEndLoc = this.endLoc;
5398 this.lastTokStartLoc = this.startLoc;
5399 this.nextToken();
5400};
5401
5402pp.getToken = function() {
5403 this.next();
5404 return new Token(this)
5405};
5406
5407// If we're in an ES6 environment, make parsers iterable
5408if (typeof Symbol !== "undefined")
5409 { pp[Symbol.iterator] = function() {
5410 var this$1$1 = this;
5411
5412 return {
5413 next: function () {
5414 var token = this$1$1.getToken();
5415 return {
5416 done: token.type === types$1.eof,
5417 value: token
5418 }
5419 }
5420 }
5421 }; }
5422
5423// Toggle strict mode. Re-reads the next number or string to please
5424// pedantic tests (`"use strict"; 010;` should fail).
5425
5426// Read a single token, updating the parser object's token-related
5427// properties.
5428
5429pp.nextToken = function() {
5430 var curContext = this.curContext();
5431 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
5432
5433 this.start = this.pos;
5434 if (this.options.locations) { this.startLoc = this.curPosition(); }
5435 if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }
5436
5437 if (curContext.override) { return curContext.override(this) }
5438 else { this.readToken(this.fullCharCodeAtPos()); }
5439};
5440
5441pp.readToken = function(code) {
5442 // Identifier or keyword. '\uXXXX' sequences are allowed in
5443 // identifiers, so '\' also dispatches to that.
5444 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
5445 { return this.readWord() }
5446
5447 return this.getTokenFromCode(code)
5448};
5449
5450pp.fullCharCodeAtPos = function() {
5451 var code = this.input.charCodeAt(this.pos);
5452 if (code <= 0xd7ff || code >= 0xdc00) { return code }
5453 var next = this.input.charCodeAt(this.pos + 1);
5454 return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
5455};
5456
5457pp.skipBlockComment = function() {
5458 var startLoc = this.options.onComment && this.curPosition();
5459 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
5460 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
5461 this.pos = end + 2;
5462 if (this.options.locations) {
5463 for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {
5464 ++this.curLine;
5465 pos = this.lineStart = nextBreak;
5466 }
5467 }
5468 if (this.options.onComment)
5469 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
5470 startLoc, this.curPosition()); }
5471};
5472
5473pp.skipLineComment = function(startSkip) {
5474 var start = this.pos;
5475 var startLoc = this.options.onComment && this.curPosition();
5476 var ch = this.input.charCodeAt(this.pos += startSkip);
5477 while (this.pos < this.input.length && !isNewLine(ch)) {
5478 ch = this.input.charCodeAt(++this.pos);
5479 }
5480 if (this.options.onComment)
5481 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
5482 startLoc, this.curPosition()); }
5483};
5484
5485// Called at the start of the parse and after every token. Skips
5486// whitespace and comments, and.
5487
5488pp.skipSpace = function() {
5489 loop: while (this.pos < this.input.length) {
5490 var ch = this.input.charCodeAt(this.pos);
5491 switch (ch) {
5492 case 32: case 160: // ' '
5493 ++this.pos;
5494 break
5495 case 13:
5496 if (this.input.charCodeAt(this.pos + 1) === 10) {
5497 ++this.pos;
5498 }
5499 case 10: case 8232: case 8233:
5500 ++this.pos;
5501 if (this.options.locations) {
5502 ++this.curLine;
5503 this.lineStart = this.pos;
5504 }
5505 break
5506 case 47: // '/'
5507 switch (this.input.charCodeAt(this.pos + 1)) {
5508 case 42: // '*'
5509 this.skipBlockComment();
5510 break
5511 case 47:
5512 this.skipLineComment(2);
5513 break
5514 default:
5515 break loop
5516 }
5517 break
5518 default:
5519 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
5520 ++this.pos;
5521 } else {
5522 break loop
5523 }
5524 }
5525 }
5526};
5527
5528// Called at the end of every token. Sets `end`, `val`, and
5529// maintains `context` and `exprAllowed`, and skips the space after
5530// the token, so that the next one's `start` will point at the
5531// right position.
5532
5533pp.finishToken = function(type, val) {
5534 this.end = this.pos;
5535 if (this.options.locations) { this.endLoc = this.curPosition(); }
5536 var prevType = this.type;
5537 this.type = type;
5538 this.value = val;
5539
5540 this.updateContext(prevType);
5541};
5542
5543// ### Token reading
5544
5545// This is the function that is called to fetch the next token. It
5546// is somewhat obscure, because it works in character codes rather
5547// than characters, and because operator parsing has been inlined
5548// into it.
5549//
5550// All in the name of speed.
5551//
5552pp.readToken_dot = function() {
5553 var next = this.input.charCodeAt(this.pos + 1);
5554 if (next >= 48 && next <= 57) { return this.readNumber(true) }
5555 var next2 = this.input.charCodeAt(this.pos + 2);
5556 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
5557 this.pos += 3;
5558 return this.finishToken(types$1.ellipsis)
5559 } else {
5560 ++this.pos;
5561 return this.finishToken(types$1.dot)
5562 }
5563};
5564
5565pp.readToken_slash = function() { // '/'
5566 var next = this.input.charCodeAt(this.pos + 1);
5567 if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
5568 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5569 return this.finishOp(types$1.slash, 1)
5570};
5571
5572pp.readToken_mult_modulo_exp = function(code) { // '%*'
5573 var next = this.input.charCodeAt(this.pos + 1);
5574 var size = 1;
5575 var tokentype = code === 42 ? types$1.star : types$1.modulo;
5576
5577 // exponentiation operator ** and **=
5578 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
5579 ++size;
5580 tokentype = types$1.starstar;
5581 next = this.input.charCodeAt(this.pos + 2);
5582 }
5583
5584 if (next === 61) { return this.finishOp(types$1.assign, size + 1) }
5585 return this.finishOp(tokentype, size)
5586};
5587
5588pp.readToken_pipe_amp = function(code) { // '|&'
5589 var next = this.input.charCodeAt(this.pos + 1);
5590 if (next === code) {
5591 if (this.options.ecmaVersion >= 12) {
5592 var next2 = this.input.charCodeAt(this.pos + 2);
5593 if (next2 === 61) { return this.finishOp(types$1.assign, 3) }
5594 }
5595 return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)
5596 }
5597 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5598 return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)
5599};
5600
5601pp.readToken_caret = function() { // '^'
5602 var next = this.input.charCodeAt(this.pos + 1);
5603 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5604 return this.finishOp(types$1.bitwiseXOR, 1)
5605};
5606
5607pp.readToken_plus_min = function(code) { // '+-'
5608 var next = this.input.charCodeAt(this.pos + 1);
5609 if (next === code) {
5610 if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
5611 (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
5612 // A `-->` line comment
5613 this.skipLineComment(3);
5614 this.skipSpace();
5615 return this.nextToken()
5616 }
5617 return this.finishOp(types$1.incDec, 2)
5618 }
5619 if (next === 61) { return this.finishOp(types$1.assign, 2) }
5620 return this.finishOp(types$1.plusMin, 1)
5621};
5622
5623pp.readToken_lt_gt = function(code) { // '<>'
5624 var next = this.input.charCodeAt(this.pos + 1);
5625 var size = 1;
5626 if (next === code) {
5627 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
5628 if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }
5629 return this.finishOp(types$1.bitShift, size)
5630 }
5631 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
5632 this.input.charCodeAt(this.pos + 3) === 45) {
5633 // `<!--`, an XML-style comment that should be interpreted as a line comment
5634 this.skipLineComment(4);
5635 this.skipSpace();
5636 return this.nextToken()
5637 }
5638 if (next === 61) { size = 2; }
5639 return this.finishOp(types$1.relational, size)
5640};
5641
5642pp.readToken_eq_excl = function(code) { // '=!'
5643 var next = this.input.charCodeAt(this.pos + 1);
5644 if (next === 61) { return this.finishOp(types$1.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
5645 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
5646 this.pos += 2;
5647 return this.finishToken(types$1.arrow)
5648 }
5649 return this.finishOp(code === 61 ? types$1.eq : types$1.prefix, 1)
5650};
5651
5652pp.readToken_question = function() { // '?'
5653 var ecmaVersion = this.options.ecmaVersion;
5654 if (ecmaVersion >= 11) {
5655 var next = this.input.charCodeAt(this.pos + 1);
5656 if (next === 46) {
5657 var next2 = this.input.charCodeAt(this.pos + 2);
5658 if (next2 < 48 || next2 > 57) { return this.finishOp(types$1.questionDot, 2) }
5659 }
5660 if (next === 63) {
5661 if (ecmaVersion >= 12) {
5662 var next2$1 = this.input.charCodeAt(this.pos + 2);
5663 if (next2$1 === 61) { return this.finishOp(types$1.assign, 3) }
5664 }
5665 return this.finishOp(types$1.coalesce, 2)
5666 }
5667 }
5668 return this.finishOp(types$1.question, 1)
5669};
5670
5671pp.readToken_numberSign = function() { // '#'
5672 var ecmaVersion = this.options.ecmaVersion;
5673 var code = 35; // '#'
5674 if (ecmaVersion >= 13) {
5675 ++this.pos;
5676 code = this.fullCharCodeAtPos();
5677 if (isIdentifierStart(code, true) || code === 92 /* '\' */) {
5678 return this.finishToken(types$1.privateId, this.readWord1())
5679 }
5680 }
5681
5682 this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
5683};
5684
5685pp.getTokenFromCode = function(code) {
5686 switch (code) {
5687 // The interpretation of a dot depends on whether it is followed
5688 // by a digit or another two dots.
5689 case 46: // '.'
5690 return this.readToken_dot()
5691
5692 // Punctuation tokens.
5693 case 40: ++this.pos; return this.finishToken(types$1.parenL)
5694 case 41: ++this.pos; return this.finishToken(types$1.parenR)
5695 case 59: ++this.pos; return this.finishToken(types$1.semi)
5696 case 44: ++this.pos; return this.finishToken(types$1.comma)
5697 case 91: ++this.pos; return this.finishToken(types$1.bracketL)
5698 case 93: ++this.pos; return this.finishToken(types$1.bracketR)
5699 case 123: ++this.pos; return this.finishToken(types$1.braceL)
5700 case 125: ++this.pos; return this.finishToken(types$1.braceR)
5701 case 58: ++this.pos; return this.finishToken(types$1.colon)
5702
5703 case 96: // '`'
5704 if (this.options.ecmaVersion < 6) { break }
5705 ++this.pos;
5706 return this.finishToken(types$1.backQuote)
5707
5708 case 48: // '0'
5709 var next = this.input.charCodeAt(this.pos + 1);
5710 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
5711 if (this.options.ecmaVersion >= 6) {
5712 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
5713 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
5714 }
5715
5716 // Anything else beginning with a digit is an integer, octal
5717 // number, or float.
5718 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
5719 return this.readNumber(false)
5720
5721 // Quotes produce strings.
5722 case 34: case 39: // '"', "'"
5723 return this.readString(code)
5724
5725 // Operators are parsed inline in tiny state machines. '=' (61) is
5726 // often referred to. `finishOp` simply skips the amount of
5727 // characters it is given as second argument, and returns a token
5728 // of the type given by its first argument.
5729 case 47: // '/'
5730 return this.readToken_slash()
5731
5732 case 37: case 42: // '%*'
5733 return this.readToken_mult_modulo_exp(code)
5734
5735 case 124: case 38: // '|&'
5736 return this.readToken_pipe_amp(code)
5737
5738 case 94: // '^'
5739 return this.readToken_caret()
5740
5741 case 43: case 45: // '+-'
5742 return this.readToken_plus_min(code)
5743
5744 case 60: case 62: // '<>'
5745 return this.readToken_lt_gt(code)
5746
5747 case 61: case 33: // '=!'
5748 return this.readToken_eq_excl(code)
5749
5750 case 63: // '?'
5751 return this.readToken_question()
5752
5753 case 126: // '~'
5754 return this.finishOp(types$1.prefix, 1)
5755
5756 case 35: // '#'
5757 return this.readToken_numberSign()
5758 }
5759
5760 this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
5761};
5762
5763pp.finishOp = function(type, size) {
5764 var str = this.input.slice(this.pos, this.pos + size);
5765 this.pos += size;
5766 return this.finishToken(type, str)
5767};
5768
5769pp.readRegexp = function() {
5770 var escaped, inClass, start = this.pos;
5771 for (;;) {
5772 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
5773 var ch = this.input.charAt(this.pos);
5774 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
5775 if (!escaped) {
5776 if (ch === "[") { inClass = true; }
5777 else if (ch === "]" && inClass) { inClass = false; }
5778 else if (ch === "/" && !inClass) { break }
5779 escaped = ch === "\\";
5780 } else { escaped = false; }
5781 ++this.pos;
5782 }
5783 var pattern = this.input.slice(start, this.pos);
5784 ++this.pos;
5785 var flagsStart = this.pos;
5786 var flags = this.readWord1();
5787 if (this.containsEsc) { this.unexpected(flagsStart); }
5788
5789 // Validate pattern
5790 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
5791 state.reset(start, pattern, flags);
5792 this.validateRegExpFlags(state);
5793 this.validateRegExpPattern(state);
5794
5795 // Create Literal#value property value.
5796 var value = null;
5797 try {
5798 value = new RegExp(pattern, flags);
5799 } catch (e) {
5800 // ESTree requires null if it failed to instantiate RegExp object.
5801 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
5802 }
5803
5804 return this.finishToken(types$1.regexp, {pattern: pattern, flags: flags, value: value})
5805};
5806
5807// Read an integer in the given radix. Return null if zero digits
5808// were read, the integer value otherwise. When `len` is given, this
5809// will return `null` unless the integer has exactly `len` digits.
5810
5811pp.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
5812 // `len` is used for character escape sequences. In that case, disallow separators.
5813 var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
5814
5815 // `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b)
5816 // and isn't fraction part nor exponent part. In that case, if the first digit
5817 // is zero then disallow separators.
5818 var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
5819
5820 var start = this.pos, total = 0, lastCode = 0;
5821 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
5822 var code = this.input.charCodeAt(this.pos), val = (void 0);
5823
5824 if (allowSeparators && code === 95) {
5825 if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
5826 if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
5827 if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
5828 lastCode = code;
5829 continue
5830 }
5831
5832 if (code >= 97) { val = code - 97 + 10; } // a
5833 else if (code >= 65) { val = code - 65 + 10; } // A
5834 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
5835 else { val = Infinity; }
5836 if (val >= radix) { break }
5837 lastCode = code;
5838 total = total * radix + val;
5839 }
5840
5841 if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
5842 if (this.pos === start || len != null && this.pos - start !== len) { return null }
5843
5844 return total
5845};
5846
5847function stringToNumber(str, isLegacyOctalNumericLiteral) {
5848 if (isLegacyOctalNumericLiteral) {
5849 return parseInt(str, 8)
5850 }
5851
5852 // `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value.
5853 return parseFloat(str.replace(/_/g, ""))
5854}
5855
5856function stringToBigInt(str) {
5857 if (typeof BigInt !== "function") {
5858 return null
5859 }
5860
5861 // `BigInt(value)` throws syntax error if the string contains numeric separators.
5862 return BigInt(str.replace(/_/g, ""))
5863}
5864
5865pp.readRadixNumber = function(radix) {
5866 var start = this.pos;
5867 this.pos += 2; // 0x
5868 var val = this.readInt(radix);
5869 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
5870 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
5871 val = stringToBigInt(this.input.slice(start, this.pos));
5872 ++this.pos;
5873 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5874 return this.finishToken(types$1.num, val)
5875};
5876
5877// Read an integer, octal integer, or floating-point number.
5878
5879pp.readNumber = function(startsWithDot) {
5880 var start = this.pos;
5881 if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
5882 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
5883 if (octal && this.strict) { this.raise(start, "Invalid number"); }
5884 var next = this.input.charCodeAt(this.pos);
5885 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
5886 var val$1 = stringToBigInt(this.input.slice(start, this.pos));
5887 ++this.pos;
5888 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5889 return this.finishToken(types$1.num, val$1)
5890 }
5891 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
5892 if (next === 46 && !octal) { // '.'
5893 ++this.pos;
5894 this.readInt(10);
5895 next = this.input.charCodeAt(this.pos);
5896 }
5897 if ((next === 69 || next === 101) && !octal) { // 'eE'
5898 next = this.input.charCodeAt(++this.pos);
5899 if (next === 43 || next === 45) { ++this.pos; } // '+-'
5900 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
5901 }
5902 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
5903
5904 var val = stringToNumber(this.input.slice(start, this.pos), octal);
5905 return this.finishToken(types$1.num, val)
5906};
5907
5908// Read a string value, interpreting backslash-escapes.
5909
5910pp.readCodePoint = function() {
5911 var ch = this.input.charCodeAt(this.pos), code;
5912
5913 if (ch === 123) { // '{'
5914 if (this.options.ecmaVersion < 6) { this.unexpected(); }
5915 var codePos = ++this.pos;
5916 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
5917 ++this.pos;
5918 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
5919 } else {
5920 code = this.readHexChar(4);
5921 }
5922 return code
5923};
5924
5925pp.readString = function(quote) {
5926 var out = "", chunkStart = ++this.pos;
5927 for (;;) {
5928 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
5929 var ch = this.input.charCodeAt(this.pos);
5930 if (ch === quote) { break }
5931 if (ch === 92) { // '\'
5932 out += this.input.slice(chunkStart, this.pos);
5933 out += this.readEscapedChar(false);
5934 chunkStart = this.pos;
5935 } else if (ch === 0x2028 || ch === 0x2029) {
5936 if (this.options.ecmaVersion < 10) { this.raise(this.start, "Unterminated string constant"); }
5937 ++this.pos;
5938 if (this.options.locations) {
5939 this.curLine++;
5940 this.lineStart = this.pos;
5941 }
5942 } else {
5943 if (isNewLine(ch)) { this.raise(this.start, "Unterminated string constant"); }
5944 ++this.pos;
5945 }
5946 }
5947 out += this.input.slice(chunkStart, this.pos++);
5948 return this.finishToken(types$1.string, out)
5949};
5950
5951// Reads template string tokens.
5952
5953var INVALID_TEMPLATE_ESCAPE_ERROR = {};
5954
5955pp.tryReadTemplateToken = function() {
5956 this.inTemplateElement = true;
5957 try {
5958 this.readTmplToken();
5959 } catch (err) {
5960 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
5961 this.readInvalidTemplateToken();
5962 } else {
5963 throw err
5964 }
5965 }
5966
5967 this.inTemplateElement = false;
5968};
5969
5970pp.invalidStringToken = function(position, message) {
5971 if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
5972 throw INVALID_TEMPLATE_ESCAPE_ERROR
5973 } else {
5974 this.raise(position, message);
5975 }
5976};
5977
5978pp.readTmplToken = function() {
5979 var out = "", chunkStart = this.pos;
5980 for (;;) {
5981 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
5982 var ch = this.input.charCodeAt(this.pos);
5983 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
5984 if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) {
5985 if (ch === 36) {
5986 this.pos += 2;
5987 return this.finishToken(types$1.dollarBraceL)
5988 } else {
5989 ++this.pos;
5990 return this.finishToken(types$1.backQuote)
5991 }
5992 }
5993 out += this.input.slice(chunkStart, this.pos);
5994 return this.finishToken(types$1.template, out)
5995 }
5996 if (ch === 92) { // '\'
5997 out += this.input.slice(chunkStart, this.pos);
5998 out += this.readEscapedChar(true);
5999 chunkStart = this.pos;
6000 } else if (isNewLine(ch)) {
6001 out += this.input.slice(chunkStart, this.pos);
6002 ++this.pos;
6003 switch (ch) {
6004 case 13:
6005 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
6006 case 10:
6007 out += "\n";
6008 break
6009 default:
6010 out += String.fromCharCode(ch);
6011 break
6012 }
6013 if (this.options.locations) {
6014 ++this.curLine;
6015 this.lineStart = this.pos;
6016 }
6017 chunkStart = this.pos;
6018 } else {
6019 ++this.pos;
6020 }
6021 }
6022};
6023
6024// Reads a template token to search for the end, without validating any escape sequences
6025pp.readInvalidTemplateToken = function() {
6026 for (; this.pos < this.input.length; this.pos++) {
6027 switch (this.input[this.pos]) {
6028 case "\\":
6029 ++this.pos;
6030 break
6031
6032 case "$":
6033 if (this.input[this.pos + 1] !== "{") { break }
6034 // fall through
6035 case "`":
6036 return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos))
6037
6038 case "\r":
6039 if (this.input[this.pos + 1] === "\n") { ++this.pos; }
6040 // fall through
6041 case "\n": case "\u2028": case "\u2029":
6042 ++this.curLine;
6043 this.lineStart = this.pos + 1;
6044 break
6045 }
6046 }
6047 this.raise(this.start, "Unterminated template");
6048};
6049
6050// Used to read escaped characters
6051
6052pp.readEscapedChar = function(inTemplate) {
6053 var ch = this.input.charCodeAt(++this.pos);
6054 ++this.pos;
6055 switch (ch) {
6056 case 110: return "\n" // 'n' -> '\n'
6057 case 114: return "\r" // 'r' -> '\r'
6058 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
6059 case 117: return codePointToString(this.readCodePoint()) // 'u'
6060 case 116: return "\t" // 't' -> '\t'
6061 case 98: return "\b" // 'b' -> '\b'
6062 case 118: return "\u000b" // 'v' -> '\u000b'
6063 case 102: return "\f" // 'f' -> '\f'
6064 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
6065 case 10: // ' \n'
6066 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
6067 return ""
6068 case 56:
6069 case 57:
6070 if (this.strict) {
6071 this.invalidStringToken(
6072 this.pos - 1,
6073 "Invalid escape sequence"
6074 );
6075 }
6076 if (inTemplate) {
6077 var codePos = this.pos - 1;
6078
6079 this.invalidStringToken(
6080 codePos,
6081 "Invalid escape sequence in template string"
6082 );
6083 }
6084 default:
6085 if (ch >= 48 && ch <= 55) {
6086 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
6087 var octal = parseInt(octalStr, 8);
6088 if (octal > 255) {
6089 octalStr = octalStr.slice(0, -1);
6090 octal = parseInt(octalStr, 8);
6091 }
6092 this.pos += octalStr.length - 1;
6093 ch = this.input.charCodeAt(this.pos);
6094 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
6095 this.invalidStringToken(
6096 this.pos - 1 - octalStr.length,
6097 inTemplate
6098 ? "Octal literal in template string"
6099 : "Octal literal in strict mode"
6100 );
6101 }
6102 return String.fromCharCode(octal)
6103 }
6104 if (isNewLine(ch)) {
6105 // Unicode new line characters after \ get removed from output in both
6106 // template literals and strings
6107 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
6108 return ""
6109 }
6110 return String.fromCharCode(ch)
6111 }
6112};
6113
6114// Used to read character escape sequences ('\x', '\u', '\U').
6115
6116pp.readHexChar = function(len) {
6117 var codePos = this.pos;
6118 var n = this.readInt(16, len);
6119 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
6120 return n
6121};
6122
6123// Read an identifier, and return it as a string. Sets `this.containsEsc`
6124// to whether the word contained a '\u' escape.
6125//
6126// Incrementally adds only escaped chars, adding other chunks as-is
6127// as a micro-optimization.
6128
6129pp.readWord1 = function() {
6130 this.containsEsc = false;
6131 var word = "", first = true, chunkStart = this.pos;
6132 var astral = this.options.ecmaVersion >= 6;
6133 while (this.pos < this.input.length) {
6134 var ch = this.fullCharCodeAtPos();
6135 if (isIdentifierChar(ch, astral)) {
6136 this.pos += ch <= 0xffff ? 1 : 2;
6137 } else if (ch === 92) { // "\"
6138 this.containsEsc = true;
6139 word += this.input.slice(chunkStart, this.pos);
6140 var escStart = this.pos;
6141 if (this.input.charCodeAt(++this.pos) !== 117) // "u"
6142 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
6143 ++this.pos;
6144 var esc = this.readCodePoint();
6145 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
6146 { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
6147 word += codePointToString(esc);
6148 chunkStart = this.pos;
6149 } else {
6150 break
6151 }
6152 first = false;
6153 }
6154 return word + this.input.slice(chunkStart, this.pos)
6155};
6156
6157// Read an identifier or keyword token. Will check for reserved
6158// words when necessary.
6159
6160pp.readWord = function() {
6161 var word = this.readWord1();
6162 var type = types$1.name;
6163 if (this.keywords.test(word)) {
6164 type = keywords[word];
6165 }
6166 return this.finishToken(type, word)
6167};
6168
6169// Acorn is a tiny, fast JavaScript parser written in JavaScript.
6170//
6171// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
6172// various contributors and released under an MIT license.
6173//
6174// Git repositories for Acorn are available at
6175//
6176// http://marijnhaverbeke.nl/git/acorn
6177// https://github.com/acornjs/acorn.git
6178//
6179// Please use the [github bug tracker][ghbt] to report issues.
6180//
6181// [ghbt]: https://github.com/acornjs/acorn/issues
6182
6183
6184var version = "8.15.0";
6185
6186Parser.acorn = {
6187 Parser: Parser,
6188 version: version,
6189 defaultOptions: defaultOptions,
6190 Position: Position,
6191 SourceLocation: SourceLocation,
6192 getLineInfo: getLineInfo,
6193 Node: Node,
6194 TokenType: TokenType,
6195 tokTypes: types$1,
6196 keywordTypes: keywords,
6197 TokContext: TokContext,
6198 tokContexts: types,
6199 isIdentifierChar: isIdentifierChar,
6200 isIdentifierStart: isIdentifierStart,
6201 Token: Token,
6202 isNewLine: isNewLine,
6203 lineBreak: lineBreak,
6204 lineBreakG: lineBreakG,
6205 nonASCIIwhitespace: nonASCIIwhitespace
6206};
6207
6208// The main exported interface (under `self.acorn` when in the
6209// browser) is a `parse` function that takes a code string and returns
6210// an abstract syntax tree as specified by the [ESTree spec][estree].
6211//
6212// [estree]: https://github.com/estree/estree
6213
6214function parse(input, options) {
6215 return Parser.parse(input, options)
6216}
6217
6218// This function tries to parse a single expression at a given
6219// offset in a string. Useful for parsing mixed-language formats
6220// that embed JavaScript expressions.
6221
6222function parseExpressionAt(input, pos, options) {
6223 return Parser.parseExpressionAt(input, pos, options)
6224}
6225
6226// Acorn is organized as a tokenizer and a recursive-descent parser.
6227// The `tokenizer` export provides an interface to the tokenizer.
6228
6229function tokenizer(input, options) {
6230 return Parser.tokenizer(input, options)
6231}
6232
6233export { Node, Parser, Position, SourceLocation, TokContext, Token, TokenType, defaultOptions, getLineInfo, isIdentifierChar, isIdentifierStart, isNewLine, keywords as keywordTypes, lineBreak, lineBreakG, nonASCIIwhitespace, parse, parseExpressionAt, types as tokContexts, types$1 as tokTypes, tokenizer, version };
vendor/acorn/dist/bin.js +90 -0
……@@ -0,0 +1,90 @@
1'use strict';
2
3var path = require('path');
4var fs = require('fs');
5var acorn = require('./acorn.js');
6
7function _interopNamespaceDefault(e) {
8 var n = Object.create(null);
9 if (e) {
10 Object.keys(e).forEach(function (k) {
11 if (k !== 'default') {
12 var d = Object.getOwnPropertyDescriptor(e, k);
13 Object.defineProperty(n, k, d.get ? d : {
14 enumerable: true,
15 get: function () { return e[k]; }
16 });
17 }
18 });
19 }
20 n.default = e;
21 return Object.freeze(n);
22}
23
24var acorn__namespace = /*#__PURE__*/_interopNamespaceDefault(acorn);
25
26var inputFilePaths = [], forceFileName = false, fileMode = false, silent = false, compact = false, tokenize = false;
27var options = {};
28
29function help(status) {
30 var print = (status === 0) ? console.log : console.error;
31 print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|...|--ecma2015|--ecma2016|--ecma2017|--ecma2018|...]");
32 print(" [--tokenize] [--locations] [--allow-hash-bang] [--allow-await-outside-function] [--compact] [--silent] [--module] [--help] [--] [<infile>...]");
33 process.exit(status);
34}
35
36for (var i = 2; i < process.argv.length; ++i) {
37 var arg = process.argv[i];
38 if (arg[0] !== "-" || arg === "-") { inputFilePaths.push(arg); }
39 else if (arg === "--") {
40 inputFilePaths.push.apply(inputFilePaths, process.argv.slice(i + 1));
41 forceFileName = true;
42 break
43 } else if (arg === "--locations") { options.locations = true; }
44 else if (arg === "--allow-hash-bang") { options.allowHashBang = true; }
45 else if (arg === "--allow-await-outside-function") { options.allowAwaitOutsideFunction = true; }
46 else if (arg === "--silent") { silent = true; }
47 else if (arg === "--compact") { compact = true; }
48 else if (arg === "--help") { help(0); }
49 else if (arg === "--tokenize") { tokenize = true; }
50 else if (arg === "--module") { options.sourceType = "module"; }
51 else {
52 var match = arg.match(/^--ecma(\d+)$/);
53 if (match)
54 { options.ecmaVersion = +match[1]; }
55 else
56 { help(1); }
57 }
58}
59
60function run(codeList) {
61 var result = [], fileIdx = 0;
62 try {
63 codeList.forEach(function (code, idx) {
64 fileIdx = idx;
65 if (!tokenize) {
66 result = acorn__namespace.parse(code, options);
67 options.program = result;
68 } else {
69 var tokenizer = acorn__namespace.tokenizer(code, options), token;
70 do {
71 token = tokenizer.getToken();
72 result.push(token);
73 } while (token.type !== acorn__namespace.tokTypes.eof)
74 }
75 });
76 } catch (e) {
77 console.error(fileMode ? e.message.replace(/\(\d+:\d+\)$/, function (m) { return m.slice(0, 1) + inputFilePaths[fileIdx] + " " + m.slice(1); }) : e.message);
78 process.exit(1);
79 }
80 if (!silent) { console.log(JSON.stringify(result, function (_, value) { return typeof value === "bigint" ? null : value; }, compact ? null : 2)); }
81}
82
83if (fileMode = inputFilePaths.length && (forceFileName || !inputFilePaths.includes("-") || inputFilePaths.length !== 1)) {
84 run(inputFilePaths.map(function (path) { return fs.readFileSync(path, "utf8"); }));
85} else {
86 var code = "";
87 process.stdin.resume();
88 process.stdin.on("data", function (chunk) { return code += chunk; });
89 process.stdin.on("end", function () { return run([code]); });
90}
vendor/acorn/package.json +50 -0
……@@ -0,0 +1,50 @@
1{
2 "name": "acorn",
3 "description": "ECMAScript parser",
4 "homepage": "https://github.com/acornjs/acorn",
5 "main": "dist/acorn.js",
6 "types": "dist/acorn.d.ts",
7 "module": "dist/acorn.mjs",
8 "exports": {
9 ".": [
10 {
11 "import": "./dist/acorn.mjs",
12 "require": "./dist/acorn.js",
13 "default": "./dist/acorn.js"
14 },
15 "./dist/acorn.js"
16 ],
17 "./package.json": "./package.json"
18 },
19 "version": "8.15.0",
20 "engines": {
21 "node": ">=0.4.0"
22 },
23 "maintainers": [
24 {
25 "name": "Marijn Haverbeke",
26 "email": "marijnh@gmail.com",
27 "web": "https://marijnhaverbeke.nl"
28 },
29 {
30 "name": "Ingvar Stepanyan",
31 "email": "me@rreverser.com",
32 "web": "https://rreverser.com/"
33 },
34 {
35 "name": "Adrian Heine",
36 "web": "http://adrianheine.de"
37 }
38 ],
39 "repository": {
40 "type": "git",
41 "url": "git+https://github.com/acornjs/acorn.git"
42 },
43 "license": "MIT",
44 "scripts": {
45 "prepare": "cd ..; npm run build:main"
46 },
47 "bin": {
48 "acorn": "bin/acorn"
49 }
50}
vendor/glsl-parser/README.md +633 -0
……@@ -0,0 +1,633 @@
1# Shaderfrog GLSL Compiler
2
3The [Shaderfrog](https://shaderfrog.com/app) GLSL compiler is an open source
4GLSL 1.00 and 3.00 parser and preprocessor that compiles [back to
5GLSL](src/parser/generator.ts). Both the parser and preprocessor can preserve
6comments and whitespace.
7
8The parser is built with a PEG grammar, via the [Peggy](https://peggyjs.org)
9Javascript library. The PEG grammars for both the preprocessor and parser
10are available [on Github](https://github.com/ShaderFrog/glsl-parser).
11
12See [the state of this library](#state-of-this-library) for limitations and
13goals of this compiler.
14
15# Table of Contents
16
17- [Installation](#installation)
18- [Parsing](#parsing)
19 - [The program type](#the-program-type)
20 - [Scope](#scope)
21 - [Errors](#errors)
22- [Preprocessing](#preprocessing)
23- [Manipulating and Searching ASTs](#manipulating-and-searching-asts)
24 - [Visitors](#visitors)
25 - [Utility Functions](#utility-functions)
26- [What are "parsing" and "preprocessing"?](#what-are-parsing-and-preprocessing)
27- [State of this library](#state-of-this-library)
28 - [Limitations of the Parser and Preprocessor](#limitations-of-the-parser-and-preprocessor)
29- [Local Development](#local-development)
30
31# Usage
32
33## Installation
34
35```bash
36npm install --save @shaderfrog/glsl-parser
37```
38
39## Parsing
40
41```typescript
42import { parse, generate } from '@shaderfrog/glsl-parser';
43
44// To parse a GLSL program's source code into an AST:
45const program = parse('float a = 1.0;');
46
47// To turn a parsed AST back into a source program
48const transpiled = generate(program);
49```
50
51The parser accepts an optional second `options` argument:
52```js
53parse('float a = 1.0;', options);
54```
55
56Where `options` is:
57
58```typescript
59type ParserOptions = {
60 // The stage of the GLSL source, which defines the built in variables when
61 // parsing, like gl_Position. If specified, when the compiler encounters an
62 // expected variable for that stage, it will continue on normally (and add
63 // that variable, like gl_Position, to the current scope). If it encounters an
64 // unknown variable, it will log a warning or raise an exception, depending
65 // on if `failOnWarn` is set. If the stage is set to 'either' - used in the
66 // case when you don't yet know what stage the GLSL is, the compiler *won't*
67 // warn on built-in variables for *either* stage. If this option is not set,
68 // the compiler will warn on *all* built-in variables it encounters as not
69 // defined.
70 stage: 'vertex' | 'fragment' | 'either';
71
72 // Hide warnings. If set to false or not set, then the parser logs warnings
73 // like undefined functions and variables. If `failOnWarn` is set to true,
74 // warnings will still cause the parser to raise an error. Defaults to false.
75 quiet?: boolean;
76
77 // If true, sets location information on each AST node, in the form of
78 // { column: number, line: number, offset: number }. Defaults to false.
79 includeLocation?: boolean;
80
81 // If true, causes the parser to raise an error instead of log a warning.
82 // The parser does limited type checking, and things like undeclared variables
83 // are treated as warnings. Defaults to false.
84 failOnWarn?: boolean;
85
86 // An optional string representing the file name of your GLSL For example,
87 // you can pass "main.glsl" here. If an error is raised, the error message
88 // will show "main.glsl:row:column". This is only used in the error message.
89 grammarSource?: string;
90}
91```
92
93## The program type
94`parse()` returns a `Program`, which is a special AST Node:
95
96```typescript
97interface Program {
98 // Hard coded AST node type of "program"
99 type: 'program';
100 // The AST itself is an array of the top level statements
101 program: AstNode[];
102 // All of the scopes found during parsing
103 scopes: Scope[];
104 // Leading whitespace of the source code
105 wsStart?: string;
106 // Trailing whitespace of the source code
107 wsEnd?: string;
108}
109```
110
111## Scope
112
113`parse()` returns a [`Program`](#the-program-type), which has a `scopes` array on it. A scope looks
114like:
115```typescript
116type Scope = {
117 name: string;
118 parent?: Scope;
119 bindings: ScopeIndex;
120 types: TypeScopeIndex;
121 functions: FunctionScopeIndex;
122 location?: LocationObject;
123}
124```
125
126The `name` of a scope is either `"global"`, the name of the function that
127introduced the scope, or in anonymous blocks, `"{"`. In each scope, `bindings` represents variables,
128`types` represents user-created types (structs in GLSL), and `functions` represents
129functions.
130
131For `bindings` and `types`, the scope index looks like:
132```typescript
133type ScopeIndex = {
134 [name: string]: {
135 declaration?: AstNode;
136 references: AstNode[];
137 }
138}
139```
140
141Where `name` is the name of the variable or type. `declaration` is the AST node
142where the variable was declared. In the case the variable is used without being
143declared, `declaration` won't be present. If you set the [`failOnWarn` parser
144option](#Parsing) to `true`, the parser will throw an error when encountering
145an undeclared variable, rather than allow a scope entry without a declaration.
146
147For `functions`, the scope index is slightly different:
148```typescript
149type FunctionScopeIndex = {
150 [name: string]: {
151 [signature: string]: {
152 returnType: string;
153 parameterTypes: string[];
154 declaration?: FunctionNode;
155 references: AstNode[];
156 }
157 }
158};
159```
160
161Where `name` is the name of the function, and `signature` is a string representing
162the function's return and parameter types, in the form of `"returnType: paramType1, paramType2, ..."`
163or `"returnType: void"` in the case of no arguments. Each `signature` in this
164index represents an "overloaded" function in GLSL, as in:
165
166```glsl
167void someFunction(int x) {};
168void someFunction(int x, int y) {};
169```
170
171With this source code, there will be two entries under `name`, one for each
172overload signature. The `references` are the uses of that specific overloaded
173version of the function. `references` also contains the function prototypes
174for the overloaded function, if present.
175
176In the case there is only one declaration for a function, there will still be
177a single entry under `name` with the function's `signature`.
178
179⚠️ Caution! This parser does very limited type checking. This leads to a known
180case where a function call can match to the wrong overload in scope:
181
182```glsl
183void someFunction(float, float);
184void someFunction(bool, bool);
185someFunction(true, true); // This will be attributed to the wrong scope entry
186```
187
188The parser doesn't know the type of the operands in the function call, so it
189matches based on the name and arity of the functions.
190
191See also [Utility-Functions](#Utility-Functions) for renaming scope references.
192
193## Errors
194
195If you have invalid GLSL, the parser throws a `GlslSyntaxError`.
196
197```ts
198import { parse, GlslSyntaxError } from '@shaderfrog/glsl-parser';
199
200let error: GlslSyntaxError | undefined;
201try {
202 // Line without a semicolon
203 parse(`float a`);
204} catch (e) {
205 error = e as GlslSyntaxError;
206}
207```
208
209If you want to check if a caught error is an `instanceof` a `GlslSyntaxError`:
210```ts
211console.log(error instanceof GlslSyntaxError)
212// true
213```
214
215The only error the parser intentionally throws is a `GlslSyntaxError`. You
216should be safe to cast it to a `GlslSyntaxError` with `as` in Typescript.
217
218The error message string is automatically generated by Peggy:
219```ts
220console.log(error.message)
221/*
222Error: Expected ",", ";", "=", or array specifier but "f" found.
223 --> undefined:2:1
224 |
2252 | float b
226 | ^
227*/
228```
229
230The error object includes the location of the error.
231
232```ts
233console.log(error.location)
234/*
235{
236 source: undefined,
237 start: { offset: 7, line: 1, column: 8 },
238 end: { offset: 7, line: 1, column: 8 }
239}
240*/
241```
242Note the `source` field on the error object is the `grammarSource` string
243provided to the parser options, which is `undefined` by default. If you pass in
244a `grammarSource` to `parse()`, it shows up in the error object. This is
245meant to help you track which source file you're parsing, for example you could
246enter `"myfile.glsl"` as an argument to `parse()` so that the error
247includes that your source GLSL came from your application's `myfile.glsl` file.
248
249## Preprocessing
250
251The parser also ships with a `preprocess()` function.
252
253The preprocessor takes in a program source code string and produces a
254preprocessed program source code string. If you want to access and manipulate
255the AST produced by preprocessing, see the next sections.
256
257```typescript
258import preprocess from '@shaderfrog/glsl-parser/preprocessor';
259
260// Preprocess a program
261console.log(preprocess(`
262 #define a 1
263 float b = a;
264`, options));
265```
266
267Where `options` is:
268
269```typescript
270type PreprocessorOptions = {
271 // Don't strip comments before preprocessing
272 preserveComments: boolean,
273 // Macro definitions to use when preprocessing
274 defines: {
275 SOME_MACRO_NAME: 'macro body'
276 },
277 // A list of callbacks evaluated for each node type, and returns whether or not
278 // this AST node is subject to preprocessing
279 preserve: {
280 ast_node_name: (path) => boolean
281 }
282}
283```
284
285A preprocessed program string can be handed off to the main GLSL parser.
286Preprocessing is optional, but a program string may not be valid until it is
287preprocessed.
288
289If you want more control over preprocessing, the `preprocess` function above is
290a convenience method for approximately the following:
291
292```typescript
293import {
294 preprocessAst,
295 preprocessComments,
296 generate,
297 parse,
298} from '@shaderfrog/glsl-parser/preprocessor';
299
300// Remove comments before preprocessing
301const commentsRemoved = preprocessComments(`float a = 1.0;`);
302
303// Parse the source text into an AST
304const ast = parse(commentsRemoved);
305
306// Then preprocess it, expanding #defines, evaluating #ifs, etc
307preprocessAst(ast);
308
309// Then convert it back into a program string, which can be passed to the
310// core glsl parser
311const preprocessed = generate(ast);
312```
313
314## Accessing the raw Peggy parser
315
316If you need to access the Peggy compiled parser directly, import the `parser`.
317You can manually call `parser.parse()` if you prefer. Note if there are errors,
318rather than returning a `GlslSyntaxError`, it will return the underlying
319`peg$syntaxError`.
320
321```typescript
322import { parser } from '@shaderfrog/glsl-parser';
323import { parser as preprocessorParser } from '@shaderfrog/glsl-parser/preprocessor';
324
325try {
326 const ast = parser.parse('float f = 1.0;');
327} catch (e) {
328 console.log(e instanceof parser.SyntaxError); // true
329}
330```
331
332## Manipulating and Searching ASTs
333
334### Visitors
335
336The Shaderfrog parser provides a AST visitor function for manipulating and
337searching an AST. The visitor API loosely follows the [Babel visitor API](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-visitors). A visitor object looks
338like:
339
340```typescript
341const visitors = {
342 function_call: {
343 enter: (path) => {},
344 exit: (path) => {},
345 }
346}
347```
348
349Where every key in the object is a node type, and every value is an object
350with optional `enter` and `exit` functions. What's passed to each function
351is **not** the AST node itself, instead it's a "path" object, which gives you
352information about the node's parents, methods to manipulate the node, and the
353node itself. The path object:
354
355```typescript
356{
357 // Properties:
358
359 // The node itself
360 node: AstNode;
361 // The parent of this node
362 parent: AstNode | null;
363 // The parent path of this path
364 parentPath: Path | null;
365 // The key of this node in the parent object, if node parent is an object
366 key: string | null;
367 // The index of this node in the parent array, if node parent is an array
368 index: number | null;
369
370 // Methods:
371
372 // Don't visit any children of this node
373 skip: () => void;
374 // Stop traversal entirely
375 stop: () => void;
376 // Remove this node from the AST
377 remove: () => void;
378 // Replace this node with another AST node. See replaceWith() documentation.
379 replaceWith: (replacer: any) => void;
380 // Search for parents of this node's parent using a test function
381 findParent: (test: (p: Path) => boolean) => Path | null;
382}
383```
384
385Visit an AST by calling the visit method with an AST and visitors:
386
387```typescript
388import { visit } from '@shaderfrog/glsl-parser/ast';
389
390visit(ast, visitors);
391```
392
393The visit function doesn't return a value. If you want to collect data from the
394AST, use a variable in the outer scope to collect data. For example:
395
396```typescript
397let numberOfFunctionCalls = 0;
398visit(ast, {
399 function_call: {
400 enter: (path) => {
401 numberOfFunctionCalls += 1;
402 },
403 }
404});
405console.log('There are ', numberOfFunctionCalls, 'function calls');
406```
407
408You can also visit the preprocessed AST with `visitPreprocessedAst`. Visitors
409follow the same convention outlined above.
410
411```typescript
412import {
413 parse,
414 visitPreprocessedAst,
415} from '@shaderfrog/glsl-parser/preprocessor';
416
417// Parse the source text into an AST
418const ast = parse(`float a = 1.0;`);
419visitPreprocessedAst(ast, visitors);
420```
421
422### Stopping traversal
423
424To skip all children of a node, call `path.skip()`.
425
426To stop traversal entirely, call `path.stop()` in either `enter()` or `exit()`.
427No future `enter()` nor `exit()` callbacks will fire.
428
429### Visitor `.replaceWith()` Behavior
430
431When you visit a node and call `path.replaceWith(otherNode)` inside the visitor's `enter()` method:
4321. `otherNode` and its children **are** visited by the same visitors.
4332. The `exit()` function of the visitor **is not called.**
434
435Notes:
436- Calling `.replaceWith()` in a visitor's `exit()` method is undefined behavior.
437- Replacing a node with the same type can cause infinite recursion, as the
438 visitor will continue to visit the replaced node of the same type. You must
439 handle this case manually.
440
441These rules apply to all visitors, both GLSL AST visitors and preprocessor AST
442visitors.
443
444### Utility Functions
445
446#### Rename variables / identifiers in a program
447
448You can rename bindings (aka variables), functions, and types (aka structs) with `renameBindings`, `renameFunctions`, and `renameTypes` respectively.
449
450The signature for these methods:
451
452```ts
453const renameBindings = (
454 // The scope to rename the bindings in. ast.scopes[0] is the global scope.
455 // Passing this ast.scopes[0] renames all global variables
456 bindings: ScopeIndex,
457
458 // The rename function. This is called once per scope entry with the original
459 // name in the scope, to generate the renamed variable.
460 mangle: (name: string) => string
461): ScopeIndex
462```
463
464These scope renaming functions, `renameBindings`, `renameFunctions`, and `renameTypes`, do two things:
4651. Each function *mutates* the AST to rename identifiers in place.
4662. They *return* an *immutable* new ScopeIndex where the scope references
467 themselves are renamed.
468
469If you want your ast.scopes array to stay in sync with your AST, you need to
470re-assign it to the output of the functions! Examples:
471
472```typescript
473import { renameBindings, renameFunctions, renameTypes } from '@shaderfrog/glsl-parser/parser/utils';
474
475// Suffix top level variables with _x, and update the scope
476ast.scopes[0].bindings = renameBindings(ast.scopes[0].bindings, (name) => `${name}_x`);
477
478// Suffix function names with _x
479ast.scopes[0].functions = renameFunctions(ast.scopes[0].functions, (name) => `${name}_x`);
480
481// Suffix struct names and usages (including constructors) with _x
482ast.scopes[0].types = renameTypes(ast.scopes[0].types, (name) => `${name}_x`);
483```
484
485There are also functions to rename only one variable/identifier in a given
486scope. Use these if you know specifically which variable you want to rename.
487
488```typescript
489import { renameBinding, renameFunction, renameType } from '@shaderfrog/glsl-parser/parser/utils';
490
491// Replace all instances of "oldVar" with "newVar" in the global scope, and
492// creates a new global scope entry named "newVar"
493ast.scopes[0].bindings.newVar = renameBinding(
494 ast.scopes[0].bindings.oldVar,
495 'newVar',
496);
497// You need to manually delete the old scope entry if you want the scope to stay
498// in sync with your program AST
499delete ast.scopes[0].bindings.oldVar;
500
501// Rename a specific function
502ast.scopes[0].functions.newFn = renameFunction(
503 ast.scopes[0].functions.oldFn,
504 'newFn',
505);
506delete ast.scopes[0].functions.oldFn;
507
508// Rename a specific type/struct
509ast.scopes[0].functions.newType = renametype(
510 ast.scopes[0].functions.oldType,
511 'newType',
512);
513delete ast.scopes[0].functions.oldType;
514```
515
516#### Debugging utility functions
517
518The parser also exports a debugging function, useful for logging information
519about the AST.
520
521```ts
522import { debugScopes } from '@shaderfrog/glsl-parser/parser/utils';
523
524// Print a condensed representation of the AST scopes to the console
525debugScopes(ast);
526```
527
528## What are "parsing" and "preprocessing"?
529
530In general, a parser is a computer program that analyzes source code and turn it
531into a data structure called an "abstract syntax tree" (AST). The AST is a tree
532representation of the source program, which can be analyzed or manipulated. A
533use of this GLSL parser could be to parse a program into an AST, find all
534variable names in the AST, rename them, and generate new GLSL source code with
535renamed variables.
536
537Preprocessing is a text manipulation step supported in shader source code. One
538way to think about preprocessing is it's a glorified find and replace language
539that's also part of your program's source code. Special lines starting with `#`
540tell the preprocessor how to manipulate other text in the program source code.
541Some programs are not parsable until they are preprocessed, because the source
542code may be invalid until the text find and replacements are done. During
543preprocessing, the source code is treated purely as text. Said another way,
544there is no consideration for the GLSL source code structure, like `float`,
545`vec2`, etc. Preprocessing only handles special lines and rules starting with
546`#`.
547
548See the [GLSL Langauge Spec](https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf) to learn more about GLSL preprocessing. Some notable
549differences from the C++ parser are no "stringize" operator (`#`), no `#include`
550operator, and `#if` expressions can only operate on integer constants, not other
551types of data. The Shaderfrog GLSL preprocessor can't be used as a C/C++
552preprocessor without modification.
553
554Parsing, preprocessing, and code generation, are all phases of a compiler. This
555library is technically a source code > source code compiler, also known as a
556"transpiler." The input and output source code are both GLSL.
557
558# State of this library
559
560The Shaderfrog compiler [has tests](parser/parse.test.ts) for the more complex
561parts of the GLSL ES 3.00 grammar. This library is definitively the most
562complete GLSL compiler written in **Javascript.**
563
564This library is used by the experimental [Shaderfrog 2.0 shader
565composer](https://twitter.com/andrewray/status/1558307538063437826). The
566compiler has wide expoure to different GLSL programs.
567
568This library also exposed:
569- [A typo](https://github.com/KhronosGroup/GLSL/issues/161) in the official GLSL grammar specification.
570- [A bug](https://bugs.chromium.org/p/angleproject/issues/detail?id=6338#c1) in Chrome's ANGLE compiler.
571
572This library doesn't support full "semantic analysis" required by the Khronos
573GLSL specification. For example, some tokens are only valid in GLSL 1.00 vs
5743.00, like `texture()` vs `texture2D()`. This parser considers both valid as
575they're both part of the grammar. However if you send compiled source code off
576to a native compiler like ANGLE with the wrong `texture` function, it will fail
577to compile.
578
579This library is mainly for manipulating ASTs before handing off a generated
580program to a downstream compilers like as ANGLE.
581
582The preprocessor supports full macro evaluations and expansions, with the
583exceptions of `__LINE__`. Additional control lines like `#error` and `#pragma`
584and `#extension` have no effect, and can be fully preserved as part of parsing.
585
586# Limitations of the Parser and Preprocessor
587
588## Known Issues
589
590- There's probably some bugs in the preprocessor logic. I haven't yet verified
591 all of the evaluations of "binary" expressions in `preprocessor.ts`
592- `preprocessor.ts` has lots of yucky typecasting
593
594## Known missing semantic analysis compared to the specification
595
596- Compilers are supposed to raise an error if a switch body ends in a case or
597 default label.
598- Currently no semantic analysis of vertex vs fragment shaders
599
600## Deviations from the Khronos Grammar
601
602- The parser allows for programs to contain top level preprocessor statements,
603 like `#define X`, as a convenience to avoid preprocessing some programs, and
604 for simple programs lets you preserve preprocessor lines in the AST if you
605 want to do something specific with them. However, preprocessor statements at
606 any other part of the program are not allowed. The Khronos grammar does not
607 include preprocessor statements.
608- `selection_statement` is renamed to `if_statement`
609- The grammar specifies `declaration` itself ends with a semicolon. I moved the
610 semicolon into the `declaration_statement` rule.
611- The grammar has a left paren "(" in the function_call production. Due to how
612 I de-left-recursed the function_call -> postfix_expression loop, I moved the
613 left paren into the function_identifier production.
614- Function calls in the grammar are TYPE_NAME LEFT_PAREN, in my grammar they're
615 IDENTIFIER LEFT_PAREN, because TYPE_NAME is only used for structs, and
616 function names are stored in their own separate place in the scope.
617
618# Local Development
619
620To work on the tests, run `npx jest --watch`.
621
622The GLSL grammar definition lives in `src/parser/glsl-grammar.pegjs`. Peggy
623supports inlining Javascript code in the `.pegjs` file to define utility
624functions, but that means you have to write in vanilla Javascript, which is
625terrible. Instead, I've pulled out utility functions into the `grammar.ts`
626entrypoint. Some functions need access to Peggy's local variables, like
627`location(s)`, so the `makeLocals()` function uses a closure to provide that
628access.
629
630To submit a change, please open a pull request. Tests are appreciated!
631
632See [the Github workflow](.github/workflows/main.yml) for the checks run against
633each PR.
vendor/glsl-parser/VENDOR.md +28 -0
……@@ -0,0 +1,28 @@
1# Vendored: @shaderfrog/glsl-parser
2
3- **Source**: https://www.npmjs.com/package/@shaderfrog/glsl-parser
4- **Homepage**: https://github.com/ShaderFrog/glsl-parser
5- **Version**: 7.0.1
6- **License**: ISC (per package.json; no LICENSE file ships with npm package — see homepage)
7- **Bundled**: Self-contained (zero dependencies)
8- **Bundle size**: 489 KB
9
10## Usage
11
12```js
13import { parse } from '../vendor/glsl-parser/glsl-parser.mjs'
14const ast = parse(source)
15// ast.program is the top-level array of declarations
16```
17
18Exports: `parser`, `generate`, `parse`, `GlslSyntaxError`
19
20## Regeneration
21
22```sh
23cd /tmp && mkdir -p codetree-vendor && cd codetree-vendor
24npm init -y && echo '{"type":"module"}' > package.json
25npm install @shaderfrog/glsl-parser esbuild
26echo "export { parser, generate, parse, GlslSyntaxError } from '@shaderfrog/glsl-parser'" > bundle.js
27./node_modules/.bin/esbuild bundle.js --bundle --format=esm --platform=neutral --outfile=glsl-parser.mjs
28```
vendor/glsl-parser/glsl-parser.mjs +14488 -0
……@@ -0,0 +1,14488 @@
1var __defProp = Object.defineProperty;
2var __export = (target, all) => {
3 for (var name in all)
4 __defProp(target, name, { get: all[name], enumerable: true });
5};
6
7// node_modules/@shaderfrog/glsl-parser/ast/ast.js
8var makeGenerator = function(generators2) {
9 var gen = function(ast) {
10 return typeof ast === "string" ? ast : ast === null || ast === void 0 ? "" : Array.isArray(ast) ? ast.map(gen).join("") : ast.type in generators2 ? generators2[ast.type](ast) : "NO GENERATOR FOR ".concat(ast.type) + ast;
11 };
12 return gen;
13};
14var makeEveryOtherGenerator = function(generate2) {
15 var everyOther = function(nodes, eo) {
16 return nodes.reduce(function(output, node, index) {
17 return output + generate2(node) + (index === nodes.length - 1 ? "" : generate2(eo[index]));
18 }, "");
19 };
20 return everyOther;
21};
22
23// node_modules/@shaderfrog/glsl-parser/parser/generator.js
24var generators = {
25 program: function(node) {
26 return generate(node.wsStart) + generate(node.program);
27 },
28 preprocessor: function(node) {
29 return generate(node.line) + generate(node._);
30 },
31 keyword: function(node) {
32 return generate(node.token) + generate(node.whitespace);
33 },
34 precision: function(node) {
35 return generate(node.prefix) + generate(node.qualifier) + generate(node.specifier);
36 },
37 // Statements
38 expression_statement: function(node) {
39 return generate(node.expression) + generate(node.semi);
40 },
41 if_statement: function(node) {
42 return generate(node.if) + generate(node.lp) + generate(node.condition) + generate(node.rp) + generate(node.body) + generate(node.else);
43 },
44 switch_statement: function(node) {
45 return generate(node.switch) + generate(node.lp) + generate(node.expression) + generate(node.rp) + generate(node.lb) + generate(node.cases) + generate(node.rb);
46 },
47 break_statement: function(node) {
48 return generate(node.break) + generate(node.semi);
49 },
50 do_statement: function(node) {
51 return generate(node.do) + generate(node.body) + generate(node.while) + generate(node.lp) + generate(node.expression) + generate(node.rp) + generate(node.semi);
52 },
53 continue_statement: function(node) {
54 return generate(node.continue) + generate(node.semi);
55 },
56 return_statement: function(node) {
57 return generate(node.return) + generate(node.expression) + generate(node.semi);
58 },
59 discard_statement: function(node) {
60 return generate(node.discard) + generate(node.semi);
61 },
62 while_statement: function(node) {
63 return generate(node.while) + generate(node.lp) + generate(node.condition) + generate(node.rp) + generate(node.body);
64 },
65 for_statement: function(node) {
66 return generate(node.for) + generate(node.lp) + generate(node.init) + generate(node.initSemi) + generate(node.condition) + generate(node.conditionSemi) + generate(node.operation) + generate(node.rp) + generate(node.body);
67 },
68 condition_expression: function(node) {
69 return generate(node.specified_type) + generate(node.identifier) + generate(node.operator) + generate(node.initializer);
70 },
71 declaration_statement: function(node) {
72 return generate(node.declaration) + generate(node.semi);
73 },
74 fully_specified_type: function(node) {
75 return generate(node.qualifiers) + generate(node.specifier);
76 },
77 layout_qualifier: function(node) {
78 return generate(node.layout) + generate(node.lp) + generateWithEveryOther(node.qualifiers, node.commas) + generate(node.rp);
79 },
80 layout_qualifier_id: function(node) {
81 return generate(node.identifier) + generate(node.operator) + generate(node.expression);
82 },
83 switch_case: function(node) {
84 return generate(node.case) + generate(node.test) + generate(node.colon) + generate(node.statements);
85 },
86 default_case: function(node) {
87 return generate(node.default) + generate(node.colon) + generate(node.statements);
88 },
89 declaration: function(node) {
90 return generate(node.identifier) + generate(node.quantifier) + generate(node.equal) + generate(node.initializer);
91 },
92 declarator_list: function(node) {
93 return generate(node.specified_type) + generateWithEveryOther(node.declarations, node.commas);
94 },
95 type_specifier: function(node) {
96 return generate(node.specifier) + generate(node.quantifier);
97 },
98 array_specifier: function(node) {
99 return generate(node.lb) + generate(node.expression) + generate(node.rb);
100 },
101 identifier: function(node) {
102 return node.identifier + generate(node.whitespace);
103 },
104 type_name: function(node) {
105 return node.identifier + generate(node.whitespace);
106 },
107 function_header: function(node) {
108 return generate(node.returnType) + generate(node.name) + generate(node.lp);
109 },
110 function_prototype: function(node) {
111 return generate(node.header.returnType) + generate(node.header.name) + generate(node.header.lp) + (node.parameters ? generateWithEveryOther(node.parameters, node.commas) : "") + generate(node.rp);
112 },
113 parameter_declaration: function(node) {
114 return generate(node.qualifier) + generate(node.specifier) + generate(node.identifier) + generate(node.quantifier);
115 },
116 compound_statement: function(node) {
117 return generate(node.lb) + generate(node.statements) + generate(node.rb);
118 },
119 function: function(node) {
120 return generate(node["prototype"]) + generate(node.body);
121 },
122 function_call: function(node) {
123 return generate(node.identifier) + generate(node.lp) + generate(node.args) + generate(node.rp);
124 },
125 postfix: function(node) {
126 return generate(node.expression) + generate(node.postfix);
127 },
128 quantifier: function(node) {
129 return generate(node.lb) + generate(node.expression) + generate(node.rb);
130 },
131 quantified_identifier: function(node) {
132 return generate(node.identifier) + generate(node.quantifier);
133 },
134 field_selection: function(node) {
135 return generate(node.dot) + generate(node.selection);
136 },
137 subroutine_qualifier: function(node) {
138 return generate(node.subroutine) + generate(node.lp) + generate(node.type_names) + generate(node.commas) + generate(node.rp);
139 },
140 assignment: function(node) {
141 return generate(node.left) + generate(node.operator) + generate(node.right);
142 },
143 ternary: function(node) {
144 return generate(node.expression) + generate(node.question) + generate(node.left) + generate(node.colon) + generate(node.right);
145 },
146 binary: function(node) {
147 return generate(node.left) + generate(node.operator) + generate(node.right);
148 },
149 group: function(node) {
150 return generate(node.lp) + generate(node.expression) + generate(node.rp);
151 },
152 unary: function(node) {
153 return generate(node.operator) + generate(node.expression);
154 },
155 float_constant: function(node) {
156 return generate(node.token) + generate(node.whitespace);
157 },
158 double_constant: function(node) {
159 return generate(node.token) + generate(node.whitespace);
160 },
161 int_constant: function(node) {
162 return generate(node.token) + generate(node.whitespace);
163 },
164 uint_constant: function(node) {
165 return generate(node.token) + generate(node.whitespace);
166 },
167 bool_constant: function(node) {
168 return generate(node.token) + generate(node.whitespace);
169 },
170 literal: function(node) {
171 return generate(node.literal) + generate(node.whitespace);
172 },
173 struct: function(node) {
174 return generate(node.struct) + generate(node.typeName) + generate(node.lb) + generate(node.declarations) + generate(node.rb);
175 },
176 struct_declaration: function(node) {
177 return generate(node.declaration) + generate(node.semi);
178 },
179 interface_declarator: function(node) {
180 return generate(node.qualifiers) + generate(node.interface_type) + generate(node.lp) + generate(node.declarations) + generate(node.rp) + generate(node.identifier);
181 },
182 struct_declarator: function(node) {
183 return generate(node.specified_type) + generateWithEveryOther(node.declarations, node.commas);
184 },
185 initializer_list: function(node) {
186 return generate(node.lb) + generateWithEveryOther(node.initializers, node.commas) + generate(node.rb);
187 },
188 qualifier_declarator: function(node) {
189 return generate(node.qualifiers) + generateWithEveryOther(node.declarations, node.commas);
190 }
191};
192var generate = makeGenerator(generators);
193var generateWithEveryOther = makeEveryOtherGenerator(generate);
194var generator_default = generate;
195
196// node_modules/@shaderfrog/glsl-parser/parser/parser.js
197var parser_exports = {};
198__export(parser_exports, {
199 SyntaxError: () => peg$SyntaxError,
200 parse: () => peg$parse
201});
202
203// node_modules/@shaderfrog/glsl-parser/parser/utils.js
204var xor = function(a, b) {
205 return (a || b) && !(a && b);
206};
207
208// node_modules/@shaderfrog/glsl-parser/parser/scope.js
209var __spreadArray = function(to, from, pack) {
210 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
211 if (ar || !(i in from)) {
212 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
213 ar[i] = from[i];
214 }
215 }
216 return to.concat(ar || Array.prototype.slice.call(from));
217};
218var UNKNOWN_TYPE = "UNKNOWN TYPE";
219var makeScopeIndex = function(firstReference, declaration) {
220 return {
221 declaration,
222 references: [firstReference]
223 };
224};
225var findTypeScope = function(scope, typeName) {
226 if (!scope) {
227 return null;
228 }
229 if (typeName in scope.types) {
230 return scope;
231 }
232 return findTypeScope(scope.parent, typeName);
233};
234var isDeclaredType = function(scope, typeName) {
235 return findTypeScope(scope, typeName) !== null;
236};
237var findBindingScope = function(scope, name) {
238 if (!scope) {
239 return null;
240 }
241 if (name in scope.bindings) {
242 return scope;
243 }
244 return findBindingScope(scope.parent, name);
245};
246var extractConstant = function(expression) {
247 var result = UNKNOWN_TYPE;
248 if ("token" in expression) {
249 result = expression.token;
250 } else if ("identifier" in expression && typeof expression.identifier === "string") {
251 result = expression.identifier;
252 } else {
253 console.warn(result, expression);
254 }
255 return result;
256};
257var quantifiersSignature = function(quantifier) {
258 return quantifier.map(function(q) {
259 return "[".concat(extractConstant(q.expression), "]");
260 }).join("");
261};
262var functionDeclarationSignature = function(node) {
263 var _a;
264 var proto = node.type === "function" ? node.prototype : node;
265 var specifier = proto.header.returnType.specifier;
266 var quantifiers = specifier.quantifier || [];
267 var parameterTypes = ((_a = proto === null || proto === void 0 ? void 0 : proto.parameters) === null || _a === void 0 ? void 0 : _a.map(function(_a2) {
268 var specifier2 = _a2.specifier, quantifier = _a2.quantifier;
269 var quantifiers2 = (
270 // vec4[1][2] param
271 specifier2.quantifier || // vec4 param[1][3]
272 quantifier || []
273 );
274 return "".concat(extractConstant(specifier2.specifier)).concat(quantifiersSignature(quantifiers2));
275 })) || ["void"];
276 var returnType = "".concat(specifier.specifier.token).concat(quantifiersSignature(quantifiers));
277 return [
278 returnType,
279 parameterTypes,
280 "".concat(returnType, ": ").concat(parameterTypes.join(", "))
281 ];
282};
283var doSignaturesMatch = function(definitionSignature, definition, callSignature) {
284 if (definitionSignature === callSignature[0]) {
285 return true;
286 }
287 var left = __spreadArray([definition.returnType], definition.parameterTypes, true);
288 var right = __spreadArray([callSignature[0]], callSignature[1], true);
289 if (left.length === 2 && xor(left[1] === "void", right[1] === "void")) {
290 return false;
291 }
292 return left.length === right.length && left.every(function(type, index) {
293 return type === right[index] || type === UNKNOWN_TYPE || right[index] === UNKNOWN_TYPE;
294 });
295};
296var findOverloadDefinition = function(signature, index) {
297 return Object.entries(index).reduce(function(found, _a) {
298 var overloadSignature = _a[0], overloadDefinition = _a[1];
299 return found || (doSignaturesMatch(overloadSignature, overloadDefinition, signature) ? overloadDefinition : void 0);
300 }, void 0);
301};
302var functionUseSignature = function(node) {
303 var parameterTypes = node.args.length === 0 ? ["void"] : node.args.filter(function(arg) {
304 return arg.literal !== ",";
305 }).map(function() {
306 return UNKNOWN_TYPE;
307 });
308 var returnType = UNKNOWN_TYPE;
309 return [
310 returnType,
311 parameterTypes,
312 "".concat(returnType, ": ").concat(parameterTypes.join(", "))
313 ];
314};
315var newOverloadIndex = function(returnType, parameterTypes, firstReference, declaration) {
316 return {
317 returnType,
318 parameterTypes,
319 declaration,
320 references: [firstReference]
321 };
322};
323var findGlobalScope = function(scope) {
324 return scope.parent ? findGlobalScope(scope.parent) : scope;
325};
326var isDeclaredFunction = function(scope, fnName) {
327 return fnName in findGlobalScope(scope).functions;
328};
329
330// node_modules/@shaderfrog/glsl-parser/parser/grammar.js
331var __assign = function() {
332 __assign = Object.assign || function(t) {
333 for (var s, i = 1, n = arguments.length; i < n; i++) {
334 s = arguments[i];
335 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
336 t[p] = s[p];
337 }
338 return t;
339 };
340 return __assign.apply(this, arguments);
341};
342var __spreadArray2 = function(to, from, pack) {
343 if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
344 if (ar || !(i in from)) {
345 if (!ar) ar = Array.prototype.slice.call(from, 0, i);
346 ar[i] = from[i];
347 }
348 }
349 return to.concat(ar || Array.prototype.slice.call(from));
350};
351var partial = function(typeNameOrAttrs, attrs) {
352 return {
353 partial: attrs === void 0 ? typeNameOrAttrs : __assign({ type: typeNameOrAttrs }, attrs)
354 };
355};
356var xnil = function() {
357 var args = [];
358 for (var _i = 0; _i < arguments.length; _i++) {
359 args[_i] = arguments[_i];
360 }
361 return args.flat().filter(function(e) {
362 return e !== void 0 && e !== null && e !== "" && e.length !== 0;
363 });
364};
365var ifOnly = function(arr) {
366 return arr.length > 1 ? arr : arr[0];
367};
368var collapse = function() {
369 var args = [];
370 for (var _i = 0; _i < arguments.length; _i++) {
371 args[_i] = arguments[_i];
372 }
373 return ifOnly(xnil(args));
374};
375var leftAssociate = function(head) {
376 var tail = [];
377 for (var _i = 1; _i < arguments.length; _i++) {
378 tail[_i - 1] = arguments[_i];
379 }
380 return tail.flat().reduce(function(left, _a) {
381 var operator = _a[0], right = _a[1];
382 return {
383 type: "binary",
384 operator,
385 left,
386 right
387 };
388 }, head);
389};
390var BUILT_INS = {
391 vertex: /* @__PURE__ */ new Set([
392 "gl_VertexID",
393 "gl_InstanceID",
394 "gl_DrawID",
395 "gl_BaseVertex",
396 "gl_BaseInstance",
397 "gl_Position",
398 "gl_PointSize",
399 "gl_ClipDistance"
400 ]),
401 fragment: /* @__PURE__ */ new Set([
402 "gl_FragColor",
403 "gl_FragData",
404 "gl_FragCoord",
405 "gl_FrontFacing",
406 "gl_PointCoord",
407 "gl_SampleID",
408 "gl_SamplePosition",
409 "gl_SampleMaskIn",
410 "gl_ClipDistance",
411 "gl_PrimitiveID",
412 "gl_Layer",
413 "gl_ViewportIndex",
414 "gl_FragDepth",
415 "gl_SampleMask"
416 ])
417};
418var FN_BUILT_INS = /* @__PURE__ */ new Set([
419 "abs",
420 "acos",
421 "acosh",
422 "all",
423 "any",
424 "asin",
425 "asinh",
426 "atan",
427 "atanh",
428 "atomicAdd",
429 "atomicAnd",
430 "atomicCompSwap",
431 "atomicCounter",
432 "atomicCounterDecrement",
433 "atomicCounterIncrement",
434 "atomicExchange",
435 "atomicMax",
436 "atomicMin",
437 "atomicOr",
438 "atomicXor",
439 "barrier",
440 "bitCount",
441 "bitfieldExtract",
442 "bitfieldInsert",
443 "bitfieldReverse",
444 "ceil",
445 "clamp",
446 "cos",
447 "cosh",
448 "cross",
449 "degrees",
450 "determinant",
451 "dFdx",
452 "dFdxCoarse",
453 "dFdxFine",
454 "dFdy",
455 "dFdyCoarse",
456 "dFdyFine",
457 "distance",
458 "dot",
459 "EmitStreamVertex",
460 "EmitVertex",
461 "EndPrimitive",
462 "EndStreamPrimitive",
463 "equal",
464 "exp",
465 "exp2",
466 "faceforward",
467 "findLSB",
468 "findMSB",
469 "floatBitsToInt",
470 "floatBitsToUint",
471 "floor",
472 "fma",
473 "fract",
474 "frexp",
475 "fwidth",
476 "fwidthCoarse",
477 "fwidthFine",
478 "greaterThan",
479 "greaterThanEqual",
480 "groupMemoryBarrier",
481 "imageAtomicAdd",
482 "imageAtomicAnd",
483 "imageAtomicCompSwap",
484 "imageAtomicExchange",
485 "imageAtomicMax",
486 "imageAtomicMin",
487 "imageAtomicOr",
488 "imageAtomicXor",
489 "imageLoad",
490 "imageSamples",
491 "imageSize",
492 "imageStore",
493 "imulExtended",
494 "intBitsToFloat",
495 "interpolateAtCentroid",
496 "interpolateAtOffset",
497 "interpolateAtSample",
498 "inverse",
499 "inversesqrt",
500 "isinf",
501 "isnan",
502 "ldexp",
503 "length",
504 "lessThan",
505 "lessThanEqual",
506 "log",
507 "log2",
508 "matrixCompMult",
509 "max",
510 "memoryBarrier",
511 "memoryBarrierAtomicCounter",
512 "memoryBarrierBuffer",
513 "memoryBarrierImage",
514 "memoryBarrierShared",
515 "min",
516 "mix",
517 "mod",
518 "modf",
519 "noise",
520 "noise1",
521 "noise2",
522 "noise3",
523 "noise4",
524 "normalize",
525 "not",
526 "notEqual",
527 "outerProduct",
528 "packDouble2x32",
529 "packHalf2x16",
530 "packSnorm2x16",
531 "packSnorm4x8",
532 "packUnorm",
533 "packUnorm2x16",
534 "packUnorm4x8",
535 "pow",
536 "radians",
537 "reflect",
538 "refract",
539 "round",
540 "roundEven",
541 "sign",
542 "sin",
543 "sinh",
544 "smoothstep",
545 "sqrt",
546 "step",
547 "tan",
548 "tanh",
549 "texelFetch",
550 "texelFetchOffset",
551 "texture",
552 "textureGather",
553 "textureGatherOffset",
554 "textureGatherOffsets",
555 "textureGrad",
556 "textureGradOffset",
557 "textureLod",
558 "textureLodOffset",
559 "textureOffset",
560 "textureProj",
561 "textureProjGrad",
562 "textureProjGradOffset",
563 "textureProjLod",
564 "textureProjLodOffset",
565 "textureProjOffset",
566 "textureQueryLevels",
567 "textureQueryLod",
568 "textureSamples",
569 "textureSize",
570 "transpose",
571 "trunc",
572 "uaddCarry",
573 "uintBitsToFloat",
574 "umulExtended",
575 "unpackDouble2x32",
576 "unpackHalf2x16",
577 "unpackSnorm2x16",
578 "unpackSnorm4x8",
579 "unpackUnorm",
580 "unpackUnorm2x16",
581 "unpackUnorm4x8",
582 "usubBorrow",
583 // GLSL ES 1.00
584 "texture2D",
585 "textureCube"
586]);
587var makeLocals = function(context) {
588 var getLocation = function(loc) {
589 if (!context.options.includeLocation) {
590 return;
591 }
592 var _a = loc || context.location(), start = _a.start, end = _a.end;
593 return { start, end };
594 };
595 var node = function(type, attrs) {
596 var n = __assign({ type }, attrs);
597 if (context.options.includeLocation) {
598 n.location = getLocation();
599 }
600 return n;
601 };
602 var makeScope = function(name, parent, startLocation) {
603 var newLocation = getLocation(startLocation);
604 return __assign(__assign({ name, parent }, newLocation ? { location: newLocation } : false), { bindings: {}, types: {}, functions: {} });
605 };
606 var warn = function(message) {
607 if (context.options.failOnWarn) {
608 throw new Error(message);
609 }
610 if (!context.options.quiet) {
611 console.warn(message);
612 }
613 };
614 var pushScope = function(scope) {
615 context.scopes.push(scope);
616 return scope;
617 };
618 var popScope = function(scope) {
619 if (!scope.parent) {
620 throw new Error("Popped bad scope ".concat(scope, " at ").concat(context.text()));
621 }
622 return scope.parent;
623 };
624 var setScopeEnd = function(scope, end) {
625 if (context.options.includeLocation) {
626 if (!scope.location) {
627 console.error("No end location at ".concat(context.text()));
628 } else {
629 scope.location.end = end;
630 }
631 }
632 };
633 var addFunctionCallReference = function(scope, name, fnRef) {
634 var _a;
635 var global = findGlobalScope(scope);
636 var signature = functionUseSignature(fnRef);
637 if (!global.functions[name]) {
638 warn('Encountered undeclared function: "'.concat(name, '" with signature "').concat(signature[2], '"'));
639 global.functions[name] = (_a = {}, _a[signature[2]] = newOverloadIndex(signature[0], signature[1], fnRef), _a);
640 } else {
641 var existingOverload = findOverloadDefinition(signature, global.functions[name]);
642 if (!existingOverload) {
643 warn('No matching overload for function: "'.concat(name, '" with signature "').concat(signature[2], '"'));
644 global.functions[name][signature[2]] = newOverloadIndex(signature[0], signature[1], fnRef);
645 } else {
646 existingOverload.references.push(fnRef);
647 }
648 }
649 };
650 var createFunctionDefinition = function(scope, name, fnRef) {
651 var global = findGlobalScope(scope);
652 var signature = functionDeclarationSignature(fnRef);
653 if (!global.functions[name]) {
654 global.functions[name] = {};
655 }
656 var existing = global.functions[name][signature[2]];
657 if (existing) {
658 if (existing.declaration) {
659 warn('Encountered duplicate function definition: "'.concat(name, '" with signature "').concat(signature[2], '"'));
660 } else {
661 existing.declaration = fnRef;
662 }
663 existing.references.push(fnRef);
664 } else {
665 global.functions[name][signature[2]] = newOverloadIndex(signature[0], signature[1], fnRef);
666 global.functions[name][signature[2]].declaration = fnRef;
667 }
668 };
669 var createFunctionPrototype = function(scope, name, fnRef) {
670 var global = findGlobalScope(scope);
671 var signature = functionDeclarationSignature(fnRef);
672 if (!global.functions[name]) {
673 global.functions[name] = {};
674 }
675 var existing = global.functions[name][signature[2]];
676 if (existing) {
677 warn('Encountered duplicate function prototype: "'.concat(name, '" with signature "').concat(signature[2], '"'));
678 existing.references.push(fnRef);
679 } else {
680 global.functions[name][signature[2]] = newOverloadIndex(signature[0], signature[1], fnRef);
681 }
682 };
683 var addTypeReference = function(scope, name, reference) {
684 var declaredScope = findTypeScope(scope, name);
685 if (declaredScope) {
686 declaredScope.types[name].references.push(reference);
687 } else {
688 warn('Encountered undeclared type: "'.concat(name, '"'));
689 scope.types[name] = {
690 references: [reference]
691 };
692 }
693 };
694 var createType = function(scope, name, declaration) {
695 if (name in scope.types) {
696 if (scope.types[name].declaration) {
697 warn('Encountered duplicate type declaration: "'.concat(name, '"'));
698 } else {
699 warn('Type "'.concat(name, '" was used before it was declared'));
700 scope.types[name].declaration = declaration;
701 }
702 scope.types[name].references.push(declaration);
703 } else {
704 scope.types[name] = {
705 declaration,
706 references: [declaration]
707 };
708 }
709 };
710 var addTypeIfFound = function(scope, node2) {
711 var _a;
712 var specifier = node2.type === "fully_specified_type" ? (_a = node2 === null || node2 === void 0 ? void 0 : node2.specifier) === null || _a === void 0 ? void 0 : _a.specifier : node2 === null || node2 === void 0 ? void 0 : node2.specifier;
713 if (specifier.type === "type_name") {
714 var name = specifier.identifier;
715 addTypeReference(scope, name, specifier);
716 } else if (specifier.type !== "struct" && specifier.type !== "keyword") {
717 console.warn("Unknown specifier", specifier);
718 throw new Error("Unknown declarator specifier ".concat(specifier === null || specifier === void 0 ? void 0 : specifier.type, ". Please file a bug against @shaderfrog/glsl-parser and incldue your source grammar."));
719 }
720 };
721 var createBindings = function(scope) {
722 var bindings = [];
723 for (var _i = 1; _i < arguments.length; _i++) {
724 bindings[_i - 1] = arguments[_i];
725 }
726 bindings.forEach(function(_a) {
727 var identifier = _a[0], binding = _a[1];
728 var existing = scope.bindings[identifier];
729 if (existing) {
730 warn('Encountered duplicate variable declaration: "'.concat(identifier, '"'));
731 existing.references.unshift(binding);
732 } else {
733 scope.bindings[identifier] = makeScopeIndex(binding, binding);
734 }
735 });
736 };
737 var addOrCreateBindingReference = function(scope, name, reference) {
738 var foundScope = findBindingScope(scope, name);
739 if (foundScope) {
740 foundScope.bindings[name].references.push(reference);
741 } else {
742 if (!context.options.stage || context.options.stage === "vertex" && !BUILT_INS.vertex.has(name) || context.options.stage === "fragment" && !BUILT_INS.fragment.has(name) || context.options.stage === "either" && !BUILT_INS.vertex.has(name) && !BUILT_INS.fragment) {
743 warn('Encountered undefined variable: "'.concat(name, '"'));
744 }
745 scope.bindings[name] = makeScopeIndex(reference);
746 }
747 };
748 var groupCases = function(statements) {
749 return statements.reduce(function(cases, stmt) {
750 var partial2 = "partial" in stmt ? stmt.partial : {};
751 if (partial2.type === "case_label") {
752 return __spreadArray2(__spreadArray2([], cases, true), [
753 node("switch_case", {
754 statements: [],
755 case: partial2.case,
756 test: partial2.test,
757 colon: partial2.colon
758 })
759 ], false);
760 } else if (partial2.type === "default_label") {
761 return __spreadArray2(__spreadArray2([], cases, true), [
762 node("default_case", {
763 statements: [],
764 default: partial2.default,
765 colon: partial2.colon
766 })
767 ], false);
768 } else if (!cases.length) {
769 throw new Error("A switch statement body must start with a case or default label");
770 } else {
771 var tail = cases.slice(-1)[0];
772 return __spreadArray2(__spreadArray2([], cases.slice(0, -1), true), [
773 __assign(__assign({}, tail), { statements: __spreadArray2(__spreadArray2([], tail.statements, true), [stmt], false) })
774 ], false);
775 }
776 }, []);
777 };
778 context.scope = makeScope("global");
779 context.scopes = [context.scope];
780 return {
781 getLocation,
782 node,
783 makeScope,
784 warn,
785 pushScope,
786 popScope,
787 setScopeEnd,
788 createFunctionDefinition,
789 addFunctionCallReference,
790 createFunctionPrototype,
791 groupCases,
792 addTypeReference,
793 addTypeIfFound,
794 createType,
795 createBindings,
796 addOrCreateBindingReference
797 };
798};
799
800// node_modules/@shaderfrog/glsl-parser/parser/parser.js
801var OPEN_CURLY = String.fromCharCode(123);
802function peg$subclass(child, parent) {
803 function C() {
804 this.constructor = child;
805 }
806 C.prototype = parent.prototype;
807 child.prototype = new C();
808}
809function peg$SyntaxError(message, expected, found, location) {
810 var self = Error.call(this, message);
811 if (Object.setPrototypeOf) {
812 Object.setPrototypeOf(self, peg$SyntaxError.prototype);
813 }
814 self.expected = expected;
815 self.found = found;
816 self.location = location;
817 self.name = "SyntaxError";
818 return self;
819}
820peg$subclass(peg$SyntaxError, Error);
821function peg$padEnd(str, targetLength, padString) {
822 padString = padString || " ";
823 if (str.length > targetLength) {
824 return str;
825 }
826 targetLength -= str.length;
827 padString += padString.repeat(targetLength);
828 return str + padString.slice(0, targetLength);
829}
830peg$SyntaxError.prototype.format = function(sources) {
831 var str = "Error: " + this.message;
832 if (this.location) {
833 var src = null;
834 var k;
835 for (k = 0; k < sources.length; k++) {
836 if (sources[k].source === this.location.source) {
837 src = sources[k].text.split(/\r\n|\n|\r/g);
838 break;
839 }
840 }
841 var s = this.location.start;
842 var loc = this.location.source + ":" + s.line + ":" + s.column;
843 if (src) {
844 var e = this.location.end;
845 var filler = peg$padEnd("", s.line.toString().length);
846 var line = src[s.line - 1];
847 var last = s.line === e.line ? e.column : line.length + 1;
848 str += "\n --> " + loc + "\n" + filler + " |\n" + s.line + " | " + line + "\n" + filler + " | " + peg$padEnd("", s.column - 1) + peg$padEnd("", last - s.column, "^");
849 } else {
850 str += "\n at " + loc;
851 }
852 }
853 return str;
854};
855peg$SyntaxError.buildMessage = function(expected, found) {
856 var DESCRIBE_EXPECTATION_FNS = {
857 literal: function(expectation) {
858 return '"' + literalEscape(expectation.text) + '"';
859 },
860 class: function(expectation) {
861 var escapedParts = expectation.parts.map(function(part) {
862 return Array.isArray(part) ? classEscape(part[0]) + "-" + classEscape(part[1]) : classEscape(part);
863 });
864 return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
865 },
866 any: function() {
867 return "any character";
868 },
869 end: function() {
870 return "end of input";
871 },
872 other: function(expectation) {
873 return expectation.description;
874 }
875 };
876 function hex(ch) {
877 return ch.charCodeAt(0).toString(16).toUpperCase();
878 }
879 function literalEscape(s) {
880 return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
881 return "\\x0" + hex(ch);
882 }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
883 return "\\x" + hex(ch);
884 });
885 }
886 function classEscape(s) {
887 return s.replace(/\\/g, "\\\\").replace(/\]/g, "\\]").replace(/\^/g, "\\^").replace(/-/g, "\\-").replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
888 return "\\x0" + hex(ch);
889 }).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
890 return "\\x" + hex(ch);
891 });
892 }
893 function describeExpectation(expectation) {
894 return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
895 }
896 function describeExpected(expected2) {
897 var descriptions = expected2.map(describeExpectation);
898 var i, j;
899 descriptions.sort();
900 if (descriptions.length > 0) {
901 for (i = 1, j = 1; i < descriptions.length; i++) {
902 if (descriptions[i - 1] !== descriptions[i]) {
903 descriptions[j] = descriptions[i];
904 j++;
905 }
906 }
907 descriptions.length = j;
908 }
909 switch (descriptions.length) {
910 case 1:
911 return descriptions[0];
912 case 2:
913 return descriptions[0] + " or " + descriptions[1];
914 default:
915 return descriptions.slice(0, -1).join(", ") + ", or " + descriptions[descriptions.length - 1];
916 }
917 }
918 function describeFound(found2) {
919 return found2 ? '"' + literalEscape(found2) + '"' : "end of input";
920 }
921 return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
922};
923function peg$parse(input, options) {
924 options = options !== void 0 ? options : {};
925 var peg$FAILED = {};
926 var peg$source = options.grammarSource;
927 var peg$startRuleFunctions = { start: peg$parsestart };
928 var peg$startRuleFunction = peg$parsestart;
929 var peg$c0 = "attribute";
930 var peg$c1 = "varying";
931 var peg$c2 = "const";
932 var peg$c3 = "bool";
933 var peg$c4 = "float";
934 var peg$c5 = "double";
935 var peg$c6 = "int";
936 var peg$c7 = "uint";
937 var peg$c8 = "break";
938 var peg$c9 = "continue";
939 var peg$c10 = "do";
940 var peg$c11 = "else";
941 var peg$c12 = "for";
942 var peg$c13 = "if";
943 var peg$c14 = "discard";
944 var peg$c15 = "return";
945 var peg$c16 = "switch";
946 var peg$c17 = "case";
947 var peg$c18 = "default";
948 var peg$c19 = "subroutine";
949 var peg$c20 = "bvec2";
950 var peg$c21 = "bvec3";
951 var peg$c22 = "bvec4";
952 var peg$c23 = "ivec2";
953 var peg$c24 = "ivec3";
954 var peg$c25 = "ivec4";
955 var peg$c26 = "uvec2";
956 var peg$c27 = "uvec3";
957 var peg$c28 = "uvec4";
958 var peg$c29 = "vec2";
959 var peg$c30 = "vec3";
960 var peg$c31 = "vec4";
961 var peg$c32 = "mat2";
962 var peg$c33 = "mat3";
963 var peg$c34 = "mat4";
964 var peg$c35 = "centroid";
965 var peg$c36 = "in";
966 var peg$c37 = "out";
967 var peg$c38 = "inout";
968 var peg$c39 = "uniform";
969 var peg$c40 = "patch";
970 var peg$c41 = "sample";
971 var peg$c42 = "buffer";
972 var peg$c43 = "shared";
973 var peg$c44 = "coherent";
974 var peg$c45 = "volatile";
975 var peg$c46 = "restrict";
976 var peg$c47 = "readonly";
977 var peg$c48 = "writeonly";
978 var peg$c49 = "dvec2";
979 var peg$c50 = "dvec3";
980 var peg$c51 = "dvec4";
981 var peg$c52 = "dmat2";
982 var peg$c53 = "dmat3";
983 var peg$c54 = "dmat4";
984 var peg$c55 = "noperspective";
985 var peg$c56 = "flat";
986 var peg$c57 = "smooth";
987 var peg$c58 = "layout";
988 var peg$c59 = "mat2x2";
989 var peg$c60 = "mat2x3";
990 var peg$c61 = "mat2x4";
991 var peg$c62 = "mat3x2";
992 var peg$c63 = "mat3x3";
993 var peg$c64 = "mat3x4";
994 var peg$c65 = "mat4x2";
995 var peg$c66 = "mat4x3";
996 var peg$c67 = "mat4x4";
997 var peg$c68 = "dmat2x2";
998 var peg$c69 = "dmat2x3";
999 var peg$c70 = "dmat2x4";
1000 var peg$c71 = "dmat3x2";
1001 var peg$c72 = "dmat3x3";
1002 var peg$c73 = "dmat3x4";
1003 var peg$c74 = "dmat4x2";
1004 var peg$c75 = "dmat4x3";
1005 var peg$c76 = "dmat4x4";
1006 var peg$c77 = "atomic_uint";
1007 var peg$c78 = "sampler1D";
1008 var peg$c79 = "sampler2D";
1009 var peg$c80 = "sampler3D";
1010 var peg$c81 = "samplerCube";
1011 var peg$c82 = "sampler1DShadow";
1012 var peg$c83 = "sampler2DShadow";
1013 var peg$c84 = "samplerCubeShadow";
1014 var peg$c85 = "sampler1DArray";
1015 var peg$c86 = "sampler2DArray";
1016 var peg$c87 = "sampler1DArrayShadow";
1017 var peg$c88 = "sampler2DArrayShadow";
1018 var peg$c89 = "isampler1D";
1019 var peg$c90 = "isampler2D";
1020 var peg$c91 = "isampler3D";
1021 var peg$c92 = "isamplerCube";
1022 var peg$c93 = "isampler1Darray";
1023 var peg$c94 = "isampler2DArray";
1024 var peg$c95 = "usampler1D";
1025 var peg$c96 = "usampler2D";
1026 var peg$c97 = "usampler3D";
1027 var peg$c98 = "usamplerCube";
1028 var peg$c99 = "usampler1DArray";
1029 var peg$c100 = "usampler2DArray";
1030 var peg$c101 = "sampler2DRect";
1031 var peg$c102 = "sampler2DRectShadow";
1032 var peg$c103 = "isampler2DRect";
1033 var peg$c104 = "usampler2DRect";
1034 var peg$c105 = "samplerBuffer";
1035 var peg$c106 = "isamplerBuffer";
1036 var peg$c107 = "usamplerBuffer";
1037 var peg$c108 = "samplerCubeArray";
1038 var peg$c109 = "samplerCubeArrayShadow";
1039 var peg$c110 = "isamplerCubeArray";
1040 var peg$c111 = "usamplerCubeArray";
1041 var peg$c112 = "sampler2DMS";
1042 var peg$c113 = "isampler2DMS";
1043 var peg$c114 = "usampler2DMS";
1044 var peg$c115 = "sampler2DMSArray";
1045 var peg$c116 = "isampler2DMSArray";
1046 var peg$c117 = "usampler2DMSArray";
1047 var peg$c118 = "image1D";
1048 var peg$c119 = "iimage1D";
1049 var peg$c120 = "uimage1D";
1050 var peg$c121 = "image2D";
1051 var peg$c122 = "iimage2D";
1052 var peg$c123 = "uimage2D";
1053 var peg$c124 = "image3D";
1054 var peg$c125 = "iimage3D";
1055 var peg$c126 = "uimage3D";
1056 var peg$c127 = "image2DRect";
1057 var peg$c128 = "iimage2DRect";
1058 var peg$c129 = "uimage2DRect";
1059 var peg$c130 = "imageCube";
1060 var peg$c131 = "iimageCube";
1061 var peg$c132 = "uimageCube";
1062 var peg$c133 = "imageBuffer";
1063 var peg$c134 = "iimageBuffer";
1064 var peg$c135 = "uimageBuffer";
1065 var peg$c136 = "image1DArray";
1066 var peg$c137 = "iimage1DArray";
1067 var peg$c138 = "uimage1DArray";
1068 var peg$c139 = "image2DArray";
1069 var peg$c140 = "iimage2DArray";
1070 var peg$c141 = "uimage2DArray";
1071 var peg$c142 = "imageCubeArray";
1072 var peg$c143 = "iimageCubeArray";
1073 var peg$c144 = "uimageCubeArray";
1074 var peg$c145 = "image2DMS";
1075 var peg$c146 = "iimage2DMS";
1076 var peg$c147 = "uimage2DMS";
1077 var peg$c148 = "image2DMArray";
1078 var peg$c149 = "iimage2DMSArray";
1079 var peg$c150 = "uimage2DMSArray";
1080 var peg$c151 = "struct";
1081 var peg$c152 = "void";
1082 var peg$c153 = "while";
1083 var peg$c154 = "invariant";
1084 var peg$c155 = "precise";
1085 var peg$c156 = "highp";
1086 var peg$c157 = "mediump";
1087 var peg$c158 = "lowp";
1088 var peg$c159 = "precision";
1089 var peg$c160 = "true";
1090 var peg$c161 = "false";
1091 var peg$c162 = "<<";
1092 var peg$c163 = ">>";
1093 var peg$c164 = "++";
1094 var peg$c165 = "--";
1095 var peg$c166 = "<=";
1096 var peg$c167 = ">=";
1097 var peg$c168 = "==";
1098 var peg$c169 = "!=";
1099 var peg$c170 = "&&";
1100 var peg$c171 = "||";
1101 var peg$c172 = "^^";
1102 var peg$c173 = "*=";
1103 var peg$c174 = "/=";
1104 var peg$c175 = "+=";
1105 var peg$c176 = "%=";
1106 var peg$c177 = "<<=";
1107 var peg$c178 = ">>=";
1108 var peg$c179 = "&=";
1109 var peg$c180 = "^=";
1110 var peg$c181 = "|=";
1111 var peg$c182 = "-=";
1112 var peg$c183 = "(";
1113 var peg$c184 = ")";
1114 var peg$c185 = "[";
1115 var peg$c186 = "]";
1116 var peg$c187 = "{";
1117 var peg$c188 = "}";
1118 var peg$c189 = ".";
1119 var peg$c190 = ",";
1120 var peg$c191 = ":";
1121 var peg$c192 = "=";
1122 var peg$c193 = ";";
1123 var peg$c194 = "!";
1124 var peg$c195 = "-";
1125 var peg$c196 = "~";
1126 var peg$c197 = "+";
1127 var peg$c198 = "*";
1128 var peg$c199 = "/";
1129 var peg$c200 = "%";
1130 var peg$c201 = "<";
1131 var peg$c202 = ">";
1132 var peg$c203 = "|";
1133 var peg$c204 = "^";
1134 var peg$c205 = "&";
1135 var peg$c206 = "?";
1136 var peg$c207 = "0";
1137 var peg$c208 = "lf";
1138 var peg$c209 = "LF";
1139 var peg$c210 = "#";
1140 var peg$c211 = "//";
1141 var peg$c212 = "/*";
1142 var peg$c213 = "*/";
1143 var peg$r0 = /^[A-Za-z_]/;
1144 var peg$r1 = /^[A-Za-z_0-9]/;
1145 var peg$r2 = /^[uU]/;
1146 var peg$r3 = /^[1-9]/;
1147 var peg$r4 = /^[0-7]/;
1148 var peg$r5 = /^[xX]/;
1149 var peg$r6 = /^[0-9a-fA-F]/;
1150 var peg$r7 = /^[0-9]/;
1151 var peg$r8 = /^[eE]/;
1152 var peg$r9 = /^[+\-]/;
1153 var peg$r10 = /^[fF]/;
1154 var peg$r11 = /^[^\n]/;
1155 var peg$r12 = /^[ \t\n\r]/;
1156 var peg$e0 = peg$literalExpectation("attribute", false);
1157 var peg$e1 = peg$literalExpectation("varying", false);
1158 var peg$e2 = peg$literalExpectation("const", false);
1159 var peg$e3 = peg$literalExpectation("bool", false);
1160 var peg$e4 = peg$literalExpectation("float", false);
1161 var peg$e5 = peg$literalExpectation("double", false);
1162 var peg$e6 = peg$literalExpectation("int", false);
1163 var peg$e7 = peg$literalExpectation("uint", false);
1164 var peg$e8 = peg$literalExpectation("break", false);
1165 var peg$e9 = peg$literalExpectation("continue", false);
1166 var peg$e10 = peg$literalExpectation("do", false);
1167 var peg$e11 = peg$literalExpectation("else", false);
1168 var peg$e12 = peg$literalExpectation("for", false);
1169 var peg$e13 = peg$literalExpectation("if", false);
1170 var peg$e14 = peg$literalExpectation("discard", false);
1171 var peg$e15 = peg$literalExpectation("return", false);
1172 var peg$e16 = peg$literalExpectation("switch", false);
1173 var peg$e17 = peg$literalExpectation("case", false);
1174 var peg$e18 = peg$literalExpectation("default", false);
1175 var peg$e19 = peg$literalExpectation("subroutine", false);
1176 var peg$e20 = peg$literalExpectation("bvec2", false);
1177 var peg$e21 = peg$literalExpectation("bvec3", false);
1178 var peg$e22 = peg$literalExpectation("bvec4", false);
1179 var peg$e23 = peg$literalExpectation("ivec2", false);
1180 var peg$e24 = peg$literalExpectation("ivec3", false);
1181 var peg$e25 = peg$literalExpectation("ivec4", false);
1182 var peg$e26 = peg$literalExpectation("uvec2", false);
1183 var peg$e27 = peg$literalExpectation("uvec3", false);
1184 var peg$e28 = peg$literalExpectation("uvec4", false);
1185 var peg$e29 = peg$literalExpectation("vec2", false);
1186 var peg$e30 = peg$literalExpectation("vec3", false);
1187 var peg$e31 = peg$literalExpectation("vec4", false);
1188 var peg$e32 = peg$literalExpectation("mat2", false);
1189 var peg$e33 = peg$literalExpectation("mat3", false);
1190 var peg$e34 = peg$literalExpectation("mat4", false);
1191 var peg$e35 = peg$literalExpectation("centroid", false);
1192 var peg$e36 = peg$literalExpectation("in", false);
1193 var peg$e37 = peg$literalExpectation("out", false);
1194 var peg$e38 = peg$literalExpectation("inout", false);
1195 var peg$e39 = peg$literalExpectation("uniform", false);
1196 var peg$e40 = peg$literalExpectation("patch", false);
1197 var peg$e41 = peg$literalExpectation("sample", false);
1198 var peg$e42 = peg$literalExpectation("buffer", false);
1199 var peg$e43 = peg$literalExpectation("shared", false);
1200 var peg$e44 = peg$literalExpectation("coherent", false);
1201 var peg$e45 = peg$literalExpectation("volatile", false);
1202 var peg$e46 = peg$literalExpectation("restrict", false);
1203 var peg$e47 = peg$literalExpectation("readonly", false);
1204 var peg$e48 = peg$literalExpectation("writeonly", false);
1205 var peg$e49 = peg$literalExpectation("dvec2", false);
1206 var peg$e50 = peg$literalExpectation("dvec3", false);
1207 var peg$e51 = peg$literalExpectation("dvec4", false);
1208 var peg$e52 = peg$literalExpectation("dmat2", false);
1209 var peg$e53 = peg$literalExpectation("dmat3", false);
1210 var peg$e54 = peg$literalExpectation("dmat4", false);
1211 var peg$e55 = peg$literalExpectation("noperspective", false);
1212 var peg$e56 = peg$literalExpectation("flat", false);
1213 var peg$e57 = peg$literalExpectation("smooth", false);
1214 var peg$e58 = peg$literalExpectation("layout", false);
1215 var peg$e59 = peg$literalExpectation("mat2x2", false);
1216 var peg$e60 = peg$literalExpectation("mat2x3", false);
1217 var peg$e61 = peg$literalExpectation("mat2x4", false);
1218 var peg$e62 = peg$literalExpectation("mat3x2", false);
1219 var peg$e63 = peg$literalExpectation("mat3x3", false);
1220 var peg$e64 = peg$literalExpectation("mat3x4", false);
1221 var peg$e65 = peg$literalExpectation("mat4x2", false);
1222 var peg$e66 = peg$literalExpectation("mat4x3", false);
1223 var peg$e67 = peg$literalExpectation("mat4x4", false);
1224 var peg$e68 = peg$literalExpectation("dmat2x2", false);
1225 var peg$e69 = peg$literalExpectation("dmat2x3", false);
1226 var peg$e70 = peg$literalExpectation("dmat2x4", false);
1227 var peg$e71 = peg$literalExpectation("dmat3x2", false);
1228 var peg$e72 = peg$literalExpectation("dmat3x3", false);
1229 var peg$e73 = peg$literalExpectation("dmat3x4", false);
1230 var peg$e74 = peg$literalExpectation("dmat4x2", false);
1231 var peg$e75 = peg$literalExpectation("dmat4x3", false);
1232 var peg$e76 = peg$literalExpectation("dmat4x4", false);
1233 var peg$e77 = peg$literalExpectation("atomic_uint", false);
1234 var peg$e78 = peg$literalExpectation("sampler1D", false);
1235 var peg$e79 = peg$literalExpectation("sampler2D", false);
1236 var peg$e80 = peg$literalExpectation("sampler3D", false);
1237 var peg$e81 = peg$literalExpectation("samplerCube", false);
1238 var peg$e82 = peg$literalExpectation("sampler1DShadow", false);
1239 var peg$e83 = peg$literalExpectation("sampler2DShadow", false);
1240 var peg$e84 = peg$literalExpectation("samplerCubeShadow", false);
1241 var peg$e85 = peg$literalExpectation("sampler1DArray", false);
1242 var peg$e86 = peg$literalExpectation("sampler2DArray", false);
1243 var peg$e87 = peg$literalExpectation("sampler1DArrayShadow", false);
1244 var peg$e88 = peg$literalExpectation("sampler2DArrayShadow", false);
1245 var peg$e89 = peg$literalExpectation("isampler1D", false);
1246 var peg$e90 = peg$literalExpectation("isampler2D", false);
1247 var peg$e91 = peg$literalExpectation("isampler3D", false);
1248 var peg$e92 = peg$literalExpectation("isamplerCube", false);
1249 var peg$e93 = peg$literalExpectation("isampler1Darray", false);
1250 var peg$e94 = peg$literalExpectation("isampler2DArray", false);
1251 var peg$e95 = peg$literalExpectation("usampler1D", false);
1252 var peg$e96 = peg$literalExpectation("usampler2D", false);
1253 var peg$e97 = peg$literalExpectation("usampler3D", false);
1254 var peg$e98 = peg$literalExpectation("usamplerCube", false);
1255 var peg$e99 = peg$literalExpectation("usampler1DArray", false);
1256 var peg$e100 = peg$literalExpectation("usampler2DArray", false);
1257 var peg$e101 = peg$literalExpectation("sampler2DRect", false);
1258 var peg$e102 = peg$literalExpectation("sampler2DRectShadow", false);
1259 var peg$e103 = peg$literalExpectation("isampler2DRect", false);
1260 var peg$e104 = peg$literalExpectation("usampler2DRect", false);
1261 var peg$e105 = peg$literalExpectation("samplerBuffer", false);
1262 var peg$e106 = peg$literalExpectation("isamplerBuffer", false);
1263 var peg$e107 = peg$literalExpectation("usamplerBuffer", false);
1264 var peg$e108 = peg$literalExpectation("samplerCubeArray", false);
1265 var peg$e109 = peg$literalExpectation("samplerCubeArrayShadow", false);
1266 var peg$e110 = peg$literalExpectation("isamplerCubeArray", false);
1267 var peg$e111 = peg$literalExpectation("usamplerCubeArray", false);
1268 var peg$e112 = peg$literalExpectation("sampler2DMS", false);
1269 var peg$e113 = peg$literalExpectation("isampler2DMS", false);
1270 var peg$e114 = peg$literalExpectation("usampler2DMS", false);
1271 var peg$e115 = peg$literalExpectation("sampler2DMSArray", false);
1272 var peg$e116 = peg$literalExpectation("isampler2DMSArray", false);
1273 var peg$e117 = peg$literalExpectation("usampler2DMSArray", false);
1274 var peg$e118 = peg$literalExpectation("image1D", false);
1275 var peg$e119 = peg$literalExpectation("iimage1D", false);
1276 var peg$e120 = peg$literalExpectation("uimage1D", false);
1277 var peg$e121 = peg$literalExpectation("image2D", false);
1278 var peg$e122 = peg$literalExpectation("iimage2D", false);
1279 var peg$e123 = peg$literalExpectation("uimage2D", false);
1280 var peg$e124 = peg$literalExpectation("image3D", false);
1281 var peg$e125 = peg$literalExpectation("iimage3D", false);
1282 var peg$e126 = peg$literalExpectation("uimage3D", false);
1283 var peg$e127 = peg$literalExpectation("image2DRect", false);
1284 var peg$e128 = peg$literalExpectation("iimage2DRect", false);
1285 var peg$e129 = peg$literalExpectation("uimage2DRect", false);
1286 var peg$e130 = peg$literalExpectation("imageCube", false);
1287 var peg$e131 = peg$literalExpectation("iimageCube", false);
1288 var peg$e132 = peg$literalExpectation("uimageCube", false);
1289 var peg$e133 = peg$literalExpectation("imageBuffer", false);
1290 var peg$e134 = peg$literalExpectation("iimageBuffer", false);
1291 var peg$e135 = peg$literalExpectation("uimageBuffer", false);
1292 var peg$e136 = peg$literalExpectation("image1DArray", false);
1293 var peg$e137 = peg$literalExpectation("iimage1DArray", false);
1294 var peg$e138 = peg$literalExpectation("uimage1DArray", false);
1295 var peg$e139 = peg$literalExpectation("image2DArray", false);
1296 var peg$e140 = peg$literalExpectation("iimage2DArray", false);
1297 var peg$e141 = peg$literalExpectation("uimage2DArray", false);
1298 var peg$e142 = peg$literalExpectation("imageCubeArray", false);
1299 var peg$e143 = peg$literalExpectation("iimageCubeArray", false);
1300 var peg$e144 = peg$literalExpectation("uimageCubeArray", false);
1301 var peg$e145 = peg$literalExpectation("image2DMS", false);
1302 var peg$e146 = peg$literalExpectation("iimage2DMS", false);
1303 var peg$e147 = peg$literalExpectation("uimage2DMS", false);
1304 var peg$e148 = peg$literalExpectation("image2DMArray", false);
1305 var peg$e149 = peg$literalExpectation("iimage2DMSArray", false);
1306 var peg$e150 = peg$literalExpectation("uimage2DMSArray", false);
1307 var peg$e151 = peg$literalExpectation("struct", false);
1308 var peg$e152 = peg$literalExpectation("void", false);
1309 var peg$e153 = peg$literalExpectation("while", false);
1310 var peg$e154 = peg$literalExpectation("invariant", false);
1311 var peg$e155 = peg$literalExpectation("precise", false);
1312 var peg$e156 = peg$literalExpectation("highp", false);
1313 var peg$e157 = peg$literalExpectation("mediump", false);
1314 var peg$e158 = peg$literalExpectation("lowp", false);
1315 var peg$e159 = peg$literalExpectation("precision", false);
1316 var peg$e160 = peg$literalExpectation("true", false);
1317 var peg$e161 = peg$literalExpectation("false", false);
1318 var peg$e162 = peg$otherExpectation("keyword");
1319 var peg$e163 = peg$literalExpectation("<<", false);
1320 var peg$e164 = peg$literalExpectation(">>", false);
1321 var peg$e165 = peg$literalExpectation("++", false);
1322 var peg$e166 = peg$literalExpectation("--", false);
1323 var peg$e167 = peg$literalExpectation("<=", false);
1324 var peg$e168 = peg$literalExpectation(">=", false);
1325 var peg$e169 = peg$literalExpectation("==", false);
1326 var peg$e170 = peg$literalExpectation("!=", false);
1327 var peg$e171 = peg$literalExpectation("&&", false);
1328 var peg$e172 = peg$literalExpectation("||", false);
1329 var peg$e173 = peg$literalExpectation("^^", false);
1330 var peg$e174 = peg$literalExpectation("*=", false);
1331 var peg$e175 = peg$literalExpectation("/=", false);
1332 var peg$e176 = peg$literalExpectation("+=", false);
1333 var peg$e177 = peg$literalExpectation("%=", false);
1334 var peg$e178 = peg$literalExpectation("<<=", false);
1335 var peg$e179 = peg$literalExpectation(">>=", false);
1336 var peg$e180 = peg$literalExpectation("&=", false);
1337 var peg$e181 = peg$literalExpectation("^=", false);
1338 var peg$e182 = peg$literalExpectation("|=", false);
1339 var peg$e183 = peg$literalExpectation("-=", false);
1340 var peg$e184 = peg$literalExpectation("(", false);
1341 var peg$e185 = peg$literalExpectation(")", false);
1342 var peg$e186 = peg$literalExpectation("[", false);
1343 var peg$e187 = peg$literalExpectation("]", false);
1344 var peg$e188 = peg$literalExpectation("{", false);
1345 var peg$e189 = peg$literalExpectation("}", false);
1346 var peg$e190 = peg$literalExpectation(".", false);
1347 var peg$e191 = peg$literalExpectation(",", false);
1348 var peg$e192 = peg$literalExpectation(":", false);
1349 var peg$e193 = peg$literalExpectation("=", false);
1350 var peg$e194 = peg$literalExpectation(";", false);
1351 var peg$e195 = peg$literalExpectation("!", false);
1352 var peg$e196 = peg$literalExpectation("-", false);
1353 var peg$e197 = peg$literalExpectation("~", false);
1354 var peg$e198 = peg$literalExpectation("+", false);
1355 var peg$e199 = peg$literalExpectation("*", false);
1356 var peg$e200 = peg$literalExpectation("/", false);
1357 var peg$e201 = peg$literalExpectation("%", false);
1358 var peg$e202 = peg$literalExpectation("<", false);
1359 var peg$e203 = peg$literalExpectation(">", false);
1360 var peg$e204 = peg$literalExpectation("|", false);
1361 var peg$e205 = peg$literalExpectation("^", false);
1362 var peg$e206 = peg$literalExpectation("&", false);
1363 var peg$e207 = peg$literalExpectation("?", false);
1364 var peg$e208 = peg$classExpectation([["A", "Z"], ["a", "z"], "_"], false, false);
1365 var peg$e209 = peg$classExpectation([["A", "Z"], ["a", "z"], "_", ["0", "9"]], false, false);
1366 var peg$e210 = peg$classExpectation(["u", "U"], false, false);
1367 var peg$e211 = peg$classExpectation([["1", "9"]], false, false);
1368 var peg$e212 = peg$literalExpectation("0", false);
1369 var peg$e213 = peg$classExpectation([["0", "7"]], false, false);
1370 var peg$e214 = peg$classExpectation(["x", "X"], false, false);
1371 var peg$e215 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false);
1372 var peg$e216 = peg$classExpectation([["0", "9"]], false, false);
1373 var peg$e217 = peg$otherExpectation("exponent");
1374 var peg$e218 = peg$classExpectation(["e", "E"], false, false);
1375 var peg$e219 = peg$classExpectation(["+", "-"], false, false);
1376 var peg$e220 = peg$classExpectation(["f", "F"], false, false);
1377 var peg$e221 = peg$literalExpectation("lf", false);
1378 var peg$e222 = peg$literalExpectation("LF", false);
1379 var peg$e223 = peg$otherExpectation("primary expression");
1380 var peg$e224 = peg$otherExpectation("unary expression");
1381 var peg$e225 = peg$otherExpectation("equality expression");
1382 var peg$e226 = peg$otherExpectation("and expression");
1383 var peg$e227 = peg$otherExpectation("asignment");
1384 var peg$e228 = peg$otherExpectation("expression");
1385 var peg$e229 = peg$otherExpectation("precision statement");
1386 var peg$e230 = peg$otherExpectation("function prototype");
1387 var peg$e231 = peg$otherExpectation("function header");
1388 var peg$e232 = peg$otherExpectation("function prototype scope");
1389 var peg$e233 = peg$otherExpectation("function header scope");
1390 var peg$e234 = peg$otherExpectation("function parameters");
1391 var peg$e235 = peg$otherExpectation("parameter declaration");
1392 var peg$e236 = peg$otherExpectation("single type qualifier");
1393 var peg$e237 = peg$otherExpectation("interpolation qualifier");
1394 var peg$e238 = peg$otherExpectation("storage qualifier");
1395 var peg$e239 = peg$otherExpectation("type specifier");
1396 var peg$e240 = peg$otherExpectation("array specifier");
1397 var peg$e241 = peg$otherExpectation("precision qualifier");
1398 var peg$e242 = peg$otherExpectation("struct specifier");
1399 var peg$e243 = peg$otherExpectation("iteration statement");
1400 var peg$e244 = peg$otherExpectation("jump statement");
1401 var peg$e245 = peg$otherExpectation("prepocessor");
1402 var peg$e246 = peg$literalExpectation("#", false);
1403 var peg$e247 = peg$classExpectation(["\n"], true, false);
1404 var peg$e248 = peg$otherExpectation("whitespace");
1405 var peg$e249 = peg$literalExpectation("//", false);
1406 var peg$e250 = peg$literalExpectation("/*", false);
1407 var peg$e251 = peg$literalExpectation("*/", false);
1408 var peg$e252 = peg$anyExpectation();
1409 var peg$e253 = peg$classExpectation([" ", " ", "\n", "\r"], false, false);
1410 var peg$f0 = function(wsStart, program) {
1411 setScopeEnd(context.scope, getLocation()?.end);
1412 return node("program", { wsStart, program, scopes: context.scopes });
1413 };
1414 var peg$f1 = function(token, t) {
1415 return node("keyword", { token, whitespace: t });
1416 };
1417 var peg$f2 = function(token, _) {
1418 return node("float_constant", { token, whitespace: _ });
1419 };
1420 var peg$f3 = function(token, _) {
1421 return node("double_constant", { token, whitespace: _ });
1422 };
1423 var peg$f4 = function(token, _) {
1424 return node("int_constant", { token, whitespace: _ });
1425 };
1426 var peg$f5 = function(token, _) {
1427 return node("uint_constant", { token, whitespace: _ });
1428 };
1429 var peg$f6 = function(token, t) {
1430 return node("bool_constant", { token, whitespace: t });
1431 };
1432 var peg$f7 = function(token, _) {
1433 return node("literal", { literal: token, whitespace: _ });
1434 };
1435 var peg$f8 = function(identifier, _) {
1436 return node("identifier", { identifier, whitespace: _ });
1437 };
1438 var peg$f9 = function(identifier, _) {
1439 return node("type_name", { identifier, whitespace: _ });
1440 };
1441 var peg$f10 = function(lp, expression, rp) {
1442 return node("group", { lp, expression, rp });
1443 };
1444 var peg$f11 = function(ident) {
1445 const { identifier } = ident;
1446 addOrCreateBindingReference(context.scope, identifier, ident);
1447 return ident;
1448 };
1449 var peg$f12 = function(body) {
1450 return body.flat().reduceRight(
1451 (postfix, expression) => postfix ? node("postfix", { expression, postfix }) : expression
1452 );
1453 };
1454 var peg$f13 = function(lb, expression, rb) {
1455 return node("quantifier", { lb, expression, rb });
1456 };
1457 var peg$f14 = function(dot, selection) {
1458 return node("field_selection", { dot, selection });
1459 };
1460 var peg$f15 = function(function_identifier, args, rp) {
1461 const identifierPartial = function_identifier.partial;
1462 const { identifier } = identifierPartial;
1463 let fnIdentifier = identifier.type === "postfix" ? identifier.expression.identifier ? identifier.expression.identifier.specifier : identifier.expression.specifier : identifier.specifier;
1464 let fnName = fnIdentifier.identifier;
1465 const n = node("function_call", { ...identifierPartial, args: args || [], rp });
1466 const isDeclaredFn = isDeclaredFunction(context.scope, fnName);
1467 const isBuiltIn = FN_BUILT_INS.has(fnName);
1468 const isType = isDeclaredType(context.scope, fnName);
1469 if (fnName) {
1470 if (!isType && fnIdentifier.type === "type_name" && (!isDeclaredFn || isBuiltIn)) {
1471 fnIdentifier = node("identifier", {
1472 identifier: fnIdentifier.identifier,
1473 whitespace: fnIdentifier.whitespace
1474 });
1475 if (n.identifier.type === "postfix") {
1476 n.identifier.expression.identifier = fnIdentifier;
1477 } else {
1478 n.identifier = fnIdentifier;
1479 }
1480 }
1481 if (
1482 // You can override built-in functions like "noise", so only add
1483 // "noise" to scope usage if it's declared by the user
1484 isDeclaredFn || !isBuiltIn
1485 ) {
1486 if (isType) {
1487 if (identifier.type === "type_specifier") {
1488 addTypeReference(
1489 context.scope,
1490 fnName,
1491 identifier.specifier
1492 );
1493 } else {
1494 throw new Error(`Unknown function call identifier type ${identifier.type}. Please file a bug against @shaderfrog/glsl-parser and incldue your source grammar.`);
1495 }
1496 } else {
1497 addFunctionCallReference(context.scope, fnName, n);
1498 }
1499 }
1500 }
1501 return n;
1502 };
1503 var peg$f16 = function(v) {
1504 return [v];
1505 };
1506 var peg$f17 = function(head, tail) {
1507 return [head, ...tail.flat()];
1508 };
1509 var peg$f18 = function(head, suffix, lp) {
1510 return partial({ head: [head, suffix], lp });
1511 };
1512 var peg$f19 = function(identifier) {
1513 return partial({
1514 lp: identifier.partial.lp,
1515 identifier: [identifier.partial.head].flat().reduceRight(
1516 (postfix, expression) => postfix ? node("postfix", { expression, postfix }) : expression
1517 )
1518 });
1519 };
1520 var peg$f20 = function(identifier, lp, args, rp) {
1521 return node("function_call", { identifier, lp, args, rp });
1522 };
1523 var peg$f21 = function(operator, expression) {
1524 return node("unary", { operator, expression });
1525 };
1526 var peg$f22 = function(head, tail) {
1527 return leftAssociate(head, tail);
1528 };
1529 var peg$f23 = function(expression, question, left, colon, right) {
1530 return { question, left, right, colon };
1531 };
1532 var peg$f24 = function(expression, suffix) {
1533 return suffix ? node("ternary", { expression, ...suffix }) : expression;
1534 };
1535 var peg$f25 = function(left, operator, right) {
1536 return node("assignment", { left, operator, right });
1537 };
1538 var peg$f26 = function(declaration) {
1539 return node(
1540 "declaration_statement",
1541 {
1542 declaration: declaration.partial.node,
1543 semi: declaration.partial.semi
1544 }
1545 );
1546 };
1547 var peg$f27 = function(qualifiers, head, tail, semi) {
1548 return partial({
1549 node: node(
1550 "qualifier_declarator",
1551 {
1552 qualifiers,
1553 // Head is optional, so remove falsey
1554 declarations: xnil([head, ...tail.map((t) => t[1])]),
1555 commas: tail.map((t) => t[0])
1556 }
1557 ),
1558 semi
1559 });
1560 };
1561 var peg$f28 = function(qualifiers, interface_type, lp, declarations, rp, identifier, semi) {
1562 const n = node(
1563 "interface_declarator",
1564 { qualifiers, interface_type, lp, declarations, rp, identifier }
1565 );
1566 createBindings(context.scope, [interface_type.identifier, n]);
1567 return partial({
1568 node: n,
1569 semi
1570 });
1571 };
1572 var peg$f29 = function(prefix, qualifier, specifier, semi) {
1573 return partial({
1574 node: node("precision", { prefix, qualifier, specifier }),
1575 semi
1576 });
1577 };
1578 var peg$f30 = function(header, params, rp) {
1579 const bindings = (params?.parameters || []).filter((p) => !!p.identifier).map((p) => [p.identifier.identifier, p]);
1580 createBindings(context.scope, ...bindings);
1581 return node("function_prototype", { header, ...params, rp });
1582 };
1583 var peg$f31 = function(returnType, name, lp) {
1584 const n = node(
1585 "function_header",
1586 { returnType, name, lp }
1587 );
1588 context.scope = pushScope(makeScope(name.identifier, context.scope, lp.location));
1589 return n;
1590 };
1591 var peg$f32 = function(header, params, rp) {
1592 return node("function_prototype", { header, ...params, rp });
1593 };
1594 var peg$f33 = function(returnType, name, lp) {
1595 return node(
1596 "function_header",
1597 { returnType, name, lp }
1598 );
1599 };
1600 var peg$f34 = function(head, tail) {
1601 return {
1602 parameters: [head, ...tail.map((t) => t[1])],
1603 commas: tail.map((t) => t[0])
1604 };
1605 };
1606 var peg$f35 = function(qualifier, specifier, declaration) {
1607 return node(
1608 "parameter_declaration",
1609 {
1610 qualifier,
1611 specifier,
1612 identifier: declaration?.[0],
1613 quantifier: declaration?.[1]
1614 }
1615 );
1616 };
1617 var peg$f36 = function(head, tail, semi) {
1618 const declarations = [
1619 head.partial.declaration,
1620 ...tail.map((t) => t[1])
1621 ].filter((decl) => !!decl.identifier);
1622 addTypeIfFound(context.scope, head.partial.specified_type);
1623 createBindings(context.scope, ...tail.map((t) => t[1]).map((decl) => [decl.identifier.identifier, decl]));
1624 return partial({
1625 node: node(
1626 "declarator_list",
1627 {
1628 specified_type: head.partial.specified_type,
1629 declarations,
1630 commas: tail.map((t) => t[0])
1631 }
1632 ),
1633 semi
1634 });
1635 };
1636 var peg$f37 = function(identifier, quantifier, suffix) {
1637 const [equal, initializer] = suffix || [];
1638 return node(
1639 "declaration",
1640 { identifier, quantifier, equal, initializer }
1641 );
1642 };
1643 var peg$f38 = function(specified_type, suffix) {
1644 const [identifier, quantifier, suffix_tail] = suffix || [];
1645 const [equal, initializer] = suffix_tail || [];
1646 if (identifier) {
1647 createBindings(context.scope, [identifier.identifier, identifier]);
1648 }
1649 return partial({
1650 declaration: node(
1651 "declaration",
1652 { identifier, quantifier, equal, initializer }
1653 ),
1654 specified_type
1655 });
1656 };
1657 var peg$f39 = function(qualifiers, specifier) {
1658 return node(
1659 "fully_specified_type",
1660 { qualifiers, specifier }
1661 );
1662 };
1663 var peg$f40 = function(layout, lp, head, tail) {
1664 return partial({
1665 qualifiers: [head, ...tail.map((t) => t[1])],
1666 commas: tail.map((t) => t[0])
1667 });
1668 };
1669 var peg$f41 = function(layout, lp, qualifiers, rp) {
1670 return node(
1671 "layout_qualifier",
1672 { layout, lp, ...qualifiers.partial, rp }
1673 );
1674 };
1675 var peg$f42 = function(identifier, tail) {
1676 const [operator, expression] = tail || [];
1677 return node("layout_qualifier_id", { identifier, operator, expression });
1678 };
1679 var peg$f43 = function(subroutine, lp, head, tail, rp) {
1680 return partial({
1681 lp,
1682 type_names: [head, ...tail.map((t) => t[1])],
1683 commas: tail.map((t) => t[0]),
1684 rp
1685 });
1686 };
1687 var peg$f44 = function(subroutine, type_names) {
1688 return node(
1689 "subroutine_qualifier",
1690 {
1691 subroutine,
1692 ...type_names?.partial
1693 }
1694 );
1695 };
1696 var peg$f45 = function(specifier, quantifier) {
1697 return node("type_specifier", { specifier, quantifier });
1698 };
1699 var peg$f46 = function(lb, expression, rb) {
1700 return node("array_specifier", { lb, expression, rb });
1701 };
1702 var peg$f47 = function(specifiers) {
1703 return specifiers;
1704 };
1705 var peg$f48 = function(struct, typeName, lb, declarations, rb) {
1706 const n = node("struct", { lb, declarations, rb, struct, typeName });
1707 if (typeName) {
1708 createType(context.scope, typeName.identifier, n.typeName);
1709 }
1710 return n;
1711 };
1712 var peg$f49 = function(declaration, semi) {
1713 addTypeIfFound(context.scope, declaration.specified_type);
1714 return node("struct_declaration", { declaration, semi });
1715 };
1716 var peg$f50 = function(specified_type, head, tail) {
1717 if (specified_type)
1718 return node(
1719 "struct_declarator",
1720 {
1721 specified_type,
1722 declarations: [head, ...tail.map((t) => t[1])],
1723 commas: tail.map((t) => t[0])
1724 }
1725 );
1726 };
1727 var peg$f51 = function(identifier, quantifier) {
1728 return node("quantified_identifier", { identifier, quantifier });
1729 };
1730 var peg$f52 = function(lb, head, tail, trailing, rb) {
1731 return node(
1732 "initializer_list",
1733 {
1734 lb,
1735 initializers: [head, ...tail.map((t) => t[1])],
1736 commas: xnil(tail.map((t) => t[0]), trailing),
1737 rb
1738 }
1739 );
1740 };
1741 var peg$f53 = function(sym) {
1742 context.scope = pushScope(makeScope(OPEN_CURLY, context.scope));
1743 return sym;
1744 };
1745 var peg$f54 = function(lb, statements, rb) {
1746 setScopeEnd(context.scope, rb.location?.start);
1747 context.scope = popScope(context.scope);
1748 return node(
1749 "compound_statement",
1750 { lb, statements: (statements || []).flat(), rb }
1751 );
1752 };
1753 var peg$f55 = function(lb, statements, rb) {
1754 return node(
1755 "compound_statement",
1756 { lb, statements: (statements || []).flat(), rb }
1757 );
1758 };
1759 var peg$f56 = function(expression, semi) {
1760 return node("expression_statement", { expression, semi });
1761 };
1762 var peg$f57 = function(ifSymbol, lp, condition, rp, tail) {
1763 const [body, elseBranch] = tail;
1764 return node(
1765 "if_statement",
1766 {
1767 "if": ifSymbol,
1768 body,
1769 lp,
1770 condition,
1771 rp,
1772 ...elseBranch && { "else": elseBranch.flat() }
1773 }
1774 );
1775 };
1776 var peg$f58 = function(switchSymbol, lp, expression, rp, lb, statements, rb) {
1777 return node(
1778 "switch_statement",
1779 {
1780 switch: switchSymbol,
1781 lp,
1782 expression,
1783 rp,
1784 lb,
1785 cases: groupCases(statements),
1786 rb
1787 }
1788 );
1789 };
1790 var peg$f59 = function(caseSymbol, test, colon) {
1791 return partial("case_label", { "case": caseSymbol, test, colon });
1792 };
1793 var peg$f60 = function(defaultSymbol, colon) {
1794 return partial("default_label", { default: defaultSymbol, colon });
1795 };
1796 var peg$f61 = function(sym) {
1797 context.scope = pushScope(makeScope("while", context.scope));
1798 return sym;
1799 };
1800 var peg$f62 = function(whileSymbol, lp, condition, rp, body) {
1801 const end = body.rb ? body.rb.location?.start : body.location?.end;
1802 setScopeEnd(context.scope, end);
1803 context.scope = popScope(context.scope);
1804 return node(
1805 "while_statement",
1806 {
1807 while: whileSymbol,
1808 lp,
1809 condition,
1810 rp,
1811 body
1812 }
1813 );
1814 };
1815 var peg$f63 = function(doSymbol, body, whileSymbol, lp, expression, rp, semi) {
1816 return node(
1817 "do_statement",
1818 {
1819 do: doSymbol,
1820 body,
1821 while: whileSymbol,
1822 lp,
1823 expression,
1824 rp,
1825 semi
1826 }
1827 );
1828 };
1829 var peg$f64 = function(sym) {
1830 context.scope = pushScope(makeScope("for", context.scope));
1831 return sym;
1832 };
1833 var peg$f65 = function(forSymbol, lp, init, condition, conditionSemi, operation, rp, body) {
1834 const end = body.rb ? body.rb.location?.start : body.location?.end;
1835 setScopeEnd(context.scope, end);
1836 context.scope = popScope(context.scope);
1837 return node(
1838 "for_statement",
1839 {
1840 "for": forSymbol,
1841 body,
1842 lp,
1843 init: init.expression || init.declaration,
1844 initSemi: init.semi,
1845 condition,
1846 conditionSemi,
1847 operation,
1848 rp
1849 }
1850 );
1851 };
1852 var peg$f66 = function(specified_type, identifier, operator, initializer) {
1853 const n = node(
1854 "condition_expression",
1855 { specified_type, identifier, operator, initializer }
1856 );
1857 createBindings(context.scope, [identifier.identifier, n]);
1858 return n;
1859 };
1860 var peg$f67 = function(jump, semi) {
1861 return node("continue_statement", { continue: jump, semi });
1862 };
1863 var peg$f68 = function(jump, semi) {
1864 return node("break_statement", { break: jump, semi });
1865 };
1866 var peg$f69 = function(jump, expression, semi) {
1867 return node("return_statement", { return: jump, expression, semi });
1868 };
1869 var peg$f70 = function(jump, semi) {
1870 return node("discard_statement", { discard: jump, semi });
1871 };
1872 var peg$f71 = function(line, _) {
1873 return node("preprocessor", { line, _ });
1874 };
1875 var peg$f72 = function(declaration, semi) {
1876 (declaration.parameters || []).forEach((p) => addTypeIfFound(context.scope, p.specifier));
1877 addTypeIfFound(context.scope, declaration.header.returnType);
1878 createFunctionPrototype(context.scope, declaration.header.name.identifier, declaration);
1879 const n = node(
1880 "declaration_statement",
1881 {
1882 declaration,
1883 semi
1884 }
1885 );
1886 return n;
1887 };
1888 var peg$f73 = function(prototype, body) {
1889 const n = node("function", { prototype, body });
1890 setScopeEnd(context.scope, body.rb.location?.start);
1891 context.scope = popScope(context.scope);
1892 (prototype.parameters || []).forEach((p) => addTypeIfFound(context.scope, p.specifier));
1893 addTypeIfFound(context.scope, prototype.header.returnType);
1894 createFunctionDefinition(context.scope, prototype.header.name.identifier, n, n);
1895 return n;
1896 };
1897 var peg$f74 = function(w, rest) {
1898 return collapse(w, rest);
1899 };
1900 var peg$f75 = function(a, x, cc) {
1901 return xnil(x, cc);
1902 };
1903 var peg$f76 = function(a, d) {
1904 return xnil(a, d.flat());
1905 };
1906 var peg$f77 = function(i) {
1907 return i;
1908 };
1909 var peg$f78 = function(_) {
1910 return _;
1911 };
1912 var peg$currPos = 0;
1913 var peg$savedPos = 0;
1914 var peg$posDetailsCache = [{ line: 1, column: 1 }];
1915 var peg$maxFailPos = 0;
1916 var peg$maxFailExpected = [];
1917 var peg$silentFails = 0;
1918 var peg$resultsCache = {};
1919 var peg$result;
1920 if ("startRule" in options) {
1921 if (!(options.startRule in peg$startRuleFunctions)) {
1922 throw new Error(`Can't start parsing from rule "` + options.startRule + '".');
1923 }
1924 peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
1925 }
1926 function text() {
1927 return input.substring(peg$savedPos, peg$currPos);
1928 }
1929 function offset() {
1930 return peg$savedPos;
1931 }
1932 function range() {
1933 return {
1934 source: peg$source,
1935 start: peg$savedPos,
1936 end: peg$currPos
1937 };
1938 }
1939 function location() {
1940 return peg$computeLocation(peg$savedPos, peg$currPos);
1941 }
1942 function expected(description, location2) {
1943 location2 = location2 !== void 0 ? location2 : peg$computeLocation(peg$savedPos, peg$currPos);
1944 throw peg$buildStructuredError(
1945 [peg$otherExpectation(description)],
1946 input.substring(peg$savedPos, peg$currPos),
1947 location2
1948 );
1949 }
1950 function error(message, location2) {
1951 location2 = location2 !== void 0 ? location2 : peg$computeLocation(peg$savedPos, peg$currPos);
1952 throw peg$buildSimpleError(message, location2);
1953 }
1954 function peg$literalExpectation(text2, ignoreCase) {
1955 return { type: "literal", text: text2, ignoreCase };
1956 }
1957 function peg$classExpectation(parts, inverted, ignoreCase) {
1958 return { type: "class", parts, inverted, ignoreCase };
1959 }
1960 function peg$anyExpectation() {
1961 return { type: "any" };
1962 }
1963 function peg$endExpectation() {
1964 return { type: "end" };
1965 }
1966 function peg$otherExpectation(description) {
1967 return { type: "other", description };
1968 }
1969 function peg$computePosDetails(pos) {
1970 var details = peg$posDetailsCache[pos];
1971 var p;
1972 if (details) {
1973 return details;
1974 } else {
1975 p = pos - 1;
1976 while (!peg$posDetailsCache[p]) {
1977 p--;
1978 }
1979 details = peg$posDetailsCache[p];
1980 details = {
1981 line: details.line,
1982 column: details.column
1983 };
1984 while (p < pos) {
1985 if (input.charCodeAt(p) === 10) {
1986 details.line++;
1987 details.column = 1;
1988 } else {
1989 details.column++;
1990 }
1991 p++;
1992 }
1993 peg$posDetailsCache[pos] = details;
1994 return details;
1995 }
1996 }
1997 function peg$computeLocation(startPos, endPos) {
1998 var startPosDetails = peg$computePosDetails(startPos);
1999 var endPosDetails = peg$computePosDetails(endPos);
2000 return {
2001 source: peg$source,
2002 start: {
2003 offset: startPos,
2004 line: startPosDetails.line,
2005 column: startPosDetails.column
2006 },
2007 end: {
2008 offset: endPos,
2009 line: endPosDetails.line,
2010 column: endPosDetails.column
2011 }
2012 };
2013 }
2014 function peg$fail(expected2) {
2015 if (peg$currPos < peg$maxFailPos) {
2016 return;
2017 }
2018 if (peg$currPos > peg$maxFailPos) {
2019 peg$maxFailPos = peg$currPos;
2020 peg$maxFailExpected = [];
2021 }
2022 peg$maxFailExpected.push(expected2);
2023 }
2024 function peg$buildSimpleError(message, location2) {
2025 return new peg$SyntaxError(message, null, null, location2);
2026 }
2027 function peg$buildStructuredError(expected2, found, location2) {
2028 return new peg$SyntaxError(
2029 peg$SyntaxError.buildMessage(expected2, found),
2030 expected2,
2031 found,
2032 location2
2033 );
2034 }
2035 function peg$parsestart() {
2036 var s0, s1, s2;
2037 var key = peg$currPos * 306 + 0;
2038 var cached = peg$resultsCache[key];
2039 if (cached) {
2040 peg$currPos = cached.nextPos;
2041 return cached.result;
2042 }
2043 s0 = peg$currPos;
2044 s1 = peg$parse_();
2045 s2 = peg$parsetranslation_unit();
2046 if (s2 !== peg$FAILED) {
2047 peg$savedPos = s0;
2048 s0 = peg$f0(s1, s2);
2049 } else {
2050 peg$currPos = s0;
2051 s0 = peg$FAILED;
2052 }
2053 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2054 return s0;
2055 }
2056 function peg$parseATTRIBUTE() {
2057 var s0, s1, s2;
2058 var key = peg$currPos * 306 + 1;
2059 var cached = peg$resultsCache[key];
2060 if (cached) {
2061 peg$currPos = cached.nextPos;
2062 return cached.result;
2063 }
2064 s0 = peg$currPos;
2065 if (input.substr(peg$currPos, 9) === peg$c0) {
2066 s1 = peg$c0;
2067 peg$currPos += 9;
2068 } else {
2069 s1 = peg$FAILED;
2070 if (peg$silentFails === 0) {
2071 peg$fail(peg$e0);
2072 }
2073 }
2074 if (s1 !== peg$FAILED) {
2075 s2 = peg$parseterminal();
2076 if (s2 !== peg$FAILED) {
2077 peg$savedPos = s0;
2078 s0 = peg$f1(s1, s2);
2079 } else {
2080 peg$currPos = s0;
2081 s0 = peg$FAILED;
2082 }
2083 } else {
2084 peg$currPos = s0;
2085 s0 = peg$FAILED;
2086 }
2087 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2088 return s0;
2089 }
2090 function peg$parseVARYING() {
2091 var s0, s1, s2;
2092 var key = peg$currPos * 306 + 2;
2093 var cached = peg$resultsCache[key];
2094 if (cached) {
2095 peg$currPos = cached.nextPos;
2096 return cached.result;
2097 }
2098 s0 = peg$currPos;
2099 if (input.substr(peg$currPos, 7) === peg$c1) {
2100 s1 = peg$c1;
2101 peg$currPos += 7;
2102 } else {
2103 s1 = peg$FAILED;
2104 if (peg$silentFails === 0) {
2105 peg$fail(peg$e1);
2106 }
2107 }
2108 if (s1 !== peg$FAILED) {
2109 s2 = peg$parseterminal();
2110 if (s2 !== peg$FAILED) {
2111 peg$savedPos = s0;
2112 s0 = peg$f1(s1, s2);
2113 } else {
2114 peg$currPos = s0;
2115 s0 = peg$FAILED;
2116 }
2117 } else {
2118 peg$currPos = s0;
2119 s0 = peg$FAILED;
2120 }
2121 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2122 return s0;
2123 }
2124 function peg$parseCONST() {
2125 var s0, s1, s2;
2126 var key = peg$currPos * 306 + 3;
2127 var cached = peg$resultsCache[key];
2128 if (cached) {
2129 peg$currPos = cached.nextPos;
2130 return cached.result;
2131 }
2132 s0 = peg$currPos;
2133 if (input.substr(peg$currPos, 5) === peg$c2) {
2134 s1 = peg$c2;
2135 peg$currPos += 5;
2136 } else {
2137 s1 = peg$FAILED;
2138 if (peg$silentFails === 0) {
2139 peg$fail(peg$e2);
2140 }
2141 }
2142 if (s1 !== peg$FAILED) {
2143 s2 = peg$parseterminal();
2144 if (s2 !== peg$FAILED) {
2145 peg$savedPos = s0;
2146 s0 = peg$f1(s1, s2);
2147 } else {
2148 peg$currPos = s0;
2149 s0 = peg$FAILED;
2150 }
2151 } else {
2152 peg$currPos = s0;
2153 s0 = peg$FAILED;
2154 }
2155 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2156 return s0;
2157 }
2158 function peg$parseBOOL() {
2159 var s0, s1, s2;
2160 var key = peg$currPos * 306 + 4;
2161 var cached = peg$resultsCache[key];
2162 if (cached) {
2163 peg$currPos = cached.nextPos;
2164 return cached.result;
2165 }
2166 s0 = peg$currPos;
2167 if (input.substr(peg$currPos, 4) === peg$c3) {
2168 s1 = peg$c3;
2169 peg$currPos += 4;
2170 } else {
2171 s1 = peg$FAILED;
2172 if (peg$silentFails === 0) {
2173 peg$fail(peg$e3);
2174 }
2175 }
2176 if (s1 !== peg$FAILED) {
2177 s2 = peg$parseterminal();
2178 if (s2 !== peg$FAILED) {
2179 peg$savedPos = s0;
2180 s0 = peg$f1(s1, s2);
2181 } else {
2182 peg$currPos = s0;
2183 s0 = peg$FAILED;
2184 }
2185 } else {
2186 peg$currPos = s0;
2187 s0 = peg$FAILED;
2188 }
2189 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2190 return s0;
2191 }
2192 function peg$parseFLOAT() {
2193 var s0, s1, s2;
2194 var key = peg$currPos * 306 + 5;
2195 var cached = peg$resultsCache[key];
2196 if (cached) {
2197 peg$currPos = cached.nextPos;
2198 return cached.result;
2199 }
2200 s0 = peg$currPos;
2201 if (input.substr(peg$currPos, 5) === peg$c4) {
2202 s1 = peg$c4;
2203 peg$currPos += 5;
2204 } else {
2205 s1 = peg$FAILED;
2206 if (peg$silentFails === 0) {
2207 peg$fail(peg$e4);
2208 }
2209 }
2210 if (s1 !== peg$FAILED) {
2211 s2 = peg$parseterminal();
2212 if (s2 !== peg$FAILED) {
2213 peg$savedPos = s0;
2214 s0 = peg$f1(s1, s2);
2215 } else {
2216 peg$currPos = s0;
2217 s0 = peg$FAILED;
2218 }
2219 } else {
2220 peg$currPos = s0;
2221 s0 = peg$FAILED;
2222 }
2223 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2224 return s0;
2225 }
2226 function peg$parseDOUBLE() {
2227 var s0, s1, s2;
2228 var key = peg$currPos * 306 + 6;
2229 var cached = peg$resultsCache[key];
2230 if (cached) {
2231 peg$currPos = cached.nextPos;
2232 return cached.result;
2233 }
2234 s0 = peg$currPos;
2235 if (input.substr(peg$currPos, 6) === peg$c5) {
2236 s1 = peg$c5;
2237 peg$currPos += 6;
2238 } else {
2239 s1 = peg$FAILED;
2240 if (peg$silentFails === 0) {
2241 peg$fail(peg$e5);
2242 }
2243 }
2244 if (s1 !== peg$FAILED) {
2245 s2 = peg$parseterminal();
2246 if (s2 !== peg$FAILED) {
2247 peg$savedPos = s0;
2248 s0 = peg$f1(s1, s2);
2249 } else {
2250 peg$currPos = s0;
2251 s0 = peg$FAILED;
2252 }
2253 } else {
2254 peg$currPos = s0;
2255 s0 = peg$FAILED;
2256 }
2257 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2258 return s0;
2259 }
2260 function peg$parseINT() {
2261 var s0, s1, s2;
2262 var key = peg$currPos * 306 + 7;
2263 var cached = peg$resultsCache[key];
2264 if (cached) {
2265 peg$currPos = cached.nextPos;
2266 return cached.result;
2267 }
2268 s0 = peg$currPos;
2269 if (input.substr(peg$currPos, 3) === peg$c6) {
2270 s1 = peg$c6;
2271 peg$currPos += 3;
2272 } else {
2273 s1 = peg$FAILED;
2274 if (peg$silentFails === 0) {
2275 peg$fail(peg$e6);
2276 }
2277 }
2278 if (s1 !== peg$FAILED) {
2279 s2 = peg$parseterminal();
2280 if (s2 !== peg$FAILED) {
2281 peg$savedPos = s0;
2282 s0 = peg$f1(s1, s2);
2283 } else {
2284 peg$currPos = s0;
2285 s0 = peg$FAILED;
2286 }
2287 } else {
2288 peg$currPos = s0;
2289 s0 = peg$FAILED;
2290 }
2291 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2292 return s0;
2293 }
2294 function peg$parseUINT() {
2295 var s0, s1, s2;
2296 var key = peg$currPos * 306 + 8;
2297 var cached = peg$resultsCache[key];
2298 if (cached) {
2299 peg$currPos = cached.nextPos;
2300 return cached.result;
2301 }
2302 s0 = peg$currPos;
2303 if (input.substr(peg$currPos, 4) === peg$c7) {
2304 s1 = peg$c7;
2305 peg$currPos += 4;
2306 } else {
2307 s1 = peg$FAILED;
2308 if (peg$silentFails === 0) {
2309 peg$fail(peg$e7);
2310 }
2311 }
2312 if (s1 !== peg$FAILED) {
2313 s2 = peg$parseterminal();
2314 if (s2 !== peg$FAILED) {
2315 peg$savedPos = s0;
2316 s0 = peg$f1(s1, s2);
2317 } else {
2318 peg$currPos = s0;
2319 s0 = peg$FAILED;
2320 }
2321 } else {
2322 peg$currPos = s0;
2323 s0 = peg$FAILED;
2324 }
2325 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2326 return s0;
2327 }
2328 function peg$parseBREAK() {
2329 var s0, s1, s2;
2330 var key = peg$currPos * 306 + 9;
2331 var cached = peg$resultsCache[key];
2332 if (cached) {
2333 peg$currPos = cached.nextPos;
2334 return cached.result;
2335 }
2336 s0 = peg$currPos;
2337 if (input.substr(peg$currPos, 5) === peg$c8) {
2338 s1 = peg$c8;
2339 peg$currPos += 5;
2340 } else {
2341 s1 = peg$FAILED;
2342 if (peg$silentFails === 0) {
2343 peg$fail(peg$e8);
2344 }
2345 }
2346 if (s1 !== peg$FAILED) {
2347 s2 = peg$parseterminal();
2348 if (s2 !== peg$FAILED) {
2349 peg$savedPos = s0;
2350 s0 = peg$f1(s1, s2);
2351 } else {
2352 peg$currPos = s0;
2353 s0 = peg$FAILED;
2354 }
2355 } else {
2356 peg$currPos = s0;
2357 s0 = peg$FAILED;
2358 }
2359 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2360 return s0;
2361 }
2362 function peg$parseCONTINUE() {
2363 var s0, s1, s2;
2364 var key = peg$currPos * 306 + 10;
2365 var cached = peg$resultsCache[key];
2366 if (cached) {
2367 peg$currPos = cached.nextPos;
2368 return cached.result;
2369 }
2370 s0 = peg$currPos;
2371 if (input.substr(peg$currPos, 8) === peg$c9) {
2372 s1 = peg$c9;
2373 peg$currPos += 8;
2374 } else {
2375 s1 = peg$FAILED;
2376 if (peg$silentFails === 0) {
2377 peg$fail(peg$e9);
2378 }
2379 }
2380 if (s1 !== peg$FAILED) {
2381 s2 = peg$parseterminal();
2382 if (s2 !== peg$FAILED) {
2383 peg$savedPos = s0;
2384 s0 = peg$f1(s1, s2);
2385 } else {
2386 peg$currPos = s0;
2387 s0 = peg$FAILED;
2388 }
2389 } else {
2390 peg$currPos = s0;
2391 s0 = peg$FAILED;
2392 }
2393 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2394 return s0;
2395 }
2396 function peg$parseDO() {
2397 var s0, s1, s2;
2398 var key = peg$currPos * 306 + 11;
2399 var cached = peg$resultsCache[key];
2400 if (cached) {
2401 peg$currPos = cached.nextPos;
2402 return cached.result;
2403 }
2404 s0 = peg$currPos;
2405 if (input.substr(peg$currPos, 2) === peg$c10) {
2406 s1 = peg$c10;
2407 peg$currPos += 2;
2408 } else {
2409 s1 = peg$FAILED;
2410 if (peg$silentFails === 0) {
2411 peg$fail(peg$e10);
2412 }
2413 }
2414 if (s1 !== peg$FAILED) {
2415 s2 = peg$parseterminal();
2416 if (s2 !== peg$FAILED) {
2417 peg$savedPos = s0;
2418 s0 = peg$f1(s1, s2);
2419 } else {
2420 peg$currPos = s0;
2421 s0 = peg$FAILED;
2422 }
2423 } else {
2424 peg$currPos = s0;
2425 s0 = peg$FAILED;
2426 }
2427 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2428 return s0;
2429 }
2430 function peg$parseELSE() {
2431 var s0, s1, s2;
2432 var key = peg$currPos * 306 + 12;
2433 var cached = peg$resultsCache[key];
2434 if (cached) {
2435 peg$currPos = cached.nextPos;
2436 return cached.result;
2437 }
2438 s0 = peg$currPos;
2439 if (input.substr(peg$currPos, 4) === peg$c11) {
2440 s1 = peg$c11;
2441 peg$currPos += 4;
2442 } else {
2443 s1 = peg$FAILED;
2444 if (peg$silentFails === 0) {
2445 peg$fail(peg$e11);
2446 }
2447 }
2448 if (s1 !== peg$FAILED) {
2449 s2 = peg$parseterminal();
2450 if (s2 !== peg$FAILED) {
2451 peg$savedPos = s0;
2452 s0 = peg$f1(s1, s2);
2453 } else {
2454 peg$currPos = s0;
2455 s0 = peg$FAILED;
2456 }
2457 } else {
2458 peg$currPos = s0;
2459 s0 = peg$FAILED;
2460 }
2461 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2462 return s0;
2463 }
2464 function peg$parseFOR() {
2465 var s0, s1, s2;
2466 var key = peg$currPos * 306 + 13;
2467 var cached = peg$resultsCache[key];
2468 if (cached) {
2469 peg$currPos = cached.nextPos;
2470 return cached.result;
2471 }
2472 s0 = peg$currPos;
2473 if (input.substr(peg$currPos, 3) === peg$c12) {
2474 s1 = peg$c12;
2475 peg$currPos += 3;
2476 } else {
2477 s1 = peg$FAILED;
2478 if (peg$silentFails === 0) {
2479 peg$fail(peg$e12);
2480 }
2481 }
2482 if (s1 !== peg$FAILED) {
2483 s2 = peg$parseterminal();
2484 if (s2 !== peg$FAILED) {
2485 peg$savedPos = s0;
2486 s0 = peg$f1(s1, s2);
2487 } else {
2488 peg$currPos = s0;
2489 s0 = peg$FAILED;
2490 }
2491 } else {
2492 peg$currPos = s0;
2493 s0 = peg$FAILED;
2494 }
2495 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2496 return s0;
2497 }
2498 function peg$parseIF() {
2499 var s0, s1, s2;
2500 var key = peg$currPos * 306 + 14;
2501 var cached = peg$resultsCache[key];
2502 if (cached) {
2503 peg$currPos = cached.nextPos;
2504 return cached.result;
2505 }
2506 s0 = peg$currPos;
2507 if (input.substr(peg$currPos, 2) === peg$c13) {
2508 s1 = peg$c13;
2509 peg$currPos += 2;
2510 } else {
2511 s1 = peg$FAILED;
2512 if (peg$silentFails === 0) {
2513 peg$fail(peg$e13);
2514 }
2515 }
2516 if (s1 !== peg$FAILED) {
2517 s2 = peg$parseterminal();
2518 if (s2 !== peg$FAILED) {
2519 peg$savedPos = s0;
2520 s0 = peg$f1(s1, s2);
2521 } else {
2522 peg$currPos = s0;
2523 s0 = peg$FAILED;
2524 }
2525 } else {
2526 peg$currPos = s0;
2527 s0 = peg$FAILED;
2528 }
2529 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2530 return s0;
2531 }
2532 function peg$parseDISCARD() {
2533 var s0, s1, s2;
2534 var key = peg$currPos * 306 + 15;
2535 var cached = peg$resultsCache[key];
2536 if (cached) {
2537 peg$currPos = cached.nextPos;
2538 return cached.result;
2539 }
2540 s0 = peg$currPos;
2541 if (input.substr(peg$currPos, 7) === peg$c14) {
2542 s1 = peg$c14;
2543 peg$currPos += 7;
2544 } else {
2545 s1 = peg$FAILED;
2546 if (peg$silentFails === 0) {
2547 peg$fail(peg$e14);
2548 }
2549 }
2550 if (s1 !== peg$FAILED) {
2551 s2 = peg$parseterminal();
2552 if (s2 !== peg$FAILED) {
2553 peg$savedPos = s0;
2554 s0 = peg$f1(s1, s2);
2555 } else {
2556 peg$currPos = s0;
2557 s0 = peg$FAILED;
2558 }
2559 } else {
2560 peg$currPos = s0;
2561 s0 = peg$FAILED;
2562 }
2563 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2564 return s0;
2565 }
2566 function peg$parseRETURN() {
2567 var s0, s1, s2;
2568 var key = peg$currPos * 306 + 16;
2569 var cached = peg$resultsCache[key];
2570 if (cached) {
2571 peg$currPos = cached.nextPos;
2572 return cached.result;
2573 }
2574 s0 = peg$currPos;
2575 if (input.substr(peg$currPos, 6) === peg$c15) {
2576 s1 = peg$c15;
2577 peg$currPos += 6;
2578 } else {
2579 s1 = peg$FAILED;
2580 if (peg$silentFails === 0) {
2581 peg$fail(peg$e15);
2582 }
2583 }
2584 if (s1 !== peg$FAILED) {
2585 s2 = peg$parseterminal();
2586 if (s2 !== peg$FAILED) {
2587 peg$savedPos = s0;
2588 s0 = peg$f1(s1, s2);
2589 } else {
2590 peg$currPos = s0;
2591 s0 = peg$FAILED;
2592 }
2593 } else {
2594 peg$currPos = s0;
2595 s0 = peg$FAILED;
2596 }
2597 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2598 return s0;
2599 }
2600 function peg$parseSWITCH() {
2601 var s0, s1, s2;
2602 var key = peg$currPos * 306 + 17;
2603 var cached = peg$resultsCache[key];
2604 if (cached) {
2605 peg$currPos = cached.nextPos;
2606 return cached.result;
2607 }
2608 s0 = peg$currPos;
2609 if (input.substr(peg$currPos, 6) === peg$c16) {
2610 s1 = peg$c16;
2611 peg$currPos += 6;
2612 } else {
2613 s1 = peg$FAILED;
2614 if (peg$silentFails === 0) {
2615 peg$fail(peg$e16);
2616 }
2617 }
2618 if (s1 !== peg$FAILED) {
2619 s2 = peg$parseterminal();
2620 if (s2 !== peg$FAILED) {
2621 peg$savedPos = s0;
2622 s0 = peg$f1(s1, s2);
2623 } else {
2624 peg$currPos = s0;
2625 s0 = peg$FAILED;
2626 }
2627 } else {
2628 peg$currPos = s0;
2629 s0 = peg$FAILED;
2630 }
2631 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2632 return s0;
2633 }
2634 function peg$parseCASE() {
2635 var s0, s1, s2;
2636 var key = peg$currPos * 306 + 18;
2637 var cached = peg$resultsCache[key];
2638 if (cached) {
2639 peg$currPos = cached.nextPos;
2640 return cached.result;
2641 }
2642 s0 = peg$currPos;
2643 if (input.substr(peg$currPos, 4) === peg$c17) {
2644 s1 = peg$c17;
2645 peg$currPos += 4;
2646 } else {
2647 s1 = peg$FAILED;
2648 if (peg$silentFails === 0) {
2649 peg$fail(peg$e17);
2650 }
2651 }
2652 if (s1 !== peg$FAILED) {
2653 s2 = peg$parseterminal();
2654 if (s2 !== peg$FAILED) {
2655 peg$savedPos = s0;
2656 s0 = peg$f1(s1, s2);
2657 } else {
2658 peg$currPos = s0;
2659 s0 = peg$FAILED;
2660 }
2661 } else {
2662 peg$currPos = s0;
2663 s0 = peg$FAILED;
2664 }
2665 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2666 return s0;
2667 }
2668 function peg$parseDEFAULT() {
2669 var s0, s1, s2;
2670 var key = peg$currPos * 306 + 19;
2671 var cached = peg$resultsCache[key];
2672 if (cached) {
2673 peg$currPos = cached.nextPos;
2674 return cached.result;
2675 }
2676 s0 = peg$currPos;
2677 if (input.substr(peg$currPos, 7) === peg$c18) {
2678 s1 = peg$c18;
2679 peg$currPos += 7;
2680 } else {
2681 s1 = peg$FAILED;
2682 if (peg$silentFails === 0) {
2683 peg$fail(peg$e18);
2684 }
2685 }
2686 if (s1 !== peg$FAILED) {
2687 s2 = peg$parseterminal();
2688 if (s2 !== peg$FAILED) {
2689 peg$savedPos = s0;
2690 s0 = peg$f1(s1, s2);
2691 } else {
2692 peg$currPos = s0;
2693 s0 = peg$FAILED;
2694 }
2695 } else {
2696 peg$currPos = s0;
2697 s0 = peg$FAILED;
2698 }
2699 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2700 return s0;
2701 }
2702 function peg$parseSUBROUTINE() {
2703 var s0, s1, s2;
2704 var key = peg$currPos * 306 + 20;
2705 var cached = peg$resultsCache[key];
2706 if (cached) {
2707 peg$currPos = cached.nextPos;
2708 return cached.result;
2709 }
2710 s0 = peg$currPos;
2711 if (input.substr(peg$currPos, 10) === peg$c19) {
2712 s1 = peg$c19;
2713 peg$currPos += 10;
2714 } else {
2715 s1 = peg$FAILED;
2716 if (peg$silentFails === 0) {
2717 peg$fail(peg$e19);
2718 }
2719 }
2720 if (s1 !== peg$FAILED) {
2721 s2 = peg$parseterminal();
2722 if (s2 !== peg$FAILED) {
2723 peg$savedPos = s0;
2724 s0 = peg$f1(s1, s2);
2725 } else {
2726 peg$currPos = s0;
2727 s0 = peg$FAILED;
2728 }
2729 } else {
2730 peg$currPos = s0;
2731 s0 = peg$FAILED;
2732 }
2733 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2734 return s0;
2735 }
2736 function peg$parseBVEC2() {
2737 var s0, s1, s2;
2738 var key = peg$currPos * 306 + 21;
2739 var cached = peg$resultsCache[key];
2740 if (cached) {
2741 peg$currPos = cached.nextPos;
2742 return cached.result;
2743 }
2744 s0 = peg$currPos;
2745 if (input.substr(peg$currPos, 5) === peg$c20) {
2746 s1 = peg$c20;
2747 peg$currPos += 5;
2748 } else {
2749 s1 = peg$FAILED;
2750 if (peg$silentFails === 0) {
2751 peg$fail(peg$e20);
2752 }
2753 }
2754 if (s1 !== peg$FAILED) {
2755 s2 = peg$parseterminal();
2756 if (s2 !== peg$FAILED) {
2757 peg$savedPos = s0;
2758 s0 = peg$f1(s1, s2);
2759 } else {
2760 peg$currPos = s0;
2761 s0 = peg$FAILED;
2762 }
2763 } else {
2764 peg$currPos = s0;
2765 s0 = peg$FAILED;
2766 }
2767 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2768 return s0;
2769 }
2770 function peg$parseBVEC3() {
2771 var s0, s1, s2;
2772 var key = peg$currPos * 306 + 22;
2773 var cached = peg$resultsCache[key];
2774 if (cached) {
2775 peg$currPos = cached.nextPos;
2776 return cached.result;
2777 }
2778 s0 = peg$currPos;
2779 if (input.substr(peg$currPos, 5) === peg$c21) {
2780 s1 = peg$c21;
2781 peg$currPos += 5;
2782 } else {
2783 s1 = peg$FAILED;
2784 if (peg$silentFails === 0) {
2785 peg$fail(peg$e21);
2786 }
2787 }
2788 if (s1 !== peg$FAILED) {
2789 s2 = peg$parseterminal();
2790 if (s2 !== peg$FAILED) {
2791 peg$savedPos = s0;
2792 s0 = peg$f1(s1, s2);
2793 } else {
2794 peg$currPos = s0;
2795 s0 = peg$FAILED;
2796 }
2797 } else {
2798 peg$currPos = s0;
2799 s0 = peg$FAILED;
2800 }
2801 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2802 return s0;
2803 }
2804 function peg$parseBVEC4() {
2805 var s0, s1, s2;
2806 var key = peg$currPos * 306 + 23;
2807 var cached = peg$resultsCache[key];
2808 if (cached) {
2809 peg$currPos = cached.nextPos;
2810 return cached.result;
2811 }
2812 s0 = peg$currPos;
2813 if (input.substr(peg$currPos, 5) === peg$c22) {
2814 s1 = peg$c22;
2815 peg$currPos += 5;
2816 } else {
2817 s1 = peg$FAILED;
2818 if (peg$silentFails === 0) {
2819 peg$fail(peg$e22);
2820 }
2821 }
2822 if (s1 !== peg$FAILED) {
2823 s2 = peg$parseterminal();
2824 if (s2 !== peg$FAILED) {
2825 peg$savedPos = s0;
2826 s0 = peg$f1(s1, s2);
2827 } else {
2828 peg$currPos = s0;
2829 s0 = peg$FAILED;
2830 }
2831 } else {
2832 peg$currPos = s0;
2833 s0 = peg$FAILED;
2834 }
2835 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2836 return s0;
2837 }
2838 function peg$parseIVEC2() {
2839 var s0, s1, s2;
2840 var key = peg$currPos * 306 + 24;
2841 var cached = peg$resultsCache[key];
2842 if (cached) {
2843 peg$currPos = cached.nextPos;
2844 return cached.result;
2845 }
2846 s0 = peg$currPos;
2847 if (input.substr(peg$currPos, 5) === peg$c23) {
2848 s1 = peg$c23;
2849 peg$currPos += 5;
2850 } else {
2851 s1 = peg$FAILED;
2852 if (peg$silentFails === 0) {
2853 peg$fail(peg$e23);
2854 }
2855 }
2856 if (s1 !== peg$FAILED) {
2857 s2 = peg$parseterminal();
2858 if (s2 !== peg$FAILED) {
2859 peg$savedPos = s0;
2860 s0 = peg$f1(s1, s2);
2861 } else {
2862 peg$currPos = s0;
2863 s0 = peg$FAILED;
2864 }
2865 } else {
2866 peg$currPos = s0;
2867 s0 = peg$FAILED;
2868 }
2869 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2870 return s0;
2871 }
2872 function peg$parseIVEC3() {
2873 var s0, s1, s2;
2874 var key = peg$currPos * 306 + 25;
2875 var cached = peg$resultsCache[key];
2876 if (cached) {
2877 peg$currPos = cached.nextPos;
2878 return cached.result;
2879 }
2880 s0 = peg$currPos;
2881 if (input.substr(peg$currPos, 5) === peg$c24) {
2882 s1 = peg$c24;
2883 peg$currPos += 5;
2884 } else {
2885 s1 = peg$FAILED;
2886 if (peg$silentFails === 0) {
2887 peg$fail(peg$e24);
2888 }
2889 }
2890 if (s1 !== peg$FAILED) {
2891 s2 = peg$parseterminal();
2892 if (s2 !== peg$FAILED) {
2893 peg$savedPos = s0;
2894 s0 = peg$f1(s1, s2);
2895 } else {
2896 peg$currPos = s0;
2897 s0 = peg$FAILED;
2898 }
2899 } else {
2900 peg$currPos = s0;
2901 s0 = peg$FAILED;
2902 }
2903 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2904 return s0;
2905 }
2906 function peg$parseIVEC4() {
2907 var s0, s1, s2;
2908 var key = peg$currPos * 306 + 26;
2909 var cached = peg$resultsCache[key];
2910 if (cached) {
2911 peg$currPos = cached.nextPos;
2912 return cached.result;
2913 }
2914 s0 = peg$currPos;
2915 if (input.substr(peg$currPos, 5) === peg$c25) {
2916 s1 = peg$c25;
2917 peg$currPos += 5;
2918 } else {
2919 s1 = peg$FAILED;
2920 if (peg$silentFails === 0) {
2921 peg$fail(peg$e25);
2922 }
2923 }
2924 if (s1 !== peg$FAILED) {
2925 s2 = peg$parseterminal();
2926 if (s2 !== peg$FAILED) {
2927 peg$savedPos = s0;
2928 s0 = peg$f1(s1, s2);
2929 } else {
2930 peg$currPos = s0;
2931 s0 = peg$FAILED;
2932 }
2933 } else {
2934 peg$currPos = s0;
2935 s0 = peg$FAILED;
2936 }
2937 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2938 return s0;
2939 }
2940 function peg$parseUVEC2() {
2941 var s0, s1, s2;
2942 var key = peg$currPos * 306 + 27;
2943 var cached = peg$resultsCache[key];
2944 if (cached) {
2945 peg$currPos = cached.nextPos;
2946 return cached.result;
2947 }
2948 s0 = peg$currPos;
2949 if (input.substr(peg$currPos, 5) === peg$c26) {
2950 s1 = peg$c26;
2951 peg$currPos += 5;
2952 } else {
2953 s1 = peg$FAILED;
2954 if (peg$silentFails === 0) {
2955 peg$fail(peg$e26);
2956 }
2957 }
2958 if (s1 !== peg$FAILED) {
2959 s2 = peg$parseterminal();
2960 if (s2 !== peg$FAILED) {
2961 peg$savedPos = s0;
2962 s0 = peg$f1(s1, s2);
2963 } else {
2964 peg$currPos = s0;
2965 s0 = peg$FAILED;
2966 }
2967 } else {
2968 peg$currPos = s0;
2969 s0 = peg$FAILED;
2970 }
2971 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
2972 return s0;
2973 }
2974 function peg$parseUVEC3() {
2975 var s0, s1, s2;
2976 var key = peg$currPos * 306 + 28;
2977 var cached = peg$resultsCache[key];
2978 if (cached) {
2979 peg$currPos = cached.nextPos;
2980 return cached.result;
2981 }
2982 s0 = peg$currPos;
2983 if (input.substr(peg$currPos, 5) === peg$c27) {
2984 s1 = peg$c27;
2985 peg$currPos += 5;
2986 } else {
2987 s1 = peg$FAILED;
2988 if (peg$silentFails === 0) {
2989 peg$fail(peg$e27);
2990 }
2991 }
2992 if (s1 !== peg$FAILED) {
2993 s2 = peg$parseterminal();
2994 if (s2 !== peg$FAILED) {
2995 peg$savedPos = s0;
2996 s0 = peg$f1(s1, s2);
2997 } else {
2998 peg$currPos = s0;
2999 s0 = peg$FAILED;
3000 }
3001 } else {
3002 peg$currPos = s0;
3003 s0 = peg$FAILED;
3004 }
3005 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3006 return s0;
3007 }
3008 function peg$parseUVEC4() {
3009 var s0, s1, s2;
3010 var key = peg$currPos * 306 + 29;
3011 var cached = peg$resultsCache[key];
3012 if (cached) {
3013 peg$currPos = cached.nextPos;
3014 return cached.result;
3015 }
3016 s0 = peg$currPos;
3017 if (input.substr(peg$currPos, 5) === peg$c28) {
3018 s1 = peg$c28;
3019 peg$currPos += 5;
3020 } else {
3021 s1 = peg$FAILED;
3022 if (peg$silentFails === 0) {
3023 peg$fail(peg$e28);
3024 }
3025 }
3026 if (s1 !== peg$FAILED) {
3027 s2 = peg$parseterminal();
3028 if (s2 !== peg$FAILED) {
3029 peg$savedPos = s0;
3030 s0 = peg$f1(s1, s2);
3031 } else {
3032 peg$currPos = s0;
3033 s0 = peg$FAILED;
3034 }
3035 } else {
3036 peg$currPos = s0;
3037 s0 = peg$FAILED;
3038 }
3039 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3040 return s0;
3041 }
3042 function peg$parseVEC2() {
3043 var s0, s1, s2;
3044 var key = peg$currPos * 306 + 30;
3045 var cached = peg$resultsCache[key];
3046 if (cached) {
3047 peg$currPos = cached.nextPos;
3048 return cached.result;
3049 }
3050 s0 = peg$currPos;
3051 if (input.substr(peg$currPos, 4) === peg$c29) {
3052 s1 = peg$c29;
3053 peg$currPos += 4;
3054 } else {
3055 s1 = peg$FAILED;
3056 if (peg$silentFails === 0) {
3057 peg$fail(peg$e29);
3058 }
3059 }
3060 if (s1 !== peg$FAILED) {
3061 s2 = peg$parseterminal();
3062 if (s2 !== peg$FAILED) {
3063 peg$savedPos = s0;
3064 s0 = peg$f1(s1, s2);
3065 } else {
3066 peg$currPos = s0;
3067 s0 = peg$FAILED;
3068 }
3069 } else {
3070 peg$currPos = s0;
3071 s0 = peg$FAILED;
3072 }
3073 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3074 return s0;
3075 }
3076 function peg$parseVEC3() {
3077 var s0, s1, s2;
3078 var key = peg$currPos * 306 + 31;
3079 var cached = peg$resultsCache[key];
3080 if (cached) {
3081 peg$currPos = cached.nextPos;
3082 return cached.result;
3083 }
3084 s0 = peg$currPos;
3085 if (input.substr(peg$currPos, 4) === peg$c30) {
3086 s1 = peg$c30;
3087 peg$currPos += 4;
3088 } else {
3089 s1 = peg$FAILED;
3090 if (peg$silentFails === 0) {
3091 peg$fail(peg$e30);
3092 }
3093 }
3094 if (s1 !== peg$FAILED) {
3095 s2 = peg$parseterminal();
3096 if (s2 !== peg$FAILED) {
3097 peg$savedPos = s0;
3098 s0 = peg$f1(s1, s2);
3099 } else {
3100 peg$currPos = s0;
3101 s0 = peg$FAILED;
3102 }
3103 } else {
3104 peg$currPos = s0;
3105 s0 = peg$FAILED;
3106 }
3107 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3108 return s0;
3109 }
3110 function peg$parseVEC4() {
3111 var s0, s1, s2;
3112 var key = peg$currPos * 306 + 32;
3113 var cached = peg$resultsCache[key];
3114 if (cached) {
3115 peg$currPos = cached.nextPos;
3116 return cached.result;
3117 }
3118 s0 = peg$currPos;
3119 if (input.substr(peg$currPos, 4) === peg$c31) {
3120 s1 = peg$c31;
3121 peg$currPos += 4;
3122 } else {
3123 s1 = peg$FAILED;
3124 if (peg$silentFails === 0) {
3125 peg$fail(peg$e31);
3126 }
3127 }
3128 if (s1 !== peg$FAILED) {
3129 s2 = peg$parseterminal();
3130 if (s2 !== peg$FAILED) {
3131 peg$savedPos = s0;
3132 s0 = peg$f1(s1, s2);
3133 } else {
3134 peg$currPos = s0;
3135 s0 = peg$FAILED;
3136 }
3137 } else {
3138 peg$currPos = s0;
3139 s0 = peg$FAILED;
3140 }
3141 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3142 return s0;
3143 }
3144 function peg$parseMAT2() {
3145 var s0, s1, s2;
3146 var key = peg$currPos * 306 + 33;
3147 var cached = peg$resultsCache[key];
3148 if (cached) {
3149 peg$currPos = cached.nextPos;
3150 return cached.result;
3151 }
3152 s0 = peg$currPos;
3153 if (input.substr(peg$currPos, 4) === peg$c32) {
3154 s1 = peg$c32;
3155 peg$currPos += 4;
3156 } else {
3157 s1 = peg$FAILED;
3158 if (peg$silentFails === 0) {
3159 peg$fail(peg$e32);
3160 }
3161 }
3162 if (s1 !== peg$FAILED) {
3163 s2 = peg$parseterminal();
3164 if (s2 !== peg$FAILED) {
3165 peg$savedPos = s0;
3166 s0 = peg$f1(s1, s2);
3167 } else {
3168 peg$currPos = s0;
3169 s0 = peg$FAILED;
3170 }
3171 } else {
3172 peg$currPos = s0;
3173 s0 = peg$FAILED;
3174 }
3175 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3176 return s0;
3177 }
3178 function peg$parseMAT3() {
3179 var s0, s1, s2;
3180 var key = peg$currPos * 306 + 34;
3181 var cached = peg$resultsCache[key];
3182 if (cached) {
3183 peg$currPos = cached.nextPos;
3184 return cached.result;
3185 }
3186 s0 = peg$currPos;
3187 if (input.substr(peg$currPos, 4) === peg$c33) {
3188 s1 = peg$c33;
3189 peg$currPos += 4;
3190 } else {
3191 s1 = peg$FAILED;
3192 if (peg$silentFails === 0) {
3193 peg$fail(peg$e33);
3194 }
3195 }
3196 if (s1 !== peg$FAILED) {
3197 s2 = peg$parseterminal();
3198 if (s2 !== peg$FAILED) {
3199 peg$savedPos = s0;
3200 s0 = peg$f1(s1, s2);
3201 } else {
3202 peg$currPos = s0;
3203 s0 = peg$FAILED;
3204 }
3205 } else {
3206 peg$currPos = s0;
3207 s0 = peg$FAILED;
3208 }
3209 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3210 return s0;
3211 }
3212 function peg$parseMAT4() {
3213 var s0, s1, s2;
3214 var key = peg$currPos * 306 + 35;
3215 var cached = peg$resultsCache[key];
3216 if (cached) {
3217 peg$currPos = cached.nextPos;
3218 return cached.result;
3219 }
3220 s0 = peg$currPos;
3221 if (input.substr(peg$currPos, 4) === peg$c34) {
3222 s1 = peg$c34;
3223 peg$currPos += 4;
3224 } else {
3225 s1 = peg$FAILED;
3226 if (peg$silentFails === 0) {
3227 peg$fail(peg$e34);
3228 }
3229 }
3230 if (s1 !== peg$FAILED) {
3231 s2 = peg$parseterminal();
3232 if (s2 !== peg$FAILED) {
3233 peg$savedPos = s0;
3234 s0 = peg$f1(s1, s2);
3235 } else {
3236 peg$currPos = s0;
3237 s0 = peg$FAILED;
3238 }
3239 } else {
3240 peg$currPos = s0;
3241 s0 = peg$FAILED;
3242 }
3243 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3244 return s0;
3245 }
3246 function peg$parseCENTROID() {
3247 var s0, s1, s2;
3248 var key = peg$currPos * 306 + 36;
3249 var cached = peg$resultsCache[key];
3250 if (cached) {
3251 peg$currPos = cached.nextPos;
3252 return cached.result;
3253 }
3254 s0 = peg$currPos;
3255 if (input.substr(peg$currPos, 8) === peg$c35) {
3256 s1 = peg$c35;
3257 peg$currPos += 8;
3258 } else {
3259 s1 = peg$FAILED;
3260 if (peg$silentFails === 0) {
3261 peg$fail(peg$e35);
3262 }
3263 }
3264 if (s1 !== peg$FAILED) {
3265 s2 = peg$parseterminal();
3266 if (s2 !== peg$FAILED) {
3267 peg$savedPos = s0;
3268 s0 = peg$f1(s1, s2);
3269 } else {
3270 peg$currPos = s0;
3271 s0 = peg$FAILED;
3272 }
3273 } else {
3274 peg$currPos = s0;
3275 s0 = peg$FAILED;
3276 }
3277 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3278 return s0;
3279 }
3280 function peg$parseIN() {
3281 var s0, s1, s2;
3282 var key = peg$currPos * 306 + 37;
3283 var cached = peg$resultsCache[key];
3284 if (cached) {
3285 peg$currPos = cached.nextPos;
3286 return cached.result;
3287 }
3288 s0 = peg$currPos;
3289 if (input.substr(peg$currPos, 2) === peg$c36) {
3290 s1 = peg$c36;
3291 peg$currPos += 2;
3292 } else {
3293 s1 = peg$FAILED;
3294 if (peg$silentFails === 0) {
3295 peg$fail(peg$e36);
3296 }
3297 }
3298 if (s1 !== peg$FAILED) {
3299 s2 = peg$parseterminal();
3300 if (s2 !== peg$FAILED) {
3301 peg$savedPos = s0;
3302 s0 = peg$f1(s1, s2);
3303 } else {
3304 peg$currPos = s0;
3305 s0 = peg$FAILED;
3306 }
3307 } else {
3308 peg$currPos = s0;
3309 s0 = peg$FAILED;
3310 }
3311 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3312 return s0;
3313 }
3314 function peg$parseOUT() {
3315 var s0, s1, s2;
3316 var key = peg$currPos * 306 + 38;
3317 var cached = peg$resultsCache[key];
3318 if (cached) {
3319 peg$currPos = cached.nextPos;
3320 return cached.result;
3321 }
3322 s0 = peg$currPos;
3323 if (input.substr(peg$currPos, 3) === peg$c37) {
3324 s1 = peg$c37;
3325 peg$currPos += 3;
3326 } else {
3327 s1 = peg$FAILED;
3328 if (peg$silentFails === 0) {
3329 peg$fail(peg$e37);
3330 }
3331 }
3332 if (s1 !== peg$FAILED) {
3333 s2 = peg$parseterminal();
3334 if (s2 !== peg$FAILED) {
3335 peg$savedPos = s0;
3336 s0 = peg$f1(s1, s2);
3337 } else {
3338 peg$currPos = s0;
3339 s0 = peg$FAILED;
3340 }
3341 } else {
3342 peg$currPos = s0;
3343 s0 = peg$FAILED;
3344 }
3345 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3346 return s0;
3347 }
3348 function peg$parseINOUT() {
3349 var s0, s1, s2;
3350 var key = peg$currPos * 306 + 39;
3351 var cached = peg$resultsCache[key];
3352 if (cached) {
3353 peg$currPos = cached.nextPos;
3354 return cached.result;
3355 }
3356 s0 = peg$currPos;
3357 if (input.substr(peg$currPos, 5) === peg$c38) {
3358 s1 = peg$c38;
3359 peg$currPos += 5;
3360 } else {
3361 s1 = peg$FAILED;
3362 if (peg$silentFails === 0) {
3363 peg$fail(peg$e38);
3364 }
3365 }
3366 if (s1 !== peg$FAILED) {
3367 s2 = peg$parseterminal();
3368 if (s2 !== peg$FAILED) {
3369 peg$savedPos = s0;
3370 s0 = peg$f1(s1, s2);
3371 } else {
3372 peg$currPos = s0;
3373 s0 = peg$FAILED;
3374 }
3375 } else {
3376 peg$currPos = s0;
3377 s0 = peg$FAILED;
3378 }
3379 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3380 return s0;
3381 }
3382 function peg$parseUNIFORM() {
3383 var s0, s1, s2;
3384 var key = peg$currPos * 306 + 40;
3385 var cached = peg$resultsCache[key];
3386 if (cached) {
3387 peg$currPos = cached.nextPos;
3388 return cached.result;
3389 }
3390 s0 = peg$currPos;
3391 if (input.substr(peg$currPos, 7) === peg$c39) {
3392 s1 = peg$c39;
3393 peg$currPos += 7;
3394 } else {
3395 s1 = peg$FAILED;
3396 if (peg$silentFails === 0) {
3397 peg$fail(peg$e39);
3398 }
3399 }
3400 if (s1 !== peg$FAILED) {
3401 s2 = peg$parseterminal();
3402 if (s2 !== peg$FAILED) {
3403 peg$savedPos = s0;
3404 s0 = peg$f1(s1, s2);
3405 } else {
3406 peg$currPos = s0;
3407 s0 = peg$FAILED;
3408 }
3409 } else {
3410 peg$currPos = s0;
3411 s0 = peg$FAILED;
3412 }
3413 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3414 return s0;
3415 }
3416 function peg$parsePATCH() {
3417 var s0, s1, s2;
3418 var key = peg$currPos * 306 + 41;
3419 var cached = peg$resultsCache[key];
3420 if (cached) {
3421 peg$currPos = cached.nextPos;
3422 return cached.result;
3423 }
3424 s0 = peg$currPos;
3425 if (input.substr(peg$currPos, 5) === peg$c40) {
3426 s1 = peg$c40;
3427 peg$currPos += 5;
3428 } else {
3429 s1 = peg$FAILED;
3430 if (peg$silentFails === 0) {
3431 peg$fail(peg$e40);
3432 }
3433 }
3434 if (s1 !== peg$FAILED) {
3435 s2 = peg$parseterminal();
3436 if (s2 !== peg$FAILED) {
3437 peg$savedPos = s0;
3438 s0 = peg$f1(s1, s2);
3439 } else {
3440 peg$currPos = s0;
3441 s0 = peg$FAILED;
3442 }
3443 } else {
3444 peg$currPos = s0;
3445 s0 = peg$FAILED;
3446 }
3447 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3448 return s0;
3449 }
3450 function peg$parseSAMPLE() {
3451 var s0, s1, s2;
3452 var key = peg$currPos * 306 + 42;
3453 var cached = peg$resultsCache[key];
3454 if (cached) {
3455 peg$currPos = cached.nextPos;
3456 return cached.result;
3457 }
3458 s0 = peg$currPos;
3459 if (input.substr(peg$currPos, 6) === peg$c41) {
3460 s1 = peg$c41;
3461 peg$currPos += 6;
3462 } else {
3463 s1 = peg$FAILED;
3464 if (peg$silentFails === 0) {
3465 peg$fail(peg$e41);
3466 }
3467 }
3468 if (s1 !== peg$FAILED) {
3469 s2 = peg$parseterminal();
3470 if (s2 !== peg$FAILED) {
3471 peg$savedPos = s0;
3472 s0 = peg$f1(s1, s2);
3473 } else {
3474 peg$currPos = s0;
3475 s0 = peg$FAILED;
3476 }
3477 } else {
3478 peg$currPos = s0;
3479 s0 = peg$FAILED;
3480 }
3481 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3482 return s0;
3483 }
3484 function peg$parseBUFFER() {
3485 var s0, s1, s2;
3486 var key = peg$currPos * 306 + 43;
3487 var cached = peg$resultsCache[key];
3488 if (cached) {
3489 peg$currPos = cached.nextPos;
3490 return cached.result;
3491 }
3492 s0 = peg$currPos;
3493 if (input.substr(peg$currPos, 6) === peg$c42) {
3494 s1 = peg$c42;
3495 peg$currPos += 6;
3496 } else {
3497 s1 = peg$FAILED;
3498 if (peg$silentFails === 0) {
3499 peg$fail(peg$e42);
3500 }
3501 }
3502 if (s1 !== peg$FAILED) {
3503 s2 = peg$parseterminal();
3504 if (s2 !== peg$FAILED) {
3505 peg$savedPos = s0;
3506 s0 = peg$f1(s1, s2);
3507 } else {
3508 peg$currPos = s0;
3509 s0 = peg$FAILED;
3510 }
3511 } else {
3512 peg$currPos = s0;
3513 s0 = peg$FAILED;
3514 }
3515 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3516 return s0;
3517 }
3518 function peg$parseSHARED() {
3519 var s0, s1, s2;
3520 var key = peg$currPos * 306 + 44;
3521 var cached = peg$resultsCache[key];
3522 if (cached) {
3523 peg$currPos = cached.nextPos;
3524 return cached.result;
3525 }
3526 s0 = peg$currPos;
3527 if (input.substr(peg$currPos, 6) === peg$c43) {
3528 s1 = peg$c43;
3529 peg$currPos += 6;
3530 } else {
3531 s1 = peg$FAILED;
3532 if (peg$silentFails === 0) {
3533 peg$fail(peg$e43);
3534 }
3535 }
3536 if (s1 !== peg$FAILED) {
3537 s2 = peg$parseterminal();
3538 if (s2 !== peg$FAILED) {
3539 peg$savedPos = s0;
3540 s0 = peg$f1(s1, s2);
3541 } else {
3542 peg$currPos = s0;
3543 s0 = peg$FAILED;
3544 }
3545 } else {
3546 peg$currPos = s0;
3547 s0 = peg$FAILED;
3548 }
3549 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3550 return s0;
3551 }
3552 function peg$parseCOHERENT() {
3553 var s0, s1, s2;
3554 var key = peg$currPos * 306 + 45;
3555 var cached = peg$resultsCache[key];
3556 if (cached) {
3557 peg$currPos = cached.nextPos;
3558 return cached.result;
3559 }
3560 s0 = peg$currPos;
3561 if (input.substr(peg$currPos, 8) === peg$c44) {
3562 s1 = peg$c44;
3563 peg$currPos += 8;
3564 } else {
3565 s1 = peg$FAILED;
3566 if (peg$silentFails === 0) {
3567 peg$fail(peg$e44);
3568 }
3569 }
3570 if (s1 !== peg$FAILED) {
3571 s2 = peg$parseterminal();
3572 if (s2 !== peg$FAILED) {
3573 peg$savedPos = s0;
3574 s0 = peg$f1(s1, s2);
3575 } else {
3576 peg$currPos = s0;
3577 s0 = peg$FAILED;
3578 }
3579 } else {
3580 peg$currPos = s0;
3581 s0 = peg$FAILED;
3582 }
3583 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3584 return s0;
3585 }
3586 function peg$parseVOLATILE() {
3587 var s0, s1, s2;
3588 var key = peg$currPos * 306 + 46;
3589 var cached = peg$resultsCache[key];
3590 if (cached) {
3591 peg$currPos = cached.nextPos;
3592 return cached.result;
3593 }
3594 s0 = peg$currPos;
3595 if (input.substr(peg$currPos, 8) === peg$c45) {
3596 s1 = peg$c45;
3597 peg$currPos += 8;
3598 } else {
3599 s1 = peg$FAILED;
3600 if (peg$silentFails === 0) {
3601 peg$fail(peg$e45);
3602 }
3603 }
3604 if (s1 !== peg$FAILED) {
3605 s2 = peg$parseterminal();
3606 if (s2 !== peg$FAILED) {
3607 peg$savedPos = s0;
3608 s0 = peg$f1(s1, s2);
3609 } else {
3610 peg$currPos = s0;
3611 s0 = peg$FAILED;
3612 }
3613 } else {
3614 peg$currPos = s0;
3615 s0 = peg$FAILED;
3616 }
3617 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3618 return s0;
3619 }
3620 function peg$parseRESTRICT() {
3621 var s0, s1, s2;
3622 var key = peg$currPos * 306 + 47;
3623 var cached = peg$resultsCache[key];
3624 if (cached) {
3625 peg$currPos = cached.nextPos;
3626 return cached.result;
3627 }
3628 s0 = peg$currPos;
3629 if (input.substr(peg$currPos, 8) === peg$c46) {
3630 s1 = peg$c46;
3631 peg$currPos += 8;
3632 } else {
3633 s1 = peg$FAILED;
3634 if (peg$silentFails === 0) {
3635 peg$fail(peg$e46);
3636 }
3637 }
3638 if (s1 !== peg$FAILED) {
3639 s2 = peg$parseterminal();
3640 if (s2 !== peg$FAILED) {
3641 peg$savedPos = s0;
3642 s0 = peg$f1(s1, s2);
3643 } else {
3644 peg$currPos = s0;
3645 s0 = peg$FAILED;
3646 }
3647 } else {
3648 peg$currPos = s0;
3649 s0 = peg$FAILED;
3650 }
3651 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3652 return s0;
3653 }
3654 function peg$parseREADONLY() {
3655 var s0, s1, s2;
3656 var key = peg$currPos * 306 + 48;
3657 var cached = peg$resultsCache[key];
3658 if (cached) {
3659 peg$currPos = cached.nextPos;
3660 return cached.result;
3661 }
3662 s0 = peg$currPos;
3663 if (input.substr(peg$currPos, 8) === peg$c47) {
3664 s1 = peg$c47;
3665 peg$currPos += 8;
3666 } else {
3667 s1 = peg$FAILED;
3668 if (peg$silentFails === 0) {
3669 peg$fail(peg$e47);
3670 }
3671 }
3672 if (s1 !== peg$FAILED) {
3673 s2 = peg$parseterminal();
3674 if (s2 !== peg$FAILED) {
3675 peg$savedPos = s0;
3676 s0 = peg$f1(s1, s2);
3677 } else {
3678 peg$currPos = s0;
3679 s0 = peg$FAILED;
3680 }
3681 } else {
3682 peg$currPos = s0;
3683 s0 = peg$FAILED;
3684 }
3685 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3686 return s0;
3687 }
3688 function peg$parseWRITEONLY() {
3689 var s0, s1, s2;
3690 var key = peg$currPos * 306 + 49;
3691 var cached = peg$resultsCache[key];
3692 if (cached) {
3693 peg$currPos = cached.nextPos;
3694 return cached.result;
3695 }
3696 s0 = peg$currPos;
3697 if (input.substr(peg$currPos, 9) === peg$c48) {
3698 s1 = peg$c48;
3699 peg$currPos += 9;
3700 } else {
3701 s1 = peg$FAILED;
3702 if (peg$silentFails === 0) {
3703 peg$fail(peg$e48);
3704 }
3705 }
3706 if (s1 !== peg$FAILED) {
3707 s2 = peg$parseterminal();
3708 if (s2 !== peg$FAILED) {
3709 peg$savedPos = s0;
3710 s0 = peg$f1(s1, s2);
3711 } else {
3712 peg$currPos = s0;
3713 s0 = peg$FAILED;
3714 }
3715 } else {
3716 peg$currPos = s0;
3717 s0 = peg$FAILED;
3718 }
3719 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3720 return s0;
3721 }
3722 function peg$parseDVEC2() {
3723 var s0, s1, s2;
3724 var key = peg$currPos * 306 + 50;
3725 var cached = peg$resultsCache[key];
3726 if (cached) {
3727 peg$currPos = cached.nextPos;
3728 return cached.result;
3729 }
3730 s0 = peg$currPos;
3731 if (input.substr(peg$currPos, 5) === peg$c49) {
3732 s1 = peg$c49;
3733 peg$currPos += 5;
3734 } else {
3735 s1 = peg$FAILED;
3736 if (peg$silentFails === 0) {
3737 peg$fail(peg$e49);
3738 }
3739 }
3740 if (s1 !== peg$FAILED) {
3741 s2 = peg$parseterminal();
3742 if (s2 !== peg$FAILED) {
3743 peg$savedPos = s0;
3744 s0 = peg$f1(s1, s2);
3745 } else {
3746 peg$currPos = s0;
3747 s0 = peg$FAILED;
3748 }
3749 } else {
3750 peg$currPos = s0;
3751 s0 = peg$FAILED;
3752 }
3753 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3754 return s0;
3755 }
3756 function peg$parseDVEC3() {
3757 var s0, s1, s2;
3758 var key = peg$currPos * 306 + 51;
3759 var cached = peg$resultsCache[key];
3760 if (cached) {
3761 peg$currPos = cached.nextPos;
3762 return cached.result;
3763 }
3764 s0 = peg$currPos;
3765 if (input.substr(peg$currPos, 5) === peg$c50) {
3766 s1 = peg$c50;
3767 peg$currPos += 5;
3768 } else {
3769 s1 = peg$FAILED;
3770 if (peg$silentFails === 0) {
3771 peg$fail(peg$e50);
3772 }
3773 }
3774 if (s1 !== peg$FAILED) {
3775 s2 = peg$parseterminal();
3776 if (s2 !== peg$FAILED) {
3777 peg$savedPos = s0;
3778 s0 = peg$f1(s1, s2);
3779 } else {
3780 peg$currPos = s0;
3781 s0 = peg$FAILED;
3782 }
3783 } else {
3784 peg$currPos = s0;
3785 s0 = peg$FAILED;
3786 }
3787 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3788 return s0;
3789 }
3790 function peg$parseDVEC4() {
3791 var s0, s1, s2;
3792 var key = peg$currPos * 306 + 52;
3793 var cached = peg$resultsCache[key];
3794 if (cached) {
3795 peg$currPos = cached.nextPos;
3796 return cached.result;
3797 }
3798 s0 = peg$currPos;
3799 if (input.substr(peg$currPos, 5) === peg$c51) {
3800 s1 = peg$c51;
3801 peg$currPos += 5;
3802 } else {
3803 s1 = peg$FAILED;
3804 if (peg$silentFails === 0) {
3805 peg$fail(peg$e51);
3806 }
3807 }
3808 if (s1 !== peg$FAILED) {
3809 s2 = peg$parseterminal();
3810 if (s2 !== peg$FAILED) {
3811 peg$savedPos = s0;
3812 s0 = peg$f1(s1, s2);
3813 } else {
3814 peg$currPos = s0;
3815 s0 = peg$FAILED;
3816 }
3817 } else {
3818 peg$currPos = s0;
3819 s0 = peg$FAILED;
3820 }
3821 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3822 return s0;
3823 }
3824 function peg$parseDMAT2() {
3825 var s0, s1, s2;
3826 var key = peg$currPos * 306 + 53;
3827 var cached = peg$resultsCache[key];
3828 if (cached) {
3829 peg$currPos = cached.nextPos;
3830 return cached.result;
3831 }
3832 s0 = peg$currPos;
3833 if (input.substr(peg$currPos, 5) === peg$c52) {
3834 s1 = peg$c52;
3835 peg$currPos += 5;
3836 } else {
3837 s1 = peg$FAILED;
3838 if (peg$silentFails === 0) {
3839 peg$fail(peg$e52);
3840 }
3841 }
3842 if (s1 !== peg$FAILED) {
3843 s2 = peg$parseterminal();
3844 if (s2 !== peg$FAILED) {
3845 peg$savedPos = s0;
3846 s0 = peg$f1(s1, s2);
3847 } else {
3848 peg$currPos = s0;
3849 s0 = peg$FAILED;
3850 }
3851 } else {
3852 peg$currPos = s0;
3853 s0 = peg$FAILED;
3854 }
3855 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3856 return s0;
3857 }
3858 function peg$parseDMAT3() {
3859 var s0, s1, s2;
3860 var key = peg$currPos * 306 + 54;
3861 var cached = peg$resultsCache[key];
3862 if (cached) {
3863 peg$currPos = cached.nextPos;
3864 return cached.result;
3865 }
3866 s0 = peg$currPos;
3867 if (input.substr(peg$currPos, 5) === peg$c53) {
3868 s1 = peg$c53;
3869 peg$currPos += 5;
3870 } else {
3871 s1 = peg$FAILED;
3872 if (peg$silentFails === 0) {
3873 peg$fail(peg$e53);
3874 }
3875 }
3876 if (s1 !== peg$FAILED) {
3877 s2 = peg$parseterminal();
3878 if (s2 !== peg$FAILED) {
3879 peg$savedPos = s0;
3880 s0 = peg$f1(s1, s2);
3881 } else {
3882 peg$currPos = s0;
3883 s0 = peg$FAILED;
3884 }
3885 } else {
3886 peg$currPos = s0;
3887 s0 = peg$FAILED;
3888 }
3889 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3890 return s0;
3891 }
3892 function peg$parseDMAT4() {
3893 var s0, s1, s2;
3894 var key = peg$currPos * 306 + 55;
3895 var cached = peg$resultsCache[key];
3896 if (cached) {
3897 peg$currPos = cached.nextPos;
3898 return cached.result;
3899 }
3900 s0 = peg$currPos;
3901 if (input.substr(peg$currPos, 5) === peg$c54) {
3902 s1 = peg$c54;
3903 peg$currPos += 5;
3904 } else {
3905 s1 = peg$FAILED;
3906 if (peg$silentFails === 0) {
3907 peg$fail(peg$e54);
3908 }
3909 }
3910 if (s1 !== peg$FAILED) {
3911 s2 = peg$parseterminal();
3912 if (s2 !== peg$FAILED) {
3913 peg$savedPos = s0;
3914 s0 = peg$f1(s1, s2);
3915 } else {
3916 peg$currPos = s0;
3917 s0 = peg$FAILED;
3918 }
3919 } else {
3920 peg$currPos = s0;
3921 s0 = peg$FAILED;
3922 }
3923 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3924 return s0;
3925 }
3926 function peg$parseNOPERSPECTIVE() {
3927 var s0, s1, s2;
3928 var key = peg$currPos * 306 + 56;
3929 var cached = peg$resultsCache[key];
3930 if (cached) {
3931 peg$currPos = cached.nextPos;
3932 return cached.result;
3933 }
3934 s0 = peg$currPos;
3935 if (input.substr(peg$currPos, 13) === peg$c55) {
3936 s1 = peg$c55;
3937 peg$currPos += 13;
3938 } else {
3939 s1 = peg$FAILED;
3940 if (peg$silentFails === 0) {
3941 peg$fail(peg$e55);
3942 }
3943 }
3944 if (s1 !== peg$FAILED) {
3945 s2 = peg$parseterminal();
3946 if (s2 !== peg$FAILED) {
3947 peg$savedPos = s0;
3948 s0 = peg$f1(s1, s2);
3949 } else {
3950 peg$currPos = s0;
3951 s0 = peg$FAILED;
3952 }
3953 } else {
3954 peg$currPos = s0;
3955 s0 = peg$FAILED;
3956 }
3957 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3958 return s0;
3959 }
3960 function peg$parseFLAT() {
3961 var s0, s1, s2;
3962 var key = peg$currPos * 306 + 57;
3963 var cached = peg$resultsCache[key];
3964 if (cached) {
3965 peg$currPos = cached.nextPos;
3966 return cached.result;
3967 }
3968 s0 = peg$currPos;
3969 if (input.substr(peg$currPos, 4) === peg$c56) {
3970 s1 = peg$c56;
3971 peg$currPos += 4;
3972 } else {
3973 s1 = peg$FAILED;
3974 if (peg$silentFails === 0) {
3975 peg$fail(peg$e56);
3976 }
3977 }
3978 if (s1 !== peg$FAILED) {
3979 s2 = peg$parseterminal();
3980 if (s2 !== peg$FAILED) {
3981 peg$savedPos = s0;
3982 s0 = peg$f1(s1, s2);
3983 } else {
3984 peg$currPos = s0;
3985 s0 = peg$FAILED;
3986 }
3987 } else {
3988 peg$currPos = s0;
3989 s0 = peg$FAILED;
3990 }
3991 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
3992 return s0;
3993 }
3994 function peg$parseSMOOTH() {
3995 var s0, s1, s2;
3996 var key = peg$currPos * 306 + 58;
3997 var cached = peg$resultsCache[key];
3998 if (cached) {
3999 peg$currPos = cached.nextPos;
4000 return cached.result;
4001 }
4002 s0 = peg$currPos;
4003 if (input.substr(peg$currPos, 6) === peg$c57) {
4004 s1 = peg$c57;
4005 peg$currPos += 6;
4006 } else {
4007 s1 = peg$FAILED;
4008 if (peg$silentFails === 0) {
4009 peg$fail(peg$e57);
4010 }
4011 }
4012 if (s1 !== peg$FAILED) {
4013 s2 = peg$parseterminal();
4014 if (s2 !== peg$FAILED) {
4015 peg$savedPos = s0;
4016 s0 = peg$f1(s1, s2);
4017 } else {
4018 peg$currPos = s0;
4019 s0 = peg$FAILED;
4020 }
4021 } else {
4022 peg$currPos = s0;
4023 s0 = peg$FAILED;
4024 }
4025 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4026 return s0;
4027 }
4028 function peg$parseLAYOUT() {
4029 var s0, s1, s2;
4030 var key = peg$currPos * 306 + 59;
4031 var cached = peg$resultsCache[key];
4032 if (cached) {
4033 peg$currPos = cached.nextPos;
4034 return cached.result;
4035 }
4036 s0 = peg$currPos;
4037 if (input.substr(peg$currPos, 6) === peg$c58) {
4038 s1 = peg$c58;
4039 peg$currPos += 6;
4040 } else {
4041 s1 = peg$FAILED;
4042 if (peg$silentFails === 0) {
4043 peg$fail(peg$e58);
4044 }
4045 }
4046 if (s1 !== peg$FAILED) {
4047 s2 = peg$parseterminal();
4048 if (s2 !== peg$FAILED) {
4049 peg$savedPos = s0;
4050 s0 = peg$f1(s1, s2);
4051 } else {
4052 peg$currPos = s0;
4053 s0 = peg$FAILED;
4054 }
4055 } else {
4056 peg$currPos = s0;
4057 s0 = peg$FAILED;
4058 }
4059 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4060 return s0;
4061 }
4062 function peg$parseMAT2X2() {
4063 var s0, s1, s2;
4064 var key = peg$currPos * 306 + 60;
4065 var cached = peg$resultsCache[key];
4066 if (cached) {
4067 peg$currPos = cached.nextPos;
4068 return cached.result;
4069 }
4070 s0 = peg$currPos;
4071 if (input.substr(peg$currPos, 6) === peg$c59) {
4072 s1 = peg$c59;
4073 peg$currPos += 6;
4074 } else {
4075 s1 = peg$FAILED;
4076 if (peg$silentFails === 0) {
4077 peg$fail(peg$e59);
4078 }
4079 }
4080 if (s1 !== peg$FAILED) {
4081 s2 = peg$parseterminal();
4082 if (s2 !== peg$FAILED) {
4083 peg$savedPos = s0;
4084 s0 = peg$f1(s1, s2);
4085 } else {
4086 peg$currPos = s0;
4087 s0 = peg$FAILED;
4088 }
4089 } else {
4090 peg$currPos = s0;
4091 s0 = peg$FAILED;
4092 }
4093 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4094 return s0;
4095 }
4096 function peg$parseMAT2X3() {
4097 var s0, s1, s2;
4098 var key = peg$currPos * 306 + 61;
4099 var cached = peg$resultsCache[key];
4100 if (cached) {
4101 peg$currPos = cached.nextPos;
4102 return cached.result;
4103 }
4104 s0 = peg$currPos;
4105 if (input.substr(peg$currPos, 6) === peg$c60) {
4106 s1 = peg$c60;
4107 peg$currPos += 6;
4108 } else {
4109 s1 = peg$FAILED;
4110 if (peg$silentFails === 0) {
4111 peg$fail(peg$e60);
4112 }
4113 }
4114 if (s1 !== peg$FAILED) {
4115 s2 = peg$parseterminal();
4116 if (s2 !== peg$FAILED) {
4117 peg$savedPos = s0;
4118 s0 = peg$f1(s1, s2);
4119 } else {
4120 peg$currPos = s0;
4121 s0 = peg$FAILED;
4122 }
4123 } else {
4124 peg$currPos = s0;
4125 s0 = peg$FAILED;
4126 }
4127 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4128 return s0;
4129 }
4130 function peg$parseMAT2X4() {
4131 var s0, s1, s2;
4132 var key = peg$currPos * 306 + 62;
4133 var cached = peg$resultsCache[key];
4134 if (cached) {
4135 peg$currPos = cached.nextPos;
4136 return cached.result;
4137 }
4138 s0 = peg$currPos;
4139 if (input.substr(peg$currPos, 6) === peg$c61) {
4140 s1 = peg$c61;
4141 peg$currPos += 6;
4142 } else {
4143 s1 = peg$FAILED;
4144 if (peg$silentFails === 0) {
4145 peg$fail(peg$e61);
4146 }
4147 }
4148 if (s1 !== peg$FAILED) {
4149 s2 = peg$parseterminal();
4150 if (s2 !== peg$FAILED) {
4151 peg$savedPos = s0;
4152 s0 = peg$f1(s1, s2);
4153 } else {
4154 peg$currPos = s0;
4155 s0 = peg$FAILED;
4156 }
4157 } else {
4158 peg$currPos = s0;
4159 s0 = peg$FAILED;
4160 }
4161 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4162 return s0;
4163 }
4164 function peg$parseMAT3X2() {
4165 var s0, s1, s2;
4166 var key = peg$currPos * 306 + 63;
4167 var cached = peg$resultsCache[key];
4168 if (cached) {
4169 peg$currPos = cached.nextPos;
4170 return cached.result;
4171 }
4172 s0 = peg$currPos;
4173 if (input.substr(peg$currPos, 6) === peg$c62) {
4174 s1 = peg$c62;
4175 peg$currPos += 6;
4176 } else {
4177 s1 = peg$FAILED;
4178 if (peg$silentFails === 0) {
4179 peg$fail(peg$e62);
4180 }
4181 }
4182 if (s1 !== peg$FAILED) {
4183 s2 = peg$parseterminal();
4184 if (s2 !== peg$FAILED) {
4185 peg$savedPos = s0;
4186 s0 = peg$f1(s1, s2);
4187 } else {
4188 peg$currPos = s0;
4189 s0 = peg$FAILED;
4190 }
4191 } else {
4192 peg$currPos = s0;
4193 s0 = peg$FAILED;
4194 }
4195 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4196 return s0;
4197 }
4198 function peg$parseMAT3X3() {
4199 var s0, s1, s2;
4200 var key = peg$currPos * 306 + 64;
4201 var cached = peg$resultsCache[key];
4202 if (cached) {
4203 peg$currPos = cached.nextPos;
4204 return cached.result;
4205 }
4206 s0 = peg$currPos;
4207 if (input.substr(peg$currPos, 6) === peg$c63) {
4208 s1 = peg$c63;
4209 peg$currPos += 6;
4210 } else {
4211 s1 = peg$FAILED;
4212 if (peg$silentFails === 0) {
4213 peg$fail(peg$e63);
4214 }
4215 }
4216 if (s1 !== peg$FAILED) {
4217 s2 = peg$parseterminal();
4218 if (s2 !== peg$FAILED) {
4219 peg$savedPos = s0;
4220 s0 = peg$f1(s1, s2);
4221 } else {
4222 peg$currPos = s0;
4223 s0 = peg$FAILED;
4224 }
4225 } else {
4226 peg$currPos = s0;
4227 s0 = peg$FAILED;
4228 }
4229 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4230 return s0;
4231 }
4232 function peg$parseMAT3X4() {
4233 var s0, s1, s2;
4234 var key = peg$currPos * 306 + 65;
4235 var cached = peg$resultsCache[key];
4236 if (cached) {
4237 peg$currPos = cached.nextPos;
4238 return cached.result;
4239 }
4240 s0 = peg$currPos;
4241 if (input.substr(peg$currPos, 6) === peg$c64) {
4242 s1 = peg$c64;
4243 peg$currPos += 6;
4244 } else {
4245 s1 = peg$FAILED;
4246 if (peg$silentFails === 0) {
4247 peg$fail(peg$e64);
4248 }
4249 }
4250 if (s1 !== peg$FAILED) {
4251 s2 = peg$parseterminal();
4252 if (s2 !== peg$FAILED) {
4253 peg$savedPos = s0;
4254 s0 = peg$f1(s1, s2);
4255 } else {
4256 peg$currPos = s0;
4257 s0 = peg$FAILED;
4258 }
4259 } else {
4260 peg$currPos = s0;
4261 s0 = peg$FAILED;
4262 }
4263 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4264 return s0;
4265 }
4266 function peg$parseMAT4X2() {
4267 var s0, s1, s2;
4268 var key = peg$currPos * 306 + 66;
4269 var cached = peg$resultsCache[key];
4270 if (cached) {
4271 peg$currPos = cached.nextPos;
4272 return cached.result;
4273 }
4274 s0 = peg$currPos;
4275 if (input.substr(peg$currPos, 6) === peg$c65) {
4276 s1 = peg$c65;
4277 peg$currPos += 6;
4278 } else {
4279 s1 = peg$FAILED;
4280 if (peg$silentFails === 0) {
4281 peg$fail(peg$e65);
4282 }
4283 }
4284 if (s1 !== peg$FAILED) {
4285 s2 = peg$parseterminal();
4286 if (s2 !== peg$FAILED) {
4287 peg$savedPos = s0;
4288 s0 = peg$f1(s1, s2);
4289 } else {
4290 peg$currPos = s0;
4291 s0 = peg$FAILED;
4292 }
4293 } else {
4294 peg$currPos = s0;
4295 s0 = peg$FAILED;
4296 }
4297 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4298 return s0;
4299 }
4300 function peg$parseMAT4X3() {
4301 var s0, s1, s2;
4302 var key = peg$currPos * 306 + 67;
4303 var cached = peg$resultsCache[key];
4304 if (cached) {
4305 peg$currPos = cached.nextPos;
4306 return cached.result;
4307 }
4308 s0 = peg$currPos;
4309 if (input.substr(peg$currPos, 6) === peg$c66) {
4310 s1 = peg$c66;
4311 peg$currPos += 6;
4312 } else {
4313 s1 = peg$FAILED;
4314 if (peg$silentFails === 0) {
4315 peg$fail(peg$e66);
4316 }
4317 }
4318 if (s1 !== peg$FAILED) {
4319 s2 = peg$parseterminal();
4320 if (s2 !== peg$FAILED) {
4321 peg$savedPos = s0;
4322 s0 = peg$f1(s1, s2);
4323 } else {
4324 peg$currPos = s0;
4325 s0 = peg$FAILED;
4326 }
4327 } else {
4328 peg$currPos = s0;
4329 s0 = peg$FAILED;
4330 }
4331 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4332 return s0;
4333 }
4334 function peg$parseMAT4X4() {
4335 var s0, s1, s2;
4336 var key = peg$currPos * 306 + 68;
4337 var cached = peg$resultsCache[key];
4338 if (cached) {
4339 peg$currPos = cached.nextPos;
4340 return cached.result;
4341 }
4342 s0 = peg$currPos;
4343 if (input.substr(peg$currPos, 6) === peg$c67) {
4344 s1 = peg$c67;
4345 peg$currPos += 6;
4346 } else {
4347 s1 = peg$FAILED;
4348 if (peg$silentFails === 0) {
4349 peg$fail(peg$e67);
4350 }
4351 }
4352 if (s1 !== peg$FAILED) {
4353 s2 = peg$parseterminal();
4354 if (s2 !== peg$FAILED) {
4355 peg$savedPos = s0;
4356 s0 = peg$f1(s1, s2);
4357 } else {
4358 peg$currPos = s0;
4359 s0 = peg$FAILED;
4360 }
4361 } else {
4362 peg$currPos = s0;
4363 s0 = peg$FAILED;
4364 }
4365 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4366 return s0;
4367 }
4368 function peg$parseDMAT2X2() {
4369 var s0, s1, s2;
4370 var key = peg$currPos * 306 + 69;
4371 var cached = peg$resultsCache[key];
4372 if (cached) {
4373 peg$currPos = cached.nextPos;
4374 return cached.result;
4375 }
4376 s0 = peg$currPos;
4377 if (input.substr(peg$currPos, 7) === peg$c68) {
4378 s1 = peg$c68;
4379 peg$currPos += 7;
4380 } else {
4381 s1 = peg$FAILED;
4382 if (peg$silentFails === 0) {
4383 peg$fail(peg$e68);
4384 }
4385 }
4386 if (s1 !== peg$FAILED) {
4387 s2 = peg$parseterminal();
4388 if (s2 !== peg$FAILED) {
4389 peg$savedPos = s0;
4390 s0 = peg$f1(s1, s2);
4391 } else {
4392 peg$currPos = s0;
4393 s0 = peg$FAILED;
4394 }
4395 } else {
4396 peg$currPos = s0;
4397 s0 = peg$FAILED;
4398 }
4399 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4400 return s0;
4401 }
4402 function peg$parseDMAT2X3() {
4403 var s0, s1, s2;
4404 var key = peg$currPos * 306 + 70;
4405 var cached = peg$resultsCache[key];
4406 if (cached) {
4407 peg$currPos = cached.nextPos;
4408 return cached.result;
4409 }
4410 s0 = peg$currPos;
4411 if (input.substr(peg$currPos, 7) === peg$c69) {
4412 s1 = peg$c69;
4413 peg$currPos += 7;
4414 } else {
4415 s1 = peg$FAILED;
4416 if (peg$silentFails === 0) {
4417 peg$fail(peg$e69);
4418 }
4419 }
4420 if (s1 !== peg$FAILED) {
4421 s2 = peg$parseterminal();
4422 if (s2 !== peg$FAILED) {
4423 peg$savedPos = s0;
4424 s0 = peg$f1(s1, s2);
4425 } else {
4426 peg$currPos = s0;
4427 s0 = peg$FAILED;
4428 }
4429 } else {
4430 peg$currPos = s0;
4431 s0 = peg$FAILED;
4432 }
4433 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4434 return s0;
4435 }
4436 function peg$parseDMAT2X4() {
4437 var s0, s1, s2;
4438 var key = peg$currPos * 306 + 71;
4439 var cached = peg$resultsCache[key];
4440 if (cached) {
4441 peg$currPos = cached.nextPos;
4442 return cached.result;
4443 }
4444 s0 = peg$currPos;
4445 if (input.substr(peg$currPos, 7) === peg$c70) {
4446 s1 = peg$c70;
4447 peg$currPos += 7;
4448 } else {
4449 s1 = peg$FAILED;
4450 if (peg$silentFails === 0) {
4451 peg$fail(peg$e70);
4452 }
4453 }
4454 if (s1 !== peg$FAILED) {
4455 s2 = peg$parseterminal();
4456 if (s2 !== peg$FAILED) {
4457 peg$savedPos = s0;
4458 s0 = peg$f1(s1, s2);
4459 } else {
4460 peg$currPos = s0;
4461 s0 = peg$FAILED;
4462 }
4463 } else {
4464 peg$currPos = s0;
4465 s0 = peg$FAILED;
4466 }
4467 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4468 return s0;
4469 }
4470 function peg$parseDMAT3X2() {
4471 var s0, s1, s2;
4472 var key = peg$currPos * 306 + 72;
4473 var cached = peg$resultsCache[key];
4474 if (cached) {
4475 peg$currPos = cached.nextPos;
4476 return cached.result;
4477 }
4478 s0 = peg$currPos;
4479 if (input.substr(peg$currPos, 7) === peg$c71) {
4480 s1 = peg$c71;
4481 peg$currPos += 7;
4482 } else {
4483 s1 = peg$FAILED;
4484 if (peg$silentFails === 0) {
4485 peg$fail(peg$e71);
4486 }
4487 }
4488 if (s1 !== peg$FAILED) {
4489 s2 = peg$parseterminal();
4490 if (s2 !== peg$FAILED) {
4491 peg$savedPos = s0;
4492 s0 = peg$f1(s1, s2);
4493 } else {
4494 peg$currPos = s0;
4495 s0 = peg$FAILED;
4496 }
4497 } else {
4498 peg$currPos = s0;
4499 s0 = peg$FAILED;
4500 }
4501 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4502 return s0;
4503 }
4504 function peg$parseDMAT3X3() {
4505 var s0, s1, s2;
4506 var key = peg$currPos * 306 + 73;
4507 var cached = peg$resultsCache[key];
4508 if (cached) {
4509 peg$currPos = cached.nextPos;
4510 return cached.result;
4511 }
4512 s0 = peg$currPos;
4513 if (input.substr(peg$currPos, 7) === peg$c72) {
4514 s1 = peg$c72;
4515 peg$currPos += 7;
4516 } else {
4517 s1 = peg$FAILED;
4518 if (peg$silentFails === 0) {
4519 peg$fail(peg$e72);
4520 }
4521 }
4522 if (s1 !== peg$FAILED) {
4523 s2 = peg$parseterminal();
4524 if (s2 !== peg$FAILED) {
4525 peg$savedPos = s0;
4526 s0 = peg$f1(s1, s2);
4527 } else {
4528 peg$currPos = s0;
4529 s0 = peg$FAILED;
4530 }
4531 } else {
4532 peg$currPos = s0;
4533 s0 = peg$FAILED;
4534 }
4535 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4536 return s0;
4537 }
4538 function peg$parseDMAT3X4() {
4539 var s0, s1, s2;
4540 var key = peg$currPos * 306 + 74;
4541 var cached = peg$resultsCache[key];
4542 if (cached) {
4543 peg$currPos = cached.nextPos;
4544 return cached.result;
4545 }
4546 s0 = peg$currPos;
4547 if (input.substr(peg$currPos, 7) === peg$c73) {
4548 s1 = peg$c73;
4549 peg$currPos += 7;
4550 } else {
4551 s1 = peg$FAILED;
4552 if (peg$silentFails === 0) {
4553 peg$fail(peg$e73);
4554 }
4555 }
4556 if (s1 !== peg$FAILED) {
4557 s2 = peg$parseterminal();
4558 if (s2 !== peg$FAILED) {
4559 peg$savedPos = s0;
4560 s0 = peg$f1(s1, s2);
4561 } else {
4562 peg$currPos = s0;
4563 s0 = peg$FAILED;
4564 }
4565 } else {
4566 peg$currPos = s0;
4567 s0 = peg$FAILED;
4568 }
4569 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4570 return s0;
4571 }
4572 function peg$parseDMAT4X2() {
4573 var s0, s1, s2;
4574 var key = peg$currPos * 306 + 75;
4575 var cached = peg$resultsCache[key];
4576 if (cached) {
4577 peg$currPos = cached.nextPos;
4578 return cached.result;
4579 }
4580 s0 = peg$currPos;
4581 if (input.substr(peg$currPos, 7) === peg$c74) {
4582 s1 = peg$c74;
4583 peg$currPos += 7;
4584 } else {
4585 s1 = peg$FAILED;
4586 if (peg$silentFails === 0) {
4587 peg$fail(peg$e74);
4588 }
4589 }
4590 if (s1 !== peg$FAILED) {
4591 s2 = peg$parseterminal();
4592 if (s2 !== peg$FAILED) {
4593 peg$savedPos = s0;
4594 s0 = peg$f1(s1, s2);
4595 } else {
4596 peg$currPos = s0;
4597 s0 = peg$FAILED;
4598 }
4599 } else {
4600 peg$currPos = s0;
4601 s0 = peg$FAILED;
4602 }
4603 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4604 return s0;
4605 }
4606 function peg$parseDMAT4X3() {
4607 var s0, s1, s2;
4608 var key = peg$currPos * 306 + 76;
4609 var cached = peg$resultsCache[key];
4610 if (cached) {
4611 peg$currPos = cached.nextPos;
4612 return cached.result;
4613 }
4614 s0 = peg$currPos;
4615 if (input.substr(peg$currPos, 7) === peg$c75) {
4616 s1 = peg$c75;
4617 peg$currPos += 7;
4618 } else {
4619 s1 = peg$FAILED;
4620 if (peg$silentFails === 0) {
4621 peg$fail(peg$e75);
4622 }
4623 }
4624 if (s1 !== peg$FAILED) {
4625 s2 = peg$parseterminal();
4626 if (s2 !== peg$FAILED) {
4627 peg$savedPos = s0;
4628 s0 = peg$f1(s1, s2);
4629 } else {
4630 peg$currPos = s0;
4631 s0 = peg$FAILED;
4632 }
4633 } else {
4634 peg$currPos = s0;
4635 s0 = peg$FAILED;
4636 }
4637 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4638 return s0;
4639 }
4640 function peg$parseDMAT4X4() {
4641 var s0, s1, s2;
4642 var key = peg$currPos * 306 + 77;
4643 var cached = peg$resultsCache[key];
4644 if (cached) {
4645 peg$currPos = cached.nextPos;
4646 return cached.result;
4647 }
4648 s0 = peg$currPos;
4649 if (input.substr(peg$currPos, 7) === peg$c76) {
4650 s1 = peg$c76;
4651 peg$currPos += 7;
4652 } else {
4653 s1 = peg$FAILED;
4654 if (peg$silentFails === 0) {
4655 peg$fail(peg$e76);
4656 }
4657 }
4658 if (s1 !== peg$FAILED) {
4659 s2 = peg$parseterminal();
4660 if (s2 !== peg$FAILED) {
4661 peg$savedPos = s0;
4662 s0 = peg$f1(s1, s2);
4663 } else {
4664 peg$currPos = s0;
4665 s0 = peg$FAILED;
4666 }
4667 } else {
4668 peg$currPos = s0;
4669 s0 = peg$FAILED;
4670 }
4671 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4672 return s0;
4673 }
4674 function peg$parseATOMIC_UINT() {
4675 var s0, s1, s2;
4676 var key = peg$currPos * 306 + 78;
4677 var cached = peg$resultsCache[key];
4678 if (cached) {
4679 peg$currPos = cached.nextPos;
4680 return cached.result;
4681 }
4682 s0 = peg$currPos;
4683 if (input.substr(peg$currPos, 11) === peg$c77) {
4684 s1 = peg$c77;
4685 peg$currPos += 11;
4686 } else {
4687 s1 = peg$FAILED;
4688 if (peg$silentFails === 0) {
4689 peg$fail(peg$e77);
4690 }
4691 }
4692 if (s1 !== peg$FAILED) {
4693 s2 = peg$parseterminal();
4694 if (s2 !== peg$FAILED) {
4695 peg$savedPos = s0;
4696 s0 = peg$f1(s1, s2);
4697 } else {
4698 peg$currPos = s0;
4699 s0 = peg$FAILED;
4700 }
4701 } else {
4702 peg$currPos = s0;
4703 s0 = peg$FAILED;
4704 }
4705 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4706 return s0;
4707 }
4708 function peg$parseSAMPLER1D() {
4709 var s0, s1, s2;
4710 var key = peg$currPos * 306 + 79;
4711 var cached = peg$resultsCache[key];
4712 if (cached) {
4713 peg$currPos = cached.nextPos;
4714 return cached.result;
4715 }
4716 s0 = peg$currPos;
4717 if (input.substr(peg$currPos, 9) === peg$c78) {
4718 s1 = peg$c78;
4719 peg$currPos += 9;
4720 } else {
4721 s1 = peg$FAILED;
4722 if (peg$silentFails === 0) {
4723 peg$fail(peg$e78);
4724 }
4725 }
4726 if (s1 !== peg$FAILED) {
4727 s2 = peg$parseterminal();
4728 if (s2 !== peg$FAILED) {
4729 peg$savedPos = s0;
4730 s0 = peg$f1(s1, s2);
4731 } else {
4732 peg$currPos = s0;
4733 s0 = peg$FAILED;
4734 }
4735 } else {
4736 peg$currPos = s0;
4737 s0 = peg$FAILED;
4738 }
4739 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4740 return s0;
4741 }
4742 function peg$parseSAMPLER2D() {
4743 var s0, s1, s2;
4744 var key = peg$currPos * 306 + 80;
4745 var cached = peg$resultsCache[key];
4746 if (cached) {
4747 peg$currPos = cached.nextPos;
4748 return cached.result;
4749 }
4750 s0 = peg$currPos;
4751 if (input.substr(peg$currPos, 9) === peg$c79) {
4752 s1 = peg$c79;
4753 peg$currPos += 9;
4754 } else {
4755 s1 = peg$FAILED;
4756 if (peg$silentFails === 0) {
4757 peg$fail(peg$e79);
4758 }
4759 }
4760 if (s1 !== peg$FAILED) {
4761 s2 = peg$parseterminal();
4762 if (s2 !== peg$FAILED) {
4763 peg$savedPos = s0;
4764 s0 = peg$f1(s1, s2);
4765 } else {
4766 peg$currPos = s0;
4767 s0 = peg$FAILED;
4768 }
4769 } else {
4770 peg$currPos = s0;
4771 s0 = peg$FAILED;
4772 }
4773 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4774 return s0;
4775 }
4776 function peg$parseSAMPLER3D() {
4777 var s0, s1, s2;
4778 var key = peg$currPos * 306 + 81;
4779 var cached = peg$resultsCache[key];
4780 if (cached) {
4781 peg$currPos = cached.nextPos;
4782 return cached.result;
4783 }
4784 s0 = peg$currPos;
4785 if (input.substr(peg$currPos, 9) === peg$c80) {
4786 s1 = peg$c80;
4787 peg$currPos += 9;
4788 } else {
4789 s1 = peg$FAILED;
4790 if (peg$silentFails === 0) {
4791 peg$fail(peg$e80);
4792 }
4793 }
4794 if (s1 !== peg$FAILED) {
4795 s2 = peg$parseterminal();
4796 if (s2 !== peg$FAILED) {
4797 peg$savedPos = s0;
4798 s0 = peg$f1(s1, s2);
4799 } else {
4800 peg$currPos = s0;
4801 s0 = peg$FAILED;
4802 }
4803 } else {
4804 peg$currPos = s0;
4805 s0 = peg$FAILED;
4806 }
4807 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4808 return s0;
4809 }
4810 function peg$parseSAMPLERCUBE() {
4811 var s0, s1, s2;
4812 var key = peg$currPos * 306 + 82;
4813 var cached = peg$resultsCache[key];
4814 if (cached) {
4815 peg$currPos = cached.nextPos;
4816 return cached.result;
4817 }
4818 s0 = peg$currPos;
4819 if (input.substr(peg$currPos, 11) === peg$c81) {
4820 s1 = peg$c81;
4821 peg$currPos += 11;
4822 } else {
4823 s1 = peg$FAILED;
4824 if (peg$silentFails === 0) {
4825 peg$fail(peg$e81);
4826 }
4827 }
4828 if (s1 !== peg$FAILED) {
4829 s2 = peg$parseterminal();
4830 if (s2 !== peg$FAILED) {
4831 peg$savedPos = s0;
4832 s0 = peg$f1(s1, s2);
4833 } else {
4834 peg$currPos = s0;
4835 s0 = peg$FAILED;
4836 }
4837 } else {
4838 peg$currPos = s0;
4839 s0 = peg$FAILED;
4840 }
4841 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4842 return s0;
4843 }
4844 function peg$parseSAMPLER1DSHADOW() {
4845 var s0, s1, s2;
4846 var key = peg$currPos * 306 + 83;
4847 var cached = peg$resultsCache[key];
4848 if (cached) {
4849 peg$currPos = cached.nextPos;
4850 return cached.result;
4851 }
4852 s0 = peg$currPos;
4853 if (input.substr(peg$currPos, 15) === peg$c82) {
4854 s1 = peg$c82;
4855 peg$currPos += 15;
4856 } else {
4857 s1 = peg$FAILED;
4858 if (peg$silentFails === 0) {
4859 peg$fail(peg$e82);
4860 }
4861 }
4862 if (s1 !== peg$FAILED) {
4863 s2 = peg$parseterminal();
4864 if (s2 !== peg$FAILED) {
4865 peg$savedPos = s0;
4866 s0 = peg$f1(s1, s2);
4867 } else {
4868 peg$currPos = s0;
4869 s0 = peg$FAILED;
4870 }
4871 } else {
4872 peg$currPos = s0;
4873 s0 = peg$FAILED;
4874 }
4875 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4876 return s0;
4877 }
4878 function peg$parseSAMPLER2DSHADOW() {
4879 var s0, s1, s2;
4880 var key = peg$currPos * 306 + 84;
4881 var cached = peg$resultsCache[key];
4882 if (cached) {
4883 peg$currPos = cached.nextPos;
4884 return cached.result;
4885 }
4886 s0 = peg$currPos;
4887 if (input.substr(peg$currPos, 15) === peg$c83) {
4888 s1 = peg$c83;
4889 peg$currPos += 15;
4890 } else {
4891 s1 = peg$FAILED;
4892 if (peg$silentFails === 0) {
4893 peg$fail(peg$e83);
4894 }
4895 }
4896 if (s1 !== peg$FAILED) {
4897 s2 = peg$parseterminal();
4898 if (s2 !== peg$FAILED) {
4899 peg$savedPos = s0;
4900 s0 = peg$f1(s1, s2);
4901 } else {
4902 peg$currPos = s0;
4903 s0 = peg$FAILED;
4904 }
4905 } else {
4906 peg$currPos = s0;
4907 s0 = peg$FAILED;
4908 }
4909 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4910 return s0;
4911 }
4912 function peg$parseSAMPLERCUBESHADOW() {
4913 var s0, s1, s2;
4914 var key = peg$currPos * 306 + 85;
4915 var cached = peg$resultsCache[key];
4916 if (cached) {
4917 peg$currPos = cached.nextPos;
4918 return cached.result;
4919 }
4920 s0 = peg$currPos;
4921 if (input.substr(peg$currPos, 17) === peg$c84) {
4922 s1 = peg$c84;
4923 peg$currPos += 17;
4924 } else {
4925 s1 = peg$FAILED;
4926 if (peg$silentFails === 0) {
4927 peg$fail(peg$e84);
4928 }
4929 }
4930 if (s1 !== peg$FAILED) {
4931 s2 = peg$parseterminal();
4932 if (s2 !== peg$FAILED) {
4933 peg$savedPos = s0;
4934 s0 = peg$f1(s1, s2);
4935 } else {
4936 peg$currPos = s0;
4937 s0 = peg$FAILED;
4938 }
4939 } else {
4940 peg$currPos = s0;
4941 s0 = peg$FAILED;
4942 }
4943 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4944 return s0;
4945 }
4946 function peg$parseSAMPLER1DARRAY() {
4947 var s0, s1, s2;
4948 var key = peg$currPos * 306 + 86;
4949 var cached = peg$resultsCache[key];
4950 if (cached) {
4951 peg$currPos = cached.nextPos;
4952 return cached.result;
4953 }
4954 s0 = peg$currPos;
4955 if (input.substr(peg$currPos, 14) === peg$c85) {
4956 s1 = peg$c85;
4957 peg$currPos += 14;
4958 } else {
4959 s1 = peg$FAILED;
4960 if (peg$silentFails === 0) {
4961 peg$fail(peg$e85);
4962 }
4963 }
4964 if (s1 !== peg$FAILED) {
4965 s2 = peg$parseterminal();
4966 if (s2 !== peg$FAILED) {
4967 peg$savedPos = s0;
4968 s0 = peg$f1(s1, s2);
4969 } else {
4970 peg$currPos = s0;
4971 s0 = peg$FAILED;
4972 }
4973 } else {
4974 peg$currPos = s0;
4975 s0 = peg$FAILED;
4976 }
4977 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
4978 return s0;
4979 }
4980 function peg$parseSAMPLER2DARRAY() {
4981 var s0, s1, s2;
4982 var key = peg$currPos * 306 + 87;
4983 var cached = peg$resultsCache[key];
4984 if (cached) {
4985 peg$currPos = cached.nextPos;
4986 return cached.result;
4987 }
4988 s0 = peg$currPos;
4989 if (input.substr(peg$currPos, 14) === peg$c86) {
4990 s1 = peg$c86;
4991 peg$currPos += 14;
4992 } else {
4993 s1 = peg$FAILED;
4994 if (peg$silentFails === 0) {
4995 peg$fail(peg$e86);
4996 }
4997 }
4998 if (s1 !== peg$FAILED) {
4999 s2 = peg$parseterminal();
5000 if (s2 !== peg$FAILED) {
5001 peg$savedPos = s0;
5002 s0 = peg$f1(s1, s2);
5003 } else {
5004 peg$currPos = s0;
5005 s0 = peg$FAILED;
5006 }
5007 } else {
5008 peg$currPos = s0;
5009 s0 = peg$FAILED;
5010 }
5011 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5012 return s0;
5013 }
5014 function peg$parseSAMPLER1DARRAYSHADOW() {
5015 var s0, s1, s2;
5016 var key = peg$currPos * 306 + 88;
5017 var cached = peg$resultsCache[key];
5018 if (cached) {
5019 peg$currPos = cached.nextPos;
5020 return cached.result;
5021 }
5022 s0 = peg$currPos;
5023 if (input.substr(peg$currPos, 20) === peg$c87) {
5024 s1 = peg$c87;
5025 peg$currPos += 20;
5026 } else {
5027 s1 = peg$FAILED;
5028 if (peg$silentFails === 0) {
5029 peg$fail(peg$e87);
5030 }
5031 }
5032 if (s1 !== peg$FAILED) {
5033 s2 = peg$parseterminal();
5034 if (s2 !== peg$FAILED) {
5035 peg$savedPos = s0;
5036 s0 = peg$f1(s1, s2);
5037 } else {
5038 peg$currPos = s0;
5039 s0 = peg$FAILED;
5040 }
5041 } else {
5042 peg$currPos = s0;
5043 s0 = peg$FAILED;
5044 }
5045 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5046 return s0;
5047 }
5048 function peg$parseSAMPLER2DARRAYSHADOW() {
5049 var s0, s1, s2;
5050 var key = peg$currPos * 306 + 89;
5051 var cached = peg$resultsCache[key];
5052 if (cached) {
5053 peg$currPos = cached.nextPos;
5054 return cached.result;
5055 }
5056 s0 = peg$currPos;
5057 if (input.substr(peg$currPos, 20) === peg$c88) {
5058 s1 = peg$c88;
5059 peg$currPos += 20;
5060 } else {
5061 s1 = peg$FAILED;
5062 if (peg$silentFails === 0) {
5063 peg$fail(peg$e88);
5064 }
5065 }
5066 if (s1 !== peg$FAILED) {
5067 s2 = peg$parseterminal();
5068 if (s2 !== peg$FAILED) {
5069 peg$savedPos = s0;
5070 s0 = peg$f1(s1, s2);
5071 } else {
5072 peg$currPos = s0;
5073 s0 = peg$FAILED;
5074 }
5075 } else {
5076 peg$currPos = s0;
5077 s0 = peg$FAILED;
5078 }
5079 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5080 return s0;
5081 }
5082 function peg$parseISAMPLER1D() {
5083 var s0, s1, s2;
5084 var key = peg$currPos * 306 + 90;
5085 var cached = peg$resultsCache[key];
5086 if (cached) {
5087 peg$currPos = cached.nextPos;
5088 return cached.result;
5089 }
5090 s0 = peg$currPos;
5091 if (input.substr(peg$currPos, 10) === peg$c89) {
5092 s1 = peg$c89;
5093 peg$currPos += 10;
5094 } else {
5095 s1 = peg$FAILED;
5096 if (peg$silentFails === 0) {
5097 peg$fail(peg$e89);
5098 }
5099 }
5100 if (s1 !== peg$FAILED) {
5101 s2 = peg$parseterminal();
5102 if (s2 !== peg$FAILED) {
5103 peg$savedPos = s0;
5104 s0 = peg$f1(s1, s2);
5105 } else {
5106 peg$currPos = s0;
5107 s0 = peg$FAILED;
5108 }
5109 } else {
5110 peg$currPos = s0;
5111 s0 = peg$FAILED;
5112 }
5113 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5114 return s0;
5115 }
5116 function peg$parseISAMPLER2D() {
5117 var s0, s1, s2;
5118 var key = peg$currPos * 306 + 91;
5119 var cached = peg$resultsCache[key];
5120 if (cached) {
5121 peg$currPos = cached.nextPos;
5122 return cached.result;
5123 }
5124 s0 = peg$currPos;
5125 if (input.substr(peg$currPos, 10) === peg$c90) {
5126 s1 = peg$c90;
5127 peg$currPos += 10;
5128 } else {
5129 s1 = peg$FAILED;
5130 if (peg$silentFails === 0) {
5131 peg$fail(peg$e90);
5132 }
5133 }
5134 if (s1 !== peg$FAILED) {
5135 s2 = peg$parseterminal();
5136 if (s2 !== peg$FAILED) {
5137 peg$savedPos = s0;
5138 s0 = peg$f1(s1, s2);
5139 } else {
5140 peg$currPos = s0;
5141 s0 = peg$FAILED;
5142 }
5143 } else {
5144 peg$currPos = s0;
5145 s0 = peg$FAILED;
5146 }
5147 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5148 return s0;
5149 }
5150 function peg$parseISAMPLER3D() {
5151 var s0, s1, s2;
5152 var key = peg$currPos * 306 + 92;
5153 var cached = peg$resultsCache[key];
5154 if (cached) {
5155 peg$currPos = cached.nextPos;
5156 return cached.result;
5157 }
5158 s0 = peg$currPos;
5159 if (input.substr(peg$currPos, 10) === peg$c91) {
5160 s1 = peg$c91;
5161 peg$currPos += 10;
5162 } else {
5163 s1 = peg$FAILED;
5164 if (peg$silentFails === 0) {
5165 peg$fail(peg$e91);
5166 }
5167 }
5168 if (s1 !== peg$FAILED) {
5169 s2 = peg$parseterminal();
5170 if (s2 !== peg$FAILED) {
5171 peg$savedPos = s0;
5172 s0 = peg$f1(s1, s2);
5173 } else {
5174 peg$currPos = s0;
5175 s0 = peg$FAILED;
5176 }
5177 } else {
5178 peg$currPos = s0;
5179 s0 = peg$FAILED;
5180 }
5181 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5182 return s0;
5183 }
5184 function peg$parseISAMPLERCUBE() {
5185 var s0, s1, s2;
5186 var key = peg$currPos * 306 + 93;
5187 var cached = peg$resultsCache[key];
5188 if (cached) {
5189 peg$currPos = cached.nextPos;
5190 return cached.result;
5191 }
5192 s0 = peg$currPos;
5193 if (input.substr(peg$currPos, 12) === peg$c92) {
5194 s1 = peg$c92;
5195 peg$currPos += 12;
5196 } else {
5197 s1 = peg$FAILED;
5198 if (peg$silentFails === 0) {
5199 peg$fail(peg$e92);
5200 }
5201 }
5202 if (s1 !== peg$FAILED) {
5203 s2 = peg$parseterminal();
5204 if (s2 !== peg$FAILED) {
5205 peg$savedPos = s0;
5206 s0 = peg$f1(s1, s2);
5207 } else {
5208 peg$currPos = s0;
5209 s0 = peg$FAILED;
5210 }
5211 } else {
5212 peg$currPos = s0;
5213 s0 = peg$FAILED;
5214 }
5215 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5216 return s0;
5217 }
5218 function peg$parseISAMPLER1DARRAY() {
5219 var s0, s1, s2;
5220 var key = peg$currPos * 306 + 94;
5221 var cached = peg$resultsCache[key];
5222 if (cached) {
5223 peg$currPos = cached.nextPos;
5224 return cached.result;
5225 }
5226 s0 = peg$currPos;
5227 if (input.substr(peg$currPos, 15) === peg$c93) {
5228 s1 = peg$c93;
5229 peg$currPos += 15;
5230 } else {
5231 s1 = peg$FAILED;
5232 if (peg$silentFails === 0) {
5233 peg$fail(peg$e93);
5234 }
5235 }
5236 if (s1 !== peg$FAILED) {
5237 s2 = peg$parseterminal();
5238 if (s2 !== peg$FAILED) {
5239 peg$savedPos = s0;
5240 s0 = peg$f1(s1, s2);
5241 } else {
5242 peg$currPos = s0;
5243 s0 = peg$FAILED;
5244 }
5245 } else {
5246 peg$currPos = s0;
5247 s0 = peg$FAILED;
5248 }
5249 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5250 return s0;
5251 }
5252 function peg$parseISAMPLER2DARRAY() {
5253 var s0, s1, s2;
5254 var key = peg$currPos * 306 + 95;
5255 var cached = peg$resultsCache[key];
5256 if (cached) {
5257 peg$currPos = cached.nextPos;
5258 return cached.result;
5259 }
5260 s0 = peg$currPos;
5261 if (input.substr(peg$currPos, 15) === peg$c94) {
5262 s1 = peg$c94;
5263 peg$currPos += 15;
5264 } else {
5265 s1 = peg$FAILED;
5266 if (peg$silentFails === 0) {
5267 peg$fail(peg$e94);
5268 }
5269 }
5270 if (s1 !== peg$FAILED) {
5271 s2 = peg$parseterminal();
5272 if (s2 !== peg$FAILED) {
5273 peg$savedPos = s0;
5274 s0 = peg$f1(s1, s2);
5275 } else {
5276 peg$currPos = s0;
5277 s0 = peg$FAILED;
5278 }
5279 } else {
5280 peg$currPos = s0;
5281 s0 = peg$FAILED;
5282 }
5283 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5284 return s0;
5285 }
5286 function peg$parseUSAMPLER1D() {
5287 var s0, s1, s2;
5288 var key = peg$currPos * 306 + 96;
5289 var cached = peg$resultsCache[key];
5290 if (cached) {
5291 peg$currPos = cached.nextPos;
5292 return cached.result;
5293 }
5294 s0 = peg$currPos;
5295 if (input.substr(peg$currPos, 10) === peg$c95) {
5296 s1 = peg$c95;
5297 peg$currPos += 10;
5298 } else {
5299 s1 = peg$FAILED;
5300 if (peg$silentFails === 0) {
5301 peg$fail(peg$e95);
5302 }
5303 }
5304 if (s1 !== peg$FAILED) {
5305 s2 = peg$parseterminal();
5306 if (s2 !== peg$FAILED) {
5307 peg$savedPos = s0;
5308 s0 = peg$f1(s1, s2);
5309 } else {
5310 peg$currPos = s0;
5311 s0 = peg$FAILED;
5312 }
5313 } else {
5314 peg$currPos = s0;
5315 s0 = peg$FAILED;
5316 }
5317 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5318 return s0;
5319 }
5320 function peg$parseUSAMPLER2D() {
5321 var s0, s1, s2;
5322 var key = peg$currPos * 306 + 97;
5323 var cached = peg$resultsCache[key];
5324 if (cached) {
5325 peg$currPos = cached.nextPos;
5326 return cached.result;
5327 }
5328 s0 = peg$currPos;
5329 if (input.substr(peg$currPos, 10) === peg$c96) {
5330 s1 = peg$c96;
5331 peg$currPos += 10;
5332 } else {
5333 s1 = peg$FAILED;
5334 if (peg$silentFails === 0) {
5335 peg$fail(peg$e96);
5336 }
5337 }
5338 if (s1 !== peg$FAILED) {
5339 s2 = peg$parseterminal();
5340 if (s2 !== peg$FAILED) {
5341 peg$savedPos = s0;
5342 s0 = peg$f1(s1, s2);
5343 } else {
5344 peg$currPos = s0;
5345 s0 = peg$FAILED;
5346 }
5347 } else {
5348 peg$currPos = s0;
5349 s0 = peg$FAILED;
5350 }
5351 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5352 return s0;
5353 }
5354 function peg$parseUSAMPLER3D() {
5355 var s0, s1, s2;
5356 var key = peg$currPos * 306 + 98;
5357 var cached = peg$resultsCache[key];
5358 if (cached) {
5359 peg$currPos = cached.nextPos;
5360 return cached.result;
5361 }
5362 s0 = peg$currPos;
5363 if (input.substr(peg$currPos, 10) === peg$c97) {
5364 s1 = peg$c97;
5365 peg$currPos += 10;
5366 } else {
5367 s1 = peg$FAILED;
5368 if (peg$silentFails === 0) {
5369 peg$fail(peg$e97);
5370 }
5371 }
5372 if (s1 !== peg$FAILED) {
5373 s2 = peg$parseterminal();
5374 if (s2 !== peg$FAILED) {
5375 peg$savedPos = s0;
5376 s0 = peg$f1(s1, s2);
5377 } else {
5378 peg$currPos = s0;
5379 s0 = peg$FAILED;
5380 }
5381 } else {
5382 peg$currPos = s0;
5383 s0 = peg$FAILED;
5384 }
5385 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5386 return s0;
5387 }
5388 function peg$parseUSAMPLERCUBE() {
5389 var s0, s1, s2;
5390 var key = peg$currPos * 306 + 99;
5391 var cached = peg$resultsCache[key];
5392 if (cached) {
5393 peg$currPos = cached.nextPos;
5394 return cached.result;
5395 }
5396 s0 = peg$currPos;
5397 if (input.substr(peg$currPos, 12) === peg$c98) {
5398 s1 = peg$c98;
5399 peg$currPos += 12;
5400 } else {
5401 s1 = peg$FAILED;
5402 if (peg$silentFails === 0) {
5403 peg$fail(peg$e98);
5404 }
5405 }
5406 if (s1 !== peg$FAILED) {
5407 s2 = peg$parseterminal();
5408 if (s2 !== peg$FAILED) {
5409 peg$savedPos = s0;
5410 s0 = peg$f1(s1, s2);
5411 } else {
5412 peg$currPos = s0;
5413 s0 = peg$FAILED;
5414 }
5415 } else {
5416 peg$currPos = s0;
5417 s0 = peg$FAILED;
5418 }
5419 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5420 return s0;
5421 }
5422 function peg$parseUSAMPLER1DARRAY() {
5423 var s0, s1, s2;
5424 var key = peg$currPos * 306 + 100;
5425 var cached = peg$resultsCache[key];
5426 if (cached) {
5427 peg$currPos = cached.nextPos;
5428 return cached.result;
5429 }
5430 s0 = peg$currPos;
5431 if (input.substr(peg$currPos, 15) === peg$c99) {
5432 s1 = peg$c99;
5433 peg$currPos += 15;
5434 } else {
5435 s1 = peg$FAILED;
5436 if (peg$silentFails === 0) {
5437 peg$fail(peg$e99);
5438 }
5439 }
5440 if (s1 !== peg$FAILED) {
5441 s2 = peg$parseterminal();
5442 if (s2 !== peg$FAILED) {
5443 peg$savedPos = s0;
5444 s0 = peg$f1(s1, s2);
5445 } else {
5446 peg$currPos = s0;
5447 s0 = peg$FAILED;
5448 }
5449 } else {
5450 peg$currPos = s0;
5451 s0 = peg$FAILED;
5452 }
5453 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5454 return s0;
5455 }
5456 function peg$parseUSAMPLER2DARRAY() {
5457 var s0, s1, s2;
5458 var key = peg$currPos * 306 + 101;
5459 var cached = peg$resultsCache[key];
5460 if (cached) {
5461 peg$currPos = cached.nextPos;
5462 return cached.result;
5463 }
5464 s0 = peg$currPos;
5465 if (input.substr(peg$currPos, 15) === peg$c100) {
5466 s1 = peg$c100;
5467 peg$currPos += 15;
5468 } else {
5469 s1 = peg$FAILED;
5470 if (peg$silentFails === 0) {
5471 peg$fail(peg$e100);
5472 }
5473 }
5474 if (s1 !== peg$FAILED) {
5475 s2 = peg$parseterminal();
5476 if (s2 !== peg$FAILED) {
5477 peg$savedPos = s0;
5478 s0 = peg$f1(s1, s2);
5479 } else {
5480 peg$currPos = s0;
5481 s0 = peg$FAILED;
5482 }
5483 } else {
5484 peg$currPos = s0;
5485 s0 = peg$FAILED;
5486 }
5487 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5488 return s0;
5489 }
5490 function peg$parseSAMPLER2DRECT() {
5491 var s0, s1, s2;
5492 var key = peg$currPos * 306 + 102;
5493 var cached = peg$resultsCache[key];
5494 if (cached) {
5495 peg$currPos = cached.nextPos;
5496 return cached.result;
5497 }
5498 s0 = peg$currPos;
5499 if (input.substr(peg$currPos, 13) === peg$c101) {
5500 s1 = peg$c101;
5501 peg$currPos += 13;
5502 } else {
5503 s1 = peg$FAILED;
5504 if (peg$silentFails === 0) {
5505 peg$fail(peg$e101);
5506 }
5507 }
5508 if (s1 !== peg$FAILED) {
5509 s2 = peg$parseterminal();
5510 if (s2 !== peg$FAILED) {
5511 peg$savedPos = s0;
5512 s0 = peg$f1(s1, s2);
5513 } else {
5514 peg$currPos = s0;
5515 s0 = peg$FAILED;
5516 }
5517 } else {
5518 peg$currPos = s0;
5519 s0 = peg$FAILED;
5520 }
5521 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5522 return s0;
5523 }
5524 function peg$parseSAMPLER2DRECTSHADOW() {
5525 var s0, s1, s2;
5526 var key = peg$currPos * 306 + 103;
5527 var cached = peg$resultsCache[key];
5528 if (cached) {
5529 peg$currPos = cached.nextPos;
5530 return cached.result;
5531 }
5532 s0 = peg$currPos;
5533 if (input.substr(peg$currPos, 19) === peg$c102) {
5534 s1 = peg$c102;
5535 peg$currPos += 19;
5536 } else {
5537 s1 = peg$FAILED;
5538 if (peg$silentFails === 0) {
5539 peg$fail(peg$e102);
5540 }
5541 }
5542 if (s1 !== peg$FAILED) {
5543 s2 = peg$parseterminal();
5544 if (s2 !== peg$FAILED) {
5545 peg$savedPos = s0;
5546 s0 = peg$f1(s1, s2);
5547 } else {
5548 peg$currPos = s0;
5549 s0 = peg$FAILED;
5550 }
5551 } else {
5552 peg$currPos = s0;
5553 s0 = peg$FAILED;
5554 }
5555 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5556 return s0;
5557 }
5558 function peg$parseISAMPLER2DRECT() {
5559 var s0, s1, s2;
5560 var key = peg$currPos * 306 + 104;
5561 var cached = peg$resultsCache[key];
5562 if (cached) {
5563 peg$currPos = cached.nextPos;
5564 return cached.result;
5565 }
5566 s0 = peg$currPos;
5567 if (input.substr(peg$currPos, 14) === peg$c103) {
5568 s1 = peg$c103;
5569 peg$currPos += 14;
5570 } else {
5571 s1 = peg$FAILED;
5572 if (peg$silentFails === 0) {
5573 peg$fail(peg$e103);
5574 }
5575 }
5576 if (s1 !== peg$FAILED) {
5577 s2 = peg$parseterminal();
5578 if (s2 !== peg$FAILED) {
5579 peg$savedPos = s0;
5580 s0 = peg$f1(s1, s2);
5581 } else {
5582 peg$currPos = s0;
5583 s0 = peg$FAILED;
5584 }
5585 } else {
5586 peg$currPos = s0;
5587 s0 = peg$FAILED;
5588 }
5589 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5590 return s0;
5591 }
5592 function peg$parseUSAMPLER2DRECT() {
5593 var s0, s1, s2;
5594 var key = peg$currPos * 306 + 105;
5595 var cached = peg$resultsCache[key];
5596 if (cached) {
5597 peg$currPos = cached.nextPos;
5598 return cached.result;
5599 }
5600 s0 = peg$currPos;
5601 if (input.substr(peg$currPos, 14) === peg$c104) {
5602 s1 = peg$c104;
5603 peg$currPos += 14;
5604 } else {
5605 s1 = peg$FAILED;
5606 if (peg$silentFails === 0) {
5607 peg$fail(peg$e104);
5608 }
5609 }
5610 if (s1 !== peg$FAILED) {
5611 s2 = peg$parseterminal();
5612 if (s2 !== peg$FAILED) {
5613 peg$savedPos = s0;
5614 s0 = peg$f1(s1, s2);
5615 } else {
5616 peg$currPos = s0;
5617 s0 = peg$FAILED;
5618 }
5619 } else {
5620 peg$currPos = s0;
5621 s0 = peg$FAILED;
5622 }
5623 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5624 return s0;
5625 }
5626 function peg$parseSAMPLERBUFFER() {
5627 var s0, s1, s2;
5628 var key = peg$currPos * 306 + 106;
5629 var cached = peg$resultsCache[key];
5630 if (cached) {
5631 peg$currPos = cached.nextPos;
5632 return cached.result;
5633 }
5634 s0 = peg$currPos;
5635 if (input.substr(peg$currPos, 13) === peg$c105) {
5636 s1 = peg$c105;
5637 peg$currPos += 13;
5638 } else {
5639 s1 = peg$FAILED;
5640 if (peg$silentFails === 0) {
5641 peg$fail(peg$e105);
5642 }
5643 }
5644 if (s1 !== peg$FAILED) {
5645 s2 = peg$parseterminal();
5646 if (s2 !== peg$FAILED) {
5647 peg$savedPos = s0;
5648 s0 = peg$f1(s1, s2);
5649 } else {
5650 peg$currPos = s0;
5651 s0 = peg$FAILED;
5652 }
5653 } else {
5654 peg$currPos = s0;
5655 s0 = peg$FAILED;
5656 }
5657 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5658 return s0;
5659 }
5660 function peg$parseISAMPLERBUFFER() {
5661 var s0, s1, s2;
5662 var key = peg$currPos * 306 + 107;
5663 var cached = peg$resultsCache[key];
5664 if (cached) {
5665 peg$currPos = cached.nextPos;
5666 return cached.result;
5667 }
5668 s0 = peg$currPos;
5669 if (input.substr(peg$currPos, 14) === peg$c106) {
5670 s1 = peg$c106;
5671 peg$currPos += 14;
5672 } else {
5673 s1 = peg$FAILED;
5674 if (peg$silentFails === 0) {
5675 peg$fail(peg$e106);
5676 }
5677 }
5678 if (s1 !== peg$FAILED) {
5679 s2 = peg$parseterminal();
5680 if (s2 !== peg$FAILED) {
5681 peg$savedPos = s0;
5682 s0 = peg$f1(s1, s2);
5683 } else {
5684 peg$currPos = s0;
5685 s0 = peg$FAILED;
5686 }
5687 } else {
5688 peg$currPos = s0;
5689 s0 = peg$FAILED;
5690 }
5691 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5692 return s0;
5693 }
5694 function peg$parseUSAMPLERBUFFER() {
5695 var s0, s1, s2;
5696 var key = peg$currPos * 306 + 108;
5697 var cached = peg$resultsCache[key];
5698 if (cached) {
5699 peg$currPos = cached.nextPos;
5700 return cached.result;
5701 }
5702 s0 = peg$currPos;
5703 if (input.substr(peg$currPos, 14) === peg$c107) {
5704 s1 = peg$c107;
5705 peg$currPos += 14;
5706 } else {
5707 s1 = peg$FAILED;
5708 if (peg$silentFails === 0) {
5709 peg$fail(peg$e107);
5710 }
5711 }
5712 if (s1 !== peg$FAILED) {
5713 s2 = peg$parseterminal();
5714 if (s2 !== peg$FAILED) {
5715 peg$savedPos = s0;
5716 s0 = peg$f1(s1, s2);
5717 } else {
5718 peg$currPos = s0;
5719 s0 = peg$FAILED;
5720 }
5721 } else {
5722 peg$currPos = s0;
5723 s0 = peg$FAILED;
5724 }
5725 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5726 return s0;
5727 }
5728 function peg$parseSAMPLERCUBEARRAY() {
5729 var s0, s1, s2;
5730 var key = peg$currPos * 306 + 109;
5731 var cached = peg$resultsCache[key];
5732 if (cached) {
5733 peg$currPos = cached.nextPos;
5734 return cached.result;
5735 }
5736 s0 = peg$currPos;
5737 if (input.substr(peg$currPos, 16) === peg$c108) {
5738 s1 = peg$c108;
5739 peg$currPos += 16;
5740 } else {
5741 s1 = peg$FAILED;
5742 if (peg$silentFails === 0) {
5743 peg$fail(peg$e108);
5744 }
5745 }
5746 if (s1 !== peg$FAILED) {
5747 s2 = peg$parseterminal();
5748 if (s2 !== peg$FAILED) {
5749 peg$savedPos = s0;
5750 s0 = peg$f1(s1, s2);
5751 } else {
5752 peg$currPos = s0;
5753 s0 = peg$FAILED;
5754 }
5755 } else {
5756 peg$currPos = s0;
5757 s0 = peg$FAILED;
5758 }
5759 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5760 return s0;
5761 }
5762 function peg$parseSAMPLERCUBEARRAYSHADOW() {
5763 var s0, s1, s2;
5764 var key = peg$currPos * 306 + 110;
5765 var cached = peg$resultsCache[key];
5766 if (cached) {
5767 peg$currPos = cached.nextPos;
5768 return cached.result;
5769 }
5770 s0 = peg$currPos;
5771 if (input.substr(peg$currPos, 22) === peg$c109) {
5772 s1 = peg$c109;
5773 peg$currPos += 22;
5774 } else {
5775 s1 = peg$FAILED;
5776 if (peg$silentFails === 0) {
5777 peg$fail(peg$e109);
5778 }
5779 }
5780 if (s1 !== peg$FAILED) {
5781 s2 = peg$parseterminal();
5782 if (s2 !== peg$FAILED) {
5783 peg$savedPos = s0;
5784 s0 = peg$f1(s1, s2);
5785 } else {
5786 peg$currPos = s0;
5787 s0 = peg$FAILED;
5788 }
5789 } else {
5790 peg$currPos = s0;
5791 s0 = peg$FAILED;
5792 }
5793 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5794 return s0;
5795 }
5796 function peg$parseISAMPLERCUBEARRAY() {
5797 var s0, s1, s2;
5798 var key = peg$currPos * 306 + 111;
5799 var cached = peg$resultsCache[key];
5800 if (cached) {
5801 peg$currPos = cached.nextPos;
5802 return cached.result;
5803 }
5804 s0 = peg$currPos;
5805 if (input.substr(peg$currPos, 17) === peg$c110) {
5806 s1 = peg$c110;
5807 peg$currPos += 17;
5808 } else {
5809 s1 = peg$FAILED;
5810 if (peg$silentFails === 0) {
5811 peg$fail(peg$e110);
5812 }
5813 }
5814 if (s1 !== peg$FAILED) {
5815 s2 = peg$parseterminal();
5816 if (s2 !== peg$FAILED) {
5817 peg$savedPos = s0;
5818 s0 = peg$f1(s1, s2);
5819 } else {
5820 peg$currPos = s0;
5821 s0 = peg$FAILED;
5822 }
5823 } else {
5824 peg$currPos = s0;
5825 s0 = peg$FAILED;
5826 }
5827 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5828 return s0;
5829 }
5830 function peg$parseUSAMPLERCUBEARRAY() {
5831 var s0, s1, s2;
5832 var key = peg$currPos * 306 + 112;
5833 var cached = peg$resultsCache[key];
5834 if (cached) {
5835 peg$currPos = cached.nextPos;
5836 return cached.result;
5837 }
5838 s0 = peg$currPos;
5839 if (input.substr(peg$currPos, 17) === peg$c111) {
5840 s1 = peg$c111;
5841 peg$currPos += 17;
5842 } else {
5843 s1 = peg$FAILED;
5844 if (peg$silentFails === 0) {
5845 peg$fail(peg$e111);
5846 }
5847 }
5848 if (s1 !== peg$FAILED) {
5849 s2 = peg$parseterminal();
5850 if (s2 !== peg$FAILED) {
5851 peg$savedPos = s0;
5852 s0 = peg$f1(s1, s2);
5853 } else {
5854 peg$currPos = s0;
5855 s0 = peg$FAILED;
5856 }
5857 } else {
5858 peg$currPos = s0;
5859 s0 = peg$FAILED;
5860 }
5861 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5862 return s0;
5863 }
5864 function peg$parseSAMPLER2DMS() {
5865 var s0, s1, s2;
5866 var key = peg$currPos * 306 + 113;
5867 var cached = peg$resultsCache[key];
5868 if (cached) {
5869 peg$currPos = cached.nextPos;
5870 return cached.result;
5871 }
5872 s0 = peg$currPos;
5873 if (input.substr(peg$currPos, 11) === peg$c112) {
5874 s1 = peg$c112;
5875 peg$currPos += 11;
5876 } else {
5877 s1 = peg$FAILED;
5878 if (peg$silentFails === 0) {
5879 peg$fail(peg$e112);
5880 }
5881 }
5882 if (s1 !== peg$FAILED) {
5883 s2 = peg$parseterminal();
5884 if (s2 !== peg$FAILED) {
5885 peg$savedPos = s0;
5886 s0 = peg$f1(s1, s2);
5887 } else {
5888 peg$currPos = s0;
5889 s0 = peg$FAILED;
5890 }
5891 } else {
5892 peg$currPos = s0;
5893 s0 = peg$FAILED;
5894 }
5895 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5896 return s0;
5897 }
5898 function peg$parseISAMPLER2DMS() {
5899 var s0, s1, s2;
5900 var key = peg$currPos * 306 + 114;
5901 var cached = peg$resultsCache[key];
5902 if (cached) {
5903 peg$currPos = cached.nextPos;
5904 return cached.result;
5905 }
5906 s0 = peg$currPos;
5907 if (input.substr(peg$currPos, 12) === peg$c113) {
5908 s1 = peg$c113;
5909 peg$currPos += 12;
5910 } else {
5911 s1 = peg$FAILED;
5912 if (peg$silentFails === 0) {
5913 peg$fail(peg$e113);
5914 }
5915 }
5916 if (s1 !== peg$FAILED) {
5917 s2 = peg$parseterminal();
5918 if (s2 !== peg$FAILED) {
5919 peg$savedPos = s0;
5920 s0 = peg$f1(s1, s2);
5921 } else {
5922 peg$currPos = s0;
5923 s0 = peg$FAILED;
5924 }
5925 } else {
5926 peg$currPos = s0;
5927 s0 = peg$FAILED;
5928 }
5929 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5930 return s0;
5931 }
5932 function peg$parseUSAMPLER2DMS() {
5933 var s0, s1, s2;
5934 var key = peg$currPos * 306 + 115;
5935 var cached = peg$resultsCache[key];
5936 if (cached) {
5937 peg$currPos = cached.nextPos;
5938 return cached.result;
5939 }
5940 s0 = peg$currPos;
5941 if (input.substr(peg$currPos, 12) === peg$c114) {
5942 s1 = peg$c114;
5943 peg$currPos += 12;
5944 } else {
5945 s1 = peg$FAILED;
5946 if (peg$silentFails === 0) {
5947 peg$fail(peg$e114);
5948 }
5949 }
5950 if (s1 !== peg$FAILED) {
5951 s2 = peg$parseterminal();
5952 if (s2 !== peg$FAILED) {
5953 peg$savedPos = s0;
5954 s0 = peg$f1(s1, s2);
5955 } else {
5956 peg$currPos = s0;
5957 s0 = peg$FAILED;
5958 }
5959 } else {
5960 peg$currPos = s0;
5961 s0 = peg$FAILED;
5962 }
5963 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5964 return s0;
5965 }
5966 function peg$parseSAMPLER2DMSARRAY() {
5967 var s0, s1, s2;
5968 var key = peg$currPos * 306 + 116;
5969 var cached = peg$resultsCache[key];
5970 if (cached) {
5971 peg$currPos = cached.nextPos;
5972 return cached.result;
5973 }
5974 s0 = peg$currPos;
5975 if (input.substr(peg$currPos, 16) === peg$c115) {
5976 s1 = peg$c115;
5977 peg$currPos += 16;
5978 } else {
5979 s1 = peg$FAILED;
5980 if (peg$silentFails === 0) {
5981 peg$fail(peg$e115);
5982 }
5983 }
5984 if (s1 !== peg$FAILED) {
5985 s2 = peg$parseterminal();
5986 if (s2 !== peg$FAILED) {
5987 peg$savedPos = s0;
5988 s0 = peg$f1(s1, s2);
5989 } else {
5990 peg$currPos = s0;
5991 s0 = peg$FAILED;
5992 }
5993 } else {
5994 peg$currPos = s0;
5995 s0 = peg$FAILED;
5996 }
5997 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
5998 return s0;
5999 }
6000 function peg$parseISAMPLER2DMSARRAY() {
6001 var s0, s1, s2;
6002 var key = peg$currPos * 306 + 117;
6003 var cached = peg$resultsCache[key];
6004 if (cached) {
6005 peg$currPos = cached.nextPos;
6006 return cached.result;
6007 }
6008 s0 = peg$currPos;
6009 if (input.substr(peg$currPos, 17) === peg$c116) {
6010 s1 = peg$c116;
6011 peg$currPos += 17;
6012 } else {
6013 s1 = peg$FAILED;
6014 if (peg$silentFails === 0) {
6015 peg$fail(peg$e116);
6016 }
6017 }
6018 if (s1 !== peg$FAILED) {
6019 s2 = peg$parseterminal();
6020 if (s2 !== peg$FAILED) {
6021 peg$savedPos = s0;
6022 s0 = peg$f1(s1, s2);
6023 } else {
6024 peg$currPos = s0;
6025 s0 = peg$FAILED;
6026 }
6027 } else {
6028 peg$currPos = s0;
6029 s0 = peg$FAILED;
6030 }
6031 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6032 return s0;
6033 }
6034 function peg$parseUSAMPLER2DMSARRAY() {
6035 var s0, s1, s2;
6036 var key = peg$currPos * 306 + 118;
6037 var cached = peg$resultsCache[key];
6038 if (cached) {
6039 peg$currPos = cached.nextPos;
6040 return cached.result;
6041 }
6042 s0 = peg$currPos;
6043 if (input.substr(peg$currPos, 17) === peg$c117) {
6044 s1 = peg$c117;
6045 peg$currPos += 17;
6046 } else {
6047 s1 = peg$FAILED;
6048 if (peg$silentFails === 0) {
6049 peg$fail(peg$e117);
6050 }
6051 }
6052 if (s1 !== peg$FAILED) {
6053 s2 = peg$parseterminal();
6054 if (s2 !== peg$FAILED) {
6055 peg$savedPos = s0;
6056 s0 = peg$f1(s1, s2);
6057 } else {
6058 peg$currPos = s0;
6059 s0 = peg$FAILED;
6060 }
6061 } else {
6062 peg$currPos = s0;
6063 s0 = peg$FAILED;
6064 }
6065 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6066 return s0;
6067 }
6068 function peg$parseIMAGE1D() {
6069 var s0, s1, s2;
6070 var key = peg$currPos * 306 + 119;
6071 var cached = peg$resultsCache[key];
6072 if (cached) {
6073 peg$currPos = cached.nextPos;
6074 return cached.result;
6075 }
6076 s0 = peg$currPos;
6077 if (input.substr(peg$currPos, 7) === peg$c118) {
6078 s1 = peg$c118;
6079 peg$currPos += 7;
6080 } else {
6081 s1 = peg$FAILED;
6082 if (peg$silentFails === 0) {
6083 peg$fail(peg$e118);
6084 }
6085 }
6086 if (s1 !== peg$FAILED) {
6087 s2 = peg$parseterminal();
6088 if (s2 !== peg$FAILED) {
6089 peg$savedPos = s0;
6090 s0 = peg$f1(s1, s2);
6091 } else {
6092 peg$currPos = s0;
6093 s0 = peg$FAILED;
6094 }
6095 } else {
6096 peg$currPos = s0;
6097 s0 = peg$FAILED;
6098 }
6099 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6100 return s0;
6101 }
6102 function peg$parseIIMAGE1D() {
6103 var s0, s1, s2;
6104 var key = peg$currPos * 306 + 120;
6105 var cached = peg$resultsCache[key];
6106 if (cached) {
6107 peg$currPos = cached.nextPos;
6108 return cached.result;
6109 }
6110 s0 = peg$currPos;
6111 if (input.substr(peg$currPos, 8) === peg$c119) {
6112 s1 = peg$c119;
6113 peg$currPos += 8;
6114 } else {
6115 s1 = peg$FAILED;
6116 if (peg$silentFails === 0) {
6117 peg$fail(peg$e119);
6118 }
6119 }
6120 if (s1 !== peg$FAILED) {
6121 s2 = peg$parseterminal();
6122 if (s2 !== peg$FAILED) {
6123 peg$savedPos = s0;
6124 s0 = peg$f1(s1, s2);
6125 } else {
6126 peg$currPos = s0;
6127 s0 = peg$FAILED;
6128 }
6129 } else {
6130 peg$currPos = s0;
6131 s0 = peg$FAILED;
6132 }
6133 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6134 return s0;
6135 }
6136 function peg$parseUIMAGE1D() {
6137 var s0, s1, s2;
6138 var key = peg$currPos * 306 + 121;
6139 var cached = peg$resultsCache[key];
6140 if (cached) {
6141 peg$currPos = cached.nextPos;
6142 return cached.result;
6143 }
6144 s0 = peg$currPos;
6145 if (input.substr(peg$currPos, 8) === peg$c120) {
6146 s1 = peg$c120;
6147 peg$currPos += 8;
6148 } else {
6149 s1 = peg$FAILED;
6150 if (peg$silentFails === 0) {
6151 peg$fail(peg$e120);
6152 }
6153 }
6154 if (s1 !== peg$FAILED) {
6155 s2 = peg$parseterminal();
6156 if (s2 !== peg$FAILED) {
6157 peg$savedPos = s0;
6158 s0 = peg$f1(s1, s2);
6159 } else {
6160 peg$currPos = s0;
6161 s0 = peg$FAILED;
6162 }
6163 } else {
6164 peg$currPos = s0;
6165 s0 = peg$FAILED;
6166 }
6167 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6168 return s0;
6169 }
6170 function peg$parseIMAGE2D() {
6171 var s0, s1, s2;
6172 var key = peg$currPos * 306 + 122;
6173 var cached = peg$resultsCache[key];
6174 if (cached) {
6175 peg$currPos = cached.nextPos;
6176 return cached.result;
6177 }
6178 s0 = peg$currPos;
6179 if (input.substr(peg$currPos, 7) === peg$c121) {
6180 s1 = peg$c121;
6181 peg$currPos += 7;
6182 } else {
6183 s1 = peg$FAILED;
6184 if (peg$silentFails === 0) {
6185 peg$fail(peg$e121);
6186 }
6187 }
6188 if (s1 !== peg$FAILED) {
6189 s2 = peg$parseterminal();
6190 if (s2 !== peg$FAILED) {
6191 peg$savedPos = s0;
6192 s0 = peg$f1(s1, s2);
6193 } else {
6194 peg$currPos = s0;
6195 s0 = peg$FAILED;
6196 }
6197 } else {
6198 peg$currPos = s0;
6199 s0 = peg$FAILED;
6200 }
6201 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6202 return s0;
6203 }
6204 function peg$parseIIMAGE2D() {
6205 var s0, s1, s2;
6206 var key = peg$currPos * 306 + 123;
6207 var cached = peg$resultsCache[key];
6208 if (cached) {
6209 peg$currPos = cached.nextPos;
6210 return cached.result;
6211 }
6212 s0 = peg$currPos;
6213 if (input.substr(peg$currPos, 8) === peg$c122) {
6214 s1 = peg$c122;
6215 peg$currPos += 8;
6216 } else {
6217 s1 = peg$FAILED;
6218 if (peg$silentFails === 0) {
6219 peg$fail(peg$e122);
6220 }
6221 }
6222 if (s1 !== peg$FAILED) {
6223 s2 = peg$parseterminal();
6224 if (s2 !== peg$FAILED) {
6225 peg$savedPos = s0;
6226 s0 = peg$f1(s1, s2);
6227 } else {
6228 peg$currPos = s0;
6229 s0 = peg$FAILED;
6230 }
6231 } else {
6232 peg$currPos = s0;
6233 s0 = peg$FAILED;
6234 }
6235 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6236 return s0;
6237 }
6238 function peg$parseUIMAGE2D() {
6239 var s0, s1, s2;
6240 var key = peg$currPos * 306 + 124;
6241 var cached = peg$resultsCache[key];
6242 if (cached) {
6243 peg$currPos = cached.nextPos;
6244 return cached.result;
6245 }
6246 s0 = peg$currPos;
6247 if (input.substr(peg$currPos, 8) === peg$c123) {
6248 s1 = peg$c123;
6249 peg$currPos += 8;
6250 } else {
6251 s1 = peg$FAILED;
6252 if (peg$silentFails === 0) {
6253 peg$fail(peg$e123);
6254 }
6255 }
6256 if (s1 !== peg$FAILED) {
6257 s2 = peg$parseterminal();
6258 if (s2 !== peg$FAILED) {
6259 peg$savedPos = s0;
6260 s0 = peg$f1(s1, s2);
6261 } else {
6262 peg$currPos = s0;
6263 s0 = peg$FAILED;
6264 }
6265 } else {
6266 peg$currPos = s0;
6267 s0 = peg$FAILED;
6268 }
6269 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6270 return s0;
6271 }
6272 function peg$parseIMAGE3D() {
6273 var s0, s1, s2;
6274 var key = peg$currPos * 306 + 125;
6275 var cached = peg$resultsCache[key];
6276 if (cached) {
6277 peg$currPos = cached.nextPos;
6278 return cached.result;
6279 }
6280 s0 = peg$currPos;
6281 if (input.substr(peg$currPos, 7) === peg$c124) {
6282 s1 = peg$c124;
6283 peg$currPos += 7;
6284 } else {
6285 s1 = peg$FAILED;
6286 if (peg$silentFails === 0) {
6287 peg$fail(peg$e124);
6288 }
6289 }
6290 if (s1 !== peg$FAILED) {
6291 s2 = peg$parseterminal();
6292 if (s2 !== peg$FAILED) {
6293 peg$savedPos = s0;
6294 s0 = peg$f1(s1, s2);
6295 } else {
6296 peg$currPos = s0;
6297 s0 = peg$FAILED;
6298 }
6299 } else {
6300 peg$currPos = s0;
6301 s0 = peg$FAILED;
6302 }
6303 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6304 return s0;
6305 }
6306 function peg$parseIIMAGE3D() {
6307 var s0, s1, s2;
6308 var key = peg$currPos * 306 + 126;
6309 var cached = peg$resultsCache[key];
6310 if (cached) {
6311 peg$currPos = cached.nextPos;
6312 return cached.result;
6313 }
6314 s0 = peg$currPos;
6315 if (input.substr(peg$currPos, 8) === peg$c125) {
6316 s1 = peg$c125;
6317 peg$currPos += 8;
6318 } else {
6319 s1 = peg$FAILED;
6320 if (peg$silentFails === 0) {
6321 peg$fail(peg$e125);
6322 }
6323 }
6324 if (s1 !== peg$FAILED) {
6325 s2 = peg$parseterminal();
6326 if (s2 !== peg$FAILED) {
6327 peg$savedPos = s0;
6328 s0 = peg$f1(s1, s2);
6329 } else {
6330 peg$currPos = s0;
6331 s0 = peg$FAILED;
6332 }
6333 } else {
6334 peg$currPos = s0;
6335 s0 = peg$FAILED;
6336 }
6337 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6338 return s0;
6339 }
6340 function peg$parseUIMAGE3D() {
6341 var s0, s1, s2;
6342 var key = peg$currPos * 306 + 127;
6343 var cached = peg$resultsCache[key];
6344 if (cached) {
6345 peg$currPos = cached.nextPos;
6346 return cached.result;
6347 }
6348 s0 = peg$currPos;
6349 if (input.substr(peg$currPos, 8) === peg$c126) {
6350 s1 = peg$c126;
6351 peg$currPos += 8;
6352 } else {
6353 s1 = peg$FAILED;
6354 if (peg$silentFails === 0) {
6355 peg$fail(peg$e126);
6356 }
6357 }
6358 if (s1 !== peg$FAILED) {
6359 s2 = peg$parseterminal();
6360 if (s2 !== peg$FAILED) {
6361 peg$savedPos = s0;
6362 s0 = peg$f1(s1, s2);
6363 } else {
6364 peg$currPos = s0;
6365 s0 = peg$FAILED;
6366 }
6367 } else {
6368 peg$currPos = s0;
6369 s0 = peg$FAILED;
6370 }
6371 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6372 return s0;
6373 }
6374 function peg$parseIMAGE2DRECT() {
6375 var s0, s1, s2;
6376 var key = peg$currPos * 306 + 128;
6377 var cached = peg$resultsCache[key];
6378 if (cached) {
6379 peg$currPos = cached.nextPos;
6380 return cached.result;
6381 }
6382 s0 = peg$currPos;
6383 if (input.substr(peg$currPos, 11) === peg$c127) {
6384 s1 = peg$c127;
6385 peg$currPos += 11;
6386 } else {
6387 s1 = peg$FAILED;
6388 if (peg$silentFails === 0) {
6389 peg$fail(peg$e127);
6390 }
6391 }
6392 if (s1 !== peg$FAILED) {
6393 s2 = peg$parseterminal();
6394 if (s2 !== peg$FAILED) {
6395 peg$savedPos = s0;
6396 s0 = peg$f1(s1, s2);
6397 } else {
6398 peg$currPos = s0;
6399 s0 = peg$FAILED;
6400 }
6401 } else {
6402 peg$currPos = s0;
6403 s0 = peg$FAILED;
6404 }
6405 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6406 return s0;
6407 }
6408 function peg$parseIIMAGE2DRECT() {
6409 var s0, s1, s2;
6410 var key = peg$currPos * 306 + 129;
6411 var cached = peg$resultsCache[key];
6412 if (cached) {
6413 peg$currPos = cached.nextPos;
6414 return cached.result;
6415 }
6416 s0 = peg$currPos;
6417 if (input.substr(peg$currPos, 12) === peg$c128) {
6418 s1 = peg$c128;
6419 peg$currPos += 12;
6420 } else {
6421 s1 = peg$FAILED;
6422 if (peg$silentFails === 0) {
6423 peg$fail(peg$e128);
6424 }
6425 }
6426 if (s1 !== peg$FAILED) {
6427 s2 = peg$parseterminal();
6428 if (s2 !== peg$FAILED) {
6429 peg$savedPos = s0;
6430 s0 = peg$f1(s1, s2);
6431 } else {
6432 peg$currPos = s0;
6433 s0 = peg$FAILED;
6434 }
6435 } else {
6436 peg$currPos = s0;
6437 s0 = peg$FAILED;
6438 }
6439 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6440 return s0;
6441 }
6442 function peg$parseUIMAGE2DRECT() {
6443 var s0, s1, s2;
6444 var key = peg$currPos * 306 + 130;
6445 var cached = peg$resultsCache[key];
6446 if (cached) {
6447 peg$currPos = cached.nextPos;
6448 return cached.result;
6449 }
6450 s0 = peg$currPos;
6451 if (input.substr(peg$currPos, 12) === peg$c129) {
6452 s1 = peg$c129;
6453 peg$currPos += 12;
6454 } else {
6455 s1 = peg$FAILED;
6456 if (peg$silentFails === 0) {
6457 peg$fail(peg$e129);
6458 }
6459 }
6460 if (s1 !== peg$FAILED) {
6461 s2 = peg$parseterminal();
6462 if (s2 !== peg$FAILED) {
6463 peg$savedPos = s0;
6464 s0 = peg$f1(s1, s2);
6465 } else {
6466 peg$currPos = s0;
6467 s0 = peg$FAILED;
6468 }
6469 } else {
6470 peg$currPos = s0;
6471 s0 = peg$FAILED;
6472 }
6473 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6474 return s0;
6475 }
6476 function peg$parseIMAGECUBE() {
6477 var s0, s1, s2;
6478 var key = peg$currPos * 306 + 131;
6479 var cached = peg$resultsCache[key];
6480 if (cached) {
6481 peg$currPos = cached.nextPos;
6482 return cached.result;
6483 }
6484 s0 = peg$currPos;
6485 if (input.substr(peg$currPos, 9) === peg$c130) {
6486 s1 = peg$c130;
6487 peg$currPos += 9;
6488 } else {
6489 s1 = peg$FAILED;
6490 if (peg$silentFails === 0) {
6491 peg$fail(peg$e130);
6492 }
6493 }
6494 if (s1 !== peg$FAILED) {
6495 s2 = peg$parseterminal();
6496 if (s2 !== peg$FAILED) {
6497 peg$savedPos = s0;
6498 s0 = peg$f1(s1, s2);
6499 } else {
6500 peg$currPos = s0;
6501 s0 = peg$FAILED;
6502 }
6503 } else {
6504 peg$currPos = s0;
6505 s0 = peg$FAILED;
6506 }
6507 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6508 return s0;
6509 }
6510 function peg$parseIIMAGECUBE() {
6511 var s0, s1, s2;
6512 var key = peg$currPos * 306 + 132;
6513 var cached = peg$resultsCache[key];
6514 if (cached) {
6515 peg$currPos = cached.nextPos;
6516 return cached.result;
6517 }
6518 s0 = peg$currPos;
6519 if (input.substr(peg$currPos, 10) === peg$c131) {
6520 s1 = peg$c131;
6521 peg$currPos += 10;
6522 } else {
6523 s1 = peg$FAILED;
6524 if (peg$silentFails === 0) {
6525 peg$fail(peg$e131);
6526 }
6527 }
6528 if (s1 !== peg$FAILED) {
6529 s2 = peg$parseterminal();
6530 if (s2 !== peg$FAILED) {
6531 peg$savedPos = s0;
6532 s0 = peg$f1(s1, s2);
6533 } else {
6534 peg$currPos = s0;
6535 s0 = peg$FAILED;
6536 }
6537 } else {
6538 peg$currPos = s0;
6539 s0 = peg$FAILED;
6540 }
6541 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6542 return s0;
6543 }
6544 function peg$parseUIMAGECUBE() {
6545 var s0, s1, s2;
6546 var key = peg$currPos * 306 + 133;
6547 var cached = peg$resultsCache[key];
6548 if (cached) {
6549 peg$currPos = cached.nextPos;
6550 return cached.result;
6551 }
6552 s0 = peg$currPos;
6553 if (input.substr(peg$currPos, 10) === peg$c132) {
6554 s1 = peg$c132;
6555 peg$currPos += 10;
6556 } else {
6557 s1 = peg$FAILED;
6558 if (peg$silentFails === 0) {
6559 peg$fail(peg$e132);
6560 }
6561 }
6562 if (s1 !== peg$FAILED) {
6563 s2 = peg$parseterminal();
6564 if (s2 !== peg$FAILED) {
6565 peg$savedPos = s0;
6566 s0 = peg$f1(s1, s2);
6567 } else {
6568 peg$currPos = s0;
6569 s0 = peg$FAILED;
6570 }
6571 } else {
6572 peg$currPos = s0;
6573 s0 = peg$FAILED;
6574 }
6575 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6576 return s0;
6577 }
6578 function peg$parseIMAGEBUFFER() {
6579 var s0, s1, s2;
6580 var key = peg$currPos * 306 + 134;
6581 var cached = peg$resultsCache[key];
6582 if (cached) {
6583 peg$currPos = cached.nextPos;
6584 return cached.result;
6585 }
6586 s0 = peg$currPos;
6587 if (input.substr(peg$currPos, 11) === peg$c133) {
6588 s1 = peg$c133;
6589 peg$currPos += 11;
6590 } else {
6591 s1 = peg$FAILED;
6592 if (peg$silentFails === 0) {
6593 peg$fail(peg$e133);
6594 }
6595 }
6596 if (s1 !== peg$FAILED) {
6597 s2 = peg$parseterminal();
6598 if (s2 !== peg$FAILED) {
6599 peg$savedPos = s0;
6600 s0 = peg$f1(s1, s2);
6601 } else {
6602 peg$currPos = s0;
6603 s0 = peg$FAILED;
6604 }
6605 } else {
6606 peg$currPos = s0;
6607 s0 = peg$FAILED;
6608 }
6609 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6610 return s0;
6611 }
6612 function peg$parseIIMAGEBUFFER() {
6613 var s0, s1, s2;
6614 var key = peg$currPos * 306 + 135;
6615 var cached = peg$resultsCache[key];
6616 if (cached) {
6617 peg$currPos = cached.nextPos;
6618 return cached.result;
6619 }
6620 s0 = peg$currPos;
6621 if (input.substr(peg$currPos, 12) === peg$c134) {
6622 s1 = peg$c134;
6623 peg$currPos += 12;
6624 } else {
6625 s1 = peg$FAILED;
6626 if (peg$silentFails === 0) {
6627 peg$fail(peg$e134);
6628 }
6629 }
6630 if (s1 !== peg$FAILED) {
6631 s2 = peg$parseterminal();
6632 if (s2 !== peg$FAILED) {
6633 peg$savedPos = s0;
6634 s0 = peg$f1(s1, s2);
6635 } else {
6636 peg$currPos = s0;
6637 s0 = peg$FAILED;
6638 }
6639 } else {
6640 peg$currPos = s0;
6641 s0 = peg$FAILED;
6642 }
6643 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6644 return s0;
6645 }
6646 function peg$parseUIMAGEBUFFER() {
6647 var s0, s1, s2;
6648 var key = peg$currPos * 306 + 136;
6649 var cached = peg$resultsCache[key];
6650 if (cached) {
6651 peg$currPos = cached.nextPos;
6652 return cached.result;
6653 }
6654 s0 = peg$currPos;
6655 if (input.substr(peg$currPos, 12) === peg$c135) {
6656 s1 = peg$c135;
6657 peg$currPos += 12;
6658 } else {
6659 s1 = peg$FAILED;
6660 if (peg$silentFails === 0) {
6661 peg$fail(peg$e135);
6662 }
6663 }
6664 if (s1 !== peg$FAILED) {
6665 s2 = peg$parseterminal();
6666 if (s2 !== peg$FAILED) {
6667 peg$savedPos = s0;
6668 s0 = peg$f1(s1, s2);
6669 } else {
6670 peg$currPos = s0;
6671 s0 = peg$FAILED;
6672 }
6673 } else {
6674 peg$currPos = s0;
6675 s0 = peg$FAILED;
6676 }
6677 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6678 return s0;
6679 }
6680 function peg$parseIMAGE1DARRAY() {
6681 var s0, s1, s2;
6682 var key = peg$currPos * 306 + 137;
6683 var cached = peg$resultsCache[key];
6684 if (cached) {
6685 peg$currPos = cached.nextPos;
6686 return cached.result;
6687 }
6688 s0 = peg$currPos;
6689 if (input.substr(peg$currPos, 12) === peg$c136) {
6690 s1 = peg$c136;
6691 peg$currPos += 12;
6692 } else {
6693 s1 = peg$FAILED;
6694 if (peg$silentFails === 0) {
6695 peg$fail(peg$e136);
6696 }
6697 }
6698 if (s1 !== peg$FAILED) {
6699 s2 = peg$parseterminal();
6700 if (s2 !== peg$FAILED) {
6701 peg$savedPos = s0;
6702 s0 = peg$f1(s1, s2);
6703 } else {
6704 peg$currPos = s0;
6705 s0 = peg$FAILED;
6706 }
6707 } else {
6708 peg$currPos = s0;
6709 s0 = peg$FAILED;
6710 }
6711 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6712 return s0;
6713 }
6714 function peg$parseIIMAGE1DARRAY() {
6715 var s0, s1, s2;
6716 var key = peg$currPos * 306 + 138;
6717 var cached = peg$resultsCache[key];
6718 if (cached) {
6719 peg$currPos = cached.nextPos;
6720 return cached.result;
6721 }
6722 s0 = peg$currPos;
6723 if (input.substr(peg$currPos, 13) === peg$c137) {
6724 s1 = peg$c137;
6725 peg$currPos += 13;
6726 } else {
6727 s1 = peg$FAILED;
6728 if (peg$silentFails === 0) {
6729 peg$fail(peg$e137);
6730 }
6731 }
6732 if (s1 !== peg$FAILED) {
6733 s2 = peg$parseterminal();
6734 if (s2 !== peg$FAILED) {
6735 peg$savedPos = s0;
6736 s0 = peg$f1(s1, s2);
6737 } else {
6738 peg$currPos = s0;
6739 s0 = peg$FAILED;
6740 }
6741 } else {
6742 peg$currPos = s0;
6743 s0 = peg$FAILED;
6744 }
6745 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6746 return s0;
6747 }
6748 function peg$parseUIMAGE1DARRAY() {
6749 var s0, s1, s2;
6750 var key = peg$currPos * 306 + 139;
6751 var cached = peg$resultsCache[key];
6752 if (cached) {
6753 peg$currPos = cached.nextPos;
6754 return cached.result;
6755 }
6756 s0 = peg$currPos;
6757 if (input.substr(peg$currPos, 13) === peg$c138) {
6758 s1 = peg$c138;
6759 peg$currPos += 13;
6760 } else {
6761 s1 = peg$FAILED;
6762 if (peg$silentFails === 0) {
6763 peg$fail(peg$e138);
6764 }
6765 }
6766 if (s1 !== peg$FAILED) {
6767 s2 = peg$parseterminal();
6768 if (s2 !== peg$FAILED) {
6769 peg$savedPos = s0;
6770 s0 = peg$f1(s1, s2);
6771 } else {
6772 peg$currPos = s0;
6773 s0 = peg$FAILED;
6774 }
6775 } else {
6776 peg$currPos = s0;
6777 s0 = peg$FAILED;
6778 }
6779 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6780 return s0;
6781 }
6782 function peg$parseIMAGE2DARRAY() {
6783 var s0, s1, s2;
6784 var key = peg$currPos * 306 + 140;
6785 var cached = peg$resultsCache[key];
6786 if (cached) {
6787 peg$currPos = cached.nextPos;
6788 return cached.result;
6789 }
6790 s0 = peg$currPos;
6791 if (input.substr(peg$currPos, 12) === peg$c139) {
6792 s1 = peg$c139;
6793 peg$currPos += 12;
6794 } else {
6795 s1 = peg$FAILED;
6796 if (peg$silentFails === 0) {
6797 peg$fail(peg$e139);
6798 }
6799 }
6800 if (s1 !== peg$FAILED) {
6801 s2 = peg$parseterminal();
6802 if (s2 !== peg$FAILED) {
6803 peg$savedPos = s0;
6804 s0 = peg$f1(s1, s2);
6805 } else {
6806 peg$currPos = s0;
6807 s0 = peg$FAILED;
6808 }
6809 } else {
6810 peg$currPos = s0;
6811 s0 = peg$FAILED;
6812 }
6813 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6814 return s0;
6815 }
6816 function peg$parseIIMAGE2DARRAY() {
6817 var s0, s1, s2;
6818 var key = peg$currPos * 306 + 141;
6819 var cached = peg$resultsCache[key];
6820 if (cached) {
6821 peg$currPos = cached.nextPos;
6822 return cached.result;
6823 }
6824 s0 = peg$currPos;
6825 if (input.substr(peg$currPos, 13) === peg$c140) {
6826 s1 = peg$c140;
6827 peg$currPos += 13;
6828 } else {
6829 s1 = peg$FAILED;
6830 if (peg$silentFails === 0) {
6831 peg$fail(peg$e140);
6832 }
6833 }
6834 if (s1 !== peg$FAILED) {
6835 s2 = peg$parseterminal();
6836 if (s2 !== peg$FAILED) {
6837 peg$savedPos = s0;
6838 s0 = peg$f1(s1, s2);
6839 } else {
6840 peg$currPos = s0;
6841 s0 = peg$FAILED;
6842 }
6843 } else {
6844 peg$currPos = s0;
6845 s0 = peg$FAILED;
6846 }
6847 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6848 return s0;
6849 }
6850 function peg$parseUIMAGE2DARRAY() {
6851 var s0, s1, s2;
6852 var key = peg$currPos * 306 + 142;
6853 var cached = peg$resultsCache[key];
6854 if (cached) {
6855 peg$currPos = cached.nextPos;
6856 return cached.result;
6857 }
6858 s0 = peg$currPos;
6859 if (input.substr(peg$currPos, 13) === peg$c141) {
6860 s1 = peg$c141;
6861 peg$currPos += 13;
6862 } else {
6863 s1 = peg$FAILED;
6864 if (peg$silentFails === 0) {
6865 peg$fail(peg$e141);
6866 }
6867 }
6868 if (s1 !== peg$FAILED) {
6869 s2 = peg$parseterminal();
6870 if (s2 !== peg$FAILED) {
6871 peg$savedPos = s0;
6872 s0 = peg$f1(s1, s2);
6873 } else {
6874 peg$currPos = s0;
6875 s0 = peg$FAILED;
6876 }
6877 } else {
6878 peg$currPos = s0;
6879 s0 = peg$FAILED;
6880 }
6881 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6882 return s0;
6883 }
6884 function peg$parseIMAGECUBEARRAY() {
6885 var s0, s1, s2;
6886 var key = peg$currPos * 306 + 143;
6887 var cached = peg$resultsCache[key];
6888 if (cached) {
6889 peg$currPos = cached.nextPos;
6890 return cached.result;
6891 }
6892 s0 = peg$currPos;
6893 if (input.substr(peg$currPos, 14) === peg$c142) {
6894 s1 = peg$c142;
6895 peg$currPos += 14;
6896 } else {
6897 s1 = peg$FAILED;
6898 if (peg$silentFails === 0) {
6899 peg$fail(peg$e142);
6900 }
6901 }
6902 if (s1 !== peg$FAILED) {
6903 s2 = peg$parseterminal();
6904 if (s2 !== peg$FAILED) {
6905 peg$savedPos = s0;
6906 s0 = peg$f1(s1, s2);
6907 } else {
6908 peg$currPos = s0;
6909 s0 = peg$FAILED;
6910 }
6911 } else {
6912 peg$currPos = s0;
6913 s0 = peg$FAILED;
6914 }
6915 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6916 return s0;
6917 }
6918 function peg$parseIIMAGECUBEARRAY() {
6919 var s0, s1, s2;
6920 var key = peg$currPos * 306 + 144;
6921 var cached = peg$resultsCache[key];
6922 if (cached) {
6923 peg$currPos = cached.nextPos;
6924 return cached.result;
6925 }
6926 s0 = peg$currPos;
6927 if (input.substr(peg$currPos, 15) === peg$c143) {
6928 s1 = peg$c143;
6929 peg$currPos += 15;
6930 } else {
6931 s1 = peg$FAILED;
6932 if (peg$silentFails === 0) {
6933 peg$fail(peg$e143);
6934 }
6935 }
6936 if (s1 !== peg$FAILED) {
6937 s2 = peg$parseterminal();
6938 if (s2 !== peg$FAILED) {
6939 peg$savedPos = s0;
6940 s0 = peg$f1(s1, s2);
6941 } else {
6942 peg$currPos = s0;
6943 s0 = peg$FAILED;
6944 }
6945 } else {
6946 peg$currPos = s0;
6947 s0 = peg$FAILED;
6948 }
6949 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6950 return s0;
6951 }
6952 function peg$parseUIMAGECUBEARRAY() {
6953 var s0, s1, s2;
6954 var key = peg$currPos * 306 + 145;
6955 var cached = peg$resultsCache[key];
6956 if (cached) {
6957 peg$currPos = cached.nextPos;
6958 return cached.result;
6959 }
6960 s0 = peg$currPos;
6961 if (input.substr(peg$currPos, 15) === peg$c144) {
6962 s1 = peg$c144;
6963 peg$currPos += 15;
6964 } else {
6965 s1 = peg$FAILED;
6966 if (peg$silentFails === 0) {
6967 peg$fail(peg$e144);
6968 }
6969 }
6970 if (s1 !== peg$FAILED) {
6971 s2 = peg$parseterminal();
6972 if (s2 !== peg$FAILED) {
6973 peg$savedPos = s0;
6974 s0 = peg$f1(s1, s2);
6975 } else {
6976 peg$currPos = s0;
6977 s0 = peg$FAILED;
6978 }
6979 } else {
6980 peg$currPos = s0;
6981 s0 = peg$FAILED;
6982 }
6983 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
6984 return s0;
6985 }
6986 function peg$parseIMAGE2DMS() {
6987 var s0, s1, s2;
6988 var key = peg$currPos * 306 + 146;
6989 var cached = peg$resultsCache[key];
6990 if (cached) {
6991 peg$currPos = cached.nextPos;
6992 return cached.result;
6993 }
6994 s0 = peg$currPos;
6995 if (input.substr(peg$currPos, 9) === peg$c145) {
6996 s1 = peg$c145;
6997 peg$currPos += 9;
6998 } else {
6999 s1 = peg$FAILED;
7000 if (peg$silentFails === 0) {
7001 peg$fail(peg$e145);
7002 }
7003 }
7004 if (s1 !== peg$FAILED) {
7005 s2 = peg$parseterminal();
7006 if (s2 !== peg$FAILED) {
7007 peg$savedPos = s0;
7008 s0 = peg$f1(s1, s2);
7009 } else {
7010 peg$currPos = s0;
7011 s0 = peg$FAILED;
7012 }
7013 } else {
7014 peg$currPos = s0;
7015 s0 = peg$FAILED;
7016 }
7017 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7018 return s0;
7019 }
7020 function peg$parseIIMAGE2DMS() {
7021 var s0, s1, s2;
7022 var key = peg$currPos * 306 + 147;
7023 var cached = peg$resultsCache[key];
7024 if (cached) {
7025 peg$currPos = cached.nextPos;
7026 return cached.result;
7027 }
7028 s0 = peg$currPos;
7029 if (input.substr(peg$currPos, 10) === peg$c146) {
7030 s1 = peg$c146;
7031 peg$currPos += 10;
7032 } else {
7033 s1 = peg$FAILED;
7034 if (peg$silentFails === 0) {
7035 peg$fail(peg$e146);
7036 }
7037 }
7038 if (s1 !== peg$FAILED) {
7039 s2 = peg$parseterminal();
7040 if (s2 !== peg$FAILED) {
7041 peg$savedPos = s0;
7042 s0 = peg$f1(s1, s2);
7043 } else {
7044 peg$currPos = s0;
7045 s0 = peg$FAILED;
7046 }
7047 } else {
7048 peg$currPos = s0;
7049 s0 = peg$FAILED;
7050 }
7051 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7052 return s0;
7053 }
7054 function peg$parseUIMAGE2DMS() {
7055 var s0, s1, s2;
7056 var key = peg$currPos * 306 + 148;
7057 var cached = peg$resultsCache[key];
7058 if (cached) {
7059 peg$currPos = cached.nextPos;
7060 return cached.result;
7061 }
7062 s0 = peg$currPos;
7063 if (input.substr(peg$currPos, 10) === peg$c147) {
7064 s1 = peg$c147;
7065 peg$currPos += 10;
7066 } else {
7067 s1 = peg$FAILED;
7068 if (peg$silentFails === 0) {
7069 peg$fail(peg$e147);
7070 }
7071 }
7072 if (s1 !== peg$FAILED) {
7073 s2 = peg$parseterminal();
7074 if (s2 !== peg$FAILED) {
7075 peg$savedPos = s0;
7076 s0 = peg$f1(s1, s2);
7077 } else {
7078 peg$currPos = s0;
7079 s0 = peg$FAILED;
7080 }
7081 } else {
7082 peg$currPos = s0;
7083 s0 = peg$FAILED;
7084 }
7085 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7086 return s0;
7087 }
7088 function peg$parseIMAGE2DMSARRAY() {
7089 var s0, s1, s2;
7090 var key = peg$currPos * 306 + 149;
7091 var cached = peg$resultsCache[key];
7092 if (cached) {
7093 peg$currPos = cached.nextPos;
7094 return cached.result;
7095 }
7096 s0 = peg$currPos;
7097 if (input.substr(peg$currPos, 13) === peg$c148) {
7098 s1 = peg$c148;
7099 peg$currPos += 13;
7100 } else {
7101 s1 = peg$FAILED;
7102 if (peg$silentFails === 0) {
7103 peg$fail(peg$e148);
7104 }
7105 }
7106 if (s1 !== peg$FAILED) {
7107 s2 = peg$parseterminal();
7108 if (s2 !== peg$FAILED) {
7109 peg$savedPos = s0;
7110 s0 = peg$f1(s1, s2);
7111 } else {
7112 peg$currPos = s0;
7113 s0 = peg$FAILED;
7114 }
7115 } else {
7116 peg$currPos = s0;
7117 s0 = peg$FAILED;
7118 }
7119 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7120 return s0;
7121 }
7122 function peg$parseIIMAGE2DMSARRAY() {
7123 var s0, s1, s2;
7124 var key = peg$currPos * 306 + 150;
7125 var cached = peg$resultsCache[key];
7126 if (cached) {
7127 peg$currPos = cached.nextPos;
7128 return cached.result;
7129 }
7130 s0 = peg$currPos;
7131 if (input.substr(peg$currPos, 15) === peg$c149) {
7132 s1 = peg$c149;
7133 peg$currPos += 15;
7134 } else {
7135 s1 = peg$FAILED;
7136 if (peg$silentFails === 0) {
7137 peg$fail(peg$e149);
7138 }
7139 }
7140 if (s1 !== peg$FAILED) {
7141 s2 = peg$parseterminal();
7142 if (s2 !== peg$FAILED) {
7143 peg$savedPos = s0;
7144 s0 = peg$f1(s1, s2);
7145 } else {
7146 peg$currPos = s0;
7147 s0 = peg$FAILED;
7148 }
7149 } else {
7150 peg$currPos = s0;
7151 s0 = peg$FAILED;
7152 }
7153 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7154 return s0;
7155 }
7156 function peg$parseUIMAGE2DMSARRAY() {
7157 var s0, s1, s2;
7158 var key = peg$currPos * 306 + 151;
7159 var cached = peg$resultsCache[key];
7160 if (cached) {
7161 peg$currPos = cached.nextPos;
7162 return cached.result;
7163 }
7164 s0 = peg$currPos;
7165 if (input.substr(peg$currPos, 15) === peg$c150) {
7166 s1 = peg$c150;
7167 peg$currPos += 15;
7168 } else {
7169 s1 = peg$FAILED;
7170 if (peg$silentFails === 0) {
7171 peg$fail(peg$e150);
7172 }
7173 }
7174 if (s1 !== peg$FAILED) {
7175 s2 = peg$parseterminal();
7176 if (s2 !== peg$FAILED) {
7177 peg$savedPos = s0;
7178 s0 = peg$f1(s1, s2);
7179 } else {
7180 peg$currPos = s0;
7181 s0 = peg$FAILED;
7182 }
7183 } else {
7184 peg$currPos = s0;
7185 s0 = peg$FAILED;
7186 }
7187 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7188 return s0;
7189 }
7190 function peg$parseSTRUCT() {
7191 var s0, s1, s2;
7192 var key = peg$currPos * 306 + 152;
7193 var cached = peg$resultsCache[key];
7194 if (cached) {
7195 peg$currPos = cached.nextPos;
7196 return cached.result;
7197 }
7198 s0 = peg$currPos;
7199 if (input.substr(peg$currPos, 6) === peg$c151) {
7200 s1 = peg$c151;
7201 peg$currPos += 6;
7202 } else {
7203 s1 = peg$FAILED;
7204 if (peg$silentFails === 0) {
7205 peg$fail(peg$e151);
7206 }
7207 }
7208 if (s1 !== peg$FAILED) {
7209 s2 = peg$parseterminal();
7210 if (s2 !== peg$FAILED) {
7211 peg$savedPos = s0;
7212 s0 = peg$f1(s1, s2);
7213 } else {
7214 peg$currPos = s0;
7215 s0 = peg$FAILED;
7216 }
7217 } else {
7218 peg$currPos = s0;
7219 s0 = peg$FAILED;
7220 }
7221 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7222 return s0;
7223 }
7224 function peg$parseVOID() {
7225 var s0, s1, s2;
7226 var key = peg$currPos * 306 + 153;
7227 var cached = peg$resultsCache[key];
7228 if (cached) {
7229 peg$currPos = cached.nextPos;
7230 return cached.result;
7231 }
7232 s0 = peg$currPos;
7233 if (input.substr(peg$currPos, 4) === peg$c152) {
7234 s1 = peg$c152;
7235 peg$currPos += 4;
7236 } else {
7237 s1 = peg$FAILED;
7238 if (peg$silentFails === 0) {
7239 peg$fail(peg$e152);
7240 }
7241 }
7242 if (s1 !== peg$FAILED) {
7243 s2 = peg$parseterminal();
7244 if (s2 !== peg$FAILED) {
7245 peg$savedPos = s0;
7246 s0 = peg$f1(s1, s2);
7247 } else {
7248 peg$currPos = s0;
7249 s0 = peg$FAILED;
7250 }
7251 } else {
7252 peg$currPos = s0;
7253 s0 = peg$FAILED;
7254 }
7255 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7256 return s0;
7257 }
7258 function peg$parseWHILE() {
7259 var s0, s1, s2;
7260 var key = peg$currPos * 306 + 154;
7261 var cached = peg$resultsCache[key];
7262 if (cached) {
7263 peg$currPos = cached.nextPos;
7264 return cached.result;
7265 }
7266 s0 = peg$currPos;
7267 if (input.substr(peg$currPos, 5) === peg$c153) {
7268 s1 = peg$c153;
7269 peg$currPos += 5;
7270 } else {
7271 s1 = peg$FAILED;
7272 if (peg$silentFails === 0) {
7273 peg$fail(peg$e153);
7274 }
7275 }
7276 if (s1 !== peg$FAILED) {
7277 s2 = peg$parseterminal();
7278 if (s2 !== peg$FAILED) {
7279 peg$savedPos = s0;
7280 s0 = peg$f1(s1, s2);
7281 } else {
7282 peg$currPos = s0;
7283 s0 = peg$FAILED;
7284 }
7285 } else {
7286 peg$currPos = s0;
7287 s0 = peg$FAILED;
7288 }
7289 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7290 return s0;
7291 }
7292 function peg$parseINVARIANT() {
7293 var s0, s1, s2;
7294 var key = peg$currPos * 306 + 155;
7295 var cached = peg$resultsCache[key];
7296 if (cached) {
7297 peg$currPos = cached.nextPos;
7298 return cached.result;
7299 }
7300 s0 = peg$currPos;
7301 if (input.substr(peg$currPos, 9) === peg$c154) {
7302 s1 = peg$c154;
7303 peg$currPos += 9;
7304 } else {
7305 s1 = peg$FAILED;
7306 if (peg$silentFails === 0) {
7307 peg$fail(peg$e154);
7308 }
7309 }
7310 if (s1 !== peg$FAILED) {
7311 s2 = peg$parseterminal();
7312 if (s2 !== peg$FAILED) {
7313 peg$savedPos = s0;
7314 s0 = peg$f1(s1, s2);
7315 } else {
7316 peg$currPos = s0;
7317 s0 = peg$FAILED;
7318 }
7319 } else {
7320 peg$currPos = s0;
7321 s0 = peg$FAILED;
7322 }
7323 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7324 return s0;
7325 }
7326 function peg$parsePRECISE() {
7327 var s0, s1, s2;
7328 var key = peg$currPos * 306 + 156;
7329 var cached = peg$resultsCache[key];
7330 if (cached) {
7331 peg$currPos = cached.nextPos;
7332 return cached.result;
7333 }
7334 s0 = peg$currPos;
7335 if (input.substr(peg$currPos, 7) === peg$c155) {
7336 s1 = peg$c155;
7337 peg$currPos += 7;
7338 } else {
7339 s1 = peg$FAILED;
7340 if (peg$silentFails === 0) {
7341 peg$fail(peg$e155);
7342 }
7343 }
7344 if (s1 !== peg$FAILED) {
7345 s2 = peg$parseterminal();
7346 if (s2 !== peg$FAILED) {
7347 peg$savedPos = s0;
7348 s0 = peg$f1(s1, s2);
7349 } else {
7350 peg$currPos = s0;
7351 s0 = peg$FAILED;
7352 }
7353 } else {
7354 peg$currPos = s0;
7355 s0 = peg$FAILED;
7356 }
7357 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7358 return s0;
7359 }
7360 function peg$parseHIGH_PRECISION() {
7361 var s0, s1, s2;
7362 var key = peg$currPos * 306 + 157;
7363 var cached = peg$resultsCache[key];
7364 if (cached) {
7365 peg$currPos = cached.nextPos;
7366 return cached.result;
7367 }
7368 s0 = peg$currPos;
7369 if (input.substr(peg$currPos, 5) === peg$c156) {
7370 s1 = peg$c156;
7371 peg$currPos += 5;
7372 } else {
7373 s1 = peg$FAILED;
7374 if (peg$silentFails === 0) {
7375 peg$fail(peg$e156);
7376 }
7377 }
7378 if (s1 !== peg$FAILED) {
7379 s2 = peg$parseterminal();
7380 if (s2 !== peg$FAILED) {
7381 peg$savedPos = s0;
7382 s0 = peg$f1(s1, s2);
7383 } else {
7384 peg$currPos = s0;
7385 s0 = peg$FAILED;
7386 }
7387 } else {
7388 peg$currPos = s0;
7389 s0 = peg$FAILED;
7390 }
7391 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7392 return s0;
7393 }
7394 function peg$parseMEDIUM_PRECISION() {
7395 var s0, s1, s2;
7396 var key = peg$currPos * 306 + 158;
7397 var cached = peg$resultsCache[key];
7398 if (cached) {
7399 peg$currPos = cached.nextPos;
7400 return cached.result;
7401 }
7402 s0 = peg$currPos;
7403 if (input.substr(peg$currPos, 7) === peg$c157) {
7404 s1 = peg$c157;
7405 peg$currPos += 7;
7406 } else {
7407 s1 = peg$FAILED;
7408 if (peg$silentFails === 0) {
7409 peg$fail(peg$e157);
7410 }
7411 }
7412 if (s1 !== peg$FAILED) {
7413 s2 = peg$parseterminal();
7414 if (s2 !== peg$FAILED) {
7415 peg$savedPos = s0;
7416 s0 = peg$f1(s1, s2);
7417 } else {
7418 peg$currPos = s0;
7419 s0 = peg$FAILED;
7420 }
7421 } else {
7422 peg$currPos = s0;
7423 s0 = peg$FAILED;
7424 }
7425 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7426 return s0;
7427 }
7428 function peg$parseLOW_PRECISION() {
7429 var s0, s1, s2;
7430 var key = peg$currPos * 306 + 159;
7431 var cached = peg$resultsCache[key];
7432 if (cached) {
7433 peg$currPos = cached.nextPos;
7434 return cached.result;
7435 }
7436 s0 = peg$currPos;
7437 if (input.substr(peg$currPos, 4) === peg$c158) {
7438 s1 = peg$c158;
7439 peg$currPos += 4;
7440 } else {
7441 s1 = peg$FAILED;
7442 if (peg$silentFails === 0) {
7443 peg$fail(peg$e158);
7444 }
7445 }
7446 if (s1 !== peg$FAILED) {
7447 s2 = peg$parseterminal();
7448 if (s2 !== peg$FAILED) {
7449 peg$savedPos = s0;
7450 s0 = peg$f1(s1, s2);
7451 } else {
7452 peg$currPos = s0;
7453 s0 = peg$FAILED;
7454 }
7455 } else {
7456 peg$currPos = s0;
7457 s0 = peg$FAILED;
7458 }
7459 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7460 return s0;
7461 }
7462 function peg$parsePRECISION() {
7463 var s0, s1, s2;
7464 var key = peg$currPos * 306 + 160;
7465 var cached = peg$resultsCache[key];
7466 if (cached) {
7467 peg$currPos = cached.nextPos;
7468 return cached.result;
7469 }
7470 s0 = peg$currPos;
7471 if (input.substr(peg$currPos, 9) === peg$c159) {
7472 s1 = peg$c159;
7473 peg$currPos += 9;
7474 } else {
7475 s1 = peg$FAILED;
7476 if (peg$silentFails === 0) {
7477 peg$fail(peg$e159);
7478 }
7479 }
7480 if (s1 !== peg$FAILED) {
7481 s2 = peg$parseterminal();
7482 if (s2 !== peg$FAILED) {
7483 peg$savedPos = s0;
7484 s0 = peg$f1(s1, s2);
7485 } else {
7486 peg$currPos = s0;
7487 s0 = peg$FAILED;
7488 }
7489 } else {
7490 peg$currPos = s0;
7491 s0 = peg$FAILED;
7492 }
7493 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7494 return s0;
7495 }
7496 function peg$parseFLOATCONSTANT() {
7497 var s0, s1, s2;
7498 var key = peg$currPos * 306 + 161;
7499 var cached = peg$resultsCache[key];
7500 if (cached) {
7501 peg$currPos = cached.nextPos;
7502 return cached.result;
7503 }
7504 s0 = peg$currPos;
7505 s1 = peg$parsefloating_constant();
7506 if (s1 !== peg$FAILED) {
7507 s2 = peg$parse_();
7508 peg$savedPos = s0;
7509 s0 = peg$f2(s1, s2);
7510 } else {
7511 peg$currPos = s0;
7512 s0 = peg$FAILED;
7513 }
7514 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7515 return s0;
7516 }
7517 function peg$parseDOUBLECONSTANT() {
7518 var s0, s1, s2;
7519 var key = peg$currPos * 306 + 162;
7520 var cached = peg$resultsCache[key];
7521 if (cached) {
7522 peg$currPos = cached.nextPos;
7523 return cached.result;
7524 }
7525 s0 = peg$currPos;
7526 s1 = peg$parsefloating_constant();
7527 if (s1 !== peg$FAILED) {
7528 s2 = peg$parse_();
7529 peg$savedPos = s0;
7530 s0 = peg$f3(s1, s2);
7531 } else {
7532 peg$currPos = s0;
7533 s0 = peg$FAILED;
7534 }
7535 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7536 return s0;
7537 }
7538 function peg$parseINTCONSTANT() {
7539 var s0, s1, s2;
7540 var key = peg$currPos * 306 + 163;
7541 var cached = peg$resultsCache[key];
7542 if (cached) {
7543 peg$currPos = cached.nextPos;
7544 return cached.result;
7545 }
7546 s0 = peg$currPos;
7547 s1 = peg$parseinteger_constant();
7548 if (s1 !== peg$FAILED) {
7549 s2 = peg$parse_();
7550 peg$savedPos = s0;
7551 s0 = peg$f4(s1, s2);
7552 } else {
7553 peg$currPos = s0;
7554 s0 = peg$FAILED;
7555 }
7556 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7557 return s0;
7558 }
7559 function peg$parseUINTCONSTANT() {
7560 var s0, s1, s2;
7561 var key = peg$currPos * 306 + 164;
7562 var cached = peg$resultsCache[key];
7563 if (cached) {
7564 peg$currPos = cached.nextPos;
7565 return cached.result;
7566 }
7567 s0 = peg$currPos;
7568 s1 = peg$parseinteger_constant();
7569 if (s1 !== peg$FAILED) {
7570 s2 = peg$parse_();
7571 peg$savedPos = s0;
7572 s0 = peg$f5(s1, s2);
7573 } else {
7574 peg$currPos = s0;
7575 s0 = peg$FAILED;
7576 }
7577 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7578 return s0;
7579 }
7580 function peg$parseBOOLCONSTANT() {
7581 var s0, s1, s2;
7582 var key = peg$currPos * 306 + 165;
7583 var cached = peg$resultsCache[key];
7584 if (cached) {
7585 peg$currPos = cached.nextPos;
7586 return cached.result;
7587 }
7588 s0 = peg$currPos;
7589 if (input.substr(peg$currPos, 4) === peg$c160) {
7590 s1 = peg$c160;
7591 peg$currPos += 4;
7592 } else {
7593 s1 = peg$FAILED;
7594 if (peg$silentFails === 0) {
7595 peg$fail(peg$e160);
7596 }
7597 }
7598 if (s1 === peg$FAILED) {
7599 if (input.substr(peg$currPos, 5) === peg$c161) {
7600 s1 = peg$c161;
7601 peg$currPos += 5;
7602 } else {
7603 s1 = peg$FAILED;
7604 if (peg$silentFails === 0) {
7605 peg$fail(peg$e161);
7606 }
7607 }
7608 }
7609 if (s1 !== peg$FAILED) {
7610 s2 = peg$parseterminal();
7611 if (s2 !== peg$FAILED) {
7612 peg$savedPos = s0;
7613 s0 = peg$f6(s1, s2);
7614 } else {
7615 peg$currPos = s0;
7616 s0 = peg$FAILED;
7617 }
7618 } else {
7619 peg$currPos = s0;
7620 s0 = peg$FAILED;
7621 }
7622 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
7623 return s0;
7624 }
7625 function peg$parsekeyword() {
7626 var s0, s1;
7627 var key = peg$currPos * 306 + 166;
7628 var cached = peg$resultsCache[key];
7629 if (cached) {
7630 peg$currPos = cached.nextPos;
7631 return cached.result;
7632 }
7633 peg$silentFails++;
7634 s0 = peg$parseATTRIBUTE();
7635 if (s0 === peg$FAILED) {
7636 s0 = peg$parseVARYING();
7637 if (s0 === peg$FAILED) {
7638 s0 = peg$parseCONST();
7639 if (s0 === peg$FAILED) {
7640 s0 = peg$parseBOOL();
7641 if (s0 === peg$FAILED) {
7642 s0 = peg$parseFLOAT();
7643 if (s0 === peg$FAILED) {
7644 s0 = peg$parseDOUBLE();
7645 if (s0 === peg$FAILED) {
7646 s0 = peg$parseINT();
7647 if (s0 === peg$FAILED) {
7648 s0 = peg$parseUINT();
7649 if (s0 === peg$FAILED) {
7650 s0 = peg$parseBREAK();
7651 if (s0 === peg$FAILED) {
7652 s0 = peg$parseCONTINUE();
7653 if (s0 === peg$FAILED) {
7654 s0 = peg$parseDO();
7655 if (s0 === peg$FAILED) {
7656 s0 = peg$parseELSE();
7657 if (s0 === peg$FAILED) {
7658 s0 = peg$parseFOR();
7659 if (s0 === peg$FAILED) {
7660 s0 = peg$parseIF();
7661 if (s0 === peg$FAILED) {
7662 s0 = peg$parseDISCARD();
7663 if (s0 === peg$FAILED) {
7664 s0 = peg$parseRETURN();
7665 if (s0 === peg$FAILED) {
7666 s0 = peg$parseSWITCH();
7667 if (s0 === peg$FAILED) {
7668 s0 = peg$parseCASE();
7669 if (s0 === peg$FAILED) {
7670 s0 = peg$parseDEFAULT();
7671 if (s0 === peg$FAILED) {
7672 s0 = peg$parseSUBROUTINE();
7673 if (s0 === peg$FAILED) {
7674 s0 = peg$parseBVEC2();
7675 if (s0 === peg$FAILED) {
7676 s0 = peg$parseBVEC3();
7677 if (s0 === peg$FAILED) {
7678 s0 = peg$parseBVEC4();
7679 if (s0 === peg$FAILED) {
7680 s0 = peg$parseIVEC2();
7681 if (s0 === peg$FAILED) {
7682 s0 = peg$parseIVEC3();
7683 if (s0 === peg$FAILED) {
7684 s0 = peg$parseIVEC4();
7685 if (s0 === peg$FAILED) {
7686 s0 = peg$parseUVEC2();
7687 if (s0 === peg$FAILED) {
7688 s0 = peg$parseUVEC3();
7689 if (s0 === peg$FAILED) {
7690 s0 = peg$parseUVEC4();
7691 if (s0 === peg$FAILED) {
7692 s0 = peg$parseVEC2();
7693 if (s0 === peg$FAILED) {
7694 s0 = peg$parseVEC3();
7695 if (s0 === peg$FAILED) {
7696 s0 = peg$parseVEC4();
7697 if (s0 === peg$FAILED) {
7698 s0 = peg$parseMAT2();
7699 if (s0 === peg$FAILED) {
7700 s0 = peg$parseMAT3();
7701 if (s0 === peg$FAILED) {
7702 s0 = peg$parseMAT4();
7703 if (s0 === peg$FAILED) {
7704 s0 = peg$parseCENTROID();
7705 if (s0 === peg$FAILED) {
7706 s0 = peg$parseIN();
7707 if (s0 === peg$FAILED) {
7708 s0 = peg$parseOUT();
7709 if (s0 === peg$FAILED) {
7710 s0 = peg$parseINOUT();
7711 if (s0 === peg$FAILED) {
7712 s0 = peg$parseUNIFORM();
7713 if (s0 === peg$FAILED) {
7714 s0 = peg$parsePATCH();
7715 if (s0 === peg$FAILED) {
7716 s0 = peg$parseSAMPLE();
7717 if (s0 === peg$FAILED) {
7718 s0 = peg$parseBUFFER();
7719 if (s0 === peg$FAILED) {
7720 s0 = peg$parseSHARED();
7721 if (s0 === peg$FAILED) {
7722 s0 = peg$parseCOHERENT();
7723 if (s0 === peg$FAILED) {
7724 s0 = peg$parseVOLATILE();
7725 if (s0 === peg$FAILED) {
7726 s0 = peg$parseRESTRICT();
7727 if (s0 === peg$FAILED) {
7728 s0 = peg$parseREADONLY();
7729 if (s0 === peg$FAILED) {
7730 s0 = peg$parseWRITEONLY();
7731 if (s0 === peg$FAILED) {
7732 s0 = peg$parseDVEC2();
7733 if (s0 === peg$FAILED) {
7734 s0 = peg$parseDVEC3();
7735 if (s0 === peg$FAILED) {
7736 s0 = peg$parseDVEC4();
7737 if (s0 === peg$FAILED) {
7738 s0 = peg$parseDMAT2();
7739 if (s0 === peg$FAILED) {
7740 s0 = peg$parseDMAT3();
7741 if (s0 === peg$FAILED) {
7742 s0 = peg$parseDMAT4();
7743 if (s0 === peg$FAILED) {
7744 s0 = peg$parseNOPERSPECTIVE();
7745 if (s0 === peg$FAILED) {
7746 s0 = peg$parseFLAT();
7747 if (s0 === peg$FAILED) {
7748 s0 = peg$parseSMOOTH();
7749 if (s0 === peg$FAILED) {
7750 s0 = peg$parseLAYOUT();
7751 if (s0 === peg$FAILED) {
7752 s0 = peg$parseMAT2X2();
7753 if (s0 === peg$FAILED) {
7754 s0 = peg$parseMAT2X3();
7755 if (s0 === peg$FAILED) {
7756 s0 = peg$parseMAT2X4();
7757 if (s0 === peg$FAILED) {
7758 s0 = peg$parseMAT3X2();
7759 if (s0 === peg$FAILED) {
7760 s0 = peg$parseMAT3X3();
7761 if (s0 === peg$FAILED) {
7762 s0 = peg$parseMAT3X4();
7763 if (s0 === peg$FAILED) {
7764 s0 = peg$parseMAT4X2();
7765 if (s0 === peg$FAILED) {
7766 s0 = peg$parseMAT4X3();
7767 if (s0 === peg$FAILED) {
7768 s0 = peg$parseMAT4X4();
7769 if (s0 === peg$FAILED) {
7770 s0 = peg$parseDMAT2X2();
7771 if (s0 === peg$FAILED) {
7772 s0 = peg$parseDMAT2X3();
7773 if (s0 === peg$FAILED) {
7774 s0 = peg$parseDMAT2X4();
7775 if (s0 === peg$FAILED) {
7776 s0 = peg$parseDMAT3X2();
7777 if (s0 === peg$FAILED) {
7778 s0 = peg$parseDMAT3X3();
7779 if (s0 === peg$FAILED) {
7780 s0 = peg$parseDMAT3X4();
7781 if (s0 === peg$FAILED) {
7782 s0 = peg$parseDMAT4X2();
7783 if (s0 === peg$FAILED) {
7784 s0 = peg$parseDMAT4X3();
7785 if (s0 === peg$FAILED) {
7786 s0 = peg$parseDMAT4X4();
7787 if (s0 === peg$FAILED) {
7788 s0 = peg$parseATOMIC_UINT();
7789 if (s0 === peg$FAILED) {
7790 s0 = peg$parseSAMPLER1D();
7791 if (s0 === peg$FAILED) {
7792 s0 = peg$parseSAMPLER2D();
7793 if (s0 === peg$FAILED) {
7794 s0 = peg$parseSAMPLER3D();
7795 if (s0 === peg$FAILED) {
7796 s0 = peg$parseSAMPLERCUBE();
7797 if (s0 === peg$FAILED) {
7798 s0 = peg$parseSAMPLER1DSHADOW();
7799 if (s0 === peg$FAILED) {
7800 s0 = peg$parseSAMPLER2DSHADOW();
7801 if (s0 === peg$FAILED) {
7802 s0 = peg$parseSAMPLERCUBESHADOW();
7803 if (s0 === peg$FAILED) {
7804 s0 = peg$parseSAMPLER1DARRAY();
7805 if (s0 === peg$FAILED) {
7806 s0 = peg$parseSAMPLER2DARRAY();
7807 if (s0 === peg$FAILED) {
7808 s0 = peg$parseSAMPLER1DARRAYSHADOW();
7809 if (s0 === peg$FAILED) {
7810 s0 = peg$parseSAMPLER2DARRAYSHADOW();
7811 if (s0 === peg$FAILED) {
7812 s0 = peg$parseISAMPLER1D();
7813 if (s0 === peg$FAILED) {
7814 s0 = peg$parseISAMPLER2D();
7815 if (s0 === peg$FAILED) {
7816 s0 = peg$parseISAMPLER3D();
7817 if (s0 === peg$FAILED) {
7818 s0 = peg$parseISAMPLERCUBE();
7819 if (s0 === peg$FAILED) {
7820 s0 = peg$parseISAMPLER1DARRAY();
7821 if (s0 === peg$FAILED) {
7822 s0 = peg$parseISAMPLER2DARRAY();
7823 if (s0 === peg$FAILED) {
7824 s0 = peg$parseUSAMPLER1D();
7825 if (s0 === peg$FAILED) {
7826 s0 = peg$parseUSAMPLER2D();
7827 if (s0 === peg$FAILED) {
7828 s0 = peg$parseUSAMPLER3D();
7829 if (s0 === peg$FAILED) {
7830 s0 = peg$parseUSAMPLERCUBE();
7831 if (s0 === peg$FAILED) {
7832 s0 = peg$parseUSAMPLER1DARRAY();
7833 if (s0 === peg$FAILED) {
7834 s0 = peg$parseUSAMPLER2DARRAY();
7835 if (s0 === peg$FAILED) {
7836 s0 = peg$parseSAMPLER2DRECT();
7837 if (s0 === peg$FAILED) {
7838 s0 = peg$parseSAMPLER2DRECTSHADOW();
7839 if (s0 === peg$FAILED) {
7840 s0 = peg$parseISAMPLER2DRECT();
7841 if (s0 === peg$FAILED) {
7842 s0 = peg$parseUSAMPLER2DRECT();
7843 if (s0 === peg$FAILED) {
7844 s0 = peg$parseSAMPLERBUFFER();
7845 if (s0 === peg$FAILED) {
7846 s0 = peg$parseISAMPLERBUFFER();
7847 if (s0 === peg$FAILED) {
7848 s0 = peg$parseUSAMPLERBUFFER();
7849 if (s0 === peg$FAILED) {
7850 s0 = peg$parseSAMPLERCUBEARRAY();
7851 if (s0 === peg$FAILED) {
7852 s0 = peg$parseSAMPLERCUBEARRAYSHADOW();
7853 if (s0 === peg$FAILED) {
7854 s0 = peg$parseISAMPLERCUBEARRAY();
7855 if (s0 === peg$FAILED) {
7856 s0 = peg$parseUSAMPLERCUBEARRAY();
7857 if (s0 === peg$FAILED) {
7858 s0 = peg$parseSAMPLER2DMS();
7859 if (s0 === peg$FAILED) {
7860 s0 = peg$parseISAMPLER2DMS();
7861 if (s0 === peg$FAILED) {
7862 s0 = peg$parseUSAMPLER2DMS();
7863 if (s0 === peg$FAILED) {
7864 s0 = peg$parseSAMPLER2DMSARRAY();
7865 if (s0 === peg$FAILED) {
7866 s0 = peg$parseISAMPLER2DMSARRAY();
7867 if (s0 === peg$FAILED) {
7868 s0 = peg$parseUSAMPLER2DMSARRAY();
7869 if (s0 === peg$FAILED) {
7870 s0 = peg$parseIMAGE1D();
7871 if (s0 === peg$FAILED) {
7872 s0 = peg$parseIIMAGE1D();
7873 if (s0 === peg$FAILED) {
7874 s0 = peg$parseUIMAGE1D();
7875 if (s0 === peg$FAILED) {
7876 s0 = peg$parseIMAGE2D();
7877 if (s0 === peg$FAILED) {
7878 s0 = peg$parseIIMAGE2D();
7879 if (s0 === peg$FAILED) {
7880 s0 = peg$parseUIMAGE2D();
7881 if (s0 === peg$FAILED) {
7882 s0 = peg$parseIMAGE3D();
7883 if (s0 === peg$FAILED) {
7884 s0 = peg$parseIIMAGE3D();
7885 if (s0 === peg$FAILED) {
7886 s0 = peg$parseUIMAGE3D();
7887 if (s0 === peg$FAILED) {
7888 s0 = peg$parseIMAGE2DRECT();
7889 if (s0 === peg$FAILED) {
7890 s0 = peg$parseIIMAGE2DRECT();
7891 if (s0 === peg$FAILED) {
7892 s0 = peg$parseUIMAGE2DRECT();
7893 if (s0 === peg$FAILED) {
7894 s0 = peg$parseIMAGECUBE();
7895 if (s0 === peg$FAILED) {
7896 s0 = peg$parseIIMAGECUBE();
7897 if (s0 === peg$FAILED) {
7898 s0 = peg$parseUIMAGECUBE();
7899 if (s0 === peg$FAILED) {
7900 s0 = peg$parseIMAGEBUFFER();
7901 if (s0 === peg$FAILED) {
7902 s0 = peg$parseIIMAGEBUFFER();
7903 if (s0 === peg$FAILED) {
7904 s0 = peg$parseUIMAGEBUFFER();
7905 if (s0 === peg$FAILED) {
7906 s0 = peg$parseIMAGE1DARRAY();
7907 if (s0 === peg$FAILED) {
7908 s0 = peg$parseIIMAGE1DARRAY();
7909 if (s0 === peg$FAILED) {
7910 s0 = peg$parseUIMAGE1DARRAY();
7911 if (s0 === peg$FAILED) {
7912 s0 = peg$parseIMAGE2DARRAY();
7913 if (s0 === peg$FAILED) {
7914 s0 = peg$parseIIMAGE2DARRAY();
7915 if (s0 === peg$FAILED) {
7916 s0 = peg$parseUIMAGE2DARRAY();
7917 if (s0 === peg$FAILED) {
7918 s0 = peg$parseIMAGECUBEARRAY();
7919 if (s0 === peg$FAILED) {
7920 s0 = peg$parseIIMAGECUBEARRAY();
7921 if (s0 === peg$FAILED) {
7922 s0 = peg$parseUIMAGECUBEARRAY();
7923 if (s0 === peg$FAILED) {
7924 s0 = peg$parseIMAGE2DMS();
7925 if (s0 === peg$FAILED) {
7926 s0 = peg$parseIIMAGE2DMS();
7927 if (s0 === peg$FAILED) {
7928 s0 = peg$parseUIMAGE2DMS();
7929 if (s0 === peg$FAILED) {
7930 s0 = peg$parseIMAGE2DMSARRAY();
7931 if (s0 === peg$FAILED) {
7932 s0 = peg$parseIIMAGE2DMSARRAY();
7933 if (s0 === peg$FAILED) {
7934 s0 = peg$parseUIMAGE2DMSARRAY();
7935 if (s0 === peg$FAILED) {
7936 s0 = peg$parseSTRUCT();
7937 if (s0 === peg$FAILED) {
7938 s0 = peg$parseVOID();
7939 if (s0 === peg$FAILED) {
7940 s0 = peg$parseWHILE();
7941 if (s0 === peg$FAILED) {
7942 s0 = peg$parseINVARIANT();
7943 if (s0 === peg$FAILED) {
7944 s0 = peg$parsePRECISE();
7945 if (s0 === peg$FAILED) {
7946 s0 = peg$parseHIGH_PRECISION();
7947 if (s0 === peg$FAILED) {
7948 s0 = peg$parseMEDIUM_PRECISION();
7949 if (s0 === peg$FAILED) {
7950 s0 = peg$parseLOW_PRECISION();
7951 if (s0 === peg$FAILED) {
7952 s0 = peg$parsePRECISION();
7953 }
7954 }
7955 }
7956 }
7957 }
7958 }
7959 }
7960 }
7961 }
7962 }
7963 }
7964 }
7965 }
7966 }
7967 }
7968 }
7969 }
7970 }
7971 }
7972 }
7973 }
7974 }
7975 }
7976 }
7977 }
7978 }
7979 }
7980 }
7981 }
7982 }
7983 }
7984 }
7985 }
7986 }
7987 }
7988 }
7989 }
7990 }
7991 }
7992 }
7993 }
7994 }
7995 }
7996 }
7997 }
7998 }
7999 }
8000 }
8001 }
8002 }
8003 }
8004 }
8005 }
8006 }
8007 }
8008 }
8009 }
8010 }
8011 }
8012 }
8013 }
8014 }
8015 }
8016 }
8017 }
8018 }
8019 }
8020 }
8021 }
8022 }
8023 }
8024 }
8025 }
8026 }
8027 }
8028 }
8029 }
8030 }
8031 }
8032 }
8033 }
8034 }
8035 }
8036 }
8037 }
8038 }
8039 }
8040 }
8041 }
8042 }
8043 }
8044 }
8045 }
8046 }
8047 }
8048 }
8049 }
8050 }
8051 }
8052 }
8053 }
8054 }
8055 }
8056 }
8057 }
8058 }
8059 }
8060 }
8061 }
8062 }
8063 }
8064 }
8065 }
8066 }
8067 }
8068 }
8069 }
8070 }
8071 }
8072 }
8073 }
8074 }
8075 }
8076 }
8077 }
8078 }
8079 }
8080 }
8081 }
8082 }
8083 }
8084 }
8085 }
8086 }
8087 }
8088 }
8089 }
8090 }
8091 }
8092 }
8093 }
8094 }
8095 }
8096 }
8097 }
8098 }
8099 }
8100 }
8101 }
8102 }
8103 }
8104 }
8105 }
8106 }
8107 }
8108 }
8109 }
8110 }
8111 }
8112 peg$silentFails--;
8113 if (s0 === peg$FAILED) {
8114 s1 = peg$FAILED;
8115 if (peg$silentFails === 0) {
8116 peg$fail(peg$e162);
8117 }
8118 }
8119 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8120 return s0;
8121 }
8122 function peg$parseLEFT_OP() {
8123 var s0, s1, s2;
8124 var key = peg$currPos * 306 + 167;
8125 var cached = peg$resultsCache[key];
8126 if (cached) {
8127 peg$currPos = cached.nextPos;
8128 return cached.result;
8129 }
8130 s0 = peg$currPos;
8131 if (input.substr(peg$currPos, 2) === peg$c162) {
8132 s1 = peg$c162;
8133 peg$currPos += 2;
8134 } else {
8135 s1 = peg$FAILED;
8136 if (peg$silentFails === 0) {
8137 peg$fail(peg$e163);
8138 }
8139 }
8140 if (s1 !== peg$FAILED) {
8141 s2 = peg$parse_();
8142 peg$savedPos = s0;
8143 s0 = peg$f7(s1, s2);
8144 } else {
8145 peg$currPos = s0;
8146 s0 = peg$FAILED;
8147 }
8148 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8149 return s0;
8150 }
8151 function peg$parseRIGHT_OP() {
8152 var s0, s1, s2;
8153 var key = peg$currPos * 306 + 168;
8154 var cached = peg$resultsCache[key];
8155 if (cached) {
8156 peg$currPos = cached.nextPos;
8157 return cached.result;
8158 }
8159 s0 = peg$currPos;
8160 if (input.substr(peg$currPos, 2) === peg$c163) {
8161 s1 = peg$c163;
8162 peg$currPos += 2;
8163 } else {
8164 s1 = peg$FAILED;
8165 if (peg$silentFails === 0) {
8166 peg$fail(peg$e164);
8167 }
8168 }
8169 if (s1 !== peg$FAILED) {
8170 s2 = peg$parse_();
8171 peg$savedPos = s0;
8172 s0 = peg$f7(s1, s2);
8173 } else {
8174 peg$currPos = s0;
8175 s0 = peg$FAILED;
8176 }
8177 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8178 return s0;
8179 }
8180 function peg$parseINC_OP() {
8181 var s0, s1, s2;
8182 var key = peg$currPos * 306 + 169;
8183 var cached = peg$resultsCache[key];
8184 if (cached) {
8185 peg$currPos = cached.nextPos;
8186 return cached.result;
8187 }
8188 s0 = peg$currPos;
8189 if (input.substr(peg$currPos, 2) === peg$c164) {
8190 s1 = peg$c164;
8191 peg$currPos += 2;
8192 } else {
8193 s1 = peg$FAILED;
8194 if (peg$silentFails === 0) {
8195 peg$fail(peg$e165);
8196 }
8197 }
8198 if (s1 !== peg$FAILED) {
8199 s2 = peg$parse_();
8200 peg$savedPos = s0;
8201 s0 = peg$f7(s1, s2);
8202 } else {
8203 peg$currPos = s0;
8204 s0 = peg$FAILED;
8205 }
8206 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8207 return s0;
8208 }
8209 function peg$parseDEC_OP() {
8210 var s0, s1, s2;
8211 var key = peg$currPos * 306 + 170;
8212 var cached = peg$resultsCache[key];
8213 if (cached) {
8214 peg$currPos = cached.nextPos;
8215 return cached.result;
8216 }
8217 s0 = peg$currPos;
8218 if (input.substr(peg$currPos, 2) === peg$c165) {
8219 s1 = peg$c165;
8220 peg$currPos += 2;
8221 } else {
8222 s1 = peg$FAILED;
8223 if (peg$silentFails === 0) {
8224 peg$fail(peg$e166);
8225 }
8226 }
8227 if (s1 !== peg$FAILED) {
8228 s2 = peg$parse_();
8229 peg$savedPos = s0;
8230 s0 = peg$f7(s1, s2);
8231 } else {
8232 peg$currPos = s0;
8233 s0 = peg$FAILED;
8234 }
8235 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8236 return s0;
8237 }
8238 function peg$parseLE_OP() {
8239 var s0, s1, s2;
8240 var key = peg$currPos * 306 + 171;
8241 var cached = peg$resultsCache[key];
8242 if (cached) {
8243 peg$currPos = cached.nextPos;
8244 return cached.result;
8245 }
8246 s0 = peg$currPos;
8247 if (input.substr(peg$currPos, 2) === peg$c166) {
8248 s1 = peg$c166;
8249 peg$currPos += 2;
8250 } else {
8251 s1 = peg$FAILED;
8252 if (peg$silentFails === 0) {
8253 peg$fail(peg$e167);
8254 }
8255 }
8256 if (s1 !== peg$FAILED) {
8257 s2 = peg$parse_();
8258 peg$savedPos = s0;
8259 s0 = peg$f7(s1, s2);
8260 } else {
8261 peg$currPos = s0;
8262 s0 = peg$FAILED;
8263 }
8264 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8265 return s0;
8266 }
8267 function peg$parseGE_OP() {
8268 var s0, s1, s2;
8269 var key = peg$currPos * 306 + 172;
8270 var cached = peg$resultsCache[key];
8271 if (cached) {
8272 peg$currPos = cached.nextPos;
8273 return cached.result;
8274 }
8275 s0 = peg$currPos;
8276 if (input.substr(peg$currPos, 2) === peg$c167) {
8277 s1 = peg$c167;
8278 peg$currPos += 2;
8279 } else {
8280 s1 = peg$FAILED;
8281 if (peg$silentFails === 0) {
8282 peg$fail(peg$e168);
8283 }
8284 }
8285 if (s1 !== peg$FAILED) {
8286 s2 = peg$parse_();
8287 peg$savedPos = s0;
8288 s0 = peg$f7(s1, s2);
8289 } else {
8290 peg$currPos = s0;
8291 s0 = peg$FAILED;
8292 }
8293 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8294 return s0;
8295 }
8296 function peg$parseEQ_OP() {
8297 var s0, s1, s2;
8298 var key = peg$currPos * 306 + 173;
8299 var cached = peg$resultsCache[key];
8300 if (cached) {
8301 peg$currPos = cached.nextPos;
8302 return cached.result;
8303 }
8304 s0 = peg$currPos;
8305 if (input.substr(peg$currPos, 2) === peg$c168) {
8306 s1 = peg$c168;
8307 peg$currPos += 2;
8308 } else {
8309 s1 = peg$FAILED;
8310 if (peg$silentFails === 0) {
8311 peg$fail(peg$e169);
8312 }
8313 }
8314 if (s1 !== peg$FAILED) {
8315 s2 = peg$parse_();
8316 peg$savedPos = s0;
8317 s0 = peg$f7(s1, s2);
8318 } else {
8319 peg$currPos = s0;
8320 s0 = peg$FAILED;
8321 }
8322 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8323 return s0;
8324 }
8325 function peg$parseNE_OP() {
8326 var s0, s1, s2;
8327 var key = peg$currPos * 306 + 174;
8328 var cached = peg$resultsCache[key];
8329 if (cached) {
8330 peg$currPos = cached.nextPos;
8331 return cached.result;
8332 }
8333 s0 = peg$currPos;
8334 if (input.substr(peg$currPos, 2) === peg$c169) {
8335 s1 = peg$c169;
8336 peg$currPos += 2;
8337 } else {
8338 s1 = peg$FAILED;
8339 if (peg$silentFails === 0) {
8340 peg$fail(peg$e170);
8341 }
8342 }
8343 if (s1 !== peg$FAILED) {
8344 s2 = peg$parse_();
8345 peg$savedPos = s0;
8346 s0 = peg$f7(s1, s2);
8347 } else {
8348 peg$currPos = s0;
8349 s0 = peg$FAILED;
8350 }
8351 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8352 return s0;
8353 }
8354 function peg$parseAND_OP() {
8355 var s0, s1, s2;
8356 var key = peg$currPos * 306 + 175;
8357 var cached = peg$resultsCache[key];
8358 if (cached) {
8359 peg$currPos = cached.nextPos;
8360 return cached.result;
8361 }
8362 s0 = peg$currPos;
8363 if (input.substr(peg$currPos, 2) === peg$c170) {
8364 s1 = peg$c170;
8365 peg$currPos += 2;
8366 } else {
8367 s1 = peg$FAILED;
8368 if (peg$silentFails === 0) {
8369 peg$fail(peg$e171);
8370 }
8371 }
8372 if (s1 !== peg$FAILED) {
8373 s2 = peg$parse_();
8374 peg$savedPos = s0;
8375 s0 = peg$f7(s1, s2);
8376 } else {
8377 peg$currPos = s0;
8378 s0 = peg$FAILED;
8379 }
8380 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8381 return s0;
8382 }
8383 function peg$parseOR_OP() {
8384 var s0, s1, s2;
8385 var key = peg$currPos * 306 + 176;
8386 var cached = peg$resultsCache[key];
8387 if (cached) {
8388 peg$currPos = cached.nextPos;
8389 return cached.result;
8390 }
8391 s0 = peg$currPos;
8392 if (input.substr(peg$currPos, 2) === peg$c171) {
8393 s1 = peg$c171;
8394 peg$currPos += 2;
8395 } else {
8396 s1 = peg$FAILED;
8397 if (peg$silentFails === 0) {
8398 peg$fail(peg$e172);
8399 }
8400 }
8401 if (s1 !== peg$FAILED) {
8402 s2 = peg$parse_();
8403 peg$savedPos = s0;
8404 s0 = peg$f7(s1, s2);
8405 } else {
8406 peg$currPos = s0;
8407 s0 = peg$FAILED;
8408 }
8409 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8410 return s0;
8411 }
8412 function peg$parseXOR_OP() {
8413 var s0, s1, s2;
8414 var key = peg$currPos * 306 + 177;
8415 var cached = peg$resultsCache[key];
8416 if (cached) {
8417 peg$currPos = cached.nextPos;
8418 return cached.result;
8419 }
8420 s0 = peg$currPos;
8421 if (input.substr(peg$currPos, 2) === peg$c172) {
8422 s1 = peg$c172;
8423 peg$currPos += 2;
8424 } else {
8425 s1 = peg$FAILED;
8426 if (peg$silentFails === 0) {
8427 peg$fail(peg$e173);
8428 }
8429 }
8430 if (s1 !== peg$FAILED) {
8431 s2 = peg$parse_();
8432 peg$savedPos = s0;
8433 s0 = peg$f7(s1, s2);
8434 } else {
8435 peg$currPos = s0;
8436 s0 = peg$FAILED;
8437 }
8438 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8439 return s0;
8440 }
8441 function peg$parseMUL_ASSIGN() {
8442 var s0, s1, s2;
8443 var key = peg$currPos * 306 + 178;
8444 var cached = peg$resultsCache[key];
8445 if (cached) {
8446 peg$currPos = cached.nextPos;
8447 return cached.result;
8448 }
8449 s0 = peg$currPos;
8450 if (input.substr(peg$currPos, 2) === peg$c173) {
8451 s1 = peg$c173;
8452 peg$currPos += 2;
8453 } else {
8454 s1 = peg$FAILED;
8455 if (peg$silentFails === 0) {
8456 peg$fail(peg$e174);
8457 }
8458 }
8459 if (s1 !== peg$FAILED) {
8460 s2 = peg$parse_();
8461 peg$savedPos = s0;
8462 s0 = peg$f7(s1, s2);
8463 } else {
8464 peg$currPos = s0;
8465 s0 = peg$FAILED;
8466 }
8467 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8468 return s0;
8469 }
8470 function peg$parseDIV_ASSIGN() {
8471 var s0, s1, s2;
8472 var key = peg$currPos * 306 + 179;
8473 var cached = peg$resultsCache[key];
8474 if (cached) {
8475 peg$currPos = cached.nextPos;
8476 return cached.result;
8477 }
8478 s0 = peg$currPos;
8479 if (input.substr(peg$currPos, 2) === peg$c174) {
8480 s1 = peg$c174;
8481 peg$currPos += 2;
8482 } else {
8483 s1 = peg$FAILED;
8484 if (peg$silentFails === 0) {
8485 peg$fail(peg$e175);
8486 }
8487 }
8488 if (s1 !== peg$FAILED) {
8489 s2 = peg$parse_();
8490 peg$savedPos = s0;
8491 s0 = peg$f7(s1, s2);
8492 } else {
8493 peg$currPos = s0;
8494 s0 = peg$FAILED;
8495 }
8496 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8497 return s0;
8498 }
8499 function peg$parseADD_ASSIGN() {
8500 var s0, s1, s2;
8501 var key = peg$currPos * 306 + 180;
8502 var cached = peg$resultsCache[key];
8503 if (cached) {
8504 peg$currPos = cached.nextPos;
8505 return cached.result;
8506 }
8507 s0 = peg$currPos;
8508 if (input.substr(peg$currPos, 2) === peg$c175) {
8509 s1 = peg$c175;
8510 peg$currPos += 2;
8511 } else {
8512 s1 = peg$FAILED;
8513 if (peg$silentFails === 0) {
8514 peg$fail(peg$e176);
8515 }
8516 }
8517 if (s1 !== peg$FAILED) {
8518 s2 = peg$parse_();
8519 peg$savedPos = s0;
8520 s0 = peg$f7(s1, s2);
8521 } else {
8522 peg$currPos = s0;
8523 s0 = peg$FAILED;
8524 }
8525 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8526 return s0;
8527 }
8528 function peg$parseMOD_ASSIGN() {
8529 var s0, s1, s2;
8530 var key = peg$currPos * 306 + 181;
8531 var cached = peg$resultsCache[key];
8532 if (cached) {
8533 peg$currPos = cached.nextPos;
8534 return cached.result;
8535 }
8536 s0 = peg$currPos;
8537 if (input.substr(peg$currPos, 2) === peg$c176) {
8538 s1 = peg$c176;
8539 peg$currPos += 2;
8540 } else {
8541 s1 = peg$FAILED;
8542 if (peg$silentFails === 0) {
8543 peg$fail(peg$e177);
8544 }
8545 }
8546 if (s1 !== peg$FAILED) {
8547 s2 = peg$parse_();
8548 peg$savedPos = s0;
8549 s0 = peg$f7(s1, s2);
8550 } else {
8551 peg$currPos = s0;
8552 s0 = peg$FAILED;
8553 }
8554 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8555 return s0;
8556 }
8557 function peg$parseLEFT_ASSIGN() {
8558 var s0, s1, s2;
8559 var key = peg$currPos * 306 + 182;
8560 var cached = peg$resultsCache[key];
8561 if (cached) {
8562 peg$currPos = cached.nextPos;
8563 return cached.result;
8564 }
8565 s0 = peg$currPos;
8566 if (input.substr(peg$currPos, 3) === peg$c177) {
8567 s1 = peg$c177;
8568 peg$currPos += 3;
8569 } else {
8570 s1 = peg$FAILED;
8571 if (peg$silentFails === 0) {
8572 peg$fail(peg$e178);
8573 }
8574 }
8575 if (s1 !== peg$FAILED) {
8576 s2 = peg$parse_();
8577 peg$savedPos = s0;
8578 s0 = peg$f7(s1, s2);
8579 } else {
8580 peg$currPos = s0;
8581 s0 = peg$FAILED;
8582 }
8583 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8584 return s0;
8585 }
8586 function peg$parseRIGHT_ASSIGN() {
8587 var s0, s1, s2;
8588 var key = peg$currPos * 306 + 183;
8589 var cached = peg$resultsCache[key];
8590 if (cached) {
8591 peg$currPos = cached.nextPos;
8592 return cached.result;
8593 }
8594 s0 = peg$currPos;
8595 if (input.substr(peg$currPos, 3) === peg$c178) {
8596 s1 = peg$c178;
8597 peg$currPos += 3;
8598 } else {
8599 s1 = peg$FAILED;
8600 if (peg$silentFails === 0) {
8601 peg$fail(peg$e179);
8602 }
8603 }
8604 if (s1 !== peg$FAILED) {
8605 s2 = peg$parse_();
8606 peg$savedPos = s0;
8607 s0 = peg$f7(s1, s2);
8608 } else {
8609 peg$currPos = s0;
8610 s0 = peg$FAILED;
8611 }
8612 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8613 return s0;
8614 }
8615 function peg$parseAND_ASSIGN() {
8616 var s0, s1, s2;
8617 var key = peg$currPos * 306 + 184;
8618 var cached = peg$resultsCache[key];
8619 if (cached) {
8620 peg$currPos = cached.nextPos;
8621 return cached.result;
8622 }
8623 s0 = peg$currPos;
8624 if (input.substr(peg$currPos, 2) === peg$c179) {
8625 s1 = peg$c179;
8626 peg$currPos += 2;
8627 } else {
8628 s1 = peg$FAILED;
8629 if (peg$silentFails === 0) {
8630 peg$fail(peg$e180);
8631 }
8632 }
8633 if (s1 !== peg$FAILED) {
8634 s2 = peg$parse_();
8635 peg$savedPos = s0;
8636 s0 = peg$f7(s1, s2);
8637 } else {
8638 peg$currPos = s0;
8639 s0 = peg$FAILED;
8640 }
8641 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8642 return s0;
8643 }
8644 function peg$parseXOR_ASSIGN() {
8645 var s0, s1, s2;
8646 var key = peg$currPos * 306 + 185;
8647 var cached = peg$resultsCache[key];
8648 if (cached) {
8649 peg$currPos = cached.nextPos;
8650 return cached.result;
8651 }
8652 s0 = peg$currPos;
8653 if (input.substr(peg$currPos, 2) === peg$c180) {
8654 s1 = peg$c180;
8655 peg$currPos += 2;
8656 } else {
8657 s1 = peg$FAILED;
8658 if (peg$silentFails === 0) {
8659 peg$fail(peg$e181);
8660 }
8661 }
8662 if (s1 !== peg$FAILED) {
8663 s2 = peg$parse_();
8664 peg$savedPos = s0;
8665 s0 = peg$f7(s1, s2);
8666 } else {
8667 peg$currPos = s0;
8668 s0 = peg$FAILED;
8669 }
8670 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8671 return s0;
8672 }
8673 function peg$parseOR_ASSIGN() {
8674 var s0, s1, s2;
8675 var key = peg$currPos * 306 + 186;
8676 var cached = peg$resultsCache[key];
8677 if (cached) {
8678 peg$currPos = cached.nextPos;
8679 return cached.result;
8680 }
8681 s0 = peg$currPos;
8682 if (input.substr(peg$currPos, 2) === peg$c181) {
8683 s1 = peg$c181;
8684 peg$currPos += 2;
8685 } else {
8686 s1 = peg$FAILED;
8687 if (peg$silentFails === 0) {
8688 peg$fail(peg$e182);
8689 }
8690 }
8691 if (s1 !== peg$FAILED) {
8692 s2 = peg$parse_();
8693 peg$savedPos = s0;
8694 s0 = peg$f7(s1, s2);
8695 } else {
8696 peg$currPos = s0;
8697 s0 = peg$FAILED;
8698 }
8699 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8700 return s0;
8701 }
8702 function peg$parseSUB_ASSIGN() {
8703 var s0, s1, s2;
8704 var key = peg$currPos * 306 + 187;
8705 var cached = peg$resultsCache[key];
8706 if (cached) {
8707 peg$currPos = cached.nextPos;
8708 return cached.result;
8709 }
8710 s0 = peg$currPos;
8711 if (input.substr(peg$currPos, 2) === peg$c182) {
8712 s1 = peg$c182;
8713 peg$currPos += 2;
8714 } else {
8715 s1 = peg$FAILED;
8716 if (peg$silentFails === 0) {
8717 peg$fail(peg$e183);
8718 }
8719 }
8720 if (s1 !== peg$FAILED) {
8721 s2 = peg$parse_();
8722 peg$savedPos = s0;
8723 s0 = peg$f7(s1, s2);
8724 } else {
8725 peg$currPos = s0;
8726 s0 = peg$FAILED;
8727 }
8728 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8729 return s0;
8730 }
8731 function peg$parseLEFT_PAREN() {
8732 var s0, s1, s2;
8733 var key = peg$currPos * 306 + 188;
8734 var cached = peg$resultsCache[key];
8735 if (cached) {
8736 peg$currPos = cached.nextPos;
8737 return cached.result;
8738 }
8739 s0 = peg$currPos;
8740 if (input.charCodeAt(peg$currPos) === 40) {
8741 s1 = peg$c183;
8742 peg$currPos++;
8743 } else {
8744 s1 = peg$FAILED;
8745 if (peg$silentFails === 0) {
8746 peg$fail(peg$e184);
8747 }
8748 }
8749 if (s1 !== peg$FAILED) {
8750 s2 = peg$parse_();
8751 peg$savedPos = s0;
8752 s0 = peg$f7(s1, s2);
8753 } else {
8754 peg$currPos = s0;
8755 s0 = peg$FAILED;
8756 }
8757 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8758 return s0;
8759 }
8760 function peg$parseRIGHT_PAREN() {
8761 var s0, s1, s2;
8762 var key = peg$currPos * 306 + 189;
8763 var cached = peg$resultsCache[key];
8764 if (cached) {
8765 peg$currPos = cached.nextPos;
8766 return cached.result;
8767 }
8768 s0 = peg$currPos;
8769 if (input.charCodeAt(peg$currPos) === 41) {
8770 s1 = peg$c184;
8771 peg$currPos++;
8772 } else {
8773 s1 = peg$FAILED;
8774 if (peg$silentFails === 0) {
8775 peg$fail(peg$e185);
8776 }
8777 }
8778 if (s1 !== peg$FAILED) {
8779 s2 = peg$parse_();
8780 peg$savedPos = s0;
8781 s0 = peg$f7(s1, s2);
8782 } else {
8783 peg$currPos = s0;
8784 s0 = peg$FAILED;
8785 }
8786 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8787 return s0;
8788 }
8789 function peg$parseLEFT_BRACKET() {
8790 var s0, s1, s2;
8791 var key = peg$currPos * 306 + 190;
8792 var cached = peg$resultsCache[key];
8793 if (cached) {
8794 peg$currPos = cached.nextPos;
8795 return cached.result;
8796 }
8797 s0 = peg$currPos;
8798 if (input.charCodeAt(peg$currPos) === 91) {
8799 s1 = peg$c185;
8800 peg$currPos++;
8801 } else {
8802 s1 = peg$FAILED;
8803 if (peg$silentFails === 0) {
8804 peg$fail(peg$e186);
8805 }
8806 }
8807 if (s1 !== peg$FAILED) {
8808 s2 = peg$parse_();
8809 peg$savedPos = s0;
8810 s0 = peg$f7(s1, s2);
8811 } else {
8812 peg$currPos = s0;
8813 s0 = peg$FAILED;
8814 }
8815 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8816 return s0;
8817 }
8818 function peg$parseRIGHT_BRACKET() {
8819 var s0, s1, s2;
8820 var key = peg$currPos * 306 + 191;
8821 var cached = peg$resultsCache[key];
8822 if (cached) {
8823 peg$currPos = cached.nextPos;
8824 return cached.result;
8825 }
8826 s0 = peg$currPos;
8827 if (input.charCodeAt(peg$currPos) === 93) {
8828 s1 = peg$c186;
8829 peg$currPos++;
8830 } else {
8831 s1 = peg$FAILED;
8832 if (peg$silentFails === 0) {
8833 peg$fail(peg$e187);
8834 }
8835 }
8836 if (s1 !== peg$FAILED) {
8837 s2 = peg$parse_();
8838 peg$savedPos = s0;
8839 s0 = peg$f7(s1, s2);
8840 } else {
8841 peg$currPos = s0;
8842 s0 = peg$FAILED;
8843 }
8844 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8845 return s0;
8846 }
8847 function peg$parseLEFT_BRACE() {
8848 var s0, s1, s2;
8849 var key = peg$currPos * 306 + 192;
8850 var cached = peg$resultsCache[key];
8851 if (cached) {
8852 peg$currPos = cached.nextPos;
8853 return cached.result;
8854 }
8855 s0 = peg$currPos;
8856 if (input.charCodeAt(peg$currPos) === 123) {
8857 s1 = peg$c187;
8858 peg$currPos++;
8859 } else {
8860 s1 = peg$FAILED;
8861 if (peg$silentFails === 0) {
8862 peg$fail(peg$e188);
8863 }
8864 }
8865 if (s1 !== peg$FAILED) {
8866 s2 = peg$parse_();
8867 peg$savedPos = s0;
8868 s0 = peg$f7(s1, s2);
8869 } else {
8870 peg$currPos = s0;
8871 s0 = peg$FAILED;
8872 }
8873 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8874 return s0;
8875 }
8876 function peg$parseRIGHT_BRACE() {
8877 var s0, s1, s2;
8878 var key = peg$currPos * 306 + 193;
8879 var cached = peg$resultsCache[key];
8880 if (cached) {
8881 peg$currPos = cached.nextPos;
8882 return cached.result;
8883 }
8884 s0 = peg$currPos;
8885 if (input.charCodeAt(peg$currPos) === 125) {
8886 s1 = peg$c188;
8887 peg$currPos++;
8888 } else {
8889 s1 = peg$FAILED;
8890 if (peg$silentFails === 0) {
8891 peg$fail(peg$e189);
8892 }
8893 }
8894 if (s1 !== peg$FAILED) {
8895 s2 = peg$parse_();
8896 peg$savedPos = s0;
8897 s0 = peg$f7(s1, s2);
8898 } else {
8899 peg$currPos = s0;
8900 s0 = peg$FAILED;
8901 }
8902 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8903 return s0;
8904 }
8905 function peg$parseDOT() {
8906 var s0, s1, s2;
8907 var key = peg$currPos * 306 + 194;
8908 var cached = peg$resultsCache[key];
8909 if (cached) {
8910 peg$currPos = cached.nextPos;
8911 return cached.result;
8912 }
8913 s0 = peg$currPos;
8914 if (input.charCodeAt(peg$currPos) === 46) {
8915 s1 = peg$c189;
8916 peg$currPos++;
8917 } else {
8918 s1 = peg$FAILED;
8919 if (peg$silentFails === 0) {
8920 peg$fail(peg$e190);
8921 }
8922 }
8923 if (s1 !== peg$FAILED) {
8924 s2 = peg$parse_();
8925 peg$savedPos = s0;
8926 s0 = peg$f7(s1, s2);
8927 } else {
8928 peg$currPos = s0;
8929 s0 = peg$FAILED;
8930 }
8931 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8932 return s0;
8933 }
8934 function peg$parseCOMMA() {
8935 var s0, s1, s2;
8936 var key = peg$currPos * 306 + 195;
8937 var cached = peg$resultsCache[key];
8938 if (cached) {
8939 peg$currPos = cached.nextPos;
8940 return cached.result;
8941 }
8942 s0 = peg$currPos;
8943 if (input.charCodeAt(peg$currPos) === 44) {
8944 s1 = peg$c190;
8945 peg$currPos++;
8946 } else {
8947 s1 = peg$FAILED;
8948 if (peg$silentFails === 0) {
8949 peg$fail(peg$e191);
8950 }
8951 }
8952 if (s1 !== peg$FAILED) {
8953 s2 = peg$parse_();
8954 peg$savedPos = s0;
8955 s0 = peg$f7(s1, s2);
8956 } else {
8957 peg$currPos = s0;
8958 s0 = peg$FAILED;
8959 }
8960 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8961 return s0;
8962 }
8963 function peg$parseCOLON() {
8964 var s0, s1, s2;
8965 var key = peg$currPos * 306 + 196;
8966 var cached = peg$resultsCache[key];
8967 if (cached) {
8968 peg$currPos = cached.nextPos;
8969 return cached.result;
8970 }
8971 s0 = peg$currPos;
8972 if (input.charCodeAt(peg$currPos) === 58) {
8973 s1 = peg$c191;
8974 peg$currPos++;
8975 } else {
8976 s1 = peg$FAILED;
8977 if (peg$silentFails === 0) {
8978 peg$fail(peg$e192);
8979 }
8980 }
8981 if (s1 !== peg$FAILED) {
8982 s2 = peg$parse_();
8983 peg$savedPos = s0;
8984 s0 = peg$f7(s1, s2);
8985 } else {
8986 peg$currPos = s0;
8987 s0 = peg$FAILED;
8988 }
8989 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
8990 return s0;
8991 }
8992 function peg$parseEQUAL() {
8993 var s0, s1, s2;
8994 var key = peg$currPos * 306 + 197;
8995 var cached = peg$resultsCache[key];
8996 if (cached) {
8997 peg$currPos = cached.nextPos;
8998 return cached.result;
8999 }
9000 s0 = peg$currPos;
9001 if (input.charCodeAt(peg$currPos) === 61) {
9002 s1 = peg$c192;
9003 peg$currPos++;
9004 } else {
9005 s1 = peg$FAILED;
9006 if (peg$silentFails === 0) {
9007 peg$fail(peg$e193);
9008 }
9009 }
9010 if (s1 !== peg$FAILED) {
9011 s2 = peg$parse_();
9012 peg$savedPos = s0;
9013 s0 = peg$f7(s1, s2);
9014 } else {
9015 peg$currPos = s0;
9016 s0 = peg$FAILED;
9017 }
9018 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9019 return s0;
9020 }
9021 function peg$parseSEMICOLON() {
9022 var s0, s1, s2;
9023 var key = peg$currPos * 306 + 198;
9024 var cached = peg$resultsCache[key];
9025 if (cached) {
9026 peg$currPos = cached.nextPos;
9027 return cached.result;
9028 }
9029 s0 = peg$currPos;
9030 if (input.charCodeAt(peg$currPos) === 59) {
9031 s1 = peg$c193;
9032 peg$currPos++;
9033 } else {
9034 s1 = peg$FAILED;
9035 if (peg$silentFails === 0) {
9036 peg$fail(peg$e194);
9037 }
9038 }
9039 if (s1 !== peg$FAILED) {
9040 s2 = peg$parse_();
9041 peg$savedPos = s0;
9042 s0 = peg$f7(s1, s2);
9043 } else {
9044 peg$currPos = s0;
9045 s0 = peg$FAILED;
9046 }
9047 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9048 return s0;
9049 }
9050 function peg$parseBANG() {
9051 var s0, s1, s2;
9052 var key = peg$currPos * 306 + 199;
9053 var cached = peg$resultsCache[key];
9054 if (cached) {
9055 peg$currPos = cached.nextPos;
9056 return cached.result;
9057 }
9058 s0 = peg$currPos;
9059 if (input.charCodeAt(peg$currPos) === 33) {
9060 s1 = peg$c194;
9061 peg$currPos++;
9062 } else {
9063 s1 = peg$FAILED;
9064 if (peg$silentFails === 0) {
9065 peg$fail(peg$e195);
9066 }
9067 }
9068 if (s1 !== peg$FAILED) {
9069 s2 = peg$parse_();
9070 peg$savedPos = s0;
9071 s0 = peg$f7(s1, s2);
9072 } else {
9073 peg$currPos = s0;
9074 s0 = peg$FAILED;
9075 }
9076 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9077 return s0;
9078 }
9079 function peg$parseDASH() {
9080 var s0, s1, s2;
9081 var key = peg$currPos * 306 + 200;
9082 var cached = peg$resultsCache[key];
9083 if (cached) {
9084 peg$currPos = cached.nextPos;
9085 return cached.result;
9086 }
9087 s0 = peg$currPos;
9088 if (input.charCodeAt(peg$currPos) === 45) {
9089 s1 = peg$c195;
9090 peg$currPos++;
9091 } else {
9092 s1 = peg$FAILED;
9093 if (peg$silentFails === 0) {
9094 peg$fail(peg$e196);
9095 }
9096 }
9097 if (s1 !== peg$FAILED) {
9098 s2 = peg$parse_();
9099 peg$savedPos = s0;
9100 s0 = peg$f7(s1, s2);
9101 } else {
9102 peg$currPos = s0;
9103 s0 = peg$FAILED;
9104 }
9105 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9106 return s0;
9107 }
9108 function peg$parseTILDE() {
9109 var s0, s1, s2;
9110 var key = peg$currPos * 306 + 201;
9111 var cached = peg$resultsCache[key];
9112 if (cached) {
9113 peg$currPos = cached.nextPos;
9114 return cached.result;
9115 }
9116 s0 = peg$currPos;
9117 if (input.charCodeAt(peg$currPos) === 126) {
9118 s1 = peg$c196;
9119 peg$currPos++;
9120 } else {
9121 s1 = peg$FAILED;
9122 if (peg$silentFails === 0) {
9123 peg$fail(peg$e197);
9124 }
9125 }
9126 if (s1 !== peg$FAILED) {
9127 s2 = peg$parse_();
9128 peg$savedPos = s0;
9129 s0 = peg$f7(s1, s2);
9130 } else {
9131 peg$currPos = s0;
9132 s0 = peg$FAILED;
9133 }
9134 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9135 return s0;
9136 }
9137 function peg$parsePLUS() {
9138 var s0, s1, s2;
9139 var key = peg$currPos * 306 + 202;
9140 var cached = peg$resultsCache[key];
9141 if (cached) {
9142 peg$currPos = cached.nextPos;
9143 return cached.result;
9144 }
9145 s0 = peg$currPos;
9146 if (input.charCodeAt(peg$currPos) === 43) {
9147 s1 = peg$c197;
9148 peg$currPos++;
9149 } else {
9150 s1 = peg$FAILED;
9151 if (peg$silentFails === 0) {
9152 peg$fail(peg$e198);
9153 }
9154 }
9155 if (s1 !== peg$FAILED) {
9156 s2 = peg$parse_();
9157 peg$savedPos = s0;
9158 s0 = peg$f7(s1, s2);
9159 } else {
9160 peg$currPos = s0;
9161 s0 = peg$FAILED;
9162 }
9163 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9164 return s0;
9165 }
9166 function peg$parseSTAR() {
9167 var s0, s1, s2;
9168 var key = peg$currPos * 306 + 203;
9169 var cached = peg$resultsCache[key];
9170 if (cached) {
9171 peg$currPos = cached.nextPos;
9172 return cached.result;
9173 }
9174 s0 = peg$currPos;
9175 if (input.charCodeAt(peg$currPos) === 42) {
9176 s1 = peg$c198;
9177 peg$currPos++;
9178 } else {
9179 s1 = peg$FAILED;
9180 if (peg$silentFails === 0) {
9181 peg$fail(peg$e199);
9182 }
9183 }
9184 if (s1 !== peg$FAILED) {
9185 s2 = peg$parse_();
9186 peg$savedPos = s0;
9187 s0 = peg$f7(s1, s2);
9188 } else {
9189 peg$currPos = s0;
9190 s0 = peg$FAILED;
9191 }
9192 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9193 return s0;
9194 }
9195 function peg$parseSLASH() {
9196 var s0, s1, s2;
9197 var key = peg$currPos * 306 + 204;
9198 var cached = peg$resultsCache[key];
9199 if (cached) {
9200 peg$currPos = cached.nextPos;
9201 return cached.result;
9202 }
9203 s0 = peg$currPos;
9204 if (input.charCodeAt(peg$currPos) === 47) {
9205 s1 = peg$c199;
9206 peg$currPos++;
9207 } else {
9208 s1 = peg$FAILED;
9209 if (peg$silentFails === 0) {
9210 peg$fail(peg$e200);
9211 }
9212 }
9213 if (s1 !== peg$FAILED) {
9214 s2 = peg$parse_();
9215 peg$savedPos = s0;
9216 s0 = peg$f7(s1, s2);
9217 } else {
9218 peg$currPos = s0;
9219 s0 = peg$FAILED;
9220 }
9221 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9222 return s0;
9223 }
9224 function peg$parsePERCENT() {
9225 var s0, s1, s2;
9226 var key = peg$currPos * 306 + 205;
9227 var cached = peg$resultsCache[key];
9228 if (cached) {
9229 peg$currPos = cached.nextPos;
9230 return cached.result;
9231 }
9232 s0 = peg$currPos;
9233 if (input.charCodeAt(peg$currPos) === 37) {
9234 s1 = peg$c200;
9235 peg$currPos++;
9236 } else {
9237 s1 = peg$FAILED;
9238 if (peg$silentFails === 0) {
9239 peg$fail(peg$e201);
9240 }
9241 }
9242 if (s1 !== peg$FAILED) {
9243 s2 = peg$parse_();
9244 peg$savedPos = s0;
9245 s0 = peg$f7(s1, s2);
9246 } else {
9247 peg$currPos = s0;
9248 s0 = peg$FAILED;
9249 }
9250 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9251 return s0;
9252 }
9253 function peg$parseLEFT_ANGLE() {
9254 var s0, s1, s2;
9255 var key = peg$currPos * 306 + 206;
9256 var cached = peg$resultsCache[key];
9257 if (cached) {
9258 peg$currPos = cached.nextPos;
9259 return cached.result;
9260 }
9261 s0 = peg$currPos;
9262 if (input.charCodeAt(peg$currPos) === 60) {
9263 s1 = peg$c201;
9264 peg$currPos++;
9265 } else {
9266 s1 = peg$FAILED;
9267 if (peg$silentFails === 0) {
9268 peg$fail(peg$e202);
9269 }
9270 }
9271 if (s1 !== peg$FAILED) {
9272 s2 = peg$parse_();
9273 peg$savedPos = s0;
9274 s0 = peg$f7(s1, s2);
9275 } else {
9276 peg$currPos = s0;
9277 s0 = peg$FAILED;
9278 }
9279 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9280 return s0;
9281 }
9282 function peg$parseRIGHT_ANGLE() {
9283 var s0, s1, s2;
9284 var key = peg$currPos * 306 + 207;
9285 var cached = peg$resultsCache[key];
9286 if (cached) {
9287 peg$currPos = cached.nextPos;
9288 return cached.result;
9289 }
9290 s0 = peg$currPos;
9291 if (input.charCodeAt(peg$currPos) === 62) {
9292 s1 = peg$c202;
9293 peg$currPos++;
9294 } else {
9295 s1 = peg$FAILED;
9296 if (peg$silentFails === 0) {
9297 peg$fail(peg$e203);
9298 }
9299 }
9300 if (s1 !== peg$FAILED) {
9301 s2 = peg$parse_();
9302 peg$savedPos = s0;
9303 s0 = peg$f7(s1, s2);
9304 } else {
9305 peg$currPos = s0;
9306 s0 = peg$FAILED;
9307 }
9308 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9309 return s0;
9310 }
9311 function peg$parseVERTICAL_BAR() {
9312 var s0, s1, s2;
9313 var key = peg$currPos * 306 + 208;
9314 var cached = peg$resultsCache[key];
9315 if (cached) {
9316 peg$currPos = cached.nextPos;
9317 return cached.result;
9318 }
9319 s0 = peg$currPos;
9320 if (input.charCodeAt(peg$currPos) === 124) {
9321 s1 = peg$c203;
9322 peg$currPos++;
9323 } else {
9324 s1 = peg$FAILED;
9325 if (peg$silentFails === 0) {
9326 peg$fail(peg$e204);
9327 }
9328 }
9329 if (s1 !== peg$FAILED) {
9330 s2 = peg$parse_();
9331 peg$savedPos = s0;
9332 s0 = peg$f7(s1, s2);
9333 } else {
9334 peg$currPos = s0;
9335 s0 = peg$FAILED;
9336 }
9337 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9338 return s0;
9339 }
9340 function peg$parseCARET() {
9341 var s0, s1, s2;
9342 var key = peg$currPos * 306 + 209;
9343 var cached = peg$resultsCache[key];
9344 if (cached) {
9345 peg$currPos = cached.nextPos;
9346 return cached.result;
9347 }
9348 s0 = peg$currPos;
9349 if (input.charCodeAt(peg$currPos) === 94) {
9350 s1 = peg$c204;
9351 peg$currPos++;
9352 } else {
9353 s1 = peg$FAILED;
9354 if (peg$silentFails === 0) {
9355 peg$fail(peg$e205);
9356 }
9357 }
9358 if (s1 !== peg$FAILED) {
9359 s2 = peg$parse_();
9360 peg$savedPos = s0;
9361 s0 = peg$f7(s1, s2);
9362 } else {
9363 peg$currPos = s0;
9364 s0 = peg$FAILED;
9365 }
9366 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9367 return s0;
9368 }
9369 function peg$parseAMPERSAND() {
9370 var s0, s1, s2;
9371 var key = peg$currPos * 306 + 210;
9372 var cached = peg$resultsCache[key];
9373 if (cached) {
9374 peg$currPos = cached.nextPos;
9375 return cached.result;
9376 }
9377 s0 = peg$currPos;
9378 if (input.charCodeAt(peg$currPos) === 38) {
9379 s1 = peg$c205;
9380 peg$currPos++;
9381 } else {
9382 s1 = peg$FAILED;
9383 if (peg$silentFails === 0) {
9384 peg$fail(peg$e206);
9385 }
9386 }
9387 if (s1 !== peg$FAILED) {
9388 s2 = peg$parse_();
9389 peg$savedPos = s0;
9390 s0 = peg$f7(s1, s2);
9391 } else {
9392 peg$currPos = s0;
9393 s0 = peg$FAILED;
9394 }
9395 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9396 return s0;
9397 }
9398 function peg$parseQUESTION() {
9399 var s0, s1, s2;
9400 var key = peg$currPos * 306 + 211;
9401 var cached = peg$resultsCache[key];
9402 if (cached) {
9403 peg$currPos = cached.nextPos;
9404 return cached.result;
9405 }
9406 s0 = peg$currPos;
9407 if (input.charCodeAt(peg$currPos) === 63) {
9408 s1 = peg$c206;
9409 peg$currPos++;
9410 } else {
9411 s1 = peg$FAILED;
9412 if (peg$silentFails === 0) {
9413 peg$fail(peg$e207);
9414 }
9415 }
9416 if (s1 !== peg$FAILED) {
9417 s2 = peg$parse_();
9418 peg$savedPos = s0;
9419 s0 = peg$f7(s1, s2);
9420 } else {
9421 peg$currPos = s0;
9422 s0 = peg$FAILED;
9423 }
9424 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9425 return s0;
9426 }
9427 function peg$parseIDENTIFIER() {
9428 var s0, s1, s2, s3, s4, s5, s6;
9429 var key = peg$currPos * 306 + 212;
9430 var cached = peg$resultsCache[key];
9431 if (cached) {
9432 peg$currPos = cached.nextPos;
9433 return cached.result;
9434 }
9435 s0 = peg$currPos;
9436 s1 = peg$currPos;
9437 peg$silentFails++;
9438 s2 = peg$parsekeyword();
9439 peg$silentFails--;
9440 if (s2 === peg$FAILED) {
9441 s1 = void 0;
9442 } else {
9443 peg$currPos = s1;
9444 s1 = peg$FAILED;
9445 }
9446 if (s1 !== peg$FAILED) {
9447 s2 = peg$currPos;
9448 s3 = peg$currPos;
9449 if (peg$r0.test(input.charAt(peg$currPos))) {
9450 s4 = input.charAt(peg$currPos);
9451 peg$currPos++;
9452 } else {
9453 s4 = peg$FAILED;
9454 if (peg$silentFails === 0) {
9455 peg$fail(peg$e208);
9456 }
9457 }
9458 if (s4 !== peg$FAILED) {
9459 s5 = [];
9460 if (peg$r1.test(input.charAt(peg$currPos))) {
9461 s6 = input.charAt(peg$currPos);
9462 peg$currPos++;
9463 } else {
9464 s6 = peg$FAILED;
9465 if (peg$silentFails === 0) {
9466 peg$fail(peg$e209);
9467 }
9468 }
9469 while (s6 !== peg$FAILED) {
9470 s5.push(s6);
9471 if (peg$r1.test(input.charAt(peg$currPos))) {
9472 s6 = input.charAt(peg$currPos);
9473 peg$currPos++;
9474 } else {
9475 s6 = peg$FAILED;
9476 if (peg$silentFails === 0) {
9477 peg$fail(peg$e209);
9478 }
9479 }
9480 }
9481 s4 = [s4, s5];
9482 s3 = s4;
9483 } else {
9484 peg$currPos = s3;
9485 s3 = peg$FAILED;
9486 }
9487 if (s3 !== peg$FAILED) {
9488 s2 = input.substring(s2, peg$currPos);
9489 } else {
9490 s2 = s3;
9491 }
9492 if (s2 !== peg$FAILED) {
9493 s3 = peg$parse_();
9494 peg$savedPos = s0;
9495 s0 = peg$f8(s2, s3);
9496 } else {
9497 peg$currPos = s0;
9498 s0 = peg$FAILED;
9499 }
9500 } else {
9501 peg$currPos = s0;
9502 s0 = peg$FAILED;
9503 }
9504 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9505 return s0;
9506 }
9507 function peg$parseTYPE_NAME() {
9508 var s0, s1, s2, s3, s4, s5, s6;
9509 var key = peg$currPos * 306 + 213;
9510 var cached = peg$resultsCache[key];
9511 if (cached) {
9512 peg$currPos = cached.nextPos;
9513 return cached.result;
9514 }
9515 s0 = peg$currPos;
9516 s1 = peg$currPos;
9517 peg$silentFails++;
9518 s2 = peg$parsekeyword();
9519 peg$silentFails--;
9520 if (s2 === peg$FAILED) {
9521 s1 = void 0;
9522 } else {
9523 peg$currPos = s1;
9524 s1 = peg$FAILED;
9525 }
9526 if (s1 !== peg$FAILED) {
9527 s2 = peg$currPos;
9528 s3 = peg$currPos;
9529 if (peg$r0.test(input.charAt(peg$currPos))) {
9530 s4 = input.charAt(peg$currPos);
9531 peg$currPos++;
9532 } else {
9533 s4 = peg$FAILED;
9534 if (peg$silentFails === 0) {
9535 peg$fail(peg$e208);
9536 }
9537 }
9538 if (s4 !== peg$FAILED) {
9539 s5 = [];
9540 if (peg$r1.test(input.charAt(peg$currPos))) {
9541 s6 = input.charAt(peg$currPos);
9542 peg$currPos++;
9543 } else {
9544 s6 = peg$FAILED;
9545 if (peg$silentFails === 0) {
9546 peg$fail(peg$e209);
9547 }
9548 }
9549 while (s6 !== peg$FAILED) {
9550 s5.push(s6);
9551 if (peg$r1.test(input.charAt(peg$currPos))) {
9552 s6 = input.charAt(peg$currPos);
9553 peg$currPos++;
9554 } else {
9555 s6 = peg$FAILED;
9556 if (peg$silentFails === 0) {
9557 peg$fail(peg$e209);
9558 }
9559 }
9560 }
9561 s4 = [s4, s5];
9562 s3 = s4;
9563 } else {
9564 peg$currPos = s3;
9565 s3 = peg$FAILED;
9566 }
9567 if (s3 !== peg$FAILED) {
9568 s2 = input.substring(s2, peg$currPos);
9569 } else {
9570 s2 = s3;
9571 }
9572 if (s2 !== peg$FAILED) {
9573 s3 = peg$parse_();
9574 peg$savedPos = s0;
9575 s0 = peg$f9(s2, s3);
9576 } else {
9577 peg$currPos = s0;
9578 s0 = peg$FAILED;
9579 }
9580 } else {
9581 peg$currPos = s0;
9582 s0 = peg$FAILED;
9583 }
9584 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9585 return s0;
9586 }
9587 function peg$parseinteger_constant() {
9588 var s0, s1, s2, s3;
9589 var key = peg$currPos * 306 + 214;
9590 var cached = peg$resultsCache[key];
9591 if (cached) {
9592 peg$currPos = cached.nextPos;
9593 return cached.result;
9594 }
9595 s0 = peg$currPos;
9596 s1 = peg$currPos;
9597 s2 = peg$parsehexadecimal_constant();
9598 if (s2 !== peg$FAILED) {
9599 s3 = peg$parseinteger_suffix();
9600 if (s3 === peg$FAILED) {
9601 s3 = null;
9602 }
9603 s2 = [s2, s3];
9604 s1 = s2;
9605 } else {
9606 peg$currPos = s1;
9607 s1 = peg$FAILED;
9608 }
9609 if (s1 !== peg$FAILED) {
9610 s0 = input.substring(s0, peg$currPos);
9611 } else {
9612 s0 = s1;
9613 }
9614 if (s0 === peg$FAILED) {
9615 s0 = peg$currPos;
9616 s1 = peg$currPos;
9617 s2 = peg$parsedecimal_constant();
9618 if (s2 !== peg$FAILED) {
9619 s3 = peg$parseinteger_suffix();
9620 if (s3 === peg$FAILED) {
9621 s3 = null;
9622 }
9623 s2 = [s2, s3];
9624 s1 = s2;
9625 } else {
9626 peg$currPos = s1;
9627 s1 = peg$FAILED;
9628 }
9629 if (s1 !== peg$FAILED) {
9630 s0 = input.substring(s0, peg$currPos);
9631 } else {
9632 s0 = s1;
9633 }
9634 if (s0 === peg$FAILED) {
9635 s0 = peg$currPos;
9636 s1 = peg$currPos;
9637 s2 = peg$parseoctal_constant();
9638 if (s2 !== peg$FAILED) {
9639 s3 = peg$parseinteger_suffix();
9640 if (s3 === peg$FAILED) {
9641 s3 = null;
9642 }
9643 s2 = [s2, s3];
9644 s1 = s2;
9645 } else {
9646 peg$currPos = s1;
9647 s1 = peg$FAILED;
9648 }
9649 if (s1 !== peg$FAILED) {
9650 s0 = input.substring(s0, peg$currPos);
9651 } else {
9652 s0 = s1;
9653 }
9654 }
9655 }
9656 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9657 return s0;
9658 }
9659 function peg$parseinteger_suffix() {
9660 var s0;
9661 var key = peg$currPos * 306 + 215;
9662 var cached = peg$resultsCache[key];
9663 if (cached) {
9664 peg$currPos = cached.nextPos;
9665 return cached.result;
9666 }
9667 if (peg$r2.test(input.charAt(peg$currPos))) {
9668 s0 = input.charAt(peg$currPos);
9669 peg$currPos++;
9670 } else {
9671 s0 = peg$FAILED;
9672 if (peg$silentFails === 0) {
9673 peg$fail(peg$e210);
9674 }
9675 }
9676 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9677 return s0;
9678 }
9679 function peg$parsedecimal_constant() {
9680 var s0, s1, s2, s3, s4;
9681 var key = peg$currPos * 306 + 216;
9682 var cached = peg$resultsCache[key];
9683 if (cached) {
9684 peg$currPos = cached.nextPos;
9685 return cached.result;
9686 }
9687 s0 = peg$currPos;
9688 s1 = peg$currPos;
9689 if (peg$r3.test(input.charAt(peg$currPos))) {
9690 s2 = input.charAt(peg$currPos);
9691 peg$currPos++;
9692 } else {
9693 s2 = peg$FAILED;
9694 if (peg$silentFails === 0) {
9695 peg$fail(peg$e211);
9696 }
9697 }
9698 if (s2 !== peg$FAILED) {
9699 s3 = [];
9700 s4 = peg$parsedigit();
9701 while (s4 !== peg$FAILED) {
9702 s3.push(s4);
9703 s4 = peg$parsedigit();
9704 }
9705 s2 = [s2, s3];
9706 s1 = s2;
9707 } else {
9708 peg$currPos = s1;
9709 s1 = peg$FAILED;
9710 }
9711 if (s1 !== peg$FAILED) {
9712 s0 = input.substring(s0, peg$currPos);
9713 } else {
9714 s0 = s1;
9715 }
9716 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9717 return s0;
9718 }
9719 function peg$parseoctal_constant() {
9720 var s0, s1, s2, s3;
9721 var key = peg$currPos * 306 + 217;
9722 var cached = peg$resultsCache[key];
9723 if (cached) {
9724 peg$currPos = cached.nextPos;
9725 return cached.result;
9726 }
9727 s0 = peg$currPos;
9728 if (input.charCodeAt(peg$currPos) === 48) {
9729 s1 = peg$c207;
9730 peg$currPos++;
9731 } else {
9732 s1 = peg$FAILED;
9733 if (peg$silentFails === 0) {
9734 peg$fail(peg$e212);
9735 }
9736 }
9737 if (s1 !== peg$FAILED) {
9738 s2 = [];
9739 if (peg$r4.test(input.charAt(peg$currPos))) {
9740 s3 = input.charAt(peg$currPos);
9741 peg$currPos++;
9742 } else {
9743 s3 = peg$FAILED;
9744 if (peg$silentFails === 0) {
9745 peg$fail(peg$e213);
9746 }
9747 }
9748 while (s3 !== peg$FAILED) {
9749 s2.push(s3);
9750 if (peg$r4.test(input.charAt(peg$currPos))) {
9751 s3 = input.charAt(peg$currPos);
9752 peg$currPos++;
9753 } else {
9754 s3 = peg$FAILED;
9755 if (peg$silentFails === 0) {
9756 peg$fail(peg$e213);
9757 }
9758 }
9759 }
9760 s1 = [s1, s2];
9761 s0 = s1;
9762 } else {
9763 peg$currPos = s0;
9764 s0 = peg$FAILED;
9765 }
9766 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9767 return s0;
9768 }
9769 function peg$parsehexadecimal_constant() {
9770 var s0, s1, s2, s3, s4;
9771 var key = peg$currPos * 306 + 218;
9772 var cached = peg$resultsCache[key];
9773 if (cached) {
9774 peg$currPos = cached.nextPos;
9775 return cached.result;
9776 }
9777 s0 = peg$currPos;
9778 if (input.charCodeAt(peg$currPos) === 48) {
9779 s1 = peg$c207;
9780 peg$currPos++;
9781 } else {
9782 s1 = peg$FAILED;
9783 if (peg$silentFails === 0) {
9784 peg$fail(peg$e212);
9785 }
9786 }
9787 if (s1 !== peg$FAILED) {
9788 if (peg$r5.test(input.charAt(peg$currPos))) {
9789 s2 = input.charAt(peg$currPos);
9790 peg$currPos++;
9791 } else {
9792 s2 = peg$FAILED;
9793 if (peg$silentFails === 0) {
9794 peg$fail(peg$e214);
9795 }
9796 }
9797 if (s2 !== peg$FAILED) {
9798 s3 = [];
9799 if (peg$r6.test(input.charAt(peg$currPos))) {
9800 s4 = input.charAt(peg$currPos);
9801 peg$currPos++;
9802 } else {
9803 s4 = peg$FAILED;
9804 if (peg$silentFails === 0) {
9805 peg$fail(peg$e215);
9806 }
9807 }
9808 while (s4 !== peg$FAILED) {
9809 s3.push(s4);
9810 if (peg$r6.test(input.charAt(peg$currPos))) {
9811 s4 = input.charAt(peg$currPos);
9812 peg$currPos++;
9813 } else {
9814 s4 = peg$FAILED;
9815 if (peg$silentFails === 0) {
9816 peg$fail(peg$e215);
9817 }
9818 }
9819 }
9820 s1 = [s1, s2, s3];
9821 s0 = s1;
9822 } else {
9823 peg$currPos = s0;
9824 s0 = peg$FAILED;
9825 }
9826 } else {
9827 peg$currPos = s0;
9828 s0 = peg$FAILED;
9829 }
9830 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9831 return s0;
9832 }
9833 function peg$parsedigit() {
9834 var s0;
9835 var key = peg$currPos * 306 + 219;
9836 var cached = peg$resultsCache[key];
9837 if (cached) {
9838 peg$currPos = cached.nextPos;
9839 return cached.result;
9840 }
9841 if (peg$r7.test(input.charAt(peg$currPos))) {
9842 s0 = input.charAt(peg$currPos);
9843 peg$currPos++;
9844 } else {
9845 s0 = peg$FAILED;
9846 if (peg$silentFails === 0) {
9847 peg$fail(peg$e216);
9848 }
9849 }
9850 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9851 return s0;
9852 }
9853 function peg$parsefloating_constant() {
9854 var s0, s1, s2, s3, s4;
9855 var key = peg$currPos * 306 + 220;
9856 var cached = peg$resultsCache[key];
9857 if (cached) {
9858 peg$currPos = cached.nextPos;
9859 return cached.result;
9860 }
9861 s0 = peg$currPos;
9862 s1 = peg$currPos;
9863 s2 = peg$parsefractional_constant();
9864 if (s2 !== peg$FAILED) {
9865 s3 = peg$parseexponent_part();
9866 if (s3 === peg$FAILED) {
9867 s3 = null;
9868 }
9869 s4 = peg$parsefloating_suffix();
9870 if (s4 === peg$FAILED) {
9871 s4 = null;
9872 }
9873 s2 = [s2, s3, s4];
9874 s1 = s2;
9875 } else {
9876 peg$currPos = s1;
9877 s1 = peg$FAILED;
9878 }
9879 if (s1 !== peg$FAILED) {
9880 s0 = input.substring(s0, peg$currPos);
9881 } else {
9882 s0 = s1;
9883 }
9884 if (s0 === peg$FAILED) {
9885 s0 = peg$currPos;
9886 s1 = peg$currPos;
9887 s2 = peg$parsedigit_sequence();
9888 if (s2 !== peg$FAILED) {
9889 s3 = peg$parseexponent_part();
9890 if (s3 !== peg$FAILED) {
9891 s4 = peg$parsefloating_suffix();
9892 if (s4 === peg$FAILED) {
9893 s4 = null;
9894 }
9895 s2 = [s2, s3, s4];
9896 s1 = s2;
9897 } else {
9898 peg$currPos = s1;
9899 s1 = peg$FAILED;
9900 }
9901 } else {
9902 peg$currPos = s1;
9903 s1 = peg$FAILED;
9904 }
9905 if (s1 !== peg$FAILED) {
9906 s0 = input.substring(s0, peg$currPos);
9907 } else {
9908 s0 = s1;
9909 }
9910 }
9911 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9912 return s0;
9913 }
9914 function peg$parsefractional_constant() {
9915 var s0, s1, s2, s3, s4;
9916 var key = peg$currPos * 306 + 221;
9917 var cached = peg$resultsCache[key];
9918 if (cached) {
9919 peg$currPos = cached.nextPos;
9920 return cached.result;
9921 }
9922 s0 = peg$currPos;
9923 s1 = peg$currPos;
9924 s2 = peg$parsedigit_sequence();
9925 if (s2 === peg$FAILED) {
9926 s2 = null;
9927 }
9928 if (input.charCodeAt(peg$currPos) === 46) {
9929 s3 = peg$c189;
9930 peg$currPos++;
9931 } else {
9932 s3 = peg$FAILED;
9933 if (peg$silentFails === 0) {
9934 peg$fail(peg$e190);
9935 }
9936 }
9937 if (s3 !== peg$FAILED) {
9938 s4 = peg$parsedigit_sequence();
9939 if (s4 === peg$FAILED) {
9940 s4 = null;
9941 }
9942 s2 = [s2, s3, s4];
9943 s1 = s2;
9944 } else {
9945 peg$currPos = s1;
9946 s1 = peg$FAILED;
9947 }
9948 if (s1 !== peg$FAILED) {
9949 s0 = input.substring(s0, peg$currPos);
9950 } else {
9951 s0 = s1;
9952 }
9953 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
9954 return s0;
9955 }
9956 function peg$parseexponent_part() {
9957 var s0, s1, s2, s3, s4;
9958 var key = peg$currPos * 306 + 222;
9959 var cached = peg$resultsCache[key];
9960 if (cached) {
9961 peg$currPos = cached.nextPos;
9962 return cached.result;
9963 }
9964 peg$silentFails++;
9965 s0 = peg$currPos;
9966 s1 = peg$currPos;
9967 if (peg$r8.test(input.charAt(peg$currPos))) {
9968 s2 = input.charAt(peg$currPos);
9969 peg$currPos++;
9970 } else {
9971 s2 = peg$FAILED;
9972 if (peg$silentFails === 0) {
9973 peg$fail(peg$e218);
9974 }
9975 }
9976 if (s2 !== peg$FAILED) {
9977 if (peg$r9.test(input.charAt(peg$currPos))) {
9978 s3 = input.charAt(peg$currPos);
9979 peg$currPos++;
9980 } else {
9981 s3 = peg$FAILED;
9982 if (peg$silentFails === 0) {
9983 peg$fail(peg$e219);
9984 }
9985 }
9986 if (s3 === peg$FAILED) {
9987 s3 = null;
9988 }
9989 s4 = peg$parsedigit_sequence();
9990 if (s4 !== peg$FAILED) {
9991 s2 = [s2, s3, s4];
9992 s1 = s2;
9993 } else {
9994 peg$currPos = s1;
9995 s1 = peg$FAILED;
9996 }
9997 } else {
9998 peg$currPos = s1;
9999 s1 = peg$FAILED;
10000 }
10001 if (s1 !== peg$FAILED) {
10002 s0 = input.substring(s0, peg$currPos);
10003 } else {
10004 s0 = s1;
10005 }
10006 peg$silentFails--;
10007 if (s0 === peg$FAILED) {
10008 s1 = peg$FAILED;
10009 if (peg$silentFails === 0) {
10010 peg$fail(peg$e217);
10011 }
10012 }
10013 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10014 return s0;
10015 }
10016 function peg$parsedigit_sequence() {
10017 var s0, s1, s2;
10018 var key = peg$currPos * 306 + 223;
10019 var cached = peg$resultsCache[key];
10020 if (cached) {
10021 peg$currPos = cached.nextPos;
10022 return cached.result;
10023 }
10024 s0 = peg$currPos;
10025 s1 = [];
10026 s2 = peg$parsedigit();
10027 if (s2 !== peg$FAILED) {
10028 while (s2 !== peg$FAILED) {
10029 s1.push(s2);
10030 s2 = peg$parsedigit();
10031 }
10032 } else {
10033 s1 = peg$FAILED;
10034 }
10035 if (s1 !== peg$FAILED) {
10036 s0 = input.substring(s0, peg$currPos);
10037 } else {
10038 s0 = s1;
10039 }
10040 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10041 return s0;
10042 }
10043 function peg$parsefloating_suffix() {
10044 var s0;
10045 var key = peg$currPos * 306 + 224;
10046 var cached = peg$resultsCache[key];
10047 if (cached) {
10048 peg$currPos = cached.nextPos;
10049 return cached.result;
10050 }
10051 if (peg$r10.test(input.charAt(peg$currPos))) {
10052 s0 = input.charAt(peg$currPos);
10053 peg$currPos++;
10054 } else {
10055 s0 = peg$FAILED;
10056 if (peg$silentFails === 0) {
10057 peg$fail(peg$e220);
10058 }
10059 }
10060 if (s0 === peg$FAILED) {
10061 if (input.substr(peg$currPos, 2) === peg$c208) {
10062 s0 = peg$c208;
10063 peg$currPos += 2;
10064 } else {
10065 s0 = peg$FAILED;
10066 if (peg$silentFails === 0) {
10067 peg$fail(peg$e221);
10068 }
10069 }
10070 if (s0 === peg$FAILED) {
10071 if (input.substr(peg$currPos, 2) === peg$c209) {
10072 s0 = peg$c209;
10073 peg$currPos += 2;
10074 } else {
10075 s0 = peg$FAILED;
10076 if (peg$silentFails === 0) {
10077 peg$fail(peg$e222);
10078 }
10079 }
10080 }
10081 }
10082 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10083 return s0;
10084 }
10085 function peg$parseprimary_expression() {
10086 var s0, s1, s2, s3;
10087 var key = peg$currPos * 306 + 225;
10088 var cached = peg$resultsCache[key];
10089 if (cached) {
10090 peg$currPos = cached.nextPos;
10091 return cached.result;
10092 }
10093 peg$silentFails++;
10094 s0 = peg$parseFLOATCONSTANT();
10095 if (s0 === peg$FAILED) {
10096 s0 = peg$parseINTCONSTANT();
10097 if (s0 === peg$FAILED) {
10098 s0 = peg$parseUINTCONSTANT();
10099 if (s0 === peg$FAILED) {
10100 s0 = peg$parseBOOLCONSTANT();
10101 if (s0 === peg$FAILED) {
10102 s0 = peg$parseDOUBLECONSTANT();
10103 if (s0 === peg$FAILED) {
10104 s0 = peg$currPos;
10105 s1 = peg$parseLEFT_PAREN();
10106 if (s1 !== peg$FAILED) {
10107 s2 = peg$parseexpression();
10108 if (s2 !== peg$FAILED) {
10109 s3 = peg$parseRIGHT_PAREN();
10110 if (s3 !== peg$FAILED) {
10111 peg$savedPos = s0;
10112 s0 = peg$f10(s1, s2, s3);
10113 } else {
10114 peg$currPos = s0;
10115 s0 = peg$FAILED;
10116 }
10117 } else {
10118 peg$currPos = s0;
10119 s0 = peg$FAILED;
10120 }
10121 } else {
10122 peg$currPos = s0;
10123 s0 = peg$FAILED;
10124 }
10125 if (s0 === peg$FAILED) {
10126 s0 = peg$currPos;
10127 s1 = peg$parseIDENTIFIER();
10128 if (s1 !== peg$FAILED) {
10129 peg$savedPos = s0;
10130 s1 = peg$f11(s1);
10131 }
10132 s0 = s1;
10133 }
10134 }
10135 }
10136 }
10137 }
10138 }
10139 peg$silentFails--;
10140 if (s0 === peg$FAILED) {
10141 s1 = peg$FAILED;
10142 if (peg$silentFails === 0) {
10143 peg$fail(peg$e223);
10144 }
10145 }
10146 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10147 return s0;
10148 }
10149 function peg$parsepostfix_expression() {
10150 var s0, s1, s2, s3, s4;
10151 var key = peg$currPos * 306 + 226;
10152 var cached = peg$resultsCache[key];
10153 if (cached) {
10154 peg$currPos = cached.nextPos;
10155 return cached.result;
10156 }
10157 s0 = peg$currPos;
10158 s1 = peg$currPos;
10159 s2 = peg$parsefunction_call();
10160 if (s2 !== peg$FAILED) {
10161 s3 = [];
10162 s4 = peg$parsepostfix_expression_suffix();
10163 while (s4 !== peg$FAILED) {
10164 s3.push(s4);
10165 s4 = peg$parsepostfix_expression_suffix();
10166 }
10167 s2 = [s2, s3];
10168 s1 = s2;
10169 } else {
10170 peg$currPos = s1;
10171 s1 = peg$FAILED;
10172 }
10173 if (s1 === peg$FAILED) {
10174 s1 = peg$currPos;
10175 s2 = peg$parseprimary_expression();
10176 if (s2 !== peg$FAILED) {
10177 s3 = [];
10178 s4 = peg$parsepostfix_expression_suffix();
10179 while (s4 !== peg$FAILED) {
10180 s3.push(s4);
10181 s4 = peg$parsepostfix_expression_suffix();
10182 }
10183 s2 = [s2, s3];
10184 s1 = s2;
10185 } else {
10186 peg$currPos = s1;
10187 s1 = peg$FAILED;
10188 }
10189 }
10190 if (s1 !== peg$FAILED) {
10191 peg$savedPos = s0;
10192 s1 = peg$f12(s1);
10193 }
10194 s0 = s1;
10195 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10196 return s0;
10197 }
10198 function peg$parsepostfix_expression_suffix() {
10199 var s0;
10200 var key = peg$currPos * 306 + 227;
10201 var cached = peg$resultsCache[key];
10202 if (cached) {
10203 peg$currPos = cached.nextPos;
10204 return cached.result;
10205 }
10206 s0 = peg$parseinteger_index();
10207 if (s0 === peg$FAILED) {
10208 s0 = peg$parsefield_selection();
10209 if (s0 === peg$FAILED) {
10210 s0 = peg$parseINC_OP();
10211 if (s0 === peg$FAILED) {
10212 s0 = peg$parseDEC_OP();
10213 }
10214 }
10215 }
10216 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10217 return s0;
10218 }
10219 function peg$parseinteger_index() {
10220 var s0, s1, s2, s3;
10221 var key = peg$currPos * 306 + 228;
10222 var cached = peg$resultsCache[key];
10223 if (cached) {
10224 peg$currPos = cached.nextPos;
10225 return cached.result;
10226 }
10227 s0 = peg$currPos;
10228 s1 = peg$parseLEFT_BRACKET();
10229 if (s1 !== peg$FAILED) {
10230 s2 = peg$parseexpression();
10231 if (s2 !== peg$FAILED) {
10232 s3 = peg$parseRIGHT_BRACKET();
10233 if (s3 !== peg$FAILED) {
10234 peg$savedPos = s0;
10235 s0 = peg$f13(s1, s2, s3);
10236 } else {
10237 peg$currPos = s0;
10238 s0 = peg$FAILED;
10239 }
10240 } else {
10241 peg$currPos = s0;
10242 s0 = peg$FAILED;
10243 }
10244 } else {
10245 peg$currPos = s0;
10246 s0 = peg$FAILED;
10247 }
10248 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10249 return s0;
10250 }
10251 function peg$parsefield_selection() {
10252 var s0, s1, s2;
10253 var key = peg$currPos * 306 + 229;
10254 var cached = peg$resultsCache[key];
10255 if (cached) {
10256 peg$currPos = cached.nextPos;
10257 return cached.result;
10258 }
10259 s0 = peg$currPos;
10260 s1 = peg$parseDOT();
10261 if (s1 !== peg$FAILED) {
10262 s2 = peg$parseIDENTIFIER();
10263 if (s2 !== peg$FAILED) {
10264 peg$savedPos = s0;
10265 s0 = peg$f14(s1, s2);
10266 } else {
10267 peg$currPos = s0;
10268 s0 = peg$FAILED;
10269 }
10270 } else {
10271 peg$currPos = s0;
10272 s0 = peg$FAILED;
10273 }
10274 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10275 return s0;
10276 }
10277 function peg$parsefunction_call() {
10278 var s0, s1, s2, s3;
10279 var key = peg$currPos * 306 + 230;
10280 var cached = peg$resultsCache[key];
10281 if (cached) {
10282 peg$currPos = cached.nextPos;
10283 return cached.result;
10284 }
10285 s0 = peg$currPos;
10286 s1 = peg$parsefunction_identifier();
10287 if (s1 !== peg$FAILED) {
10288 s2 = peg$parsefunction_arguments();
10289 if (s2 === peg$FAILED) {
10290 s2 = null;
10291 }
10292 s3 = peg$parseRIGHT_PAREN();
10293 if (s3 !== peg$FAILED) {
10294 peg$savedPos = s0;
10295 s0 = peg$f15(s1, s2, s3);
10296 } else {
10297 peg$currPos = s0;
10298 s0 = peg$FAILED;
10299 }
10300 } else {
10301 peg$currPos = s0;
10302 s0 = peg$FAILED;
10303 }
10304 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10305 return s0;
10306 }
10307 function peg$parsefunction_arguments() {
10308 var s0, s1, s2, s3, s4, s5;
10309 var key = peg$currPos * 306 + 231;
10310 var cached = peg$resultsCache[key];
10311 if (cached) {
10312 peg$currPos = cached.nextPos;
10313 return cached.result;
10314 }
10315 s0 = peg$currPos;
10316 s1 = peg$parseVOID();
10317 if (s1 !== peg$FAILED) {
10318 peg$savedPos = s0;
10319 s1 = peg$f16(s1);
10320 }
10321 s0 = s1;
10322 if (s0 === peg$FAILED) {
10323 s0 = peg$currPos;
10324 s1 = peg$parseassignment_expression();
10325 if (s1 !== peg$FAILED) {
10326 s2 = [];
10327 s3 = peg$currPos;
10328 s4 = peg$parseCOMMA();
10329 if (s4 !== peg$FAILED) {
10330 s5 = peg$parseassignment_expression();
10331 if (s5 !== peg$FAILED) {
10332 s4 = [s4, s5];
10333 s3 = s4;
10334 } else {
10335 peg$currPos = s3;
10336 s3 = peg$FAILED;
10337 }
10338 } else {
10339 peg$currPos = s3;
10340 s3 = peg$FAILED;
10341 }
10342 while (s3 !== peg$FAILED) {
10343 s2.push(s3);
10344 s3 = peg$currPos;
10345 s4 = peg$parseCOMMA();
10346 if (s4 !== peg$FAILED) {
10347 s5 = peg$parseassignment_expression();
10348 if (s5 !== peg$FAILED) {
10349 s4 = [s4, s5];
10350 s3 = s4;
10351 } else {
10352 peg$currPos = s3;
10353 s3 = peg$FAILED;
10354 }
10355 } else {
10356 peg$currPos = s3;
10357 s3 = peg$FAILED;
10358 }
10359 }
10360 peg$savedPos = s0;
10361 s0 = peg$f17(s1, s2);
10362 } else {
10363 peg$currPos = s0;
10364 s0 = peg$FAILED;
10365 }
10366 }
10367 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10368 return s0;
10369 }
10370 function peg$parsefunction_identifier() {
10371 var s0, s1, s2, s3, s4;
10372 var key = peg$currPos * 306 + 232;
10373 var cached = peg$resultsCache[key];
10374 if (cached) {
10375 peg$currPos = cached.nextPos;
10376 return cached.result;
10377 }
10378 s0 = peg$currPos;
10379 s1 = peg$currPos;
10380 s2 = peg$parsechained_function_call();
10381 if (s2 !== peg$FAILED) {
10382 s3 = peg$parsefunction_suffix();
10383 if (s3 !== peg$FAILED) {
10384 s4 = peg$parseLEFT_PAREN();
10385 if (s4 !== peg$FAILED) {
10386 peg$savedPos = s1;
10387 s1 = peg$f18(s2, s3, s4);
10388 } else {
10389 peg$currPos = s1;
10390 s1 = peg$FAILED;
10391 }
10392 } else {
10393 peg$currPos = s1;
10394 s1 = peg$FAILED;
10395 }
10396 } else {
10397 peg$currPos = s1;
10398 s1 = peg$FAILED;
10399 }
10400 if (s1 === peg$FAILED) {
10401 s1 = peg$currPos;
10402 s2 = peg$parsetype_specifier();
10403 if (s2 !== peg$FAILED) {
10404 s3 = peg$parsefunction_suffix();
10405 if (s3 === peg$FAILED) {
10406 s3 = null;
10407 }
10408 s4 = peg$parseLEFT_PAREN();
10409 if (s4 !== peg$FAILED) {
10410 peg$savedPos = s1;
10411 s1 = peg$f18(s2, s3, s4);
10412 } else {
10413 peg$currPos = s1;
10414 s1 = peg$FAILED;
10415 }
10416 } else {
10417 peg$currPos = s1;
10418 s1 = peg$FAILED;
10419 }
10420 }
10421 if (s1 !== peg$FAILED) {
10422 peg$savedPos = s0;
10423 s1 = peg$f19(s1);
10424 }
10425 s0 = s1;
10426 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10427 return s0;
10428 }
10429 function peg$parsefunction_suffix() {
10430 var s0;
10431 var key = peg$currPos * 306 + 233;
10432 var cached = peg$resultsCache[key];
10433 if (cached) {
10434 peg$currPos = cached.nextPos;
10435 return cached.result;
10436 }
10437 s0 = peg$parseinteger_index();
10438 if (s0 === peg$FAILED) {
10439 s0 = peg$parsefield_selection();
10440 }
10441 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10442 return s0;
10443 }
10444 function peg$parsechained_function_call() {
10445 var s0, s1, s2, s3, s4;
10446 var key = peg$currPos * 306 + 234;
10447 var cached = peg$resultsCache[key];
10448 if (cached) {
10449 peg$currPos = cached.nextPos;
10450 return cached.result;
10451 }
10452 s0 = peg$currPos;
10453 s1 = peg$parsetype_specifier();
10454 if (s1 !== peg$FAILED) {
10455 s2 = peg$parseLEFT_PAREN();
10456 if (s2 !== peg$FAILED) {
10457 s3 = peg$parsefunction_arguments();
10458 if (s3 === peg$FAILED) {
10459 s3 = null;
10460 }
10461 s4 = peg$parseRIGHT_PAREN();
10462 if (s4 !== peg$FAILED) {
10463 peg$savedPos = s0;
10464 s0 = peg$f20(s1, s2, s3, s4);
10465 } else {
10466 peg$currPos = s0;
10467 s0 = peg$FAILED;
10468 }
10469 } else {
10470 peg$currPos = s0;
10471 s0 = peg$FAILED;
10472 }
10473 } else {
10474 peg$currPos = s0;
10475 s0 = peg$FAILED;
10476 }
10477 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10478 return s0;
10479 }
10480 function peg$parseunary_expression() {
10481 var s0, s1, s2;
10482 var key = peg$currPos * 306 + 235;
10483 var cached = peg$resultsCache[key];
10484 if (cached) {
10485 peg$currPos = cached.nextPos;
10486 return cached.result;
10487 }
10488 peg$silentFails++;
10489 s0 = peg$parsepostfix_expression();
10490 if (s0 === peg$FAILED) {
10491 s0 = peg$currPos;
10492 s1 = peg$parseINC_OP();
10493 if (s1 === peg$FAILED) {
10494 s1 = peg$parseDEC_OP();
10495 if (s1 === peg$FAILED) {
10496 s1 = peg$parsePLUS();
10497 if (s1 === peg$FAILED) {
10498 s1 = peg$parseDASH();
10499 if (s1 === peg$FAILED) {
10500 s1 = peg$parseBANG();
10501 if (s1 === peg$FAILED) {
10502 s1 = peg$parseTILDE();
10503 }
10504 }
10505 }
10506 }
10507 }
10508 if (s1 !== peg$FAILED) {
10509 s2 = peg$parseunary_expression();
10510 if (s2 !== peg$FAILED) {
10511 peg$savedPos = s0;
10512 s0 = peg$f21(s1, s2);
10513 } else {
10514 peg$currPos = s0;
10515 s0 = peg$FAILED;
10516 }
10517 } else {
10518 peg$currPos = s0;
10519 s0 = peg$FAILED;
10520 }
10521 }
10522 peg$silentFails--;
10523 if (s0 === peg$FAILED) {
10524 s1 = peg$FAILED;
10525 if (peg$silentFails === 0) {
10526 peg$fail(peg$e224);
10527 }
10528 }
10529 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10530 return s0;
10531 }
10532 function peg$parsemultiplicative_expression() {
10533 var s0, s1, s2, s3, s4, s5;
10534 var key = peg$currPos * 306 + 236;
10535 var cached = peg$resultsCache[key];
10536 if (cached) {
10537 peg$currPos = cached.nextPos;
10538 return cached.result;
10539 }
10540 s0 = peg$currPos;
10541 s1 = peg$parseunary_expression();
10542 if (s1 !== peg$FAILED) {
10543 s2 = [];
10544 s3 = peg$currPos;
10545 s4 = peg$parseSTAR();
10546 if (s4 === peg$FAILED) {
10547 s4 = peg$parseSLASH();
10548 if (s4 === peg$FAILED) {
10549 s4 = peg$parsePERCENT();
10550 }
10551 }
10552 if (s4 !== peg$FAILED) {
10553 s5 = peg$parseunary_expression();
10554 if (s5 !== peg$FAILED) {
10555 s4 = [s4, s5];
10556 s3 = s4;
10557 } else {
10558 peg$currPos = s3;
10559 s3 = peg$FAILED;
10560 }
10561 } else {
10562 peg$currPos = s3;
10563 s3 = peg$FAILED;
10564 }
10565 while (s3 !== peg$FAILED) {
10566 s2.push(s3);
10567 s3 = peg$currPos;
10568 s4 = peg$parseSTAR();
10569 if (s4 === peg$FAILED) {
10570 s4 = peg$parseSLASH();
10571 if (s4 === peg$FAILED) {
10572 s4 = peg$parsePERCENT();
10573 }
10574 }
10575 if (s4 !== peg$FAILED) {
10576 s5 = peg$parseunary_expression();
10577 if (s5 !== peg$FAILED) {
10578 s4 = [s4, s5];
10579 s3 = s4;
10580 } else {
10581 peg$currPos = s3;
10582 s3 = peg$FAILED;
10583 }
10584 } else {
10585 peg$currPos = s3;
10586 s3 = peg$FAILED;
10587 }
10588 }
10589 peg$savedPos = s0;
10590 s0 = peg$f22(s1, s2);
10591 } else {
10592 peg$currPos = s0;
10593 s0 = peg$FAILED;
10594 }
10595 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10596 return s0;
10597 }
10598 function peg$parseadditive_expression() {
10599 var s0, s1, s2, s3, s4, s5;
10600 var key = peg$currPos * 306 + 237;
10601 var cached = peg$resultsCache[key];
10602 if (cached) {
10603 peg$currPos = cached.nextPos;
10604 return cached.result;
10605 }
10606 s0 = peg$currPos;
10607 s1 = peg$parsemultiplicative_expression();
10608 if (s1 !== peg$FAILED) {
10609 s2 = [];
10610 s3 = peg$currPos;
10611 s4 = peg$parsePLUS();
10612 if (s4 === peg$FAILED) {
10613 s4 = peg$parseDASH();
10614 }
10615 if (s4 !== peg$FAILED) {
10616 s5 = peg$parsemultiplicative_expression();
10617 if (s5 !== peg$FAILED) {
10618 s4 = [s4, s5];
10619 s3 = s4;
10620 } else {
10621 peg$currPos = s3;
10622 s3 = peg$FAILED;
10623 }
10624 } else {
10625 peg$currPos = s3;
10626 s3 = peg$FAILED;
10627 }
10628 while (s3 !== peg$FAILED) {
10629 s2.push(s3);
10630 s3 = peg$currPos;
10631 s4 = peg$parsePLUS();
10632 if (s4 === peg$FAILED) {
10633 s4 = peg$parseDASH();
10634 }
10635 if (s4 !== peg$FAILED) {
10636 s5 = peg$parsemultiplicative_expression();
10637 if (s5 !== peg$FAILED) {
10638 s4 = [s4, s5];
10639 s3 = s4;
10640 } else {
10641 peg$currPos = s3;
10642 s3 = peg$FAILED;
10643 }
10644 } else {
10645 peg$currPos = s3;
10646 s3 = peg$FAILED;
10647 }
10648 }
10649 peg$savedPos = s0;
10650 s0 = peg$f22(s1, s2);
10651 } else {
10652 peg$currPos = s0;
10653 s0 = peg$FAILED;
10654 }
10655 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10656 return s0;
10657 }
10658 function peg$parseshift_expression() {
10659 var s0, s1, s2, s3, s4, s5;
10660 var key = peg$currPos * 306 + 238;
10661 var cached = peg$resultsCache[key];
10662 if (cached) {
10663 peg$currPos = cached.nextPos;
10664 return cached.result;
10665 }
10666 s0 = peg$currPos;
10667 s1 = peg$parseadditive_expression();
10668 if (s1 !== peg$FAILED) {
10669 s2 = [];
10670 s3 = peg$currPos;
10671 s4 = peg$parseRIGHT_OP();
10672 if (s4 === peg$FAILED) {
10673 s4 = peg$parseLEFT_OP();
10674 }
10675 if (s4 !== peg$FAILED) {
10676 s5 = peg$parseadditive_expression();
10677 if (s5 !== peg$FAILED) {
10678 s4 = [s4, s5];
10679 s3 = s4;
10680 } else {
10681 peg$currPos = s3;
10682 s3 = peg$FAILED;
10683 }
10684 } else {
10685 peg$currPos = s3;
10686 s3 = peg$FAILED;
10687 }
10688 while (s3 !== peg$FAILED) {
10689 s2.push(s3);
10690 s3 = peg$currPos;
10691 s4 = peg$parseRIGHT_OP();
10692 if (s4 === peg$FAILED) {
10693 s4 = peg$parseLEFT_OP();
10694 }
10695 if (s4 !== peg$FAILED) {
10696 s5 = peg$parseadditive_expression();
10697 if (s5 !== peg$FAILED) {
10698 s4 = [s4, s5];
10699 s3 = s4;
10700 } else {
10701 peg$currPos = s3;
10702 s3 = peg$FAILED;
10703 }
10704 } else {
10705 peg$currPos = s3;
10706 s3 = peg$FAILED;
10707 }
10708 }
10709 peg$savedPos = s0;
10710 s0 = peg$f22(s1, s2);
10711 } else {
10712 peg$currPos = s0;
10713 s0 = peg$FAILED;
10714 }
10715 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10716 return s0;
10717 }
10718 function peg$parserelational_expression() {
10719 var s0, s1, s2, s3, s4, s5;
10720 var key = peg$currPos * 306 + 239;
10721 var cached = peg$resultsCache[key];
10722 if (cached) {
10723 peg$currPos = cached.nextPos;
10724 return cached.result;
10725 }
10726 s0 = peg$currPos;
10727 s1 = peg$parseshift_expression();
10728 if (s1 !== peg$FAILED) {
10729 s2 = [];
10730 s3 = peg$currPos;
10731 s4 = peg$parseLE_OP();
10732 if (s4 === peg$FAILED) {
10733 s4 = peg$parseGE_OP();
10734 if (s4 === peg$FAILED) {
10735 s4 = peg$parseLEFT_ANGLE();
10736 if (s4 === peg$FAILED) {
10737 s4 = peg$parseRIGHT_ANGLE();
10738 }
10739 }
10740 }
10741 if (s4 !== peg$FAILED) {
10742 s5 = peg$parseshift_expression();
10743 if (s5 !== peg$FAILED) {
10744 s4 = [s4, s5];
10745 s3 = s4;
10746 } else {
10747 peg$currPos = s3;
10748 s3 = peg$FAILED;
10749 }
10750 } else {
10751 peg$currPos = s3;
10752 s3 = peg$FAILED;
10753 }
10754 while (s3 !== peg$FAILED) {
10755 s2.push(s3);
10756 s3 = peg$currPos;
10757 s4 = peg$parseLE_OP();
10758 if (s4 === peg$FAILED) {
10759 s4 = peg$parseGE_OP();
10760 if (s4 === peg$FAILED) {
10761 s4 = peg$parseLEFT_ANGLE();
10762 if (s4 === peg$FAILED) {
10763 s4 = peg$parseRIGHT_ANGLE();
10764 }
10765 }
10766 }
10767 if (s4 !== peg$FAILED) {
10768 s5 = peg$parseshift_expression();
10769 if (s5 !== peg$FAILED) {
10770 s4 = [s4, s5];
10771 s3 = s4;
10772 } else {
10773 peg$currPos = s3;
10774 s3 = peg$FAILED;
10775 }
10776 } else {
10777 peg$currPos = s3;
10778 s3 = peg$FAILED;
10779 }
10780 }
10781 peg$savedPos = s0;
10782 s0 = peg$f22(s1, s2);
10783 } else {
10784 peg$currPos = s0;
10785 s0 = peg$FAILED;
10786 }
10787 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10788 return s0;
10789 }
10790 function peg$parseequality_expression() {
10791 var s0, s1, s2, s3, s4, s5;
10792 var key = peg$currPos * 306 + 240;
10793 var cached = peg$resultsCache[key];
10794 if (cached) {
10795 peg$currPos = cached.nextPos;
10796 return cached.result;
10797 }
10798 peg$silentFails++;
10799 s0 = peg$currPos;
10800 s1 = peg$parserelational_expression();
10801 if (s1 !== peg$FAILED) {
10802 s2 = [];
10803 s3 = peg$currPos;
10804 s4 = peg$parseEQ_OP();
10805 if (s4 === peg$FAILED) {
10806 s4 = peg$parseNE_OP();
10807 }
10808 if (s4 !== peg$FAILED) {
10809 s5 = peg$parserelational_expression();
10810 if (s5 !== peg$FAILED) {
10811 s4 = [s4, s5];
10812 s3 = s4;
10813 } else {
10814 peg$currPos = s3;
10815 s3 = peg$FAILED;
10816 }
10817 } else {
10818 peg$currPos = s3;
10819 s3 = peg$FAILED;
10820 }
10821 while (s3 !== peg$FAILED) {
10822 s2.push(s3);
10823 s3 = peg$currPos;
10824 s4 = peg$parseEQ_OP();
10825 if (s4 === peg$FAILED) {
10826 s4 = peg$parseNE_OP();
10827 }
10828 if (s4 !== peg$FAILED) {
10829 s5 = peg$parserelational_expression();
10830 if (s5 !== peg$FAILED) {
10831 s4 = [s4, s5];
10832 s3 = s4;
10833 } else {
10834 peg$currPos = s3;
10835 s3 = peg$FAILED;
10836 }
10837 } else {
10838 peg$currPos = s3;
10839 s3 = peg$FAILED;
10840 }
10841 }
10842 peg$savedPos = s0;
10843 s0 = peg$f22(s1, s2);
10844 } else {
10845 peg$currPos = s0;
10846 s0 = peg$FAILED;
10847 }
10848 peg$silentFails--;
10849 if (s0 === peg$FAILED) {
10850 s1 = peg$FAILED;
10851 if (peg$silentFails === 0) {
10852 peg$fail(peg$e225);
10853 }
10854 }
10855 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10856 return s0;
10857 }
10858 function peg$parseand_expression() {
10859 var s0, s1, s2, s3, s4, s5;
10860 var key = peg$currPos * 306 + 241;
10861 var cached = peg$resultsCache[key];
10862 if (cached) {
10863 peg$currPos = cached.nextPos;
10864 return cached.result;
10865 }
10866 peg$silentFails++;
10867 s0 = peg$currPos;
10868 s1 = peg$parseequality_expression();
10869 if (s1 !== peg$FAILED) {
10870 s2 = [];
10871 s3 = peg$currPos;
10872 s4 = peg$parseAMPERSAND();
10873 if (s4 !== peg$FAILED) {
10874 s5 = peg$parseequality_expression();
10875 if (s5 !== peg$FAILED) {
10876 s4 = [s4, s5];
10877 s3 = s4;
10878 } else {
10879 peg$currPos = s3;
10880 s3 = peg$FAILED;
10881 }
10882 } else {
10883 peg$currPos = s3;
10884 s3 = peg$FAILED;
10885 }
10886 while (s3 !== peg$FAILED) {
10887 s2.push(s3);
10888 s3 = peg$currPos;
10889 s4 = peg$parseAMPERSAND();
10890 if (s4 !== peg$FAILED) {
10891 s5 = peg$parseequality_expression();
10892 if (s5 !== peg$FAILED) {
10893 s4 = [s4, s5];
10894 s3 = s4;
10895 } else {
10896 peg$currPos = s3;
10897 s3 = peg$FAILED;
10898 }
10899 } else {
10900 peg$currPos = s3;
10901 s3 = peg$FAILED;
10902 }
10903 }
10904 peg$savedPos = s0;
10905 s0 = peg$f22(s1, s2);
10906 } else {
10907 peg$currPos = s0;
10908 s0 = peg$FAILED;
10909 }
10910 peg$silentFails--;
10911 if (s0 === peg$FAILED) {
10912 s1 = peg$FAILED;
10913 if (peg$silentFails === 0) {
10914 peg$fail(peg$e226);
10915 }
10916 }
10917 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10918 return s0;
10919 }
10920 function peg$parseexclusive_or_expression() {
10921 var s0, s1, s2, s3, s4, s5;
10922 var key = peg$currPos * 306 + 242;
10923 var cached = peg$resultsCache[key];
10924 if (cached) {
10925 peg$currPos = cached.nextPos;
10926 return cached.result;
10927 }
10928 s0 = peg$currPos;
10929 s1 = peg$parseand_expression();
10930 if (s1 !== peg$FAILED) {
10931 s2 = [];
10932 s3 = peg$currPos;
10933 s4 = peg$parseCARET();
10934 if (s4 !== peg$FAILED) {
10935 s5 = peg$parseand_expression();
10936 if (s5 !== peg$FAILED) {
10937 s4 = [s4, s5];
10938 s3 = s4;
10939 } else {
10940 peg$currPos = s3;
10941 s3 = peg$FAILED;
10942 }
10943 } else {
10944 peg$currPos = s3;
10945 s3 = peg$FAILED;
10946 }
10947 while (s3 !== peg$FAILED) {
10948 s2.push(s3);
10949 s3 = peg$currPos;
10950 s4 = peg$parseCARET();
10951 if (s4 !== peg$FAILED) {
10952 s5 = peg$parseand_expression();
10953 if (s5 !== peg$FAILED) {
10954 s4 = [s4, s5];
10955 s3 = s4;
10956 } else {
10957 peg$currPos = s3;
10958 s3 = peg$FAILED;
10959 }
10960 } else {
10961 peg$currPos = s3;
10962 s3 = peg$FAILED;
10963 }
10964 }
10965 peg$savedPos = s0;
10966 s0 = peg$f22(s1, s2);
10967 } else {
10968 peg$currPos = s0;
10969 s0 = peg$FAILED;
10970 }
10971 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
10972 return s0;
10973 }
10974 function peg$parseinclusive_or_expression() {
10975 var s0, s1, s2, s3, s4, s5;
10976 var key = peg$currPos * 306 + 243;
10977 var cached = peg$resultsCache[key];
10978 if (cached) {
10979 peg$currPos = cached.nextPos;
10980 return cached.result;
10981 }
10982 s0 = peg$currPos;
10983 s1 = peg$parseexclusive_or_expression();
10984 if (s1 !== peg$FAILED) {
10985 s2 = [];
10986 s3 = peg$currPos;
10987 s4 = peg$parseVERTICAL_BAR();
10988 if (s4 !== peg$FAILED) {
10989 s5 = peg$parseexclusive_or_expression();
10990 if (s5 !== peg$FAILED) {
10991 s4 = [s4, s5];
10992 s3 = s4;
10993 } else {
10994 peg$currPos = s3;
10995 s3 = peg$FAILED;
10996 }
10997 } else {
10998 peg$currPos = s3;
10999 s3 = peg$FAILED;
11000 }
11001 while (s3 !== peg$FAILED) {
11002 s2.push(s3);
11003 s3 = peg$currPos;
11004 s4 = peg$parseVERTICAL_BAR();
11005 if (s4 !== peg$FAILED) {
11006 s5 = peg$parseexclusive_or_expression();
11007 if (s5 !== peg$FAILED) {
11008 s4 = [s4, s5];
11009 s3 = s4;
11010 } else {
11011 peg$currPos = s3;
11012 s3 = peg$FAILED;
11013 }
11014 } else {
11015 peg$currPos = s3;
11016 s3 = peg$FAILED;
11017 }
11018 }
11019 peg$savedPos = s0;
11020 s0 = peg$f22(s1, s2);
11021 } else {
11022 peg$currPos = s0;
11023 s0 = peg$FAILED;
11024 }
11025 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11026 return s0;
11027 }
11028 function peg$parselogical_and_expression() {
11029 var s0, s1, s2, s3, s4, s5;
11030 var key = peg$currPos * 306 + 244;
11031 var cached = peg$resultsCache[key];
11032 if (cached) {
11033 peg$currPos = cached.nextPos;
11034 return cached.result;
11035 }
11036 s0 = peg$currPos;
11037 s1 = peg$parseinclusive_or_expression();
11038 if (s1 !== peg$FAILED) {
11039 s2 = [];
11040 s3 = peg$currPos;
11041 s4 = peg$parseAND_OP();
11042 if (s4 !== peg$FAILED) {
11043 s5 = peg$parseinclusive_or_expression();
11044 if (s5 !== peg$FAILED) {
11045 s4 = [s4, s5];
11046 s3 = s4;
11047 } else {
11048 peg$currPos = s3;
11049 s3 = peg$FAILED;
11050 }
11051 } else {
11052 peg$currPos = s3;
11053 s3 = peg$FAILED;
11054 }
11055 while (s3 !== peg$FAILED) {
11056 s2.push(s3);
11057 s3 = peg$currPos;
11058 s4 = peg$parseAND_OP();
11059 if (s4 !== peg$FAILED) {
11060 s5 = peg$parseinclusive_or_expression();
11061 if (s5 !== peg$FAILED) {
11062 s4 = [s4, s5];
11063 s3 = s4;
11064 } else {
11065 peg$currPos = s3;
11066 s3 = peg$FAILED;
11067 }
11068 } else {
11069 peg$currPos = s3;
11070 s3 = peg$FAILED;
11071 }
11072 }
11073 peg$savedPos = s0;
11074 s0 = peg$f22(s1, s2);
11075 } else {
11076 peg$currPos = s0;
11077 s0 = peg$FAILED;
11078 }
11079 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11080 return s0;
11081 }
11082 function peg$parselogical_xor_expression() {
11083 var s0, s1, s2, s3, s4, s5;
11084 var key = peg$currPos * 306 + 245;
11085 var cached = peg$resultsCache[key];
11086 if (cached) {
11087 peg$currPos = cached.nextPos;
11088 return cached.result;
11089 }
11090 s0 = peg$currPos;
11091 s1 = peg$parselogical_and_expression();
11092 if (s1 !== peg$FAILED) {
11093 s2 = [];
11094 s3 = peg$currPos;
11095 s4 = peg$parseXOR_OP();
11096 if (s4 !== peg$FAILED) {
11097 s5 = peg$parselogical_and_expression();
11098 if (s5 !== peg$FAILED) {
11099 s4 = [s4, s5];
11100 s3 = s4;
11101 } else {
11102 peg$currPos = s3;
11103 s3 = peg$FAILED;
11104 }
11105 } else {
11106 peg$currPos = s3;
11107 s3 = peg$FAILED;
11108 }
11109 while (s3 !== peg$FAILED) {
11110 s2.push(s3);
11111 s3 = peg$currPos;
11112 s4 = peg$parseXOR_OP();
11113 if (s4 !== peg$FAILED) {
11114 s5 = peg$parselogical_and_expression();
11115 if (s5 !== peg$FAILED) {
11116 s4 = [s4, s5];
11117 s3 = s4;
11118 } else {
11119 peg$currPos = s3;
11120 s3 = peg$FAILED;
11121 }
11122 } else {
11123 peg$currPos = s3;
11124 s3 = peg$FAILED;
11125 }
11126 }
11127 peg$savedPos = s0;
11128 s0 = peg$f22(s1, s2);
11129 } else {
11130 peg$currPos = s0;
11131 s0 = peg$FAILED;
11132 }
11133 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11134 return s0;
11135 }
11136 function peg$parselogical_or_expression() {
11137 var s0, s1, s2, s3, s4, s5;
11138 var key = peg$currPos * 306 + 246;
11139 var cached = peg$resultsCache[key];
11140 if (cached) {
11141 peg$currPos = cached.nextPos;
11142 return cached.result;
11143 }
11144 s0 = peg$currPos;
11145 s1 = peg$parselogical_xor_expression();
11146 if (s1 !== peg$FAILED) {
11147 s2 = [];
11148 s3 = peg$currPos;
11149 s4 = peg$parseOR_OP();
11150 if (s4 !== peg$FAILED) {
11151 s5 = peg$parselogical_xor_expression();
11152 if (s5 !== peg$FAILED) {
11153 s4 = [s4, s5];
11154 s3 = s4;
11155 } else {
11156 peg$currPos = s3;
11157 s3 = peg$FAILED;
11158 }
11159 } else {
11160 peg$currPos = s3;
11161 s3 = peg$FAILED;
11162 }
11163 while (s3 !== peg$FAILED) {
11164 s2.push(s3);
11165 s3 = peg$currPos;
11166 s4 = peg$parseOR_OP();
11167 if (s4 !== peg$FAILED) {
11168 s5 = peg$parselogical_xor_expression();
11169 if (s5 !== peg$FAILED) {
11170 s4 = [s4, s5];
11171 s3 = s4;
11172 } else {
11173 peg$currPos = s3;
11174 s3 = peg$FAILED;
11175 }
11176 } else {
11177 peg$currPos = s3;
11178 s3 = peg$FAILED;
11179 }
11180 }
11181 peg$savedPos = s0;
11182 s0 = peg$f22(s1, s2);
11183 } else {
11184 peg$currPos = s0;
11185 s0 = peg$FAILED;
11186 }
11187 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11188 return s0;
11189 }
11190 function peg$parseternary_expression() {
11191 var s0, s1, s2, s3, s4, s5, s6;
11192 var key = peg$currPos * 306 + 247;
11193 var cached = peg$resultsCache[key];
11194 if (cached) {
11195 peg$currPos = cached.nextPos;
11196 return cached.result;
11197 }
11198 s0 = peg$currPos;
11199 s1 = peg$parselogical_or_expression();
11200 if (s1 !== peg$FAILED) {
11201 s2 = peg$currPos;
11202 s3 = peg$parseQUESTION();
11203 if (s3 !== peg$FAILED) {
11204 s4 = peg$parseexpression();
11205 if (s4 !== peg$FAILED) {
11206 s5 = peg$parseCOLON();
11207 if (s5 !== peg$FAILED) {
11208 s6 = peg$parseassignment_expression();
11209 if (s6 !== peg$FAILED) {
11210 peg$savedPos = s2;
11211 s2 = peg$f23(s1, s3, s4, s5, s6);
11212 } else {
11213 peg$currPos = s2;
11214 s2 = peg$FAILED;
11215 }
11216 } else {
11217 peg$currPos = s2;
11218 s2 = peg$FAILED;
11219 }
11220 } else {
11221 peg$currPos = s2;
11222 s2 = peg$FAILED;
11223 }
11224 } else {
11225 peg$currPos = s2;
11226 s2 = peg$FAILED;
11227 }
11228 if (s2 === peg$FAILED) {
11229 s2 = null;
11230 }
11231 peg$savedPos = s0;
11232 s0 = peg$f24(s1, s2);
11233 } else {
11234 peg$currPos = s0;
11235 s0 = peg$FAILED;
11236 }
11237 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11238 return s0;
11239 }
11240 function peg$parseassignment_expression() {
11241 var s0, s1, s2, s3;
11242 var key = peg$currPos * 306 + 248;
11243 var cached = peg$resultsCache[key];
11244 if (cached) {
11245 peg$currPos = cached.nextPos;
11246 return cached.result;
11247 }
11248 s0 = peg$currPos;
11249 s1 = peg$parseunary_expression();
11250 if (s1 !== peg$FAILED) {
11251 s2 = peg$parseassignment_operator();
11252 if (s2 !== peg$FAILED) {
11253 s3 = peg$parseassignment_expression();
11254 if (s3 !== peg$FAILED) {
11255 peg$savedPos = s0;
11256 s0 = peg$f25(s1, s2, s3);
11257 } else {
11258 peg$currPos = s0;
11259 s0 = peg$FAILED;
11260 }
11261 } else {
11262 peg$currPos = s0;
11263 s0 = peg$FAILED;
11264 }
11265 } else {
11266 peg$currPos = s0;
11267 s0 = peg$FAILED;
11268 }
11269 if (s0 === peg$FAILED) {
11270 s0 = peg$parseternary_expression();
11271 }
11272 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11273 return s0;
11274 }
11275 function peg$parseassignment_operator() {
11276 var s0, s1;
11277 var key = peg$currPos * 306 + 249;
11278 var cached = peg$resultsCache[key];
11279 if (cached) {
11280 peg$currPos = cached.nextPos;
11281 return cached.result;
11282 }
11283 peg$silentFails++;
11284 s0 = peg$parseEQUAL();
11285 if (s0 === peg$FAILED) {
11286 s0 = peg$parseMUL_ASSIGN();
11287 if (s0 === peg$FAILED) {
11288 s0 = peg$parseDIV_ASSIGN();
11289 if (s0 === peg$FAILED) {
11290 s0 = peg$parseMOD_ASSIGN();
11291 if (s0 === peg$FAILED) {
11292 s0 = peg$parseADD_ASSIGN();
11293 if (s0 === peg$FAILED) {
11294 s0 = peg$parseSUB_ASSIGN();
11295 if (s0 === peg$FAILED) {
11296 s0 = peg$parseLEFT_ASSIGN();
11297 if (s0 === peg$FAILED) {
11298 s0 = peg$parseRIGHT_ASSIGN();
11299 if (s0 === peg$FAILED) {
11300 s0 = peg$parseAND_ASSIGN();
11301 if (s0 === peg$FAILED) {
11302 s0 = peg$parseXOR_ASSIGN();
11303 if (s0 === peg$FAILED) {
11304 s0 = peg$parseOR_ASSIGN();
11305 }
11306 }
11307 }
11308 }
11309 }
11310 }
11311 }
11312 }
11313 }
11314 }
11315 peg$silentFails--;
11316 if (s0 === peg$FAILED) {
11317 s1 = peg$FAILED;
11318 if (peg$silentFails === 0) {
11319 peg$fail(peg$e227);
11320 }
11321 }
11322 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11323 return s0;
11324 }
11325 function peg$parseexpression() {
11326 var s0, s1, s2, s3, s4, s5;
11327 var key = peg$currPos * 306 + 250;
11328 var cached = peg$resultsCache[key];
11329 if (cached) {
11330 peg$currPos = cached.nextPos;
11331 return cached.result;
11332 }
11333 peg$silentFails++;
11334 s0 = peg$currPos;
11335 s1 = peg$parseassignment_expression();
11336 if (s1 !== peg$FAILED) {
11337 s2 = [];
11338 s3 = peg$currPos;
11339 s4 = peg$parseCOMMA();
11340 if (s4 !== peg$FAILED) {
11341 s5 = peg$parseassignment_expression();
11342 if (s5 !== peg$FAILED) {
11343 s4 = [s4, s5];
11344 s3 = s4;
11345 } else {
11346 peg$currPos = s3;
11347 s3 = peg$FAILED;
11348 }
11349 } else {
11350 peg$currPos = s3;
11351 s3 = peg$FAILED;
11352 }
11353 while (s3 !== peg$FAILED) {
11354 s2.push(s3);
11355 s3 = peg$currPos;
11356 s4 = peg$parseCOMMA();
11357 if (s4 !== peg$FAILED) {
11358 s5 = peg$parseassignment_expression();
11359 if (s5 !== peg$FAILED) {
11360 s4 = [s4, s5];
11361 s3 = s4;
11362 } else {
11363 peg$currPos = s3;
11364 s3 = peg$FAILED;
11365 }
11366 } else {
11367 peg$currPos = s3;
11368 s3 = peg$FAILED;
11369 }
11370 }
11371 peg$savedPos = s0;
11372 s0 = peg$f22(s1, s2);
11373 } else {
11374 peg$currPos = s0;
11375 s0 = peg$FAILED;
11376 }
11377 peg$silentFails--;
11378 if (s0 === peg$FAILED) {
11379 s1 = peg$FAILED;
11380 if (peg$silentFails === 0) {
11381 peg$fail(peg$e228);
11382 }
11383 }
11384 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11385 return s0;
11386 }
11387 function peg$parsedeclaration_statement() {
11388 var s0, s1;
11389 var key = peg$currPos * 306 + 251;
11390 var cached = peg$resultsCache[key];
11391 if (cached) {
11392 peg$currPos = cached.nextPos;
11393 return cached.result;
11394 }
11395 s0 = peg$currPos;
11396 s1 = peg$parseprecision_declarator_statement();
11397 if (s1 === peg$FAILED) {
11398 s1 = peg$parseinterface_declarator_statement();
11399 if (s1 === peg$FAILED) {
11400 s1 = peg$parsequalifier_declarator_statement();
11401 if (s1 === peg$FAILED) {
11402 s1 = peg$parseinit_declarator_list_statement();
11403 }
11404 }
11405 }
11406 if (s1 !== peg$FAILED) {
11407 peg$savedPos = s0;
11408 s1 = peg$f26(s1);
11409 }
11410 s0 = s1;
11411 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11412 return s0;
11413 }
11414 function peg$parsequalifier_declarator_statement() {
11415 var s0, s1, s2, s3, s4, s5, s6;
11416 var key = peg$currPos * 306 + 252;
11417 var cached = peg$resultsCache[key];
11418 if (cached) {
11419 peg$currPos = cached.nextPos;
11420 return cached.result;
11421 }
11422 s0 = peg$currPos;
11423 s1 = peg$parsetype_qualifiers();
11424 if (s1 !== peg$FAILED) {
11425 s2 = peg$parseIDENTIFIER();
11426 if (s2 === peg$FAILED) {
11427 s2 = null;
11428 }
11429 s3 = [];
11430 s4 = peg$currPos;
11431 s5 = peg$parseCOMMA();
11432 if (s5 !== peg$FAILED) {
11433 s6 = peg$parseIDENTIFIER();
11434 if (s6 !== peg$FAILED) {
11435 s5 = [s5, s6];
11436 s4 = s5;
11437 } else {
11438 peg$currPos = s4;
11439 s4 = peg$FAILED;
11440 }
11441 } else {
11442 peg$currPos = s4;
11443 s4 = peg$FAILED;
11444 }
11445 while (s4 !== peg$FAILED) {
11446 s3.push(s4);
11447 s4 = peg$currPos;
11448 s5 = peg$parseCOMMA();
11449 if (s5 !== peg$FAILED) {
11450 s6 = peg$parseIDENTIFIER();
11451 if (s6 !== peg$FAILED) {
11452 s5 = [s5, s6];
11453 s4 = s5;
11454 } else {
11455 peg$currPos = s4;
11456 s4 = peg$FAILED;
11457 }
11458 } else {
11459 peg$currPos = s4;
11460 s4 = peg$FAILED;
11461 }
11462 }
11463 s4 = peg$parseSEMICOLON();
11464 if (s4 !== peg$FAILED) {
11465 peg$savedPos = s0;
11466 s0 = peg$f27(s1, s2, s3, s4);
11467 } else {
11468 peg$currPos = s0;
11469 s0 = peg$FAILED;
11470 }
11471 } else {
11472 peg$currPos = s0;
11473 s0 = peg$FAILED;
11474 }
11475 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11476 return s0;
11477 }
11478 function peg$parseinterface_declarator_statement() {
11479 var s0, s1, s2, s3, s4, s5, s6, s7;
11480 var key = peg$currPos * 306 + 253;
11481 var cached = peg$resultsCache[key];
11482 if (cached) {
11483 peg$currPos = cached.nextPos;
11484 return cached.result;
11485 }
11486 s0 = peg$currPos;
11487 s1 = peg$parsetype_qualifiers();
11488 if (s1 !== peg$FAILED) {
11489 s2 = peg$parseIDENTIFIER();
11490 if (s2 !== peg$FAILED) {
11491 s3 = peg$parseLEFT_BRACE();
11492 if (s3 !== peg$FAILED) {
11493 s4 = peg$parsestruct_declaration_list();
11494 if (s4 !== peg$FAILED) {
11495 s5 = peg$parseRIGHT_BRACE();
11496 if (s5 !== peg$FAILED) {
11497 s6 = peg$parsequantified_identifier();
11498 if (s6 === peg$FAILED) {
11499 s6 = null;
11500 }
11501 s7 = peg$parseSEMICOLON();
11502 if (s7 !== peg$FAILED) {
11503 peg$savedPos = s0;
11504 s0 = peg$f28(s1, s2, s3, s4, s5, s6, s7);
11505 } else {
11506 peg$currPos = s0;
11507 s0 = peg$FAILED;
11508 }
11509 } else {
11510 peg$currPos = s0;
11511 s0 = peg$FAILED;
11512 }
11513 } else {
11514 peg$currPos = s0;
11515 s0 = peg$FAILED;
11516 }
11517 } else {
11518 peg$currPos = s0;
11519 s0 = peg$FAILED;
11520 }
11521 } else {
11522 peg$currPos = s0;
11523 s0 = peg$FAILED;
11524 }
11525 } else {
11526 peg$currPos = s0;
11527 s0 = peg$FAILED;
11528 }
11529 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11530 return s0;
11531 }
11532 function peg$parseprecision_declarator_statement() {
11533 var s0, s1, s2, s3, s4;
11534 var key = peg$currPos * 306 + 254;
11535 var cached = peg$resultsCache[key];
11536 if (cached) {
11537 peg$currPos = cached.nextPos;
11538 return cached.result;
11539 }
11540 peg$silentFails++;
11541 s0 = peg$currPos;
11542 s1 = peg$parsePRECISION();
11543 if (s1 !== peg$FAILED) {
11544 s2 = peg$parseprecision_qualifier();
11545 if (s2 !== peg$FAILED) {
11546 s3 = peg$parsetype_specifier();
11547 if (s3 !== peg$FAILED) {
11548 s4 = peg$parseSEMICOLON();
11549 if (s4 !== peg$FAILED) {
11550 peg$savedPos = s0;
11551 s0 = peg$f29(s1, s2, s3, s4);
11552 } else {
11553 peg$currPos = s0;
11554 s0 = peg$FAILED;
11555 }
11556 } else {
11557 peg$currPos = s0;
11558 s0 = peg$FAILED;
11559 }
11560 } else {
11561 peg$currPos = s0;
11562 s0 = peg$FAILED;
11563 }
11564 } else {
11565 peg$currPos = s0;
11566 s0 = peg$FAILED;
11567 }
11568 peg$silentFails--;
11569 if (s0 === peg$FAILED) {
11570 s1 = peg$FAILED;
11571 if (peg$silentFails === 0) {
11572 peg$fail(peg$e229);
11573 }
11574 }
11575 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11576 return s0;
11577 }
11578 function peg$parsefunction_prototype_new_scope() {
11579 var s0, s1, s2, s3;
11580 var key = peg$currPos * 306 + 255;
11581 var cached = peg$resultsCache[key];
11582 if (cached) {
11583 peg$currPos = cached.nextPos;
11584 return cached.result;
11585 }
11586 peg$silentFails++;
11587 s0 = peg$currPos;
11588 s1 = peg$parsefunction_header_new_scope();
11589 if (s1 !== peg$FAILED) {
11590 s2 = peg$parsefunction_parameters();
11591 if (s2 === peg$FAILED) {
11592 s2 = null;
11593 }
11594 s3 = peg$parseRIGHT_PAREN();
11595 if (s3 !== peg$FAILED) {
11596 peg$savedPos = s0;
11597 s0 = peg$f30(s1, s2, s3);
11598 } else {
11599 peg$currPos = s0;
11600 s0 = peg$FAILED;
11601 }
11602 } else {
11603 peg$currPos = s0;
11604 s0 = peg$FAILED;
11605 }
11606 peg$silentFails--;
11607 if (s0 === peg$FAILED) {
11608 s1 = peg$FAILED;
11609 if (peg$silentFails === 0) {
11610 peg$fail(peg$e230);
11611 }
11612 }
11613 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11614 return s0;
11615 }
11616 function peg$parsefunction_header_new_scope() {
11617 var s0, s1, s2, s3;
11618 var key = peg$currPos * 306 + 256;
11619 var cached = peg$resultsCache[key];
11620 if (cached) {
11621 peg$currPos = cached.nextPos;
11622 return cached.result;
11623 }
11624 peg$silentFails++;
11625 s0 = peg$currPos;
11626 s1 = peg$parsefully_specified_type();
11627 if (s1 !== peg$FAILED) {
11628 s2 = peg$parseIDENTIFIER();
11629 if (s2 !== peg$FAILED) {
11630 s3 = peg$parseLEFT_PAREN();
11631 if (s3 !== peg$FAILED) {
11632 peg$savedPos = s0;
11633 s0 = peg$f31(s1, s2, s3);
11634 } else {
11635 peg$currPos = s0;
11636 s0 = peg$FAILED;
11637 }
11638 } else {
11639 peg$currPos = s0;
11640 s0 = peg$FAILED;
11641 }
11642 } else {
11643 peg$currPos = s0;
11644 s0 = peg$FAILED;
11645 }
11646 peg$silentFails--;
11647 if (s0 === peg$FAILED) {
11648 s1 = peg$FAILED;
11649 if (peg$silentFails === 0) {
11650 peg$fail(peg$e231);
11651 }
11652 }
11653 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11654 return s0;
11655 }
11656 function peg$parsefunction_prototype_no_new_scope() {
11657 var s0, s1, s2, s3;
11658 var key = peg$currPos * 306 + 257;
11659 var cached = peg$resultsCache[key];
11660 if (cached) {
11661 peg$currPos = cached.nextPos;
11662 return cached.result;
11663 }
11664 peg$silentFails++;
11665 s0 = peg$currPos;
11666 s1 = peg$parsefunction_header_no_new_scope();
11667 if (s1 !== peg$FAILED) {
11668 s2 = peg$parsefunction_parameters();
11669 if (s2 === peg$FAILED) {
11670 s2 = null;
11671 }
11672 s3 = peg$parseRIGHT_PAREN();
11673 if (s3 !== peg$FAILED) {
11674 peg$savedPos = s0;
11675 s0 = peg$f32(s1, s2, s3);
11676 } else {
11677 peg$currPos = s0;
11678 s0 = peg$FAILED;
11679 }
11680 } else {
11681 peg$currPos = s0;
11682 s0 = peg$FAILED;
11683 }
11684 peg$silentFails--;
11685 if (s0 === peg$FAILED) {
11686 s1 = peg$FAILED;
11687 if (peg$silentFails === 0) {
11688 peg$fail(peg$e232);
11689 }
11690 }
11691 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11692 return s0;
11693 }
11694 function peg$parsefunction_header_no_new_scope() {
11695 var s0, s1, s2, s3;
11696 var key = peg$currPos * 306 + 258;
11697 var cached = peg$resultsCache[key];
11698 if (cached) {
11699 peg$currPos = cached.nextPos;
11700 return cached.result;
11701 }
11702 peg$silentFails++;
11703 s0 = peg$currPos;
11704 s1 = peg$parsefully_specified_type();
11705 if (s1 !== peg$FAILED) {
11706 s2 = peg$parseIDENTIFIER();
11707 if (s2 !== peg$FAILED) {
11708 s3 = peg$parseLEFT_PAREN();
11709 if (s3 !== peg$FAILED) {
11710 peg$savedPos = s0;
11711 s0 = peg$f33(s1, s2, s3);
11712 } else {
11713 peg$currPos = s0;
11714 s0 = peg$FAILED;
11715 }
11716 } else {
11717 peg$currPos = s0;
11718 s0 = peg$FAILED;
11719 }
11720 } else {
11721 peg$currPos = s0;
11722 s0 = peg$FAILED;
11723 }
11724 peg$silentFails--;
11725 if (s0 === peg$FAILED) {
11726 s1 = peg$FAILED;
11727 if (peg$silentFails === 0) {
11728 peg$fail(peg$e233);
11729 }
11730 }
11731 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11732 return s0;
11733 }
11734 function peg$parsefunction_parameters() {
11735 var s0, s1, s2, s3, s4, s5;
11736 var key = peg$currPos * 306 + 259;
11737 var cached = peg$resultsCache[key];
11738 if (cached) {
11739 peg$currPos = cached.nextPos;
11740 return cached.result;
11741 }
11742 peg$silentFails++;
11743 s0 = peg$currPos;
11744 s1 = peg$parseparameter_declaration();
11745 if (s1 !== peg$FAILED) {
11746 s2 = [];
11747 s3 = peg$currPos;
11748 s4 = peg$parseCOMMA();
11749 if (s4 !== peg$FAILED) {
11750 s5 = peg$parseparameter_declaration();
11751 if (s5 !== peg$FAILED) {
11752 s4 = [s4, s5];
11753 s3 = s4;
11754 } else {
11755 peg$currPos = s3;
11756 s3 = peg$FAILED;
11757 }
11758 } else {
11759 peg$currPos = s3;
11760 s3 = peg$FAILED;
11761 }
11762 while (s3 !== peg$FAILED) {
11763 s2.push(s3);
11764 s3 = peg$currPos;
11765 s4 = peg$parseCOMMA();
11766 if (s4 !== peg$FAILED) {
11767 s5 = peg$parseparameter_declaration();
11768 if (s5 !== peg$FAILED) {
11769 s4 = [s4, s5];
11770 s3 = s4;
11771 } else {
11772 peg$currPos = s3;
11773 s3 = peg$FAILED;
11774 }
11775 } else {
11776 peg$currPos = s3;
11777 s3 = peg$FAILED;
11778 }
11779 }
11780 peg$savedPos = s0;
11781 s0 = peg$f34(s1, s2);
11782 } else {
11783 peg$currPos = s0;
11784 s0 = peg$FAILED;
11785 }
11786 peg$silentFails--;
11787 if (s0 === peg$FAILED) {
11788 s1 = peg$FAILED;
11789 if (peg$silentFails === 0) {
11790 peg$fail(peg$e234);
11791 }
11792 }
11793 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11794 return s0;
11795 }
11796 function peg$parseparameter_declaration() {
11797 var s0, s1, s2, s3, s4, s5;
11798 var key = peg$currPos * 306 + 260;
11799 var cached = peg$resultsCache[key];
11800 if (cached) {
11801 peg$currPos = cached.nextPos;
11802 return cached.result;
11803 }
11804 peg$silentFails++;
11805 s0 = peg$currPos;
11806 s1 = [];
11807 s2 = peg$parseparameter_qualifier();
11808 while (s2 !== peg$FAILED) {
11809 s1.push(s2);
11810 s2 = peg$parseparameter_qualifier();
11811 }
11812 s2 = peg$parsetype_specifier();
11813 if (s2 !== peg$FAILED) {
11814 s3 = peg$currPos;
11815 s4 = peg$parseIDENTIFIER();
11816 if (s4 !== peg$FAILED) {
11817 s5 = peg$parsearray_specifiers();
11818 if (s5 === peg$FAILED) {
11819 s5 = null;
11820 }
11821 s4 = [s4, s5];
11822 s3 = s4;
11823 } else {
11824 peg$currPos = s3;
11825 s3 = peg$FAILED;
11826 }
11827 if (s3 === peg$FAILED) {
11828 s3 = null;
11829 }
11830 peg$savedPos = s0;
11831 s0 = peg$f35(s1, s2, s3);
11832 } else {
11833 peg$currPos = s0;
11834 s0 = peg$FAILED;
11835 }
11836 peg$silentFails--;
11837 if (s0 === peg$FAILED) {
11838 s1 = peg$FAILED;
11839 if (peg$silentFails === 0) {
11840 peg$fail(peg$e235);
11841 }
11842 }
11843 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11844 return s0;
11845 }
11846 function peg$parseparameter_qualifier() {
11847 var s0;
11848 var key = peg$currPos * 306 + 261;
11849 var cached = peg$resultsCache[key];
11850 if (cached) {
11851 peg$currPos = cached.nextPos;
11852 return cached.result;
11853 }
11854 s0 = peg$parseCONST();
11855 if (s0 === peg$FAILED) {
11856 s0 = peg$parseIN();
11857 if (s0 === peg$FAILED) {
11858 s0 = peg$parseOUT();
11859 if (s0 === peg$FAILED) {
11860 s0 = peg$parseINOUT();
11861 if (s0 === peg$FAILED) {
11862 s0 = peg$parsememory_qualifier();
11863 if (s0 === peg$FAILED) {
11864 s0 = peg$parseprecision_qualifier();
11865 }
11866 }
11867 }
11868 }
11869 }
11870 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11871 return s0;
11872 }
11873 function peg$parsememory_qualifier() {
11874 var s0;
11875 var key = peg$currPos * 306 + 262;
11876 var cached = peg$resultsCache[key];
11877 if (cached) {
11878 peg$currPos = cached.nextPos;
11879 return cached.result;
11880 }
11881 s0 = peg$parseCOHERENT();
11882 if (s0 === peg$FAILED) {
11883 s0 = peg$parseVOLATILE();
11884 if (s0 === peg$FAILED) {
11885 s0 = peg$parseRESTRICT();
11886 if (s0 === peg$FAILED) {
11887 s0 = peg$parseREADONLY();
11888 if (s0 === peg$FAILED) {
11889 s0 = peg$parseWRITEONLY();
11890 }
11891 }
11892 }
11893 }
11894 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11895 return s0;
11896 }
11897 function peg$parseinit_declarator_list_statement() {
11898 var s0, s1, s2, s3, s4, s5;
11899 var key = peg$currPos * 306 + 263;
11900 var cached = peg$resultsCache[key];
11901 if (cached) {
11902 peg$currPos = cached.nextPos;
11903 return cached.result;
11904 }
11905 s0 = peg$currPos;
11906 s1 = peg$parseinitial_declaration();
11907 if (s1 !== peg$FAILED) {
11908 s2 = [];
11909 s3 = peg$currPos;
11910 s4 = peg$parseCOMMA();
11911 if (s4 !== peg$FAILED) {
11912 s5 = peg$parsesubsequent_declaration();
11913 if (s5 !== peg$FAILED) {
11914 s4 = [s4, s5];
11915 s3 = s4;
11916 } else {
11917 peg$currPos = s3;
11918 s3 = peg$FAILED;
11919 }
11920 } else {
11921 peg$currPos = s3;
11922 s3 = peg$FAILED;
11923 }
11924 while (s3 !== peg$FAILED) {
11925 s2.push(s3);
11926 s3 = peg$currPos;
11927 s4 = peg$parseCOMMA();
11928 if (s4 !== peg$FAILED) {
11929 s5 = peg$parsesubsequent_declaration();
11930 if (s5 !== peg$FAILED) {
11931 s4 = [s4, s5];
11932 s3 = s4;
11933 } else {
11934 peg$currPos = s3;
11935 s3 = peg$FAILED;
11936 }
11937 } else {
11938 peg$currPos = s3;
11939 s3 = peg$FAILED;
11940 }
11941 }
11942 s3 = peg$parseSEMICOLON();
11943 if (s3 !== peg$FAILED) {
11944 peg$savedPos = s0;
11945 s0 = peg$f36(s1, s2, s3);
11946 } else {
11947 peg$currPos = s0;
11948 s0 = peg$FAILED;
11949 }
11950 } else {
11951 peg$currPos = s0;
11952 s0 = peg$FAILED;
11953 }
11954 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11955 return s0;
11956 }
11957 function peg$parsesubsequent_declaration() {
11958 var s0, s1, s2, s3, s4, s5;
11959 var key = peg$currPos * 306 + 264;
11960 var cached = peg$resultsCache[key];
11961 if (cached) {
11962 peg$currPos = cached.nextPos;
11963 return cached.result;
11964 }
11965 s0 = peg$currPos;
11966 s1 = peg$parseIDENTIFIER();
11967 if (s1 !== peg$FAILED) {
11968 s2 = peg$parsearray_specifiers();
11969 if (s2 === peg$FAILED) {
11970 s2 = null;
11971 }
11972 s3 = peg$currPos;
11973 s4 = peg$parseEQUAL();
11974 if (s4 !== peg$FAILED) {
11975 s5 = peg$parseinitializer();
11976 if (s5 !== peg$FAILED) {
11977 s4 = [s4, s5];
11978 s3 = s4;
11979 } else {
11980 peg$currPos = s3;
11981 s3 = peg$FAILED;
11982 }
11983 } else {
11984 peg$currPos = s3;
11985 s3 = peg$FAILED;
11986 }
11987 if (s3 === peg$FAILED) {
11988 s3 = null;
11989 }
11990 peg$savedPos = s0;
11991 s0 = peg$f37(s1, s2, s3);
11992 } else {
11993 peg$currPos = s0;
11994 s0 = peg$FAILED;
11995 }
11996 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
11997 return s0;
11998 }
11999 function peg$parseinitial_declaration() {
12000 var s0, s1, s2, s3, s4, s5, s6, s7;
12001 var key = peg$currPos * 306 + 265;
12002 var cached = peg$resultsCache[key];
12003 if (cached) {
12004 peg$currPos = cached.nextPos;
12005 return cached.result;
12006 }
12007 s0 = peg$currPos;
12008 s1 = peg$parsefully_specified_type();
12009 if (s1 !== peg$FAILED) {
12010 s2 = peg$currPos;
12011 s3 = peg$parseIDENTIFIER();
12012 if (s3 !== peg$FAILED) {
12013 s4 = peg$parsearray_specifiers();
12014 if (s4 === peg$FAILED) {
12015 s4 = null;
12016 }
12017 s5 = peg$currPos;
12018 s6 = peg$parseEQUAL();
12019 if (s6 !== peg$FAILED) {
12020 s7 = peg$parseinitializer();
12021 if (s7 !== peg$FAILED) {
12022 s6 = [s6, s7];
12023 s5 = s6;
12024 } else {
12025 peg$currPos = s5;
12026 s5 = peg$FAILED;
12027 }
12028 } else {
12029 peg$currPos = s5;
12030 s5 = peg$FAILED;
12031 }
12032 if (s5 === peg$FAILED) {
12033 s5 = null;
12034 }
12035 s3 = [s3, s4, s5];
12036 s2 = s3;
12037 } else {
12038 peg$currPos = s2;
12039 s2 = peg$FAILED;
12040 }
12041 if (s2 === peg$FAILED) {
12042 s2 = null;
12043 }
12044 peg$savedPos = s0;
12045 s0 = peg$f38(s1, s2);
12046 } else {
12047 peg$currPos = s0;
12048 s0 = peg$FAILED;
12049 }
12050 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12051 return s0;
12052 }
12053 function peg$parsefully_specified_type() {
12054 var s0, s1, s2;
12055 var key = peg$currPos * 306 + 266;
12056 var cached = peg$resultsCache[key];
12057 if (cached) {
12058 peg$currPos = cached.nextPos;
12059 return cached.result;
12060 }
12061 s0 = peg$currPos;
12062 s1 = peg$parsetype_qualifiers();
12063 if (s1 === peg$FAILED) {
12064 s1 = null;
12065 }
12066 s2 = peg$parsetype_specifier();
12067 if (s2 !== peg$FAILED) {
12068 peg$savedPos = s0;
12069 s0 = peg$f39(s1, s2);
12070 } else {
12071 peg$currPos = s0;
12072 s0 = peg$FAILED;
12073 }
12074 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12075 return s0;
12076 }
12077 function peg$parselayout_qualifier() {
12078 var s0, s1, s2, s3, s4, s5, s6, s7, s8;
12079 var key = peg$currPos * 306 + 267;
12080 var cached = peg$resultsCache[key];
12081 if (cached) {
12082 peg$currPos = cached.nextPos;
12083 return cached.result;
12084 }
12085 s0 = peg$currPos;
12086 s1 = peg$parseLAYOUT();
12087 if (s1 !== peg$FAILED) {
12088 s2 = peg$parseLEFT_PAREN();
12089 if (s2 !== peg$FAILED) {
12090 s3 = peg$currPos;
12091 s4 = peg$parselayout_qualifier_id();
12092 if (s4 !== peg$FAILED) {
12093 s5 = [];
12094 s6 = peg$currPos;
12095 s7 = peg$parseCOMMA();
12096 if (s7 !== peg$FAILED) {
12097 s8 = peg$parselayout_qualifier_id();
12098 if (s8 !== peg$FAILED) {
12099 s7 = [s7, s8];
12100 s6 = s7;
12101 } else {
12102 peg$currPos = s6;
12103 s6 = peg$FAILED;
12104 }
12105 } else {
12106 peg$currPos = s6;
12107 s6 = peg$FAILED;
12108 }
12109 while (s6 !== peg$FAILED) {
12110 s5.push(s6);
12111 s6 = peg$currPos;
12112 s7 = peg$parseCOMMA();
12113 if (s7 !== peg$FAILED) {
12114 s8 = peg$parselayout_qualifier_id();
12115 if (s8 !== peg$FAILED) {
12116 s7 = [s7, s8];
12117 s6 = s7;
12118 } else {
12119 peg$currPos = s6;
12120 s6 = peg$FAILED;
12121 }
12122 } else {
12123 peg$currPos = s6;
12124 s6 = peg$FAILED;
12125 }
12126 }
12127 peg$savedPos = s3;
12128 s3 = peg$f40(s1, s2, s4, s5);
12129 } else {
12130 peg$currPos = s3;
12131 s3 = peg$FAILED;
12132 }
12133 if (s3 !== peg$FAILED) {
12134 s4 = peg$parseRIGHT_PAREN();
12135 if (s4 !== peg$FAILED) {
12136 peg$savedPos = s0;
12137 s0 = peg$f41(s1, s2, s3, s4);
12138 } else {
12139 peg$currPos = s0;
12140 s0 = peg$FAILED;
12141 }
12142 } else {
12143 peg$currPos = s0;
12144 s0 = peg$FAILED;
12145 }
12146 } else {
12147 peg$currPos = s0;
12148 s0 = peg$FAILED;
12149 }
12150 } else {
12151 peg$currPos = s0;
12152 s0 = peg$FAILED;
12153 }
12154 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12155 return s0;
12156 }
12157 function peg$parselayout_qualifier_id() {
12158 var s0, s1, s2, s3, s4;
12159 var key = peg$currPos * 306 + 268;
12160 var cached = peg$resultsCache[key];
12161 if (cached) {
12162 peg$currPos = cached.nextPos;
12163 return cached.result;
12164 }
12165 s0 = peg$currPos;
12166 s1 = peg$parseIDENTIFIER();
12167 if (s1 !== peg$FAILED) {
12168 s2 = peg$currPos;
12169 s3 = peg$parseEQUAL();
12170 if (s3 !== peg$FAILED) {
12171 s4 = peg$parseternary_expression();
12172 if (s4 !== peg$FAILED) {
12173 s3 = [s3, s4];
12174 s2 = s3;
12175 } else {
12176 peg$currPos = s2;
12177 s2 = peg$FAILED;
12178 }
12179 } else {
12180 peg$currPos = s2;
12181 s2 = peg$FAILED;
12182 }
12183 if (s2 === peg$FAILED) {
12184 s2 = null;
12185 }
12186 peg$savedPos = s0;
12187 s0 = peg$f42(s1, s2);
12188 } else {
12189 peg$currPos = s0;
12190 s0 = peg$FAILED;
12191 }
12192 if (s0 === peg$FAILED) {
12193 s0 = peg$parseSHARED();
12194 }
12195 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12196 return s0;
12197 }
12198 function peg$parsetype_qualifiers() {
12199 var s0, s1;
12200 var key = peg$currPos * 306 + 269;
12201 var cached = peg$resultsCache[key];
12202 if (cached) {
12203 peg$currPos = cached.nextPos;
12204 return cached.result;
12205 }
12206 s0 = [];
12207 s1 = peg$parsesingle_type_qualifier();
12208 if (s1 !== peg$FAILED) {
12209 while (s1 !== peg$FAILED) {
12210 s0.push(s1);
12211 s1 = peg$parsesingle_type_qualifier();
12212 }
12213 } else {
12214 s0 = peg$FAILED;
12215 }
12216 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12217 return s0;
12218 }
12219 function peg$parsesingle_type_qualifier() {
12220 var s0, s1;
12221 var key = peg$currPos * 306 + 270;
12222 var cached = peg$resultsCache[key];
12223 if (cached) {
12224 peg$currPos = cached.nextPos;
12225 return cached.result;
12226 }
12227 peg$silentFails++;
12228 s0 = peg$parsestorage_qualifier();
12229 if (s0 === peg$FAILED) {
12230 s0 = peg$parselayout_qualifier();
12231 if (s0 === peg$FAILED) {
12232 s0 = peg$parseprecision_qualifier();
12233 if (s0 === peg$FAILED) {
12234 s0 = peg$parseinterpolation_qualifier();
12235 if (s0 === peg$FAILED) {
12236 s0 = peg$parseINVARIANT();
12237 if (s0 === peg$FAILED) {
12238 s0 = peg$parsePRECISE();
12239 }
12240 }
12241 }
12242 }
12243 }
12244 peg$silentFails--;
12245 if (s0 === peg$FAILED) {
12246 s1 = peg$FAILED;
12247 if (peg$silentFails === 0) {
12248 peg$fail(peg$e236);
12249 }
12250 }
12251 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12252 return s0;
12253 }
12254 function peg$parseinterpolation_qualifier() {
12255 var s0, s1;
12256 var key = peg$currPos * 306 + 271;
12257 var cached = peg$resultsCache[key];
12258 if (cached) {
12259 peg$currPos = cached.nextPos;
12260 return cached.result;
12261 }
12262 peg$silentFails++;
12263 s0 = peg$parseSMOOTH();
12264 if (s0 === peg$FAILED) {
12265 s0 = peg$parseFLAT();
12266 if (s0 === peg$FAILED) {
12267 s0 = peg$parseNOPERSPECTIVE();
12268 }
12269 }
12270 peg$silentFails--;
12271 if (s0 === peg$FAILED) {
12272 s1 = peg$FAILED;
12273 if (peg$silentFails === 0) {
12274 peg$fail(peg$e237);
12275 }
12276 }
12277 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12278 return s0;
12279 }
12280 function peg$parsestorage_qualifier() {
12281 var s0, s1, s2, s3, s4, s5, s6, s7, s8;
12282 var key = peg$currPos * 306 + 272;
12283 var cached = peg$resultsCache[key];
12284 if (cached) {
12285 peg$currPos = cached.nextPos;
12286 return cached.result;
12287 }
12288 peg$silentFails++;
12289 s0 = peg$parseCONST();
12290 if (s0 === peg$FAILED) {
12291 s0 = peg$parseINOUT();
12292 if (s0 === peg$FAILED) {
12293 s0 = peg$parseIN();
12294 if (s0 === peg$FAILED) {
12295 s0 = peg$parseOUT();
12296 if (s0 === peg$FAILED) {
12297 s0 = peg$parseCENTROID();
12298 if (s0 === peg$FAILED) {
12299 s0 = peg$parsePATCH();
12300 if (s0 === peg$FAILED) {
12301 s0 = peg$parseSAMPLE();
12302 if (s0 === peg$FAILED) {
12303 s0 = peg$parseUNIFORM();
12304 if (s0 === peg$FAILED) {
12305 s0 = peg$parseBUFFER();
12306 if (s0 === peg$FAILED) {
12307 s0 = peg$parseSHARED();
12308 if (s0 === peg$FAILED) {
12309 s0 = peg$parseCOHERENT();
12310 if (s0 === peg$FAILED) {
12311 s0 = peg$parseVOLATILE();
12312 if (s0 === peg$FAILED) {
12313 s0 = peg$parseRESTRICT();
12314 if (s0 === peg$FAILED) {
12315 s0 = peg$parseREADONLY();
12316 if (s0 === peg$FAILED) {
12317 s0 = peg$parseWRITEONLY();
12318 if (s0 === peg$FAILED) {
12319 s0 = peg$parseVARYING();
12320 if (s0 === peg$FAILED) {
12321 s0 = peg$parseATTRIBUTE();
12322 if (s0 === peg$FAILED) {
12323 s0 = peg$currPos;
12324 s1 = peg$parseSUBROUTINE();
12325 if (s1 !== peg$FAILED) {
12326 s2 = peg$currPos;
12327 s3 = peg$parseLEFT_PAREN();
12328 if (s3 !== peg$FAILED) {
12329 s4 = peg$parseTYPE_NAME();
12330 if (s4 !== peg$FAILED) {
12331 s5 = [];
12332 s6 = peg$currPos;
12333 s7 = peg$parseCOMMA();
12334 if (s7 !== peg$FAILED) {
12335 s8 = peg$parseTYPE_NAME();
12336 if (s8 !== peg$FAILED) {
12337 s7 = [s7, s8];
12338 s6 = s7;
12339 } else {
12340 peg$currPos = s6;
12341 s6 = peg$FAILED;
12342 }
12343 } else {
12344 peg$currPos = s6;
12345 s6 = peg$FAILED;
12346 }
12347 while (s6 !== peg$FAILED) {
12348 s5.push(s6);
12349 s6 = peg$currPos;
12350 s7 = peg$parseCOMMA();
12351 if (s7 !== peg$FAILED) {
12352 s8 = peg$parseTYPE_NAME();
12353 if (s8 !== peg$FAILED) {
12354 s7 = [s7, s8];
12355 s6 = s7;
12356 } else {
12357 peg$currPos = s6;
12358 s6 = peg$FAILED;
12359 }
12360 } else {
12361 peg$currPos = s6;
12362 s6 = peg$FAILED;
12363 }
12364 }
12365 s6 = peg$parseRIGHT_PAREN();
12366 if (s6 !== peg$FAILED) {
12367 peg$savedPos = s2;
12368 s2 = peg$f43(s1, s3, s4, s5, s6);
12369 } else {
12370 peg$currPos = s2;
12371 s2 = peg$FAILED;
12372 }
12373 } else {
12374 peg$currPos = s2;
12375 s2 = peg$FAILED;
12376 }
12377 } else {
12378 peg$currPos = s2;
12379 s2 = peg$FAILED;
12380 }
12381 if (s2 === peg$FAILED) {
12382 s2 = null;
12383 }
12384 peg$savedPos = s0;
12385 s0 = peg$f44(s1, s2);
12386 } else {
12387 peg$currPos = s0;
12388 s0 = peg$FAILED;
12389 }
12390 }
12391 }
12392 }
12393 }
12394 }
12395 }
12396 }
12397 }
12398 }
12399 }
12400 }
12401 }
12402 }
12403 }
12404 }
12405 }
12406 }
12407 peg$silentFails--;
12408 if (s0 === peg$FAILED) {
12409 s1 = peg$FAILED;
12410 if (peg$silentFails === 0) {
12411 peg$fail(peg$e238);
12412 }
12413 }
12414 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12415 return s0;
12416 }
12417 function peg$parsetype_specifier() {
12418 var s0, s1, s2;
12419 var key = peg$currPos * 306 + 273;
12420 var cached = peg$resultsCache[key];
12421 if (cached) {
12422 peg$currPos = cached.nextPos;
12423 return cached.result;
12424 }
12425 peg$silentFails++;
12426 s0 = peg$currPos;
12427 s1 = peg$parsetype_specifier_nonarray();
12428 if (s1 !== peg$FAILED) {
12429 s2 = peg$parsearray_specifiers();
12430 if (s2 === peg$FAILED) {
12431 s2 = null;
12432 }
12433 peg$savedPos = s0;
12434 s0 = peg$f45(s1, s2);
12435 } else {
12436 peg$currPos = s0;
12437 s0 = peg$FAILED;
12438 }
12439 peg$silentFails--;
12440 if (s0 === peg$FAILED) {
12441 s1 = peg$FAILED;
12442 if (peg$silentFails === 0) {
12443 peg$fail(peg$e239);
12444 }
12445 }
12446 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12447 return s0;
12448 }
12449 function peg$parsetype_specifier_nonarray() {
12450 var s0, s1;
12451 var key = peg$currPos * 306 + 274;
12452 var cached = peg$resultsCache[key];
12453 if (cached) {
12454 peg$currPos = cached.nextPos;
12455 return cached.result;
12456 }
12457 peg$silentFails++;
12458 s0 = peg$parseVOID();
12459 if (s0 === peg$FAILED) {
12460 s0 = peg$parseFLOAT();
12461 if (s0 === peg$FAILED) {
12462 s0 = peg$parseDOUBLE();
12463 if (s0 === peg$FAILED) {
12464 s0 = peg$parseINT();
12465 if (s0 === peg$FAILED) {
12466 s0 = peg$parseUINT();
12467 if (s0 === peg$FAILED) {
12468 s0 = peg$parseBOOL();
12469 if (s0 === peg$FAILED) {
12470 s0 = peg$parseVEC2();
12471 if (s0 === peg$FAILED) {
12472 s0 = peg$parseVEC3();
12473 if (s0 === peg$FAILED) {
12474 s0 = peg$parseVEC4();
12475 if (s0 === peg$FAILED) {
12476 s0 = peg$parseDVEC2();
12477 if (s0 === peg$FAILED) {
12478 s0 = peg$parseDVEC3();
12479 if (s0 === peg$FAILED) {
12480 s0 = peg$parseDVEC4();
12481 if (s0 === peg$FAILED) {
12482 s0 = peg$parseBVEC2();
12483 if (s0 === peg$FAILED) {
12484 s0 = peg$parseBVEC3();
12485 if (s0 === peg$FAILED) {
12486 s0 = peg$parseBVEC4();
12487 if (s0 === peg$FAILED) {
12488 s0 = peg$parseIVEC2();
12489 if (s0 === peg$FAILED) {
12490 s0 = peg$parseIVEC3();
12491 if (s0 === peg$FAILED) {
12492 s0 = peg$parseIVEC4();
12493 if (s0 === peg$FAILED) {
12494 s0 = peg$parseUVEC2();
12495 if (s0 === peg$FAILED) {
12496 s0 = peg$parseUVEC3();
12497 if (s0 === peg$FAILED) {
12498 s0 = peg$parseUVEC4();
12499 if (s0 === peg$FAILED) {
12500 s0 = peg$parseMAT2();
12501 if (s0 === peg$FAILED) {
12502 s0 = peg$parseMAT3();
12503 if (s0 === peg$FAILED) {
12504 s0 = peg$parseMAT4();
12505 if (s0 === peg$FAILED) {
12506 s0 = peg$parseMAT2X2();
12507 if (s0 === peg$FAILED) {
12508 s0 = peg$parseMAT2X3();
12509 if (s0 === peg$FAILED) {
12510 s0 = peg$parseMAT2X4();
12511 if (s0 === peg$FAILED) {
12512 s0 = peg$parseMAT3X2();
12513 if (s0 === peg$FAILED) {
12514 s0 = peg$parseMAT3X3();
12515 if (s0 === peg$FAILED) {
12516 s0 = peg$parseMAT3X4();
12517 if (s0 === peg$FAILED) {
12518 s0 = peg$parseMAT4X2();
12519 if (s0 === peg$FAILED) {
12520 s0 = peg$parseMAT4X3();
12521 if (s0 === peg$FAILED) {
12522 s0 = peg$parseMAT4X4();
12523 if (s0 === peg$FAILED) {
12524 s0 = peg$parseDMAT2();
12525 if (s0 === peg$FAILED) {
12526 s0 = peg$parseDMAT3();
12527 if (s0 === peg$FAILED) {
12528 s0 = peg$parseDMAT4();
12529 if (s0 === peg$FAILED) {
12530 s0 = peg$parseDMAT2X2();
12531 if (s0 === peg$FAILED) {
12532 s0 = peg$parseDMAT2X3();
12533 if (s0 === peg$FAILED) {
12534 s0 = peg$parseDMAT2X4();
12535 if (s0 === peg$FAILED) {
12536 s0 = peg$parseDMAT3X2();
12537 if (s0 === peg$FAILED) {
12538 s0 = peg$parseDMAT3X3();
12539 if (s0 === peg$FAILED) {
12540 s0 = peg$parseDMAT3X4();
12541 if (s0 === peg$FAILED) {
12542 s0 = peg$parseDMAT4X2();
12543 if (s0 === peg$FAILED) {
12544 s0 = peg$parseDMAT4X3();
12545 if (s0 === peg$FAILED) {
12546 s0 = peg$parseDMAT4X4();
12547 if (s0 === peg$FAILED) {
12548 s0 = peg$parseATOMIC_UINT();
12549 if (s0 === peg$FAILED) {
12550 s0 = peg$parseSAMPLER1D();
12551 if (s0 === peg$FAILED) {
12552 s0 = peg$parseSAMPLER2D();
12553 if (s0 === peg$FAILED) {
12554 s0 = peg$parseSAMPLER3D();
12555 if (s0 === peg$FAILED) {
12556 s0 = peg$parseSAMPLERCUBE();
12557 if (s0 === peg$FAILED) {
12558 s0 = peg$parseSAMPLER1DSHADOW();
12559 if (s0 === peg$FAILED) {
12560 s0 = peg$parseSAMPLER2DSHADOW();
12561 if (s0 === peg$FAILED) {
12562 s0 = peg$parseSAMPLERCUBESHADOW();
12563 if (s0 === peg$FAILED) {
12564 s0 = peg$parseSAMPLER1DARRAY();
12565 if (s0 === peg$FAILED) {
12566 s0 = peg$parseSAMPLER2DARRAY();
12567 if (s0 === peg$FAILED) {
12568 s0 = peg$parseSAMPLER1DARRAYSHADOW();
12569 if (s0 === peg$FAILED) {
12570 s0 = peg$parseSAMPLER2DARRAYSHADOW();
12571 if (s0 === peg$FAILED) {
12572 s0 = peg$parseSAMPLERCUBEARRAY();
12573 if (s0 === peg$FAILED) {
12574 s0 = peg$parseSAMPLERCUBEARRAYSHADOW();
12575 if (s0 === peg$FAILED) {
12576 s0 = peg$parseISAMPLER1D();
12577 if (s0 === peg$FAILED) {
12578 s0 = peg$parseISAMPLER2D();
12579 if (s0 === peg$FAILED) {
12580 s0 = peg$parseISAMPLER3D();
12581 if (s0 === peg$FAILED) {
12582 s0 = peg$parseISAMPLERCUBE();
12583 if (s0 === peg$FAILED) {
12584 s0 = peg$parseISAMPLER1DARRAY();
12585 if (s0 === peg$FAILED) {
12586 s0 = peg$parseISAMPLER2DARRAY();
12587 if (s0 === peg$FAILED) {
12588 s0 = peg$parseISAMPLERCUBEARRAY();
12589 if (s0 === peg$FAILED) {
12590 s0 = peg$parseUSAMPLER1D();
12591 if (s0 === peg$FAILED) {
12592 s0 = peg$parseUSAMPLER2D();
12593 if (s0 === peg$FAILED) {
12594 s0 = peg$parseUSAMPLER3D();
12595 if (s0 === peg$FAILED) {
12596 s0 = peg$parseUSAMPLERCUBE();
12597 if (s0 === peg$FAILED) {
12598 s0 = peg$parseUSAMPLER1DARRAY();
12599 if (s0 === peg$FAILED) {
12600 s0 = peg$parseUSAMPLER2DARRAY();
12601 if (s0 === peg$FAILED) {
12602 s0 = peg$parseUSAMPLERCUBEARRAY();
12603 if (s0 === peg$FAILED) {
12604 s0 = peg$parseSAMPLER2DRECT();
12605 if (s0 === peg$FAILED) {
12606 s0 = peg$parseSAMPLER2DRECTSHADOW();
12607 if (s0 === peg$FAILED) {
12608 s0 = peg$parseISAMPLER2DRECT();
12609 if (s0 === peg$FAILED) {
12610 s0 = peg$parseUSAMPLER2DRECT();
12611 if (s0 === peg$FAILED) {
12612 s0 = peg$parseSAMPLERBUFFER();
12613 if (s0 === peg$FAILED) {
12614 s0 = peg$parseISAMPLERBUFFER();
12615 if (s0 === peg$FAILED) {
12616 s0 = peg$parseUSAMPLERBUFFER();
12617 if (s0 === peg$FAILED) {
12618 s0 = peg$parseSAMPLER2DMS();
12619 if (s0 === peg$FAILED) {
12620 s0 = peg$parseISAMPLER2DMS();
12621 if (s0 === peg$FAILED) {
12622 s0 = peg$parseUSAMPLER2DMS();
12623 if (s0 === peg$FAILED) {
12624 s0 = peg$parseSAMPLER2DMSARRAY();
12625 if (s0 === peg$FAILED) {
12626 s0 = peg$parseISAMPLER2DMSARRAY();
12627 if (s0 === peg$FAILED) {
12628 s0 = peg$parseUSAMPLER2DMSARRAY();
12629 if (s0 === peg$FAILED) {
12630 s0 = peg$parseIMAGE1D();
12631 if (s0 === peg$FAILED) {
12632 s0 = peg$parseIIMAGE1D();
12633 if (s0 === peg$FAILED) {
12634 s0 = peg$parseUIMAGE1D();
12635 if (s0 === peg$FAILED) {
12636 s0 = peg$parseIMAGE2D();
12637 if (s0 === peg$FAILED) {
12638 s0 = peg$parseIIMAGE2D();
12639 if (s0 === peg$FAILED) {
12640 s0 = peg$parseUIMAGE2D();
12641 if (s0 === peg$FAILED) {
12642 s0 = peg$parseIMAGE3D();
12643 if (s0 === peg$FAILED) {
12644 s0 = peg$parseIIMAGE3D();
12645 if (s0 === peg$FAILED) {
12646 s0 = peg$parseUIMAGE3D();
12647 if (s0 === peg$FAILED) {
12648 s0 = peg$parseIMAGE2DRECT();
12649 if (s0 === peg$FAILED) {
12650 s0 = peg$parseIIMAGE2DRECT();
12651 if (s0 === peg$FAILED) {
12652 s0 = peg$parseUIMAGE2DRECT();
12653 if (s0 === peg$FAILED) {
12654 s0 = peg$parseIMAGECUBE();
12655 if (s0 === peg$FAILED) {
12656 s0 = peg$parseIIMAGECUBE();
12657 if (s0 === peg$FAILED) {
12658 s0 = peg$parseUIMAGECUBE();
12659 if (s0 === peg$FAILED) {
12660 s0 = peg$parseIMAGEBUFFER();
12661 if (s0 === peg$FAILED) {
12662 s0 = peg$parseIIMAGEBUFFER();
12663 if (s0 === peg$FAILED) {
12664 s0 = peg$parseUIMAGEBUFFER();
12665 if (s0 === peg$FAILED) {
12666 s0 = peg$parseIMAGE1DARRAY();
12667 if (s0 === peg$FAILED) {
12668 s0 = peg$parseIIMAGE1DARRAY();
12669 if (s0 === peg$FAILED) {
12670 s0 = peg$parseUIMAGE1DARRAY();
12671 if (s0 === peg$FAILED) {
12672 s0 = peg$parseIMAGE2DARRAY();
12673 if (s0 === peg$FAILED) {
12674 s0 = peg$parseIIMAGE2DARRAY();
12675 if (s0 === peg$FAILED) {
12676 s0 = peg$parseUIMAGE2DARRAY();
12677 if (s0 === peg$FAILED) {
12678 s0 = peg$parseIMAGECUBEARRAY();
12679 if (s0 === peg$FAILED) {
12680 s0 = peg$parseIIMAGECUBEARRAY();
12681 if (s0 === peg$FAILED) {
12682 s0 = peg$parseUIMAGECUBEARRAY();
12683 if (s0 === peg$FAILED) {
12684 s0 = peg$parseIMAGE2DMS();
12685 if (s0 === peg$FAILED) {
12686 s0 = peg$parseIIMAGE2DMS();
12687 if (s0 === peg$FAILED) {
12688 s0 = peg$parseUIMAGE2DMS();
12689 if (s0 === peg$FAILED) {
12690 s0 = peg$parseIMAGE2DMSARRAY();
12691 if (s0 === peg$FAILED) {
12692 s0 = peg$parseIIMAGE2DMSARRAY();
12693 if (s0 === peg$FAILED) {
12694 s0 = peg$parseUIMAGE2DMSARRAY();
12695 if (s0 === peg$FAILED) {
12696 s0 = peg$parsestruct_specifier();
12697 if (s0 === peg$FAILED) {
12698 s0 = peg$parseTYPE_NAME();
12699 }
12700 }
12701 }
12702 }
12703 }
12704 }
12705 }
12706 }
12707 }
12708 }
12709 }
12710 }
12711 }
12712 }
12713 }
12714 }
12715 }
12716 }
12717 }
12718 }
12719 }
12720 }
12721 }
12722 }
12723 }
12724 }
12725 }
12726 }
12727 }
12728 }
12729 }
12730 }
12731 }
12732 }
12733 }
12734 }
12735 }
12736 }
12737 }
12738 }
12739 }
12740 }
12741 }
12742 }
12743 }
12744 }
12745 }
12746 }
12747 }
12748 }
12749 }
12750 }
12751 }
12752 }
12753 }
12754 }
12755 }
12756 }
12757 }
12758 }
12759 }
12760 }
12761 }
12762 }
12763 }
12764 }
12765 }
12766 }
12767 }
12768 }
12769 }
12770 }
12771 }
12772 }
12773 }
12774 }
12775 }
12776 }
12777 }
12778 }
12779 }
12780 }
12781 }
12782 }
12783 }
12784 }
12785 }
12786 }
12787 }
12788 }
12789 }
12790 }
12791 }
12792 }
12793 }
12794 }
12795 }
12796 }
12797 }
12798 }
12799 }
12800 }
12801 }
12802 }
12803 }
12804 }
12805 }
12806 }
12807 }
12808 }
12809 }
12810 }
12811 }
12812 }
12813 }
12814 }
12815 }
12816 }
12817 }
12818 }
12819 peg$silentFails--;
12820 if (s0 === peg$FAILED) {
12821 s1 = peg$FAILED;
12822 if (peg$silentFails === 0) {
12823 peg$fail(peg$e239);
12824 }
12825 }
12826 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12827 return s0;
12828 }
12829 function peg$parsearray_specifiers() {
12830 var s0, s1, s2, s3, s4, s5;
12831 var key = peg$currPos * 306 + 275;
12832 var cached = peg$resultsCache[key];
12833 if (cached) {
12834 peg$currPos = cached.nextPos;
12835 return cached.result;
12836 }
12837 peg$silentFails++;
12838 s0 = peg$currPos;
12839 s1 = [];
12840 s2 = peg$currPos;
12841 s3 = peg$parseLEFT_BRACKET();
12842 if (s3 !== peg$FAILED) {
12843 s4 = peg$parseternary_expression();
12844 if (s4 === peg$FAILED) {
12845 s4 = null;
12846 }
12847 s5 = peg$parseRIGHT_BRACKET();
12848 if (s5 !== peg$FAILED) {
12849 peg$savedPos = s2;
12850 s2 = peg$f46(s3, s4, s5);
12851 } else {
12852 peg$currPos = s2;
12853 s2 = peg$FAILED;
12854 }
12855 } else {
12856 peg$currPos = s2;
12857 s2 = peg$FAILED;
12858 }
12859 if (s2 !== peg$FAILED) {
12860 while (s2 !== peg$FAILED) {
12861 s1.push(s2);
12862 s2 = peg$currPos;
12863 s3 = peg$parseLEFT_BRACKET();
12864 if (s3 !== peg$FAILED) {
12865 s4 = peg$parseternary_expression();
12866 if (s4 === peg$FAILED) {
12867 s4 = null;
12868 }
12869 s5 = peg$parseRIGHT_BRACKET();
12870 if (s5 !== peg$FAILED) {
12871 peg$savedPos = s2;
12872 s2 = peg$f46(s3, s4, s5);
12873 } else {
12874 peg$currPos = s2;
12875 s2 = peg$FAILED;
12876 }
12877 } else {
12878 peg$currPos = s2;
12879 s2 = peg$FAILED;
12880 }
12881 }
12882 } else {
12883 s1 = peg$FAILED;
12884 }
12885 if (s1 !== peg$FAILED) {
12886 peg$savedPos = s0;
12887 s1 = peg$f47(s1);
12888 }
12889 s0 = s1;
12890 peg$silentFails--;
12891 if (s0 === peg$FAILED) {
12892 s1 = peg$FAILED;
12893 if (peg$silentFails === 0) {
12894 peg$fail(peg$e240);
12895 }
12896 }
12897 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12898 return s0;
12899 }
12900 function peg$parseprecision_qualifier() {
12901 var s0, s1;
12902 var key = peg$currPos * 306 + 276;
12903 var cached = peg$resultsCache[key];
12904 if (cached) {
12905 peg$currPos = cached.nextPos;
12906 return cached.result;
12907 }
12908 peg$silentFails++;
12909 s0 = peg$parseHIGH_PRECISION();
12910 if (s0 === peg$FAILED) {
12911 s0 = peg$parseMEDIUM_PRECISION();
12912 if (s0 === peg$FAILED) {
12913 s0 = peg$parseLOW_PRECISION();
12914 }
12915 }
12916 peg$silentFails--;
12917 if (s0 === peg$FAILED) {
12918 s1 = peg$FAILED;
12919 if (peg$silentFails === 0) {
12920 peg$fail(peg$e241);
12921 }
12922 }
12923 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12924 return s0;
12925 }
12926 function peg$parsestruct_specifier() {
12927 var s0, s1, s2, s3, s4, s5;
12928 var key = peg$currPos * 306 + 277;
12929 var cached = peg$resultsCache[key];
12930 if (cached) {
12931 peg$currPos = cached.nextPos;
12932 return cached.result;
12933 }
12934 peg$silentFails++;
12935 s0 = peg$currPos;
12936 s1 = peg$parseSTRUCT();
12937 if (s1 !== peg$FAILED) {
12938 s2 = peg$parseTYPE_NAME();
12939 if (s2 === peg$FAILED) {
12940 s2 = null;
12941 }
12942 s3 = peg$parseLEFT_BRACE();
12943 if (s3 !== peg$FAILED) {
12944 s4 = peg$parsestruct_declaration_list();
12945 if (s4 !== peg$FAILED) {
12946 s5 = peg$parseRIGHT_BRACE();
12947 if (s5 !== peg$FAILED) {
12948 peg$savedPos = s0;
12949 s0 = peg$f48(s1, s2, s3, s4, s5);
12950 } else {
12951 peg$currPos = s0;
12952 s0 = peg$FAILED;
12953 }
12954 } else {
12955 peg$currPos = s0;
12956 s0 = peg$FAILED;
12957 }
12958 } else {
12959 peg$currPos = s0;
12960 s0 = peg$FAILED;
12961 }
12962 } else {
12963 peg$currPos = s0;
12964 s0 = peg$FAILED;
12965 }
12966 peg$silentFails--;
12967 if (s0 === peg$FAILED) {
12968 s1 = peg$FAILED;
12969 if (peg$silentFails === 0) {
12970 peg$fail(peg$e242);
12971 }
12972 }
12973 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
12974 return s0;
12975 }
12976 function peg$parsestruct_declaration_list() {
12977 var s0, s1, s2, s3;
12978 var key = peg$currPos * 306 + 278;
12979 var cached = peg$resultsCache[key];
12980 if (cached) {
12981 peg$currPos = cached.nextPos;
12982 return cached.result;
12983 }
12984 s0 = [];
12985 s1 = peg$currPos;
12986 s2 = peg$parsestruct_declaration();
12987 if (s2 !== peg$FAILED) {
12988 s3 = peg$parseSEMICOLON();
12989 if (s3 !== peg$FAILED) {
12990 peg$savedPos = s1;
12991 s1 = peg$f49(s2, s3);
12992 } else {
12993 peg$currPos = s1;
12994 s1 = peg$FAILED;
12995 }
12996 } else {
12997 peg$currPos = s1;
12998 s1 = peg$FAILED;
12999 }
13000 if (s1 !== peg$FAILED) {
13001 while (s1 !== peg$FAILED) {
13002 s0.push(s1);
13003 s1 = peg$currPos;
13004 s2 = peg$parsestruct_declaration();
13005 if (s2 !== peg$FAILED) {
13006 s3 = peg$parseSEMICOLON();
13007 if (s3 !== peg$FAILED) {
13008 peg$savedPos = s1;
13009 s1 = peg$f49(s2, s3);
13010 } else {
13011 peg$currPos = s1;
13012 s1 = peg$FAILED;
13013 }
13014 } else {
13015 peg$currPos = s1;
13016 s1 = peg$FAILED;
13017 }
13018 }
13019 } else {
13020 s0 = peg$FAILED;
13021 }
13022 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13023 return s0;
13024 }
13025 function peg$parsestruct_declaration() {
13026 var s0, s1, s2, s3, s4, s5, s6;
13027 var key = peg$currPos * 306 + 279;
13028 var cached = peg$resultsCache[key];
13029 if (cached) {
13030 peg$currPos = cached.nextPos;
13031 return cached.result;
13032 }
13033 s0 = peg$currPos;
13034 s1 = peg$parsefully_specified_type();
13035 if (s1 !== peg$FAILED) {
13036 s2 = peg$parsequantified_identifier();
13037 if (s2 !== peg$FAILED) {
13038 s3 = [];
13039 s4 = peg$currPos;
13040 s5 = peg$parseCOMMA();
13041 if (s5 !== peg$FAILED) {
13042 s6 = peg$parsequantified_identifier();
13043 if (s6 !== peg$FAILED) {
13044 s5 = [s5, s6];
13045 s4 = s5;
13046 } else {
13047 peg$currPos = s4;
13048 s4 = peg$FAILED;
13049 }
13050 } else {
13051 peg$currPos = s4;
13052 s4 = peg$FAILED;
13053 }
13054 while (s4 !== peg$FAILED) {
13055 s3.push(s4);
13056 s4 = peg$currPos;
13057 s5 = peg$parseCOMMA();
13058 if (s5 !== peg$FAILED) {
13059 s6 = peg$parsequantified_identifier();
13060 if (s6 !== peg$FAILED) {
13061 s5 = [s5, s6];
13062 s4 = s5;
13063 } else {
13064 peg$currPos = s4;
13065 s4 = peg$FAILED;
13066 }
13067 } else {
13068 peg$currPos = s4;
13069 s4 = peg$FAILED;
13070 }
13071 }
13072 peg$savedPos = s0;
13073 s0 = peg$f50(s1, s2, s3);
13074 } else {
13075 peg$currPos = s0;
13076 s0 = peg$FAILED;
13077 }
13078 } else {
13079 peg$currPos = s0;
13080 s0 = peg$FAILED;
13081 }
13082 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13083 return s0;
13084 }
13085 function peg$parsequantified_identifier() {
13086 var s0, s1, s2;
13087 var key = peg$currPos * 306 + 280;
13088 var cached = peg$resultsCache[key];
13089 if (cached) {
13090 peg$currPos = cached.nextPos;
13091 return cached.result;
13092 }
13093 s0 = peg$currPos;
13094 s1 = peg$parseIDENTIFIER();
13095 if (s1 !== peg$FAILED) {
13096 s2 = peg$parsearray_specifiers();
13097 if (s2 === peg$FAILED) {
13098 s2 = null;
13099 }
13100 peg$savedPos = s0;
13101 s0 = peg$f51(s1, s2);
13102 } else {
13103 peg$currPos = s0;
13104 s0 = peg$FAILED;
13105 }
13106 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13107 return s0;
13108 }
13109 function peg$parseinitializer() {
13110 var s0, s1, s2, s3, s4, s5, s6;
13111 var key = peg$currPos * 306 + 281;
13112 var cached = peg$resultsCache[key];
13113 if (cached) {
13114 peg$currPos = cached.nextPos;
13115 return cached.result;
13116 }
13117 s0 = peg$parseassignment_expression();
13118 if (s0 === peg$FAILED) {
13119 s0 = peg$currPos;
13120 s1 = peg$parseLEFT_BRACE();
13121 if (s1 !== peg$FAILED) {
13122 s2 = peg$parseinitializer();
13123 if (s2 !== peg$FAILED) {
13124 s3 = [];
13125 s4 = peg$currPos;
13126 s5 = peg$parseCOMMA();
13127 if (s5 !== peg$FAILED) {
13128 s6 = peg$parseinitializer();
13129 if (s6 !== peg$FAILED) {
13130 s5 = [s5, s6];
13131 s4 = s5;
13132 } else {
13133 peg$currPos = s4;
13134 s4 = peg$FAILED;
13135 }
13136 } else {
13137 peg$currPos = s4;
13138 s4 = peg$FAILED;
13139 }
13140 while (s4 !== peg$FAILED) {
13141 s3.push(s4);
13142 s4 = peg$currPos;
13143 s5 = peg$parseCOMMA();
13144 if (s5 !== peg$FAILED) {
13145 s6 = peg$parseinitializer();
13146 if (s6 !== peg$FAILED) {
13147 s5 = [s5, s6];
13148 s4 = s5;
13149 } else {
13150 peg$currPos = s4;
13151 s4 = peg$FAILED;
13152 }
13153 } else {
13154 peg$currPos = s4;
13155 s4 = peg$FAILED;
13156 }
13157 }
13158 s4 = peg$parseCOMMA();
13159 if (s4 === peg$FAILED) {
13160 s4 = null;
13161 }
13162 s5 = peg$parseRIGHT_BRACE();
13163 if (s5 !== peg$FAILED) {
13164 peg$savedPos = s0;
13165 s0 = peg$f52(s1, s2, s3, s4, s5);
13166 } else {
13167 peg$currPos = s0;
13168 s0 = peg$FAILED;
13169 }
13170 } else {
13171 peg$currPos = s0;
13172 s0 = peg$FAILED;
13173 }
13174 } else {
13175 peg$currPos = s0;
13176 s0 = peg$FAILED;
13177 }
13178 }
13179 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13180 return s0;
13181 }
13182 function peg$parsestatement() {
13183 var s0;
13184 var key = peg$currPos * 306 + 282;
13185 var cached = peg$resultsCache[key];
13186 if (cached) {
13187 peg$currPos = cached.nextPos;
13188 return cached.result;
13189 }
13190 s0 = peg$parsecompound_statement();
13191 if (s0 === peg$FAILED) {
13192 s0 = peg$parsesimple_statement();
13193 }
13194 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13195 return s0;
13196 }
13197 function peg$parsesimple_statement() {
13198 var s0;
13199 var key = peg$currPos * 306 + 283;
13200 var cached = peg$resultsCache[key];
13201 if (cached) {
13202 peg$currPos = cached.nextPos;
13203 return cached.result;
13204 }
13205 s0 = peg$parsejump_statement();
13206 if (s0 === peg$FAILED) {
13207 s0 = peg$parsedeclaration_statement();
13208 if (s0 === peg$FAILED) {
13209 s0 = peg$parseexpression_statement();
13210 if (s0 === peg$FAILED) {
13211 s0 = peg$parseif_statement();
13212 if (s0 === peg$FAILED) {
13213 s0 = peg$parseswitch_statement();
13214 if (s0 === peg$FAILED) {
13215 s0 = peg$parsecase_label();
13216 if (s0 === peg$FAILED) {
13217 s0 = peg$parseiteration_statement();
13218 }
13219 }
13220 }
13221 }
13222 }
13223 }
13224 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13225 return s0;
13226 }
13227 function peg$parsecompound_statement() {
13228 var s0, s1, s2, s3;
13229 var key = peg$currPos * 306 + 284;
13230 var cached = peg$resultsCache[key];
13231 if (cached) {
13232 peg$currPos = cached.nextPos;
13233 return cached.result;
13234 }
13235 s0 = peg$currPos;
13236 s1 = peg$currPos;
13237 s2 = peg$parseLEFT_BRACE();
13238 if (s2 !== peg$FAILED) {
13239 peg$savedPos = s1;
13240 s2 = peg$f53(s2);
13241 }
13242 s1 = s2;
13243 if (s1 !== peg$FAILED) {
13244 s2 = peg$parsestatement_list();
13245 if (s2 === peg$FAILED) {
13246 s2 = null;
13247 }
13248 s3 = peg$parseRIGHT_BRACE();
13249 if (s3 !== peg$FAILED) {
13250 peg$savedPos = s0;
13251 s0 = peg$f54(s1, s2, s3);
13252 } else {
13253 peg$currPos = s0;
13254 s0 = peg$FAILED;
13255 }
13256 } else {
13257 peg$currPos = s0;
13258 s0 = peg$FAILED;
13259 }
13260 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13261 return s0;
13262 }
13263 function peg$parsecompound_statement_no_new_scope() {
13264 var s0, s1, s2, s3;
13265 var key = peg$currPos * 306 + 285;
13266 var cached = peg$resultsCache[key];
13267 if (cached) {
13268 peg$currPos = cached.nextPos;
13269 return cached.result;
13270 }
13271 s0 = peg$currPos;
13272 s1 = peg$parseLEFT_BRACE();
13273 if (s1 !== peg$FAILED) {
13274 s2 = peg$parsestatement_list();
13275 if (s2 === peg$FAILED) {
13276 s2 = null;
13277 }
13278 s3 = peg$parseRIGHT_BRACE();
13279 if (s3 !== peg$FAILED) {
13280 peg$savedPos = s0;
13281 s0 = peg$f55(s1, s2, s3);
13282 } else {
13283 peg$currPos = s0;
13284 s0 = peg$FAILED;
13285 }
13286 } else {
13287 peg$currPos = s0;
13288 s0 = peg$FAILED;
13289 }
13290 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13291 return s0;
13292 }
13293 function peg$parsestatement_no_new_scope() {
13294 var s0;
13295 var key = peg$currPos * 306 + 286;
13296 var cached = peg$resultsCache[key];
13297 if (cached) {
13298 peg$currPos = cached.nextPos;
13299 return cached.result;
13300 }
13301 s0 = peg$parsecompound_statement_no_new_scope();
13302 if (s0 === peg$FAILED) {
13303 s0 = peg$parsesimple_statement();
13304 }
13305 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13306 return s0;
13307 }
13308 function peg$parsestatement_list() {
13309 var s0, s1;
13310 var key = peg$currPos * 306 + 287;
13311 var cached = peg$resultsCache[key];
13312 if (cached) {
13313 peg$currPos = cached.nextPos;
13314 return cached.result;
13315 }
13316 s0 = [];
13317 s1 = peg$parsestatement();
13318 if (s1 === peg$FAILED) {
13319 s1 = peg$parsepreprocessor();
13320 }
13321 if (s1 !== peg$FAILED) {
13322 while (s1 !== peg$FAILED) {
13323 s0.push(s1);
13324 s1 = peg$parsestatement();
13325 if (s1 === peg$FAILED) {
13326 s1 = peg$parsepreprocessor();
13327 }
13328 }
13329 } else {
13330 s0 = peg$FAILED;
13331 }
13332 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13333 return s0;
13334 }
13335 function peg$parseexpression_statement() {
13336 var s0, s1, s2;
13337 var key = peg$currPos * 306 + 288;
13338 var cached = peg$resultsCache[key];
13339 if (cached) {
13340 peg$currPos = cached.nextPos;
13341 return cached.result;
13342 }
13343 s0 = peg$currPos;
13344 s1 = peg$parseexpression();
13345 if (s1 === peg$FAILED) {
13346 s1 = null;
13347 }
13348 s2 = peg$parseSEMICOLON();
13349 if (s2 !== peg$FAILED) {
13350 peg$savedPos = s0;
13351 s0 = peg$f56(s1, s2);
13352 } else {
13353 peg$currPos = s0;
13354 s0 = peg$FAILED;
13355 }
13356 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13357 return s0;
13358 }
13359 function peg$parseif_statement() {
13360 var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9;
13361 var key = peg$currPos * 306 + 289;
13362 var cached = peg$resultsCache[key];
13363 if (cached) {
13364 peg$currPos = cached.nextPos;
13365 return cached.result;
13366 }
13367 s0 = peg$currPos;
13368 s1 = peg$parseIF();
13369 if (s1 !== peg$FAILED) {
13370 s2 = peg$parseLEFT_PAREN();
13371 if (s2 !== peg$FAILED) {
13372 s3 = peg$parseexpression();
13373 if (s3 !== peg$FAILED) {
13374 s4 = peg$parseRIGHT_PAREN();
13375 if (s4 !== peg$FAILED) {
13376 s5 = peg$currPos;
13377 s6 = peg$parsestatement();
13378 if (s6 !== peg$FAILED) {
13379 s7 = peg$currPos;
13380 s8 = peg$parseELSE();
13381 if (s8 !== peg$FAILED) {
13382 s9 = peg$parsestatement();
13383 if (s9 !== peg$FAILED) {
13384 s8 = [s8, s9];
13385 s7 = s8;
13386 } else {
13387 peg$currPos = s7;
13388 s7 = peg$FAILED;
13389 }
13390 } else {
13391 peg$currPos = s7;
13392 s7 = peg$FAILED;
13393 }
13394 if (s7 === peg$FAILED) {
13395 s7 = null;
13396 }
13397 s6 = [s6, s7];
13398 s5 = s6;
13399 } else {
13400 peg$currPos = s5;
13401 s5 = peg$FAILED;
13402 }
13403 if (s5 !== peg$FAILED) {
13404 peg$savedPos = s0;
13405 s0 = peg$f57(s1, s2, s3, s4, s5);
13406 } else {
13407 peg$currPos = s0;
13408 s0 = peg$FAILED;
13409 }
13410 } else {
13411 peg$currPos = s0;
13412 s0 = peg$FAILED;
13413 }
13414 } else {
13415 peg$currPos = s0;
13416 s0 = peg$FAILED;
13417 }
13418 } else {
13419 peg$currPos = s0;
13420 s0 = peg$FAILED;
13421 }
13422 } else {
13423 peg$currPos = s0;
13424 s0 = peg$FAILED;
13425 }
13426 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13427 return s0;
13428 }
13429 function peg$parseswitch_statement() {
13430 var s0, s1, s2, s3, s4, s5, s6, s7;
13431 var key = peg$currPos * 306 + 290;
13432 var cached = peg$resultsCache[key];
13433 if (cached) {
13434 peg$currPos = cached.nextPos;
13435 return cached.result;
13436 }
13437 s0 = peg$currPos;
13438 s1 = peg$parseSWITCH();
13439 if (s1 !== peg$FAILED) {
13440 s2 = peg$parseLEFT_PAREN();
13441 if (s2 !== peg$FAILED) {
13442 s3 = peg$parseexpression();
13443 if (s3 !== peg$FAILED) {
13444 s4 = peg$parseRIGHT_PAREN();
13445 if (s4 !== peg$FAILED) {
13446 s5 = peg$parseLEFT_BRACE();
13447 if (s5 !== peg$FAILED) {
13448 s6 = peg$parsestatement_list();
13449 if (s6 !== peg$FAILED) {
13450 s7 = peg$parseRIGHT_BRACE();
13451 if (s7 !== peg$FAILED) {
13452 peg$savedPos = s0;
13453 s0 = peg$f58(s1, s2, s3, s4, s5, s6, s7);
13454 } else {
13455 peg$currPos = s0;
13456 s0 = peg$FAILED;
13457 }
13458 } else {
13459 peg$currPos = s0;
13460 s0 = peg$FAILED;
13461 }
13462 } else {
13463 peg$currPos = s0;
13464 s0 = peg$FAILED;
13465 }
13466 } else {
13467 peg$currPos = s0;
13468 s0 = peg$FAILED;
13469 }
13470 } else {
13471 peg$currPos = s0;
13472 s0 = peg$FAILED;
13473 }
13474 } else {
13475 peg$currPos = s0;
13476 s0 = peg$FAILED;
13477 }
13478 } else {
13479 peg$currPos = s0;
13480 s0 = peg$FAILED;
13481 }
13482 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13483 return s0;
13484 }
13485 function peg$parsecase_label() {
13486 var s0, s1, s2, s3;
13487 var key = peg$currPos * 306 + 291;
13488 var cached = peg$resultsCache[key];
13489 if (cached) {
13490 peg$currPos = cached.nextPos;
13491 return cached.result;
13492 }
13493 s0 = peg$currPos;
13494 s1 = peg$parseCASE();
13495 if (s1 !== peg$FAILED) {
13496 s2 = peg$parseexpression();
13497 if (s2 !== peg$FAILED) {
13498 s3 = peg$parseCOLON();
13499 if (s3 !== peg$FAILED) {
13500 peg$savedPos = s0;
13501 s0 = peg$f59(s1, s2, s3);
13502 } else {
13503 peg$currPos = s0;
13504 s0 = peg$FAILED;
13505 }
13506 } else {
13507 peg$currPos = s0;
13508 s0 = peg$FAILED;
13509 }
13510 } else {
13511 peg$currPos = s0;
13512 s0 = peg$FAILED;
13513 }
13514 if (s0 === peg$FAILED) {
13515 s0 = peg$currPos;
13516 s1 = peg$parseDEFAULT();
13517 if (s1 !== peg$FAILED) {
13518 s2 = peg$parseCOLON();
13519 if (s2 !== peg$FAILED) {
13520 peg$savedPos = s0;
13521 s0 = peg$f60(s1, s2);
13522 } else {
13523 peg$currPos = s0;
13524 s0 = peg$FAILED;
13525 }
13526 } else {
13527 peg$currPos = s0;
13528 s0 = peg$FAILED;
13529 }
13530 }
13531 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13532 return s0;
13533 }
13534 function peg$parseiteration_statement() {
13535 var s0, s1, s2, s3, s4, s5, s6, s7, s8;
13536 var key = peg$currPos * 306 + 292;
13537 var cached = peg$resultsCache[key];
13538 if (cached) {
13539 peg$currPos = cached.nextPos;
13540 return cached.result;
13541 }
13542 peg$silentFails++;
13543 s0 = peg$currPos;
13544 s1 = peg$currPos;
13545 s2 = peg$parseWHILE();
13546 if (s2 !== peg$FAILED) {
13547 peg$savedPos = s1;
13548 s2 = peg$f61(s2);
13549 }
13550 s1 = s2;
13551 if (s1 !== peg$FAILED) {
13552 s2 = peg$parseLEFT_PAREN();
13553 if (s2 !== peg$FAILED) {
13554 s3 = peg$parsecondition();
13555 if (s3 !== peg$FAILED) {
13556 s4 = peg$parseRIGHT_PAREN();
13557 if (s4 !== peg$FAILED) {
13558 s5 = peg$parsestatement_no_new_scope();
13559 if (s5 !== peg$FAILED) {
13560 peg$savedPos = s0;
13561 s0 = peg$f62(s1, s2, s3, s4, s5);
13562 } else {
13563 peg$currPos = s0;
13564 s0 = peg$FAILED;
13565 }
13566 } else {
13567 peg$currPos = s0;
13568 s0 = peg$FAILED;
13569 }
13570 } else {
13571 peg$currPos = s0;
13572 s0 = peg$FAILED;
13573 }
13574 } else {
13575 peg$currPos = s0;
13576 s0 = peg$FAILED;
13577 }
13578 } else {
13579 peg$currPos = s0;
13580 s0 = peg$FAILED;
13581 }
13582 if (s0 === peg$FAILED) {
13583 s0 = peg$currPos;
13584 s1 = peg$parseDO();
13585 if (s1 !== peg$FAILED) {
13586 s2 = peg$parsestatement();
13587 if (s2 !== peg$FAILED) {
13588 s3 = peg$parseWHILE();
13589 if (s3 !== peg$FAILED) {
13590 s4 = peg$parseLEFT_PAREN();
13591 if (s4 !== peg$FAILED) {
13592 s5 = peg$parseexpression();
13593 if (s5 !== peg$FAILED) {
13594 s6 = peg$parseRIGHT_PAREN();
13595 if (s6 !== peg$FAILED) {
13596 s7 = peg$parseSEMICOLON();
13597 if (s7 !== peg$FAILED) {
13598 peg$savedPos = s0;
13599 s0 = peg$f63(s1, s2, s3, s4, s5, s6, s7);
13600 } else {
13601 peg$currPos = s0;
13602 s0 = peg$FAILED;
13603 }
13604 } else {
13605 peg$currPos = s0;
13606 s0 = peg$FAILED;
13607 }
13608 } else {
13609 peg$currPos = s0;
13610 s0 = peg$FAILED;
13611 }
13612 } else {
13613 peg$currPos = s0;
13614 s0 = peg$FAILED;
13615 }
13616 } else {
13617 peg$currPos = s0;
13618 s0 = peg$FAILED;
13619 }
13620 } else {
13621 peg$currPos = s0;
13622 s0 = peg$FAILED;
13623 }
13624 } else {
13625 peg$currPos = s0;
13626 s0 = peg$FAILED;
13627 }
13628 if (s0 === peg$FAILED) {
13629 s0 = peg$currPos;
13630 s1 = peg$currPos;
13631 s2 = peg$parseFOR();
13632 if (s2 !== peg$FAILED) {
13633 peg$savedPos = s1;
13634 s2 = peg$f64(s2);
13635 }
13636 s1 = s2;
13637 if (s1 !== peg$FAILED) {
13638 s2 = peg$parseLEFT_PAREN();
13639 if (s2 !== peg$FAILED) {
13640 s3 = peg$parseexpression_statement();
13641 if (s3 === peg$FAILED) {
13642 s3 = peg$parsedeclaration_statement();
13643 }
13644 if (s3 === peg$FAILED) {
13645 s3 = null;
13646 }
13647 s4 = peg$parsecondition();
13648 if (s4 === peg$FAILED) {
13649 s4 = null;
13650 }
13651 s5 = peg$parseSEMICOLON();
13652 if (s5 !== peg$FAILED) {
13653 s6 = peg$parseexpression();
13654 if (s6 === peg$FAILED) {
13655 s6 = null;
13656 }
13657 s7 = peg$parseRIGHT_PAREN();
13658 if (s7 !== peg$FAILED) {
13659 s8 = peg$parsestatement_no_new_scope();
13660 if (s8 !== peg$FAILED) {
13661 peg$savedPos = s0;
13662 s0 = peg$f65(s1, s2, s3, s4, s5, s6, s7, s8);
13663 } else {
13664 peg$currPos = s0;
13665 s0 = peg$FAILED;
13666 }
13667 } else {
13668 peg$currPos = s0;
13669 s0 = peg$FAILED;
13670 }
13671 } else {
13672 peg$currPos = s0;
13673 s0 = peg$FAILED;
13674 }
13675 } else {
13676 peg$currPos = s0;
13677 s0 = peg$FAILED;
13678 }
13679 } else {
13680 peg$currPos = s0;
13681 s0 = peg$FAILED;
13682 }
13683 }
13684 }
13685 peg$silentFails--;
13686 if (s0 === peg$FAILED) {
13687 s1 = peg$FAILED;
13688 if (peg$silentFails === 0) {
13689 peg$fail(peg$e243);
13690 }
13691 }
13692 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13693 return s0;
13694 }
13695 function peg$parsecondition() {
13696 var s0, s1, s2, s3, s4;
13697 var key = peg$currPos * 306 + 293;
13698 var cached = peg$resultsCache[key];
13699 if (cached) {
13700 peg$currPos = cached.nextPos;
13701 return cached.result;
13702 }
13703 s0 = peg$currPos;
13704 s1 = peg$parsefully_specified_type();
13705 if (s1 !== peg$FAILED) {
13706 s2 = peg$parseIDENTIFIER();
13707 if (s2 !== peg$FAILED) {
13708 s3 = peg$parseEQUAL();
13709 if (s3 !== peg$FAILED) {
13710 s4 = peg$parseinitializer();
13711 if (s4 !== peg$FAILED) {
13712 peg$savedPos = s0;
13713 s0 = peg$f66(s1, s2, s3, s4);
13714 } else {
13715 peg$currPos = s0;
13716 s0 = peg$FAILED;
13717 }
13718 } else {
13719 peg$currPos = s0;
13720 s0 = peg$FAILED;
13721 }
13722 } else {
13723 peg$currPos = s0;
13724 s0 = peg$FAILED;
13725 }
13726 } else {
13727 peg$currPos = s0;
13728 s0 = peg$FAILED;
13729 }
13730 if (s0 === peg$FAILED) {
13731 s0 = peg$parseexpression();
13732 }
13733 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13734 return s0;
13735 }
13736 function peg$parsejump_statement() {
13737 var s0, s1, s2, s3;
13738 var key = peg$currPos * 306 + 294;
13739 var cached = peg$resultsCache[key];
13740 if (cached) {
13741 peg$currPos = cached.nextPos;
13742 return cached.result;
13743 }
13744 peg$silentFails++;
13745 s0 = peg$currPos;
13746 s1 = peg$parseCONTINUE();
13747 if (s1 !== peg$FAILED) {
13748 s2 = peg$parseSEMICOLON();
13749 if (s2 !== peg$FAILED) {
13750 peg$savedPos = s0;
13751 s0 = peg$f67(s1, s2);
13752 } else {
13753 peg$currPos = s0;
13754 s0 = peg$FAILED;
13755 }
13756 } else {
13757 peg$currPos = s0;
13758 s0 = peg$FAILED;
13759 }
13760 if (s0 === peg$FAILED) {
13761 s0 = peg$currPos;
13762 s1 = peg$parseBREAK();
13763 if (s1 !== peg$FAILED) {
13764 s2 = peg$parseSEMICOLON();
13765 if (s2 !== peg$FAILED) {
13766 peg$savedPos = s0;
13767 s0 = peg$f68(s1, s2);
13768 } else {
13769 peg$currPos = s0;
13770 s0 = peg$FAILED;
13771 }
13772 } else {
13773 peg$currPos = s0;
13774 s0 = peg$FAILED;
13775 }
13776 if (s0 === peg$FAILED) {
13777 s0 = peg$currPos;
13778 s1 = peg$parseRETURN();
13779 if (s1 !== peg$FAILED) {
13780 s2 = peg$parseexpression();
13781 if (s2 === peg$FAILED) {
13782 s2 = null;
13783 }
13784 s3 = peg$parseSEMICOLON();
13785 if (s3 !== peg$FAILED) {
13786 peg$savedPos = s0;
13787 s0 = peg$f69(s1, s2, s3);
13788 } else {
13789 peg$currPos = s0;
13790 s0 = peg$FAILED;
13791 }
13792 } else {
13793 peg$currPos = s0;
13794 s0 = peg$FAILED;
13795 }
13796 if (s0 === peg$FAILED) {
13797 s0 = peg$currPos;
13798 s1 = peg$parseDISCARD();
13799 if (s1 !== peg$FAILED) {
13800 s2 = peg$parseSEMICOLON();
13801 if (s2 !== peg$FAILED) {
13802 peg$savedPos = s0;
13803 s0 = peg$f70(s1, s2);
13804 } else {
13805 peg$currPos = s0;
13806 s0 = peg$FAILED;
13807 }
13808 } else {
13809 peg$currPos = s0;
13810 s0 = peg$FAILED;
13811 }
13812 }
13813 }
13814 }
13815 peg$silentFails--;
13816 if (s0 === peg$FAILED) {
13817 s1 = peg$FAILED;
13818 if (peg$silentFails === 0) {
13819 peg$fail(peg$e244);
13820 }
13821 }
13822 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13823 return s0;
13824 }
13825 function peg$parsepreprocessor() {
13826 var s0, s1, s2, s3, s4, s5;
13827 var key = peg$currPos * 306 + 295;
13828 var cached = peg$resultsCache[key];
13829 if (cached) {
13830 peg$currPos = cached.nextPos;
13831 return cached.result;
13832 }
13833 peg$silentFails++;
13834 s0 = peg$currPos;
13835 s1 = peg$currPos;
13836 s2 = peg$currPos;
13837 if (input.charCodeAt(peg$currPos) === 35) {
13838 s3 = peg$c210;
13839 peg$currPos++;
13840 } else {
13841 s3 = peg$FAILED;
13842 if (peg$silentFails === 0) {
13843 peg$fail(peg$e246);
13844 }
13845 }
13846 if (s3 !== peg$FAILED) {
13847 s4 = [];
13848 if (peg$r11.test(input.charAt(peg$currPos))) {
13849 s5 = input.charAt(peg$currPos);
13850 peg$currPos++;
13851 } else {
13852 s5 = peg$FAILED;
13853 if (peg$silentFails === 0) {
13854 peg$fail(peg$e247);
13855 }
13856 }
13857 while (s5 !== peg$FAILED) {
13858 s4.push(s5);
13859 if (peg$r11.test(input.charAt(peg$currPos))) {
13860 s5 = input.charAt(peg$currPos);
13861 peg$currPos++;
13862 } else {
13863 s5 = peg$FAILED;
13864 if (peg$silentFails === 0) {
13865 peg$fail(peg$e247);
13866 }
13867 }
13868 }
13869 s3 = [s3, s4];
13870 s2 = s3;
13871 } else {
13872 peg$currPos = s2;
13873 s2 = peg$FAILED;
13874 }
13875 if (s2 !== peg$FAILED) {
13876 s1 = input.substring(s1, peg$currPos);
13877 } else {
13878 s1 = s2;
13879 }
13880 if (s1 !== peg$FAILED) {
13881 s2 = peg$parse_();
13882 peg$savedPos = s0;
13883 s0 = peg$f71(s1, s2);
13884 } else {
13885 peg$currPos = s0;
13886 s0 = peg$FAILED;
13887 }
13888 peg$silentFails--;
13889 if (s0 === peg$FAILED) {
13890 s1 = peg$FAILED;
13891 if (peg$silentFails === 0) {
13892 peg$fail(peg$e245);
13893 }
13894 }
13895 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13896 return s0;
13897 }
13898 function peg$parsetranslation_unit() {
13899 var s0, s1;
13900 var key = peg$currPos * 306 + 296;
13901 var cached = peg$resultsCache[key];
13902 if (cached) {
13903 peg$currPos = cached.nextPos;
13904 return cached.result;
13905 }
13906 s0 = [];
13907 s1 = peg$parseexternal_declaration();
13908 if (s1 === peg$FAILED) {
13909 s1 = peg$parsepreprocessor();
13910 }
13911 if (s1 !== peg$FAILED) {
13912 while (s1 !== peg$FAILED) {
13913 s0.push(s1);
13914 s1 = peg$parseexternal_declaration();
13915 if (s1 === peg$FAILED) {
13916 s1 = peg$parsepreprocessor();
13917 }
13918 }
13919 } else {
13920 s0 = peg$FAILED;
13921 }
13922 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13923 return s0;
13924 }
13925 function peg$parsefunction_prototype_statement() {
13926 var s0, s1, s2;
13927 var key = peg$currPos * 306 + 297;
13928 var cached = peg$resultsCache[key];
13929 if (cached) {
13930 peg$currPos = cached.nextPos;
13931 return cached.result;
13932 }
13933 s0 = peg$currPos;
13934 s1 = peg$parsefunction_prototype_no_new_scope();
13935 if (s1 !== peg$FAILED) {
13936 s2 = peg$parseSEMICOLON();
13937 if (s2 !== peg$FAILED) {
13938 peg$savedPos = s0;
13939 s0 = peg$f72(s1, s2);
13940 } else {
13941 peg$currPos = s0;
13942 s0 = peg$FAILED;
13943 }
13944 } else {
13945 peg$currPos = s0;
13946 s0 = peg$FAILED;
13947 }
13948 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13949 return s0;
13950 }
13951 function peg$parseexternal_declaration() {
13952 var s0;
13953 var key = peg$currPos * 306 + 298;
13954 var cached = peg$resultsCache[key];
13955 if (cached) {
13956 peg$currPos = cached.nextPos;
13957 return cached.result;
13958 }
13959 s0 = peg$parsefunction_prototype_statement();
13960 if (s0 === peg$FAILED) {
13961 s0 = peg$parsefunction_definition();
13962 if (s0 === peg$FAILED) {
13963 s0 = peg$parsedeclaration_statement();
13964 }
13965 }
13966 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13967 return s0;
13968 }
13969 function peg$parsefunction_definition() {
13970 var s0, s1, s2;
13971 var key = peg$currPos * 306 + 299;
13972 var cached = peg$resultsCache[key];
13973 if (cached) {
13974 peg$currPos = cached.nextPos;
13975 return cached.result;
13976 }
13977 s0 = peg$currPos;
13978 s1 = peg$parsefunction_prototype_new_scope();
13979 if (s1 !== peg$FAILED) {
13980 s2 = peg$parsecompound_statement_no_new_scope();
13981 if (s2 !== peg$FAILED) {
13982 peg$savedPos = s0;
13983 s0 = peg$f73(s1, s2);
13984 } else {
13985 peg$currPos = s0;
13986 s0 = peg$FAILED;
13987 }
13988 } else {
13989 peg$currPos = s0;
13990 s0 = peg$FAILED;
13991 }
13992 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
13993 return s0;
13994 }
13995 function peg$parse_() {
13996 var s0, s1, s2, s3, s4, s5;
13997 var key = peg$currPos * 306 + 300;
13998 var cached = peg$resultsCache[key];
13999 if (cached) {
14000 peg$currPos = cached.nextPos;
14001 return cached.result;
14002 }
14003 peg$silentFails++;
14004 s0 = peg$currPos;
14005 s1 = peg$parsewhitespace();
14006 if (s1 === peg$FAILED) {
14007 s1 = null;
14008 }
14009 s2 = [];
14010 s3 = peg$currPos;
14011 s4 = peg$parsecomment();
14012 if (s4 !== peg$FAILED) {
14013 s5 = peg$parsewhitespace();
14014 if (s5 === peg$FAILED) {
14015 s5 = null;
14016 }
14017 s4 = [s4, s5];
14018 s3 = s4;
14019 } else {
14020 peg$currPos = s3;
14021 s3 = peg$FAILED;
14022 }
14023 while (s3 !== peg$FAILED) {
14024 s2.push(s3);
14025 s3 = peg$currPos;
14026 s4 = peg$parsecomment();
14027 if (s4 !== peg$FAILED) {
14028 s5 = peg$parsewhitespace();
14029 if (s5 === peg$FAILED) {
14030 s5 = null;
14031 }
14032 s4 = [s4, s5];
14033 s3 = s4;
14034 } else {
14035 peg$currPos = s3;
14036 s3 = peg$FAILED;
14037 }
14038 }
14039 peg$savedPos = s0;
14040 s0 = peg$f74(s1, s2);
14041 peg$silentFails--;
14042 s1 = peg$FAILED;
14043 if (peg$silentFails === 0) {
14044 peg$fail(peg$e248);
14045 }
14046 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14047 return s0;
14048 }
14049 function peg$parsecomment() {
14050 var s0, s1, s2, s3, s4, s5;
14051 var key = peg$currPos * 306 + 301;
14052 var cached = peg$resultsCache[key];
14053 if (cached) {
14054 peg$currPos = cached.nextPos;
14055 return cached.result;
14056 }
14057 s0 = peg$parsesingle_comment();
14058 if (s0 === peg$FAILED) {
14059 s0 = peg$currPos;
14060 s1 = peg$parsemultiline_comment();
14061 if (s1 !== peg$FAILED) {
14062 s2 = [];
14063 s3 = peg$currPos;
14064 s4 = peg$parsewhitespace();
14065 if (s4 !== peg$FAILED) {
14066 s5 = peg$parsecomment();
14067 if (s5 !== peg$FAILED) {
14068 peg$savedPos = s3;
14069 s3 = peg$f75(s1, s4, s5);
14070 } else {
14071 peg$currPos = s3;
14072 s3 = peg$FAILED;
14073 }
14074 } else {
14075 peg$currPos = s3;
14076 s3 = peg$FAILED;
14077 }
14078 while (s3 !== peg$FAILED) {
14079 s2.push(s3);
14080 s3 = peg$currPos;
14081 s4 = peg$parsewhitespace();
14082 if (s4 !== peg$FAILED) {
14083 s5 = peg$parsecomment();
14084 if (s5 !== peg$FAILED) {
14085 peg$savedPos = s3;
14086 s3 = peg$f75(s1, s4, s5);
14087 } else {
14088 peg$currPos = s3;
14089 s3 = peg$FAILED;
14090 }
14091 } else {
14092 peg$currPos = s3;
14093 s3 = peg$FAILED;
14094 }
14095 }
14096 peg$savedPos = s0;
14097 s0 = peg$f76(s1, s2);
14098 } else {
14099 peg$currPos = s0;
14100 s0 = peg$FAILED;
14101 }
14102 }
14103 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14104 return s0;
14105 }
14106 function peg$parsesingle_comment() {
14107 var s0, s1, s2, s3, s4;
14108 var key = peg$currPos * 306 + 302;
14109 var cached = peg$resultsCache[key];
14110 if (cached) {
14111 peg$currPos = cached.nextPos;
14112 return cached.result;
14113 }
14114 s0 = peg$currPos;
14115 s1 = peg$currPos;
14116 if (input.substr(peg$currPos, 2) === peg$c211) {
14117 s2 = peg$c211;
14118 peg$currPos += 2;
14119 } else {
14120 s2 = peg$FAILED;
14121 if (peg$silentFails === 0) {
14122 peg$fail(peg$e249);
14123 }
14124 }
14125 if (s2 !== peg$FAILED) {
14126 s3 = [];
14127 if (peg$r11.test(input.charAt(peg$currPos))) {
14128 s4 = input.charAt(peg$currPos);
14129 peg$currPos++;
14130 } else {
14131 s4 = peg$FAILED;
14132 if (peg$silentFails === 0) {
14133 peg$fail(peg$e247);
14134 }
14135 }
14136 while (s4 !== peg$FAILED) {
14137 s3.push(s4);
14138 if (peg$r11.test(input.charAt(peg$currPos))) {
14139 s4 = input.charAt(peg$currPos);
14140 peg$currPos++;
14141 } else {
14142 s4 = peg$FAILED;
14143 if (peg$silentFails === 0) {
14144 peg$fail(peg$e247);
14145 }
14146 }
14147 }
14148 s2 = [s2, s3];
14149 s1 = s2;
14150 } else {
14151 peg$currPos = s1;
14152 s1 = peg$FAILED;
14153 }
14154 if (s1 !== peg$FAILED) {
14155 s0 = input.substring(s0, peg$currPos);
14156 } else {
14157 s0 = s1;
14158 }
14159 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14160 return s0;
14161 }
14162 function peg$parsemultiline_comment() {
14163 var s0, s1, s2, s3, s4, s5, s6;
14164 var key = peg$currPos * 306 + 303;
14165 var cached = peg$resultsCache[key];
14166 if (cached) {
14167 peg$currPos = cached.nextPos;
14168 return cached.result;
14169 }
14170 s0 = peg$currPos;
14171 s1 = peg$currPos;
14172 if (input.substr(peg$currPos, 2) === peg$c212) {
14173 s2 = peg$c212;
14174 peg$currPos += 2;
14175 } else {
14176 s2 = peg$FAILED;
14177 if (peg$silentFails === 0) {
14178 peg$fail(peg$e250);
14179 }
14180 }
14181 if (s2 !== peg$FAILED) {
14182 s3 = [];
14183 s4 = peg$currPos;
14184 s5 = peg$currPos;
14185 peg$silentFails++;
14186 if (input.substr(peg$currPos, 2) === peg$c213) {
14187 s6 = peg$c213;
14188 peg$currPos += 2;
14189 } else {
14190 s6 = peg$FAILED;
14191 if (peg$silentFails === 0) {
14192 peg$fail(peg$e251);
14193 }
14194 }
14195 peg$silentFails--;
14196 if (s6 === peg$FAILED) {
14197 s5 = void 0;
14198 } else {
14199 peg$currPos = s5;
14200 s5 = peg$FAILED;
14201 }
14202 if (s5 !== peg$FAILED) {
14203 if (input.length > peg$currPos) {
14204 s6 = input.charAt(peg$currPos);
14205 peg$currPos++;
14206 } else {
14207 s6 = peg$FAILED;
14208 if (peg$silentFails === 0) {
14209 peg$fail(peg$e252);
14210 }
14211 }
14212 if (s6 !== peg$FAILED) {
14213 peg$savedPos = s4;
14214 s4 = peg$f77(s6);
14215 } else {
14216 peg$currPos = s4;
14217 s4 = peg$FAILED;
14218 }
14219 } else {
14220 peg$currPos = s4;
14221 s4 = peg$FAILED;
14222 }
14223 while (s4 !== peg$FAILED) {
14224 s3.push(s4);
14225 s4 = peg$currPos;
14226 s5 = peg$currPos;
14227 peg$silentFails++;
14228 if (input.substr(peg$currPos, 2) === peg$c213) {
14229 s6 = peg$c213;
14230 peg$currPos += 2;
14231 } else {
14232 s6 = peg$FAILED;
14233 if (peg$silentFails === 0) {
14234 peg$fail(peg$e251);
14235 }
14236 }
14237 peg$silentFails--;
14238 if (s6 === peg$FAILED) {
14239 s5 = void 0;
14240 } else {
14241 peg$currPos = s5;
14242 s5 = peg$FAILED;
14243 }
14244 if (s5 !== peg$FAILED) {
14245 if (input.length > peg$currPos) {
14246 s6 = input.charAt(peg$currPos);
14247 peg$currPos++;
14248 } else {
14249 s6 = peg$FAILED;
14250 if (peg$silentFails === 0) {
14251 peg$fail(peg$e252);
14252 }
14253 }
14254 if (s6 !== peg$FAILED) {
14255 peg$savedPos = s4;
14256 s4 = peg$f77(s6);
14257 } else {
14258 peg$currPos = s4;
14259 s4 = peg$FAILED;
14260 }
14261 } else {
14262 peg$currPos = s4;
14263 s4 = peg$FAILED;
14264 }
14265 }
14266 if (input.substr(peg$currPos, 2) === peg$c213) {
14267 s4 = peg$c213;
14268 peg$currPos += 2;
14269 } else {
14270 s4 = peg$FAILED;
14271 if (peg$silentFails === 0) {
14272 peg$fail(peg$e251);
14273 }
14274 }
14275 if (s4 !== peg$FAILED) {
14276 s2 = [s2, s3, s4];
14277 s1 = s2;
14278 } else {
14279 peg$currPos = s1;
14280 s1 = peg$FAILED;
14281 }
14282 } else {
14283 peg$currPos = s1;
14284 s1 = peg$FAILED;
14285 }
14286 if (s1 !== peg$FAILED) {
14287 s0 = input.substring(s0, peg$currPos);
14288 } else {
14289 s0 = s1;
14290 }
14291 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14292 return s0;
14293 }
14294 function peg$parsewhitespace() {
14295 var s0, s1, s2;
14296 var key = peg$currPos * 306 + 304;
14297 var cached = peg$resultsCache[key];
14298 if (cached) {
14299 peg$currPos = cached.nextPos;
14300 return cached.result;
14301 }
14302 s0 = peg$currPos;
14303 s1 = [];
14304 if (peg$r12.test(input.charAt(peg$currPos))) {
14305 s2 = input.charAt(peg$currPos);
14306 peg$currPos++;
14307 } else {
14308 s2 = peg$FAILED;
14309 if (peg$silentFails === 0) {
14310 peg$fail(peg$e253);
14311 }
14312 }
14313 if (s2 !== peg$FAILED) {
14314 while (s2 !== peg$FAILED) {
14315 s1.push(s2);
14316 if (peg$r12.test(input.charAt(peg$currPos))) {
14317 s2 = input.charAt(peg$currPos);
14318 peg$currPos++;
14319 } else {
14320 s2 = peg$FAILED;
14321 if (peg$silentFails === 0) {
14322 peg$fail(peg$e253);
14323 }
14324 }
14325 }
14326 } else {
14327 s1 = peg$FAILED;
14328 }
14329 if (s1 !== peg$FAILED) {
14330 s0 = input.substring(s0, peg$currPos);
14331 } else {
14332 s0 = s1;
14333 }
14334 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14335 return s0;
14336 }
14337 function peg$parseterminal() {
14338 var s0, s1, s2;
14339 var key = peg$currPos * 306 + 305;
14340 var cached = peg$resultsCache[key];
14341 if (cached) {
14342 peg$currPos = cached.nextPos;
14343 return cached.result;
14344 }
14345 s0 = peg$currPos;
14346 s1 = peg$currPos;
14347 peg$silentFails++;
14348 if (peg$r1.test(input.charAt(peg$currPos))) {
14349 s2 = input.charAt(peg$currPos);
14350 peg$currPos++;
14351 } else {
14352 s2 = peg$FAILED;
14353 if (peg$silentFails === 0) {
14354 peg$fail(peg$e209);
14355 }
14356 }
14357 peg$silentFails--;
14358 if (s2 === peg$FAILED) {
14359 s1 = void 0;
14360 } else {
14361 peg$currPos = s1;
14362 s1 = peg$FAILED;
14363 }
14364 if (s1 !== peg$FAILED) {
14365 s2 = peg$parse_();
14366 peg$savedPos = s0;
14367 s0 = peg$f78(s2);
14368 } else {
14369 peg$currPos = s0;
14370 s0 = peg$FAILED;
14371 }
14372 peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 };
14373 return s0;
14374 }
14375 const context = {
14376 options,
14377 location,
14378 text
14379 };
14380 const {
14381 getLocation,
14382 node,
14383 makeScope,
14384 warn,
14385 pushScope,
14386 popScope,
14387 setScopeEnd,
14388 createFunctionPrototype,
14389 addFunctionCallReference,
14390 createFunctionDefinition,
14391 addTypeReference,
14392 addTypeIfFound,
14393 createType,
14394 addOrCreateBindingReference,
14395 createBindings,
14396 groupCases
14397 } = makeLocals(context);
14398 peg$result = peg$startRuleFunction();
14399 if (peg$result !== peg$FAILED && peg$currPos === input.length) {
14400 return peg$result;
14401 } else {
14402 if (peg$result !== peg$FAILED && peg$currPos < input.length) {
14403 peg$fail(peg$endExpectation());
14404 }
14405 throw peg$buildStructuredError(
14406 peg$maxFailExpected,
14407 peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
14408 peg$maxFailPos < input.length ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) : peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
14409 );
14410 }
14411}
14412
14413// node_modules/@shaderfrog/glsl-parser/error.js
14414var __extends = /* @__PURE__ */ (function() {
14415 var extendStatics = function(d, b) {
14416 extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) {
14417 d2.__proto__ = b2;
14418 } || function(d2, b2) {
14419 for (var p in b2) if (Object.prototype.hasOwnProperty.call(b2, p)) d2[p] = b2[p];
14420 };
14421 return extendStatics(d, b);
14422 };
14423 return function(d, b) {
14424 if (typeof b !== "function" && b !== null)
14425 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
14426 extendStatics(d, b);
14427 function __() {
14428 this.constructor = d;
14429 }
14430 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14431 };
14432})();
14433var __assign2 = function() {
14434 __assign2 = Object.assign || function(t) {
14435 for (var s, i = 1, n = arguments.length; i < n; i++) {
14436 s = arguments[i];
14437 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
14438 t[p] = s[p];
14439 }
14440 return t;
14441 };
14442 return __assign2.apply(this, arguments);
14443};
14444var GlslSyntaxError = (
14445 /** @class */
14446 (function(_super) {
14447 __extends(GlslSyntaxError2, _super);
14448 function GlslSyntaxError2(source, grammarSource, error) {
14449 var _this = _super.call(this, error.format([{ source: grammarSource, text: source }])) || this;
14450 _this.location = error.location;
14451 _this.expected = error.expected;
14452 _this.found = error.found;
14453 return _this;
14454 }
14455 return GlslSyntaxError2;
14456 })(Error)
14457);
14458var DEFAULT_GRAMMAR_SOURCE = "location";
14459var formatError = function(parser, grammarSource) {
14460 if (grammarSource === void 0) {
14461 grammarSource = DEFAULT_GRAMMAR_SOURCE;
14462 }
14463 return function() {
14464 var args = [];
14465 for (var _i = 0; _i < arguments.length; _i++) {
14466 args[_i] = arguments[_i];
14467 }
14468 var src = args[0], options = args[1];
14469 try {
14470 return parser.parse(src, __assign2({ grammarSource }, options));
14471 } catch (e) {
14472 if (e instanceof parser.SyntaxError) {
14473 throw new GlslSyntaxError(src, grammarSource, e);
14474 }
14475 throw e;
14476 }
14477 };
14478};
14479
14480// node_modules/@shaderfrog/glsl-parser/parser/index.js
14481var parse = formatError(parser_exports);
14482var parser_default = parse;
14483export {
14484 GlslSyntaxError,
14485 generator_default as generate,
14486 parser_default as parse,
14487 parser_exports as parser
14488};
vendor/lezer-cpp/LICENSE +21 -0
……@@ -0,0 +1,21 @@
1MIT License
2
3Copyright (C) 2020 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21THE SOFTWARE.
vendor/lezer-cpp/VENDOR.md +25 -0
……@@ -0,0 +1,25 @@
1# Vendored: @lezer/cpp
2
3- **Source**: https://www.npmjs.com/package/@lezer/cpp
4- **Version**: 1.1.5
5- **License**: MIT (see LICENSE)
6- **Author**: Marijn Haverbeke
7- **Bundled**: Grammar + Lezer runtime (@lezer/lr + @lezer/common + @lezer/highlight)
8- **Bundle size**: 215 KB
9
10## Usage
11
12```js
13import { parser } from '../vendor/lezer-cpp/lezer-cpp.mjs'
14const tree = parser.parse(source)
15```
16
17## Regeneration
18
19```sh
20cd /tmp && mkdir -p codetree-vendor && cd codetree-vendor
21npm init -y && echo '{"type":"module"}' > package.json
22npm install @lezer/cpp @lezer/lr @lezer/common @lezer/highlight esbuild
23echo "export { parser } from '@lezer/cpp'" > bundle.js
24./node_modules/.bin/esbuild bundle.js --bundle --format=esm --platform=neutral --outfile=lezer-cpp.mjs
25```
vendor/lezer-cpp/lezer-cpp.mjs +4055 -0
……@@ -0,0 +1,4055 @@
1// node_modules/@lezer/common/dist/index.js
2var DefaultBufferLength = 1024;
3var nextPropID = 0;
4var Range = class {
5 constructor(from, to) {
6 this.from = from;
7 this.to = to;
8 }
9};
10var NodeProp = class {
11 /**
12 Create a new node prop type.
13 */
14 constructor(config = {}) {
15 this.id = nextPropID++;
16 this.perNode = !!config.perNode;
17 this.deserialize = config.deserialize || (() => {
18 throw new Error("This node type doesn't define a deserialize function");
19 });
20 this.combine = config.combine || null;
21 }
22 /**
23 This is meant to be used with
24 [`NodeSet.extend`](#common.NodeSet.extend) or
25 [`LRParser.configure`](#lr.ParserConfig.props) to compute
26 prop values for each node type in the set. Takes a [match
27 object](#common.NodeType^match) or function that returns undefined
28 if the node type doesn't get this prop, and the prop's value if
29 it does.
30 */
31 add(match) {
32 if (this.perNode)
33 throw new RangeError("Can't add per-node props to node types");
34 if (typeof match != "function")
35 match = NodeType.match(match);
36 return (type) => {
37 let result = match(type);
38 return result === void 0 ? null : [this, result];
39 };
40 }
41};
42NodeProp.closedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
43NodeProp.openedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
44NodeProp.group = new NodeProp({ deserialize: (str) => str.split(" ") });
45NodeProp.isolate = new NodeProp({ deserialize: (value) => {
46 if (value && value != "rtl" && value != "ltr" && value != "auto")
47 throw new RangeError("Invalid value for isolate: " + value);
48 return value || "auto";
49} });
50NodeProp.contextHash = new NodeProp({ perNode: true });
51NodeProp.lookAhead = new NodeProp({ perNode: true });
52NodeProp.mounted = new NodeProp({ perNode: true });
53var MountedTree = class {
54 constructor(tree, overlay, parser2, bracketed = false) {
55 this.tree = tree;
56 this.overlay = overlay;
57 this.parser = parser2;
58 this.bracketed = bracketed;
59 }
60 /**
61 @internal
62 */
63 static get(tree) {
64 return tree && tree.props && tree.props[NodeProp.mounted.id];
65 }
66};
67var noProps = /* @__PURE__ */ Object.create(null);
68var NodeType = class _NodeType {
69 /**
70 @internal
71 */
72 constructor(name2, props, id, flags = 0) {
73 this.name = name2;
74 this.props = props;
75 this.id = id;
76 this.flags = flags;
77 }
78 /**
79 Define a node type.
80 */
81 static define(spec) {
82 let props = spec.props && spec.props.length ? /* @__PURE__ */ Object.create(null) : noProps;
83 let flags = (spec.top ? 1 : 0) | (spec.skipped ? 2 : 0) | (spec.error ? 4 : 0) | (spec.name == null ? 8 : 0);
84 let type = new _NodeType(spec.name || "", props, spec.id, flags);
85 if (spec.props)
86 for (let src of spec.props) {
87 if (!Array.isArray(src))
88 src = src(type);
89 if (src) {
90 if (src[0].perNode)
91 throw new RangeError("Can't store a per-node prop on a node type");
92 props[src[0].id] = src[1];
93 }
94 }
95 return type;
96 }
97 /**
98 Retrieves a node prop for this type. Will return `undefined` if
99 the prop isn't present on this node.
100 */
101 prop(prop) {
102 return this.props[prop.id];
103 }
104 /**
105 True when this is the top node of a grammar.
106 */
107 get isTop() {
108 return (this.flags & 1) > 0;
109 }
110 /**
111 True when this node is produced by a skip rule.
112 */
113 get isSkipped() {
114 return (this.flags & 2) > 0;
115 }
116 /**
117 Indicates whether this is an error node.
118 */
119 get isError() {
120 return (this.flags & 4) > 0;
121 }
122 /**
123 When true, this node type doesn't correspond to a user-declared
124 named node, for example because it is used to cache repetition.
125 */
126 get isAnonymous() {
127 return (this.flags & 8) > 0;
128 }
129 /**
130 Returns true when this node's name or one of its
131 [groups](#common.NodeProp^group) matches the given string.
132 */
133 is(name2) {
134 if (typeof name2 == "string") {
135 if (this.name == name2)
136 return true;
137 let group = this.prop(NodeProp.group);
138 return group ? group.indexOf(name2) > -1 : false;
139 }
140 return this.id == name2;
141 }
142 /**
143 Create a function from node types to arbitrary values by
144 specifying an object whose property names are node or
145 [group](#common.NodeProp^group) names. Often useful with
146 [`NodeProp.add`](#common.NodeProp.add). You can put multiple
147 names, separated by spaces, in a single property name to map
148 multiple node names to a single value.
149 */
150 static match(map) {
151 let direct = /* @__PURE__ */ Object.create(null);
152 for (let prop in map)
153 for (let name2 of prop.split(" "))
154 direct[name2] = map[prop];
155 return (node) => {
156 for (let groups = node.prop(NodeProp.group), i = -1; i < (groups ? groups.length : 0); i++) {
157 let found = direct[i < 0 ? node.name : groups[i]];
158 if (found)
159 return found;
160 }
161 };
162 }
163};
164NodeType.none = new NodeType(
165 "",
166 /* @__PURE__ */ Object.create(null),
167 0,
168 8
169 /* NodeFlag.Anonymous */
170);
171var NodeSet = class _NodeSet {
172 /**
173 Create a set with the given types. The `id` property of each
174 type should correspond to its position within the array.
175 */
176 constructor(types) {
177 this.types = types;
178 for (let i = 0; i < types.length; i++)
179 if (types[i].id != i)
180 throw new RangeError("Node type ids should correspond to array positions when creating a node set");
181 }
182 /**
183 Create a copy of this set with some node properties added. The
184 arguments to this method can be created with
185 [`NodeProp.add`](#common.NodeProp.add).
186 */
187 extend(...props) {
188 let newTypes = [];
189 for (let type of this.types) {
190 let newProps = null;
191 for (let source of props) {
192 let add = source(type);
193 if (add) {
194 if (!newProps)
195 newProps = Object.assign({}, type.props);
196 let value = add[1], prop = add[0];
197 if (prop.combine && prop.id in newProps)
198 value = prop.combine(newProps[prop.id], value);
199 newProps[prop.id] = value;
200 }
201 }
202 newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
203 }
204 return new _NodeSet(newTypes);
205 }
206};
207var CachedNode = /* @__PURE__ */ new WeakMap();
208var CachedInnerNode = /* @__PURE__ */ new WeakMap();
209var IterMode;
210(function(IterMode2) {
211 IterMode2[IterMode2["ExcludeBuffers"] = 1] = "ExcludeBuffers";
212 IterMode2[IterMode2["IncludeAnonymous"] = 2] = "IncludeAnonymous";
213 IterMode2[IterMode2["IgnoreMounts"] = 4] = "IgnoreMounts";
214 IterMode2[IterMode2["IgnoreOverlays"] = 8] = "IgnoreOverlays";
215 IterMode2[IterMode2["EnterBracketed"] = 16] = "EnterBracketed";
216})(IterMode || (IterMode = {}));
217var Tree = class _Tree {
218 /**
219 Construct a new tree. See also [`Tree.build`](#common.Tree^build).
220 */
221 constructor(type, children, positions, length, props) {
222 this.type = type;
223 this.children = children;
224 this.positions = positions;
225 this.length = length;
226 this.props = null;
227 if (props && props.length) {
228 this.props = /* @__PURE__ */ Object.create(null);
229 for (let [prop, value] of props)
230 this.props[typeof prop == "number" ? prop : prop.id] = value;
231 }
232 }
233 /**
234 @internal
235 */
236 toString() {
237 let mounted = MountedTree.get(this);
238 if (mounted && !mounted.overlay)
239 return mounted.tree.toString();
240 let children = "";
241 for (let ch of this.children) {
242 let str = ch.toString();
243 if (str) {
244 if (children)
245 children += ",";
246 children += str;
247 }
248 }
249 return !this.type.name ? children : (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) + (children.length ? "(" + children + ")" : "");
250 }
251 /**
252 Get a [tree cursor](#common.TreeCursor) positioned at the top of
253 the tree. Mode can be used to [control](#common.IterMode) which
254 nodes the cursor visits.
255 */
256 cursor(mode = 0) {
257 return new TreeCursor(this.topNode, mode);
258 }
259 /**
260 Get a [tree cursor](#common.TreeCursor) pointing into this tree
261 at the given position and side (see
262 [`moveTo`](#common.TreeCursor.moveTo).
263 */
264 cursorAt(pos, side = 0, mode = 0) {
265 let scope = CachedNode.get(this) || this.topNode;
266 let cursor = new TreeCursor(scope);
267 cursor.moveTo(pos, side);
268 CachedNode.set(this, cursor._tree);
269 return cursor;
270 }
271 /**
272 Get a [syntax node](#common.SyntaxNode) object for the top of the
273 tree.
274 */
275 get topNode() {
276 return new TreeNode(this, 0, 0, null);
277 }
278 /**
279 Get the [syntax node](#common.SyntaxNode) at the given position.
280 If `side` is -1, this will move into nodes that end at the
281 position. If 1, it'll move into nodes that start at the
282 position. With 0, it'll only enter nodes that cover the position
283 from both sides.
284
285 Note that this will not enter
286 [overlays](#common.MountedTree.overlay), and you often want
287 [`resolveInner`](#common.Tree.resolveInner) instead.
288 */
289 resolve(pos, side = 0) {
290 let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
291 CachedNode.set(this, node);
292 return node;
293 }
294 /**
295 Like [`resolve`](#common.Tree.resolve), but will enter
296 [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
297 pointing into the innermost overlaid tree at the given position
298 (with parent links going through all parent structure, including
299 the host trees).
300 */
301 resolveInner(pos, side = 0) {
302 let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
303 CachedInnerNode.set(this, node);
304 return node;
305 }
306 /**
307 In some situations, it can be useful to iterate through all
308 nodes around a position, including those in overlays that don't
309 directly cover the position. This method gives you an iterator
310 that will produce all nodes, from small to big, around the given
311 position.
312 */
313 resolveStack(pos, side = 0) {
314 return stackIterator(this, pos, side);
315 }
316 /**
317 Iterate over the tree and its children, calling `enter` for any
318 node that touches the `from`/`to` region (if given) before
319 running over such a node's children, and `leave` (if given) when
320 leaving the node. When `enter` returns `false`, that node will
321 not have its children iterated over (or `leave` called).
322 */
323 iterate(spec) {
324 let { enter, leave, from = 0, to = this.length } = spec;
325 let mode = spec.mode || 0, anon = (mode & IterMode.IncludeAnonymous) > 0;
326 for (let c = this.cursor(mode | IterMode.IncludeAnonymous); ; ) {
327 let entered = false;
328 if (c.from <= to && c.to >= from && (!anon && c.type.isAnonymous || enter(c) !== false)) {
329 if (c.firstChild())
330 continue;
331 entered = true;
332 }
333 for (; ; ) {
334 if (entered && leave && (anon || !c.type.isAnonymous))
335 leave(c);
336 if (c.nextSibling())
337 break;
338 if (!c.parent())
339 return;
340 entered = true;
341 }
342 }
343 }
344 /**
345 Get the value of the given [node prop](#common.NodeProp) for this
346 node. Works with both per-node and per-type props.
347 */
348 prop(prop) {
349 return !prop.perNode ? this.type.prop(prop) : this.props ? this.props[prop.id] : void 0;
350 }
351 /**
352 Returns the node's [per-node props](#common.NodeProp.perNode) in a
353 format that can be passed to the [`Tree`](#common.Tree)
354 constructor.
355 */
356 get propValues() {
357 let result = [];
358 if (this.props)
359 for (let id in this.props)
360 result.push([+id, this.props[id]]);
361 return result;
362 }
363 /**
364 Balance the direct children of this tree, producing a copy of
365 which may have children grouped into subtrees with type
366 [`NodeType.none`](#common.NodeType^none).
367 */
368 balance(config = {}) {
369 return this.children.length <= 8 ? this : balanceRange(NodeType.none, this.children, this.positions, 0, this.children.length, 0, this.length, (children, positions, length) => new _Tree(this.type, children, positions, length, this.propValues), config.makeTree || ((children, positions, length) => new _Tree(NodeType.none, children, positions, length)));
370 }
371 /**
372 Build a tree from a postfix-ordered buffer of node information,
373 or a cursor over such a buffer.
374 */
375 static build(data) {
376 return buildTree(data);
377 }
378};
379Tree.empty = new Tree(NodeType.none, [], [], 0);
380var FlatBufferCursor = class _FlatBufferCursor {
381 constructor(buffer, index) {
382 this.buffer = buffer;
383 this.index = index;
384 }
385 get id() {
386 return this.buffer[this.index - 4];
387 }
388 get start() {
389 return this.buffer[this.index - 3];
390 }
391 get end() {
392 return this.buffer[this.index - 2];
393 }
394 get size() {
395 return this.buffer[this.index - 1];
396 }
397 get pos() {
398 return this.index;
399 }
400 next() {
401 this.index -= 4;
402 }
403 fork() {
404 return new _FlatBufferCursor(this.buffer, this.index);
405 }
406};
407var TreeBuffer = class _TreeBuffer {
408 /**
409 Create a tree buffer.
410 */
411 constructor(buffer, length, set) {
412 this.buffer = buffer;
413 this.length = length;
414 this.set = set;
415 }
416 /**
417 @internal
418 */
419 get type() {
420 return NodeType.none;
421 }
422 /**
423 @internal
424 */
425 toString() {
426 let result = [];
427 for (let index = 0; index < this.buffer.length; ) {
428 result.push(this.childString(index));
429 index = this.buffer[index + 3];
430 }
431 return result.join(",");
432 }
433 /**
434 @internal
435 */
436 childString(index) {
437 let id = this.buffer[index], endIndex = this.buffer[index + 3];
438 let type = this.set.types[id], result = type.name;
439 if (/\W/.test(result) && !type.isError)
440 result = JSON.stringify(result);
441 index += 4;
442 if (endIndex == index)
443 return result;
444 let children = [];
445 while (index < endIndex) {
446 children.push(this.childString(index));
447 index = this.buffer[index + 3];
448 }
449 return result + "(" + children.join(",") + ")";
450 }
451 /**
452 @internal
453 */
454 findChild(startIndex, endIndex, dir, pos, side) {
455 let { buffer } = this, pick = -1;
456 for (let i = startIndex; i != endIndex; i = buffer[i + 3]) {
457 if (checkSide(side, pos, buffer[i + 1], buffer[i + 2])) {
458 pick = i;
459 if (dir > 0)
460 break;
461 }
462 }
463 return pick;
464 }
465 /**
466 @internal
467 */
468 slice(startI, endI, from) {
469 let b = this.buffer;
470 let copy = new Uint16Array(endI - startI), len = 0;
471 for (let i = startI, j = 0; i < endI; ) {
472 copy[j++] = b[i++];
473 copy[j++] = b[i++] - from;
474 let to = copy[j++] = b[i++] - from;
475 copy[j++] = b[i++] - startI;
476 len = Math.max(len, to);
477 }
478 return new _TreeBuffer(copy, len, this.set);
479 }
480};
481function checkSide(side, pos, from, to) {
482 switch (side) {
483 case -2:
484 return from < pos;
485 case -1:
486 return to >= pos && from < pos;
487 case 0:
488 return from < pos && to > pos;
489 case 1:
490 return from <= pos && to > pos;
491 case 2:
492 return to > pos;
493 case 4:
494 return true;
495 }
496}
497function resolveNode(node, pos, side, overlays) {
498 var _a;
499 while (node.from == node.to || (side < 1 ? node.from >= pos : node.from > pos) || (side > -1 ? node.to <= pos : node.to < pos)) {
500 let parent = !overlays && node instanceof TreeNode && node.index < 0 ? null : node.parent;
501 if (!parent)
502 return node;
503 node = parent;
504 }
505 let mode = overlays ? 0 : IterMode.IgnoreOverlays;
506 if (overlays)
507 for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
508 if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, mode)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
509 node = parent;
510 }
511 for (; ; ) {
512 let inner = node.enter(pos, side, mode);
513 if (!inner)
514 return node;
515 node = inner;
516 }
517}
518var BaseNode = class {
519 cursor(mode = 0) {
520 return new TreeCursor(this, mode);
521 }
522 getChild(type, before = null, after = null) {
523 let r = getChildren(this, type, before, after);
524 return r.length ? r[0] : null;
525 }
526 getChildren(type, before = null, after = null) {
527 return getChildren(this, type, before, after);
528 }
529 resolve(pos, side = 0) {
530 return resolveNode(this, pos, side, false);
531 }
532 resolveInner(pos, side = 0) {
533 return resolveNode(this, pos, side, true);
534 }
535 matchContext(context) {
536 return matchNodeContext(this.parent, context);
537 }
538 enterUnfinishedNodesBefore(pos) {
539 let scan = this.childBefore(pos), node = this;
540 while (scan) {
541 let last = scan.lastChild;
542 if (!last || last.to != scan.to)
543 break;
544 if (last.type.isError && last.from == last.to) {
545 node = scan;
546 scan = last.prevSibling;
547 } else {
548 scan = last;
549 }
550 }
551 return node;
552 }
553 get node() {
554 return this;
555 }
556 get next() {
557 return this.parent;
558 }
559};
560var TreeNode = class _TreeNode extends BaseNode {
561 constructor(_tree, from, index, _parent) {
562 super();
563 this._tree = _tree;
564 this.from = from;
565 this.index = index;
566 this._parent = _parent;
567 }
568 get type() {
569 return this._tree.type;
570 }
571 get name() {
572 return this._tree.type.name;
573 }
574 get to() {
575 return this.from + this._tree.length;
576 }
577 nextChild(i, dir, pos, side, mode = 0) {
578 for (let parent = this; ; ) {
579 for (let { children, positions } = parent._tree, e = dir > 0 ? children.length : -1; i != e; i += dir) {
580 let next = children[i], start = positions[i] + parent.from, mounted;
581 if (!(mode & IterMode.EnterBracketed && next instanceof Tree && (mounted = MountedTree.get(next)) && !mounted.overlay && mounted.bracketed && pos >= start && pos <= start + next.length) && !checkSide(side, pos, start, start + next.length))
582 continue;
583 if (next instanceof TreeBuffer) {
584 if (mode & IterMode.ExcludeBuffers)
585 continue;
586 let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
587 if (index > -1)
588 return new BufferNode(new BufferContext(parent, next, i, start), null, index);
589 } else if (mode & IterMode.IncludeAnonymous || (!next.type.isAnonymous || hasChild(next))) {
590 let mounted2;
591 if (!(mode & IterMode.IgnoreMounts) && (mounted2 = MountedTree.get(next)) && !mounted2.overlay)
592 return new _TreeNode(mounted2.tree, start, i, parent);
593 let inner = new _TreeNode(next, start, i, parent);
594 return mode & IterMode.IncludeAnonymous || !inner.type.isAnonymous ? inner : inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side, mode);
595 }
596 }
597 if (mode & IterMode.IncludeAnonymous || !parent.type.isAnonymous)
598 return null;
599 if (parent.index >= 0)
600 i = parent.index + dir;
601 else
602 i = dir < 0 ? -1 : parent._parent._tree.children.length;
603 parent = parent._parent;
604 if (!parent)
605 return null;
606 }
607 }
608 get firstChild() {
609 return this.nextChild(
610 0,
611 1,
612 0,
613 4
614 /* Side.DontCare */
615 );
616 }
617 get lastChild() {
618 return this.nextChild(
619 this._tree.children.length - 1,
620 -1,
621 0,
622 4
623 /* Side.DontCare */
624 );
625 }
626 childAfter(pos) {
627 return this.nextChild(
628 0,
629 1,
630 pos,
631 2
632 /* Side.After */
633 );
634 }
635 childBefore(pos) {
636 return this.nextChild(
637 this._tree.children.length - 1,
638 -1,
639 pos,
640 -2
641 /* Side.Before */
642 );
643 }
644 prop(prop) {
645 return this._tree.prop(prop);
646 }
647 enter(pos, side, mode = 0) {
648 let mounted;
649 if (!(mode & IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
650 let rPos = pos - this.from, enterBracketed = mode & IterMode.EnterBracketed && mounted.bracketed;
651 for (let { from, to } of mounted.overlay) {
652 if ((side > 0 || enterBracketed ? from <= rPos : from < rPos) && (side < 0 || enterBracketed ? to >= rPos : to > rPos))
653 return new _TreeNode(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
654 }
655 }
656 return this.nextChild(0, 1, pos, side, mode);
657 }
658 nextSignificantParent() {
659 let val = this;
660 while (val.type.isAnonymous && val._parent)
661 val = val._parent;
662 return val;
663 }
664 get parent() {
665 return this._parent ? this._parent.nextSignificantParent() : null;
666 }
667 get nextSibling() {
668 return this._parent && this.index >= 0 ? this._parent.nextChild(
669 this.index + 1,
670 1,
671 0,
672 4
673 /* Side.DontCare */
674 ) : null;
675 }
676 get prevSibling() {
677 return this._parent && this.index >= 0 ? this._parent.nextChild(
678 this.index - 1,
679 -1,
680 0,
681 4
682 /* Side.DontCare */
683 ) : null;
684 }
685 get tree() {
686 return this._tree;
687 }
688 toTree() {
689 return this._tree;
690 }
691 /**
692 @internal
693 */
694 toString() {
695 return this._tree.toString();
696 }
697};
698function getChildren(node, type, before, after) {
699 let cur = node.cursor(), result = [];
700 if (!cur.firstChild())
701 return result;
702 if (before != null)
703 for (let found = false; !found; ) {
704 found = cur.type.is(before);
705 if (!cur.nextSibling())
706 return result;
707 }
708 for (; ; ) {
709 if (after != null && cur.type.is(after))
710 return result;
711 if (cur.type.is(type))
712 result.push(cur.node);
713 if (!cur.nextSibling())
714 return after == null ? result : [];
715 }
716}
717function matchNodeContext(node, context, i = context.length - 1) {
718 for (let p = node; i >= 0; p = p.parent) {
719 if (!p)
720 return false;
721 if (!p.type.isAnonymous) {
722 if (context[i] && context[i] != p.name)
723 return false;
724 i--;
725 }
726 }
727 return true;
728}
729var BufferContext = class {
730 constructor(parent, buffer, index, start) {
731 this.parent = parent;
732 this.buffer = buffer;
733 this.index = index;
734 this.start = start;
735 }
736};
737var BufferNode = class _BufferNode extends BaseNode {
738 get name() {
739 return this.type.name;
740 }
741 get from() {
742 return this.context.start + this.context.buffer.buffer[this.index + 1];
743 }
744 get to() {
745 return this.context.start + this.context.buffer.buffer[this.index + 2];
746 }
747 constructor(context, _parent, index) {
748 super();
749 this.context = context;
750 this._parent = _parent;
751 this.index = index;
752 this.type = context.buffer.set.types[context.buffer.buffer[index]];
753 }
754 child(dir, pos, side) {
755 let { buffer } = this.context;
756 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.context.start, side);
757 return index < 0 ? null : new _BufferNode(this.context, this, index);
758 }
759 get firstChild() {
760 return this.child(
761 1,
762 0,
763 4
764 /* Side.DontCare */
765 );
766 }
767 get lastChild() {
768 return this.child(
769 -1,
770 0,
771 4
772 /* Side.DontCare */
773 );
774 }
775 childAfter(pos) {
776 return this.child(
777 1,
778 pos,
779 2
780 /* Side.After */
781 );
782 }
783 childBefore(pos) {
784 return this.child(
785 -1,
786 pos,
787 -2
788 /* Side.Before */
789 );
790 }
791 prop(prop) {
792 return this.type.prop(prop);
793 }
794 enter(pos, side, mode = 0) {
795 if (mode & IterMode.ExcludeBuffers)
796 return null;
797 let { buffer } = this.context;
798 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
799 return index < 0 ? null : new _BufferNode(this.context, this, index);
800 }
801 get parent() {
802 return this._parent || this.context.parent.nextSignificantParent();
803 }
804 externalSibling(dir) {
805 return this._parent ? null : this.context.parent.nextChild(
806 this.context.index + dir,
807 dir,
808 0,
809 4
810 /* Side.DontCare */
811 );
812 }
813 get nextSibling() {
814 let { buffer } = this.context;
815 let after = buffer.buffer[this.index + 3];
816 if (after < (this._parent ? buffer.buffer[this._parent.index + 3] : buffer.buffer.length))
817 return new _BufferNode(this.context, this._parent, after);
818 return this.externalSibling(1);
819 }
820 get prevSibling() {
821 let { buffer } = this.context;
822 let parentStart = this._parent ? this._parent.index + 4 : 0;
823 if (this.index == parentStart)
824 return this.externalSibling(-1);
825 return new _BufferNode(this.context, this._parent, buffer.findChild(
826 parentStart,
827 this.index,
828 -1,
829 0,
830 4
831 /* Side.DontCare */
832 ));
833 }
834 get tree() {
835 return null;
836 }
837 toTree() {
838 let children = [], positions = [];
839 let { buffer } = this.context;
840 let startI = this.index + 4, endI = buffer.buffer[this.index + 3];
841 if (endI > startI) {
842 let from = buffer.buffer[this.index + 1];
843 children.push(buffer.slice(startI, endI, from));
844 positions.push(0);
845 }
846 return new Tree(this.type, children, positions, this.to - this.from);
847 }
848 /**
849 @internal
850 */
851 toString() {
852 return this.context.buffer.childString(this.index);
853 }
854};
855function iterStack(heads) {
856 if (!heads.length)
857 return null;
858 let pick = 0, picked = heads[0];
859 for (let i = 1; i < heads.length; i++) {
860 let node = heads[i];
861 if (node.from > picked.from || node.to < picked.to) {
862 picked = node;
863 pick = i;
864 }
865 }
866 let next = picked instanceof TreeNode && picked.index < 0 ? null : picked.parent;
867 let newHeads = heads.slice();
868 if (next)
869 newHeads[pick] = next;
870 else
871 newHeads.splice(pick, 1);
872 return new StackIterator(newHeads, picked);
873}
874var StackIterator = class {
875 constructor(heads, node) {
876 this.heads = heads;
877 this.node = node;
878 }
879 get next() {
880 return iterStack(this.heads);
881 }
882};
883function stackIterator(tree, pos, side) {
884 let inner = tree.resolveInner(pos, side), layers = null;
885 for (let scan = inner instanceof TreeNode ? inner : inner.context.parent; scan; scan = scan.parent) {
886 if (scan.index < 0) {
887 let parent = scan.parent;
888 (layers || (layers = [inner])).push(parent.resolve(pos, side));
889 scan = parent;
890 } else {
891 let mount = MountedTree.get(scan.tree);
892 if (mount && mount.overlay && mount.overlay[0].from <= pos && mount.overlay[mount.overlay.length - 1].to >= pos) {
893 let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, -1, scan);
894 (layers || (layers = [inner])).push(resolveNode(root, pos, side, false));
895 }
896 }
897 }
898 return layers ? iterStack(layers) : inner;
899}
900var TreeCursor = class {
901 /**
902 Shorthand for `.type.name`.
903 */
904 get name() {
905 return this.type.name;
906 }
907 /**
908 @internal
909 */
910 constructor(node, mode = 0) {
911 this.buffer = null;
912 this.stack = [];
913 this.index = 0;
914 this.bufferNode = null;
915 this.mode = mode & ~IterMode.EnterBracketed;
916 if (node instanceof TreeNode) {
917 this.yieldNode(node);
918 } else {
919 this._tree = node.context.parent;
920 this.buffer = node.context;
921 for (let n = node._parent; n; n = n._parent)
922 this.stack.unshift(n.index);
923 this.bufferNode = node;
924 this.yieldBuf(node.index);
925 }
926 }
927 yieldNode(node) {
928 if (!node)
929 return false;
930 this._tree = node;
931 this.type = node.type;
932 this.from = node.from;
933 this.to = node.to;
934 return true;
935 }
936 yieldBuf(index, type) {
937 this.index = index;
938 let { start, buffer } = this.buffer;
939 this.type = type || buffer.set.types[buffer.buffer[index]];
940 this.from = start + buffer.buffer[index + 1];
941 this.to = start + buffer.buffer[index + 2];
942 return true;
943 }
944 /**
945 @internal
946 */
947 yield(node) {
948 if (!node)
949 return false;
950 if (node instanceof TreeNode) {
951 this.buffer = null;
952 return this.yieldNode(node);
953 }
954 this.buffer = node.context;
955 return this.yieldBuf(node.index, node.type);
956 }
957 /**
958 @internal
959 */
960 toString() {
961 return this.buffer ? this.buffer.buffer.childString(this.index) : this._tree.toString();
962 }
963 /**
964 @internal
965 */
966 enterChild(dir, pos, side) {
967 if (!this.buffer)
968 return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
969 let { buffer } = this.buffer;
970 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
971 if (index < 0)
972 return false;
973 this.stack.push(this.index);
974 return this.yieldBuf(index);
975 }
976 /**
977 Move the cursor to this node's first child. When this returns
978 false, the node has no child, and the cursor has not been moved.
979 */
980 firstChild() {
981 return this.enterChild(
982 1,
983 0,
984 4
985 /* Side.DontCare */
986 );
987 }
988 /**
989 Move the cursor to this node's last child.
990 */
991 lastChild() {
992 return this.enterChild(
993 -1,
994 0,
995 4
996 /* Side.DontCare */
997 );
998 }
999 /**
1000 Move the cursor to the first child that ends after `pos`.
1001 */
1002 childAfter(pos) {
1003 return this.enterChild(
1004 1,
1005 pos,
1006 2
1007 /* Side.After */
1008 );
1009 }
1010 /**
1011 Move to the last child that starts before `pos`.
1012 */
1013 childBefore(pos) {
1014 return this.enterChild(
1015 -1,
1016 pos,
1017 -2
1018 /* Side.Before */
1019 );
1020 }
1021 /**
1022 Move the cursor to the child around `pos`. If side is -1 the
1023 child may end at that position, when 1 it may start there. This
1024 will also enter [overlaid](#common.MountedTree.overlay)
1025 [mounted](#common.NodeProp^mounted) trees unless `overlays` is
1026 set to false.
1027 */
1028 enter(pos, side, mode = this.mode) {
1029 if (!this.buffer)
1030 return this.yield(this._tree.enter(pos, side, mode));
1031 return mode & IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
1032 }
1033 /**
1034 Move to the node's parent node, if this isn't the top node.
1035 */
1036 parent() {
1037 if (!this.buffer)
1038 return this.yieldNode(this.mode & IterMode.IncludeAnonymous ? this._tree._parent : this._tree.parent);
1039 if (this.stack.length)
1040 return this.yieldBuf(this.stack.pop());
1041 let parent = this.mode & IterMode.IncludeAnonymous ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
1042 this.buffer = null;
1043 return this.yieldNode(parent);
1044 }
1045 /**
1046 @internal
1047 */
1048 sibling(dir) {
1049 if (!this.buffer)
1050 return !this._tree._parent ? false : this.yield(this._tree.index < 0 ? null : this._tree._parent.nextChild(this._tree.index + dir, dir, 0, 4, this.mode));
1051 let { buffer } = this.buffer, d = this.stack.length - 1;
1052 if (dir < 0) {
1053 let parentStart = d < 0 ? 0 : this.stack[d] + 4;
1054 if (this.index != parentStart)
1055 return this.yieldBuf(buffer.findChild(
1056 parentStart,
1057 this.index,
1058 -1,
1059 0,
1060 4
1061 /* Side.DontCare */
1062 ));
1063 } else {
1064 let after = buffer.buffer[this.index + 3];
1065 if (after < (d < 0 ? buffer.buffer.length : buffer.buffer[this.stack[d] + 3]))
1066 return this.yieldBuf(after);
1067 }
1068 return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir, 0, 4, this.mode)) : false;
1069 }
1070 /**
1071 Move to this node's next sibling, if any.
1072 */
1073 nextSibling() {
1074 return this.sibling(1);
1075 }
1076 /**
1077 Move to this node's previous sibling, if any.
1078 */
1079 prevSibling() {
1080 return this.sibling(-1);
1081 }
1082 atLastNode(dir) {
1083 let index, parent, { buffer } = this;
1084 if (buffer) {
1085 if (dir > 0) {
1086 if (this.index < buffer.buffer.buffer.length)
1087 return false;
1088 } else {
1089 for (let i = 0; i < this.index; i++)
1090 if (buffer.buffer.buffer[i + 3] < this.index)
1091 return false;
1092 }
1093 ({ index, parent } = buffer);
1094 } else {
1095 ({ index, _parent: parent } = this._tree);
1096 }
1097 for (; parent; { index, _parent: parent } = parent) {
1098 if (index > -1)
1099 for (let i = index + dir, e = dir < 0 ? -1 : parent._tree.children.length; i != e; i += dir) {
1100 let child = parent._tree.children[i];
1101 if (this.mode & IterMode.IncludeAnonymous || child instanceof TreeBuffer || !child.type.isAnonymous || hasChild(child))
1102 return false;
1103 }
1104 }
1105 return true;
1106 }
1107 move(dir, enter) {
1108 if (enter && this.enterChild(
1109 dir,
1110 0,
1111 4
1112 /* Side.DontCare */
1113 ))
1114 return true;
1115 for (; ; ) {
1116 if (this.sibling(dir))
1117 return true;
1118 if (this.atLastNode(dir) || !this.parent())
1119 return false;
1120 }
1121 }
1122 /**
1123 Move to the next node in a
1124 [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)
1125 traversal, going from a node to its first child or, if the
1126 current node is empty or `enter` is false, its next sibling or
1127 the next sibling of the first parent node that has one.
1128 */
1129 next(enter = true) {
1130 return this.move(1, enter);
1131 }
1132 /**
1133 Move to the next node in a last-to-first pre-order traversal. A
1134 node is followed by its last child or, if it has none, its
1135 previous sibling or the previous sibling of the first parent
1136 node that has one.
1137 */
1138 prev(enter = true) {
1139 return this.move(-1, enter);
1140 }
1141 /**
1142 Move the cursor to the innermost node that covers `pos`. If
1143 `side` is -1, it will enter nodes that end at `pos`. If it is 1,
1144 it will enter nodes that start at `pos`.
1145 */
1146 moveTo(pos, side = 0) {
1147 while (this.from == this.to || (side < 1 ? this.from >= pos : this.from > pos) || (side > -1 ? this.to <= pos : this.to < pos))
1148 if (!this.parent())
1149 break;
1150 while (this.enterChild(1, pos, side)) {
1151 }
1152 return this;
1153 }
1154 /**
1155 Get a [syntax node](#common.SyntaxNode) at the cursor's current
1156 position.
1157 */
1158 get node() {
1159 if (!this.buffer)
1160 return this._tree;
1161 let cache = this.bufferNode, result = null, depth = 0;
1162 if (cache && cache.context == this.buffer) {
1163 scan: for (let index = this.index, d = this.stack.length; d >= 0; ) {
1164 for (let c = cache; c; c = c._parent)
1165 if (c.index == index) {
1166 if (index == this.index)
1167 return c;
1168 result = c;
1169 depth = d + 1;
1170 break scan;
1171 }
1172 index = this.stack[--d];
1173 }
1174 }
1175 for (let i = depth; i < this.stack.length; i++)
1176 result = new BufferNode(this.buffer, result, this.stack[i]);
1177 return this.bufferNode = new BufferNode(this.buffer, result, this.index);
1178 }
1179 /**
1180 Get the [tree](#common.Tree) that represents the current node, if
1181 any. Will return null when the node is in a [tree
1182 buffer](#common.TreeBuffer).
1183 */
1184 get tree() {
1185 return this.buffer ? null : this._tree._tree;
1186 }
1187 /**
1188 Iterate over the current node and all its descendants, calling
1189 `enter` when entering a node and `leave`, if given, when leaving
1190 one. When `enter` returns `false`, any children of that node are
1191 skipped, and `leave` isn't called for it.
1192 */
1193 iterate(enter, leave) {
1194 for (let depth = 0; ; ) {
1195 let mustLeave = false;
1196 if (this.type.isAnonymous || enter(this) !== false) {
1197 if (this.firstChild()) {
1198 depth++;
1199 continue;
1200 }
1201 if (!this.type.isAnonymous)
1202 mustLeave = true;
1203 }
1204 for (; ; ) {
1205 if (mustLeave && leave)
1206 leave(this);
1207 mustLeave = this.type.isAnonymous;
1208 if (!depth)
1209 return;
1210 if (this.nextSibling())
1211 break;
1212 this.parent();
1213 depth--;
1214 mustLeave = true;
1215 }
1216 }
1217 }
1218 /**
1219 Test whether the current node matches a given context—a sequence
1220 of direct parent node names. Empty strings in the context array
1221 are treated as wildcards.
1222 */
1223 matchContext(context) {
1224 if (!this.buffer)
1225 return matchNodeContext(this.node.parent, context);
1226 let { buffer } = this.buffer, { types } = buffer.set;
1227 for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) {
1228 if (d < 0)
1229 return matchNodeContext(this._tree, context, i);
1230 let type = types[buffer.buffer[this.stack[d]]];
1231 if (!type.isAnonymous) {
1232 if (context[i] && context[i] != type.name)
1233 return false;
1234 i--;
1235 }
1236 }
1237 return true;
1238 }
1239};
1240function hasChild(tree) {
1241 return tree.children.some((ch) => ch instanceof TreeBuffer || !ch.type.isAnonymous || hasChild(ch));
1242}
1243function buildTree(data) {
1244 var _a;
1245 let { buffer, nodeSet, maxBufferLength = DefaultBufferLength, reused = [], minRepeatType = nodeSet.types.length } = data;
1246 let cursor = Array.isArray(buffer) ? new FlatBufferCursor(buffer, buffer.length) : buffer;
1247 let types = nodeSet.types;
1248 let contextHash = 0, lookAhead = 0;
1249 function takeNode(parentStart, minPos, children2, positions2, inRepeat, depth) {
1250 let { id, start, end, size } = cursor;
1251 let lookAheadAtStart = lookAhead, contextAtStart = contextHash;
1252 if (size < 0) {
1253 cursor.next();
1254 if (size == -1) {
1255 let node2 = reused[id];
1256 children2.push(node2);
1257 positions2.push(start - parentStart);
1258 return;
1259 } else if (size == -3) {
1260 contextHash = id;
1261 return;
1262 } else if (size == -4) {
1263 lookAhead = id;
1264 return;
1265 } else {
1266 throw new RangeError(`Unrecognized record size: ${size}`);
1267 }
1268 }
1269 let type = types[id], node, buffer2;
1270 let startPos = start - parentStart;
1271 if (end - start <= maxBufferLength && (buffer2 = findBufferSize(cursor.pos - minPos, inRepeat))) {
1272 let data2 = new Uint16Array(buffer2.size - buffer2.skip);
1273 let endPos = cursor.pos - buffer2.size, index = data2.length;
1274 while (cursor.pos > endPos)
1275 index = copyToBuffer(buffer2.start, data2, index);
1276 node = new TreeBuffer(data2, end - buffer2.start, nodeSet);
1277 startPos = buffer2.start - parentStart;
1278 } else {
1279 let endPos = cursor.pos - size;
1280 cursor.next();
1281 let localChildren = [], localPositions = [];
1282 let localInRepeat = id >= minRepeatType ? id : -1;
1283 let lastGroup = 0, lastEnd = end;
1284 while (cursor.pos > endPos) {
1285 if (localInRepeat >= 0 && cursor.id == localInRepeat && cursor.size >= 0) {
1286 if (cursor.end <= lastEnd - maxBufferLength) {
1287 makeRepeatLeaf(localChildren, localPositions, start, lastGroup, cursor.end, lastEnd, localInRepeat, lookAheadAtStart, contextAtStart);
1288 lastGroup = localChildren.length;
1289 lastEnd = cursor.end;
1290 }
1291 cursor.next();
1292 } else if (depth > 2500) {
1293 takeFlatNode(start, endPos, localChildren, localPositions);
1294 } else {
1295 takeNode(start, endPos, localChildren, localPositions, localInRepeat, depth + 1);
1296 }
1297 }
1298 if (localInRepeat >= 0 && lastGroup > 0 && lastGroup < localChildren.length)
1299 makeRepeatLeaf(localChildren, localPositions, start, lastGroup, start, lastEnd, localInRepeat, lookAheadAtStart, contextAtStart);
1300 localChildren.reverse();
1301 localPositions.reverse();
1302 if (localInRepeat > -1 && lastGroup > 0) {
1303 let make = makeBalanced(type, contextAtStart);
1304 node = balanceRange(type, localChildren, localPositions, 0, localChildren.length, 0, end - start, make, make);
1305 } else {
1306 node = makeTree(type, localChildren, localPositions, end - start, lookAheadAtStart - end, contextAtStart);
1307 }
1308 }
1309 children2.push(node);
1310 positions2.push(startPos);
1311 }
1312 function takeFlatNode(parentStart, minPos, children2, positions2) {
1313 let nodes = [];
1314 let nodeCount = 0, stopAt = -1;
1315 while (cursor.pos > minPos) {
1316 let { id, start, end, size } = cursor;
1317 if (size > 4) {
1318 cursor.next();
1319 } else if (stopAt > -1 && start < stopAt) {
1320 break;
1321 } else {
1322 if (stopAt < 0)
1323 stopAt = end - maxBufferLength;
1324 nodes.push(id, start, end);
1325 nodeCount++;
1326 cursor.next();
1327 }
1328 }
1329 if (nodeCount) {
1330 let buffer2 = new Uint16Array(nodeCount * 4);
1331 let start = nodes[nodes.length - 2];
1332 for (let i = nodes.length - 3, j = 0; i >= 0; i -= 3) {
1333 buffer2[j++] = nodes[i];
1334 buffer2[j++] = nodes[i + 1] - start;
1335 buffer2[j++] = nodes[i + 2] - start;
1336 buffer2[j++] = j;
1337 }
1338 children2.push(new TreeBuffer(buffer2, nodes[2] - start, nodeSet));
1339 positions2.push(start - parentStart);
1340 }
1341 }
1342 function makeBalanced(type, contextHash2) {
1343 return (children2, positions2, length2) => {
1344 let lookAhead2 = 0, lastI = children2.length - 1, last, lookAheadProp;
1345 if (lastI >= 0 && (last = children2[lastI]) instanceof Tree) {
1346 if (!lastI && last.type == type && last.length == length2)
1347 return last;
1348 if (lookAheadProp = last.prop(NodeProp.lookAhead))
1349 lookAhead2 = positions2[lastI] + last.length + lookAheadProp;
1350 }
1351 return makeTree(type, children2, positions2, length2, lookAhead2, contextHash2);
1352 };
1353 }
1354 function makeRepeatLeaf(children2, positions2, base, i, from, to, type, lookAhead2, contextHash2) {
1355 let localChildren = [], localPositions = [];
1356 while (children2.length > i) {
1357 localChildren.push(children2.pop());
1358 localPositions.push(positions2.pop() + base - from);
1359 }
1360 children2.push(makeTree(nodeSet.types[type], localChildren, localPositions, to - from, lookAhead2 - to, contextHash2));
1361 positions2.push(from - base);
1362 }
1363 function makeTree(type, children2, positions2, length2, lookAhead2, contextHash2, props) {
1364 if (contextHash2) {
1365 let pair2 = [NodeProp.contextHash, contextHash2];
1366 props = props ? [pair2].concat(props) : [pair2];
1367 }
1368 if (lookAhead2 > 25) {
1369 let pair2 = [NodeProp.lookAhead, lookAhead2];
1370 props = props ? [pair2].concat(props) : [pair2];
1371 }
1372 return new Tree(type, children2, positions2, length2, props);
1373 }
1374 function findBufferSize(maxSize, inRepeat) {
1375 let fork = cursor.fork();
1376 let size = 0, start = 0, skip = 0, minStart = fork.end - maxBufferLength;
1377 let result = { size: 0, start: 0, skip: 0 };
1378 scan: for (let minPos = fork.pos - maxSize; fork.pos > minPos; ) {
1379 let nodeSize2 = fork.size;
1380 if (fork.id == inRepeat && nodeSize2 >= 0) {
1381 result.size = size;
1382 result.start = start;
1383 result.skip = skip;
1384 skip += 4;
1385 size += 4;
1386 fork.next();
1387 continue;
1388 }
1389 let startPos = fork.pos - nodeSize2;
1390 if (nodeSize2 < 0 || startPos < minPos || fork.start < minStart)
1391 break;
1392 let localSkipped = fork.id >= minRepeatType ? 4 : 0;
1393 let nodeStart = fork.start;
1394 fork.next();
1395 while (fork.pos > startPos) {
1396 if (fork.size < 0) {
1397 if (fork.size == -3 || fork.size == -4)
1398 localSkipped += 4;
1399 else
1400 break scan;
1401 } else if (fork.id >= minRepeatType) {
1402 localSkipped += 4;
1403 }
1404 fork.next();
1405 }
1406 start = nodeStart;
1407 size += nodeSize2;
1408 skip += localSkipped;
1409 }
1410 if (inRepeat < 0 || size == maxSize) {
1411 result.size = size;
1412 result.start = start;
1413 result.skip = skip;
1414 }
1415 return result.size > 4 ? result : void 0;
1416 }
1417 function copyToBuffer(bufferStart, buffer2, index) {
1418 let { id, start, end, size } = cursor;
1419 cursor.next();
1420 if (size >= 0 && id < minRepeatType) {
1421 let startIndex = index;
1422 if (size > 4) {
1423 let endPos = cursor.pos - (size - 4);
1424 while (cursor.pos > endPos)
1425 index = copyToBuffer(bufferStart, buffer2, index);
1426 }
1427 buffer2[--index] = startIndex;
1428 buffer2[--index] = end - bufferStart;
1429 buffer2[--index] = start - bufferStart;
1430 buffer2[--index] = id;
1431 } else if (size == -3) {
1432 contextHash = id;
1433 } else if (size == -4) {
1434 lookAhead = id;
1435 }
1436 return index;
1437 }
1438 let children = [], positions = [];
1439 while (cursor.pos > 0)
1440 takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1, 0);
1441 let length = (_a = data.length) !== null && _a !== void 0 ? _a : children.length ? positions[0] + children[0].length : 0;
1442 return new Tree(types[data.topID], children.reverse(), positions.reverse(), length);
1443}
1444var nodeSizeCache = /* @__PURE__ */ new WeakMap();
1445function nodeSize(balanceType, node) {
1446 if (!balanceType.isAnonymous || node instanceof TreeBuffer || node.type != balanceType)
1447 return 1;
1448 let size = nodeSizeCache.get(node);
1449 if (size == null) {
1450 size = 1;
1451 for (let child of node.children) {
1452 if (child.type != balanceType || !(child instanceof Tree)) {
1453 size = 1;
1454 break;
1455 }
1456 size += nodeSize(balanceType, child);
1457 }
1458 nodeSizeCache.set(node, size);
1459 }
1460 return size;
1461}
1462function balanceRange(balanceType, children, positions, from, to, start, length, mkTop, mkTree) {
1463 let total = 0;
1464 for (let i = from; i < to; i++)
1465 total += nodeSize(balanceType, children[i]);
1466 let maxChild = Math.ceil(
1467 total * 1.5 / 8
1468 /* Balance.BranchFactor */
1469 );
1470 let localChildren = [], localPositions = [];
1471 function divide(children2, positions2, from2, to2, offset) {
1472 for (let i = from2; i < to2; ) {
1473 let groupFrom = i, groupStart = positions2[i], groupSize = nodeSize(balanceType, children2[i]);
1474 i++;
1475 for (; i < to2; i++) {
1476 let nextSize = nodeSize(balanceType, children2[i]);
1477 if (groupSize + nextSize >= maxChild)
1478 break;
1479 groupSize += nextSize;
1480 }
1481 if (i == groupFrom + 1) {
1482 if (groupSize > maxChild) {
1483 let only = children2[groupFrom];
1484 divide(only.children, only.positions, 0, only.children.length, positions2[groupFrom] + offset);
1485 continue;
1486 }
1487 localChildren.push(children2[groupFrom]);
1488 } else {
1489 let length2 = positions2[i - 1] + children2[i - 1].length - groupStart;
1490 localChildren.push(balanceRange(balanceType, children2, positions2, groupFrom, i, groupStart, length2, null, mkTree));
1491 }
1492 localPositions.push(groupStart + offset - start);
1493 }
1494 }
1495 divide(children, positions, from, to, 0);
1496 return (mkTop || mkTree)(localChildren, localPositions, length);
1497}
1498var Parser = class {
1499 /**
1500 Start a parse, returning a [partial parse](#common.PartialParse)
1501 object. [`fragments`](#common.TreeFragment) can be passed in to
1502 make the parse incremental.
1503
1504 By default, the entire input is parsed. You can pass `ranges`,
1505 which should be a sorted array of non-empty, non-overlapping
1506 ranges, to parse only those ranges. The tree returned in that
1507 case will start at `ranges[0].from`.
1508 */
1509 startParse(input, fragments, ranges) {
1510 if (typeof input == "string")
1511 input = new StringInput(input);
1512 ranges = !ranges ? [new Range(0, input.length)] : ranges.length ? ranges.map((r) => new Range(r.from, r.to)) : [new Range(0, 0)];
1513 return this.createParse(input, fragments || [], ranges);
1514 }
1515 /**
1516 Run a full parse, returning the resulting tree.
1517 */
1518 parse(input, fragments, ranges) {
1519 let parse = this.startParse(input, fragments, ranges);
1520 for (; ; ) {
1521 let done = parse.advance();
1522 if (done)
1523 return done;
1524 }
1525 }
1526};
1527var StringInput = class {
1528 constructor(string2) {
1529 this.string = string2;
1530 }
1531 get length() {
1532 return this.string.length;
1533 }
1534 chunk(from) {
1535 return this.string.slice(from);
1536 }
1537 get lineChunks() {
1538 return false;
1539 }
1540 read(from, to) {
1541 return this.string.slice(from, to);
1542 }
1543};
1544var stoppedInner = new NodeProp({ perNode: true });
1545
1546// node_modules/@lezer/lr/dist/index.js
1547var Stack = class _Stack {
1548 /**
1549 @internal
1550 */
1551 constructor(p, stack, state, reducePos, pos, score, buffer, bufferBase, curContext, lookAhead = 0, parent) {
1552 this.p = p;
1553 this.stack = stack;
1554 this.state = state;
1555 this.reducePos = reducePos;
1556 this.pos = pos;
1557 this.score = score;
1558 this.buffer = buffer;
1559 this.bufferBase = bufferBase;
1560 this.curContext = curContext;
1561 this.lookAhead = lookAhead;
1562 this.parent = parent;
1563 }
1564 /**
1565 @internal
1566 */
1567 toString() {
1568 return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`;
1569 }
1570 // Start an empty stack
1571 /**
1572 @internal
1573 */
1574 static start(p, state, pos = 0) {
1575 let cx = p.parser.context;
1576 return new _Stack(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext(cx, cx.start) : null, 0, null);
1577 }
1578 /**
1579 The stack's current [context](#lr.ContextTracker) value, if
1580 any. Its type will depend on the context tracker's type
1581 parameter, or it will be `null` if there is no context
1582 tracker.
1583 */
1584 get context() {
1585 return this.curContext ? this.curContext.context : null;
1586 }
1587 // Push a state onto the stack, tracking its start position as well
1588 // as the buffer base at that point.
1589 /**
1590 @internal
1591 */
1592 pushState(state, start) {
1593 this.stack.push(this.state, start, this.bufferBase + this.buffer.length);
1594 this.state = state;
1595 }
1596 // Apply a reduce action
1597 /**
1598 @internal
1599 */
1600 reduce(action) {
1601 var _a;
1602 let depth = action >> 19, type = action & 65535;
1603 let { parser: parser2 } = this.p;
1604 let lookaheadRecord = this.reducePos < this.pos - 25 && this.setLookAhead(this.pos);
1605 let dPrec = parser2.dynamicPrecedence(type);
1606 if (dPrec)
1607 this.score += dPrec;
1608 if (depth == 0) {
1609 this.pushState(parser2.getGoto(this.state, type, true), this.reducePos);
1610 if (type < parser2.minRepeatTerm)
1611 this.storeNode(type, this.reducePos, this.reducePos, lookaheadRecord ? 8 : 4, true);
1612 this.reduceContext(type, this.reducePos);
1613 return;
1614 }
1615 let base = this.stack.length - (depth - 1) * 3 - (action & 262144 ? 6 : 0);
1616 let start = base ? this.stack[base - 2] : this.p.ranges[0].from, size = this.reducePos - start;
1617 if (size >= 2e3 && !((_a = this.p.parser.nodeSet.types[type]) === null || _a === void 0 ? void 0 : _a.isAnonymous)) {
1618 if (start == this.p.lastBigReductionStart) {
1619 this.p.bigReductionCount++;
1620 this.p.lastBigReductionSize = size;
1621 } else if (this.p.lastBigReductionSize < size) {
1622 this.p.bigReductionCount = 1;
1623 this.p.lastBigReductionStart = start;
1624 this.p.lastBigReductionSize = size;
1625 }
1626 }
1627 let bufferBase = base ? this.stack[base - 1] : 0, count = this.bufferBase + this.buffer.length - bufferBase;
1628 if (type < parser2.minRepeatTerm || action & 131072) {
1629 let pos = parser2.stateFlag(
1630 this.state,
1631 1
1632 /* StateFlag.Skipped */
1633 ) ? this.pos : this.reducePos;
1634 this.storeNode(type, start, pos, count + 4, true);
1635 }
1636 if (action & 262144) {
1637 this.state = this.stack[base];
1638 } else {
1639 let baseStateID = this.stack[base - 3];
1640 this.state = parser2.getGoto(baseStateID, type, true);
1641 }
1642 while (this.stack.length > base)
1643 this.stack.pop();
1644 this.reduceContext(type, start);
1645 }
1646 // Shift a value into the buffer
1647 /**
1648 @internal
1649 */
1650 storeNode(term, start, end, size = 4, mustSink = false) {
1651 if (term == 0 && (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) {
1652 let cur = this, top = this.buffer.length;
1653 if (top == 0 && cur.parent) {
1654 top = cur.bufferBase - cur.parent.bufferBase;
1655 cur = cur.parent;
1656 }
1657 if (top > 0 && cur.buffer[top - 4] == 0 && cur.buffer[top - 1] > -1) {
1658 if (start == end)
1659 return;
1660 if (cur.buffer[top - 2] >= start) {
1661 cur.buffer[top - 2] = end;
1662 return;
1663 }
1664 }
1665 }
1666 if (!mustSink || this.pos == end) {
1667 this.buffer.push(term, start, end, size);
1668 } else {
1669 let index = this.buffer.length;
1670 if (index > 0 && (this.buffer[index - 4] != 0 || this.buffer[index - 1] < 0)) {
1671 let mustMove = false;
1672 for (let scan = index; scan > 0 && this.buffer[scan - 2] > end; scan -= 4) {
1673 if (this.buffer[scan - 1] >= 0) {
1674 mustMove = true;
1675 break;
1676 }
1677 }
1678 if (mustMove)
1679 while (index > 0 && this.buffer[index - 2] > end) {
1680 this.buffer[index] = this.buffer[index - 4];
1681 this.buffer[index + 1] = this.buffer[index - 3];
1682 this.buffer[index + 2] = this.buffer[index - 2];
1683 this.buffer[index + 3] = this.buffer[index - 1];
1684 index -= 4;
1685 if (size > 4)
1686 size -= 4;
1687 }
1688 }
1689 this.buffer[index] = term;
1690 this.buffer[index + 1] = start;
1691 this.buffer[index + 2] = end;
1692 this.buffer[index + 3] = size;
1693 }
1694 }
1695 // Apply a shift action
1696 /**
1697 @internal
1698 */
1699 shift(action, type, start, end) {
1700 if (action & 131072) {
1701 this.pushState(action & 65535, this.pos);
1702 } else if ((action & 262144) == 0) {
1703 let nextState = action, { parser: parser2 } = this.p;
1704 this.pos = end;
1705 let skipped = parser2.stateFlag(
1706 nextState,
1707 1
1708 /* StateFlag.Skipped */
1709 );
1710 if (!skipped && (end > start || type <= parser2.maxNode))
1711 this.reducePos = end;
1712 this.pushState(nextState, skipped ? start : Math.min(start, this.reducePos));
1713 this.shiftContext(type, start);
1714 if (type <= parser2.maxNode)
1715 this.buffer.push(type, start, end, 4);
1716 } else {
1717 this.pos = end;
1718 this.shiftContext(type, start);
1719 if (type <= this.p.parser.maxNode)
1720 this.buffer.push(type, start, end, 4);
1721 }
1722 }
1723 // Apply an action
1724 /**
1725 @internal
1726 */
1727 apply(action, next, nextStart, nextEnd) {
1728 if (action & 65536)
1729 this.reduce(action);
1730 else
1731 this.shift(action, next, nextStart, nextEnd);
1732 }
1733 // Add a prebuilt (reused) node into the buffer.
1734 /**
1735 @internal
1736 */
1737 useNode(value, next) {
1738 let index = this.p.reused.length - 1;
1739 if (index < 0 || this.p.reused[index] != value) {
1740 this.p.reused.push(value);
1741 index++;
1742 }
1743 let start = this.pos;
1744 this.reducePos = this.pos = start + value.length;
1745 this.pushState(next, start);
1746 this.buffer.push(
1747 index,
1748 start,
1749 this.reducePos,
1750 -1
1751 /* size == -1 means this is a reused value */
1752 );
1753 if (this.curContext)
1754 this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length)));
1755 }
1756 // Split the stack. Due to the buffer sharing and the fact
1757 // that `this.stack` tends to stay quite shallow, this isn't very
1758 // expensive.
1759 /**
1760 @internal
1761 */
1762 split() {
1763 let parent = this;
1764 let off = parent.buffer.length;
1765 while (off > 0 && parent.buffer[off - 2] > parent.reducePos)
1766 off -= 4;
1767 let buffer = parent.buffer.slice(off), base = parent.bufferBase + off;
1768 while (parent && base == parent.bufferBase)
1769 parent = parent.parent;
1770 return new _Stack(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent);
1771 }
1772 // Try to recover from an error by 'deleting' (ignoring) one token.
1773 /**
1774 @internal
1775 */
1776 recoverByDelete(next, nextEnd) {
1777 let isNode = next <= this.p.parser.maxNode;
1778 if (isNode)
1779 this.storeNode(next, this.pos, nextEnd, 4);
1780 this.storeNode(0, this.pos, nextEnd, isNode ? 8 : 4);
1781 this.pos = this.reducePos = nextEnd;
1782 this.score -= 190;
1783 }
1784 /**
1785 Check if the given term would be able to be shifted (optionally
1786 after some reductions) on this stack. This can be useful for
1787 external tokenizers that want to make sure they only provide a
1788 given token when it applies.
1789 */
1790 canShift(term) {
1791 for (let sim = new SimulatedStack(this); ; ) {
1792 let action = this.p.parser.stateSlot(
1793 sim.state,
1794 4
1795 /* ParseState.DefaultReduce */
1796 ) || this.p.parser.hasAction(sim.state, term);
1797 if (action == 0)
1798 return false;
1799 if ((action & 65536) == 0)
1800 return true;
1801 sim.reduce(action);
1802 }
1803 }
1804 // Apply up to Recover.MaxNext recovery actions that conceptually
1805 // inserts some missing token or rule.
1806 /**
1807 @internal
1808 */
1809 recoverByInsert(next) {
1810 if (this.stack.length >= 300)
1811 return [];
1812 let nextStates = this.p.parser.nextStates(this.state);
1813 if (nextStates.length > 4 << 1 || this.stack.length >= 120) {
1814 let best = [];
1815 for (let i = 0, s; i < nextStates.length; i += 2) {
1816 if ((s = nextStates[i + 1]) != this.state && this.p.parser.hasAction(s, next))
1817 best.push(nextStates[i], s);
1818 }
1819 if (this.stack.length < 120)
1820 for (let i = 0; best.length < 4 << 1 && i < nextStates.length; i += 2) {
1821 let s = nextStates[i + 1];
1822 if (!best.some((v, i2) => i2 & 1 && v == s))
1823 best.push(nextStates[i], s);
1824 }
1825 nextStates = best;
1826 }
1827 let result = [];
1828 for (let i = 0; i < nextStates.length && result.length < 4; i += 2) {
1829 let s = nextStates[i + 1];
1830 if (s == this.state)
1831 continue;
1832 let stack = this.split();
1833 stack.pushState(s, this.pos);
1834 stack.storeNode(0, stack.pos, stack.pos, 4, true);
1835 stack.shiftContext(nextStates[i], this.pos);
1836 stack.reducePos = this.pos;
1837 stack.score -= 200;
1838 result.push(stack);
1839 }
1840 return result;
1841 }
1842 // Force a reduce, if possible. Return false if that can't
1843 // be done.
1844 /**
1845 @internal
1846 */
1847 forceReduce() {
1848 let { parser: parser2 } = this.p;
1849 let reduce = parser2.stateSlot(
1850 this.state,
1851 5
1852 /* ParseState.ForcedReduce */
1853 );
1854 if ((reduce & 65536) == 0)
1855 return false;
1856 if (!parser2.validAction(this.state, reduce)) {
1857 let depth = reduce >> 19, term = reduce & 65535;
1858 let target = this.stack.length - depth * 3;
1859 if (target < 0 || parser2.getGoto(this.stack[target], term, false) < 0) {
1860 let backup = this.findForcedReduction();
1861 if (backup == null)
1862 return false;
1863 reduce = backup;
1864 }
1865 this.storeNode(0, this.pos, this.pos, 4, true);
1866 this.score -= 100;
1867 }
1868 this.reducePos = this.pos;
1869 this.reduce(reduce);
1870 return true;
1871 }
1872 /**
1873 Try to scan through the automaton to find some kind of reduction
1874 that can be applied. Used when the regular ForcedReduce field
1875 isn't a valid action. @internal
1876 */
1877 findForcedReduction() {
1878 let { parser: parser2 } = this.p, seen = [];
1879 let explore = (state, depth) => {
1880 if (seen.includes(state))
1881 return;
1882 seen.push(state);
1883 return parser2.allActions(state, (action) => {
1884 if (action & (262144 | 131072)) ;
1885 else if (action & 65536) {
1886 let rDepth = (action >> 19) - depth;
1887 if (rDepth > 1) {
1888 let term = action & 65535, target = this.stack.length - rDepth * 3;
1889 if (target >= 0 && parser2.getGoto(this.stack[target], term, false) >= 0)
1890 return rDepth << 19 | 65536 | term;
1891 }
1892 } else {
1893 let found = explore(action, depth + 1);
1894 if (found != null)
1895 return found;
1896 }
1897 });
1898 };
1899 return explore(this.state, 0);
1900 }
1901 /**
1902 @internal
1903 */
1904 forceAll() {
1905 while (!this.p.parser.stateFlag(
1906 this.state,
1907 2
1908 /* StateFlag.Accepting */
1909 )) {
1910 if (!this.forceReduce()) {
1911 this.storeNode(0, this.pos, this.pos, 4, true);
1912 break;
1913 }
1914 }
1915 return this;
1916 }
1917 /**
1918 Check whether this state has no further actions (assumed to be a direct descendant of the
1919 top state, since any other states must be able to continue
1920 somehow). @internal
1921 */
1922 get deadEnd() {
1923 if (this.stack.length != 3)
1924 return false;
1925 let { parser: parser2 } = this.p;
1926 return parser2.data[parser2.stateSlot(
1927 this.state,
1928 1
1929 /* ParseState.Actions */
1930 )] == 65535 && !parser2.stateSlot(
1931 this.state,
1932 4
1933 /* ParseState.DefaultReduce */
1934 );
1935 }
1936 /**
1937 Restart the stack (put it back in its start state). Only safe
1938 when this.stack.length == 3 (state is directly below the top
1939 state). @internal
1940 */
1941 restart() {
1942 this.storeNode(0, this.pos, this.pos, 4, true);
1943 this.state = this.stack[0];
1944 this.stack.length = 0;
1945 }
1946 /**
1947 @internal
1948 */
1949 sameState(other) {
1950 if (this.state != other.state || this.stack.length != other.stack.length)
1951 return false;
1952 for (let i = 0; i < this.stack.length; i += 3)
1953 if (this.stack[i] != other.stack[i])
1954 return false;
1955 return true;
1956 }
1957 /**
1958 Get the parser used by this stack.
1959 */
1960 get parser() {
1961 return this.p.parser;
1962 }
1963 /**
1964 Test whether a given dialect (by numeric ID, as exported from
1965 the terms file) is enabled.
1966 */
1967 dialectEnabled(dialectID) {
1968 return this.p.parser.dialect.flags[dialectID];
1969 }
1970 shiftContext(term, start) {
1971 if (this.curContext)
1972 this.updateContext(this.curContext.tracker.shift(this.curContext.context, term, this, this.p.stream.reset(start)));
1973 }
1974 reduceContext(term, start) {
1975 if (this.curContext)
1976 this.updateContext(this.curContext.tracker.reduce(this.curContext.context, term, this, this.p.stream.reset(start)));
1977 }
1978 /**
1979 @internal
1980 */
1981 emitContext() {
1982 let last = this.buffer.length - 1;
1983 if (last < 0 || this.buffer[last] != -3)
1984 this.buffer.push(this.curContext.hash, this.pos, this.pos, -3);
1985 }
1986 /**
1987 @internal
1988 */
1989 emitLookAhead() {
1990 let last = this.buffer.length - 1;
1991 if (last < 0 || this.buffer[last] != -4)
1992 this.buffer.push(this.lookAhead, this.pos, this.pos, -4);
1993 }
1994 updateContext(context) {
1995 if (context != this.curContext.context) {
1996 let newCx = new StackContext(this.curContext.tracker, context);
1997 if (newCx.hash != this.curContext.hash)
1998 this.emitContext();
1999 this.curContext = newCx;
2000 }
2001 }
2002 /**
2003 @internal
2004 */
2005 setLookAhead(lookAhead) {
2006 if (lookAhead <= this.lookAhead)
2007 return false;
2008 this.emitLookAhead();
2009 this.lookAhead = lookAhead;
2010 return true;
2011 }
2012 /**
2013 @internal
2014 */
2015 close() {
2016 if (this.curContext && this.curContext.tracker.strict)
2017 this.emitContext();
2018 if (this.lookAhead > 0)
2019 this.emitLookAhead();
2020 }
2021};
2022var StackContext = class {
2023 constructor(tracker, context) {
2024 this.tracker = tracker;
2025 this.context = context;
2026 this.hash = tracker.strict ? tracker.hash(context) : 0;
2027 }
2028};
2029var SimulatedStack = class {
2030 constructor(start) {
2031 this.start = start;
2032 this.state = start.state;
2033 this.stack = start.stack;
2034 this.base = this.stack.length;
2035 }
2036 reduce(action) {
2037 let term = action & 65535, depth = action >> 19;
2038 if (depth == 0) {
2039 if (this.stack == this.start.stack)
2040 this.stack = this.stack.slice();
2041 this.stack.push(this.state, 0, 0);
2042 this.base += 3;
2043 } else {
2044 this.base -= (depth - 1) * 3;
2045 }
2046 let goto = this.start.p.parser.getGoto(this.stack[this.base - 3], term, true);
2047 this.state = goto;
2048 }
2049};
2050var StackBufferCursor = class _StackBufferCursor {
2051 constructor(stack, pos, index) {
2052 this.stack = stack;
2053 this.pos = pos;
2054 this.index = index;
2055 this.buffer = stack.buffer;
2056 if (this.index == 0)
2057 this.maybeNext();
2058 }
2059 static create(stack, pos = stack.bufferBase + stack.buffer.length) {
2060 return new _StackBufferCursor(stack, pos, pos - stack.bufferBase);
2061 }
2062 maybeNext() {
2063 let next = this.stack.parent;
2064 if (next != null) {
2065 this.index = this.stack.bufferBase - next.bufferBase;
2066 this.stack = next;
2067 this.buffer = next.buffer;
2068 }
2069 }
2070 get id() {
2071 return this.buffer[this.index - 4];
2072 }
2073 get start() {
2074 return this.buffer[this.index - 3];
2075 }
2076 get end() {
2077 return this.buffer[this.index - 2];
2078 }
2079 get size() {
2080 return this.buffer[this.index - 1];
2081 }
2082 next() {
2083 this.index -= 4;
2084 this.pos -= 4;
2085 if (this.index == 0)
2086 this.maybeNext();
2087 }
2088 fork() {
2089 return new _StackBufferCursor(this.stack, this.pos, this.index);
2090 }
2091};
2092function decodeArray(input, Type = Uint16Array) {
2093 if (typeof input != "string")
2094 return input;
2095 let array = null;
2096 for (let pos = 0, out = 0; pos < input.length; ) {
2097 let value = 0;
2098 for (; ; ) {
2099 let next = input.charCodeAt(pos++), stop = false;
2100 if (next == 126) {
2101 value = 65535;
2102 break;
2103 }
2104 if (next >= 92)
2105 next--;
2106 if (next >= 34)
2107 next--;
2108 let digit = next - 32;
2109 if (digit >= 46) {
2110 digit -= 46;
2111 stop = true;
2112 }
2113 value += digit;
2114 if (stop)
2115 break;
2116 value *= 46;
2117 }
2118 if (array)
2119 array[out++] = value;
2120 else
2121 array = new Type(value);
2122 }
2123 return array;
2124}
2125var CachedToken = class {
2126 constructor() {
2127 this.start = -1;
2128 this.value = -1;
2129 this.end = -1;
2130 this.extended = -1;
2131 this.lookAhead = 0;
2132 this.mask = 0;
2133 this.context = 0;
2134 }
2135};
2136var nullToken = new CachedToken();
2137var InputStream = class {
2138 /**
2139 @internal
2140 */
2141 constructor(input, ranges) {
2142 this.input = input;
2143 this.ranges = ranges;
2144 this.chunk = "";
2145 this.chunkOff = 0;
2146 this.chunk2 = "";
2147 this.chunk2Pos = 0;
2148 this.next = -1;
2149 this.token = nullToken;
2150 this.rangeIndex = 0;
2151 this.pos = this.chunkPos = ranges[0].from;
2152 this.range = ranges[0];
2153 this.end = ranges[ranges.length - 1].to;
2154 this.readNext();
2155 }
2156 /**
2157 @internal
2158 */
2159 resolveOffset(offset, assoc) {
2160 let range = this.range, index = this.rangeIndex;
2161 let pos = this.pos + offset;
2162 while (pos < range.from) {
2163 if (!index)
2164 return null;
2165 let next = this.ranges[--index];
2166 pos -= range.from - next.to;
2167 range = next;
2168 }
2169 while (assoc < 0 ? pos > range.to : pos >= range.to) {
2170 if (index == this.ranges.length - 1)
2171 return null;
2172 let next = this.ranges[++index];
2173 pos += next.from - range.to;
2174 range = next;
2175 }
2176 return pos;
2177 }
2178 /**
2179 @internal
2180 */
2181 clipPos(pos) {
2182 if (pos >= this.range.from && pos < this.range.to)
2183 return pos;
2184 for (let range of this.ranges)
2185 if (range.to > pos)
2186 return Math.max(pos, range.from);
2187 return this.end;
2188 }
2189 /**
2190 Look at a code unit near the stream position. `.peek(0)` equals
2191 `.next`, `.peek(-1)` gives you the previous character, and so
2192 on.
2193
2194 Note that looking around during tokenizing creates dependencies
2195 on potentially far-away content, which may reduce the
2196 effectiveness incremental parsing—when looking forward—or even
2197 cause invalid reparses when looking backward more than 25 code
2198 units, since the library does not track lookbehind.
2199 */
2200 peek(offset) {
2201 let idx = this.chunkOff + offset, pos, result;
2202 if (idx >= 0 && idx < this.chunk.length) {
2203 pos = this.pos + offset;
2204 result = this.chunk.charCodeAt(idx);
2205 } else {
2206 let resolved = this.resolveOffset(offset, 1);
2207 if (resolved == null)
2208 return -1;
2209 pos = resolved;
2210 if (pos >= this.chunk2Pos && pos < this.chunk2Pos + this.chunk2.length) {
2211 result = this.chunk2.charCodeAt(pos - this.chunk2Pos);
2212 } else {
2213 let i = this.rangeIndex, range = this.range;
2214 while (range.to <= pos)
2215 range = this.ranges[++i];
2216 this.chunk2 = this.input.chunk(this.chunk2Pos = pos);
2217 if (pos + this.chunk2.length > range.to)
2218 this.chunk2 = this.chunk2.slice(0, range.to - pos);
2219 result = this.chunk2.charCodeAt(0);
2220 }
2221 }
2222 if (pos >= this.token.lookAhead)
2223 this.token.lookAhead = pos + 1;
2224 return result;
2225 }
2226 /**
2227 Accept a token. By default, the end of the token is set to the
2228 current stream position, but you can pass an offset (relative to
2229 the stream position) to change that.
2230 */
2231 acceptToken(token, endOffset = 0) {
2232 let end = endOffset ? this.resolveOffset(endOffset, -1) : this.pos;
2233 if (end == null || end < this.token.start)
2234 throw new RangeError("Token end out of bounds");
2235 this.token.value = token;
2236 this.token.end = end;
2237 }
2238 /**
2239 Accept a token ending at a specific given position.
2240 */
2241 acceptTokenTo(token, endPos) {
2242 this.token.value = token;
2243 this.token.end = endPos;
2244 }
2245 getChunk() {
2246 if (this.pos >= this.chunk2Pos && this.pos < this.chunk2Pos + this.chunk2.length) {
2247 let { chunk, chunkPos } = this;
2248 this.chunk = this.chunk2;
2249 this.chunkPos = this.chunk2Pos;
2250 this.chunk2 = chunk;
2251 this.chunk2Pos = chunkPos;
2252 this.chunkOff = this.pos - this.chunkPos;
2253 } else {
2254 this.chunk2 = this.chunk;
2255 this.chunk2Pos = this.chunkPos;
2256 let nextChunk = this.input.chunk(this.pos);
2257 let end = this.pos + nextChunk.length;
2258 this.chunk = end > this.range.to ? nextChunk.slice(0, this.range.to - this.pos) : nextChunk;
2259 this.chunkPos = this.pos;
2260 this.chunkOff = 0;
2261 }
2262 }
2263 readNext() {
2264 if (this.chunkOff >= this.chunk.length) {
2265 this.getChunk();
2266 if (this.chunkOff == this.chunk.length)
2267 return this.next = -1;
2268 }
2269 return this.next = this.chunk.charCodeAt(this.chunkOff);
2270 }
2271 /**
2272 Move the stream forward N (defaults to 1) code units. Returns
2273 the new value of [`next`](#lr.InputStream.next).
2274 */
2275 advance(n = 1) {
2276 this.chunkOff += n;
2277 while (this.pos + n >= this.range.to) {
2278 if (this.rangeIndex == this.ranges.length - 1)
2279 return this.setDone();
2280 n -= this.range.to - this.pos;
2281 this.range = this.ranges[++this.rangeIndex];
2282 this.pos = this.range.from;
2283 }
2284 this.pos += n;
2285 if (this.pos >= this.token.lookAhead)
2286 this.token.lookAhead = this.pos + 1;
2287 return this.readNext();
2288 }
2289 setDone() {
2290 this.pos = this.chunkPos = this.end;
2291 this.range = this.ranges[this.rangeIndex = this.ranges.length - 1];
2292 this.chunk = "";
2293 return this.next = -1;
2294 }
2295 /**
2296 @internal
2297 */
2298 reset(pos, token) {
2299 if (token) {
2300 this.token = token;
2301 token.start = pos;
2302 token.lookAhead = pos + 1;
2303 token.value = token.extended = -1;
2304 } else {
2305 this.token = nullToken;
2306 }
2307 if (this.pos != pos) {
2308 this.pos = pos;
2309 if (pos == this.end) {
2310 this.setDone();
2311 return this;
2312 }
2313 while (pos < this.range.from)
2314 this.range = this.ranges[--this.rangeIndex];
2315 while (pos >= this.range.to)
2316 this.range = this.ranges[++this.rangeIndex];
2317 if (pos >= this.chunkPos && pos < this.chunkPos + this.chunk.length) {
2318 this.chunkOff = pos - this.chunkPos;
2319 } else {
2320 this.chunk = "";
2321 this.chunkOff = 0;
2322 }
2323 this.readNext();
2324 }
2325 return this;
2326 }
2327 /**
2328 @internal
2329 */
2330 read(from, to) {
2331 if (from >= this.chunkPos && to <= this.chunkPos + this.chunk.length)
2332 return this.chunk.slice(from - this.chunkPos, to - this.chunkPos);
2333 if (from >= this.chunk2Pos && to <= this.chunk2Pos + this.chunk2.length)
2334 return this.chunk2.slice(from - this.chunk2Pos, to - this.chunk2Pos);
2335 if (from >= this.range.from && to <= this.range.to)
2336 return this.input.read(from, to);
2337 let result = "";
2338 for (let r of this.ranges) {
2339 if (r.from >= to)
2340 break;
2341 if (r.to > from)
2342 result += this.input.read(Math.max(r.from, from), Math.min(r.to, to));
2343 }
2344 return result;
2345 }
2346};
2347var TokenGroup = class {
2348 constructor(data, id) {
2349 this.data = data;
2350 this.id = id;
2351 }
2352 token(input, stack) {
2353 let { parser: parser2 } = stack.p;
2354 readToken(this.data, input, stack, this.id, parser2.data, parser2.tokenPrecTable);
2355 }
2356};
2357TokenGroup.prototype.contextual = TokenGroup.prototype.fallback = TokenGroup.prototype.extend = false;
2358var LocalTokenGroup = class {
2359 constructor(data, precTable, elseToken) {
2360 this.precTable = precTable;
2361 this.elseToken = elseToken;
2362 this.data = typeof data == "string" ? decodeArray(data) : data;
2363 }
2364 token(input, stack) {
2365 let start = input.pos, skipped = 0;
2366 for (; ; ) {
2367 let atEof = input.next < 0, nextPos = input.resolveOffset(1, 1);
2368 readToken(this.data, input, stack, 0, this.data, this.precTable);
2369 if (input.token.value > -1)
2370 break;
2371 if (this.elseToken == null)
2372 return;
2373 if (!atEof)
2374 skipped++;
2375 if (nextPos == null)
2376 break;
2377 input.reset(nextPos, input.token);
2378 }
2379 if (skipped) {
2380 input.reset(start, input.token);
2381 input.acceptToken(this.elseToken, skipped);
2382 }
2383 }
2384};
2385LocalTokenGroup.prototype.contextual = TokenGroup.prototype.fallback = TokenGroup.prototype.extend = false;
2386var ExternalTokenizer = class {
2387 /**
2388 Create a tokenizer. The first argument is the function that,
2389 given an input stream, scans for the types of tokens it
2390 recognizes at the stream's position, and calls
2391 [`acceptToken`](#lr.InputStream.acceptToken) when it finds
2392 one.
2393 */
2394 constructor(token, options = {}) {
2395 this.token = token;
2396 this.contextual = !!options.contextual;
2397 this.fallback = !!options.fallback;
2398 this.extend = !!options.extend;
2399 }
2400};
2401function readToken(data, input, stack, group, precTable, precOffset) {
2402 let state = 0, groupMask = 1 << group, { dialect } = stack.p.parser;
2403 scan: for (; ; ) {
2404 if ((groupMask & data[state]) == 0)
2405 break;
2406 let accEnd = data[state + 1];
2407 for (let i = state + 3; i < accEnd; i += 2)
2408 if ((data[i + 1] & groupMask) > 0) {
2409 let term = data[i];
2410 if (dialect.allows(term) && (input.token.value == -1 || input.token.value == term || overrides(term, input.token.value, precTable, precOffset))) {
2411 input.acceptToken(term);
2412 break;
2413 }
2414 }
2415 let next = input.next, low = 0, high = data[state + 2];
2416 if (input.next < 0 && high > low && data[accEnd + high * 3 - 3] == 65535) {
2417 state = data[accEnd + high * 3 - 1];
2418 continue scan;
2419 }
2420 for (; low < high; ) {
2421 let mid = low + high >> 1;
2422 let index = accEnd + mid + (mid << 1);
2423 let from = data[index], to = data[index + 1] || 65536;
2424 if (next < from)
2425 high = mid;
2426 else if (next >= to)
2427 low = mid + 1;
2428 else {
2429 state = data[index + 2];
2430 input.advance();
2431 continue scan;
2432 }
2433 }
2434 break;
2435 }
2436}
2437function findOffset(data, start, term) {
2438 for (let i = start, next; (next = data[i]) != 65535; i++)
2439 if (next == term)
2440 return i - start;
2441 return -1;
2442}
2443function overrides(token, prev, tableData, tableOffset) {
2444 let iPrev = findOffset(tableData, tableOffset, prev);
2445 return iPrev < 0 || findOffset(tableData, tableOffset, token) < iPrev;
2446}
2447var verbose = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG);
2448var stackIDs = null;
2449function cutAt(tree, pos, side) {
2450 let cursor = tree.cursor(IterMode.IncludeAnonymous);
2451 cursor.moveTo(pos);
2452 for (; ; ) {
2453 if (!(side < 0 ? cursor.childBefore(pos) : cursor.childAfter(pos)))
2454 for (; ; ) {
2455 if ((side < 0 ? cursor.to < pos : cursor.from > pos) && !cursor.type.isError)
2456 return side < 0 ? Math.max(0, Math.min(
2457 cursor.to - 1,
2458 pos - 25
2459 /* Lookahead.Margin */
2460 )) : Math.min(tree.length, Math.max(
2461 cursor.from + 1,
2462 pos + 25
2463 /* Lookahead.Margin */
2464 ));
2465 if (side < 0 ? cursor.prevSibling() : cursor.nextSibling())
2466 break;
2467 if (!cursor.parent())
2468 return side < 0 ? 0 : tree.length;
2469 }
2470 }
2471}
2472var FragmentCursor = class {
2473 constructor(fragments, nodeSet) {
2474 this.fragments = fragments;
2475 this.nodeSet = nodeSet;
2476 this.i = 0;
2477 this.fragment = null;
2478 this.safeFrom = -1;
2479 this.safeTo = -1;
2480 this.trees = [];
2481 this.start = [];
2482 this.index = [];
2483 this.nextFragment();
2484 }
2485 nextFragment() {
2486 let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++];
2487 if (fr) {
2488 this.safeFrom = fr.openStart ? cutAt(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from;
2489 this.safeTo = fr.openEnd ? cutAt(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to;
2490 while (this.trees.length) {
2491 this.trees.pop();
2492 this.start.pop();
2493 this.index.pop();
2494 }
2495 this.trees.push(fr.tree);
2496 this.start.push(-fr.offset);
2497 this.index.push(0);
2498 this.nextStart = this.safeFrom;
2499 } else {
2500 this.nextStart = 1e9;
2501 }
2502 }
2503 // `pos` must be >= any previously given `pos` for this cursor
2504 nodeAt(pos) {
2505 if (pos < this.nextStart)
2506 return null;
2507 while (this.fragment && this.safeTo <= pos)
2508 this.nextFragment();
2509 if (!this.fragment)
2510 return null;
2511 for (; ; ) {
2512 let last = this.trees.length - 1;
2513 if (last < 0) {
2514 this.nextFragment();
2515 return null;
2516 }
2517 let top = this.trees[last], index = this.index[last];
2518 if (index == top.children.length) {
2519 this.trees.pop();
2520 this.start.pop();
2521 this.index.pop();
2522 continue;
2523 }
2524 let next = top.children[index];
2525 let start = this.start[last] + top.positions[index];
2526 if (start > pos) {
2527 this.nextStart = start;
2528 return null;
2529 }
2530 if (next instanceof Tree) {
2531 if (start == pos) {
2532 if (start < this.safeFrom)
2533 return null;
2534 let end = start + next.length;
2535 if (end <= this.safeTo) {
2536 let lookAhead = next.prop(NodeProp.lookAhead);
2537 if (!lookAhead || end + lookAhead < this.fragment.to)
2538 return next;
2539 }
2540 }
2541 this.index[last]++;
2542 if (start + next.length >= Math.max(this.safeFrom, pos)) {
2543 this.trees.push(next);
2544 this.start.push(start);
2545 this.index.push(0);
2546 }
2547 } else {
2548 this.index[last]++;
2549 this.nextStart = start + next.length;
2550 }
2551 }
2552 }
2553};
2554var TokenCache = class {
2555 constructor(parser2, stream) {
2556 this.stream = stream;
2557 this.tokens = [];
2558 this.mainToken = null;
2559 this.actions = [];
2560 this.tokens = parser2.tokenizers.map((_) => new CachedToken());
2561 }
2562 getActions(stack) {
2563 let actionIndex = 0;
2564 let main = null;
2565 let { parser: parser2 } = stack.p, { tokenizers } = parser2;
2566 let mask = parser2.stateSlot(
2567 stack.state,
2568 3
2569 /* ParseState.TokenizerMask */
2570 );
2571 let context = stack.curContext ? stack.curContext.hash : 0;
2572 let lookAhead = 0;
2573 for (let i = 0; i < tokenizers.length; i++) {
2574 if ((1 << i & mask) == 0)
2575 continue;
2576 let tokenizer = tokenizers[i], token = this.tokens[i];
2577 if (main && !tokenizer.fallback)
2578 continue;
2579 if (tokenizer.contextual || token.start != stack.pos || token.mask != mask || token.context != context) {
2580 this.updateCachedToken(token, tokenizer, stack);
2581 token.mask = mask;
2582 token.context = context;
2583 }
2584 if (token.lookAhead > token.end + 25)
2585 lookAhead = Math.max(token.lookAhead, lookAhead);
2586 if (token.value != 0) {
2587 let startIndex = actionIndex;
2588 if (token.extended > -1)
2589 actionIndex = this.addActions(stack, token.extended, token.end, actionIndex);
2590 actionIndex = this.addActions(stack, token.value, token.end, actionIndex);
2591 if (!tokenizer.extend) {
2592 main = token;
2593 if (actionIndex > startIndex)
2594 break;
2595 }
2596 }
2597 }
2598 while (this.actions.length > actionIndex)
2599 this.actions.pop();
2600 if (lookAhead)
2601 stack.setLookAhead(lookAhead);
2602 if (!main && stack.pos == this.stream.end) {
2603 main = new CachedToken();
2604 main.value = stack.p.parser.eofTerm;
2605 main.start = main.end = stack.pos;
2606 actionIndex = this.addActions(stack, main.value, main.end, actionIndex);
2607 }
2608 this.mainToken = main;
2609 return this.actions;
2610 }
2611 getMainToken(stack) {
2612 if (this.mainToken)
2613 return this.mainToken;
2614 let main = new CachedToken(), { pos, p } = stack;
2615 main.start = pos;
2616 main.end = Math.min(pos + 1, p.stream.end);
2617 main.value = pos == p.stream.end ? p.parser.eofTerm : 0;
2618 return main;
2619 }
2620 updateCachedToken(token, tokenizer, stack) {
2621 let start = this.stream.clipPos(stack.pos);
2622 tokenizer.token(this.stream.reset(start, token), stack);
2623 if (token.value > -1) {
2624 let { parser: parser2 } = stack.p;
2625 for (let i = 0; i < parser2.specialized.length; i++)
2626 if (parser2.specialized[i] == token.value) {
2627 let result = parser2.specializers[i](this.stream.read(token.start, token.end), stack);
2628 if (result >= 0 && stack.p.parser.dialect.allows(result >> 1)) {
2629 if ((result & 1) == 0)
2630 token.value = result >> 1;
2631 else
2632 token.extended = result >> 1;
2633 break;
2634 }
2635 }
2636 } else {
2637 token.value = 0;
2638 token.end = this.stream.clipPos(start + 1);
2639 }
2640 }
2641 putAction(action, token, end, index) {
2642 for (let i = 0; i < index; i += 3)
2643 if (this.actions[i] == action)
2644 return index;
2645 this.actions[index++] = action;
2646 this.actions[index++] = token;
2647 this.actions[index++] = end;
2648 return index;
2649 }
2650 addActions(stack, token, end, index) {
2651 let { state } = stack, { parser: parser2 } = stack.p, { data } = parser2;
2652 for (let set = 0; set < 2; set++) {
2653 for (let i = parser2.stateSlot(
2654 state,
2655 set ? 2 : 1
2656 /* ParseState.Actions */
2657 ); ; i += 3) {
2658 if (data[i] == 65535) {
2659 if (data[i + 1] == 1) {
2660 i = pair(data, i + 2);
2661 } else {
2662 if (index == 0 && data[i + 1] == 2)
2663 index = this.putAction(pair(data, i + 2), token, end, index);
2664 break;
2665 }
2666 }
2667 if (data[i] == token)
2668 index = this.putAction(pair(data, i + 1), token, end, index);
2669 }
2670 }
2671 return index;
2672 }
2673};
2674var Parse = class {
2675 constructor(parser2, input, fragments, ranges) {
2676 this.parser = parser2;
2677 this.input = input;
2678 this.ranges = ranges;
2679 this.recovering = 0;
2680 this.nextStackID = 9812;
2681 this.minStackPos = 0;
2682 this.reused = [];
2683 this.stoppedAt = null;
2684 this.lastBigReductionStart = -1;
2685 this.lastBigReductionSize = 0;
2686 this.bigReductionCount = 0;
2687 this.stream = new InputStream(input, ranges);
2688 this.tokens = new TokenCache(parser2, this.stream);
2689 this.topTerm = parser2.top[1];
2690 let { from } = ranges[0];
2691 this.stacks = [Stack.start(this, parser2.top[0], from)];
2692 this.fragments = fragments.length && this.stream.end - from > parser2.bufferLength * 4 ? new FragmentCursor(fragments, parser2.nodeSet) : null;
2693 }
2694 get parsedPos() {
2695 return this.minStackPos;
2696 }
2697 // Move the parser forward. This will process all parse stacks at
2698 // `this.pos` and try to advance them to a further position. If no
2699 // stack for such a position is found, it'll start error-recovery.
2700 //
2701 // When the parse is finished, this will return a syntax tree. When
2702 // not, it returns `null`.
2703 advance() {
2704 let stacks = this.stacks, pos = this.minStackPos;
2705 let newStacks = this.stacks = [];
2706 let stopped, stoppedTokens;
2707 if (this.bigReductionCount > 300 && stacks.length == 1) {
2708 let [s] = stacks;
2709 while (s.forceReduce() && s.stack.length && s.stack[s.stack.length - 2] >= this.lastBigReductionStart) {
2710 }
2711 this.bigReductionCount = this.lastBigReductionSize = 0;
2712 }
2713 for (let i = 0; i < stacks.length; i++) {
2714 let stack = stacks[i];
2715 for (; ; ) {
2716 this.tokens.mainToken = null;
2717 if (stack.pos > pos) {
2718 newStacks.push(stack);
2719 } else if (this.advanceStack(stack, newStacks, stacks)) {
2720 continue;
2721 } else {
2722 if (!stopped) {
2723 stopped = [];
2724 stoppedTokens = [];
2725 }
2726 stopped.push(stack);
2727 let tok = this.tokens.getMainToken(stack);
2728 stoppedTokens.push(tok.value, tok.end);
2729 }
2730 break;
2731 }
2732 }
2733 if (!newStacks.length) {
2734 let finished = stopped && findFinished(stopped);
2735 if (finished) {
2736 if (verbose)
2737 console.log("Finish with " + this.stackID(finished));
2738 return this.stackToTree(finished);
2739 }
2740 if (this.parser.strict) {
2741 if (verbose && stopped)
2742 console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none"));
2743 throw new SyntaxError("No parse at " + pos);
2744 }
2745 if (!this.recovering)
2746 this.recovering = 5;
2747 }
2748 if (this.recovering && stopped) {
2749 let finished = this.stoppedAt != null && stopped[0].pos > this.stoppedAt ? stopped[0] : this.runRecovery(stopped, stoppedTokens, newStacks);
2750 if (finished) {
2751 if (verbose)
2752 console.log("Force-finish " + this.stackID(finished));
2753 return this.stackToTree(finished.forceAll());
2754 }
2755 }
2756 if (this.recovering) {
2757 let maxRemaining = this.recovering == 1 ? 1 : this.recovering * 3;
2758 if (newStacks.length > maxRemaining) {
2759 newStacks.sort((a2, b) => b.score - a2.score);
2760 while (newStacks.length > maxRemaining)
2761 newStacks.pop();
2762 }
2763 if (newStacks.some((s) => s.reducePos > pos))
2764 this.recovering--;
2765 } else if (newStacks.length > 1) {
2766 outer: for (let i = 0; i < newStacks.length - 1; i++) {
2767 let stack = newStacks[i];
2768 for (let j = i + 1; j < newStacks.length; j++) {
2769 let other = newStacks[j];
2770 if (stack.sameState(other) || stack.buffer.length > 500 && other.buffer.length > 500) {
2771 if ((stack.score - other.score || stack.buffer.length - other.buffer.length) > 0) {
2772 newStacks.splice(j--, 1);
2773 } else {
2774 newStacks.splice(i--, 1);
2775 continue outer;
2776 }
2777 }
2778 }
2779 }
2780 if (newStacks.length > 12) {
2781 newStacks.sort((a2, b) => b.score - a2.score);
2782 newStacks.splice(
2783 12,
2784 newStacks.length - 12
2785 /* Rec.MaxStackCount */
2786 );
2787 }
2788 }
2789 this.minStackPos = newStacks[0].pos;
2790 for (let i = 1; i < newStacks.length; i++)
2791 if (newStacks[i].pos < this.minStackPos)
2792 this.minStackPos = newStacks[i].pos;
2793 return null;
2794 }
2795 stopAt(pos) {
2796 if (this.stoppedAt != null && this.stoppedAt < pos)
2797 throw new RangeError("Can't move stoppedAt forward");
2798 this.stoppedAt = pos;
2799 }
2800 // Returns an updated version of the given stack, or null if the
2801 // stack can't advance normally. When `split` and `stacks` are
2802 // given, stacks split off by ambiguous operations will be pushed to
2803 // `split`, or added to `stacks` if they move `pos` forward.
2804 advanceStack(stack, stacks, split) {
2805 let start = stack.pos, { parser: parser2 } = this;
2806 let base = verbose ? this.stackID(stack) + " -> " : "";
2807 if (this.stoppedAt != null && start > this.stoppedAt)
2808 return stack.forceReduce() ? stack : null;
2809 if (this.fragments) {
2810 let strictCx = stack.curContext && stack.curContext.tracker.strict, cxHash = strictCx ? stack.curContext.hash : 0;
2811 for (let cached = this.fragments.nodeAt(start); cached; ) {
2812 let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser2.getGoto(stack.state, cached.type.id) : -1;
2813 if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) {
2814 stack.useNode(cached, match);
2815 if (verbose)
2816 console.log(base + this.stackID(stack) + ` (via reuse of ${parser2.getName(cached.type.id)})`);
2817 return true;
2818 }
2819 if (!(cached instanceof Tree) || cached.children.length == 0 || cached.positions[0] > 0)
2820 break;
2821 let inner = cached.children[0];
2822 if (inner instanceof Tree && cached.positions[0] == 0)
2823 cached = inner;
2824 else
2825 break;
2826 }
2827 }
2828 let defaultReduce = parser2.stateSlot(
2829 stack.state,
2830 4
2831 /* ParseState.DefaultReduce */
2832 );
2833 if (defaultReduce > 0) {
2834 stack.reduce(defaultReduce);
2835 if (verbose)
2836 console.log(base + this.stackID(stack) + ` (via always-reduce ${parser2.getName(
2837 defaultReduce & 65535
2838 /* Action.ValueMask */
2839 )})`);
2840 return true;
2841 }
2842 if (stack.stack.length >= 8400) {
2843 while (stack.stack.length > 6e3 && stack.forceReduce()) {
2844 }
2845 }
2846 let actions = this.tokens.getActions(stack);
2847 for (let i = 0; i < actions.length; ) {
2848 let action = actions[i++], term = actions[i++], end = actions[i++];
2849 let last = i == actions.length || !split;
2850 let localStack = last ? stack : stack.split();
2851 let main = this.tokens.mainToken;
2852 localStack.apply(action, term, main ? main.start : localStack.pos, end);
2853 if (verbose)
2854 console.log(base + this.stackID(localStack) + ` (via ${(action & 65536) == 0 ? "shift" : `reduce of ${parser2.getName(
2855 action & 65535
2856 /* Action.ValueMask */
2857 )}`} for ${parser2.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`);
2858 if (last)
2859 return true;
2860 else if (localStack.pos > start)
2861 stacks.push(localStack);
2862 else
2863 split.push(localStack);
2864 }
2865 return false;
2866 }
2867 // Advance a given stack forward as far as it will go. Returns the
2868 // (possibly updated) stack if it got stuck, or null if it moved
2869 // forward and was given to `pushStackDedup`.
2870 advanceFully(stack, newStacks) {
2871 let pos = stack.pos;
2872 for (; ; ) {
2873 if (!this.advanceStack(stack, null, null))
2874 return false;
2875 if (stack.pos > pos) {
2876 pushStackDedup(stack, newStacks);
2877 return true;
2878 }
2879 }
2880 }
2881 runRecovery(stacks, tokens, newStacks) {
2882 let finished = null, restarted = false;
2883 for (let i = 0; i < stacks.length; i++) {
2884 let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1];
2885 let base = verbose ? this.stackID(stack) + " -> " : "";
2886 if (stack.deadEnd) {
2887 if (restarted)
2888 continue;
2889 restarted = true;
2890 stack.restart();
2891 if (verbose)
2892 console.log(base + this.stackID(stack) + " (restarted)");
2893 let done = this.advanceFully(stack, newStacks);
2894 if (done)
2895 continue;
2896 }
2897 let force = stack.split(), forceBase = base;
2898 for (let j = 0; j < 10 && force.forceReduce(); j++) {
2899 if (verbose)
2900 console.log(forceBase + this.stackID(force) + " (via force-reduce)");
2901 let done = this.advanceFully(force, newStacks);
2902 if (done)
2903 break;
2904 if (verbose)
2905 forceBase = this.stackID(force) + " -> ";
2906 }
2907 for (let insert of stack.recoverByInsert(token)) {
2908 if (verbose)
2909 console.log(base + this.stackID(insert) + " (via recover-insert)");
2910 this.advanceFully(insert, newStacks);
2911 }
2912 if (this.stream.end > stack.pos) {
2913 if (tokenEnd == stack.pos) {
2914 tokenEnd++;
2915 token = 0;
2916 }
2917 stack.recoverByDelete(token, tokenEnd);
2918 if (verbose)
2919 console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`);
2920 pushStackDedup(stack, newStacks);
2921 } else if (!finished || finished.score < force.score) {
2922 finished = force;
2923 }
2924 }
2925 return finished;
2926 }
2927 // Convert the stack's buffer to a syntax tree.
2928 stackToTree(stack) {
2929 stack.close();
2930 return Tree.build({
2931 buffer: StackBufferCursor.create(stack),
2932 nodeSet: this.parser.nodeSet,
2933 topID: this.topTerm,
2934 maxBufferLength: this.parser.bufferLength,
2935 reused: this.reused,
2936 start: this.ranges[0].from,
2937 length: stack.pos - this.ranges[0].from,
2938 minRepeatType: this.parser.minRepeatTerm
2939 });
2940 }
2941 stackID(stack) {
2942 let id = (stackIDs || (stackIDs = /* @__PURE__ */ new WeakMap())).get(stack);
2943 if (!id)
2944 stackIDs.set(stack, id = String.fromCodePoint(this.nextStackID++));
2945 return id + stack;
2946 }
2947};
2948function pushStackDedup(stack, newStacks) {
2949 for (let i = 0; i < newStacks.length; i++) {
2950 let other = newStacks[i];
2951 if (other.pos == stack.pos && other.sameState(stack)) {
2952 if (newStacks[i].score < stack.score)
2953 newStacks[i] = stack;
2954 return;
2955 }
2956 }
2957 newStacks.push(stack);
2958}
2959var Dialect = class {
2960 constructor(source, flags, disabled) {
2961 this.source = source;
2962 this.flags = flags;
2963 this.disabled = disabled;
2964 }
2965 allows(term) {
2966 return !this.disabled || this.disabled[term] == 0;
2967 }
2968};
2969var LRParser = class _LRParser extends Parser {
2970 /**
2971 @internal
2972 */
2973 constructor(spec) {
2974 super();
2975 this.wrappers = [];
2976 if (spec.version != 14)
2977 throw new RangeError(`Parser version (${spec.version}) doesn't match runtime version (${14})`);
2978 let nodeNames = spec.nodeNames.split(" ");
2979 this.minRepeatTerm = nodeNames.length;
2980 for (let i = 0; i < spec.repeatNodeCount; i++)
2981 nodeNames.push("");
2982 let topTerms = Object.keys(spec.topRules).map((r) => spec.topRules[r][1]);
2983 let nodeProps = [];
2984 for (let i = 0; i < nodeNames.length; i++)
2985 nodeProps.push([]);
2986 function setProp(nodeID, prop, value) {
2987 nodeProps[nodeID].push([prop, prop.deserialize(String(value))]);
2988 }
2989 if (spec.nodeProps)
2990 for (let propSpec of spec.nodeProps) {
2991 let prop = propSpec[0];
2992 if (typeof prop == "string")
2993 prop = NodeProp[prop];
2994 for (let i = 1; i < propSpec.length; ) {
2995 let next = propSpec[i++];
2996 if (next >= 0) {
2997 setProp(next, prop, propSpec[i++]);
2998 } else {
2999 let value = propSpec[i + -next];
3000 for (let j = -next; j > 0; j--)
3001 setProp(propSpec[i++], prop, value);
3002 i++;
3003 }
3004 }
3005 }
3006 this.nodeSet = new NodeSet(nodeNames.map((name2, i) => NodeType.define({
3007 name: i >= this.minRepeatTerm ? void 0 : name2,
3008 id: i,
3009 props: nodeProps[i],
3010 top: topTerms.indexOf(i) > -1,
3011 error: i == 0,
3012 skipped: spec.skippedNodes && spec.skippedNodes.indexOf(i) > -1
3013 })));
3014 if (spec.propSources)
3015 this.nodeSet = this.nodeSet.extend(...spec.propSources);
3016 this.strict = false;
3017 this.bufferLength = DefaultBufferLength;
3018 let tokenArray = decodeArray(spec.tokenData);
3019 this.context = spec.context;
3020 this.specializerSpecs = spec.specialized || [];
3021 this.specialized = new Uint16Array(this.specializerSpecs.length);
3022 for (let i = 0; i < this.specializerSpecs.length; i++)
3023 this.specialized[i] = this.specializerSpecs[i].term;
3024 this.specializers = this.specializerSpecs.map(getSpecializer);
3025 this.states = decodeArray(spec.states, Uint32Array);
3026 this.data = decodeArray(spec.stateData);
3027 this.goto = decodeArray(spec.goto);
3028 this.maxTerm = spec.maxTerm;
3029 this.tokenizers = spec.tokenizers.map((value) => typeof value == "number" ? new TokenGroup(tokenArray, value) : value);
3030 this.topRules = spec.topRules;
3031 this.dialects = spec.dialects || {};
3032 this.dynamicPrecedences = spec.dynamicPrecedences || null;
3033 this.tokenPrecTable = spec.tokenPrec;
3034 this.termNames = spec.termNames || null;
3035 this.maxNode = this.nodeSet.types.length - 1;
3036 this.dialect = this.parseDialect();
3037 this.top = this.topRules[Object.keys(this.topRules)[0]];
3038 }
3039 createParse(input, fragments, ranges) {
3040 let parse = new Parse(this, input, fragments, ranges);
3041 for (let w of this.wrappers)
3042 parse = w(parse, input, fragments, ranges);
3043 return parse;
3044 }
3045 /**
3046 Get a goto table entry @internal
3047 */
3048 getGoto(state, term, loose = false) {
3049 let table = this.goto;
3050 if (term >= table[0])
3051 return -1;
3052 for (let pos = table[term + 1]; ; ) {
3053 let groupTag = table[pos++], last = groupTag & 1;
3054 let target = table[pos++];
3055 if (last && loose)
3056 return target;
3057 for (let end = pos + (groupTag >> 1); pos < end; pos++)
3058 if (table[pos] == state)
3059 return target;
3060 if (last)
3061 return -1;
3062 }
3063 }
3064 /**
3065 Check if this state has an action for a given terminal @internal
3066 */
3067 hasAction(state, terminal) {
3068 let data = this.data;
3069 for (let set = 0; set < 2; set++) {
3070 for (let i = this.stateSlot(
3071 state,
3072 set ? 2 : 1
3073 /* ParseState.Actions */
3074 ), next; ; i += 3) {
3075 if ((next = data[i]) == 65535) {
3076 if (data[i + 1] == 1)
3077 next = data[i = pair(data, i + 2)];
3078 else if (data[i + 1] == 2)
3079 return pair(data, i + 2);
3080 else
3081 break;
3082 }
3083 if (next == terminal || next == 0)
3084 return pair(data, i + 1);
3085 }
3086 }
3087 return 0;
3088 }
3089 /**
3090 @internal
3091 */
3092 stateSlot(state, slot) {
3093 return this.states[state * 6 + slot];
3094 }
3095 /**
3096 @internal
3097 */
3098 stateFlag(state, flag) {
3099 return (this.stateSlot(
3100 state,
3101 0
3102 /* ParseState.Flags */
3103 ) & flag) > 0;
3104 }
3105 /**
3106 @internal
3107 */
3108 validAction(state, action) {
3109 return !!this.allActions(state, (a2) => a2 == action ? true : null);
3110 }
3111 /**
3112 @internal
3113 */
3114 allActions(state, action) {
3115 let deflt = this.stateSlot(
3116 state,
3117 4
3118 /* ParseState.DefaultReduce */
3119 );
3120 let result = deflt ? action(deflt) : void 0;
3121 for (let i = this.stateSlot(
3122 state,
3123 1
3124 /* ParseState.Actions */
3125 ); result == null; i += 3) {
3126 if (this.data[i] == 65535) {
3127 if (this.data[i + 1] == 1)
3128 i = pair(this.data, i + 2);
3129 else
3130 break;
3131 }
3132 result = action(pair(this.data, i + 1));
3133 }
3134 return result;
3135 }
3136 /**
3137 Get the states that can follow this one through shift actions or
3138 goto jumps. @internal
3139 */
3140 nextStates(state) {
3141 let result = [];
3142 for (let i = this.stateSlot(
3143 state,
3144 1
3145 /* ParseState.Actions */
3146 ); ; i += 3) {
3147 if (this.data[i] == 65535) {
3148 if (this.data[i + 1] == 1)
3149 i = pair(this.data, i + 2);
3150 else
3151 break;
3152 }
3153 if ((this.data[i + 2] & 65536 >> 16) == 0) {
3154 let value = this.data[i + 1];
3155 if (!result.some((v, i2) => i2 & 1 && v == value))
3156 result.push(this.data[i], value);
3157 }
3158 }
3159 return result;
3160 }
3161 /**
3162 Configure the parser. Returns a new parser instance that has the
3163 given settings modified. Settings not provided in `config` are
3164 kept from the original parser.
3165 */
3166 configure(config) {
3167 let copy = Object.assign(Object.create(_LRParser.prototype), this);
3168 if (config.props)
3169 copy.nodeSet = this.nodeSet.extend(...config.props);
3170 if (config.top) {
3171 let info = this.topRules[config.top];
3172 if (!info)
3173 throw new RangeError(`Invalid top rule name ${config.top}`);
3174 copy.top = info;
3175 }
3176 if (config.tokenizers)
3177 copy.tokenizers = this.tokenizers.map((t2) => {
3178 let found = config.tokenizers.find((r) => r.from == t2);
3179 return found ? found.to : t2;
3180 });
3181 if (config.specializers) {
3182 copy.specializers = this.specializers.slice();
3183 copy.specializerSpecs = this.specializerSpecs.map((s, i) => {
3184 let found = config.specializers.find((r) => r.from == s.external);
3185 if (!found)
3186 return s;
3187 let spec = Object.assign(Object.assign({}, s), { external: found.to });
3188 copy.specializers[i] = getSpecializer(spec);
3189 return spec;
3190 });
3191 }
3192 if (config.contextTracker)
3193 copy.context = config.contextTracker;
3194 if (config.dialect)
3195 copy.dialect = this.parseDialect(config.dialect);
3196 if (config.strict != null)
3197 copy.strict = config.strict;
3198 if (config.wrap)
3199 copy.wrappers = copy.wrappers.concat(config.wrap);
3200 if (config.bufferLength != null)
3201 copy.bufferLength = config.bufferLength;
3202 return copy;
3203 }
3204 /**
3205 Tells you whether any [parse wrappers](#lr.ParserConfig.wrap)
3206 are registered for this parser.
3207 */
3208 hasWrappers() {
3209 return this.wrappers.length > 0;
3210 }
3211 /**
3212 Returns the name associated with a given term. This will only
3213 work for all terms when the parser was generated with the
3214 `--names` option. By default, only the names of tagged terms are
3215 stored.
3216 */
3217 getName(term) {
3218 return this.termNames ? this.termNames[term] : String(term <= this.maxNode && this.nodeSet.types[term].name || term);
3219 }
3220 /**
3221 The eof term id is always allocated directly after the node
3222 types. @internal
3223 */
3224 get eofTerm() {
3225 return this.maxNode + 1;
3226 }
3227 /**
3228 The type of top node produced by the parser.
3229 */
3230 get topNode() {
3231 return this.nodeSet.types[this.top[1]];
3232 }
3233 /**
3234 @internal
3235 */
3236 dynamicPrecedence(term) {
3237 let prec = this.dynamicPrecedences;
3238 return prec == null ? 0 : prec[term] || 0;
3239 }
3240 /**
3241 @internal
3242 */
3243 parseDialect(dialect) {
3244 let values = Object.keys(this.dialects), flags = values.map(() => false);
3245 if (dialect)
3246 for (let part of dialect.split(" ")) {
3247 let id = values.indexOf(part);
3248 if (id >= 0)
3249 flags[id] = true;
3250 }
3251 let disabled = null;
3252 for (let i = 0; i < values.length; i++)
3253 if (!flags[i]) {
3254 for (let j = this.dialects[values[i]], id; (id = this.data[j++]) != 65535; )
3255 (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id] = 1;
3256 }
3257 return new Dialect(dialect, flags, disabled);
3258 }
3259 /**
3260 Used by the output of the parser generator. Not available to
3261 user code. @hide
3262 */
3263 static deserialize(spec) {
3264 return new _LRParser(spec);
3265 }
3266};
3267function pair(data, off) {
3268 return data[off] | data[off + 1] << 16;
3269}
3270function findFinished(stacks) {
3271 let best = null;
3272 for (let stack of stacks) {
3273 let stopped = stack.p.stoppedAt;
3274 if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && stack.p.parser.stateFlag(
3275 stack.state,
3276 2
3277 /* StateFlag.Accepting */
3278 ) && (!best || best.score < stack.score))
3279 best = stack;
3280 }
3281 return best;
3282}
3283function getSpecializer(spec) {
3284 if (spec.external) {
3285 let mask = spec.extend ? 1 : 0;
3286 return (value, stack) => spec.external(value, stack) << 1 | mask;
3287 }
3288 return spec.get;
3289}
3290
3291// node_modules/@lezer/highlight/dist/index.js
3292var nextTagID = 0;
3293var Tag = class _Tag {
3294 /**
3295 @internal
3296 */
3297 constructor(name2, set, base, modified) {
3298 this.name = name2;
3299 this.set = set;
3300 this.base = base;
3301 this.modified = modified;
3302 this.id = nextTagID++;
3303 }
3304 toString() {
3305 let { name: name2 } = this;
3306 for (let mod of this.modified)
3307 if (mod.name)
3308 name2 = `${mod.name}(${name2})`;
3309 return name2;
3310 }
3311 static define(nameOrParent, parent) {
3312 let name2 = typeof nameOrParent == "string" ? nameOrParent : "?";
3313 if (nameOrParent instanceof _Tag)
3314 parent = nameOrParent;
3315 if (parent === null || parent === void 0 ? void 0 : parent.base)
3316 throw new Error("Can not derive from a modified tag");
3317 let tag = new _Tag(name2, [], null, []);
3318 tag.set.push(tag);
3319 if (parent)
3320 for (let t2 of parent.set)
3321 tag.set.push(t2);
3322 return tag;
3323 }
3324 /**
3325 Define a tag _modifier_, which is a function that, given a tag,
3326 will return a tag that is a subtag of the original. Applying the
3327 same modifier to a twice tag will return the same value (`m1(t1)
3328 == m1(t1)`) and applying multiple modifiers will, regardless or
3329 order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
3330
3331 When multiple modifiers are applied to a given base tag, each
3332 smaller set of modifiers is registered as a parent, so that for
3333 example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
3334 `m1(m3(t1)`, and so on.
3335 */
3336 static defineModifier(name2) {
3337 let mod = new Modifier(name2);
3338 return (tag) => {
3339 if (tag.modified.indexOf(mod) > -1)
3340 return tag;
3341 return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a2, b) => a2.id - b.id));
3342 };
3343 }
3344};
3345var nextModifierID = 0;
3346var Modifier = class _Modifier {
3347 constructor(name2) {
3348 this.name = name2;
3349 this.instances = [];
3350 this.id = nextModifierID++;
3351 }
3352 static get(base, mods) {
3353 if (!mods.length)
3354 return base;
3355 let exists = mods[0].instances.find((t2) => t2.base == base && sameArray(mods, t2.modified));
3356 if (exists)
3357 return exists;
3358 let set = [], tag = new Tag(base.name, set, base, mods);
3359 for (let m of mods)
3360 m.instances.push(tag);
3361 let configs = powerSet(mods);
3362 for (let parent of base.set)
3363 if (!parent.modified.length)
3364 for (let config of configs)
3365 set.push(_Modifier.get(parent, config));
3366 return tag;
3367 }
3368};
3369function sameArray(a2, b) {
3370 return a2.length == b.length && a2.every((x, i) => x == b[i]);
3371}
3372function powerSet(array) {
3373 let sets = [[]];
3374 for (let i = 0; i < array.length; i++) {
3375 for (let j = 0, e = sets.length; j < e; j++) {
3376 sets.push(sets[j].concat(array[i]));
3377 }
3378 }
3379 return sets.sort((a2, b) => b.length - a2.length);
3380}
3381function styleTags(spec) {
3382 let byName = /* @__PURE__ */ Object.create(null);
3383 for (let prop in spec) {
3384 let tags2 = spec[prop];
3385 if (!Array.isArray(tags2))
3386 tags2 = [tags2];
3387 for (let part of prop.split(" "))
3388 if (part) {
3389 let pieces = [], mode = 2, rest = part;
3390 for (let pos = 0; ; ) {
3391 if (rest == "..." && pos > 0 && pos + 3 == part.length) {
3392 mode = 1;
3393 break;
3394 }
3395 let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
3396 if (!m)
3397 throw new RangeError("Invalid path: " + part);
3398 pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]);
3399 pos += m[0].length;
3400 if (pos == part.length)
3401 break;
3402 let next = part[pos++];
3403 if (pos == part.length && next == "!") {
3404 mode = 0;
3405 break;
3406 }
3407 if (next != "/")
3408 throw new RangeError("Invalid path: " + part);
3409 rest = part.slice(pos);
3410 }
3411 let last = pieces.length - 1, inner = pieces[last];
3412 if (!inner)
3413 throw new RangeError("Invalid path: " + part);
3414 let rule = new Rule(tags2, mode, last > 0 ? pieces.slice(0, last) : null);
3415 byName[inner] = rule.sort(byName[inner]);
3416 }
3417 }
3418 return ruleNodeProp.add(byName);
3419}
3420var ruleNodeProp = new NodeProp({
3421 combine(a2, b) {
3422 let cur, root, take;
3423 while (a2 || b) {
3424 if (!a2 || b && a2.depth >= b.depth) {
3425 take = b;
3426 b = b.next;
3427 } else {
3428 take = a2;
3429 a2 = a2.next;
3430 }
3431 if (cur && cur.mode == take.mode && !take.context && !cur.context)
3432 continue;
3433 let copy = new Rule(take.tags, take.mode, take.context);
3434 if (cur)
3435 cur.next = copy;
3436 else
3437 root = copy;
3438 cur = copy;
3439 }
3440 return root;
3441 }
3442});
3443var Rule = class {
3444 constructor(tags2, mode, context, next) {
3445 this.tags = tags2;
3446 this.mode = mode;
3447 this.context = context;
3448 this.next = next;
3449 }
3450 get opaque() {
3451 return this.mode == 0;
3452 }
3453 get inherit() {
3454 return this.mode == 1;
3455 }
3456 sort(other) {
3457 if (!other || other.depth < this.depth) {
3458 this.next = other;
3459 return this;
3460 }
3461 other.next = this.sort(other.next);
3462 return other;
3463 }
3464 get depth() {
3465 return this.context ? this.context.length : 0;
3466 }
3467};
3468Rule.empty = new Rule([], 2, null);
3469function tagHighlighter(tags2, options) {
3470 let map = /* @__PURE__ */ Object.create(null);
3471 for (let style of tags2) {
3472 if (!Array.isArray(style.tag))
3473 map[style.tag.id] = style.class;
3474 else
3475 for (let tag of style.tag)
3476 map[tag.id] = style.class;
3477 }
3478 let { scope, all = null } = options || {};
3479 return {
3480 style: (tags3) => {
3481 let cls = all;
3482 for (let tag of tags3) {
3483 for (let sub of tag.set) {
3484 let tagClass = map[sub.id];
3485 if (tagClass) {
3486 cls = cls ? cls + " " + tagClass : tagClass;
3487 break;
3488 }
3489 }
3490 }
3491 return cls;
3492 },
3493 scope
3494 };
3495}
3496var t = Tag.define;
3497var comment = t();
3498var name = t();
3499var typeName = t(name);
3500var propertyName = t(name);
3501var literal = t();
3502var string = t(literal);
3503var number = t(literal);
3504var content = t();
3505var heading = t(content);
3506var keyword = t();
3507var operator = t();
3508var punctuation = t();
3509var bracket = t(punctuation);
3510var meta = t();
3511var tags = {
3512 /**
3513 A comment.
3514 */
3515 comment,
3516 /**
3517 A line [comment](#highlight.tags.comment).
3518 */
3519 lineComment: t(comment),
3520 /**
3521 A block [comment](#highlight.tags.comment).
3522 */
3523 blockComment: t(comment),
3524 /**
3525 A documentation [comment](#highlight.tags.comment).
3526 */
3527 docComment: t(comment),
3528 /**
3529 Any kind of identifier.
3530 */
3531 name,
3532 /**
3533 The [name](#highlight.tags.name) of a variable.
3534 */
3535 variableName: t(name),
3536 /**
3537 A type [name](#highlight.tags.name).
3538 */
3539 typeName,
3540 /**
3541 A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
3542 */
3543 tagName: t(typeName),
3544 /**
3545 A property or field [name](#highlight.tags.name).
3546 */
3547 propertyName,
3548 /**
3549 An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
3550 */
3551 attributeName: t(propertyName),
3552 /**
3553 The [name](#highlight.tags.name) of a class.
3554 */
3555 className: t(name),
3556 /**
3557 A label [name](#highlight.tags.name).
3558 */
3559 labelName: t(name),
3560 /**
3561 A namespace [name](#highlight.tags.name).
3562 */
3563 namespace: t(name),
3564 /**
3565 The [name](#highlight.tags.name) of a macro.
3566 */
3567 macroName: t(name),
3568 /**
3569 A literal value.
3570 */
3571 literal,
3572 /**
3573 A string [literal](#highlight.tags.literal).
3574 */
3575 string,
3576 /**
3577 A documentation [string](#highlight.tags.string).
3578 */
3579 docString: t(string),
3580 /**
3581 A character literal (subtag of [string](#highlight.tags.string)).
3582 */
3583 character: t(string),
3584 /**
3585 An attribute value (subtag of [string](#highlight.tags.string)).
3586 */
3587 attributeValue: t(string),
3588 /**
3589 A number [literal](#highlight.tags.literal).
3590 */
3591 number,
3592 /**
3593 An integer [number](#highlight.tags.number) literal.
3594 */
3595 integer: t(number),
3596 /**
3597 A floating-point [number](#highlight.tags.number) literal.
3598 */
3599 float: t(number),
3600 /**
3601 A boolean [literal](#highlight.tags.literal).
3602 */
3603 bool: t(literal),
3604 /**
3605 Regular expression [literal](#highlight.tags.literal).
3606 */
3607 regexp: t(literal),
3608 /**
3609 An escape [literal](#highlight.tags.literal), for example a
3610 backslash escape in a string.
3611 */
3612 escape: t(literal),
3613 /**
3614 A color [literal](#highlight.tags.literal).
3615 */
3616 color: t(literal),
3617 /**
3618 A URL [literal](#highlight.tags.literal).
3619 */
3620 url: t(literal),
3621 /**
3622 A language keyword.
3623 */
3624 keyword,
3625 /**
3626 The [keyword](#highlight.tags.keyword) for the self or this
3627 object.
3628 */
3629 self: t(keyword),
3630 /**
3631 The [keyword](#highlight.tags.keyword) for null.
3632 */
3633 null: t(keyword),
3634 /**
3635 A [keyword](#highlight.tags.keyword) denoting some atomic value.
3636 */
3637 atom: t(keyword),
3638 /**
3639 A [keyword](#highlight.tags.keyword) that represents a unit.
3640 */
3641 unit: t(keyword),
3642 /**
3643 A modifier [keyword](#highlight.tags.keyword).
3644 */
3645 modifier: t(keyword),
3646 /**
3647 A [keyword](#highlight.tags.keyword) that acts as an operator.
3648 */
3649 operatorKeyword: t(keyword),
3650 /**
3651 A control-flow related [keyword](#highlight.tags.keyword).
3652 */
3653 controlKeyword: t(keyword),
3654 /**
3655 A [keyword](#highlight.tags.keyword) that defines something.
3656 */
3657 definitionKeyword: t(keyword),
3658 /**
3659 A [keyword](#highlight.tags.keyword) related to defining or
3660 interfacing with modules.
3661 */
3662 moduleKeyword: t(keyword),
3663 /**
3664 An operator.
3665 */
3666 operator,
3667 /**
3668 An [operator](#highlight.tags.operator) that dereferences something.
3669 */
3670 derefOperator: t(operator),
3671 /**
3672 Arithmetic-related [operator](#highlight.tags.operator).
3673 */
3674 arithmeticOperator: t(operator),
3675 /**
3676 Logical [operator](#highlight.tags.operator).
3677 */
3678 logicOperator: t(operator),
3679 /**
3680 Bit [operator](#highlight.tags.operator).
3681 */
3682 bitwiseOperator: t(operator),
3683 /**
3684 Comparison [operator](#highlight.tags.operator).
3685 */
3686 compareOperator: t(operator),
3687 /**
3688 [Operator](#highlight.tags.operator) that updates its operand.
3689 */
3690 updateOperator: t(operator),
3691 /**
3692 [Operator](#highlight.tags.operator) that defines something.
3693 */
3694 definitionOperator: t(operator),
3695 /**
3696 Type-related [operator](#highlight.tags.operator).
3697 */
3698 typeOperator: t(operator),
3699 /**
3700 Control-flow [operator](#highlight.tags.operator).
3701 */
3702 controlOperator: t(operator),
3703 /**
3704 Program or markup punctuation.
3705 */
3706 punctuation,
3707 /**
3708 [Punctuation](#highlight.tags.punctuation) that separates
3709 things.
3710 */
3711 separator: t(punctuation),
3712 /**
3713 Bracket-style [punctuation](#highlight.tags.punctuation).
3714 */
3715 bracket,
3716 /**
3717 Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
3718 tokens).
3719 */
3720 angleBracket: t(bracket),
3721 /**
3722 Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
3723 tokens).
3724 */
3725 squareBracket: t(bracket),
3726 /**
3727 Parentheses (usually `(` and `)` tokens). Subtag of
3728 [bracket](#highlight.tags.bracket).
3729 */
3730 paren: t(bracket),
3731 /**
3732 Braces (usually `{` and `}` tokens). Subtag of
3733 [bracket](#highlight.tags.bracket).
3734 */
3735 brace: t(bracket),
3736 /**
3737 Content, for example plain text in XML or markup documents.
3738 */
3739 content,
3740 /**
3741 [Content](#highlight.tags.content) that represents a heading.
3742 */
3743 heading,
3744 /**
3745 A level 1 [heading](#highlight.tags.heading).
3746 */
3747 heading1: t(heading),
3748 /**
3749 A level 2 [heading](#highlight.tags.heading).
3750 */
3751 heading2: t(heading),
3752 /**
3753 A level 3 [heading](#highlight.tags.heading).
3754 */
3755 heading3: t(heading),
3756 /**
3757 A level 4 [heading](#highlight.tags.heading).
3758 */
3759 heading4: t(heading),
3760 /**
3761 A level 5 [heading](#highlight.tags.heading).
3762 */
3763 heading5: t(heading),
3764 /**
3765 A level 6 [heading](#highlight.tags.heading).
3766 */
3767 heading6: t(heading),
3768 /**
3769 A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
3770 */
3771 contentSeparator: t(content),
3772 /**
3773 [Content](#highlight.tags.content) that represents a list.
3774 */
3775 list: t(content),
3776 /**
3777 [Content](#highlight.tags.content) that represents a quote.
3778 */
3779 quote: t(content),
3780 /**
3781 [Content](#highlight.tags.content) that is emphasized.
3782 */
3783 emphasis: t(content),
3784 /**
3785 [Content](#highlight.tags.content) that is styled strong.
3786 */
3787 strong: t(content),
3788 /**
3789 [Content](#highlight.tags.content) that is part of a link.
3790 */
3791 link: t(content),
3792 /**
3793 [Content](#highlight.tags.content) that is styled as code or
3794 monospace.
3795 */
3796 monospace: t(content),
3797 /**
3798 [Content](#highlight.tags.content) that has a strike-through
3799 style.
3800 */
3801 strikethrough: t(content),
3802 /**
3803 Inserted text in a change-tracking format.
3804 */
3805 inserted: t(),
3806 /**
3807 Deleted text.
3808 */
3809 deleted: t(),
3810 /**
3811 Changed text.
3812 */
3813 changed: t(),
3814 /**
3815 An invalid or unsyntactic element.
3816 */
3817 invalid: t(),
3818 /**
3819 Metadata or meta-instruction.
3820 */
3821 meta,
3822 /**
3823 [Metadata](#highlight.tags.meta) that applies to the entire
3824 document.
3825 */
3826 documentMeta: t(meta),
3827 /**
3828 [Metadata](#highlight.tags.meta) that annotates or adds
3829 attributes to a given syntactic element.
3830 */
3831 annotation: t(meta),
3832 /**
3833 Processing instruction or preprocessor directive. Subtag of
3834 [meta](#highlight.tags.meta).
3835 */
3836 processingInstruction: t(meta),
3837 /**
3838 [Modifier](#highlight.Tag^defineModifier) that indicates that a
3839 given element is being defined. Expected to be used with the
3840 various [name](#highlight.tags.name) tags.
3841 */
3842 definition: Tag.defineModifier("definition"),
3843 /**
3844 [Modifier](#highlight.Tag^defineModifier) that indicates that
3845 something is constant. Mostly expected to be used with
3846 [variable names](#highlight.tags.variableName).
3847 */
3848 constant: Tag.defineModifier("constant"),
3849 /**
3850 [Modifier](#highlight.Tag^defineModifier) used to indicate that
3851 a [variable](#highlight.tags.variableName) or [property
3852 name](#highlight.tags.propertyName) is being called or defined
3853 as a function.
3854 */
3855 function: Tag.defineModifier("function"),
3856 /**
3857 [Modifier](#highlight.Tag^defineModifier) that can be applied to
3858 [names](#highlight.tags.name) to indicate that they belong to
3859 the language's standard environment.
3860 */
3861 standard: Tag.defineModifier("standard"),
3862 /**
3863 [Modifier](#highlight.Tag^defineModifier) that indicates a given
3864 [names](#highlight.tags.name) is local to some scope.
3865 */
3866 local: Tag.defineModifier("local"),
3867 /**
3868 A generic variant [modifier](#highlight.Tag^defineModifier) that
3869 can be used to tag language-specific alternative variants of
3870 some common tag. It is recommended for themes to define special
3871 forms of at least the [string](#highlight.tags.string) and
3872 [variable name](#highlight.tags.variableName) tags, since those
3873 come up a lot.
3874 */
3875 special: Tag.defineModifier("special")
3876};
3877for (let name2 in tags) {
3878 let val = tags[name2];
3879 if (val instanceof Tag)
3880 val.name = name2;
3881}
3882var classHighlighter = tagHighlighter([
3883 { tag: tags.link, class: "tok-link" },
3884 { tag: tags.heading, class: "tok-heading" },
3885 { tag: tags.emphasis, class: "tok-emphasis" },
3886 { tag: tags.strong, class: "tok-strong" },
3887 { tag: tags.keyword, class: "tok-keyword" },
3888 { tag: tags.atom, class: "tok-atom" },
3889 { tag: tags.bool, class: "tok-bool" },
3890 { tag: tags.url, class: "tok-url" },
3891 { tag: tags.labelName, class: "tok-labelName" },
3892 { tag: tags.inserted, class: "tok-inserted" },
3893 { tag: tags.deleted, class: "tok-deleted" },
3894 { tag: tags.literal, class: "tok-literal" },
3895 { tag: tags.string, class: "tok-string" },
3896 { tag: tags.number, class: "tok-number" },
3897 { tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" },
3898 { tag: tags.variableName, class: "tok-variableName" },
3899 { tag: tags.local(tags.variableName), class: "tok-variableName tok-local" },
3900 { tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" },
3901 { tag: tags.special(tags.variableName), class: "tok-variableName2" },
3902 { tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" },
3903 { tag: tags.typeName, class: "tok-typeName" },
3904 { tag: tags.namespace, class: "tok-namespace" },
3905 { tag: tags.className, class: "tok-className" },
3906 { tag: tags.macroName, class: "tok-macroName" },
3907 { tag: tags.propertyName, class: "tok-propertyName" },
3908 { tag: tags.operator, class: "tok-operator" },
3909 { tag: tags.comment, class: "tok-comment" },
3910 { tag: tags.meta, class: "tok-meta" },
3911 { tag: tags.invalid, class: "tok-invalid" },
3912 { tag: tags.punctuation, class: "tok-punctuation" }
3913]);
3914
3915// node_modules/@lezer/cpp/dist/index.js
3916var RawString = 1;
3917var templateArgsEndFallback = 2;
3918var MacroName = 3;
3919var R = 82;
3920var L = 76;
3921var u = 117;
3922var U = 85;
3923var a = 97;
3924var z = 122;
3925var A = 65;
3926var Z = 90;
3927var Underscore = 95;
3928var Zero = 48;
3929var Quote = 34;
3930var ParenL = 40;
3931var ParenR = 41;
3932var Space = 32;
3933var GreaterThan = 62;
3934var rawString = new ExternalTokenizer((input) => {
3935 if (input.next == L || input.next == U) {
3936 input.advance();
3937 } else if (input.next == u) {
3938 input.advance();
3939 if (input.next == Zero + 8) input.advance();
3940 }
3941 if (input.next != R) return;
3942 input.advance();
3943 if (input.next != Quote) return;
3944 input.advance();
3945 let marker = "";
3946 while (input.next != ParenL) {
3947 if (input.next == Space || input.next <= 13 || input.next == ParenR) return;
3948 marker += String.fromCharCode(input.next);
3949 input.advance();
3950 }
3951 input.advance();
3952 for (; ; ) {
3953 if (input.next < 0)
3954 return input.acceptToken(RawString);
3955 if (input.next == ParenR) {
3956 let match = true;
3957 for (let i = 0; match && i < marker.length; i++)
3958 if (input.peek(i + 1) != marker.charCodeAt(i)) match = false;
3959 if (match && input.peek(marker.length + 1) == Quote)
3960 return input.acceptToken(RawString, 2 + marker.length);
3961 }
3962 input.advance();
3963 }
3964});
3965var fallback = new ExternalTokenizer((input) => {
3966 if (input.next == GreaterThan) {
3967 if (input.peek(1) == GreaterThan)
3968 input.acceptToken(templateArgsEndFallback, 1);
3969 } else {
3970 let sawLetter = false, i = 0;
3971 for (; ; i++) {
3972 if (input.next >= A && input.next <= Z) sawLetter = true;
3973 else if (input.next >= a && input.next <= z) return;
3974 else if (input.next != Underscore && !(input.next >= Zero && input.next <= Zero + 9)) break;
3975 input.advance();
3976 }
3977 if (sawLetter && i > 1) input.acceptToken(MacroName);
3978 }
3979}, { extend: true });
3980var cppHighlighting = styleTags({
3981 "typedef struct union enum class typename decltype auto template operator friend noexcept namespace using requires concept import export module __attribute__ __declspec __based": tags.definitionKeyword,
3982 "extern MsCallModifier MsPointerModifier extern static register thread_local inline const volatile restrict _Atomic mutable constexpr constinit consteval virtual explicit VirtualSpecifier Access": tags.modifier,
3983 "if else switch for while do case default return break continue goto throw try catch": tags.controlKeyword,
3984 "co_return co_yield co_await": tags.controlKeyword,
3985 "new sizeof delete static_assert": tags.operatorKeyword,
3986 "NULL nullptr": tags.null,
3987 this: tags.self,
3988 "True False": tags.bool,
3989 "TypeSize PrimitiveType": tags.standard(tags.typeName),
3990 TypeIdentifier: tags.typeName,
3991 FieldIdentifier: tags.propertyName,
3992 "CallExpression/FieldExpression/FieldIdentifier": tags.function(tags.propertyName),
3993 "ModuleName/Identifier": tags.namespace,
3994 "PartitionName": tags.labelName,
3995 StatementIdentifier: tags.labelName,
3996 "Identifier DestructorName": tags.variableName,
3997 "CallExpression/Identifier": tags.function(tags.variableName),
3998 "CallExpression/ScopedIdentifier/Identifier": tags.function(tags.variableName),
3999 "FunctionDeclarator/Identifier FunctionDeclarator/DestructorName": tags.function(tags.definition(tags.variableName)),
4000 NamespaceIdentifier: tags.namespace,
4001 OperatorName: tags.operator,
4002 ArithOp: tags.arithmeticOperator,
4003 LogicOp: tags.logicOperator,
4004 BitOp: tags.bitwiseOperator,
4005 CompareOp: tags.compareOperator,
4006 AssignOp: tags.definitionOperator,
4007 UpdateOp: tags.updateOperator,
4008 LineComment: tags.lineComment,
4009 BlockComment: tags.blockComment,
4010 Number: tags.number,
4011 String: tags.string,
4012 "RawString SystemLibString": tags.special(tags.string),
4013 CharLiteral: tags.character,
4014 EscapeSequence: tags.escape,
4015 "UserDefinedLiteral/Identifier": tags.literal,
4016 PreProcArg: tags.meta,
4017 "PreprocDirectiveName #include #ifdef #ifndef #if #define #else #endif #elif": tags.processingInstruction,
4018 MacroName: tags.special(tags.name),
4019 "( )": tags.paren,
4020 "[ ]": tags.squareBracket,
4021 "{ }": tags.brace,
4022 "< >": tags.angleBracket,
4023 ". ->": tags.derefOperator,
4024 ", ;": tags.separator
4025});
4026var spec_identifier = { __proto__: null, bool: 36, char: 36, int: 36, float: 36, double: 36, void: 36, size_t: 36, ssize_t: 36, intptr_t: 36, uintptr_t: 36, charptr_t: 36, int8_t: 36, int16_t: 36, int32_t: 36, int64_t: 36, uint8_t: 36, uint16_t: 36, uint32_t: 36, uint64_t: 36, char8_t: 36, char16_t: 36, char32_t: 36, char64_t: 36, const: 70, volatile: 72, restrict: 74, _Atomic: 76, mutable: 78, constexpr: 80, constinit: 82, consteval: 84, struct: 88, __declspec: 92, final: 148, override: 148, public: 152, private: 152, protected: 152, virtual: 154, extern: 160, static: 162, register: 164, inline: 166, thread_local: 168, __attribute__: 172, __based: 178, __restrict: 180, __uptr: 180, __sptr: 180, _unaligned: 180, __unaligned: 180, noexcept: 194, requires: 198, TRUE: 796, true: 796, FALSE: 798, false: 798, typename: 218, class: 220, template: 234, throw: 248, __cdecl: 256, __clrcall: 256, __stdcall: 256, __fastcall: 256, __thiscall: 256, __vectorcall: 256, try: 260, catch: 264, export: 282, import: 286, case: 296, default: 298, if: 308, else: 314, switch: 318, do: 322, while: 324, for: 330, return: 334, break: 338, continue: 342, goto: 346, co_return: 350, co_yield: 354, using: 362, typedef: 366, namespace: 380, new: 398, delete: 400, co_await: 402, concept: 406, enum: 410, static_assert: 414, friend: 422, union: 424, explicit: 430, operator: 444, module: 456, signed: 518, unsigned: 518, long: 518, short: 518, decltype: 528, auto: 530, sizeof: 566, NULL: 572, nullptr: 586, this: 588 };
4027var spec_ = { __proto__: null, "<": 765 };
4028var spec_templateArgsEnd = { __proto__: null, ">": 135 };
4029var spec_scopedIdentifier = { __proto__: null, operator: 388, new: 576, delete: 582 };
4030var parser = LRParser.deserialize({
4031 version: 14,
4032 states: "$;xQ!QQVOOP'gOUOOO([OWO'#CdO,UQUO'#CgO,`QUO'#FjO-vQbO'#CxO.XQUO'#CxO0WQUO'#K`O0_QUO'#CwO0jOpO'#DvO0rQ!dO'#D]OOQR'#JP'#JPO5[QVO'#GUO5iQUO'#JWOOQQ'#JW'#JWO8}QUO'#KsO<hQUO'#KsO?OQVO'#E^O?`QUO'#E^OOQQ'#Ed'#EdOOQQ'#Ee'#EeO?eQVO'#EfO@[QVO'#EiOBXQUO'#FPOByQUO'#FhOOQR'#Fj'#FjOCOQUO'#FjOOQR'#LW'#LWOOQR'#LV'#LVOEWQVO'#KVOF{QUO'#L]OGYQUO'#KwOGnQUO'#L]OH`QUO'#L_OOQR'#HU'#HUOOQR'#HV'#HVOOQR'#HW'#HWOOQR'#LS'#LSOOQR'#J`'#J`Q!QQVOOOHnQVO'#FOOIZQUO'#EhOIbQUOOOK^QVO'#HgOKnQUO'#HgONYQUO'#KwONdQUO'#KwOOQQ'#Kw'#KwO!!bQUO'#KwOOQQ'#Jr'#JrO!!oQUO'#HxOOQQ'#K`'#K`O!&aQUO'#K`O!&}QUO'#KVO!(}QVO'#I]O!(}QVO'#I`OCTQUO'#KVOOQQ'#Ip'#IpOOQQ'#KV'#KVO!-QQUO'#K`OOQR'#K_'#K_O!-XQUO'#DZO!/pQUO'#KtOOQQ'#Kt'#KtO!/wQUO'#KtO!0OQUO'#ETO!0TQUO'#EWO!0YQUO'#FRO8}QUO'#FPO!QQVO'#F^O!0_Q#vO'#F`O!0jQUO'#FkO!0rQUO'#FpO!0wQVO'#FrO!0rQUO'#FuO!3vQUO'#FvO!3{QVO'#FxO!4VQUO'#FzO!4[QUO'#F|O!4aQUO'#GOO!4fQVO'#GQO!(}QVO'#GSO!4mQUO'#GpO!4{QUO'#GYO!(}QVO'#FeO!6YQUO'#FeO!6_QVO'#G`O!6fQUO'#GaO!6qQUO'#GnO!6vQUO'#GrO!6{QUO'#GzO!7mQ&lO'#HiO!:pQUO'#GuO!;QQUO'#HXO!;]QUO'#HZO!;eQUO'#DXO!;eQUO'#HuO!;eQUO'#HvO!;|QUO'#HwO!<_QUO'#H|O!=SQUO'#H}O!>xQVO'#IbO!(}QVO'#IdO!?SQUO'#IgO!?ZQVO'#IjP!AQO!LQO'#CaP!A]{,UO'#CbP!6q{,UO'#CbP!Ah{7[O'#CbP!6q{,UO'#CbP!Am{,UO'#CbP!AxOSO'#IzPOOO)CEo)CEoOOOO'#I}'#I}O!BSOWO,59OOOQR,59O,59OO!(}QVO,59VOOQQ,59X,59XOOQR'#Do'#DoO!(}QVO,5;ROOQR,5<U,5<UO!B_QUO,59ZO!(}QVO,5>qOOQR'#IX'#IXOOQR'#IY'#IYOOQR'#IZ'#IZOOQR'#I['#I[O!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!(}QVO,5>rO!D^QVO,5>zOOQQ,5?W,5?WO!FPQVO'#CjO!IxQUO'#CzOOQQ,59d,59dOOQQ,59c,59cOOQQ,5<},5<}O!JVQ&lO,5=mO!?SQUO,5?RO!LyQVO,5?UO!MQQbO,59dO!M]QVO'#FYOOQQ,5?P,5?PO!MmQVO,59WO!MtO`O,5:bO!MyQbO'#D^O!N[QbO'#KdO!NjQbO,59wO!NrQbO'#CxO# TQUO'#CxO# YQUO'#K`O# dQUO'#CwOOQR-E<}-E<}O# oQUO,5AuO# vQVO'#EfO@[QVO'#EiOBXQUO,5;kOOQR,5<p,5<pO#$oQUO'#KVO#$vQUO'#KVO!(}QVO'#IUO8}QUO,5;kO#%ZQ&lO'#HiO#(bQUO'#CtO#+VQbO'#CxO#+[QUO'#CwO#.xQUO'#K`OOQQ-E=U-E=UO#1]QUO,5A_O#1gQUO'#K`O#1qQUO,5A_OOQR,5Au,5AuOOQQ,5>l,5>lO#3uQUO'#CgO#4kQUO,5>pO#6^QUO'#IeOOQR'#JO'#JOO#6fQUO,5:xO#7SQUO,5:xO#7sQUO,5:xO#8hQUO'#CuO!0TQUO'#CmOOQQ'#JX'#JXO#7SQUO,5:xO#8pQUO,5;QO!4{QUO'#DOO#9yQUO,5;QO#:OQUO,5>QO#;[QUO'#DOO#;rQUO,5>{O#;wQUO'#K}O#=QQUO,5;TO#=YQVO,5;TO#=dQUO,5;TOOQQ,5;T,5;TO#?]QUO'#LbO#?dQUO,5>UO#?iQbO'#CxO#?tQUO'#GcO#?yQUO'#E^O#@jQUO,5;kO#ARQUO'#LTO#AZQUO,5;rOKnQUO'#HfOBXQUO'#HgO#A`QUO'#KwO!6qQUO'#HjO#BWQUO'#CuO!0wQVO,5<SOOQQ'#Cg'#CgOOQR'#Ji'#JiO#B]QVO,5=`OOQQ,5?Z,5?ZO#DfQbO'#CxO#DqQUO'#GcOOQQ'#Jj'#JjOOQQ-E=h-E=hOGYQUO,5AwOGnQUO,5AwO#DvQUO,5AyO#ERQUO'#G|OOQR,5Aw,5AwO#DvQUO,5AwO#E^QUO'#HOO#EfQUO,5AyOOQR,5Ay,5AyOOQR,5Az,5AzO#EtQVO,5AzOOQR-E=^-E=^O#GnQVO,5;jOOQR,5;j,5;jO#IoQUO'#EjO#JtQUO'#EwO#KkQVO'#ExO#M}QUO'#EvO#NVQUO'#EyO$ UQUO'#EzOOQQ'#LQ'#LQO$ {QUO,5;SO$#RQUO'#EvOOQQ,5;S,5;SO$$OQUO,5;SO$%qQUO,5:yO$([QVO,5>PO$(fQUO'#E[O$(sQUO,5>ROOQQ,5>S,5>SO$,aQVO'#C|OOQQ-E=p-E=pOOQQ,5>d,5>dOOQQ,59a,59aO$,kQUO,5>wO$.kQUO,5>zO!6qQUO,59uO$/OQUO,5;qO$/]QUO,5<{O!0TQUO,5:oOOQQ,5:r,5:rO$/hQUO,5;mO$/mQUO'#KsOBXQUO,5;kOOQR,5;x,5;xO$0^QUO'#FbO$0lQUO'#FbO$0qQUO,5;zO$4[QVO'#FmO!0wQVO,5<VO!0rQUO,5<VO!0YQUO,5<[O$4cQVO'#GUO$7_QUO,5<^O!0wQVO,5<aO$:uQVO,5<bO$;SQUO,5<dOOQR,5<d,5<dO$<]QUO,5<dOOQR,5<f,5<fOOQR,5<h,5<hOOQQ'#Fi'#FiO$<bQUO,5<jO$<gQUO,5<lOOQR,5<l,5<lO$=mQUO,5<nO$>sQUO,5<rO$?OQUO,5=[O$?TQUO,5=[O!4{QUO,5<tO$?]QUO,5<tO$?qQUO,5<PO$@wQVO,5<PO$CYQUO,5<zOOQR,5<z,5<zOOQR,5<{,5<{O$?TQUO,5<{O$D`QUO,5<{O$DkQUO,5=YO!(}QVO,5=^O!(}QVO,5=fO#NsQUO,5=mOOQQ,5>T,5>TO$FpQUO,5>TO$FzQUO,5>TO$GPQUO,5>TO$GUQUO,5>TO!6qQUO,5>TO$ISQUO'#K`O$IZQUO,5=oO$IfQUO,5=aOKnQUO,5=oO$J`QUO,5=sOOQR,5=s,5=sO$JhQUO,5=sO$LsQVO'#H[OOQQ,5=u,5=uO!;`QUO,5=uO%#nQUO'#KpO%#uQUO'#KaO%$ZQUO'#KpO%$eQUO'#DyO%$vQUO'#D|O%'sQUO'#KaOOQQ'#Ka'#KaO%)fQUO'#KaO%#uQUO'#KaO%)kQUO'#KaOOQQ,59s,59sOOQQ,5>a,5>aOOQQ,5>b,5>bO%)sQUO'#HzO%){QUO,5>cOOQQ,5>c,5>cO%-gQUO,5>cO%-rQUO,5>hO%1^QVO,5>iO%1eQUO,5>|O# vQVO'#EfO%4kQUO,5>|OOQQ,5>|,5>|O%5[QUO,5?OO%7`QUO,5?RO!<_QUO,5?RO%9[QUO,5?UO%<wQVO,5?UPOOO'#I|'#I|P%=OO!LQO,58{POOO,58{,58{P!Am{,UO,58|P%=Z{,UO,58|P%=i{7[O,58|P%=o{,UO,58|PO{O'#Jv'#JvP%=t{,UO'#LiPOOO'#Li'#LiP%=z{,UO'#LiPOOO,58|,58|POOO,5?f,5?fP%>POSO,5?fOOOO-E<{-E<{OOQR1G.j1G.jO%>WQUO1G.qO%?^QUO1G0mOOQQ1G0m1G0mO%@jQUO'#CpO%ByQbO'#CxO%CUQUO'#CsO%CZQUO'#CsO%C`QUO1G.uO#BWQUO'#CrOOQQ1G.u1G.uO%EcQUO1G4]O%FiQUO1G4^O%H[QUO1G4^O%I}QUO1G4^O%KpQUO1G4^O%McQUO1G4^O& UQUO1G4^O&!wQUO1G4^O&$jQUO1G4^O&&]QUO1G4^O&(OQUO1G4^O&)qQUO1G4^O&+dQUO'#KUO&,mQUO'#KUO&,uQUO,59UOOQQ,5=P,5=PO&.}QUO,5=PO&/XQUO,5=PO&/^QUO,5=PO&/cQUO,5=PO!6qQUO,5=PO#NsQUO1G3XO&/mQUO1G4mO!<_QUO1G4mO&1iQUO1G4pO&3[QVO1G4pOOQQ1G/O1G/OOOQQ1G.}1G.}OOQQ1G2i1G2iO!JVQ&lO1G3XO&3cQUO'#LUO@[QVO'#EiO&4lQUO'#F]OOQQ'#Jb'#JbO&4qQUO'#FZO&4|QUO'#LUO&5UQUO,5;tO&5ZQUO1G.rOOQQ1G.r1G.rOOQR1G/|1G/|O&6|Q!dO'#JQO&7RQbO,59xO&9dQ!eO'#D`O&9kQ!dO'#JSO&9pQbO,5AOO&9pQbO,5AOOOQR1G/c1G/cO&9{QbO1G/cO&:QQ&lO'#GeO&;OQbO,59dOOQR1G7a1G7aO#@jQUO1G1VO&;ZQUO1G1^OBXQUO1G1VO&=lQUO'#CzO#+VQbO,59dO&A_QUO1G6yOOQR-E<|-E<|O&BqQUO1G0dO#6fQUO1G0dOOQQ-E=V-E=VO#7SQUO1G0dOOQQ1G0l1G0lO&CfQUO,59jOOQQ1G3l1G3lO&C|QUO,59jO&DdQUO,59jO!MmQVO1G4gO!(}QVO'#JZO&EOQUO,5AiOOQQ1G0o1G0oO!(}QVO1G0oO!6qQUO'#JoO&EWQUO,5A|OOQQ1G3p1G3pOOQR1G1V1G1VO&ITQVO'#FOO!MmQVO,5;sOOQQ,5;s,5;sOBXQUO'#JdO&KPQUO,5AoO&KXQVO'#E[OOQR1G1^1G1^O&MvQUO'#LbOOQR1G1n1G1nOOQR-E=g-E=gOOQR1G7c1G7cO#DvQUO1G7cOGYQUO1G7cO#DvQUO1G7eOOQR1G7e1G7eO&NOQUO'#G}O&NWQUO'#L^OOQQ,5=h,5=hO&NfQUO,5=jO&NkQUO,5=kOOQR1G7f1G7fO#EtQVO1G7fO&NpQUO1G7fO' vQVO,5=kOOQR1G1U1G1UO$/UQUO'#E]O'!lQUO'#E]OOQQ'#LP'#LPO'#VQUO'#LOO'#bQUO,5;UO'#jQUO'#ElO'#}QUO'#ElO'$bQUO'#EtOOQQ'#J]'#J]O'$gQUO,5;cO'%^QUO,5;cO'&XQUO,5;dO''_QVO,5;dOOQQ,5;d,5;dO''iQVO,5;dO''_QVO,5;dO''pQUO,5;bO'(mQUO,5;eO'(xQUO'#KvO')QQUO,5:vO')VQUO,5;fOOQQ1G0n1G0nOOQQ'#J^'#J^O''pQUO,5;bO!4{QUO'#E}OOQQ,5;b,5;bO'*QQUO'#E`O'+zQUO'#E{OHuQUO1G0nO',PQUO'#EbOOQQ'#JY'#JYO'-iQUO'#KxOOQQ'#Kx'#KxO'.cQUO1G0eO'/ZQUO1G3kO'0aQVO1G3kOOQQ1G3k1G3kO'0kQVO1G3kO'0rQUO'#LeO'2OQUO'#K^O'2^QUO'#K]O'2iQUO,59hO'2qQUO1G/aO'2vQUO'#FPOOQR1G1]1G1]OOQR1G2g1G2gO$?TQUO1G2gO'3QQUO1G2gO'3]QUO1G0ZOOQR'#Ja'#JaO'3bQVO1G1XO'9ZQUO'#FTO'9`QUO1G1VO!6qQUO'#JeO'9nQUO,5;|O$0lQUO,5;|OOQQ'#Fc'#FcOOQQ,5;|,5;|O'9|QUO1G1fOOQR1G1f1G1fO':UQUO,5<XO$/UQUO'#FWOBXQUO'#FWO':]QUO,5<XO!(}QVO,5<XO':eQUO,5<XO':jQVO1G1qO!0wQVO1G1qOOQR1G1v1G1vO'@YQUO1G1xOOQR1G1{1G1{O'@_QUO1G1|OBXQUO1G2]O'AhQVO1G1|O'C|QUO1G1|O'DRQUO'#GWO8}QUO1G2]OOQR1G2O1G2OOOQR1G2U1G2UOOQR1G2W1G2WOOQR1G2Y1G2YO'DWQUO1G2^O!4{QUO1G2^OOQR1G2v1G2vO'D`QUO1G2vO$?]QUO1G2`OOQQ'#Cv'#CvO'DeQUO'#G[O'E`QUO'#G[O'EeQUO'#LXO'EsQUO'#G_OOQQ'#LY'#LYO'FRQUO1G2`O'FWQVO1G1kO'HiQVO'#GUOBXQUO'#FWOOQR'#Jf'#JfO'FWQVO1G1kO'HsQUO'#FvOOQR1G2f1G2fO'HxQUO1G2gO'H}QUO'#JhO'3QQUO1G2gO!(}QVO1G2tO'IVQUO1G2xO'J`QUO1G3QO'KfQUO1G3XOOQQ1G3o1G3oO'KzQUO1G3oOOQR1G3Z1G3ZO'LPQUO'#K`O'2vQUO'#LZOGnQUO'#L]OOQR'#Gy'#GyO#DvQUO'#L_OOQR'#HQ'#HQO'LZQUO'#GvO'$bQUO'#GuOOQR1G2{1G2{O'MWQUO1G2{O'M}QUO1G3ZO'NYQUO1G3_O'N_QUO1G3_OOQR1G3_1G3_O'NgQUO'#H]OOQR'#H]'#H]O( pQUO'#H]O!(}QVO'#H`O!(}QVO'#H_OOQR'#La'#LaO( uQUO'#LaOOQR'#Jl'#JlO( zQVO,5=vOOQQ,5=v,5=vO(!RQUO'#H^O(!ZQUO'#HZOOQQ1G3a1G3aO(!eQUO,5@{OOQQ,5@{,5@{O%)fQUO,5@{O%)kQUO,5@{O%$eQUO,5:eO(&SQUO'#KqO(&bQUO'#KqOOQQ,5:e,5:eOOQQ'#JT'#JTO(&mQUO'#D}O(&wQUO'#KwOGnQUO'#L]O('sQUO'#D}OOQQ'#Hp'#HpOOQQ'#Hr'#HrOOQQ'#Hs'#HsOOQQ'#Kr'#KrOOQQ'#JV'#JVO('}QUO,5:hOOQQ,5:h,5:hO((zQUO'#L]O()XQUO'#HtO()oQUO,5@{O()vQUO'#H{O(*RQUO'#LdO(*ZQUO,5>fO(*`QUO'#LcOOQQ1G3}1G3}O(.VQUO1G3}O(.^QUO1G3}O(.eQUO1G4TO(/kQUO1G4TO(/pQUO,5BSO!6qQUO1G4hO!(}QVO'#IiOOQQ1G4m1G4mO(/uQUO1G4mO(1xQVO1G4pPOOO-E<z-E<zPOOO1G.g1G.gPOOO1G.h1G.hP!Am{,UO1G.hP(3xQUO'#LkP(4T{,UO1G.hP(4Y{7[O1G.hPO{O-E=t-E=tPOOO,5BT,5BTP(4b{,UO,5BTPOOO1G5Q1G5QO!(}QVO7+$]O(4gQUO'#CzOOQQ,59_,59_O(4rQbO,59dO(4}QbO,59_OOQQ,59^,59^OOQQ7+)w7+)wO!MmQVO'#JuO(5YQUO,5@pOOQQ1G.p1G.pOOQQ1G2k1G2kO(5bQUO1G2kO(5gQUO7+(sOOQQ7+*X7+*XO(7{QUO7+*XO(8SQUO7+*XO(1xQVO7+*[O#NsQUO7+(sO(8aQVO'#JcO(8tQUO,5ApO(8|QUO,5;vOOQQ'#Cp'#CpOOQQ,5;w,5;wO!(}QVO'#F[OOQQ-E=`-E=`O!MmQVO,5;uOOQQ1G1`1G1`OOQQ,5?l,5?lOOQQ-E=O-E=OOOQR'#Dg'#DgOOQR'#Di'#DiOOQR'#Dl'#DlO(:VQ!eO'#KeO(:^QMkO'#KeO(:eQ!eO'#KeOOQR'#Ke'#KeOOQR'#JR'#JRO(:lQ!eO,59zOOQQ,59z,59zO(:sQbO,5?nOOQQ-E=Q-E=QO(;RQbO1G6jOOQR7+$}7+$}OOQR7+&q7+&qOOQR7+&x7+&xO'9`QUO7+&qO(;^QUO7+&OO#6fQUO7+&OO(<RQUO1G/UO(<iQUO1G/UO(=TQUO7+*ROOQQ7+*V7+*VO(>vQUO,5?uOOQQ-E=X-E=XO(@PQUO7+&ZOOQQ,5@Z,5@ZOOQQ-E=m-E=mO(@UQUO'#LUO@[QVO'#EiO(AbQUO1G1_OOQQ1G1_1G1_O(BkQUO,5@OOOQQ,5@O,5@OOOQQ-E=b-E=bO(CPQUO'#KvOOQR7+,}7+,}O#DvQUO7+,}OOQR7+-P7+-PO(C^QUO,5=iO#ERQUO'#JkO(CoQUO,5AxOOQR1G3U1G3UOOQR1G3V1G3VO(C}QUO7+-QOOQR7+-Q7+-QO(EuQUO,5:wO(GdQUO'#EwO!(}QVO,5;VO(HVQUO,5:wO(HaQUO'#EpO(HrQUO'#EzOOQQ,5;Z,5;ZO#KkQVO'#ExO(IYQUO,5:wO(IaQUO'#EyO#GuQUO'#J[O(JyQUO,5AjOOQQ1G0p1G0pO(KUQUO,5;WO!<_QUO,5;^O(KoQUO,5;_O(K}QUO,5;WO(NaQUO,5;`OOQQ-E=Z-E=ZO(NiQUO1G0}OOQQ1G1O1G1OO) dQUO1G1OO)!jQVO1G1OO)!qQVO1G1OO)!{QUO1G0|OOQQ1G0|1G0|OOQQ1G1P1G1PO)#xQUO'#JpO)$SQUO,5AbOOQQ1G0b1G0bOOQQ-E=[-E=[O)$[QUO,5;iO!<_QUO,5;iO)%XQVO,5:zO)%`QUO,5;gO$ {QUO7+&YOOQQ7+&Y7+&YO!(}QVO'#EfO)%gQUO,5:|OOQQ'#Ky'#KyOOQQ-E=W-E=WOOQQ,5Ad,5AdOOQQ'#Jm'#JmO))[QUO7+&PPOQQ7+&P7+&POOQQ7+)V7+)VO)*SQUO7+)VO)+YQVO7+)VOOQQ,5>m,5>mO$)hQVO'#JtO)+aQUO,5@wOOQQ1G/S1G/SOOQQ7+${7+${O)+lQUO7+(RO)+qQUO7+(ROOQR7+(R7+(RO$?TQUO7+(ROOQQ7+%u7+%uOOQR-E=_-E=_O!0YQUO,5;oOOQQ,5@P,5@POOQQ-E=c-E=cO$0lQUO1G1hOOQQ1G1h1G1hOOQR7+'Q7+'QOOQR1G1s1G1sOBXQUO,5;rO),_QUO,5<YO),fQUO1G1sO)-oQUO1G1sO!0wQVO7+']O)-tQVO7+']O)3dQUO7+'dO)3iQVO7+'hO)5}QUO7+'wO)6XQUO7+'hO)7_QVO7+'hOKnQUO7+'wO$>vQUO,5<rO!4{QUO7+'xO)7fQUO7+'xOOQR7+(b7+(bO)7kQUO7+'zO)7pQUO,5<vO'DeQUO,5<vO)8hQUO,5<vO'DeQUO,5<vOOQQ,5<w,5<wO)8yQVO,5<xO'EsQUO'#JgO)9TQUO,5AsO)9]QUO,5<yOOQR7+'z7+'zO)9hQVO7+'VO)6QQUO'#LTOOQR-E=d-E=dO);yQVO,5<bOOQQ,5@S,5@SO!6qQUO,5@SOOQQ-E=f-E=fO)>bQUO7+(`O)?hQUO7+(dO)?mQVO7+(dOOQQ7+(l7+(lOOQQ7+)Z7+)ZO)?uQUO'#KpO)@PQUO'#KpOOQR,5=b,5=bO)@^QUO,5=bO!;eQUO,5=bO!;eQUO,5=bO!;eQUO,5=bOOQR7+(g7+(gOOQR7+(u7+(uOOQR7+(y7+(yOOQR,5=w,5=wO)@cQUO,5=zO)AiQUO,5=yOOQR,5A{,5A{OOQR-E=j-E=jOOQQ1G3b1G3bO)BoQUO,5=xO)BtQVO'#EfOOQQ1G6g1G6gO%)fQUO1G6gO%)kQUO1G6gOOQQ1G0P1G0POOQQ-E=R-E=RO)E]QUO,5A]O(&SQUO'#JUO)EhQUO,5A]O)EhQUO,5A]O)EpQUO,5:iO8}QUO,5:iOOQQ,5>],5>]O)EzQUO,5AwO)FRQUO'#EVO)G]QUO'#EVO)GvQUO,5:iO)HQQUO'#HlO)HQQUO'#HmOOQQ'#Ku'#KuO)HoQUO'#KuO!(}QVO'#HnOOQQ,5:i,5:iO)IaQUO,5:iO!MmQVO,5:iOOQQ-E=T-E=TOOQQ1G0S1G0SOOQQ,5>`,5>`O)IfQUO1G6gO!(}QVO,5>gO)MTQUO'#JsO)M`QUO,5BOOOQQ1G4Q1G4QO)MhQUO,5A}OOQQ,5A},5A}OOQQ7+)i7+)iO*#VQUO7+)iOOQQ7+)o7+)oO*(UQVO1G7nO**WQUO7+*SO**]QUO,5?TO*+cQUO7+*[POOO7+$S7+$SP*-UQUO'#LlP*-^QUO,5BVP*-c{,UO7+$SPOOO1G7o1G7oO*-hQUO<<GwOOQQ1G.y1G.yOOQQ'#IT'#ITO*/ZQUO,5@aOOQQ,5@a,5@aOOQQ-E=s-E=sOOQQ7+(V7+(VOOQQ<<Ms<<MsO*0dQUO<<MsO*2gQUO<<MvO*4YQUO<<L_O*4nQUO,5?}OOQQ,5?},5?}OOQQ-E=a-E=aOOQQ1G1b1G1bO*5wQUO,5;vO*6}QUO1G1aOOQQ1G1a1G1aOOQR,5AP,5APO*8WQ!eO,5APO*8_QMkO,5APO*8fQ!eO,5APOOQR-E=P-E=POOQQ1G/f1G/fO*8mQ!eO'#DwOOQQ1G5Y1G5YOOQR<<J]<<J]O*8tQUO<<IjO*9iQUO7+$pOOQQ<<Iu<<IuO(8aQVO,5;ROOQR<=!i<=!iOOQQ1G3T1G3TOOQQ,5@V,5@VOOQQ-E=i-E=iOOQR<=!l<=!lO*:fQUO1G0cO*:mQUO'#EzO*:}QUO1G0cO*;UQUO'#JOO*<lQUO1G0qO!(}QVO1G0qOOQQ,5;[,5;[OOQQ,5;],5;]OOQQ,5?v,5?vOOQQ-E=Y-E=YO!<_QUO1G0xO*={QUO1G0xOOQQ1G0y1G0yO*>^QUO'#ElOOQQ1G0z1G0zOOQQ7+&j7+&jO*>rQUO7+&jO*?xQVO7+&jOOQQ7+&h7+&hOOQQ,5@[,5@[OOQQ-E=n-E=nO*@tQUO1G1TO*AOQUO1G1TO*AiQUO1G0fOOQQ1G0f1G0fO*BoQUO'#LRO*BwQUO1G1ROOQQ<<It<<ItOOQQ'#Hb'#HbO',PQUO,5={OOQQ'#Hd'#HdO',PQUO,5=}OOQQ-E=k-E=kPOQQ<<Ik<<IkPOQQ-E=l-E=lOOQQ<<Lq<<LqO*B|QUO'#LgO*DYQUO'#LfOOQQ,5@`,5@`OOQQ-E=r-E=rOOQR<<Km<<KmO$?TQUO<<KmO*DhQUO<<KmOOQR1G1Z1G1ZOOQQ7+'S7+'SO!MmQVO1G1tO*DmQUO1G1tOOQR7+'_7+'_OOQR<<Jw<<JwO!0wQVO<<JwOOQR<<KO<<KOO*DxQUO<<KSO*FOQVO<<KSOKnQUO<<KcO!MmQVO<<KcO*FVQUO<<KSO!0wQVO<<KSO*G`QUO<<KSO*GeQUO<<KcO*GpQUO<<KdOOQR<<Kd<<KdOOQR<<Kf<<KfO*GuQUO1G2bO)7pQUO1G2bO'DeQUO1G2bO*HWQUO1G2dO*I^QVO1G2dOOQQ1G2d1G2dO*IhQVO1G2dO*IoQUO,5@ROOQQ-E=e-E=eOOQQ1G2e1G2eO*I}QUO1G1|O*KWQVO1G1|O*K_QUO1G1|OOQQ1G5n1G5nOOQR<<Kz<<KzOOQR<<LO<<LOO*KdQVO<<LOO*KoQUO<<LOOOQR1G2|1G2|O*KtQUO1G2|O*K{QUO1G3eOOQR1G3d1G3dOOQQ7+,R7+,RO%)fQUO7+,RO*LWQUO1G6wO*LWQUO1G6wO(&SQUO,5?pO*L`QUO,5?pOOQQ-E=S-E=SO*LkQUO1G0TOOQQ1G0T1G0TO*LuQUO1G0TO!MmQVO1G0TO*LzQUO1G0TOOQQ1G3w1G3wO*MUQUO,5:qO)FRQUO,5:qO*MrQUO,5:qO)FRQUO,5:qO$$TQUO,5:uO*NaQVO,5>VO)HQQUO'#JqO*NkQUO1G0TO*N|QVO1G0TOOQQ1G3u1G3uO+ TQUO,5>WO+ `QUO,5>XO+ }QUO,5>YO+#TQUO1G0TO%)kQUO7+,RO+$ZQUO1G4ROOQQ,5@_,5@_OOQQ-E=q-E=qOOQQ<<MT<<MTOOQQ<<Mn<<MnO+%dQUO1G4oP+'gQUO'#JwP+'oQUO,5BWPO{O1G7q1G7qPOOO<<Gn<<GnOOQQANC_ANC_OOQR1G6k1G6kO+'wQ!eO,5:cOOQQ,5:c,5:cO+(OQUO1G0mO+)[QUO7+&]O+*kQUO7+&dO+*|QUO,5;WOOQQ<<JU<<JUO++[QUO7+&oOOQQ7+&Q7+&QO!4{QUO'#J_O+,VQUO,5AmOOQQ7+&m7+&mOOQQ1G3g1G3gO+,_QUO1G3iOOQQ,5>n,5>nO+0SQUOANAXOOQRANAXANAXO+0XQUO7+'`OOQRAN@cAN@cO+1eQVOAN@nO+1lQUOAN@nO!0wQVOAN@nO+2uQUOAN@nO+2zQUOAN@}O+3VQUOAN@}O+4]QUOAN@}OOQRAN@nAN@nO!MmQVOAN@}OOQRANAOANAOO+4bQUO7+'|O)7pQUO7+'|OOQQ7+(O7+(OO+4sQUO7+(OO+5yQVO7+(OO+6QQVO7+'hO+6XQUOANAjOOQR7+(h7+(hOOQR7+)P7+)PO+6^QUO7+)PO+6cQUO7+)POOQQ<= m<= mO+6kQUO7+,cO+6sQUO1G5[OOQQ1G5[1G5[O+7OQUO7+%oOOQQ7+%o7+%oO+7aQUO7+%oO*N|QVO7+%oOOQQ7+)a7+)aO+7fQUO7+%oO+8lQUO7+%oO!MmQVO7+%oO+8vQUO1G0]O*MUQUO1G0]O)FRQUO1G0]OOQQ1G0a1G0aO+9eQUO1G3qO+:kQVO1G3qOOQQ1G3q1G3qO+:uQVO1G3qO+:|QUO,5@]OOQQ-E=o-E=oOOQQ1G3r1G3rO%)fQUO<= mOOQQ7+*Z7+*ZPOQQ,5@c,5@cPOQQ-E=u-E=uOOQQ1G/}1G/}OOQQ,5?y,5?yOOQQ-E=]-E=]OOQRG26sG26sO+;eQUOG26YO!0wQVOG26YO+<nQUOG26YOOQRG26YG26YO!MmQVOG26iO!0wQVOG26iO+<sQUOG26iO+=yQUOG26iO+>OQUO<<KhOOQQ<<Kj<<KjOOQRG27UG27UOOQR<<Lk<<LkO+>aQUO<<LkOOQQ7+*v7+*vOOQQ<<IZ<<IZO+>fQUO<<IZO!MmQVO<<IZO+>kQUO<<IZO+?qQUO<<IZO*N|QVO<<IZOOQQ<<L{<<L{O+@SQUO7+%wO*MUQUO7+%wOOQQ7+)]7+)]O+@qQUO7+)]O+AwQVO7+)]OOQQANEXANEXO!0wQVOLD+tOOQRLD+tLD+tO+BOQUOLD,TO+CUQUOLD,TOOQRLD,TLD,TO!0wQVOLD,TOOQRANBVANBVOOQQAN>uAN>uO+CZQUOAN>uO+DaQUOAN>uO!MmQVOAN>uO+DfQUO<<IcOOQQ<<Lw<<LwOOQR!$( `!$( `O!0wQVO!$( oOOQR!$( o!$( oOOQQG24aG24aO+ETQUOG24aO+FZQUOG24aOOQR!)9EZ!)9EZOOQQLD){LD){O+F`QUO'#CgO(gQUO'#CgO+J]QUO'#CzO+L|QUO'#CzO!FZQUO'#CzO+MuQUO'#CzO+NYQUO'#CzO,#{QUO'#CzO,$]QUO'#CzO,$jQUO'#CzO,$uQbO,59dO,%QQbO,59dO,%]QbO,59dO,%hQbO'#CxO,%yQbO'#CxO,&[QbO'#CxO,&mQUO'#CgO,)QQUO'#CgO,)_QUO'#CgO,,SQUO'#CgO,/VQUO'#CgO,/gQUO'#CgO,3`QUO'#CgO,3gQUO'#CgO,4gQUO'#CgO,6pQUO,5:xO#?yQUO,5:xO#?yQUO,5:xO#=iQUO'#LbO,7^QbO'#CxO,7iQbO'#CxO,7tQbO'#CxO,8PQbO'#CxO#7SQUO'#E^O,8[QUO'#E^O,9iQUO'#HgO,:ZQbO'#CxO,:fQbO'#CxO,:qQUO'#CwO,:vQUO'#CwO,:{QUO'#CpO,;ZQbO,59dO,;fQbO,59dO,;qQbO,59dO,;|QbO,59dO,<XQbO,59dO,<dQbO,59dO,<oQbO,59dO,6pQUO1G0dO,<zQUO1G0dO#?yQUO1G0dO,8[QUO1G0dO,?XQUO'#K`O,?iQUO'#CzO,?wQbO,59dO,6pQUO7+&OO,<zQUO7+&OO,@SQUO'#EwO,@uQUO'#EzO,AfQUO'#E^O,AkQUO'#GcO,ApQUO'#CwO,AuQUO'#CxO,AzQUO'#CxO,BPQUO'#CwO,BUQUO'#GcO,BZQUO'#K`O,BwQUO'#K`O,CRQUO'#CwO,C^QUO'#CwO,CiQUO'#CwO,<zQUO,5:xO,8[QUO,5:xO,8[QUO,5:xO,CtQUO'#K`O,DXQbO'#CxO,DdQUO'#CsO,DiQUO'#E^",
4033 stateData: ",E_~O(oOSSOSRPQVPQ'ePQ'gPQ'hPQ'iPQ'jPQ'kPQ'lPQ'mPQ(pPQ~O*aOS~OPmO]eOb!]Oe!POmTOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!TxO!VfO!X!XO!Y!WO!i!YO!opO!r!`O!s!aO!t!aO!u!bO!v!aO!x!cO!{!dO#V#QO#a#VO#b#TO#i#OO#p!xO#t!fO#v!eO$R!gO$T!hO$Y!vO$Z!wO$`!iO$e!jO$g!kO$h!lO$k!mO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO${!tO$}!uO%U!yO%_#ZO%`#[O%a#YO%c!zO%e#UO%g!{O%l#SO%o!|O%v!}O%|#PO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(wRO)VYO)YaO)[|O)]{O)_iO)`!ZO)bXO)ncO)odO~OR#cOV#^O'e#_O'g#`O'h#aO'i#aO'j#bO'k#bO'l#`O'm#`O(p#]O~OX#eO(t#gO(v#eO~O]ZX]jXejXmhXqZXqjXsjXtjXujXvjXwjXxjXyjXzjX!OjX!TjX!VZX!VjX!XZX!YZX![ZX!^ZX!_ZX!aZX!bZX!eZX!fZX!gZX!hZX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX(zZX({$]X(|ZX(}ZX)YZX)YjX)ZZX)[ZX)[jX)]ZX)]jX)^ZX)_ZX)`ZX)pZX~O)_jX!UZX~P(gO]$PO!V#nO!X#}O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO(|#mO(}#mO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_#lO)`$OO~Oe$TO%Y$UO'[$VO'_$WO)O$QO~Om$XO~O!T$YO])SXe)SXs)SXt)SXu)SXv)SXw)SXx)SXy)SXz)SX!O)SX!V)SX!r)SX!s)SX!t)SX!u)SX!v)SX!x)SX!{)SX%v)SX&r)SX&s)SX(w)SX)Y)SX)[)SX)])SX)_)SX~Om$XO~P.^Om$XO!g$[O)p$[O~OX$]O)c$]O~O!R$^O)U)WP)`)WP~OPmO]$gOb!]Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!TxO!V$hO!X!XO!Y!WO!i!YO!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO#V#QO#a#VO#b#TO#v!eO$Y!vO$Z!wO$`!iO$e!jO$g!kO$h!lO$k!mO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)VYO)Y$mO)]$mO)_iO)`!ZO)bXO)ncO)odO~Om$aO#t$nO(wRO~P0}O](^Xb'zXe(^Xm'zXm(^Xs'zXs(^Xt'zXt(^Xu'zXu(^Xv'zXv(^Xw'zXw(^Xx'zXx(^Xy'zXy(^Xz'zXz(^X|'zX!O'zX!V(^X!o(^X!r'zX!r(^X!s'zX!s(^X!t'zX!t(^X!u'zX!u(^X!v'zX!v(^X!x'zX!x(^X!{(^X#a'zX#b'zX%e'zX%l'zX%o(^X%v(^X&m'zX&r'zX&s'zX(w'zX(w(^X)Y(^X)[(^X)](^X~Ob!TOm$qOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO#a#VO#b#TO%e#UO%l#SO&m!RO&r#WO&s!TO(w$pO~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!O!_O!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO&r#WO&s$yO])gXe)gXm)gX!V)gX!{)gX%v)gX(w)gX)Y)gX)[)gX)])gX~O)_$xO~P:qOPmO]eOe!POs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!VfO!X!XO!Y!WO!i!YO!{!dO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)YaO)[|O)]{O)`!ZO)bXO)ncO)odO~Ob%SOm;RO!|%TO(w$zO~P<oO)Y%UO~Ob!]Om$aO|#RO#a#VO#b#TO%e#UO%l#SO&m!RO&r#WO&s!TO(w;UO~P<oOPmO]$gOb%SOm;RO!V$hO!W%aO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]%_O)`!ZO)bXO)ncO)odO)p%^O~O]%jOe!POm%dO!V%mO!{!dO%v$oO(w;VO)Y%fO)[%kO)]%kO~O({%oO~O)_#lO~O(w%pO](yX!V(yX!X(yX!Y(yX![(yX!^(yX!_(yX!a(yX!b(yX!e(yX!f(yX!h(yX(z(yX(|(yX(}(yX)Y(yX)Z(yX)[(yX)](yX)^(yX)_(yX)`(yX!g(yX)p(yX[(yX!W(yX({(yX!U(yXQ(yX!d(yX~OP%qO(uQO~PCTO]%jOe!POs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V%mO!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO!{!dO%o!|O%v!}O)Y;gO)[|O)]|O~Om%tO!o%yO(w$zO~PEbO!TxO#v!eO({%{O)p&OO])kX!V)kX~O]%jOe!POm%tO!V%mO!{!dO%v!}O(w$zO)Y;gO)[|O)]|O~O!TxO#v!eO)_&RO)p&SO~O!U&VO~P!QO]&[O!TxO!V&YO)Y&XO)[&]O)]&]O~Oq&WO~PHuO]&eO!V&dO~OPmO]eOe!PO!VfO!X!XO!Y!WO!i!YO!{!dO#V#QO%_#ZO%`#[O%a#YO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)YaO)[|O)]{O)`!ZO)bXO)ncO)odO~Ob%SOm;RO%v$oO(w$zO~PIjO]%jOe!POm;cO!V%mO!{!dO%v$oO(w$zO)Y;gO)[|O)]|O~Oq&hO](yX])kX!V(yX!V)kX!X(yX!Y(yX![(yX!^(yX!_(yX!a(yX!b(yX!e(yX!f(yX!h(yX(z(yX(|(yX(}(yX)Y(yX)Z(yX)[(yX)](yX)^(yX)_(yX)`(yX[(yX[)kX!U(yX~O!g$[O)p$[O~PL`O!g(yX)p(yX~PL`O](yX!V(yX!X(yX!Y(yX![(yX!^(yX!_(yX!a(yX!b(yX!e(yX!f(yX!h(yX(z(yX(|(yX(}(yX)Y(yX)Z(yX)[(yX)](yX)^(yX)_(yX)`(yX!g(yX)p(yX[(yX!U(yX~O])kX!V)kX[)kX~PNnOb&jO&m!RO]&lXe&lXm&lXs&lXt&lXu&lXv&lXw&lXx&lXy&lXz&lX!O&lX!V&lX!r&lX!s&lX!t&lX!u&lX!v&lX!x&lX!{&lX%v&lX&r&lX&s&lX(w&lX)Y&lX)[&lX)]&lX)_&lX[&lX!T&lX!X&lX!Y&lX![&lX!^&lX!_&lX!a&lX!b&lX!e&lX!f&lX!h&lX(z&lX(|&lX(}&lX)Z&lX)^&lX)`&lX!g&lX)p&lX!W&lXQ&lX!d&lX({&lX!U&lX#v&lX~Oq&hOm)SX[)SXQ)SX!d)SX!h)SX)`)SX)p)SX~P.^O!g$[O)p$[O](yX!V(yX!X(yX!Y(yX![(yX!^(yX!_(yX!a(yX!b(yX!e(yX!f(yX!h(yX(z(yX(|(yX(}(yX)Y(yX)Z(yX)[(yX)](yX)^(yX)_(yX)`(yX[(yX!W(yX({(yX!U(yXQ(yX!d(yX~OPmO]$gOb%SOm;RO!V$hO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~O])SXe)SXm)SXs)SXt)SXu)SXv)SXw)SXx)SXy)SXz)SX!O)SX!V)SX!r)SX!s)SX!t)SX!u)SX!v)SX!x)SX!{)SX%v)SX&r)SX&s)SX(w)SX)Y)SX)[)SX)])SX)_)SX[)SXQ)SX!d)SX!h)SX)`)SX)p)SX~O]$PO~P!*tO]&nO~O])hXb)hXe)hXm)hXs)hXt)hXu)hXv)hXw)hXx)hXy)hXz)hX|)hX!O)hX!V)hX!o)hX!r)hX!s)hX!t)hX!u)hX!v)hX!x)hX!{)hX#a)hX#b)hX%e)hX%l)hX%o)hX%v)hX&m)hX&r)hX&s)hX(w)hX)Y)hX)[)hX)])hX~O(uQO~P!-^O%U&pO~P!-^O]&qO~O]$PO~O!TxO~O$W&yO(w%pO({&xO~O]&zOx&|O~O]&zO~OPmO]$gOb%SOm;RO!TxO!V$hO!X!XO!Y!WO!i!YO#V#QO#p!xO#v!eO$Y!vO$Z!wO$`!iO$e!jO$g!kO$h!lO$k!mO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w:tO)VYO)Y$mO)]$mO)_iO)`!ZO)bXO)ncO)odO~O]'RO~O!T$YO)_'TO~P!(}O)_'VO~O)_'WO~O(w'XO~O)_'[O~P!(}Om;eO%U'`O%e'`O(w;WO~Ob!TOm$qOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO#a#VO#b#TO%e#UO%l#SO&m!RO&r#WO&s!TO(w$pO~O({'dO~O)_'fO~P!(}O!TxO(w%pO)p'hO~O(w%pO~O]'kO~O]'lOe%nXm%nX!V%nX!{%nX%v%nX(w%nX)Y%nX)[%nX)]%nX~O]'pO!V'qO!X'nO!g'nO%Z'nO%['nO%]'nO%^'nO%_'rO%`'rO%a'nO(}'oO)p'nO*O'sO~P8}O]%jOb!TOe!POs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!V%mO!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO!{!dO#a#VO#b#TO%e#UO%l#SO&m!RO&r#WO&s!TO)Y;gO)[|O)]|O~Om;fOq&WO%v$oO(w;XO~P!8mO(w%pO({'xO)_'yO~O]&eO!T'{O~Om$qO!O!_O!T(SO!l(XO(w$pO({(RO)VYO~Om$qO|(`O!T(]O#b(`O(w$pO~Ob!TOm$qO|#RO#a#VO#b#TO%e#UO%l#SO&m!RO&r#WO&s!TO(w$pO~O](bO~OPmOb%SOm;RO!V$hO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]$mO)bXO)ncO)odO~O](dO)`(eO~P!=XO]$PO~P!<_OPmO]$gOb%SOm;RO!V(kO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~O(q(lO(r(lO(s(nO~OY(oO(uQO(w%pO~O'f(rO~OS(vO(p#]O*^(uO~O]$PO(o(yO~Q'nXX#eO(t({O(v#eO~Oe)VOm)QO&r#WO(w)PO~O!Y'Sa!['Sa!^'Sa!_'Sa!a'Sa!b'Sa!e'Sa!f'Sa!h'Sa(z'Sa)Y'Sa)Z'Sa)['Sa)]'Sa)^'Sa)_'Sa)`'Sa!g'Sa)p'Sa['Sa!W'Sa({'Sa!U'SaQ'Sa!d'Sa~OPmOb%SOm;RO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)bXO)ncO)odO]'Sa!V'Sa!X'Sa(|'Sa(}'Sa~P!BmO!T$YO[(xP~P!(}O]oX]%WXeoXmnXqoXq%WXsoXtoXuoXvoXwoXxoXyoXzoX!OoX!ToX!VoX!V%WX!X%WX!Y%WX![%WX!^%WX!_%WX!a%WX!b%WX!e%WX!f%WX!gnX!h%WX!roX!soX!toX!uoX!voX!xoX!{oX%voX&roX&soX(woX(z%WX(|%WX(}%WX)YoX)Y%WX)Z%WX)[oX)[%WX)]oX)]%WX)^%WX)_%WX)`%WX)pnX[%WX~O)_oX[oX!U%WX~P!FZO])iO!V)jO!X)gO!g)gO%Z)gO%[)gO%])gO%^)gO%_)kO%`)kO%a)gO(})hO)p)gO*O)lO~P8}OPmO]$gOb%SOm;RO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~O!V)qO~P!KVOe)tO%Y)uO)O$QO~O!T$YO!V)wO(|)xO!U)xP~P!KVO!T$YO~P!(}O)a*PO~Om*QO]!QX!h!QX)U!QX)`!QX~O]*SO!h*TO)U)WX)`)WX~O)U*WO)`*XO~Oe$TO%Y*YO'[$VO'_$WO)O$QO~Om*ZO~Om*ZO[)SX~P.^Om*ZO!g$[O)p$[O~O)_*[O~P:qOPmO]$gOb!]Om$aOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;UO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~Oq&hO~P!&}Oq&hO!W(yX({(yXQ(yX!d(yX~PNnO]'pO!V'qO!X'nO!g'nO%Z'nO%['nO%]'nO%^'nO%_'rO%`'rO%a'nO(}'oO)p'nO*O'sO~O]jXejXmhXqjXsjXtjXujXvjXwjXxjXyjXzjX!OjX!VjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX)YjX)[jX)]jX!TjX!hjX)`jX)pjX[jX~O!ljX({jX)_jX!XjX!YjX![jX!^jX!_jX!ajX!bjX!ejX!fjX(zjX(|jX(}jX)ZjX)^jX!gjX!WjXQjX!djX!UjX#vjX#TjX#VjX#pjXbjX|jX!ojX#ajX#bjX#ijX#tjX${jX%cjX%ejX%kjX%ljX%ojX&mjX)VjX~P#&XO)O*`O~Om*aO~O])SXe)SXs)SXt)SXu)SXv)SXw)SXx)SXy)SXz)SX!O)SX!V)SX!r)SX!s)SX!t)SX!u)SX!v)SX!x)SX!{)SX%v)SX&r)SX&s)SX(w)SX)Y)SX)[)SX)])SX)_)SX!T)SX!X)SX!Y)SX![)SX!^)SX!_)SX!a)SX!b)SX!e)SX!f)SX!h)SX(z)SX(|)SX(})SX)Z)SX)^)SX)`)SX!g)SX)p)SX[)SX!W)SXQ)SX!d)SX({)SX!U)SX#v)SX~Om*aO~P#+aOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!O!_O!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO])gae)gam)ga!V)ga!{)ga%v)ga(w)ga)Y)ga)[)ga)])gaQ)ga!d)ga!h)ga)`)ga)p)ga[)ga!T)ga({)ga)_)ga~O&r#WO&s$yO~P#/POq&hOm)SX~P#+aO&r)ga~P#/PO]ZXmhXqZXqjX!TjX!VZX!XZX!YZX![ZX!^ZX!_ZX!aZX!bZX!eZX!fZX!gZX!hZX(zZX(|ZX(}ZX)YZX)ZZX)[ZX)]ZX)^ZX)_ZX)`ZX)pZX[ZX~O!WZX({ZX!UZXQZX!dZX~P#1xO]$PO!V#nO!X#}O(|#mO(}#mO~O!Y&xa![&xa!^&xa!_&xa!a&xa!b&xa!e&xa!f&xa!g&xa!h&xa(z&xa)Y&xa)Z&xa)[&xa)]&xa)^&xa)_&xa)`&xa)p&xa[&xa!W&xa({&xa!U&xaQ&xa!d&xa~P#4YOm;oO!T$YO~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O~PKnOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!|%TO~PKnO]&eO!V&dO[#Qa!T#Qa!h#Qa#v#Qa)_#Qa)p#QaQ#Qa!d#Qa({#Qa~Oq&hO!T$YO~O[*hO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[*hO~O[*jO]&eO!V&dO~O]&[Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V&YO&r#WO&s$yO)Y&XO)[&]O)]&]O~O[rXQrX!drX!hrX)`rX)_rX~P#:ZO[*mO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h*nO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!W)qX~P#4YO!W*pO!h*qO~O!W*pO!h*qO~P!(}O!W*pO~Oq&hO!g$[O!h*rO)p$[O](yX!V(yX!W(yX!W*UX!X(yX!Y(yX![(yX!^(yX!_(yX!a(yX!b(yX!e(yX!f(yX(z(yX(|(yX(}(yX)Y(yX)Z(yX)[(yX)](yX)^(yX)`(yX~O!h(yX~P#=iO!W*tO~Oe$TO%Y*YO)O:yO~Om;rO~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!|%TO~PBXO]*{O!T*vO!V&dO!h*yO#v!eO)p*wO)_)wX~O!h*yO)_)wX~O)_*|O~Oq&hO])kX!T)kX!V)kX!h)kX#v)kX)_)kX)p)kX[)kXQ)kX!d)kX({)kX~Oq&hO~OP%qO(uQO]%ha!V%ha!X%ha!Y%ha![%ha!^%ha!_%ha!a%ha!b%ha!e%ha!f%ha!h%ha(w%ha(z%ha(|%ha(}%ha)Y%ha)Z%ha)[%ha)]%ha)^%ha)_%ha)`%ha!g%ha)p%ha[%ha!W%ha({%ha!U%haQ%ha!d%ha~Oe$TO%Y$UO)O:vO~Om;OO~O!TxO#v!eO)p&OO~Om<cO&r#WO(w;nO~O$Z+YO%`+ZO~O!TxO#v!eO)_+[O)p+]O~OPmO]$gOb%SOm;RO!V$hO!X!XO!Y!WO!i!YO#V#QO$Z+YO%_#ZO%`+_O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~O!U+`O~P!QOb!TOm$qOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO#a+fO#b+gO#i+hO%e#UO%l#SO&m!RO&r#WO&s!TO(w$pO)VYO~OQ)rP!d)rP~P#GuO]&[Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V&YO)Y&XO)[&]O)]&]O~O[#kX!T#kX#v#kX)_#kX)p#kXQ#kX!d#kX!h#kX)`#kX!x#kX({#kX~P#IyOPmO]$gOb%SOm;ROs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V$hO!W+nO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y+oO)]$mO)`!ZO)bXO)ncO)odO~O]&eO!V+pO~O]&[O!V&YO)VYO)Y&XO)[&]O)]&]O)`+sO[)jP~P8}O]&[O!V&YO)Y&XO)[&]O)]&]O~O[#nX!T#nX#v#nX)_#nX)p#nXQ#nX!d#nX!h#nX)`#nX!x#nX({#nX~P#NsO!TxO])tX!V)tX~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O#T+{O#p+|O(}+yO)[+wO)]+wO~O]#jX!T#jX!V#jX[#jX#v#jX)_#jX)p#jXQ#jX!d#jX!h#jX)`#jX!x#jX({#jX~P$!WO#V,OO~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!l,PO#T+{O#V,OO#p+|O(}+yO)[,PO)],PO])lP!T)lP!V)lP#v)lP({)lP)p)lP[)lP!h)lP)_)lP~O!x)lPQ)lP!d)lP~P$$TOPmO]$gOb%SOm;ROs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V$hO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)]$mO)`!ZO)bXO)ncO)odO~O!W,VO)Y,WO~P$&OO)VYO)`+sO[)jP~P8}O]&eO!V&dO[&Za!T&Za!h&Za#v&Za)_&Za)p&ZaQ&Za!d&Za({&Za~OPmO]$gOb!]Om;TOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;YO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~OQ)PP!d)PP~P$)hO]$PO!V#nO(|#mO(}#mO!X'Pa!Y'Pa!['Pa!^'Pa!_'Pa!a'Pa!b'Pa!e'Pa!f'Pa!h'Pa(z'Pa)Y'Pa)Z'Pa)['Pa)]'Pa)^'Pa)_'Pa)`'Pa!g'Pa)p'Pa['Pa!W'Pa({'Pa!U'PaQ'Pa!d'Pa~O]$PO!V#nO!X#}O(|#mO(}#mO~P!BmO!TxO#t!fO)VYO~P8}O!TxO(w%pO)p,aO~O#x,fO~OQ)gX!d)gX!h)gX)`)gX)p)gX[)gX!T)gX({)gX)_)gX~P:qO({,jO(|,hO)V$UX)_$UX~O(w,kO~O)VYO)_,nO~OPmO]$gOb!]Om;SOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!V$hO!X!XO!Y!WO!i!YO!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)VYO)Y$mO)]$mO)_iO)`!ZO)bXO)ncO)odO~O(w;ZO~P$0yOPmO]$gOb%SOm;RO!TxO!V$hO!X!XO!Y!WO!i!YO#V#QO#v!eO$Y!vO$Z!wO$`!iO$e!jO$g!kO$h!lO$k!mO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w:tO)VYO)Y$mO)]$mO)_iO)`!ZO)bXO)ncO)odO~O$h,xO~OPmO]$gOb!]Om;SOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!V$hO!X!XO!Y!WO!i!YO!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO#V#QO#a#VO#b#TO$}!uO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)VYO)Y$mO)]$mO)`!ZO)bXO)ncO)odO~O${-OO(w;UO)_,|O~P$7dO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_-QO)`$OO~P#4YO)_-QO~O)_-RO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_-SO)`$OO~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_-TO)`$OO~P#4YOq&hO)VYO)p-VO~O)_-WO~Om;eO(w;WO~O]-_O!{!dO&r#WO&s$yO(w-ZO)Y-[O~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO({-bO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!TxO$`!iO$e!jO$g!kO$h!lO$k-gO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO$}!uO(w:uOe$Xa!o$Xa!{$Xa#i$Xa#p$Xa#t$Xa#v$Xa$R$Xa$T$Xa$Y$Xa$Z$Xa${$Xa%U$Xa%c$Xa%g$Xa%o$Xa%|$Xa(l$Xa)[$Xa!U$Xa$c$Xa~P$0yO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_-hO)`$OO~P#4YOm-jO!TxO)p,aO~O)p-lO~O]&]a!X&]a!Y&]a![&]a!^&]a!_&]a!a&]a!b&]a!e&]a!f&]a!h&]a(z&]a(|&]a(}&]a)Z&]a)[&]a)]&]a)^&]a)_&]a)`&]a!g&]a)p&]a[&]a!W&]a!T&]a#v&]a({&]a!U&]aQ&]a!d&]a~O)Y-pO!V&]a~P$DpO[-pO~O!W-pO~O!V-qO)Y&]a~P$DpO])SXe)SXs)SXt)SXu)SXv)SXw)SXx)SXy)SXz)SX!O)SX!V)SX!r)SX!s)SX!t)SX!u)SX!v)SX!x)SX!{)SX%v)SX&r)SX&s)SX(w)SX)Y)SX)[)SX)])SX~Om;tO~P$G`O]&eO!V&dO)_-rO~Om;jO!o-uO#V,OO#i-zO#t!fO${-OO%c!zO%k-yO%o!|O%v!}O(w;[O)VYO~P!8mO!n.OO(w,kO~O)VYO)_.QO~OPmO]$gOb%SOm;RO!T.VO!V$hO!X!XO!Y!WO!i!YO#V.^O#a.]O%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO(}.UO)Y$mO)]$mO)_.SO)`!ZO)bXO)ncO)odO~O!U.[O~P$JpO])dXe)dXs)dXt)dXu)dXv)dXw)dXx)dXy)dXz)dX!O)dX!T)dX!V)dX!l)dX!r)dX!s)dX!t)dX!u)dX!v)dX!x)dX!{)dX%v)dX&r)dX&s)dX(w)dX({)dX)Y)dX)[)dX)])dX)_)dX[)dX!h)dX)`)dX!X)dX!Y)dX![)dX!^)dX!_)dX!a)dX!b)dX!e)dX!f)dX(z)dX(|)dX(})dX)Z)dX)^)dX!g)dX)p)dX!W)dXQ)dX!d)dX#T)dX#V)dX#p)dX#v)dXb)dX|)dX!o)dX#a)dX#b)dX#i)dX#t)dX${)dX%c)dX%e)dX%k)dX%l)dX%o)dX&m)dX)V)dX!U)dX~Om*aO~P$LzOm$qO!T(SO!l.cO(w$pO({(RO)VYO~Oq&hOm)dX~P$LzOm$qO!n.hO!o.hO(w$pO)VYO~Om;kO!U.sO!n.uO!o.tO#i-zO${!tO$}!uO%g!{O%k-yO%o!|O%v!}O(w;^O)VYO~P!8mO!T(SO!l.cO({(RO])TXe)TXm)TXs)TXt)TXu)TXv)TXw)TXx)TXy)TXz)TX!O)TX!V)TX!r)TX!s)TX!t)TX!u)TX!v)TX!x)TX!{)TX%v)TX&r)TX&s)TX(w)TX)Y)TX)[)TX)])TX~O)_)TX[)TX!X)TX!Y)TX![)TX!^)TX!_)TX!a)TX!b)TX!e)TX!f)TX!h)TX(z)TX(|)TX(})TX)Z)TX)^)TX)`)TX!g)TX)p)TX!W)TXQ)TX!d)TX!U)TX#v)TX~P%%sO!T(SO~O!T(SO({(RO~O(w%pO!U*WP~O!T(]O({.zO]&kae&kam&kas&kat&kau&kav&kaw&kax&kay&kaz&ka!O&ka!V&ka!r&ka!s&ka!t&ka!u&ka!v&ka!x&ka!{&ka%v&ka&r&ka&s&ka(w&ka)Y&ka)[&ka)]&ka)_&ka[&ka!X&ka!Y&ka![&ka!^&ka!_&ka!a&ka!b&ka!e&ka!f&ka!h&ka(z&ka(|&ka(}&ka)Z&ka)^&ka)`&ka!g&ka)p&ka!W&kaQ&ka!d&ka!U&ka#v&ka~Om$qO!T(]O(w$pO~O&r#WO&s$yO]&pae&pam&pas&pat&pau&pav&paw&pax&pay&paz&pa!O&pa!V&pa!r&pa!s&pa!t&pa!u&pa!v&pa!x&pa!{&pa%v&pa(w&pa)Y&pa)[&pa)]&pa)_&pa[&pa!T&pa!X&pa!Y&pa![&pa!^&pa!_&pa!a&pa!b&pa!e&pa!f&pa!h&pa(z&pa(|&pa(}&pa)Z&pa)^&pa)`&pa!g&pa)p&pa!W&paQ&pa!d&pa({&pa!U&pa#v&pa~O&s/PO~P!(}O!Y#sO![#tO!f#|O)Y#oO!^'Ua!_'Ua!a'Ua!b'Ua!e'Ua!h'Ua(z'Ua)Z'Ua)['Ua)]'Ua)^'Ua)_'Ua)`'Ua!g'Ua)p'Ua['Ua!W'Ua({'Ua!U'UaQ'Ua!d'Ua~P#4YO!V'dX!X'dX!Y'dX!['dX!^'dX!_'dX!a'dX!b'dX!e'dX!f'dX!h'dX(z'dX(|'dX(}'dX)Y'dX)Z'dX)['dX)]'dX)^'dX)`'dX['dX~O]/RO)_'dX!g'dX)p'dX!W'dX({'dX!U'dXQ'dX!d'dX~P%3WO!Y#sO![#tO!f#|O)Y#oO!^'Wa!_'Wa!a'Wa!b'Wa!e'Wa!h'Wa(z'Wa)Z'Wa)['Wa)]'Wa)^'Wa)_'Wa)`'Wa!g'Wa)p'Wa['Wa!W'Wa({'Wa!U'WaQ'Wa!d'Wa~P#4YO]$PO!T$YO!V/SO&r#WO&s$yO~O!X'Za!Y'Za!['Za!^'Za!_'Za!a'Za!b'Za!e'Za!f'Za!h'Za(z'Za(|'Za(}'Za)Y'Za)Z'Za)['Za)]'Za)^'Za)_'Za)`'Za!g'Za)p'Za['Za!W'Za({'Za!U'ZaQ'Za!d'Za~P%6}O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h'^a)_'^a!g'^a)p'^a['^a!W'^a({'^a!U'^aQ'^a!d'^a~P#4YOPmO]$gOb%SOm;RO!V$hO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)Y$mO)]%_O)`!ZO)bXO)ncO)odO)p%^O~O!W/VO~P%:}O(q(lO(r(lO(s/XO~OS(vO]$PO(p#]O*^(uO~O]/[O'f/]O*^/YO~OS/aO(p#]O*^/`O~O]$PO~Q'na!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO({/cO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO)_#Zi[#Zi~P#4YO]dXmhXqdXqjX!VdX!XdX!YdX![dX!^dX!_dX!adX!bdX!edX!fdX!gdX!hdX(zdX(|dX(}dX)YdX)ZdX)[dX)]dX)^dX)_dX)`dX)pdX[dX!WdX({dX!TdX#vdX!UdXQdX!ddX~Oe/eO%Y*YO)O/dO~Om/fO~Om/gO~Oq&hO]ci!Vci!Xci!Yci![ci!^ci!_ci!aci!bci!eci!fci!gci!hci(zci(|ci(}ci)Yci)Zci)[ci)]ci)^ci)_ci)`ci)pci[ci!Wci({ci!UciQci!dci~O!W/iO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO![#tO)Y#oO!Y&zi!^&zi!_&zi!a&zi!b&zi!e&zi!f&zi!h&zi(z&zi)Z&zi)[&zi)]&zi)^&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y&zi![&zi!^&zi!_&zi!a&zi!b&zi!e&zi!f&zi!h&zi(z&zi)Y&zi)Z&zi)[&zi)]&zi)^&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O)Y#oO)]#rO)^#jO!h&zi(z&zi)Z&zi)[&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O)Y#oO)[#pO)]#rO)^#jO!h&zi(z&zi)Z&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!_#xO!a#zO!b#{O!e#{O!f#|O)Y#oO)]#rO)^#jO!^&zi!h&zi(z&zi)Z&zi)[&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!a#zO!b#{O!e#{O!f#|O)Y#oO)]#rO)^#jO!^&zi!_&zi!h&zi(z&zi)Z&zi)[&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!a#zO!b#{O!e#{O!f#|O)Y#oO)^#jO!^&zi!_&zi!h&zi(z&zi)Z&zi)[&zi)]&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!b#{O!e#{O!f#|O)Y#oO)^#jO!^&zi!_&zi!a&zi!h&zi(z&zi)Z&zi)[&zi)]&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!f#|O)Y#oO!^&zi!_&zi!a&zi!b&zi!e&zi!h&zi(z&zi)Z&zi)[&zi)]&zi)^&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO)Y#oO!^&zi!_&zi!a&zi!b&zi!e&zi!f&zi!h&zi(z&zi)Z&zi)[&zi)]&zi)^&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O)Y#oO)Z#qO)[#pO)]#rO)^#jO!h&zi(z&zi)_&zi)`&zi!g&zi)p&zi[&zi!W&zi({&zi!U&ziQ&zi!d&zi~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h/jO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO[(xX~P#4YO!h/jO[(xX~O[/lO~O]%Xaq%Xa!X%Xa!Y%Xa![%Xa!^%Xa!_%Xa!a%Xa!b%Xa!e%Xa!f%Xa!h%Xa(z%Xa(|%Xa(}%Xa)Z%Xa)[%Xa)]%Xa)^%Xa)_%Xa)`%Xa!g%Xa)p%Xa[%Xa!W%Xa!T%Xa#v%Xa({%Xa!U%XaQ%Xa!d%Xa~O)Y/mO!V%Xa~P&,zO[/mO~O!W/mO~O!V/nO)Y%Xa~P&,zO!X'Zi!Y'Zi!['Zi!^'Zi!_'Zi!a'Zi!b'Zi!e'Zi!f'Zi!h'Zi(z'Zi(|'Zi(}'Zi)Y'Zi)Z'Zi)['Zi)]'Zi)^'Zi)_'Zi)`'Zi!g'Zi)p'Zi['Zi!W'Zi({'Zi!U'ZiQ'Zi!d'Zi~P%6}O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h'^i)_'^i!g'^i)p'^i['^i!W'^i({'^i!U'^iQ'^i!d'^i~P#4YO!W/sO~P%:}O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h/uO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!U)xX~P#4YO(w/xO~O!V/zO(|)xO)p/|O~O!h/uO!U)xX~O!U/}O~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h`i(z`i)_`i!g`i)p`i[`i!W`i({`i!U`iQ`i!d`i~P#4YO!R0OO~Om*QO]!Qa!h!Qa)U!Qa)`!Qa~OP0WO]0VOm0WO!R0WO!T0TO!V0UO!X0WO!Y0WO![0WO!^0WO!_0WO!a0WO!b0WO!e0WO!f0WO!g0WO!h0WO!i0WO(uQO({0WO(|0WO(}0WO)Y0QO)Z0RO)[0RO)]0SO)^#jO)_0WO)`0WO)bXO~O[0ZO~P&7dO!R$^O~O!h*TO)U)Wa)`)Wa~O)U0_O~O])iO!V)jO!X)gO!g)gO%Z)gO%[)gO%])gO%^)gO%_)kO%`)kO%a)gO(})hO)p)gO*O)lO~Oe)tO%Y*YO)O$QO~O)_0aO~O]oXeoXmnXqoXsoXtoXuoXvoXwoXxoXyoXzoX!OoX!VoX!roX!soX!toX!uoX!voX!xoX!{oX%voX&roX&soX(woX)YoX)[oX)]oX!ToX!hoX)`oX[oXQoX!doX~O!loX({oX)_oX!XoX!YoX![oX!^oX!_oX!aoX!boX!eoX!foX(zoX(|oX(}oX)ZoX)^oX!goX)poX!WoX!UoX#voX#ToX#VoX#poXboX|oX!ooX#aoX#boX#ioX#toX${oX%coX%eoX%koX%loX%ooX&moX)VoX~P&;`Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!O!_O!r!aO!s!aO!t!aO!u!aO!v!aO!x!cO~O])gie)gim)gi!V)gi!{)gi%v)gi(w)gi)Y)gi)[)gi)])giQ)gi!d)gi!h)gi)`)gi)p)gi[)gi!T)gi&r)gi({)gi)_)gi~P&@^O]&eO!V&dO[#Qi!T#Qi!h#Qi#v#Qi)_#Qi)p#QiQ#Qi!d#Qi({#Qi~O[raQra!dra!hra)`ra)_ra~P#:ZO[raQra!dra!hra)`ra)_ra~P#IyO]&eO!V+pO[raQra!dra!hra)`ra)_ra~O!h*nO!W)qa~O!h*rO!W*Ua~OPmOb!]Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O|#RO!O!_O!X!XO!Y!WO!i!YO!s!aO!t!aO!v!aO!x!cO#V#QO#a#VO#b#TO#v!eO$Y!vO$Z!wO$`!iO$e!jO$g!kO$h!lO$k!mO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO%_#ZO%`#[O%a#YO%e#UO%l#SO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO)VYO)_iO)`!ZO)bXO)ncO)odO~O]eOe!POmTO!T*vO!U&VO!V0oO!opO!r!`O!u!bO!{!dO#i#OO#p!xO#t!fO$R!gO$T!hO${!tO$}!uO%U!yO%c!zO%g!{O%o!|O%v!}O%|#PO(wRO(|)xO)YaO)[|O)]{O~P&E`O!h*yO)_)wa~OPmO]$gOb!]Om;TO|#RO!T$YO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;]O)VYO)Y$mO)]$mO)`0uO)bXO)ncO)odO[(xP[)jP~P&@^O!h*rO!W*UX~O]$PO!T$YO~O!h0zO!T*QX#v*QX)p*QX~O)_0|O~O)_0}O~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_1PO)`$OO~P#4YO)_0}O~P!?ZO]1ZOe!POm%dO!V1XO!{!dO%v$oO(w$zO)Y1RO)`1UO~O)[1VO)]1VO)p1SOQ#PX!d#PX!h#PX[#PX~P' }O!h1[OQ)rX!d)rX~OQ1^O!d1^O~O)`1aO)p1`OQ#`X!d#`X!h#`X~P!<_O)`1aO)p1`OQ#`X!d#`X!h#`X~P!;eOq&WO~O[#ka!T#ka#v#ka)_#ka)p#kaQ#ka!d#ka!h#ka)`#ka!x#ka({#ka~P#IyO]&eO!V+pO[#ka!T#ka#v#ka)_#ka)p#kaQ#ka!d#ka!h#ka)`#ka!x#ka({#ka~O!W1fO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W1fO)Y1hO~P$&OO!W1fO~P!(}O]#ja!T#ja!V#ja[#ja#v#ja)_#ja)p#jaQ#ja!d#ja!h#ja)`#ja!x#ja({#ja~P$!WO[1lO]&eO!V+pO~O!h1mO[)jX~O[1oO~O]&eO!V+pO[#na!T#na#v#na)_#na)p#naQ#na!d#na!h#na)`#na!x#na({#na~O]1sOs#SXt#SXu#SXv#SXw#SXx#SXy#SXz#SX!T#SX!V#SX#T#SX#p#SX(}#SX)[#SX)]#SX!l#SX!x#SX#V#SX#v#SX({#SX)p#SX[#SX!h#SX)_#SXQ#SX!d#SX)`#SX~O]1tO~O]1wOm$qO!V$hO#V#QO(w$pO)ncO)odO~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!l,PO#T+{O#V,OO#p+|O(}+yO)[,PO)],PO~O])lX!T)lX!V)lX!x)lX#v)lX({)lX)p)lX[)lX!h)lX)_)lXQ)lX!d)lX~P',hO!x!cO]#Ri!T#Ri!V#Ri#v#Ri({#Ri)p#Ri[#Ri!h#Ri)_#RiQ#Ri!d#Ri~O!W2PO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W2PO)Y2RO~P$&OO!W2PO~P!(}O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OOQ*XX!d*XX!h*XX~P#4YO)`2SOQ)QX!d)QX!h)QX~O!h2TOQ)PX!d)PX~OQ2VO!d2VO~O[2WO~O#t$nO)VYO~P8}Om-jO!TxO)p2[O~O[2]O~O#x,fOP#ui]#uib#uie#uim#uis#uit#uiu#uiv#uiw#uix#uiy#uiz#ui|#ui!O#ui!T#ui!V#ui!X#ui!Y#ui!i#ui!o#ui!r#ui!s#ui!t#ui!u#ui!v#ui!x#ui!{#ui#V#ui#a#ui#b#ui#i#ui#p#ui#t#ui#v#ui$R#ui$T#ui$Y#ui$Z#ui$`#ui$e#ui$g#ui$h#ui$k#ui$m#ui$o#ui$q#ui$s#ui$u#ui$w#ui${#ui$}#ui%U#ui%_#ui%`#ui%a#ui%c#ui%e#ui%g#ui%l#ui%o#ui%v#ui%|#ui&m#ui&r#ui&s#ui'Q#ui'R#ui'V#ui'Y#ui'a#ui'b#ui(l#ui(u#ui(w#ui)V#ui)Y#ui)[#ui)]#ui)_#ui)`#ui)b#ui)n#ui)o#ui!U#ui$c#ui!n#ui%k#ui~O]&eO~O]&eO!TxO!V&dO#v!eO~O({2bO(|,hO)V$Ua)_$Ua~O)VYO)_2dO~O[2eO~P,`O[2eO)_#lO~O[2eO~O$c2jOP$_i]$_ib$_ie$_im$_is$_it$_iu$_iv$_iw$_ix$_iy$_iz$_i|$_i!O$_i!T$_i!V$_i!X$_i!Y$_i!i$_i!o$_i!r$_i!s$_i!t$_i!u$_i!v$_i!x$_i!{$_i#V$_i#a$_i#b$_i#i$_i#p$_i#t$_i#v$_i$R$_i$T$_i$Y$_i$Z$_i$`$_i$e$_i$g$_i$h$_i$k$_i$m$_i$o$_i$q$_i$s$_i$u$_i$w$_i${$_i$}$_i%U$_i%_$_i%`$_i%a$_i%c$_i%e$_i%g$_i%l$_i%o$_i%v$_i%|$_i&m$_i&r$_i&s$_i'Q$_i'R$_i'V$_i'Y$_i'a$_i'b$_i(l$_i(u$_i(w$_i)V$_i)Y$_i)[$_i)]$_i)_$_i)`$_i)b$_i)n$_i)o$_i!U$_i~O]1wO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_2mO)`$OO~P#4YOPmO]$gOb!]Om;SO|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;UO)Y$mO)]$mO)_2pO)`!ZO)bXO)ncO)odO~P&@^O)_2mO~O(w-ZO~O)VYO)p2sO~O)_2uO~O]-_Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!{!dO!|%TO(w-ZO)Y-[O~O)Y2zO~O]&eO!V2|O!h2}O)_){X~O]-_O!{!dO(w-ZO)Y-[O~O)_3QO~O!TxO$`!iO$e!jO$g!kO$h!lO$k-gO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO$}!uO(w:uOe$Xi!o$Xi!{$Xi#i$Xi#p$Xi#t$Xi#v$Xi$R$Xi$T$Xi$Y$Xi$Z$Xi${$Xi%U$Xi%c$Xi%g$Xi%o$Xi%|$Xi(l$Xi)[$Xi!U$Xi$c$Xi~P$0yOm;SO(w:uO~P0}O]3UO~O)_2ZO~O!u3WO(w%pO~O[3ZO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h3[O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[3]O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO]&eO!V+pO!T%ui#v%ui)_%ui)p%ui~O!W3^O~Om;QO)_)SX~P$G`Ob!TOm$qO|3dO#a#VO#b3cO#t!fO%e#UO%l3eO&m!RO&r#WO&s!TO(w$pO)VYO~P&@^Om;jO!o-uO#i-zO#t!fO${-OO%c!zO%k-yO%o!|O%v!}O(w;[O)VYO~P!8mO]&eO!V&dO)_3gO~O)_3hO~O)VYO)_3hO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_3iO)`$OO~P#4YO)_3iO~O)_3lO~O!U3nO~P$JpOm$qO(w$pO~O]3pO!T'{O~P',SO!T(SO!l3sO({(RO])Tae)Tam)Tas)Tat)Tau)Tav)Taw)Tax)Tay)Taz)Ta!O)Ta!V)Ta!r)Ta!s)Ta!t)Ta!u)Ta!v)Ta!x)Ta!{)Ta%v)Ta&r)Ta&s)Ta(w)Ta)Y)Ta)[)Ta)])Ta)_)Ta[)Ta!X)Ta!Y)Ta![)Ta!^)Ta!_)Ta!a)Ta!b)Ta!e)Ta!f)Ta!h)Ta(z)Ta(|)Ta(})Ta)Z)Ta)^)Ta)`)Ta!g)Ta)p)Ta!W)TaQ)Ta!d)Ta!U)Ta#v)Ta~Om$qO!n.hO!o.hO(w$pO~O!h3wO)`3yO!T)eX~O!o3{O)VYO~P8}O)_3|O~PGYO]4ROm)QO!T$YO!{!dO%v$oO&r#WO(w)PO({4VO)Y4OO)[4SO)]4SO~O)_4WO)p4YO~P('OOm;kO!U4[O!n.uO!o.tO#i-zO${!tO$}!uO%g!{O%k-yO%o!|O%v!}O(w;^O)VYO~P!8mOm;kO%v!}O(w;^O~P!8mO({4]O~Om$qO!T(SO(w$pO({(RO)VYO~O!l3sO~P()^O)p4_O!U&oX!h&oX~O!h4`O!U*WX~O!U4bO~Ob4dOm$qO&m!RO(w$pO~O!T(]O]&kie&kim&kis&kit&kiu&kiv&kiw&kix&kiy&kiz&ki!O&ki!V&ki!r&ki!s&ki!t&ki!u&ki!v&ki!x&ki!{&ki%v&ki&r&ki&s&ki(w&ki)Y&ki)[&ki)]&ki)_&ki[&ki!X&ki!Y&ki![&ki!^&ki!_&ki!a&ki!b&ki!e&ki!f&ki!h&ki(z&ki(|&ki(}&ki)Z&ki)^&ki)`&ki!g&ki)p&ki!W&kiQ&ki!d&ki!U&ki#v&ki~O({&ki~P(*nO({.zO~P(*nO[4gO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[4gO~O[4hO~O]$PO!T$YO!V'Zi!X'Zi!Y'Zi!['Zi!^'Zi!_'Zi!a'Zi!b'Zi!e'Zi!f'Zi!h'Zi(z'Zi(|'Zi(}'Zi)Y'Zi)Z'Zi)['Zi)]'Zi)^'Zi)_'Zi)`'Zi!g'Zi)p'Zi['Zi!W'Zi({'Zi!U'ZiQ'Zi!d'Zi~OPmOb%SOm;RO!X!XO!Y!WO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)`!ZO)bXO)ncO)odO]#]aq#]a!T#]a!V#]a)Y#]a)[#]a)]#]a~O(w%pO)`4mO[*`P~O*^4lO~O'f4oO*^4lO~O*^4pO~OmnXqoXq&wX~Oe4rO%Y*YO)O/dO~Oe4rO%Y*YO)O4sO~O!h/jO[(xa~O!W4wO~O]&eO!V+pO!T%uq#v%uq)_%uq)p%uq~O]$PO!T$YO!X'Zq!Y'Zq!['Zq!^'Zq!_'Zq!a'Zq!b'Zq!e'Zq!f'Zq!h'Zq(z'Zq(|'Zq(}'Zq)Y'Zq)Z'Zq)['Zq)]'Zq)^'Zq)_'Zq)`'Zq!g'Zq)p'Zq['Zq!W'Zq({'Zq!U'ZqQ'Zq!d'Zq~O!V'Zq~P(5{O!V/SO&r#WO&s$yO~P(5{O!T$YO!V)wO(|)xO!U(VX!h(VX~P!KVO!h/uO!U)xa~O!W5PO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h*nO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!U5TO~P&7dO!W5TO~P&7dO[5TO~P&7dO[5YO~P&7dO]5ZO!h'va)U'va)`'va~O!h*TO)U)Wi)`)Wi~O]&eO!V&dO[#Qq!T#Qq!h#Qq#v#Qq)_#Qq)p#QqQ#Qq!d#Qq({#Qq~O[riQri!dri!hri)`ri)_ri~P#IyO]&eO!V+pO[riQri!dri!hri)`ri)_ri~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h'Tq)_'Tq!g'Tq)p'Tq['Tq!W'Tq({'Tq!U'TqQ'Tq!d'Tq~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!W'}a!h'}a~P#4YO!W5`O~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h5aO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_#lO)`$OO!U)xX~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h#{i)_#{i~P#4YO]*{O!T$YO!V&dO)p*wO!h(Wa)_(Wa~O!h1mO[)jX]'dX~P%3WO)`5cO!T%qa!h%qa#v%qa)p%qa~O!h0zO!T*Qa#v*Qa)p*Qa~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_5fO)`$OO~P#4YO]1ZOe!POm;cO!V1XO!{!dO%v$oO(w$zO)Y<PO)[5hO)]5hO~OQ#Pa!d#Pa!h#Pa[#Pa~P(ETO]1ZOe!POs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V1XO!{!dO!|%TO%v$oO(w$zOQ#kX!d#kX!h#kX[#kX~Om%dO)Y1RO)[<QO)]<QO~P(FVO]&eOQ#Pa!d#Pa!h#Pa[#Pa~O!V&dO)p5lO~P(GtO(w%pOQ#dX!d#dX!h#dX[#dX~O)[<QO)]<QOQ#nX!d#nX!h#nX[#nX~P' }O!V+pO~P(GtO]1ZOb!TOe!POm;dO|#RO!V1XO!{!dO#a#VO#b#TO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO(w;XO)VYO)Y<PO)[5hO)]5hO)`+sO[)jP~P&@^O!h1[OQ)ra!d)ra~Oq&hO)p5qOQ#`am)SX!d#`a!h#`a)`)SX~P$G`O(w-ZOQ#ga!d#ga!h#ga~Oq&hO)p5qOQ#`a])dXe)dXm)dXs)dXt)dXu)dXv)dXw)dXx)dXy)dXz)dX!O)dX!T)dX!V)dX!d#`a!h#`a!l)dX!r)dX!s)dX!t)dX!u)dX!v)dX!x)dX!{)dX%v)dX&r)dX&s)dX(w)dX({)dX)Y)dX)[)dX)])dX)`)dX~O#a5tO#b5tO~O]&eO!V+pO[#ki!T#ki#v#ki)_#ki)p#kiQ#ki!d#ki!h#ki)`#ki!x#ki({#ki~O!W5vO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W5vO~P!(}O!W5vO)Y5xO~P$&OO]#ji!T#ji!V#ji[#ji#v#ji)_#ji)p#jiQ#ji!d#ji!h#ji)`#ji!x#ji({#ji~P$!WO)VYO)`5zO~P8}O!h1mO[)ja~O&r#WO&s$yO!T#qa!x#qa#v#qa({#qa)p#qa[#qa!h#qa)_#qaQ#qa!d#qa)`#qa~P#NsO[6PO~P!(}O[)uP~P!4{O)Z6VO)[6TO]#Ua!T#Ua!V#Ua)Y#Ua)]#Uas#Uat#Uau#Uav#Uaw#Uax#Uay#Uaz#Ua!l#Ua!x#Ua#T#Ua#V#Ua#p#Ua#v#Ua({#Ua(}#Ua)p#Uab#Uae#Uam#Ua|#Ua!O#Ua!o#Ua!r#Ua!s#Ua!t#Ua!u#Ua!v#Ua!{#Ua#a#Ua#b#Ua#i#Ua#t#Ua${#Ua%c#Ua%e#Ua%k#Ua%l#Ua%o#Ua%v#Ua&m#Ua&r#Ua&s#Ua(w#Ua)V#Ua)_#Ua[#Ua!h#UaQ#Ua!d#Ua~O!x!cO]#Rq!T#Rq!V#Rq#v#Rq({#Rq)p#Rq[#Rq!h#Rq)_#RqQ#Rq!d#Rq~O!W6[O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W6[O~P!(}O!h2TOQ)Pa!d)Pa~O)_6aO~Om-jO!TxO)p6bO~O]*{O!T$YO!V&dO!h*yO)_)wX~O)p6fO~P)+|O[6hO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[6hO~O$c6jOP$_q]$_qb$_qe$_qm$_qs$_qt$_qu$_qv$_qw$_qx$_qy$_qz$_q|$_q!O$_q!T$_q!V$_q!X$_q!Y$_q!i$_q!o$_q!r$_q!s$_q!t$_q!u$_q!v$_q!x$_q!{$_q#V$_q#a$_q#b$_q#i$_q#p$_q#t$_q#v$_q$R$_q$T$_q$Y$_q$Z$_q$`$_q$e$_q$g$_q$h$_q$k$_q$m$_q$o$_q$q$_q$s$_q$u$_q$w$_q${$_q$}$_q%U$_q%_$_q%`$_q%a$_q%c$_q%e$_q%g$_q%l$_q%o$_q%v$_q%|$_q&m$_q&r$_q&s$_q'Q$_q'R$_q'V$_q'Y$_q'a$_q'b$_q(l$_q(u$_q(w$_q)V$_q)Y$_q)[$_q)]$_q)_$_q)`$_q)b$_q)n$_q)o$_q!U$_q~O)_6kO~OPmO]$gOb!]Om;SO|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;UO)Y$mO)]$mO)_6mO)`!ZO)bXO)ncO)odO~P&@^O({6oO)p*wO~P)+|O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_6mO)`$OO~P#4YO[6qO~P!(}O)_6uO~O)_6vO~O]-_Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!{!dO(w-ZO)Y-[O~O]&eO!V2|O!h%Oa)_%Oa[%Oa~O!W6|O)Y6}O~P$&OO!h2}O)_){a~O[7QO]&eO!V2|O~O!TxO$`!iO$e!jO$g!kO$h!lO$k-gO$m!nO$o!oO$q!pO$s!qO$u!rO$w!sO$}!uO(w:uOe$Xq!o$Xq!{$Xq#i$Xq#p$Xq#t$Xq#v$Xq$R$Xq$T$Xq$Y$Xq$Z$Xq${$Xq%U$Xq%c$Xq%g$Xq%o$Xq%|$Xq(l$Xq)[$Xq!U$Xq$c$Xq~P$0yOPmO]$gOb!]Om;SO|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;UO)VYO)Y$mO)]$mO)_7SO)`!ZO)bXO)ncO)odO~P&@^O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_7VO)`$OO~P#4YO)_7WO~OP7XO(uQO~Om*aO)_)dX~P$G`Oq&hOm)SX)_)dX~P$G`O)_7ZO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO)_&Sa~P#4YO!U7]O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO)_7^O~OPmO]$gOb!]Om;TO|#RO!V$hO!X!XO!Y!WO!i!YO#V#QO#a#VO#b#TO%_#ZO%`#[O%a#YO%e#UO%l#SO%v$oO&m!RO&r#WO&s!TO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w;]O)VYO)Y$mO)]$mO)`0uO)bXO)ncO)odO[)jP~P&@^O!h3wO)`7bO!T)ea~O!h3wO!T)ea~O)_7gO)p7iO~P('OO)_7kO~PGYO]4ROm)QOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!{!dO!|%TO%v$oO&r#WO(w)PO)Y4OO)[4SO)]4SO~O)Y7oO~O]&eO!T*vO!V7qO!h7rO#v!eO({4VO~O)_7gO)p7tO~P)GbO]4ROm)QO!{!dO%v$oO&r#WO(w)PO)Y4OO)[4SO)]4SO~Oq&hO])iX!T)iX!V)iX!h)iX#v)iX({)iX)_)iX)p)iX[)iX~O)_7gO~O!T(SO!l7zO({(RO])Tie)Tim)Tis)Tit)Tiu)Tiv)Tiw)Tix)Tiy)Tiz)Ti!O)Ti!V)Ti!r)Ti!s)Ti!t)Ti!u)Ti!v)Ti!x)Ti!{)Ti%v)Ti&r)Ti&s)Ti(w)Ti)Y)Ti)[)Ti)])Ti)_)Ti[)Ti!X)Ti!Y)Ti![)Ti!^)Ti!_)Ti!a)Ti!b)Ti!e)Ti!f)Ti!h)Ti(z)Ti(|)Ti(})Ti)Z)Ti)^)Ti)`)Ti!g)Ti)p)Ti!W)TiQ)Ti!d)Ti!U)Ti#v)Ti~O(w%pO!U(gX!h(gX~O!h4`O!U*Wa~Oq&hO]*Vae*Vam*Vas*Vat*Vau*Vav*Vaw*Vax*Vay*Vaz*Va!O*Va!T*Va!V*Va!r*Va!s*Va!t*Va!u*Va!v*Va!x*Va!{*Va%v*Va&r*Va&s*Va(w*Va)Y*Va)[*Va)]*Va)_*Va[*Va!X*Va!Y*Va![*Va!^*Va!_*Va!a*Va!b*Va!e*Va!f*Va!h*Va(z*Va(|*Va(}*Va)Z*Va)^*Va)`*Va!g*Va)p*Va!W*VaQ*Va!d*Va({*Va!U*Va#v*Va~O!T(]O]&kqe&kqm&kqs&kqt&kqu&kqv&kqw&kqx&kqy&kqz&kq!O&kq!V&kq!r&kq!s&kq!t&kq!u&kq!v&kq!x&kq!{&kq%v&kq&r&kq&s&kq(w&kq)Y&kq)[&kq)]&kq)_&kq[&kq!X&kq!Y&kq![&kq!^&kq!_&kq!a&kq!b&kq!e&kq!f&kq!h&kq(z&kq(|&kq(}&kq)Z&kq)^&kq)`&kq!g&kq)p&kq!W&kqQ&kq!d&kq({&kq!U&kq#v&kq~OPmOb%SOm;RO!T$YO!i!YO#V#QO%_#ZO%`#[O%a#YO%v$oO'Q!WO'R!WO'V#XO'Y![O'a![O'b![O(uQO(w$zO)bXO)ncO)odO~O]*[i!V*[i!X*[i!Y*[i![*[i!^*[i!_*[i!a*[i!b*[i!e*[i!f*[i!h*[i(z*[i(|*[i(}*[i)Y*[i)Z*[i)[*[i)]*[i)^*[i)_*[i)`*[i!g*[i)p*[i[*[i!W*[i({*[i!U*[iQ*[i!d*[i~P*&qO[8PO~O!W8QO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h'^q)_'^q!g'^q)p'^q['^q!W'^q({'^q!U'^qQ'^q!d'^q~P#4YO!h8RO[*`X~O[8TO~O*^8UO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h_y)__y!g_y)p_y[_y!W_y({_y!U_yQ_y!d_y~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO[(ia!h(ia~P#4YO]$PO!T$YO!V'Zy!X'Zy!Y'Zy!['Zy!^'Zy!_'Zy!a'Zy!b'Zy!e'Zy!f'Zy!h'Zy(z'Zy(|'Zy(}'Zy)Y'Zy)Z'Zy)['Zy)]'Zy)^'Zy)_'Zy)`'Zy!g'Zy)p'Zy['Zy!W'Zy({'Zy!U'ZyQ'Zy!d'Zy~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!h'^y)_'^y!g'^y)p'^y['^y!W'^y({'^y!U'^yQ'^y!d'^y~P#4YO]&eO!V+pO!T%uy#v%uy)_%uy)p%uy~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!U(Va!h(Va~P#4YO!W5PO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!U#}i!h#}i~P#4YO!U8WO~P&7dO!W8WO~P&7dO[8WO~P&7dO[8YO~P&7dO]&eO!V&dO[#Qy!T#Qy!h#Qy#v#Qy)_#Qy)p#QyQ#Qy!d#Qy({#Qy~O]&eO!V+pO[rqQrq!drq!hrq)`rq)_rq~O]&eOQ#Pi!d#Pi!h#Pi[#Pi~O!V+pO~P*:TOQ#nX!d#nX!h#nX[#nX~P(ETO!V&dO~P*:TOQ(PX](PXe'rXm'rXs(PXt(PXu(PXv(PXw(PXx(PXy(PXz(PX!V(PX!d(PX!h(PX!{'rX%v'rX(w'rX)Y(PX)[(PX)](PX[(PX~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OOQ#_i!d#_i!h#_i[#_i~P#4YO&r#WO&s$yOQ#fi!d#fi!h#fi~O(w-ZO)`1aO)p1`OQ#`X!d#`X!h#`X~O!W8_O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W8_O~P!(}O!T#qi!x#qi#v#qi({#qi)p#qi[#qi!h#qi)_#qiQ#qi!d#qi)`#qi~O]&eO!V+pO~P*@PO]&[O!V&YO&r#WO&s$yO)Y&XO)[&]O)]&]O~P*@PO[8aO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!h8bO[)uX~O[8dO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OOQ*ZX!d*ZX!h*ZX~P#4YO)`8gOQ*YX!d*YX!h*YX~O)_8iO~O[$bi!h#{a)_#{a~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_8lO)`$OO~P#4YO[8nO~P!(}O[8nO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[8nO~O]&eO!V&dO({8tO~O)_8uO~O]&eO!V2|O!h%Oi)_%Oi[%Oi~O!W8xO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W8xO)Y8zO~P$&OO!W8xO~P!(}O]&eO!V2|O!h(Za)_(Za~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_8{O)`$OO~P#4YO)_2pO~P!(}O)_8{O~OP%qO[8|O(uQO~O[8|O~O)_8}O~P%%sO#T9QO(}.UO)_9OO~O!h3wO!T)ei~O)`9UO!T'xa!h'xa~O)_9WO)p9YO~P)GbO)_9WO~O)_9WO)p9^O~P('OOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O~P)HQO]&eO!V7qO!T!ya!h!ya#v!ya({!ya)_!ya)p!ya[!ya~O!W9eO)Y9fO~P$&OO!T$YO!h7rO({4VO)_9WO)p9^O~O!T$YO~P#EtO[9iO]&eO!V7qO~O]&eO!V7qO!T&aa!h&aa#v&aa({&aa)_&aa)p&aa[&aa~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO)_&ba~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_9WO)`$OO~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!U&oi!h&oi~P#4YO!V/SO]']i!T']i!X']i!Y']i![']i!^']i!_']i!a']i!b']i!e']i!f']i!h']i(z']i(|']i(}']i)Y']i)Z']i)[']i)]']i)^']i)_']i)`']i!g']i)p']i[']i!W']i({']i!U']iQ']i!d']i~O(w%pO)`9lO~O!h8RO[*`a~O[9nO~P&7dO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO!U(Va)_#Zi~P#4YO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OOQ#_q!d#_q!h#_q[#_q~P#4YO&r#WO&s$yOQ#fq!d#fq!h#fq~O)p5qOQ#`a!d#`a!h#`a~O]&eO!V+pO!T#qq!x#qq#v#qq({#qq)p#qq[#qq!h#qq)_#qqQ#qq!d#qq)`#qq~O!h8bO[)ua~O)[6TO]&Vi!T&Vi!V&Vi)Y&Vi)Z&Vi)]&Vis&Vit&Viu&Viv&Viw&Vix&Viy&Viz&Vi!l&Vi!x&Vi#T&Vi#V&Vi#p&Vi#v&Vi({&Vi(}&Vi)p&Vib&Vie&Vim&Vi|&Vi!O&Vi!o&Vi!r&Vi!s&Vi!t&Vi!u&Vi!v&Vi!{&Vi#a&Vi#b&Vi#i&Vi#t&Vi${&Vi%c&Vi%e&Vi%k&Vi%l&Vi%o&Vi%v&Vi&m&Vi&r&Vi&s&Vi(w&Vi)V&Vi)_&Vi[&Vi!h&ViQ&Vi!d&Vi~O)_9qO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO[$bq!h#{i)_#{i~P#4YO[9sO~P!(}O[9sO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[9sO~O]&eO!V&dO({9vO~O[9wO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[9wO~O]&eO!V2|O!h%Oq)_%Oq[%Oq~O!W9{O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W9{O~P!(}O)_6mO~P!(}O)_9|O~O)_9}O~O(}.UO)_9}O~O!h3wO!T)eq~O)`:PO!T'xi!h'xi~O!T$YO!h7rO({4VO)_:QO)p:SO~O)_:QO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_:QO)`$OO~P#4YO)_:QO)p:VO~P)GbO]&eO!V7qO!T!yi!h!yi#v!yi({!yi)_!yi)p!yi[!yi~O!W:ZO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W:ZO)Y:]O~P$&OO!W:ZO~P!(}O]&eO!V7qO!T(ea!h(ea({(ea)_(ea)p(ea~O[:_O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O!h#kO(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[:_O~O[:dO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[:dO~O]&eO!V2|O!h%Oy)_%Oy[%Oy~O)_:eO~O)_:fO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_:fO)`$OO~P#4YO!T$YO!h7rO({4VO)_:fO)p:iO~O]&eO!V7qO!T!yq!h!yq#v!yq({!yq)_!yq)p!yq[!yq~O!W:kO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO!W:kO~P!(}O[:mO!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)`$OO~P#4YO[:mO~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_:oO)`$OO~P#4YO)_:oO~O]&eO!V7qO!T!yy!h!yy#v!yy({!yy)_!yy)p!yy[!yy~O!Y#sO![#tO!^#wO!_#xO!a#zO!b#{O!e#{O!f#|O(z#hO)Y#oO)Z#qO)[#pO)]#rO)^#jO)_:sO)`$OO~P#4YO)_:sO~O]ZXmhXqZXqjX!TjX!VZX!XZX!YZX![ZX!^ZX!_ZX!aZX!bZX!eZX!fZX!gZX!hZX(zZX({$]X(|ZX(}ZX)YZX)ZZX)[ZX)]ZX)^ZX)_ZX)`ZX)pZX~O]%WXmnXqoXq%WX!ToX!V%WX!X%WX!Y%WX![%WX!^%WX!_%WX!a%WX!b%WX!e%WX!f%WX!gnX!h%WX(z%WX(|%WX(}%WX)Y%WX)Z%WX)[%WX)]%WX)^%WX)`%WX)pnX[%WXQ%WX!d%WX~O)_%WX!W%WX({%WX!U%WX~P+H]O]oX]%WXeoXmnXqoXq%WXsoXtoXuoXvoXwoXxoXyoXzoX!OoX!VoX!V%WX!roX!soX!toX!uoX!voX!xoX!{oX%voX&roX&soX(woX)YoX)[oX)]oX[oX[%WX!hoX)`oX~O)_oX)poX~P+JmO]%WXmnXqoXq%WX!V%WX!h%WXQ%WX!d%WX[%WX~O!T%WX#v%WX)_%WX)p%WX({%WX~P+MWOQoXQ%WX!ToX!X%WX!Y%WX![%WX!^%WX!_%WX!a%WX!b%WX!doX!d%WX!e%WX!f%WX!gnX!h%WX(z%WX(|%WX(}%WX)Y%WX)Z%WX)[%WX)]%WX)^%WX)`%WX)pnX~P+JmO]oX]%WXmnXqoXq%WXsoXtoXuoXvoXwoXxoXyoXzoX!OoX!V%WX!roX!soX!toX!uoX!voX!xoX!{oX%voX&roX&soX(woX)YoX)[oX)]oX~O!ToX({oX)_oX)poX~P,!OOeoX!VoX)_%WX~P,!OOmnXqoX)_%WX~Oe)tO%Y)uO)O:vO~Oe)tO%Y)uO)O:{O~Oe)tO%Y)uO)O:wO~Oe$TO%Y*YO'[$VO'_$WO)O:vO~Oe$TO%Y*YO'[$VO'_$WO)O:xO~Oe$TO%Y*YO'[$VO'_$WO)O:zO~O[jX]jXsjXtjXujXvjXwjXxjXyjXzjX!VjX&rjX&sjX)YjX)[jX)]jXejX!OjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX(wjX~P#1xO]ZXmhXqZXqjX!VZX!hZX)_ZX)pZX~O!TZX#vZX({ZX~P,(fOmhXqjX)VjX)_ZX)pjX~O]ZX]jXejXmhXqZXqjXsjXtjXujXvjXwjXxjXyjXzjX!OjX!VZX!VjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX)YjX)[jX)]jX[ZX[jX!hjX)`jX)pjX~O)_ZX~P,)pO]ZX]jXmhXqZXqjXsjXtjXujXvjXwjXxjXyjXzjX!TjX!VZX!VjX!XZX!YZX![ZX!^ZX!_ZX!aZX!bZX!eZX!fZX!gZX!hZX!hjX&rjX&sjX(zZX(|ZX(}ZX)YZX)YjX)ZZX)[ZX)[jX)]ZX)]jX)^ZX)`ZX)`jX)pZX~OQZXQjX!dZX!djX~P,,ZO]jXejXsjXtjXujXvjXwjXxjXyjXzjX!OjX!VjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX)YjX)[jX)]jX~P#1xO]ZX]jXejXmhXqZXqjXsjXtjXujXvjXwjXxjXyjXzjX!OjX!VZX!VjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX)YjX)[jX)]jX~O)_jX~P,1]O[ZX[jXejX!OjX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX(wjX)pjX~P,,ZO]ZX]jXmhXqZXqjXsjXtjXujXvjXwjXxjXyjXzjX!OjX!TjX!VZX!rjX!sjX!tjX!ujX!vjX!xjX!{jX%vjX&rjX&sjX(wjX({jX)YjX)[jX)]jX)_jX)pjX~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O~PBXOe$TO%Y*YO)O:vO~Oe$TO%Y*YO)O:wO~Oe$TO%Y*YO)O:}O~Oe$TO%Y*YO)O:|O~O]%jOe!POm%dOs!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O!V%mO!{!dO!|%TO%v$oO(w$zO)Y;hO)[;iO)];iO~O]%jOe!POm%dO!V%mO!{!dO%v$oO(w$zO)Y;hO)[;iO)];iO~Oe$TO%Y$UO)O:wO~Oe$TO%Y$UO)O:{O~Om;QO~Om;PO~O]dXmhXqjX!TdX~Oe)tO%Y*YO)O:vO~Oe)tO%Y*YO)O:wO~Oe)tO%Y*YO)O:xO~Oe)tO%Y*YO)O:yO~Oe)tO%Y*YO)O:zO~Oe)tO%Y*YO)O:|O~Oe)tO%Y*YO)O:}O~Os!^Ot!^Ou!^Ov!^Ow!^Ox!^Oy!^Oz!^O~P,9iO])SXs)SXt)SXu)SXv)SXw)SXx)SXy)SXz)SX!O)SX!r)SX!s)SX!t)SX!u)SX!v)SX!x)SX!{)SX%v)SX&r)SX&s)SX(w)SX)Y)SX)[)SX)])SX)p)SX~Om;PO!T)SX({)SX)_)SX~P,=hO]&wXmnXqoX!T&wX~Oe4rO%Y*YO)O;{O~Om;cO)Y<PO)[5hO)]5hO~P(FVOe!POm%dO!{!dO%v$oO(w$zO~O]1ZO!V1XO)Y1RO)[<QO)]<QOQ#nX!d#nX!h#nX[#nX~P,@dO)Y;aO~Om;oO~Om;pO~Om;qO~Om;sO~Om;tO~Om;uO~Om;sO!T$YOQ)SX!d)SX!h)SX)`)SX[)SX)p)SX~P$G`Om;qO!T$YO~P$G`Om;oO!g$[O)p$[O~Om;qO!g$[O)p$[O~Om;sO!g$[O)p$[O~Om;pO[)SX!h)SX)`)SX)p)SX~P$G`Oe/eO%Y*YO)O;{O~Om;|O~O)Y<aO~OV'e'h'i'g(u)b!R(wS(p%Z!Y!['je%[!i'R!f]'f*a'k(|!^!_'l'm'l~",
4034 goto: "%7u*aPPPPP*b*lP*oPP.ePP4y7z7z;UP;U>`P>y?]?qFiMi!&m!-TP!3}!4r!5gP!6RPPPPPPPP!6lP!8UP!9g!;PP!;VPPPPPP!;YP!;YPP!;YPP!;fPPPPPP!=h!AOP!ARPP!Ao!BdPPPPP!BhP>|!CyPP>|!FQ!HR!Ha!Iv!KgP!KrP!LR!LR# c#$r#&Y#)f#,p!HR#,zPP!HR#-R#-X#,z#,z#-[P#-`#-}#-}#-}#-}!KgP#.h#.y#1`P#1tP#3aP#3e#3m#4b#4m#6{#7T#7T#3eP#3eP#7[#7bP#7lPP#8X#8v#9h#8XP#:Y#:fP#8XP#8XPP#8X#8XP#8XP#8XP#8XP#8XP#8XP#8XP#:i#7l#;VP#;lP#<R#<R#<R#<R#<`#3eP#<v#Ar#BaPPPPPPPP#CXP#CgP#CgP#Cs#GQ#;bPP#Ca#GdP#Gw#HS#HY#HY#Ca#IOP#3e#3e#3e#3e#3eP!LR#Ij#Iq#Iq#Iq#Iu# ]#JP# ]#JT!Ha!Ha!Ha#JW#Np!Ha>|>|>|$%i!Bd!Bd!Bd!Bd!Bd!Bd!6l!6l!6l$%|P$'i$'w!6l$'}PP!6l$*]$*`#CO$*c;U7z$-i$/d$1T$2s7zPP7z$4g7zP7z7zP7zP$7m7zP7zPP7z$7yPPPPPPPPP*lP$;R$;X$;_$=v$?|$@S$@j$@t$AP$A`$Af$Bt$Cs$Cz$DR$DX$Da$Dk$Dq$D|$ES$E]$Ee$Ep$Ev$FQ$FW$Fb$Fi$Fx$GO$GUP$G[$Gd$Gk$Gy$Ig$Im$Is$Iz$JTPPPPPPPPPPPP$JZ$J_PPPPP%#a$*]%#d%&l%(tPP%)R%)UPPPPPPPPPP%)b%*e%*k%*o%,f%-s%.f%.m%0|%1SPPP%1^%1i%1l%1r%2y%2|%3W%3b%3f%4j%5]%5c#CXP%5|%6^%6a%6q%6}%7R%7X%7_$*]$*`$*`%7b%7eP%7o%7rQ#dPZ(s#b(o(p(t/ZR#dP'`mO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mU%qm%r7XQ&o!`Q(o#^d0W*S0T0U0V0Y5U5V5W5Z8XR7X3[b}Oaewx{!g&U*v&v$k[!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|1S1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mS%bf0o#d%lgnp|#O$i%O%P%U%f%j%k%y&u'v'w(S*_*e*g*y+b,q,{-d-u-|.k.r.t0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<aS%sm!YS&w!h#PQ'_!tQ'i!yQ'j!zQ(o#aQ(p#^Q(q#_Q*}%mQ,]&nQ,b&pQ-X'`Q-i'hQ-p'sS.w(]4`Q/m)lQ0l*rQ2X,aQ2`,hQ3V-jQ4i/RQ4m/[Q5m1UQ6c2[Q7U3WQ8h6bQ9l8RR;b1X$|#iS!]${%S%V%]&l&m'S'Z']'c'e(c(g(j(|(})W)X)Y)Z)[)])^)_)`)a)b)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:pQ&r!dQ(i#ZQ(x#cQ)o$V[*x%g*]0r2g2n3SQ,c&qQ/T(hQ/Z(pQ/b(yS/p)n/UQ0y+VS4x/q/rR8V4y'a![O[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m'a!VO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mQ)T#mS+V%{0zQ/y)xk4U.l3z4O4R4S7j7l7m7o7r9`9a:YQ)V#mk4T.l3z4O4R4S7j7l7m7o7r9`9a:Yl)U#m.l3z4O4R4S7j7l7m7o7r9`9a:YT+V%{0z[UOwx!g&U*vW$b[e$g(d#l$r_!f!u!}#R#S#T#U#V#Z$U$V$n%W&W&[&e&o'a(P(R(W(`(i)o)u+a+f+g+y,O,^,p-P-V-t-y.].^.d.e.i.v.z1[1`1m1r1t2s3c3d3e3w3{5q6U6W7c8b![%eg$i%f%k&u*_*y+b,q,{-d1R1V2f;_;`;a;h;i;v;w;x;y;}<O<Q<_<`<aY%unp%y-u.kl)R#m.l3z4O4R4S7j7l7m7o7r9`9a:YS;l'v-|U;m(S.r.t&|<Saf{|!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$h$m%O%P%U%_%j%o&S&Y&d&{'O'Q'k'l'w'{(b(k)q)w*e*g*m*n*q*w+]+_+m+o+p,U,W,s,v-l.U.V.Z/S/V/c/j/s/u/z/|0d0o1Q1S1X1h1i1s1w2R2j2p2q2|4V4Y4_4h5a5h5l5x6f6j6m6n6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m;g<PQ<T1Zd<U&z'R'd,|-b-c-f2m3R3UW<V&h*{2T3pQ<W#O[<X!t'`'h,a2[6bT<d%{0z[VOwx!g&U*vW$c[e$g(dQ$r.z!j$s_!f!u!}#V#Z$U$V$n%W&W&[&e&o'a(i)o)u+a+f+y,^,p-P-V-t.i1[1`1m1r1t2s3{5q8b&^$|af{!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$h$m%_%o&S&Y&d&{'O'Q'k'l'{(b(k)q)w*m*n*q*w+]+_+m+o+p,U,W,s,v-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2j2p2|4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m![%eg$i%f%k&u*_*y+b,q,{-d1R1V2f;_;`;a;h;i;v;w;x;y;}<O<Q<_<`<aY%unp%y-u.kQ't#O|(O#R#S#T#U(P(R(W(`+g,O.].^.d.e.v3c3d3e3w6U6W7cl)R#m.l3z4O4R4S7j7l7m7o7r9`9a:YS-s'v-|Q3_-yU;z(S.r.tn<S|%O%P%U%j'w*e*g0d1Q2q5h6n;g<P[<X!t'`'h,a2[6bW<Y&h*{2T3pd<Z&z'R'd,|-b-c-f2m3R3UQ<b1ZT<d%{0z!Q!UO[ewx!g$g&U&h&z'R'd(d*v*{,|-b-c-f2T2m3R3U3p!v$v_!f!u!}#O#V#Z$U$V$n%W&W&[&e&o'a'v(S(i)o)u+a+y,^,p-P-V-t-|.i.r.t1Z1[1`1m1r1t2s3{5q8b&^%Raf{!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$h$m%_%o&S&Y&d&{'O'Q'k'l'{(b(k)q)w*m*n*q*w+]+_+m+o+p,U,W,s,v-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2j2p2|4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m$Q%ngnp|#m$i%O%P%U%f%j%k%y%{&u'`'h'w*_*e*g*y+b,a,q,{-d-u.k.l0d0z1Q1R1V2[2f2q3z4O4R4S5h6b6n7j7l7m7o7r9`9a:Y;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<aQ'^!tz(Q#R#S#T#U(P(R(W(`,O.].^.d.e.v3c3d3e3w6U6W7cf-`'b-Y-[-_2w2x2z2}6x6y8wQ1_+fQ1b+gQ2r-OQ3`-yQ4c.zQ5s1aR8^5t!Q!UO[ewx!g$g&U&h&z'R'd(d*v*{,|-b-c-f2T2m3R3U3p!x$v_!f!u!}#O#V#Z$U$V$n%W&W&[&e&o'a'v(S(i)o)u+a+f+y,^,p-P-V-t-|.i.r.t1Z1[1`1m1r1t2s3{5q8b&^%Raf{!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$h$m%_%o&S&Y&d&{'O'Q'k'l'{(b(k)q)w*m*n*q*w+]+_+m+o+p,U,W,s,v-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2j2p2|4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m$S%ngnp|!t#m$i%O%P%U%f%j%k%y%{&u'`'h'w*_*e*g*y+b,a,q,{-d-u.k.l0d0z1Q1R1V2[2f2q3z4O4R4S5h6b6n7j7l7m7o7r9`9a:Y;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<a|(Q#R#S#T#U(P(R(W(`+g,O.].^.d.e.v3c3d3e3w6U6W7cQ3`-yR4c.z[WOwx!g&U*vW$d[e$g(d#l$r_!f!u!}#R#S#T#U#V#Z$U$V$n%W&W&[&e&o'a(P(R(W(`(i)o)u+a+f+g+y,O,^,p-P-V-t-y.].^.d.e.i.v.z1[1`1m1r1t2s3c3d3e3w3{5q6U6W7c8b![%eg$i%f%k&u*_*y+b,q,{-d1R1V2f;_;`;a;h;i;v;w;x;y;}<O<Q<_<`<aY%unp%y-u.kl)R#m.l3z4O4R4S7j7l7m7o7r9`9a:YS;l'v-|U;m(S.r.tn<S|%O%P%U%j'w*e*g0d1Q2q5h6n;g<PQ<T1ZQ<W#O[<X!t'`'h,a2[6b&^<[af{!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$h$m%_%o&S&Y&d&{'O'Q'k'l'{(b(k)q)w*m*n*q*w+]+_+m+o+p,U,W,s,v-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2j2p2|4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:md<]&z'R'd,|-b-c-f2m3R3UW<^&h*{2T3pT<d%{0zp$RT$a$q%d%t)Q;R;S;T;c;d;e;f;j;k<co)r$X*Z*a/f;O;P;Q;o;p;q;r;s;t;u;|p$ST$a$q%d%t)Q;R;S;T;c;d;e;f;j;k<co)s$X*Z*a/f;O;P;Q;o;p;q;r;s;t;u;|^&g}!O$k$l%b%l;bd&k!U$v%R%n'^(Q1_1b3`4cV/h)T)U4US%[e$gQ,Y&hQ/Q(dQ2t-VQ6Q1tQ6^2TQ6t2sR9o8b#}!TO[_ewx!f!g!u!}#O#V#Z$U$V$g$n%W&U&W&[&e&h&o&z'R'a'd'v(S(d(i)o)u*v*{+a+f+y,^,p,|-P-V-b-c-f-t-y-|.i.r.t1Z1[1`1m1r1t2T2m2s3R3U3p3{5q8b#[^O[_`wx!f!g!}#O$U$f$n$u$w&U&W&[&e&o&t&z'R'd'v(S)u*b*v*{+a,^,p,|-P-b-c-f-t-y-|.i.r.t1Z1[1m2m3R3U3p3{_(W#R#S#T+g3c3d3e#}ZO[wx!g!k#R#S#T%o&U&W&[&e&o&y&z&{'O'Q'R'^'d'v'z(P(R(S(W*v*{+a+g,^,m,p,v-U-b-c-f-t-y-|.P.d.i.r.v1Z1[1m2j2r3R3U3c3d3e3p6j6q8n9s9w:_:d:mQ$_YR0[*TR*V$_e0W*S0T0U0V0Y5U5V5W5Z8X$f#{S%V%]'S'Z']'c'e(j(|(})W)Z)[)])^)_)`)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:pe0W*S0T0U0V0Y5U5V5W5Z8X'`!YO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:me0W*S0T0U0V0Y5U5V5W5Z8XR5[0[^(V#R#S#T+g3c3d3eY.b(P(T(W(X7[U3r.`.c.vS7`3s4^R9j7z^(U#R#S#T+g3c3d3e[.a(P(T(V(W(X7[W3q.`.b.c.vU7_3r3s4^S9R7`7zR:^9jT.p(S.rd]Owx!g&U'v(S*v-|.r!v^[_`!f!}#O$U$f$n$u$w&W&[&e&o&t&z'R'd)u*b*{+a,^,p,|-P-b-c-f-t-y.i.t1Z1[1m2m3R3U3p3{Q%vnT1|,S1}!jbOaenpwx{|!g#O%O%P%U%j%y&U'v'w(S*e*g*v-u-|.k.r.t0d1Q1Z2q5h6n;g<Pf-]'b-Y-[-_2w2x2z2}6x6y8wj4P.l3z4O4R4S7j7l7m7o7r9`9a:Yr<Rg$i%f%k&u*_*y,q,{-d2f;_;`;a;v;x;}i<e+b1R1V;h;i;w;y<O<Q<_<`<a!O&`y%Z&X&[&]'m)m*i*k+b+j+}/t0e1Q1R1V1Z1q5h5}<P<Qz&cz%Q%Y%g&f'u*]*d,g-}0b0c0r1T2g2n3S5^5i6s8pS'}#Q.^n+q&Z*l+k+r+u-o/o0f1Y1e4{5_5g5|8`Q2_,f^2{-^2y3P6w7O8v9ze7p4Q7f7n7v7w9]9_9g:X:jS+c&W1[Y+s&[&e*{1Z3pR5z1m#w!POaegnpwx{|!g#O$i%O%P%U%f%j%k%y&U&u'v'w(S*_*e*g*v*y+b,q,{-d-u-|.k.r.t0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<a`oOwx!g&U'v*v-|#U!Paeg{|#O$i%O%P%U%f%j%k&u'w*_*e*g*y+b,q,{-d0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<aU%xnp-uQ+S%yS.j(S.rT3}.k.tW+w&`+q+x1jV,P&c,Q7pQ+}&bU,P&c,Q7pQ-|'vT.X'{.Z'`![O[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mX1y,O.^6U6W'W!VO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/c/j/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mW1y,O.^6U6WR2l,x!WjO[wx!g!k%o&U&{'O'Q'd*v,v-b-c-f2j3R6j6q8n9s9w:_:d:mY%Xe$g(d1w3pQ'U!nS)O#k5aQ,r&zQ,}'RS.T'{.ZQ2i,sQ6r2pQ7T3UQ8o6mR9t8l'W![O[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/c/j/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mX1y,O.^6U6W'ayO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,O,U,W,s,v,|-b-c-f-l.U.V.Z.^/S/c/j/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6U6W6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mQ&byS'v#O-zR1c+hS+c&W1[R5u1cQ1W+bR5n1VR1W+bT+c&W1[z&^%Z&X&[&]'m)m*i*k+b+j/t0e1Q1R1V1Z1q5h5}<P<QQ&_yR1u+}!P&^y%Z&X&[&]'m)m*i*k+b+j+}/t0e1Q1R1V1Z1q5h5}<P<QQ+z&`S,R&c7pS1k+q+xQ1{,QR5y1j!WkO[wx!g!k%o&U&{'O'Q'd*v,v-b-c-f2j3R6j6q8n9s9w:_:d:mS%|o.jS&Qq-wQ&ayQ&s!eQ'g!yQ*u%gU+Q%x%}3}S+U%z&PQ+v&_Q,_&oS,`&p'iQ,w&}S0`*],gS0v+R+SQ0x+TQ1v+}S2Z,b-kQ5]0bQ5b0wQ6S1uQ6a2YQ6d2_Q7u4QQ9Z7fR:W9][uOwx!g&U*vQ,_&oQ-{'vQ3a-yR3f-|xlOwx!g!k%o&U&{'Q*v,v2j6j6q8n9s9w:_:d:mU$j['O-cS%|o.jS&Qq-wQ*u%gU+Q%x%}3}S+U%z&PS0`*],gS0v+R+SQ0x+TQ5]0bQ5b0wQ7u4QQ9Z7fR:W9]T,d&s,e]uOwx!g&U*v[uOwx!g&U*vQ,_&oQ,s&zQ,|'RW-e'd-b-f3RQ-{'vQ3a-yQ3f-|R7S3U[%hg$i,q,{-d2fR0s*y^$ZV!U$c$|%R<Y<ZQ'U!nS)e$P*{S){$Y*vQ*O$[Y*x%g*]0r2n3SQ/T(hS/p)n/US0h*m4hS0q*w6fQ0y+VQ4X.lQ4u/jS4x/q/rS4}/u5aQ5S/|Q6g2gU7h3z4Q4YQ8V4yQ8r6oY9X7f7i7j7s7tQ9y8tW:R9V9Y9]9^Q:b9vU:h:S:U:VR:q:iS){$Y*vT4}/u5aZ)y$Y)z*v/u5aQ&y!hR'z#PS,l&x'xQ2c,jR6e2bxlOwx!g!k%o&U&{'Q*v,v2j6j6q8n9s9w:_:d:mV$j['O-c!XkO[wx!g!k%o&U&{'O'Q'd*v,v-b-c-f2j3R6j6q8n9s9w:_:d:m!WhO[wx!g!k%o&U&{'O'Q'd*v,v-b-c-f2j3R6j6q8n9s9w:_:d:mR'Y!q!WkO[wx!g!k%o&U&{'O'Q'd*v,v-b-c-f2j3R6j6q8n9s9w:_:d:mR,s&zQ&{!iQ&}!jQ'Q!lR,v&|R,t&zxlOwx!g!k%o&U&{'Q*v,v2j6j6q8n9s9w:_:d:mX-e'd-b-f3R[uOwx!g&U*vQ-P'RQ-{'vS.p(S.rR3f-|[uOwx!g&U*vQ-P'RW-e'd-b-f3RT.p(S.rg-`'b-Y-[-_2w2x2z2}6x6y8wylOwx!g!k%o&U&{'Q*v,v2j6j6q8n9s9w:_:d:mb!OOaewx{!g&U*v&|$l[f!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m#d%lgnp|#O$i%O%P%U%f%j%k%y&u'v'w(S*_*e*g*y+b,q,{-d-u-|.k.r.t0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<aQ'_!tQ-X'`Q-i'hQ2X,aQ6c2[R8h6bj$TT$a%d%t;R;S;T;c;d;e;f;j;ki)t$X*Z;O;P;Q;o;p;q;r;s;t;uj$TT$a%d%t;R;S;T;c;d;e;f;j;kh)t$X*Z;O;P;Q;o;p;q;r;s;t;uS/e)Q<cV4r/f/g;|[uOwx!g&U*vQ-{'vR3f-|[uOwx!g&U*vT.p(S.r'`!YO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mR7Y3[[uOwx!g&U*vQ-{'vS.p(S.rR3f-|[pOwx!g&U*vQ%ynS-u'v-|T.k(S.rS%}o.jS+R%x3}R0w+SQ+W%{R5d0zS%|o.jS&Qq-wU+Q%x%}3}S+U%z&PS0v+R+SQ0x+TQ5b0wQ7u4QQ9Z7fR:W9]`qOwx!g&U(S*v.rS%zn-uU&Pp.k.tQ+T%yT-w'v-|S'|#Q.^R._'}T.W'{.ZS.X'{.ZQ9P7]R:O9QT6U1x8fR6W1x#d!Pgnp|#O$i%O%P%U%f%j%k%y&u'v'w(S*_*e*g*y+b,q,{-d-u-|.k.r.t0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<ab!QOaewx{!g&U*v&}![[f!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m#d!Pgnp|#O$i%O%P%U%f%j%k%y&u'v'w(S*_*e*g*y+b,q,{-d-u-|.k.r.t0d1Q1R1V1Z2f2q5h6n;_;`;a;g;h;i;v;w;x;y;}<O<P<Q<_<`<ab!QOaewx{!g&U*v&|![[f!W!X!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|#}$P$W$Y$[$g$h$m%_%o&S&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_4h5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mk4T.l3z4O4R4S7j7l7m7o7r9`9a:YQ4X.lS7h3z4QU9X7f7j7sS:R9V9]R:h:U#|!TO[_ewx!f!g!u!}#O#V#Z$U$V$g$n%W&U&W&[&e&h&o&z'R'a'd'v(S(d(i)o)u*v*{+a+f+y,^,p,|-P-V-b-c-f-t-y-|.i.r.t1Z1[1`1m1r1t2T2m2s3R3U3p3{5q8bR4d.zQ(_#US.{(^(`S4e.|.}R8O4fQ.x(]R7|4`#|!TO[_ewx!f!g!u!}#O#V#Z$U$V$g$n%W&U&W&[&e&h&o&z'R'a'd'v(S(d(i)o)u*v*{+a+f+y,^,p,|-P-V-b-c-f-t-y-|.i.r.t1Z1[1`1m1r1t2T2m2s3R3U3p3{5q8bp$y`$f$u%Z&t'b(a(h)n*i-Y/r1q5r5}8]q)S#m%{.l0z3z4O4R4S7j7l7m7o7r9`9a:YR,Z&hR6_2T'X!VO[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/c/j/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:m$q#tS%V%]'S'Z']'c'e(c(g(j(|(})W)X)Z)[)])^)_)`)a)b)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:p$]#uS%V%]'S'Z']'c'e(j(|(})W)[)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:p$Z#vS%V%]'S'Z']'c'e(j(|(})W)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:p$c#yS%V%]'S'Z']'c'e(j(|(})W)Z)[)])^)c)d)p)v)}+^+l,T,X,o,z-m-n.R/O/w0g0i0n0p1O1g2Q2h2o3Y3j3k4j4k4q4t4z4|5Q5R5k5w6O6]6l6p6z7R7x7y7{8Z8[8j8m8q8y9[9c9r9x:T:[:a:g:p'X![O[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/c/j/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mQ/U(hQ/q)nQ4y/rR9k8Q']![O[aefwx{!W!X!g!k!n!r!s!v!x#X#Y#[#h#k#n#s#t#u#v#w#x#y#z#{#|$P$W$Y$[$g$h$m%_%o&S&U&Y&d&h&z&{'O'Q'R'd'k'l'{(b(d(k)q)w*m*n*q*v*w*{+]+_+m+o+p,U,W,s,v,|-b-c-f-l.U.V.Z/S/V/c/j/s/u/z/|0o1S1X1h1i1s1w2R2T2j2m2p2|3R3U3p4V4Y4_5a5l5x6f6j6m6o6q6{6}7S7i7q7t8l8n8t8z8{9Y9^9d9f9s9v9w:S:V:]:_:d:i:mQ(m#]R/W(mQ#fQR(z#fU%Oa;g<Pb%We$g&h(d-V1t2T2s8bQ'a!u!Q*c%O%W'a*e*k+m,U0d0e1i2w6x6{7l8w9`9d:Y;_;v;w;}<O<_S*e%P%UQ*k%ZS+m&Y1XQ,U&dQ0d*gQ0e*iQ1i+pQ2w-[S6x2x2zQ6{2|Q7l4OQ8w6yS9`7m7oQ9d7qQ:Y9aQ;_%fS;v;`;aS;w<`<aQ;};xQ<O;yT<_1R;h[[Owx!g&U*vl$e['O(P+a,^,m,p-U-c-t.P.d.i.vl'O!k%o&{'Q,v2j6j6q8n9s9w:_:d:m^(P#R#S#T+g3c3d3e`+a&W&[&e*{1Z1[1m3pS,^&o-yQ,m&yU,p&z'R3US-U'^2rW-c'd-b-f3RS-t'v-|Q.P'zQ.d(RS.i(S.rR.v(WQ*R$^R0P*RQ0Y*SQ5U0TQ5V0UQ5W0VY5X0Y5U5V5W8XR8X5ZQ*U$_S0]*U0^R0^*VS.e(R.dS3u.e7cR7c3wQ3x.fS7a3v3yU7e3x7a9SR9S7bQ.r(SR4Z.r!|_O[wx!f!g!}#O$U$n&U&W&[&e&o&z'R'd'v(S)u*v*{+a,^,p,|-P-b-c-f-t-y-|.i.r.t1Z1[1m2m3R3U3p3{U$t_$w*bU$w`$f&tR*b$uU%Pa;g<Pd*f%P*g2x6y7m9a;`;x;y<`Q*g%UQ2x-[Q6y2zQ7m4OQ9a7oQ;`%fQ;x;aQ;y<aT<`1R;hS,Q&c7pR1z,QS*o%]/wR0j*oQ1]+dR5p1]U+j&X1R<PR1d+jQ+x&`Q1j+qT1p+x1jQ8c6QR9p8cQwOS&Tw&UT&Ux*vQ,e&sR2^,eW)z$Y*v/u5aR/{)zU/v)v){0nR5O/v[*z%g%h*]2g2n3SR0t*zQ,i&wR2a,iQ-f'dQ3R-bT3T-f3RQ3O-^R7P3OQ-k'iQ2Y,bT3X-k2YS%rm7XR+P%rdnOwx!g&U'v(S*v-|.rR%wnQ0{+WR5e0{Q.Z'{R3m.ZQ1},SR6X1}U*s%b*};bR0m*sS1n+s0uR5{1nQ7s4QQ9V7fU9h7s9V:UR:U9]$O!SO[_ewx!f!g!u!}#O#V#Z$U$V$g$n%W&U&W&[&e&h&o&z'R'a'd'v(S(d(i)o)u*v*{+a+f+y,^,p,|-P-V-b-c-f-t-y-|.i.r.t.z1Z1[1`1m1r1t2T2m2s3R3U3p3{5q8bR&i!SQ4a.xR7}4aQ2U,ZR6`2US/k)d)eR4v/kW(t#b(o(p/ZR/_(tQ8S4mR9m8ST)f$P*{!USO[wx!g!k%o&U&{'O'Q'd,v-b-c-f2j3R6j6q8n9s9w:_:d:mj${a{$m%_+o,W1h2R5x6}8z9f:]Y%Ve$g(d1w3pY%]f$h(k)q*qQ&l!WQ&m!XQ'S!nQ'Z!rQ']!sQ'c!vQ'e!xQ(c#XQ(g#YS(j#[+_Q(|#hQ(}#kQ)W#nQ)X#sQ)Y#tQ)Z#uQ)[#vQ)]#wQ)^#xQ)_#yQ)`#zQ)a#{Q)b#|Q)c#}S)d$P*{Q)p$WQ)v$YQ)}$[Q+^&SS+l&Y1XQ,T&dQ,X&hQ,o&zQ,z'RQ-m'kQ-n'lS.R'{.ZQ/O(bS/w)w0oS0g*m4hQ0i*nQ0n*vQ0p*wQ1O+]S1g+m+pQ2Q,UQ2h,sS2o,|7SQ3Y-lQ3j.UQ3k.VQ4j/SQ4k/VQ4q/cQ4t/jQ4z/sQ4|/uQ5Q/zQ5R/|Q5k1SQ5w1iQ6O1sQ6]2TS6l2m8{Q6p2pQ6z2|Q7R3UQ7x4VQ7y4YQ7{4_Q8Z5aQ8[5lQ8j6fQ8m6mQ8q6oQ8y6{S9[7i7tQ9c7qQ9r8lQ9x8tS:T9Y9^Q:[9dQ:a9vS:g:S:VR:p:iR,[&hd]Owx!g&U'v(S*v-|.r!v^[_`!f!}#O$U$f$n$u$w&W&[&e&o&t&z'R'd)u*b*{+a,^,p,|-P-b-c-f-t-y.i.t1Z1[1m2m3R3U3p3{#r$}ae!u$g%O%P%U%W%Z%f&Y&d&h'a(d*e*g*i*k+m+p,U-V-[0d0e1X1i1t2T2s2w2x2z2|4O6x6y6{7l7m7o7q8b8w9`9a9d:Y;_;`;a;g;h;v;w;x;y;}<O<_<`<aQ%vnS+i&X+jW+w&`+q+x1jU,P&c,Q7pQ1r+yT5j1R<P``Owx!g&U'v*v-|S$f[-tQ$u_b%Ze$g&h(d-V1t2T2s8b!h&t!f!}#O$U$n&W&[&e&o&z'R'd(S)u*{+a,^,p,|-P-b-c-f-y.i.r.t1Z1[1m2m3R3U3p3{Q'b!uS(a#V+fQ(h#ZS)n$V(iQ*i%WQ-Y'aQ/r)oQ1q+yQ5r1`Q5}1rR8]5qS(Y#R3dS(Z#S3eV([#T+g3cR$`Ye0X*S0T0U0V0Y5U5V5W5Z8XW(T#R#S#T+gQ(^#US.`(P(WS.f(R.dQ.}(`W1y,O.^6U6WQ3b-yQ3o.]Q3v.eQ4^.vU7[3c3d3eQ7d3wR9T7cQ.g(RR3t.dT.q(S.rdgOwx!g&U&o'v*v-y-|U$i[,^-tQ&u!fQ'm!}Q'w#OQ)m$UQ*_$n`+b&W&[&e*{1Z1[1m3pQ,q&zQ,{'RY-d'd-b-f3R3US.l(S.rQ/t)uQ1Q+aS2f,p-cS2q,|-PS3z.i.tQ6n2mR7j3{d]Owx!g&U'v(S*v-|.r!v^[_`!f!}#O$U$f$n$u$w&W&[&e&o&t&z'R'd)u*b*{+a,^,p,|-P-b-c-f-t-y.i.t1Z1[1m2m3R3U3p3{R%vnQ4Q.lQ7f3zQ7n4OQ7v4RQ7w4SQ9]7jU9_7l7m7oQ9g7rS:X9`9aR:j:YZ+t&[&e*{1Z3ppzOnpwx!g%y&U'v(S*v-u-|.k.r.t[%Qa%f1R;g;h<PU%Ye%j1ZQ%gg^&f{|%k1V5h;i<QQ'u#OQ*]$ib*d%O%P%U;_;`;a<_<`<aQ,g&uQ-}'wQ0b*_[0c*e*g;v;w;x;yQ0r*yQ1T+bQ2g,qQ2n,{S3S-d2fU5^0d;}<OQ5i1QQ6s2qR8p6nQ,S&cR9b7pS1x,O.^Q8e6UR8f6W[%`f$h(k)q)w0oR0k*qR+e&WQ+d&WR5o1[S&Zy+}Q*l%ZU+k&X1R<PS+r&[1ZW+u&]1V5h<QQ-o'mQ/o)mS0f*i*kQ1Y+bQ1e+jQ4{/tQ5_0eQ5g1QQ5|1qR8`5}R6R1tYvOwx&U*vR&v!gW%ig,q,{-dT*^$i2fT)|$Y*v[uOwx!g&U*vQ'P!kQ+O%oQ,u&{Q,y'QQ2k,vQ6i2jQ8k6jQ8s6qQ9u8nQ:`9sQ:c9wQ:l:_Q:n:dR:r:mxlOwx!g!k%o&U&{'Q*v,v2j6j6q8n9s9w:_:d:mU$j['O-cX-e'd-b-f3RQ-a'bR2v-YS-^'b-YQ2y-[Q3P-_U6w2w2x2zQ7O2}S8v6x6yR9z8w[rOwx!g&U*vS-v'v-|T.m(S.rR+X%{[sOwx!g&U*vS-x'v-|T.n(S.r[tOwx!g&U*vT.o(S.rT.Y'{.ZX%cf%m0o1XQ.|(^R4f.}R.y(]R(f#XQ(w#bS/Y(o(pR4l/ZR/^(qR4n/[",
4035 nodeNames: "\u26A0 RawString > MacroName LineComment BlockComment PreprocDirective #include String EscapeSequence SystemLibString Identifier ) ( ArgumentList ConditionalExpression AssignmentExpression CallExpression PrimitiveType FieldExpression FieldIdentifier DestructorName TemplateMethod ScopedFieldIdentifier NamespaceIdentifier TemplateType TypeIdentifier ScopedTypeIdentifier ScopedNamespaceIdentifier :: NamespaceIdentifier TypeIdentifier TemplateArgumentList < TypeDescriptor const volatile restrict _Atomic mutable constexpr constinit consteval StructSpecifier struct MsDeclspecModifier __declspec Attribute AttributeName Identifier AttributeArgs { } [ ] UpdateOp ArithOp ArithOp ArithOp LogicOp BitOp BitOp BitOp CompareOp CompareOp CompareOp > CompareOp BitOp UpdateOp , Number CharLiteral AttributeArgs VirtualSpecifier BaseClassClause Access virtual FieldDeclarationList FieldDeclaration extern static register inline thread_local AttributeSpecifier __attribute__ PointerDeclarator MsBasedModifier __based MsPointerModifier FunctionDeclarator ParameterList ParameterDeclaration PointerDeclarator FunctionDeclarator Noexcept noexcept RequiresClause requires True False ParenthesizedExpression CommaExpression LambdaExpression LambdaCaptureSpecifier TemplateParameterList OptionalParameterDeclaration TypeParameterDeclaration typename class VariadicParameterDeclaration VariadicDeclarator ReferenceDeclarator OptionalTypeParameterDeclaration VariadicTypeParameterDeclaration TemplateTemplateParameterDeclaration template AbstractFunctionDeclarator AbstractPointerDeclarator AbstractArrayDeclarator AbstractParenthesizedDeclarator AbstractReferenceDeclarator ThrowSpecifier throw TrailingReturnType CompoundStatement FunctionDefinition MsCallModifier TryStatement try CatchClause catch LinkageSpecification Declaration InitDeclarator InitializerList InitializerPair SubscriptDesignator FieldDesignator ExportDeclaration export ImportDeclaration import ModuleName PartitionName HeaderName CaseStatement case default LabeledStatement StatementIdentifier ExpressionStatement IfStatement if ConditionClause Declaration else SwitchStatement switch DoStatement do while WhileStatement ForStatement for ReturnStatement return BreakStatement break ContinueStatement continue GotoStatement goto CoReturnStatement co_return CoYieldStatement co_yield AttributeStatement ForRangeLoop AliasDeclaration using TypeDefinition typedef PointerDeclarator FunctionDeclarator ArrayDeclarator ParenthesizedDeclarator ThrowStatement NamespaceDefinition namespace ScopedIdentifier Identifier OperatorName operator ArithOp BitOp CompareOp LogicOp new delete co_await ConceptDefinition concept UsingDeclaration enum StaticAssertDeclaration static_assert ConcatenatedString TemplateDeclaration FriendDeclaration friend union FunctionDefinition ExplicitFunctionSpecifier explicit FieldInitializerList FieldInitializer DefaultMethodClause DeleteMethodClause FunctionDefinition OperatorCast operator TemplateInstantiation FunctionDefinition FunctionDefinition Declaration ModuleDeclaration module RequiresExpression RequirementList SimpleRequirement TypeRequirement CompoundRequirement ReturnTypeRequirement ConstraintConjuction LogicOp ConstraintDisjunction LogicOp ArrayDeclarator ParenthesizedDeclarator ReferenceDeclarator TemplateFunction OperatorName StructuredBindingDeclarator ArrayDeclarator ParenthesizedDeclarator ReferenceDeclarator BitfieldClause FunctionDefinition FunctionDefinition Declaration FunctionDefinition Declaration AccessSpecifier UnionSpecifier ClassSpecifier EnumSpecifier SizedTypeSpecifier TypeSize EnumeratorList Enumerator DependentType Decltype decltype auto PlaceholderTypeSpecifier ParameterPackExpansion ParameterPackExpansion FieldIdentifier PointerExpression SubscriptExpression BinaryExpression ArithOp LogicOp LogicOp BitOp UnaryExpression LogicOp BitOp UpdateExpression CastExpression SizeofExpression sizeof CoAwaitExpression CompoundLiteralExpression NULL NewExpression new NewDeclarator DeleteExpression delete ParameterPackExpansion nullptr this UserDefinedLiteral ParamPack #define PreprocArg #if #ifdef #ifndef #else #endif #elif PreprocDirectiveName Macro Program",
4036 maxTerm: 431,
4037 nodeProps: [
4038 ["group", -35, 1, 8, 11, 15, 16, 17, 19, 71, 72, 100, 101, 102, 104, 191, 208, 229, 242, 243, 270, 271, 272, 277, 280, 281, 282, 284, 285, 286, 287, 290, 292, 293, 294, 295, 296, "Expression", -13, 18, 25, 26, 27, 43, 255, 256, 257, 258, 262, 263, 265, 266, "Type", -19, 126, 129, 147, 150, 152, 153, 158, 160, 163, 164, 166, 168, 170, 172, 174, 176, 178, 179, 188, "Statement"],
4039 ["isolate", -3, 4, 8, 10, ""],
4040 ["openedBy", 12, "(", 52, "{", 54, "["],
4041 ["closedBy", 13, ")", 51, "}", 53, "]"]
4042 ],
4043 propSources: [cppHighlighting],
4044 skippedNodes: [0, 3, 4, 5, 6, 7, 10, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 308, 348, 349],
4045 repeatNodeCount: 42,
4046 tokenData: "%LSMfR!UOX$eXY({YZ.gZ]$e]^+P^p$epq({qr.}rs0}st2ktu$euv!7dvw!9bwx!;exy!<Yyz!=Tz{!>O{|!?R|}!AV}!O!BQ!O!P!DX!P!Q#+y!Q!R#5[!R![#JY![!]$4w!]!^$6s!^!_$7n!_!`%$h!`!a%%i!a!b%(o!b!c$e!c!n%)j!n!o%+R!o!w%)j!w!x%+R!x!}%)j!}#O%.O#O#P%/w#P#Q%?[#Q#R%AT#R#S%)j#S#T$e#T#i%)j#i#j%BW#j#o%)j#o#p%Cu#p#q%Dp#q#r%Fv#r#s%Gq#s;'S$e;'S;=`(u<%lO$e,j$nY)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e,f%eW)c`'f,UOY%^Zw%^wx%}x#O%^#O#P&f#P;'S%^;'S;=`'x<%lO%^,U&SU'f,UOY%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},U&kX'f,UOY%}YZ%}Z]%}]^'W^#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},U']V'f,UOY%}YZ%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},U'uP;=`<%l%},f'{P;=`<%l%^,Y(VW(vS'f,UOY(OZr(Ors%}s#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(O,Y(rP;=`<%l(O,j(xP;=`<%l$eMf)Y`)c`(vS(o<`'f,U*a1pOX$eXY({YZ*[Z]$e]^+P^p$epq({qr$ers%^sw$ewx(Ox#O$e#O#P,^#P;'S$e;'S;=`(u<%lO$e<`*aT(o<`XY*[YZ*[]^*[pq*[#O#P*p<`*sQYZ*[]^*y<`*|PYZ*[Gz+[`)c`(vS(o<`'f,UOX$eXY+PYZ*[Z]$e]^+P^p$epq+Pqr$ers%^sw$ewx(Ox#O$e#O#P,^#P;'S$e;'S;=`(u<%lO$eGf,cX'f,UOY%}YZ-OZ]%}]^-{^#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}Gf-V[(o<`'f,UOX%}XY-OYZ*[Z]%}]^-O^p%}pq-Oq#O%}#O#P,^#P;'S%};'S;=`'r<%lO%}Gf.QV'f,UOY%}YZ-OZ#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}MQ.nT*^1p(o<`XY*[YZ*[]^*[pq*[#O#P*pF`/[[%^#t'QQ)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`0Q!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`0_Y%]#t!a8O)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eKz1YY)c`(tS(u=j'f,UOY%^Zr%^rs1xsw%^wx%}x#O%^#O#P&f#P;'S%^;'S;=`'x<%lO%^/[2RW*O#t)c`'f,UOY%^Zw%^wx%}x#O%^#O#P&f#P;'S%^;'S;=`'x<%lO%^Gz2tf)c`(vS'f,UOX$eXY2kZp$epq2kqr$ers%^sw$ewx(Ox!c$e!c!}4Y!}#O$e#O#P&f#P#T$e#T#W4Y#W#X5m#X#Y>u#Y#]4Y#]#^NZ#^#o4Y#o;'S$e;'S;=`(u<%lO$eGz4eb)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGz5xd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#Y7W#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGz7cd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#Z8q#Z#o4Y#o;'S$e;'S;=`(u<%lO$eGz8|d)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#]4Y#]#^:[#^#o4Y#o;'S$e;'S;=`(u<%lO$eGz:gd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#b4Y#b#c;u#c#o4Y#o;'S$e;'S;=`(u<%lO$eGz<Qd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#Y=`#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGz=mb)c`(vS'e<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGz?Qf)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#`4Y#`#a@f#a#b4Y#b#cHV#c#o4Y#o;'S$e;'S;=`(u<%lO$eGz@qf)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#]4Y#]#^BV#^#g4Y#g#hEV#h#o4Y#o;'S$e;'S;=`(u<%lO$eGzBbd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#ZCp#Z#o4Y#o;'S$e;'S;=`(u<%lO$eGzC}b)c`(vS'f,U'l<`'m<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGzEbd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#YFp#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGzF}b)c`(vS'j<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGzHbd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#W4Y#W#XIp#X#o4Y#o;'S$e;'S;=`(u<%lO$eGzI{d)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#]4Y#]#^KZ#^#o4Y#o;'S$e;'S;=`(u<%lO$eGzKfd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#ZLt#Z#o4Y#o;'S$e;'S;=`(u<%lO$eGzMRb)c`(vS'f,U'k<`'m<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGzNff)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#Z! z#Z#b4Y#b#c!.[#c#o4Y#o;'S$e;'S;=`(u<%lO$eGz!!Xf)c`(vS'g<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#W4Y#W#X!#m#X#b4Y#b#c!(W#c#o4Y#o;'S$e;'S;=`(u<%lO$eGz!#xd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#Y!%W#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGz!%cd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#Z!&q#Z#o4Y#o;'S$e;'S;=`(u<%lO$eGz!'Ob)c`(vS'h<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGz!(cd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#W4Y#W#X!)q#X#o4Y#o;'S$e;'S;=`(u<%lO$eGz!)|d)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#Y!+[#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGz!+gd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#Y4Y#Y#Z!,u#Z#o4Y#o;'S$e;'S;=`(u<%lO$eGz!-Sb)c`(vS'i<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eGz!.gd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#V4Y#V#W!/u#W#o4Y#o;'S$e;'S;=`(u<%lO$eGz!0Qd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#`4Y#`#a!1`#a#o4Y#o;'S$e;'S;=`(u<%lO$eGz!1kd)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#i4Y#i#j!2y#j#o4Y#o;'S$e;'S;=`(u<%lO$eGz!3Ud)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#W4Y#W#X!4d#X#o4Y#o;'S$e;'S;=`(u<%lO$eGz!4od)c`(vS'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#X4Y#X#Y!5}#Y#o4Y#o;'S$e;'S;=`(u<%lO$eGz!6[b)c`(vSV<`'f,U'm<`OY$eZr$ers%^sw$ewx(Ox!Q$e!Q![4Y![!c$e!c!}4Y!}#O$e#O#P&f#P#R$e#R#S4Y#S#T$e#T#o4Y#o;'S$e;'S;=`(u<%lO$eF`!7q[)c`(vS%Z#t![8O'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!8rY!g:t)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!9o])]8O)c`(vS%[#t'f,UOY$eZr$ers%^sv$evw!:hwx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!:uY)[8O%^#t)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCb!;pW)aW(vS)b8O'f,UOY(OZr(Ors%}s#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(OLS!<eY)c`(vS]Kn'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e-^!=`Y[r)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!>][)Y8O)c`(vS%Z#t'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!?`^)c`(vS%Z#t!Y8O'f,UOY$eZr$ers%^sw$ewx(Ox{$e{|!@[|!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!@gY)c`!X:t(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCr!AbY!h8W)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!B__)c`(vS%Z#t!Y8O'f,UOY$eZr$ers%^sw$ewx(Ox}$e}!O!@[!O!_$e!_!`!8g!`!a!C^!a#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`!CiY(}:t)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCr!Dd^)c`(vS'f,U(|8OOY$eZr$ers%^sw$ewx(Ox!O$e!O!P!E`!P!Q$e!Q![!GY![#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCr!Ei[)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!O$e!O!P!F_!P#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCr!FjY)`8W)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCj!Gen)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx!Icx!Q$e!Q![!GY![!g$e!g!h#$w!h!i#*Y!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#X$e#X#Y#$w#Y#Z#*Y#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCY!IjY(vS'f,UOY(OZr(Ors%}s!Q(O!Q![!JY![#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(OCY!Jcn(vS!i8O'f,UOY(OZr(Ors%}sw(Owx!Icx!Q(O!Q![!JY![!g(O!g!h!La!h!i##`!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#X(O#X#Y!La#Y#Z##`#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY!Ljl(vS!i8O'f,UOY(OZr(Ors%}s{(O{|!Nb|}(O}!O!Nb!O!Q(O!Q![# e![!c(O!c!h# e!h!i# e!i!n(O!n!o##`!o!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#Y# e#Y#Z# e#Z#`(O#`#a##`#a#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY!Ni^(vS'f,UOY(OZr(Ors%}s!Q(O!Q![# e![!c(O!c!i# e!i#O(O#O#P&f#P#T(O#T#Z# e#Z;'S(O;'S;=`(o<%lO(OCY# nj(vS!i8O'f,UOY(OZr(Ors%}sw(Owx!Nbx!Q(O!Q![# e![!c(O!c!h# e!h!i# e!i!n(O!n!o##`!o!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#Y# e#Y#Z# e#Z#`(O#`#a##`#a#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY##id(vS!i8O'f,UOY(OZr(Ors%}s!h(O!h!i##`!i!n(O!n!o##`!o!w(O!w!x##`!x#O(O#O#P&f#P#Y(O#Y#Z##`#Z#`(O#`#a##`#a#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCj#%Sn)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx(Ox{$e{|#'Q|}$e}!O#'Q!O!Q$e!Q![#(]![!c$e!c!h#(]!h!i#(]!i!n$e!n!o#*Y!o!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#Y#(]#Y#Z#(]#Z#`$e#`#a#*Y#a#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#'Z`)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![#(]![!c$e!c!i#(]!i#O$e#O#P&f#P#T$e#T#Z#(]#Z;'S$e;'S;=`(u<%lO$eCj#(hj)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx!Nbx!Q$e!Q![#(]![!c$e!c!h#(]!h!i#(]!i!n$e!n!o#*Y!o!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#Y#(]#Y#Z#(]#Z#`$e#`#a#*Y#a#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#*ef)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx(Ox!h$e!h!i#*Y!i!n$e!n!o#*Y!o!w$e!w!x#*Y!x#O$e#O#P&f#P#Y$e#Y#Z#*Y#Z#`$e#`#a#*Y#a#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eMf#,W`)c`(vS%Z#t![8O'f,UOY$eZr$ers%^sw$ewx(Oxz$ez{#-Y{!P$e!P!Q#.T!Q!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eMf#-eY)c`(vS(pAz'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eMf#.`Y)c`(vSSAz'f,UOY#.TZr#.Trs#/Osw#.Twx#4]x#O#.T#O#P#0[#P;'S#.T;'S;=`#5U<%lO#.TMb#/XW)c`SAz'f,UOY#/OZw#/Owx#/qx#O#/O#O#P#0[#P;'S#/O;'S;=`#4V<%lO#/OMQ#/xUSAz'f,UOY#/qZ#O#/q#O#P#0[#P;'S#/q;'S;=`#1l<%lO#/qMQ#0cXSAz'f,UOY#/qYZ%}Z]#/q]^#1O^#O#/q#O#P#1r#P;'S#/q;'S;=`#1l<%lO#/qMQ#1VVSAz'f,UOY#/qYZ%}Z#O#/q#O#P#0[#P;'S#/q;'S;=`#1l<%lO#/qMQ#1oP;=`<%l#/qMQ#1y]SAz'f,UOY#/qYZ%}Z]#/q]^#1O^#O#/q#O#P#1r#P#b#/q#b#c#/q#c#f#/q#f#g#2r#g;'S#/q;'S;=`#1l<%lO#/qMQ#2yUSAz'f,UOY#/qZ#O#/q#O#P#3]#P;'S#/q;'S;=`#1l<%lO#/qMQ#3dZSAz'f,UOY#/qYZ%}Z]#/q]^#1O^#O#/q#O#P#1r#P#b#/q#b#c#/q#c;'S#/q;'S;=`#1l<%lO#/qMb#4YP;=`<%l#/OMU#4fW(vSSAz'f,UOY#4]Zr#4]rs#/qs#O#4]#O#P#0[#P;'S#4];'S;=`#5O<%lO#4]MU#5RP;=`<%l#4]Mf#5XP;=`<%l#.TCj#5gt)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx#7wx!O$e!O!P#B}!P!Q$e!Q![#JY![!g$e!g!h#$w!h!i#*Y!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#U$e#U#V#Li#V#X$e#X#Y#$w#Y#Z#*Y#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j#l$e#l#m$0p#m;'S$e;'S;=`(u<%lO$eCY#8OY(vS'f,UOY(OZr(Ors%}s!Q(O!Q![#8n![#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(OCY#8wp(vS!i8O'f,UOY(OZr(Ors%}sw(Owx#7wx!O(O!O!P#:{!P!Q(O!Q![#8n![!g(O!g!h!La!h!i##`!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#X(O#X#Y!La#Y#Z##`#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY#;Un(vS!i8O'f,UOY(OZr(Ors%}s!Q(O!Q![#=S![!c(O!c!g#=S!g!h#@d!h!i#=S!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#X#=S#X#Y#@d#Y#Z#=S#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY#=]p(vS!i8O'f,UOY(OZr(Ors%}sw(Owx#?ax!Q(O!Q![#=S![!c(O!c!g#=S!g!h#@d!h!i#=S!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#X#=S#X#Y#@d#Y#Z#=S#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY#?h^(vS'f,UOY(OZr(Ors%}s!Q(O!Q![#=S![!c(O!c!i#=S!i#O(O#O#P&f#P#T(O#T#Z#=S#Z;'S(O;'S;=`(o<%lO(OCY#@mt(vS!i8O'f,UOY(OZr(Ors%}sw(Owx#?ax{(O{|!Nb|}(O}!O!Nb!O!Q(O!Q![#=S![!c(O!c!g#=S!g!h#@d!h!i#=S!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#X#=S#X#Y#@d#Y#Z#=S#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCj#CYp)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![#E^![!c$e!c!g#E^!g!h#Gm!h!i#E^!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#X#E^#X#Y#Gm#Y#Z#E^#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#Eip)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx#?ax!Q$e!Q![#E^![!c$e!c!g#E^!g!h#Gm!h!i#E^!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#X#E^#X#Y#Gm#Y#Z#E^#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#Gxt)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx#?ax{$e{|#'Q|}$e}!O#'Q!O!Q$e!Q![#E^![!c$e!c!g#E^!g!h#Gm!h!i#E^!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#X#E^#X#Y#Gm#Y#Z#E^#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#Jep)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx#7wx!O$e!O!P#B}!P!Q$e!Q![#JY![!g$e!g!h#$w!h!i#*Y!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#X$e#X#Y#$w#Y#Z#*Y#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj#Lr_)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!O$e!O!P#Mq!P!Q$e!Q!R#Np!R![#JY![#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCj#Mz[)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![!GY![#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCj#N{t)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx#7wx!O$e!O!P#B}!P!Q$e!Q![#JY![!g$e!g!h#$w!h!i#*Y!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#U$e#U#V$#]#V#X$e#X#Y#$w#Y#Z#*Y#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j#l$e#l#m$$[#m;'S$e;'S;=`(u<%lO$eCj$#f[)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![#JY![#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCj$$e`)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![$%g![!c$e!c!i$%g!i#O$e#O#P&f#P#T$e#T#Z$%g#Z;'S$e;'S;=`(u<%lO$eCj$%rr)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx$'|x!O$e!O!P#B}!P!Q$e!Q![$%g![!c$e!c!g$%g!g!h$.Q!h!i$%g!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#X$%g#X#Y$.Q#Y#Z$%g#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCY$(T^(vS'f,UOY(OZr(Ors%}s!Q(O!Q![$)P![!c(O!c!i$)P!i#O(O#O#P&f#P#T(O#T#Z$)P#Z;'S(O;'S;=`(o<%lO(OCY$)Yr(vS!i8O'f,UOY(OZr(Ors%}sw(Owx$'|x!O(O!O!P#:{!P!Q(O!Q![$)P![!c(O!c!g$)P!g!h$+d!h!i$)P!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#X$)P#X#Y$+d#Y#Z$)P#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCY$+mu(vS!i8O'f,UOY(OZr(Ors%}sw(Owx$'|x{(O{|!Nb|}(O}!O!Nb!O!P#:{!P!Q(O!Q![$)P![!c(O!c!g$)P!g!h$+d!h!i$)P!i!n(O!n!o##`!o!r(O!r!s!La!s!w(O!w!x##`!x#O(O#O#P&f#P#T(O#T#X$)P#X#Y$+d#Y#Z$)P#Z#`(O#`#a##`#a#d(O#d#e!La#e#i(O#i#j##`#j;'S(O;'S;=`(o<%lO(OCj$.]u)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx$'|x{$e{|#'Q|}$e}!O#'Q!O!P#B}!P!Q$e!Q![$%g![!c$e!c!g$%g!g!h$.Q!h!i$%g!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#X$%g#X#Y$.Q#Y#Z$%g#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j;'S$e;'S;=`(u<%lO$eCj$0yc)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!O$e!O!P#Mq!P!Q$e!Q!R$2U!R![$%g![!c$e!c!i$%g!i#O$e#O#P&f#P#T$e#T#Z$%g#Z;'S$e;'S;=`(u<%lO$eCj$2av)c`(vS!i8O'f,UOY$eZr$ers%^sw$ewx$'|x!O$e!O!P#B}!P!Q$e!Q![$%g![!c$e!c!g$%g!g!h$.Q!h!i$%g!i!n$e!n!o#*Y!o!r$e!r!s#$w!s!w$e!w!x#*Y!x#O$e#O#P&f#P#T$e#T#U$%g#U#V$%g#V#X$%g#X#Y$.Q#Y#Z$%g#Z#`$e#`#a#*Y#a#d$e#d#e#$w#e#i$e#i#j#*Y#j#l$e#l#m$$[#m;'S$e;'S;=`(u<%lO$eGz$5S[({9b)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox![$e![!]$5x!]#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eFh$6TYm:|)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eCj$7OY)_8O)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eM^$7{_q8O%]#t)c`(vS'f,UOY$8zYZ$9|Zr$8zrs$:ksw$8zwx$Jax!^$8z!^!_$MX!_!`% f!`!a%#m!a#O$8z#O#P$<r#P;'S$8z;'S;=`$MR<%lO$8z3h$9T])c`(vS'f,UOY$8zYZ$9|Zr$8zrs$:ksw$8zwx$Jax!`$8z!`!a$LU!a#O$8z#O#P$<r#P;'S$8z;'S;=`$MR<%lO$8z!b$:PTO!`$9|!`!a$:`!a;'S$9|;'S;=`$:e<%lO$9|!b$:eO$W!b!b$:hP;=`<%l$9|3d$:rZ)c`'f,UOY$:kYZ$9|Zw$:kwx$;ex!`$:k!`!a$If!a#O$:k#O#P$<r#P;'S$:k;'S;=`$JZ<%lO$:k3S$;jX'f,UOY$;eYZ$9|Z!`$;e!`!a$<V!a#O$;e#O#P$<r#P;'S$;e;'S;=`$AY<%lO$;e3S$<`U$W!bY&j'f,UOY%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}3S$<w['f,UOY$;eYZ$;eZ]$;e]^$=m^!`$;e!`!a$A`!a#O$;e#O#P$HO#P;'S$;e;'S;=`$Hv;=`<%l$F[<%lO$;e3S$=rX'f,UOY$;eYZ$>_Z!`$;e!`!a$<V!a#O$;e#O#P$<r#P;'S$;e;'S;=`$AY<%lO$;e-h$>dX'f,UOY$>_YZ$9|Z!`$>_!`!a$?P!a#O$>_#O#P$?j#P;'S$>_;'S;=`$AS<%lO$>_-h$?WU$W!b'f,UOY%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}-h$?oZ'f,UOY$>_YZ$>_Z]$>_]^$@b^!`$>_!`!a$?P!a#O$>_#O#P$?j#P;'S$>_;'S;=`$AS<%lO$>_-h$@gX'f,UOY$>_YZ$>_Z!`$>_!`!a$?P!a#O$>_#O#P$?j#P;'S$>_;'S;=`$AS<%lO$>_-h$AVP;=`<%l$>_3S$A]P;=`<%l$;e3S$AgW$W!b'f,UOY$BPZ!`$BP!`!a$Bn!a#O$BP#O#P$CX#P;'S$BP;'S;=`$Dn<%lO$BP1p$BUW'f,UOY$BPZ!`$BP!`!a$Bn!a#O$BP#O#P$CX#P;'S$BP;'S;=`$Dn<%lO$BP1p$BuUY&j'f,UOY%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}1p$C^Y'f,UOY$BPYZ$BPZ]$BP]^$C|^#O$BP#O#P$Dt#P;'S$BP;'S;=`$El;=`<%l$F[<%lO$BP1p$DRX'f,UOY$BPYZ%}Z!`$BP!`!a$Bn!a#O$BP#O#P$CX#P;'S$BP;'S;=`$Dn<%lO$BP1p$DqP;=`<%l$BP1p$DyZ'f,UOY$BPYZ%}Z]$BP]^$C|^!`$BP!`!a$Bn!a#O$BP#O#P$CX#P;'S$BP;'S;=`$Dn<%lO$BP1p$EoXOY$F[Z!`$F[!`!a$Fw!a#O$F[#O#P$F|#P;'S$F[;'S;=`$Gx;=`<%l$BP<%lO$F[&j$F_WOY$F[Z!`$F[!`!a$Fw!a#O$F[#O#P$F|#P;'S$F[;'S;=`$Gx<%lO$F[&j$F|OY&j&j$GPRO;'S$F[;'S;=`$GY;=`O$F[&j$G]XOY$F[Z!`$F[!`!a$Fw!a#O$F[#O#P$F|#P;'S$F[;'S;=`$Gx;=`<%l$F[<%lO$F[&j$G{P;=`<%l$F[3S$HTZ'f,UOY$;eYZ$>_Z]$;e]^$=m^!`$;e!`!a$<V!a#O$;e#O#P$<r#P;'S$;e;'S;=`$AY<%lO$;e3S$HyXOY$F[Z!`$F[!`!a$Fw!a#O$F[#O#P$F|#P;'S$F[;'S;=`$Gx;=`<%l$;e<%lO$F[3d$IqW$W!bY&j)c`'f,UOY%^Zw%^wx%}x#O%^#O#P&f#P;'S%^;'S;=`'x<%lO%^3d$J^P;=`<%l$:k3W$JhZ(vS'f,UOY$JaYZ$9|Zr$Jars$;es!`$Ja!`!a$KZ!a#O$Ja#O#P$<r#P;'S$Ja;'S;=`$LO<%lO$Ja3W$KfW$W!bY&j(vS'f,UOY(OZr(Ors%}s#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(O3W$LRP;=`<%l$Ja3h$LcY$W!bY&j)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e3h$MUP;=`<%l$8zM^$Mf^)c`(vS%[#t!f8O'f,UOY$8zYZ$9|Zr$8zrs$:ksw$8zwx$Jax!_$8z!_!`$Nb!`!a$LU!a#O$8z#O#P$<r#P;'S$8z;'S;=`$MR<%lO$8zM^$Nm]!g:t)c`(vS'f,UOY$8zYZ$9|Zr$8zrs$:ksw$8zwx$Jax!`$8z!`!a$LU!a#O$8z#O#P$<r#P;'S$8z;'S;=`$MR<%lO$8zM^% s]%]#t!b8O)c`(vS'f,UOY$8zYZ$9|Zr$8zrs$:ksw$8zwx$Jax!`$8z!`!a%!l!a#O$8z#O#P$<r#P;'S$8z;'S;=`$MR<%lO$8zM^%!}Y%]#t!b8O$W!bY&j)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e2U%#xYY&j)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%$s[)p#v)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`0Q!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%%v]%]#t)c`(vS!d8O'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`%&o!`!a%'l!a#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%&|Y%]#t!b8O)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%'y[)c`(vS%[#t!f8O'f,UOY$eZr$ers%^sw$ewx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e,l%(zY(zQ)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eMf%)yb)c`)OW(vS!R7|(w*t'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![%)j![!c$e!c!}%)j!}#O$e#O#P&f#P#R$e#R#S%)j#S#T$e#T#o%)j#o;'S$e;'S;=`(u<%lO$eMf%+bb)c`)OW(vS!R7|(w*t'f,UOY$eZr$ers%,jsw$ewx%-]x!Q$e!Q![%)j![!c$e!c!}%)j!}#O$e#O#P&f#P#R$e#R#S%)j#S#T$e#T#o%)j#o;'S$e;'S;=`(u<%lO$eIQ%,sW)c`(u=j'f,UOY%^Zw%^wx%}x#O%^#O#P&f#P;'S%^;'S;=`'x<%lO%^CY%-fW(vS)b8O'f,UOY(OZr(Ors%}s#O(O#O#P&f#P;'S(O;'S;=`(o<%lO(OF`%.ZZ!V:t)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox!}$e!}#O%.|#O#P&f#P;'S$e;'S;=`(u<%lO$e,l%/XY)VQ)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eGz%/|a'f,UOY%1RYZ%1lZ]%1R]^%2k^!Q%1R!Q![%3X![!w%1R!w!x%4i!x#O%1R#O#P%;o#P#i%1R#i#j%8T#j#l%1R#l#m%<c#m;'S%1R;'S;=`%?U<%lO%1R,j%1YUXd'f,UOY%}Z#O%}#O#P&f#P;'S%};'S;=`'r<%lO%}Gz%1u[Xd(o<`'f,UOX%}XY-OYZ*[Z]%}]^-O^p%}pq-Oq#O%}#O#P,^#P;'S%};'S;=`'r<%lO%}Gz%2rVXd'f,UOY%}YZ-OZ#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},j%3`WXd'f,UOY%}Z!Q%}!Q![%3x![#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},j%4PWXd'f,UOY%}Z!Q%}!Q![%1R![#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},j%4n['f,UOY%}Z!Q%}!Q![%5d![!c%}!c!i%5d!i#O%}#O#P&f#P#T%}#T#Z%5d#Z;'S%};'S;=`'r<%lO%},j%5i['f,UOY%}Z!Q%}!Q![%6_![!c%}!c!i%6_!i#O%}#O#P&f#P#T%}#T#Z%6_#Z;'S%};'S;=`'r<%lO%},j%6d['f,UOY%}Z!Q%}!Q![%7Y![!c%}!c!i%7Y!i#O%}#O#P&f#P#T%}#T#Z%7Y#Z;'S%};'S;=`'r<%lO%},j%7_['f,UOY%}Z!Q%}!Q![%8T![!c%}!c!i%8T!i#O%}#O#P&f#P#T%}#T#Z%8T#Z;'S%};'S;=`'r<%lO%},j%8Y['f,UOY%}Z!Q%}!Q![%9O![!c%}!c!i%9O!i#O%}#O#P&f#P#T%}#T#Z%9O#Z;'S%};'S;=`'r<%lO%},j%9T['f,UOY%}Z!Q%}!Q![%9y![!c%}!c!i%9y!i#O%}#O#P&f#P#T%}#T#Z%9y#Z;'S%};'S;=`'r<%lO%},j%:O['f,UOY%}Z!Q%}!Q![%:t![!c%}!c!i%:t!i#O%}#O#P&f#P#T%}#T#Z%:t#Z;'S%};'S;=`'r<%lO%},j%:y['f,UOY%}Z!Q%}!Q![%1R![!c%}!c!i%1R!i#O%}#O#P&f#P#T%}#T#Z%1R#Z;'S%};'S;=`'r<%lO%},j%;vXXd'f,UOY%}YZ%}Z]%}]^'W^#O%}#O#P&f#P;'S%};'S;=`'r<%lO%},j%<h['f,UOY%}Z!Q%}!Q![%=^![!c%}!c!i%=^!i#O%}#O#P&f#P#T%}#T#Z%=^#Z;'S%};'S;=`'r<%lO%},j%=c['f,UOY%}Z!Q%}!Q![%>X![!c%}!c!i%>X!i#O%}#O#P&f#P#T%}#T#Z%>X#Z;'S%};'S;=`'r<%lO%},j%>`[Xd'f,UOY%}Z!Q%}!Q![%>X![!c%}!c!i%>X!i#O%}#O#P&f#P#T%}#T#Z%>X#Z;'S%};'S;=`'r<%lO%},j%?XP;=`<%l%1RCr%?gZ!W7^)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P#Q%@Y#Q;'S$e;'S;=`(u<%lO$e-d%@eY)Ux)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%Ab[)c`(vS%[#t'f,U!_8OOY$eZr$ers%^sw$ewx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eMf%Bgd)c`)OW(vS!R7|(w*t'f,UOY$eZr$ers%,jsw$ewx%-]x!Q$e!Q!Y%)j!Y!Z%+R!Z![%)j![!c$e!c!}%)j!}#O$e#O#P&f#P#R$e#R#S%)j#S#T$e#T#o%)j#o;'S$e;'S;=`(u<%lO$eCj%DQY!T8O)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$eF`%D}^)c`(vS%[#t'f,U!^8OOY$eZr$ers%^sw$ewx(Ox!_$e!_!`!8g!`#O$e#O#P&f#P#p$e#p#q%Ey#q;'S$e;'S;=`(u<%lO$eF`%FWY)Z8O%^#t)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e-^%GRY!Ur)c`(vS'f,UOY$eZr$ers%^sw$ewx(Ox#O$e#O#P&f#P;'S$e;'S;=`(u<%lO$e/j%HOc)c`(vS%[#t'RQ'f,UOX$eXY%IZZp$epq%IZqr$ers%^sw$ewx(Ox!c$e!c!}%Jo!}#O$e#O#P&f#P#R$e#R#S%Jo#S#T$e#T#o%Jo#o;'S$e;'S;=`(u<%lO$e,t%Idc)c`(vS'f,UOX$eXY%IZZp$epq%IZqr$ers%^sw$ewx(Ox!c$e!c!}%Jo!}#O$e#O#P&f#P#R$e#R#S%Jo#S#T$e#T#o%Jo#o;'S$e;'S;=`(u<%lO$e,t%Jzb)c`(vSeY'f,UOY$eZr$ers%^sw$ewx(Ox!Q$e!Q![%Jo![!c$e!c!}%Jo!}#O$e#O#P&f#P#R$e#R#S%Jo#S#T$e#T#o%Jo#o;'S$e;'S;=`(u<%lO$e",
4047 tokenizers: [rawString, fallback, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, new LocalTokenGroup("j~RQYZXz{^~^O(r~~aP!P!Qd~iO(s~~", 25, 355)],
4048 topRules: { "Program": [0, 307] },
4049 dynamicPrecedences: { "17": 1, "65": 1, "87": 1, "94": 1, "119": 1, "184": 1, "187": -10, "240": -10, "241": 1, "244": -1, "246": -10, "247": 1, "262": -1, "267": 2, "268": 2, "306": -10, "370": 3, "423": 1, "424": 3, "425": 1, "426": 1 },
4050 specialized: [{ term: 361, get: (value) => spec_identifier[value] || -1 }, { term: 33, get: (value) => spec_[value] || -1 }, { term: 66, get: (value) => spec_templateArgsEnd[value] || -1 }, { term: 368, get: (value) => spec_scopedIdentifier[value] || -1 }],
4051 tokenPrec: 24916
4052});
4053export {
4054 parser
4055};
vendor/lezer-gdscript/LICENSE +21 -0
……@@ -0,0 +1,21 @@
1MIT License
2
3Copyright (c) 2023 GDQuest
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE.
vendor/lezer-gdscript/VENDOR.md +31 -0
……@@ -0,0 +1,31 @@
1# Vendored: @gdquest/lezer-gdscript
2
3- **Source**: https://www.npmjs.com/package/@gdquest/lezer-gdscript
4- **Version**: 0.1.2
5- **License**: MIT (see LICENSE)
6- **Author**: GDQuest / Adam Scott
7- **Bundled**: Grammar + Lezer runtime (@lezer/lr + @lezer/common + @lezer/highlight)
8- **Bundle size**: 136 KB
9
10## Usage
11
12```js
13import { parser } from '../vendor/lezer-gdscript/lezer-gdscript.mjs'
14const tree = parser.parse(source)
15```
16
17## Bundled With
18
19- @lezer/lr (LR parser runtime, by Marijn Haverbeke, MIT)
20- @lezer/common (tree types, by Marijn Haverbeke, MIT)
21- @lezer/highlight (style tags, by Marijn Haverbeke, MIT)
22
23## Regeneration
24
25```sh
26cd /tmp && mkdir -p codetree-vendor && cd codetree-vendor
27npm init -y && echo '{"type":"module"}' > package.json
28npm install @gdquest/lezer-gdscript @lezer/lr @lezer/common @lezer/highlight esbuild
29echo "export { parser } from '@gdquest/lezer-gdscript'" > bundle.js
30./node_modules/.bin/esbuild bundle.js --bundle --format=esm --platform=neutral --outfile=lezer-gdscript.mjs
31```
vendor/lezer-gdscript/lezer-gdscript.mjs +4105 -0
……@@ -0,0 +1,4105 @@
1// node_modules/@lezer/common/dist/index.js
2var DefaultBufferLength = 1024;
3var nextPropID = 0;
4var Range = class {
5 constructor(from, to) {
6 this.from = from;
7 this.to = to;
8 }
9};
10var NodeProp = class {
11 /**
12 Create a new node prop type.
13 */
14 constructor(config = {}) {
15 this.id = nextPropID++;
16 this.perNode = !!config.perNode;
17 this.deserialize = config.deserialize || (() => {
18 throw new Error("This node type doesn't define a deserialize function");
19 });
20 this.combine = config.combine || null;
21 }
22 /**
23 This is meant to be used with
24 [`NodeSet.extend`](#common.NodeSet.extend) or
25 [`LRParser.configure`](#lr.ParserConfig.props) to compute
26 prop values for each node type in the set. Takes a [match
27 object](#common.NodeType^match) or function that returns undefined
28 if the node type doesn't get this prop, and the prop's value if
29 it does.
30 */
31 add(match) {
32 if (this.perNode)
33 throw new RangeError("Can't add per-node props to node types");
34 if (typeof match != "function")
35 match = NodeType.match(match);
36 return (type) => {
37 let result = match(type);
38 return result === void 0 ? null : [this, result];
39 };
40 }
41};
42NodeProp.closedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
43NodeProp.openedBy = new NodeProp({ deserialize: (str) => str.split(" ") });
44NodeProp.group = new NodeProp({ deserialize: (str) => str.split(" ") });
45NodeProp.isolate = new NodeProp({ deserialize: (value) => {
46 if (value && value != "rtl" && value != "ltr" && value != "auto")
47 throw new RangeError("Invalid value for isolate: " + value);
48 return value || "auto";
49} });
50NodeProp.contextHash = new NodeProp({ perNode: true });
51NodeProp.lookAhead = new NodeProp({ perNode: true });
52NodeProp.mounted = new NodeProp({ perNode: true });
53var MountedTree = class {
54 constructor(tree, overlay, parser2, bracketed2 = false) {
55 this.tree = tree;
56 this.overlay = overlay;
57 this.parser = parser2;
58 this.bracketed = bracketed2;
59 }
60 /**
61 @internal
62 */
63 static get(tree) {
64 return tree && tree.props && tree.props[NodeProp.mounted.id];
65 }
66};
67var noProps = /* @__PURE__ */ Object.create(null);
68var NodeType = class _NodeType {
69 /**
70 @internal
71 */
72 constructor(name2, props, id2, flags = 0) {
73 this.name = name2;
74 this.props = props;
75 this.id = id2;
76 this.flags = flags;
77 }
78 /**
79 Define a node type.
80 */
81 static define(spec) {
82 let props = spec.props && spec.props.length ? /* @__PURE__ */ Object.create(null) : noProps;
83 let flags = (spec.top ? 1 : 0) | (spec.skipped ? 2 : 0) | (spec.error ? 4 : 0) | (spec.name == null ? 8 : 0);
84 let type = new _NodeType(spec.name || "", props, spec.id, flags);
85 if (spec.props)
86 for (let src of spec.props) {
87 if (!Array.isArray(src))
88 src = src(type);
89 if (src) {
90 if (src[0].perNode)
91 throw new RangeError("Can't store a per-node prop on a node type");
92 props[src[0].id] = src[1];
93 }
94 }
95 return type;
96 }
97 /**
98 Retrieves a node prop for this type. Will return `undefined` if
99 the prop isn't present on this node.
100 */
101 prop(prop) {
102 return this.props[prop.id];
103 }
104 /**
105 True when this is the top node of a grammar.
106 */
107 get isTop() {
108 return (this.flags & 1) > 0;
109 }
110 /**
111 True when this node is produced by a skip rule.
112 */
113 get isSkipped() {
114 return (this.flags & 2) > 0;
115 }
116 /**
117 Indicates whether this is an error node.
118 */
119 get isError() {
120 return (this.flags & 4) > 0;
121 }
122 /**
123 When true, this node type doesn't correspond to a user-declared
124 named node, for example because it is used to cache repetition.
125 */
126 get isAnonymous() {
127 return (this.flags & 8) > 0;
128 }
129 /**
130 Returns true when this node's name or one of its
131 [groups](#common.NodeProp^group) matches the given string.
132 */
133 is(name2) {
134 if (typeof name2 == "string") {
135 if (this.name == name2)
136 return true;
137 let group = this.prop(NodeProp.group);
138 return group ? group.indexOf(name2) > -1 : false;
139 }
140 return this.id == name2;
141 }
142 /**
143 Create a function from node types to arbitrary values by
144 specifying an object whose property names are node or
145 [group](#common.NodeProp^group) names. Often useful with
146 [`NodeProp.add`](#common.NodeProp.add). You can put multiple
147 names, separated by spaces, in a single property name to map
148 multiple node names to a single value.
149 */
150 static match(map) {
151 let direct = /* @__PURE__ */ Object.create(null);
152 for (let prop in map)
153 for (let name2 of prop.split(" "))
154 direct[name2] = map[prop];
155 return (node) => {
156 for (let groups = node.prop(NodeProp.group), i = -1; i < (groups ? groups.length : 0); i++) {
157 let found = direct[i < 0 ? node.name : groups[i]];
158 if (found)
159 return found;
160 }
161 };
162 }
163};
164NodeType.none = new NodeType(
165 "",
166 /* @__PURE__ */ Object.create(null),
167 0,
168 8
169 /* NodeFlag.Anonymous */
170);
171var NodeSet = class _NodeSet {
172 /**
173 Create a set with the given types. The `id` property of each
174 type should correspond to its position within the array.
175 */
176 constructor(types) {
177 this.types = types;
178 for (let i = 0; i < types.length; i++)
179 if (types[i].id != i)
180 throw new RangeError("Node type ids should correspond to array positions when creating a node set");
181 }
182 /**
183 Create a copy of this set with some node properties added. The
184 arguments to this method can be created with
185 [`NodeProp.add`](#common.NodeProp.add).
186 */
187 extend(...props) {
188 let newTypes = [];
189 for (let type of this.types) {
190 let newProps = null;
191 for (let source of props) {
192 let add = source(type);
193 if (add) {
194 if (!newProps)
195 newProps = Object.assign({}, type.props);
196 let value = add[1], prop = add[0];
197 if (prop.combine && prop.id in newProps)
198 value = prop.combine(newProps[prop.id], value);
199 newProps[prop.id] = value;
200 }
201 }
202 newTypes.push(newProps ? new NodeType(type.name, newProps, type.id, type.flags) : type);
203 }
204 return new _NodeSet(newTypes);
205 }
206};
207var CachedNode = /* @__PURE__ */ new WeakMap();
208var CachedInnerNode = /* @__PURE__ */ new WeakMap();
209var IterMode;
210(function(IterMode2) {
211 IterMode2[IterMode2["ExcludeBuffers"] = 1] = "ExcludeBuffers";
212 IterMode2[IterMode2["IncludeAnonymous"] = 2] = "IncludeAnonymous";
213 IterMode2[IterMode2["IgnoreMounts"] = 4] = "IgnoreMounts";
214 IterMode2[IterMode2["IgnoreOverlays"] = 8] = "IgnoreOverlays";
215 IterMode2[IterMode2["EnterBracketed"] = 16] = "EnterBracketed";
216})(IterMode || (IterMode = {}));
217var Tree = class _Tree {
218 /**
219 Construct a new tree. See also [`Tree.build`](#common.Tree^build).
220 */
221 constructor(type, children, positions, length, props) {
222 this.type = type;
223 this.children = children;
224 this.positions = positions;
225 this.length = length;
226 this.props = null;
227 if (props && props.length) {
228 this.props = /* @__PURE__ */ Object.create(null);
229 for (let [prop, value] of props)
230 this.props[typeof prop == "number" ? prop : prop.id] = value;
231 }
232 }
233 /**
234 @internal
235 */
236 toString() {
237 let mounted = MountedTree.get(this);
238 if (mounted && !mounted.overlay)
239 return mounted.tree.toString();
240 let children = "";
241 for (let ch of this.children) {
242 let str = ch.toString();
243 if (str) {
244 if (children)
245 children += ",";
246 children += str;
247 }
248 }
249 return !this.type.name ? children : (/\W/.test(this.type.name) && !this.type.isError ? JSON.stringify(this.type.name) : this.type.name) + (children.length ? "(" + children + ")" : "");
250 }
251 /**
252 Get a [tree cursor](#common.TreeCursor) positioned at the top of
253 the tree. Mode can be used to [control](#common.IterMode) which
254 nodes the cursor visits.
255 */
256 cursor(mode = 0) {
257 return new TreeCursor(this.topNode, mode);
258 }
259 /**
260 Get a [tree cursor](#common.TreeCursor) pointing into this tree
261 at the given position and side (see
262 [`moveTo`](#common.TreeCursor.moveTo).
263 */
264 cursorAt(pos, side = 0, mode = 0) {
265 let scope = CachedNode.get(this) || this.topNode;
266 let cursor = new TreeCursor(scope);
267 cursor.moveTo(pos, side);
268 CachedNode.set(this, cursor._tree);
269 return cursor;
270 }
271 /**
272 Get a [syntax node](#common.SyntaxNode) object for the top of the
273 tree.
274 */
275 get topNode() {
276 return new TreeNode(this, 0, 0, null);
277 }
278 /**
279 Get the [syntax node](#common.SyntaxNode) at the given position.
280 If `side` is -1, this will move into nodes that end at the
281 position. If 1, it'll move into nodes that start at the
282 position. With 0, it'll only enter nodes that cover the position
283 from both sides.
284
285 Note that this will not enter
286 [overlays](#common.MountedTree.overlay), and you often want
287 [`resolveInner`](#common.Tree.resolveInner) instead.
288 */
289 resolve(pos, side = 0) {
290 let node = resolveNode(CachedNode.get(this) || this.topNode, pos, side, false);
291 CachedNode.set(this, node);
292 return node;
293 }
294 /**
295 Like [`resolve`](#common.Tree.resolve), but will enter
296 [overlaid](#common.MountedTree.overlay) nodes, producing a syntax node
297 pointing into the innermost overlaid tree at the given position
298 (with parent links going through all parent structure, including
299 the host trees).
300 */
301 resolveInner(pos, side = 0) {
302 let node = resolveNode(CachedInnerNode.get(this) || this.topNode, pos, side, true);
303 CachedInnerNode.set(this, node);
304 return node;
305 }
306 /**
307 In some situations, it can be useful to iterate through all
308 nodes around a position, including those in overlays that don't
309 directly cover the position. This method gives you an iterator
310 that will produce all nodes, from small to big, around the given
311 position.
312 */
313 resolveStack(pos, side = 0) {
314 return stackIterator(this, pos, side);
315 }
316 /**
317 Iterate over the tree and its children, calling `enter` for any
318 node that touches the `from`/`to` region (if given) before
319 running over such a node's children, and `leave` (if given) when
320 leaving the node. When `enter` returns `false`, that node will
321 not have its children iterated over (or `leave` called).
322 */
323 iterate(spec) {
324 let { enter, leave, from = 0, to = this.length } = spec;
325 let mode = spec.mode || 0, anon = (mode & IterMode.IncludeAnonymous) > 0;
326 for (let c = this.cursor(mode | IterMode.IncludeAnonymous); ; ) {
327 let entered = false;
328 if (c.from <= to && c.to >= from && (!anon && c.type.isAnonymous || enter(c) !== false)) {
329 if (c.firstChild())
330 continue;
331 entered = true;
332 }
333 for (; ; ) {
334 if (entered && leave && (anon || !c.type.isAnonymous))
335 leave(c);
336 if (c.nextSibling())
337 break;
338 if (!c.parent())
339 return;
340 entered = true;
341 }
342 }
343 }
344 /**
345 Get the value of the given [node prop](#common.NodeProp) for this
346 node. Works with both per-node and per-type props.
347 */
348 prop(prop) {
349 return !prop.perNode ? this.type.prop(prop) : this.props ? this.props[prop.id] : void 0;
350 }
351 /**
352 Returns the node's [per-node props](#common.NodeProp.perNode) in a
353 format that can be passed to the [`Tree`](#common.Tree)
354 constructor.
355 */
356 get propValues() {
357 let result = [];
358 if (this.props)
359 for (let id2 in this.props)
360 result.push([+id2, this.props[id2]]);
361 return result;
362 }
363 /**
364 Balance the direct children of this tree, producing a copy of
365 which may have children grouped into subtrees with type
366 [`NodeType.none`](#common.NodeType^none).
367 */
368 balance(config = {}) {
369 return this.children.length <= 8 ? this : balanceRange(NodeType.none, this.children, this.positions, 0, this.children.length, 0, this.length, (children, positions, length) => new _Tree(this.type, children, positions, length, this.propValues), config.makeTree || ((children, positions, length) => new _Tree(NodeType.none, children, positions, length)));
370 }
371 /**
372 Build a tree from a postfix-ordered buffer of node information,
373 or a cursor over such a buffer.
374 */
375 static build(data) {
376 return buildTree(data);
377 }
378};
379Tree.empty = new Tree(NodeType.none, [], [], 0);
380var FlatBufferCursor = class _FlatBufferCursor {
381 constructor(buffer, index) {
382 this.buffer = buffer;
383 this.index = index;
384 }
385 get id() {
386 return this.buffer[this.index - 4];
387 }
388 get start() {
389 return this.buffer[this.index - 3];
390 }
391 get end() {
392 return this.buffer[this.index - 2];
393 }
394 get size() {
395 return this.buffer[this.index - 1];
396 }
397 get pos() {
398 return this.index;
399 }
400 next() {
401 this.index -= 4;
402 }
403 fork() {
404 return new _FlatBufferCursor(this.buffer, this.index);
405 }
406};
407var TreeBuffer = class _TreeBuffer {
408 /**
409 Create a tree buffer.
410 */
411 constructor(buffer, length, set) {
412 this.buffer = buffer;
413 this.length = length;
414 this.set = set;
415 }
416 /**
417 @internal
418 */
419 get type() {
420 return NodeType.none;
421 }
422 /**
423 @internal
424 */
425 toString() {
426 let result = [];
427 for (let index = 0; index < this.buffer.length; ) {
428 result.push(this.childString(index));
429 index = this.buffer[index + 3];
430 }
431 return result.join(",");
432 }
433 /**
434 @internal
435 */
436 childString(index) {
437 let id2 = this.buffer[index], endIndex = this.buffer[index + 3];
438 let type = this.set.types[id2], result = type.name;
439 if (/\W/.test(result) && !type.isError)
440 result = JSON.stringify(result);
441 index += 4;
442 if (endIndex == index)
443 return result;
444 let children = [];
445 while (index < endIndex) {
446 children.push(this.childString(index));
447 index = this.buffer[index + 3];
448 }
449 return result + "(" + children.join(",") + ")";
450 }
451 /**
452 @internal
453 */
454 findChild(startIndex, endIndex, dir, pos, side) {
455 let { buffer } = this, pick = -1;
456 for (let i = startIndex; i != endIndex; i = buffer[i + 3]) {
457 if (checkSide(side, pos, buffer[i + 1], buffer[i + 2])) {
458 pick = i;
459 if (dir > 0)
460 break;
461 }
462 }
463 return pick;
464 }
465 /**
466 @internal
467 */
468 slice(startI, endI, from) {
469 let b = this.buffer;
470 let copy = new Uint16Array(endI - startI), len = 0;
471 for (let i = startI, j = 0; i < endI; ) {
472 copy[j++] = b[i++];
473 copy[j++] = b[i++] - from;
474 let to = copy[j++] = b[i++] - from;
475 copy[j++] = b[i++] - startI;
476 len = Math.max(len, to);
477 }
478 return new _TreeBuffer(copy, len, this.set);
479 }
480};
481function checkSide(side, pos, from, to) {
482 switch (side) {
483 case -2:
484 return from < pos;
485 case -1:
486 return to >= pos && from < pos;
487 case 0:
488 return from < pos && to > pos;
489 case 1:
490 return from <= pos && to > pos;
491 case 2:
492 return to > pos;
493 case 4:
494 return true;
495 }
496}
497function resolveNode(node, pos, side, overlays) {
498 var _a;
499 while (node.from == node.to || (side < 1 ? node.from >= pos : node.from > pos) || (side > -1 ? node.to <= pos : node.to < pos)) {
500 let parent = !overlays && node instanceof TreeNode && node.index < 0 ? null : node.parent;
501 if (!parent)
502 return node;
503 node = parent;
504 }
505 let mode = overlays ? 0 : IterMode.IgnoreOverlays;
506 if (overlays)
507 for (let scan = node, parent = scan.parent; parent; scan = parent, parent = scan.parent) {
508 if (scan instanceof TreeNode && scan.index < 0 && ((_a = parent.enter(pos, side, mode)) === null || _a === void 0 ? void 0 : _a.from) != scan.from)
509 node = parent;
510 }
511 for (; ; ) {
512 let inner = node.enter(pos, side, mode);
513 if (!inner)
514 return node;
515 node = inner;
516 }
517}
518var BaseNode = class {
519 cursor(mode = 0) {
520 return new TreeCursor(this, mode);
521 }
522 getChild(type, before = null, after = null) {
523 let r = getChildren(this, type, before, after);
524 return r.length ? r[0] : null;
525 }
526 getChildren(type, before = null, after = null) {
527 return getChildren(this, type, before, after);
528 }
529 resolve(pos, side = 0) {
530 return resolveNode(this, pos, side, false);
531 }
532 resolveInner(pos, side = 0) {
533 return resolveNode(this, pos, side, true);
534 }
535 matchContext(context) {
536 return matchNodeContext(this.parent, context);
537 }
538 enterUnfinishedNodesBefore(pos) {
539 let scan = this.childBefore(pos), node = this;
540 while (scan) {
541 let last = scan.lastChild;
542 if (!last || last.to != scan.to)
543 break;
544 if (last.type.isError && last.from == last.to) {
545 node = scan;
546 scan = last.prevSibling;
547 } else {
548 scan = last;
549 }
550 }
551 return node;
552 }
553 get node() {
554 return this;
555 }
556 get next() {
557 return this.parent;
558 }
559};
560var TreeNode = class _TreeNode extends BaseNode {
561 constructor(_tree, from, index, _parent) {
562 super();
563 this._tree = _tree;
564 this.from = from;
565 this.index = index;
566 this._parent = _parent;
567 }
568 get type() {
569 return this._tree.type;
570 }
571 get name() {
572 return this._tree.type.name;
573 }
574 get to() {
575 return this.from + this._tree.length;
576 }
577 nextChild(i, dir, pos, side, mode = 0) {
578 for (let parent = this; ; ) {
579 for (let { children, positions } = parent._tree, e = dir > 0 ? children.length : -1; i != e; i += dir) {
580 let next = children[i], start = positions[i] + parent.from, mounted;
581 if (!(mode & IterMode.EnterBracketed && next instanceof Tree && (mounted = MountedTree.get(next)) && !mounted.overlay && mounted.bracketed && pos >= start && pos <= start + next.length) && !checkSide(side, pos, start, start + next.length))
582 continue;
583 if (next instanceof TreeBuffer) {
584 if (mode & IterMode.ExcludeBuffers)
585 continue;
586 let index = next.findChild(0, next.buffer.length, dir, pos - start, side);
587 if (index > -1)
588 return new BufferNode(new BufferContext(parent, next, i, start), null, index);
589 } else if (mode & IterMode.IncludeAnonymous || (!next.type.isAnonymous || hasChild(next))) {
590 let mounted2;
591 if (!(mode & IterMode.IgnoreMounts) && (mounted2 = MountedTree.get(next)) && !mounted2.overlay)
592 return new _TreeNode(mounted2.tree, start, i, parent);
593 let inner = new _TreeNode(next, start, i, parent);
594 return mode & IterMode.IncludeAnonymous || !inner.type.isAnonymous ? inner : inner.nextChild(dir < 0 ? next.children.length - 1 : 0, dir, pos, side, mode);
595 }
596 }
597 if (mode & IterMode.IncludeAnonymous || !parent.type.isAnonymous)
598 return null;
599 if (parent.index >= 0)
600 i = parent.index + dir;
601 else
602 i = dir < 0 ? -1 : parent._parent._tree.children.length;
603 parent = parent._parent;
604 if (!parent)
605 return null;
606 }
607 }
608 get firstChild() {
609 return this.nextChild(
610 0,
611 1,
612 0,
613 4
614 /* Side.DontCare */
615 );
616 }
617 get lastChild() {
618 return this.nextChild(
619 this._tree.children.length - 1,
620 -1,
621 0,
622 4
623 /* Side.DontCare */
624 );
625 }
626 childAfter(pos) {
627 return this.nextChild(
628 0,
629 1,
630 pos,
631 2
632 /* Side.After */
633 );
634 }
635 childBefore(pos) {
636 return this.nextChild(
637 this._tree.children.length - 1,
638 -1,
639 pos,
640 -2
641 /* Side.Before */
642 );
643 }
644 prop(prop) {
645 return this._tree.prop(prop);
646 }
647 enter(pos, side, mode = 0) {
648 let mounted;
649 if (!(mode & IterMode.IgnoreOverlays) && (mounted = MountedTree.get(this._tree)) && mounted.overlay) {
650 let rPos = pos - this.from, enterBracketed = mode & IterMode.EnterBracketed && mounted.bracketed;
651 for (let { from, to } of mounted.overlay) {
652 if ((side > 0 || enterBracketed ? from <= rPos : from < rPos) && (side < 0 || enterBracketed ? to >= rPos : to > rPos))
653 return new _TreeNode(mounted.tree, mounted.overlay[0].from + this.from, -1, this);
654 }
655 }
656 return this.nextChild(0, 1, pos, side, mode);
657 }
658 nextSignificantParent() {
659 let val = this;
660 while (val.type.isAnonymous && val._parent)
661 val = val._parent;
662 return val;
663 }
664 get parent() {
665 return this._parent ? this._parent.nextSignificantParent() : null;
666 }
667 get nextSibling() {
668 return this._parent && this.index >= 0 ? this._parent.nextChild(
669 this.index + 1,
670 1,
671 0,
672 4
673 /* Side.DontCare */
674 ) : null;
675 }
676 get prevSibling() {
677 return this._parent && this.index >= 0 ? this._parent.nextChild(
678 this.index - 1,
679 -1,
680 0,
681 4
682 /* Side.DontCare */
683 ) : null;
684 }
685 get tree() {
686 return this._tree;
687 }
688 toTree() {
689 return this._tree;
690 }
691 /**
692 @internal
693 */
694 toString() {
695 return this._tree.toString();
696 }
697};
698function getChildren(node, type, before, after) {
699 let cur = node.cursor(), result = [];
700 if (!cur.firstChild())
701 return result;
702 if (before != null)
703 for (let found = false; !found; ) {
704 found = cur.type.is(before);
705 if (!cur.nextSibling())
706 return result;
707 }
708 for (; ; ) {
709 if (after != null && cur.type.is(after))
710 return result;
711 if (cur.type.is(type))
712 result.push(cur.node);
713 if (!cur.nextSibling())
714 return after == null ? result : [];
715 }
716}
717function matchNodeContext(node, context, i = context.length - 1) {
718 for (let p = node; i >= 0; p = p.parent) {
719 if (!p)
720 return false;
721 if (!p.type.isAnonymous) {
722 if (context[i] && context[i] != p.name)
723 return false;
724 i--;
725 }
726 }
727 return true;
728}
729var BufferContext = class {
730 constructor(parent, buffer, index, start) {
731 this.parent = parent;
732 this.buffer = buffer;
733 this.index = index;
734 this.start = start;
735 }
736};
737var BufferNode = class _BufferNode extends BaseNode {
738 get name() {
739 return this.type.name;
740 }
741 get from() {
742 return this.context.start + this.context.buffer.buffer[this.index + 1];
743 }
744 get to() {
745 return this.context.start + this.context.buffer.buffer[this.index + 2];
746 }
747 constructor(context, _parent, index) {
748 super();
749 this.context = context;
750 this._parent = _parent;
751 this.index = index;
752 this.type = context.buffer.set.types[context.buffer.buffer[index]];
753 }
754 child(dir, pos, side) {
755 let { buffer } = this.context;
756 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.context.start, side);
757 return index < 0 ? null : new _BufferNode(this.context, this, index);
758 }
759 get firstChild() {
760 return this.child(
761 1,
762 0,
763 4
764 /* Side.DontCare */
765 );
766 }
767 get lastChild() {
768 return this.child(
769 -1,
770 0,
771 4
772 /* Side.DontCare */
773 );
774 }
775 childAfter(pos) {
776 return this.child(
777 1,
778 pos,
779 2
780 /* Side.After */
781 );
782 }
783 childBefore(pos) {
784 return this.child(
785 -1,
786 pos,
787 -2
788 /* Side.Before */
789 );
790 }
791 prop(prop) {
792 return this.type.prop(prop);
793 }
794 enter(pos, side, mode = 0) {
795 if (mode & IterMode.ExcludeBuffers)
796 return null;
797 let { buffer } = this.context;
798 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], side > 0 ? 1 : -1, pos - this.context.start, side);
799 return index < 0 ? null : new _BufferNode(this.context, this, index);
800 }
801 get parent() {
802 return this._parent || this.context.parent.nextSignificantParent();
803 }
804 externalSibling(dir) {
805 return this._parent ? null : this.context.parent.nextChild(
806 this.context.index + dir,
807 dir,
808 0,
809 4
810 /* Side.DontCare */
811 );
812 }
813 get nextSibling() {
814 let { buffer } = this.context;
815 let after = buffer.buffer[this.index + 3];
816 if (after < (this._parent ? buffer.buffer[this._parent.index + 3] : buffer.buffer.length))
817 return new _BufferNode(this.context, this._parent, after);
818 return this.externalSibling(1);
819 }
820 get prevSibling() {
821 let { buffer } = this.context;
822 let parentStart = this._parent ? this._parent.index + 4 : 0;
823 if (this.index == parentStart)
824 return this.externalSibling(-1);
825 return new _BufferNode(this.context, this._parent, buffer.findChild(
826 parentStart,
827 this.index,
828 -1,
829 0,
830 4
831 /* Side.DontCare */
832 ));
833 }
834 get tree() {
835 return null;
836 }
837 toTree() {
838 let children = [], positions = [];
839 let { buffer } = this.context;
840 let startI = this.index + 4, endI = buffer.buffer[this.index + 3];
841 if (endI > startI) {
842 let from = buffer.buffer[this.index + 1];
843 children.push(buffer.slice(startI, endI, from));
844 positions.push(0);
845 }
846 return new Tree(this.type, children, positions, this.to - this.from);
847 }
848 /**
849 @internal
850 */
851 toString() {
852 return this.context.buffer.childString(this.index);
853 }
854};
855function iterStack(heads) {
856 if (!heads.length)
857 return null;
858 let pick = 0, picked = heads[0];
859 for (let i = 1; i < heads.length; i++) {
860 let node = heads[i];
861 if (node.from > picked.from || node.to < picked.to) {
862 picked = node;
863 pick = i;
864 }
865 }
866 let next = picked instanceof TreeNode && picked.index < 0 ? null : picked.parent;
867 let newHeads = heads.slice();
868 if (next)
869 newHeads[pick] = next;
870 else
871 newHeads.splice(pick, 1);
872 return new StackIterator(newHeads, picked);
873}
874var StackIterator = class {
875 constructor(heads, node) {
876 this.heads = heads;
877 this.node = node;
878 }
879 get next() {
880 return iterStack(this.heads);
881 }
882};
883function stackIterator(tree, pos, side) {
884 let inner = tree.resolveInner(pos, side), layers = null;
885 for (let scan = inner instanceof TreeNode ? inner : inner.context.parent; scan; scan = scan.parent) {
886 if (scan.index < 0) {
887 let parent = scan.parent;
888 (layers || (layers = [inner])).push(parent.resolve(pos, side));
889 scan = parent;
890 } else {
891 let mount = MountedTree.get(scan.tree);
892 if (mount && mount.overlay && mount.overlay[0].from <= pos && mount.overlay[mount.overlay.length - 1].to >= pos) {
893 let root = new TreeNode(mount.tree, mount.overlay[0].from + scan.from, -1, scan);
894 (layers || (layers = [inner])).push(resolveNode(root, pos, side, false));
895 }
896 }
897 }
898 return layers ? iterStack(layers) : inner;
899}
900var TreeCursor = class {
901 /**
902 Shorthand for `.type.name`.
903 */
904 get name() {
905 return this.type.name;
906 }
907 /**
908 @internal
909 */
910 constructor(node, mode = 0) {
911 this.buffer = null;
912 this.stack = [];
913 this.index = 0;
914 this.bufferNode = null;
915 this.mode = mode & ~IterMode.EnterBracketed;
916 if (node instanceof TreeNode) {
917 this.yieldNode(node);
918 } else {
919 this._tree = node.context.parent;
920 this.buffer = node.context;
921 for (let n = node._parent; n; n = n._parent)
922 this.stack.unshift(n.index);
923 this.bufferNode = node;
924 this.yieldBuf(node.index);
925 }
926 }
927 yieldNode(node) {
928 if (!node)
929 return false;
930 this._tree = node;
931 this.type = node.type;
932 this.from = node.from;
933 this.to = node.to;
934 return true;
935 }
936 yieldBuf(index, type) {
937 this.index = index;
938 let { start, buffer } = this.buffer;
939 this.type = type || buffer.set.types[buffer.buffer[index]];
940 this.from = start + buffer.buffer[index + 1];
941 this.to = start + buffer.buffer[index + 2];
942 return true;
943 }
944 /**
945 @internal
946 */
947 yield(node) {
948 if (!node)
949 return false;
950 if (node instanceof TreeNode) {
951 this.buffer = null;
952 return this.yieldNode(node);
953 }
954 this.buffer = node.context;
955 return this.yieldBuf(node.index, node.type);
956 }
957 /**
958 @internal
959 */
960 toString() {
961 return this.buffer ? this.buffer.buffer.childString(this.index) : this._tree.toString();
962 }
963 /**
964 @internal
965 */
966 enterChild(dir, pos, side) {
967 if (!this.buffer)
968 return this.yield(this._tree.nextChild(dir < 0 ? this._tree._tree.children.length - 1 : 0, dir, pos, side, this.mode));
969 let { buffer } = this.buffer;
970 let index = buffer.findChild(this.index + 4, buffer.buffer[this.index + 3], dir, pos - this.buffer.start, side);
971 if (index < 0)
972 return false;
973 this.stack.push(this.index);
974 return this.yieldBuf(index);
975 }
976 /**
977 Move the cursor to this node's first child. When this returns
978 false, the node has no child, and the cursor has not been moved.
979 */
980 firstChild() {
981 return this.enterChild(
982 1,
983 0,
984 4
985 /* Side.DontCare */
986 );
987 }
988 /**
989 Move the cursor to this node's last child.
990 */
991 lastChild() {
992 return this.enterChild(
993 -1,
994 0,
995 4
996 /* Side.DontCare */
997 );
998 }
999 /**
1000 Move the cursor to the first child that ends after `pos`.
1001 */
1002 childAfter(pos) {
1003 return this.enterChild(
1004 1,
1005 pos,
1006 2
1007 /* Side.After */
1008 );
1009 }
1010 /**
1011 Move to the last child that starts before `pos`.
1012 */
1013 childBefore(pos) {
1014 return this.enterChild(
1015 -1,
1016 pos,
1017 -2
1018 /* Side.Before */
1019 );
1020 }
1021 /**
1022 Move the cursor to the child around `pos`. If side is -1 the
1023 child may end at that position, when 1 it may start there. This
1024 will also enter [overlaid](#common.MountedTree.overlay)
1025 [mounted](#common.NodeProp^mounted) trees unless `overlays` is
1026 set to false.
1027 */
1028 enter(pos, side, mode = this.mode) {
1029 if (!this.buffer)
1030 return this.yield(this._tree.enter(pos, side, mode));
1031 return mode & IterMode.ExcludeBuffers ? false : this.enterChild(1, pos, side);
1032 }
1033 /**
1034 Move to the node's parent node, if this isn't the top node.
1035 */
1036 parent() {
1037 if (!this.buffer)
1038 return this.yieldNode(this.mode & IterMode.IncludeAnonymous ? this._tree._parent : this._tree.parent);
1039 if (this.stack.length)
1040 return this.yieldBuf(this.stack.pop());
1041 let parent = this.mode & IterMode.IncludeAnonymous ? this.buffer.parent : this.buffer.parent.nextSignificantParent();
1042 this.buffer = null;
1043 return this.yieldNode(parent);
1044 }
1045 /**
1046 @internal
1047 */
1048 sibling(dir) {
1049 if (!this.buffer)
1050 return !this._tree._parent ? false : this.yield(this._tree.index < 0 ? null : this._tree._parent.nextChild(this._tree.index + dir, dir, 0, 4, this.mode));
1051 let { buffer } = this.buffer, d = this.stack.length - 1;
1052 if (dir < 0) {
1053 let parentStart = d < 0 ? 0 : this.stack[d] + 4;
1054 if (this.index != parentStart)
1055 return this.yieldBuf(buffer.findChild(
1056 parentStart,
1057 this.index,
1058 -1,
1059 0,
1060 4
1061 /* Side.DontCare */
1062 ));
1063 } else {
1064 let after = buffer.buffer[this.index + 3];
1065 if (after < (d < 0 ? buffer.buffer.length : buffer.buffer[this.stack[d] + 3]))
1066 return this.yieldBuf(after);
1067 }
1068 return d < 0 ? this.yield(this.buffer.parent.nextChild(this.buffer.index + dir, dir, 0, 4, this.mode)) : false;
1069 }
1070 /**
1071 Move to this node's next sibling, if any.
1072 */
1073 nextSibling() {
1074 return this.sibling(1);
1075 }
1076 /**
1077 Move to this node's previous sibling, if any.
1078 */
1079 prevSibling() {
1080 return this.sibling(-1);
1081 }
1082 atLastNode(dir) {
1083 let index, parent, { buffer } = this;
1084 if (buffer) {
1085 if (dir > 0) {
1086 if (this.index < buffer.buffer.buffer.length)
1087 return false;
1088 } else {
1089 for (let i = 0; i < this.index; i++)
1090 if (buffer.buffer.buffer[i + 3] < this.index)
1091 return false;
1092 }
1093 ({ index, parent } = buffer);
1094 } else {
1095 ({ index, _parent: parent } = this._tree);
1096 }
1097 for (; parent; { index, _parent: parent } = parent) {
1098 if (index > -1)
1099 for (let i = index + dir, e = dir < 0 ? -1 : parent._tree.children.length; i != e; i += dir) {
1100 let child = parent._tree.children[i];
1101 if (this.mode & IterMode.IncludeAnonymous || child instanceof TreeBuffer || !child.type.isAnonymous || hasChild(child))
1102 return false;
1103 }
1104 }
1105 return true;
1106 }
1107 move(dir, enter) {
1108 if (enter && this.enterChild(
1109 dir,
1110 0,
1111 4
1112 /* Side.DontCare */
1113 ))
1114 return true;
1115 for (; ; ) {
1116 if (this.sibling(dir))
1117 return true;
1118 if (this.atLastNode(dir) || !this.parent())
1119 return false;
1120 }
1121 }
1122 /**
1123 Move to the next node in a
1124 [pre-order](https://en.wikipedia.org/wiki/Tree_traversal#Pre-order,_NLR)
1125 traversal, going from a node to its first child or, if the
1126 current node is empty or `enter` is false, its next sibling or
1127 the next sibling of the first parent node that has one.
1128 */
1129 next(enter = true) {
1130 return this.move(1, enter);
1131 }
1132 /**
1133 Move to the next node in a last-to-first pre-order traversal. A
1134 node is followed by its last child or, if it has none, its
1135 previous sibling or the previous sibling of the first parent
1136 node that has one.
1137 */
1138 prev(enter = true) {
1139 return this.move(-1, enter);
1140 }
1141 /**
1142 Move the cursor to the innermost node that covers `pos`. If
1143 `side` is -1, it will enter nodes that end at `pos`. If it is 1,
1144 it will enter nodes that start at `pos`.
1145 */
1146 moveTo(pos, side = 0) {
1147 while (this.from == this.to || (side < 1 ? this.from >= pos : this.from > pos) || (side > -1 ? this.to <= pos : this.to < pos))
1148 if (!this.parent())
1149 break;
1150 while (this.enterChild(1, pos, side)) {
1151 }
1152 return this;
1153 }
1154 /**
1155 Get a [syntax node](#common.SyntaxNode) at the cursor's current
1156 position.
1157 */
1158 get node() {
1159 if (!this.buffer)
1160 return this._tree;
1161 let cache = this.bufferNode, result = null, depth = 0;
1162 if (cache && cache.context == this.buffer) {
1163 scan: for (let index = this.index, d = this.stack.length; d >= 0; ) {
1164 for (let c = cache; c; c = c._parent)
1165 if (c.index == index) {
1166 if (index == this.index)
1167 return c;
1168 result = c;
1169 depth = d + 1;
1170 break scan;
1171 }
1172 index = this.stack[--d];
1173 }
1174 }
1175 for (let i = depth; i < this.stack.length; i++)
1176 result = new BufferNode(this.buffer, result, this.stack[i]);
1177 return this.bufferNode = new BufferNode(this.buffer, result, this.index);
1178 }
1179 /**
1180 Get the [tree](#common.Tree) that represents the current node, if
1181 any. Will return null when the node is in a [tree
1182 buffer](#common.TreeBuffer).
1183 */
1184 get tree() {
1185 return this.buffer ? null : this._tree._tree;
1186 }
1187 /**
1188 Iterate over the current node and all its descendants, calling
1189 `enter` when entering a node and `leave`, if given, when leaving
1190 one. When `enter` returns `false`, any children of that node are
1191 skipped, and `leave` isn't called for it.
1192 */
1193 iterate(enter, leave) {
1194 for (let depth = 0; ; ) {
1195 let mustLeave = false;
1196 if (this.type.isAnonymous || enter(this) !== false) {
1197 if (this.firstChild()) {
1198 depth++;
1199 continue;
1200 }
1201 if (!this.type.isAnonymous)
1202 mustLeave = true;
1203 }
1204 for (; ; ) {
1205 if (mustLeave && leave)
1206 leave(this);
1207 mustLeave = this.type.isAnonymous;
1208 if (!depth)
1209 return;
1210 if (this.nextSibling())
1211 break;
1212 this.parent();
1213 depth--;
1214 mustLeave = true;
1215 }
1216 }
1217 }
1218 /**
1219 Test whether the current node matches a given context—a sequence
1220 of direct parent node names. Empty strings in the context array
1221 are treated as wildcards.
1222 */
1223 matchContext(context) {
1224 if (!this.buffer)
1225 return matchNodeContext(this.node.parent, context);
1226 let { buffer } = this.buffer, { types } = buffer.set;
1227 for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) {
1228 if (d < 0)
1229 return matchNodeContext(this._tree, context, i);
1230 let type = types[buffer.buffer[this.stack[d]]];
1231 if (!type.isAnonymous) {
1232 if (context[i] && context[i] != type.name)
1233 return false;
1234 i--;
1235 }
1236 }
1237 return true;
1238 }
1239};
1240function hasChild(tree) {
1241 return tree.children.some((ch) => ch instanceof TreeBuffer || !ch.type.isAnonymous || hasChild(ch));
1242}
1243function buildTree(data) {
1244 var _a;
1245 let { buffer, nodeSet, maxBufferLength = DefaultBufferLength, reused = [], minRepeatType = nodeSet.types.length } = data;
1246 let cursor = Array.isArray(buffer) ? new FlatBufferCursor(buffer, buffer.length) : buffer;
1247 let types = nodeSet.types;
1248 let contextHash = 0, lookAhead = 0;
1249 function takeNode(parentStart, minPos, children2, positions2, inRepeat, depth) {
1250 let { id: id2, start, end, size } = cursor;
1251 let lookAheadAtStart = lookAhead, contextAtStart = contextHash;
1252 if (size < 0) {
1253 cursor.next();
1254 if (size == -1) {
1255 let node2 = reused[id2];
1256 children2.push(node2);
1257 positions2.push(start - parentStart);
1258 return;
1259 } else if (size == -3) {
1260 contextHash = id2;
1261 return;
1262 } else if (size == -4) {
1263 lookAhead = id2;
1264 return;
1265 } else {
1266 throw new RangeError(`Unrecognized record size: ${size}`);
1267 }
1268 }
1269 let type = types[id2], node, buffer2;
1270 let startPos = start - parentStart;
1271 if (end - start <= maxBufferLength && (buffer2 = findBufferSize(cursor.pos - minPos, inRepeat))) {
1272 let data2 = new Uint16Array(buffer2.size - buffer2.skip);
1273 let endPos = cursor.pos - buffer2.size, index = data2.length;
1274 while (cursor.pos > endPos)
1275 index = copyToBuffer(buffer2.start, data2, index);
1276 node = new TreeBuffer(data2, end - buffer2.start, nodeSet);
1277 startPos = buffer2.start - parentStart;
1278 } else {
1279 let endPos = cursor.pos - size;
1280 cursor.next();
1281 let localChildren = [], localPositions = [];
1282 let localInRepeat = id2 >= minRepeatType ? id2 : -1;
1283 let lastGroup = 0, lastEnd = end;
1284 while (cursor.pos > endPos) {
1285 if (localInRepeat >= 0 && cursor.id == localInRepeat && cursor.size >= 0) {
1286 if (cursor.end <= lastEnd - maxBufferLength) {
1287 makeRepeatLeaf(localChildren, localPositions, start, lastGroup, cursor.end, lastEnd, localInRepeat, lookAheadAtStart, contextAtStart);
1288 lastGroup = localChildren.length;
1289 lastEnd = cursor.end;
1290 }
1291 cursor.next();
1292 } else if (depth > 2500) {
1293 takeFlatNode(start, endPos, localChildren, localPositions);
1294 } else {
1295 takeNode(start, endPos, localChildren, localPositions, localInRepeat, depth + 1);
1296 }
1297 }
1298 if (localInRepeat >= 0 && lastGroup > 0 && lastGroup < localChildren.length)
1299 makeRepeatLeaf(localChildren, localPositions, start, lastGroup, start, lastEnd, localInRepeat, lookAheadAtStart, contextAtStart);
1300 localChildren.reverse();
1301 localPositions.reverse();
1302 if (localInRepeat > -1 && lastGroup > 0) {
1303 let make = makeBalanced(type, contextAtStart);
1304 node = balanceRange(type, localChildren, localPositions, 0, localChildren.length, 0, end - start, make, make);
1305 } else {
1306 node = makeTree(type, localChildren, localPositions, end - start, lookAheadAtStart - end, contextAtStart);
1307 }
1308 }
1309 children2.push(node);
1310 positions2.push(startPos);
1311 }
1312 function takeFlatNode(parentStart, minPos, children2, positions2) {
1313 let nodes = [];
1314 let nodeCount = 0, stopAt = -1;
1315 while (cursor.pos > minPos) {
1316 let { id: id2, start, end, size } = cursor;
1317 if (size > 4) {
1318 cursor.next();
1319 } else if (stopAt > -1 && start < stopAt) {
1320 break;
1321 } else {
1322 if (stopAt < 0)
1323 stopAt = end - maxBufferLength;
1324 nodes.push(id2, start, end);
1325 nodeCount++;
1326 cursor.next();
1327 }
1328 }
1329 if (nodeCount) {
1330 let buffer2 = new Uint16Array(nodeCount * 4);
1331 let start = nodes[nodes.length - 2];
1332 for (let i = nodes.length - 3, j = 0; i >= 0; i -= 3) {
1333 buffer2[j++] = nodes[i];
1334 buffer2[j++] = nodes[i + 1] - start;
1335 buffer2[j++] = nodes[i + 2] - start;
1336 buffer2[j++] = j;
1337 }
1338 children2.push(new TreeBuffer(buffer2, nodes[2] - start, nodeSet));
1339 positions2.push(start - parentStart);
1340 }
1341 }
1342 function makeBalanced(type, contextHash2) {
1343 return (children2, positions2, length2) => {
1344 let lookAhead2 = 0, lastI = children2.length - 1, last, lookAheadProp;
1345 if (lastI >= 0 && (last = children2[lastI]) instanceof Tree) {
1346 if (!lastI && last.type == type && last.length == length2)
1347 return last;
1348 if (lookAheadProp = last.prop(NodeProp.lookAhead))
1349 lookAhead2 = positions2[lastI] + last.length + lookAheadProp;
1350 }
1351 return makeTree(type, children2, positions2, length2, lookAhead2, contextHash2);
1352 };
1353 }
1354 function makeRepeatLeaf(children2, positions2, base, i, from, to, type, lookAhead2, contextHash2) {
1355 let localChildren = [], localPositions = [];
1356 while (children2.length > i) {
1357 localChildren.push(children2.pop());
1358 localPositions.push(positions2.pop() + base - from);
1359 }
1360 children2.push(makeTree(nodeSet.types[type], localChildren, localPositions, to - from, lookAhead2 - to, contextHash2));
1361 positions2.push(from - base);
1362 }
1363 function makeTree(type, children2, positions2, length2, lookAhead2, contextHash2, props) {
1364 if (contextHash2) {
1365 let pair2 = [NodeProp.contextHash, contextHash2];
1366 props = props ? [pair2].concat(props) : [pair2];
1367 }
1368 if (lookAhead2 > 25) {
1369 let pair2 = [NodeProp.lookAhead, lookAhead2];
1370 props = props ? [pair2].concat(props) : [pair2];
1371 }
1372 return new Tree(type, children2, positions2, length2, props);
1373 }
1374 function findBufferSize(maxSize, inRepeat) {
1375 let fork = cursor.fork();
1376 let size = 0, start = 0, skip = 0, minStart = fork.end - maxBufferLength;
1377 let result = { size: 0, start: 0, skip: 0 };
1378 scan: for (let minPos = fork.pos - maxSize; fork.pos > minPos; ) {
1379 let nodeSize2 = fork.size;
1380 if (fork.id == inRepeat && nodeSize2 >= 0) {
1381 result.size = size;
1382 result.start = start;
1383 result.skip = skip;
1384 skip += 4;
1385 size += 4;
1386 fork.next();
1387 continue;
1388 }
1389 let startPos = fork.pos - nodeSize2;
1390 if (nodeSize2 < 0 || startPos < minPos || fork.start < minStart)
1391 break;
1392 let localSkipped = fork.id >= minRepeatType ? 4 : 0;
1393 let nodeStart = fork.start;
1394 fork.next();
1395 while (fork.pos > startPos) {
1396 if (fork.size < 0) {
1397 if (fork.size == -3 || fork.size == -4)
1398 localSkipped += 4;
1399 else
1400 break scan;
1401 } else if (fork.id >= minRepeatType) {
1402 localSkipped += 4;
1403 }
1404 fork.next();
1405 }
1406 start = nodeStart;
1407 size += nodeSize2;
1408 skip += localSkipped;
1409 }
1410 if (inRepeat < 0 || size == maxSize) {
1411 result.size = size;
1412 result.start = start;
1413 result.skip = skip;
1414 }
1415 return result.size > 4 ? result : void 0;
1416 }
1417 function copyToBuffer(bufferStart, buffer2, index) {
1418 let { id: id2, start, end, size } = cursor;
1419 cursor.next();
1420 if (size >= 0 && id2 < minRepeatType) {
1421 let startIndex = index;
1422 if (size > 4) {
1423 let endPos = cursor.pos - (size - 4);
1424 while (cursor.pos > endPos)
1425 index = copyToBuffer(bufferStart, buffer2, index);
1426 }
1427 buffer2[--index] = startIndex;
1428 buffer2[--index] = end - bufferStart;
1429 buffer2[--index] = start - bufferStart;
1430 buffer2[--index] = id2;
1431 } else if (size == -3) {
1432 contextHash = id2;
1433 } else if (size == -4) {
1434 lookAhead = id2;
1435 }
1436 return index;
1437 }
1438 let children = [], positions = [];
1439 while (cursor.pos > 0)
1440 takeNode(data.start || 0, data.bufferStart || 0, children, positions, -1, 0);
1441 let length = (_a = data.length) !== null && _a !== void 0 ? _a : children.length ? positions[0] + children[0].length : 0;
1442 return new Tree(types[data.topID], children.reverse(), positions.reverse(), length);
1443}
1444var nodeSizeCache = /* @__PURE__ */ new WeakMap();
1445function nodeSize(balanceType, node) {
1446 if (!balanceType.isAnonymous || node instanceof TreeBuffer || node.type != balanceType)
1447 return 1;
1448 let size = nodeSizeCache.get(node);
1449 if (size == null) {
1450 size = 1;
1451 for (let child of node.children) {
1452 if (child.type != balanceType || !(child instanceof Tree)) {
1453 size = 1;
1454 break;
1455 }
1456 size += nodeSize(balanceType, child);
1457 }
1458 nodeSizeCache.set(node, size);
1459 }
1460 return size;
1461}
1462function balanceRange(balanceType, children, positions, from, to, start, length, mkTop, mkTree) {
1463 let total = 0;
1464 for (let i = from; i < to; i++)
1465 total += nodeSize(balanceType, children[i]);
1466 let maxChild = Math.ceil(
1467 total * 1.5 / 8
1468 /* Balance.BranchFactor */
1469 );
1470 let localChildren = [], localPositions = [];
1471 function divide(children2, positions2, from2, to2, offset) {
1472 for (let i = from2; i < to2; ) {
1473 let groupFrom = i, groupStart = positions2[i], groupSize = nodeSize(balanceType, children2[i]);
1474 i++;
1475 for (; i < to2; i++) {
1476 let nextSize = nodeSize(balanceType, children2[i]);
1477 if (groupSize + nextSize >= maxChild)
1478 break;
1479 groupSize += nextSize;
1480 }
1481 if (i == groupFrom + 1) {
1482 if (groupSize > maxChild) {
1483 let only = children2[groupFrom];
1484 divide(only.children, only.positions, 0, only.children.length, positions2[groupFrom] + offset);
1485 continue;
1486 }
1487 localChildren.push(children2[groupFrom]);
1488 } else {
1489 let length2 = positions2[i - 1] + children2[i - 1].length - groupStart;
1490 localChildren.push(balanceRange(balanceType, children2, positions2, groupFrom, i, groupStart, length2, null, mkTree));
1491 }
1492 localPositions.push(groupStart + offset - start);
1493 }
1494 }
1495 divide(children, positions, from, to, 0);
1496 return (mkTop || mkTree)(localChildren, localPositions, length);
1497}
1498var Parser = class {
1499 /**
1500 Start a parse, returning a [partial parse](#common.PartialParse)
1501 object. [`fragments`](#common.TreeFragment) can be passed in to
1502 make the parse incremental.
1503
1504 By default, the entire input is parsed. You can pass `ranges`,
1505 which should be a sorted array of non-empty, non-overlapping
1506 ranges, to parse only those ranges. The tree returned in that
1507 case will start at `ranges[0].from`.
1508 */
1509 startParse(input, fragments, ranges) {
1510 if (typeof input == "string")
1511 input = new StringInput(input);
1512 ranges = !ranges ? [new Range(0, input.length)] : ranges.length ? ranges.map((r) => new Range(r.from, r.to)) : [new Range(0, 0)];
1513 return this.createParse(input, fragments || [], ranges);
1514 }
1515 /**
1516 Run a full parse, returning the resulting tree.
1517 */
1518 parse(input, fragments, ranges) {
1519 let parse = this.startParse(input, fragments, ranges);
1520 for (; ; ) {
1521 let done = parse.advance();
1522 if (done)
1523 return done;
1524 }
1525 }
1526};
1527var StringInput = class {
1528 constructor(string2) {
1529 this.string = string2;
1530 }
1531 get length() {
1532 return this.string.length;
1533 }
1534 chunk(from) {
1535 return this.string.slice(from);
1536 }
1537 get lineChunks() {
1538 return false;
1539 }
1540 read(from, to) {
1541 return this.string.slice(from, to);
1542 }
1543};
1544var stoppedInner = new NodeProp({ perNode: true });
1545
1546// node_modules/@lezer/lr/dist/index.js
1547var Stack = class _Stack {
1548 /**
1549 @internal
1550 */
1551 constructor(p, stack, state, reducePos, pos, score, buffer, bufferBase, curContext, lookAhead = 0, parent) {
1552 this.p = p;
1553 this.stack = stack;
1554 this.state = state;
1555 this.reducePos = reducePos;
1556 this.pos = pos;
1557 this.score = score;
1558 this.buffer = buffer;
1559 this.bufferBase = bufferBase;
1560 this.curContext = curContext;
1561 this.lookAhead = lookAhead;
1562 this.parent = parent;
1563 }
1564 /**
1565 @internal
1566 */
1567 toString() {
1568 return `[${this.stack.filter((_, i) => i % 3 == 0).concat(this.state)}]@${this.pos}${this.score ? "!" + this.score : ""}`;
1569 }
1570 // Start an empty stack
1571 /**
1572 @internal
1573 */
1574 static start(p, state, pos = 0) {
1575 let cx = p.parser.context;
1576 return new _Stack(p, [], state, pos, pos, 0, [], 0, cx ? new StackContext(cx, cx.start) : null, 0, null);
1577 }
1578 /**
1579 The stack's current [context](#lr.ContextTracker) value, if
1580 any. Its type will depend on the context tracker's type
1581 parameter, or it will be `null` if there is no context
1582 tracker.
1583 */
1584 get context() {
1585 return this.curContext ? this.curContext.context : null;
1586 }
1587 // Push a state onto the stack, tracking its start position as well
1588 // as the buffer base at that point.
1589 /**
1590 @internal
1591 */
1592 pushState(state, start) {
1593 this.stack.push(this.state, start, this.bufferBase + this.buffer.length);
1594 this.state = state;
1595 }
1596 // Apply a reduce action
1597 /**
1598 @internal
1599 */
1600 reduce(action) {
1601 var _a;
1602 let depth = action >> 19, type = action & 65535;
1603 let { parser: parser2 } = this.p;
1604 let lookaheadRecord = this.reducePos < this.pos - 25 && this.setLookAhead(this.pos);
1605 let dPrec = parser2.dynamicPrecedence(type);
1606 if (dPrec)
1607 this.score += dPrec;
1608 if (depth == 0) {
1609 this.pushState(parser2.getGoto(this.state, type, true), this.reducePos);
1610 if (type < parser2.minRepeatTerm)
1611 this.storeNode(type, this.reducePos, this.reducePos, lookaheadRecord ? 8 : 4, true);
1612 this.reduceContext(type, this.reducePos);
1613 return;
1614 }
1615 let base = this.stack.length - (depth - 1) * 3 - (action & 262144 ? 6 : 0);
1616 let start = base ? this.stack[base - 2] : this.p.ranges[0].from, size = this.reducePos - start;
1617 if (size >= 2e3 && !((_a = this.p.parser.nodeSet.types[type]) === null || _a === void 0 ? void 0 : _a.isAnonymous)) {
1618 if (start == this.p.lastBigReductionStart) {
1619 this.p.bigReductionCount++;
1620 this.p.lastBigReductionSize = size;
1621 } else if (this.p.lastBigReductionSize < size) {
1622 this.p.bigReductionCount = 1;
1623 this.p.lastBigReductionStart = start;
1624 this.p.lastBigReductionSize = size;
1625 }
1626 }
1627 let bufferBase = base ? this.stack[base - 1] : 0, count = this.bufferBase + this.buffer.length - bufferBase;
1628 if (type < parser2.minRepeatTerm || action & 131072) {
1629 let pos = parser2.stateFlag(
1630 this.state,
1631 1
1632 /* StateFlag.Skipped */
1633 ) ? this.pos : this.reducePos;
1634 this.storeNode(type, start, pos, count + 4, true);
1635 }
1636 if (action & 262144) {
1637 this.state = this.stack[base];
1638 } else {
1639 let baseStateID = this.stack[base - 3];
1640 this.state = parser2.getGoto(baseStateID, type, true);
1641 }
1642 while (this.stack.length > base)
1643 this.stack.pop();
1644 this.reduceContext(type, start);
1645 }
1646 // Shift a value into the buffer
1647 /**
1648 @internal
1649 */
1650 storeNode(term, start, end, size = 4, mustSink = false) {
1651 if (term == 0 && (!this.stack.length || this.stack[this.stack.length - 1] < this.buffer.length + this.bufferBase)) {
1652 let cur = this, top = this.buffer.length;
1653 if (top == 0 && cur.parent) {
1654 top = cur.bufferBase - cur.parent.bufferBase;
1655 cur = cur.parent;
1656 }
1657 if (top > 0 && cur.buffer[top - 4] == 0 && cur.buffer[top - 1] > -1) {
1658 if (start == end)
1659 return;
1660 if (cur.buffer[top - 2] >= start) {
1661 cur.buffer[top - 2] = end;
1662 return;
1663 }
1664 }
1665 }
1666 if (!mustSink || this.pos == end) {
1667 this.buffer.push(term, start, end, size);
1668 } else {
1669 let index = this.buffer.length;
1670 if (index > 0 && (this.buffer[index - 4] != 0 || this.buffer[index - 1] < 0)) {
1671 let mustMove = false;
1672 for (let scan = index; scan > 0 && this.buffer[scan - 2] > end; scan -= 4) {
1673 if (this.buffer[scan - 1] >= 0) {
1674 mustMove = true;
1675 break;
1676 }
1677 }
1678 if (mustMove)
1679 while (index > 0 && this.buffer[index - 2] > end) {
1680 this.buffer[index] = this.buffer[index - 4];
1681 this.buffer[index + 1] = this.buffer[index - 3];
1682 this.buffer[index + 2] = this.buffer[index - 2];
1683 this.buffer[index + 3] = this.buffer[index - 1];
1684 index -= 4;
1685 if (size > 4)
1686 size -= 4;
1687 }
1688 }
1689 this.buffer[index] = term;
1690 this.buffer[index + 1] = start;
1691 this.buffer[index + 2] = end;
1692 this.buffer[index + 3] = size;
1693 }
1694 }
1695 // Apply a shift action
1696 /**
1697 @internal
1698 */
1699 shift(action, type, start, end) {
1700 if (action & 131072) {
1701 this.pushState(action & 65535, this.pos);
1702 } else if ((action & 262144) == 0) {
1703 let nextState = action, { parser: parser2 } = this.p;
1704 this.pos = end;
1705 let skipped = parser2.stateFlag(
1706 nextState,
1707 1
1708 /* StateFlag.Skipped */
1709 );
1710 if (!skipped && (end > start || type <= parser2.maxNode))
1711 this.reducePos = end;
1712 this.pushState(nextState, skipped ? start : Math.min(start, this.reducePos));
1713 this.shiftContext(type, start);
1714 if (type <= parser2.maxNode)
1715 this.buffer.push(type, start, end, 4);
1716 } else {
1717 this.pos = end;
1718 this.shiftContext(type, start);
1719 if (type <= this.p.parser.maxNode)
1720 this.buffer.push(type, start, end, 4);
1721 }
1722 }
1723 // Apply an action
1724 /**
1725 @internal
1726 */
1727 apply(action, next, nextStart, nextEnd) {
1728 if (action & 65536)
1729 this.reduce(action);
1730 else
1731 this.shift(action, next, nextStart, nextEnd);
1732 }
1733 // Add a prebuilt (reused) node into the buffer.
1734 /**
1735 @internal
1736 */
1737 useNode(value, next) {
1738 let index = this.p.reused.length - 1;
1739 if (index < 0 || this.p.reused[index] != value) {
1740 this.p.reused.push(value);
1741 index++;
1742 }
1743 let start = this.pos;
1744 this.reducePos = this.pos = start + value.length;
1745 this.pushState(next, start);
1746 this.buffer.push(
1747 index,
1748 start,
1749 this.reducePos,
1750 -1
1751 /* size == -1 means this is a reused value */
1752 );
1753 if (this.curContext)
1754 this.updateContext(this.curContext.tracker.reuse(this.curContext.context, value, this, this.p.stream.reset(this.pos - value.length)));
1755 }
1756 // Split the stack. Due to the buffer sharing and the fact
1757 // that `this.stack` tends to stay quite shallow, this isn't very
1758 // expensive.
1759 /**
1760 @internal
1761 */
1762 split() {
1763 let parent = this;
1764 let off = parent.buffer.length;
1765 while (off > 0 && parent.buffer[off - 2] > parent.reducePos)
1766 off -= 4;
1767 let buffer = parent.buffer.slice(off), base = parent.bufferBase + off;
1768 while (parent && base == parent.bufferBase)
1769 parent = parent.parent;
1770 return new _Stack(this.p, this.stack.slice(), this.state, this.reducePos, this.pos, this.score, buffer, base, this.curContext, this.lookAhead, parent);
1771 }
1772 // Try to recover from an error by 'deleting' (ignoring) one token.
1773 /**
1774 @internal
1775 */
1776 recoverByDelete(next, nextEnd) {
1777 let isNode = next <= this.p.parser.maxNode;
1778 if (isNode)
1779 this.storeNode(next, this.pos, nextEnd, 4);
1780 this.storeNode(0, this.pos, nextEnd, isNode ? 8 : 4);
1781 this.pos = this.reducePos = nextEnd;
1782 this.score -= 190;
1783 }
1784 /**
1785 Check if the given term would be able to be shifted (optionally
1786 after some reductions) on this stack. This can be useful for
1787 external tokenizers that want to make sure they only provide a
1788 given token when it applies.
1789 */
1790 canShift(term) {
1791 for (let sim = new SimulatedStack(this); ; ) {
1792 let action = this.p.parser.stateSlot(
1793 sim.state,
1794 4
1795 /* ParseState.DefaultReduce */
1796 ) || this.p.parser.hasAction(sim.state, term);
1797 if (action == 0)
1798 return false;
1799 if ((action & 65536) == 0)
1800 return true;
1801 sim.reduce(action);
1802 }
1803 }
1804 // Apply up to Recover.MaxNext recovery actions that conceptually
1805 // inserts some missing token or rule.
1806 /**
1807 @internal
1808 */
1809 recoverByInsert(next) {
1810 if (this.stack.length >= 300)
1811 return [];
1812 let nextStates = this.p.parser.nextStates(this.state);
1813 if (nextStates.length > 4 << 1 || this.stack.length >= 120) {
1814 let best = [];
1815 for (let i = 0, s; i < nextStates.length; i += 2) {
1816 if ((s = nextStates[i + 1]) != this.state && this.p.parser.hasAction(s, next))
1817 best.push(nextStates[i], s);
1818 }
1819 if (this.stack.length < 120)
1820 for (let i = 0; best.length < 4 << 1 && i < nextStates.length; i += 2) {
1821 let s = nextStates[i + 1];
1822 if (!best.some((v, i2) => i2 & 1 && v == s))
1823 best.push(nextStates[i], s);
1824 }
1825 nextStates = best;
1826 }
1827 let result = [];
1828 for (let i = 0; i < nextStates.length && result.length < 4; i += 2) {
1829 let s = nextStates[i + 1];
1830 if (s == this.state)
1831 continue;
1832 let stack = this.split();
1833 stack.pushState(s, this.pos);
1834 stack.storeNode(0, stack.pos, stack.pos, 4, true);
1835 stack.shiftContext(nextStates[i], this.pos);
1836 stack.reducePos = this.pos;
1837 stack.score -= 200;
1838 result.push(stack);
1839 }
1840 return result;
1841 }
1842 // Force a reduce, if possible. Return false if that can't
1843 // be done.
1844 /**
1845 @internal
1846 */
1847 forceReduce() {
1848 let { parser: parser2 } = this.p;
1849 let reduce = parser2.stateSlot(
1850 this.state,
1851 5
1852 /* ParseState.ForcedReduce */
1853 );
1854 if ((reduce & 65536) == 0)
1855 return false;
1856 if (!parser2.validAction(this.state, reduce)) {
1857 let depth = reduce >> 19, term = reduce & 65535;
1858 let target = this.stack.length - depth * 3;
1859 if (target < 0 || parser2.getGoto(this.stack[target], term, false) < 0) {
1860 let backup = this.findForcedReduction();
1861 if (backup == null)
1862 return false;
1863 reduce = backup;
1864 }
1865 this.storeNode(0, this.pos, this.pos, 4, true);
1866 this.score -= 100;
1867 }
1868 this.reducePos = this.pos;
1869 this.reduce(reduce);
1870 return true;
1871 }
1872 /**
1873 Try to scan through the automaton to find some kind of reduction
1874 that can be applied. Used when the regular ForcedReduce field
1875 isn't a valid action. @internal
1876 */
1877 findForcedReduction() {
1878 let { parser: parser2 } = this.p, seen = [];
1879 let explore = (state, depth) => {
1880 if (seen.includes(state))
1881 return;
1882 seen.push(state);
1883 return parser2.allActions(state, (action) => {
1884 if (action & (262144 | 131072)) ;
1885 else if (action & 65536) {
1886 let rDepth = (action >> 19) - depth;
1887 if (rDepth > 1) {
1888 let term = action & 65535, target = this.stack.length - rDepth * 3;
1889 if (target >= 0 && parser2.getGoto(this.stack[target], term, false) >= 0)
1890 return rDepth << 19 | 65536 | term;
1891 }
1892 } else {
1893 let found = explore(action, depth + 1);
1894 if (found != null)
1895 return found;
1896 }
1897 });
1898 };
1899 return explore(this.state, 0);
1900 }
1901 /**
1902 @internal
1903 */
1904 forceAll() {
1905 while (!this.p.parser.stateFlag(
1906 this.state,
1907 2
1908 /* StateFlag.Accepting */
1909 )) {
1910 if (!this.forceReduce()) {
1911 this.storeNode(0, this.pos, this.pos, 4, true);
1912 break;
1913 }
1914 }
1915 return this;
1916 }
1917 /**
1918 Check whether this state has no further actions (assumed to be a direct descendant of the
1919 top state, since any other states must be able to continue
1920 somehow). @internal
1921 */
1922 get deadEnd() {
1923 if (this.stack.length != 3)
1924 return false;
1925 let { parser: parser2 } = this.p;
1926 return parser2.data[parser2.stateSlot(
1927 this.state,
1928 1
1929 /* ParseState.Actions */
1930 )] == 65535 && !parser2.stateSlot(
1931 this.state,
1932 4
1933 /* ParseState.DefaultReduce */
1934 );
1935 }
1936 /**
1937 Restart the stack (put it back in its start state). Only safe
1938 when this.stack.length == 3 (state is directly below the top
1939 state). @internal
1940 */
1941 restart() {
1942 this.storeNode(0, this.pos, this.pos, 4, true);
1943 this.state = this.stack[0];
1944 this.stack.length = 0;
1945 }
1946 /**
1947 @internal
1948 */
1949 sameState(other) {
1950 if (this.state != other.state || this.stack.length != other.stack.length)
1951 return false;
1952 for (let i = 0; i < this.stack.length; i += 3)
1953 if (this.stack[i] != other.stack[i])
1954 return false;
1955 return true;
1956 }
1957 /**
1958 Get the parser used by this stack.
1959 */
1960 get parser() {
1961 return this.p.parser;
1962 }
1963 /**
1964 Test whether a given dialect (by numeric ID, as exported from
1965 the terms file) is enabled.
1966 */
1967 dialectEnabled(dialectID) {
1968 return this.p.parser.dialect.flags[dialectID];
1969 }
1970 shiftContext(term, start) {
1971 if (this.curContext)
1972 this.updateContext(this.curContext.tracker.shift(this.curContext.context, term, this, this.p.stream.reset(start)));
1973 }
1974 reduceContext(term, start) {
1975 if (this.curContext)
1976 this.updateContext(this.curContext.tracker.reduce(this.curContext.context, term, this, this.p.stream.reset(start)));
1977 }
1978 /**
1979 @internal
1980 */
1981 emitContext() {
1982 let last = this.buffer.length - 1;
1983 if (last < 0 || this.buffer[last] != -3)
1984 this.buffer.push(this.curContext.hash, this.pos, this.pos, -3);
1985 }
1986 /**
1987 @internal
1988 */
1989 emitLookAhead() {
1990 let last = this.buffer.length - 1;
1991 if (last < 0 || this.buffer[last] != -4)
1992 this.buffer.push(this.lookAhead, this.pos, this.pos, -4);
1993 }
1994 updateContext(context) {
1995 if (context != this.curContext.context) {
1996 let newCx = new StackContext(this.curContext.tracker, context);
1997 if (newCx.hash != this.curContext.hash)
1998 this.emitContext();
1999 this.curContext = newCx;
2000 }
2001 }
2002 /**
2003 @internal
2004 */
2005 setLookAhead(lookAhead) {
2006 if (lookAhead <= this.lookAhead)
2007 return false;
2008 this.emitLookAhead();
2009 this.lookAhead = lookAhead;
2010 return true;
2011 }
2012 /**
2013 @internal
2014 */
2015 close() {
2016 if (this.curContext && this.curContext.tracker.strict)
2017 this.emitContext();
2018 if (this.lookAhead > 0)
2019 this.emitLookAhead();
2020 }
2021};
2022var StackContext = class {
2023 constructor(tracker, context) {
2024 this.tracker = tracker;
2025 this.context = context;
2026 this.hash = tracker.strict ? tracker.hash(context) : 0;
2027 }
2028};
2029var SimulatedStack = class {
2030 constructor(start) {
2031 this.start = start;
2032 this.state = start.state;
2033 this.stack = start.stack;
2034 this.base = this.stack.length;
2035 }
2036 reduce(action) {
2037 let term = action & 65535, depth = action >> 19;
2038 if (depth == 0) {
2039 if (this.stack == this.start.stack)
2040 this.stack = this.stack.slice();
2041 this.stack.push(this.state, 0, 0);
2042 this.base += 3;
2043 } else {
2044 this.base -= (depth - 1) * 3;
2045 }
2046 let goto = this.start.p.parser.getGoto(this.stack[this.base - 3], term, true);
2047 this.state = goto;
2048 }
2049};
2050var StackBufferCursor = class _StackBufferCursor {
2051 constructor(stack, pos, index) {
2052 this.stack = stack;
2053 this.pos = pos;
2054 this.index = index;
2055 this.buffer = stack.buffer;
2056 if (this.index == 0)
2057 this.maybeNext();
2058 }
2059 static create(stack, pos = stack.bufferBase + stack.buffer.length) {
2060 return new _StackBufferCursor(stack, pos, pos - stack.bufferBase);
2061 }
2062 maybeNext() {
2063 let next = this.stack.parent;
2064 if (next != null) {
2065 this.index = this.stack.bufferBase - next.bufferBase;
2066 this.stack = next;
2067 this.buffer = next.buffer;
2068 }
2069 }
2070 get id() {
2071 return this.buffer[this.index - 4];
2072 }
2073 get start() {
2074 return this.buffer[this.index - 3];
2075 }
2076 get end() {
2077 return this.buffer[this.index - 2];
2078 }
2079 get size() {
2080 return this.buffer[this.index - 1];
2081 }
2082 next() {
2083 this.index -= 4;
2084 this.pos -= 4;
2085 if (this.index == 0)
2086 this.maybeNext();
2087 }
2088 fork() {
2089 return new _StackBufferCursor(this.stack, this.pos, this.index);
2090 }
2091};
2092function decodeArray(input, Type = Uint16Array) {
2093 if (typeof input != "string")
2094 return input;
2095 let array = null;
2096 for (let pos = 0, out = 0; pos < input.length; ) {
2097 let value = 0;
2098 for (; ; ) {
2099 let next = input.charCodeAt(pos++), stop = false;
2100 if (next == 126) {
2101 value = 65535;
2102 break;
2103 }
2104 if (next >= 92)
2105 next--;
2106 if (next >= 34)
2107 next--;
2108 let digit = next - 32;
2109 if (digit >= 46) {
2110 digit -= 46;
2111 stop = true;
2112 }
2113 value += digit;
2114 if (stop)
2115 break;
2116 value *= 46;
2117 }
2118 if (array)
2119 array[out++] = value;
2120 else
2121 array = new Type(value);
2122 }
2123 return array;
2124}
2125var CachedToken = class {
2126 constructor() {
2127 this.start = -1;
2128 this.value = -1;
2129 this.end = -1;
2130 this.extended = -1;
2131 this.lookAhead = 0;
2132 this.mask = 0;
2133 this.context = 0;
2134 }
2135};
2136var nullToken = new CachedToken();
2137var InputStream = class {
2138 /**
2139 @internal
2140 */
2141 constructor(input, ranges) {
2142 this.input = input;
2143 this.ranges = ranges;
2144 this.chunk = "";
2145 this.chunkOff = 0;
2146 this.chunk2 = "";
2147 this.chunk2Pos = 0;
2148 this.next = -1;
2149 this.token = nullToken;
2150 this.rangeIndex = 0;
2151 this.pos = this.chunkPos = ranges[0].from;
2152 this.range = ranges[0];
2153 this.end = ranges[ranges.length - 1].to;
2154 this.readNext();
2155 }
2156 /**
2157 @internal
2158 */
2159 resolveOffset(offset, assoc) {
2160 let range = this.range, index = this.rangeIndex;
2161 let pos = this.pos + offset;
2162 while (pos < range.from) {
2163 if (!index)
2164 return null;
2165 let next = this.ranges[--index];
2166 pos -= range.from - next.to;
2167 range = next;
2168 }
2169 while (assoc < 0 ? pos > range.to : pos >= range.to) {
2170 if (index == this.ranges.length - 1)
2171 return null;
2172 let next = this.ranges[++index];
2173 pos += next.from - range.to;
2174 range = next;
2175 }
2176 return pos;
2177 }
2178 /**
2179 @internal
2180 */
2181 clipPos(pos) {
2182 if (pos >= this.range.from && pos < this.range.to)
2183 return pos;
2184 for (let range of this.ranges)
2185 if (range.to > pos)
2186 return Math.max(pos, range.from);
2187 return this.end;
2188 }
2189 /**
2190 Look at a code unit near the stream position. `.peek(0)` equals
2191 `.next`, `.peek(-1)` gives you the previous character, and so
2192 on.
2193
2194 Note that looking around during tokenizing creates dependencies
2195 on potentially far-away content, which may reduce the
2196 effectiveness incremental parsing—when looking forward—or even
2197 cause invalid reparses when looking backward more than 25 code
2198 units, since the library does not track lookbehind.
2199 */
2200 peek(offset) {
2201 let idx = this.chunkOff + offset, pos, result;
2202 if (idx >= 0 && idx < this.chunk.length) {
2203 pos = this.pos + offset;
2204 result = this.chunk.charCodeAt(idx);
2205 } else {
2206 let resolved = this.resolveOffset(offset, 1);
2207 if (resolved == null)
2208 return -1;
2209 pos = resolved;
2210 if (pos >= this.chunk2Pos && pos < this.chunk2Pos + this.chunk2.length) {
2211 result = this.chunk2.charCodeAt(pos - this.chunk2Pos);
2212 } else {
2213 let i = this.rangeIndex, range = this.range;
2214 while (range.to <= pos)
2215 range = this.ranges[++i];
2216 this.chunk2 = this.input.chunk(this.chunk2Pos = pos);
2217 if (pos + this.chunk2.length > range.to)
2218 this.chunk2 = this.chunk2.slice(0, range.to - pos);
2219 result = this.chunk2.charCodeAt(0);
2220 }
2221 }
2222 if (pos >= this.token.lookAhead)
2223 this.token.lookAhead = pos + 1;
2224 return result;
2225 }
2226 /**
2227 Accept a token. By default, the end of the token is set to the
2228 current stream position, but you can pass an offset (relative to
2229 the stream position) to change that.
2230 */
2231 acceptToken(token, endOffset = 0) {
2232 let end = endOffset ? this.resolveOffset(endOffset, -1) : this.pos;
2233 if (end == null || end < this.token.start)
2234 throw new RangeError("Token end out of bounds");
2235 this.token.value = token;
2236 this.token.end = end;
2237 }
2238 /**
2239 Accept a token ending at a specific given position.
2240 */
2241 acceptTokenTo(token, endPos) {
2242 this.token.value = token;
2243 this.token.end = endPos;
2244 }
2245 getChunk() {
2246 if (this.pos >= this.chunk2Pos && this.pos < this.chunk2Pos + this.chunk2.length) {
2247 let { chunk, chunkPos } = this;
2248 this.chunk = this.chunk2;
2249 this.chunkPos = this.chunk2Pos;
2250 this.chunk2 = chunk;
2251 this.chunk2Pos = chunkPos;
2252 this.chunkOff = this.pos - this.chunkPos;
2253 } else {
2254 this.chunk2 = this.chunk;
2255 this.chunk2Pos = this.chunkPos;
2256 let nextChunk = this.input.chunk(this.pos);
2257 let end = this.pos + nextChunk.length;
2258 this.chunk = end > this.range.to ? nextChunk.slice(0, this.range.to - this.pos) : nextChunk;
2259 this.chunkPos = this.pos;
2260 this.chunkOff = 0;
2261 }
2262 }
2263 readNext() {
2264 if (this.chunkOff >= this.chunk.length) {
2265 this.getChunk();
2266 if (this.chunkOff == this.chunk.length)
2267 return this.next = -1;
2268 }
2269 return this.next = this.chunk.charCodeAt(this.chunkOff);
2270 }
2271 /**
2272 Move the stream forward N (defaults to 1) code units. Returns
2273 the new value of [`next`](#lr.InputStream.next).
2274 */
2275 advance(n = 1) {
2276 this.chunkOff += n;
2277 while (this.pos + n >= this.range.to) {
2278 if (this.rangeIndex == this.ranges.length - 1)
2279 return this.setDone();
2280 n -= this.range.to - this.pos;
2281 this.range = this.ranges[++this.rangeIndex];
2282 this.pos = this.range.from;
2283 }
2284 this.pos += n;
2285 if (this.pos >= this.token.lookAhead)
2286 this.token.lookAhead = this.pos + 1;
2287 return this.readNext();
2288 }
2289 setDone() {
2290 this.pos = this.chunkPos = this.end;
2291 this.range = this.ranges[this.rangeIndex = this.ranges.length - 1];
2292 this.chunk = "";
2293 return this.next = -1;
2294 }
2295 /**
2296 @internal
2297 */
2298 reset(pos, token) {
2299 if (token) {
2300 this.token = token;
2301 token.start = pos;
2302 token.lookAhead = pos + 1;
2303 token.value = token.extended = -1;
2304 } else {
2305 this.token = nullToken;
2306 }
2307 if (this.pos != pos) {
2308 this.pos = pos;
2309 if (pos == this.end) {
2310 this.setDone();
2311 return this;
2312 }
2313 while (pos < this.range.from)
2314 this.range = this.ranges[--this.rangeIndex];
2315 while (pos >= this.range.to)
2316 this.range = this.ranges[++this.rangeIndex];
2317 if (pos >= this.chunkPos && pos < this.chunkPos + this.chunk.length) {
2318 this.chunkOff = pos - this.chunkPos;
2319 } else {
2320 this.chunk = "";
2321 this.chunkOff = 0;
2322 }
2323 this.readNext();
2324 }
2325 return this;
2326 }
2327 /**
2328 @internal
2329 */
2330 read(from, to) {
2331 if (from >= this.chunkPos && to <= this.chunkPos + this.chunk.length)
2332 return this.chunk.slice(from - this.chunkPos, to - this.chunkPos);
2333 if (from >= this.chunk2Pos && to <= this.chunk2Pos + this.chunk2.length)
2334 return this.chunk2.slice(from - this.chunk2Pos, to - this.chunk2Pos);
2335 if (from >= this.range.from && to <= this.range.to)
2336 return this.input.read(from, to);
2337 let result = "";
2338 for (let r of this.ranges) {
2339 if (r.from >= to)
2340 break;
2341 if (r.to > from)
2342 result += this.input.read(Math.max(r.from, from), Math.min(r.to, to));
2343 }
2344 return result;
2345 }
2346};
2347var TokenGroup = class {
2348 constructor(data, id2) {
2349 this.data = data;
2350 this.id = id2;
2351 }
2352 token(input, stack) {
2353 let { parser: parser2 } = stack.p;
2354 readToken(this.data, input, stack, this.id, parser2.data, parser2.tokenPrecTable);
2355 }
2356};
2357TokenGroup.prototype.contextual = TokenGroup.prototype.fallback = TokenGroup.prototype.extend = false;
2358var LocalTokenGroup = class {
2359 constructor(data, precTable, elseToken) {
2360 this.precTable = precTable;
2361 this.elseToken = elseToken;
2362 this.data = typeof data == "string" ? decodeArray(data) : data;
2363 }
2364 token(input, stack) {
2365 let start = input.pos, skipped = 0;
2366 for (; ; ) {
2367 let atEof = input.next < 0, nextPos = input.resolveOffset(1, 1);
2368 readToken(this.data, input, stack, 0, this.data, this.precTable);
2369 if (input.token.value > -1)
2370 break;
2371 if (this.elseToken == null)
2372 return;
2373 if (!atEof)
2374 skipped++;
2375 if (nextPos == null)
2376 break;
2377 input.reset(nextPos, input.token);
2378 }
2379 if (skipped) {
2380 input.reset(start, input.token);
2381 input.acceptToken(this.elseToken, skipped);
2382 }
2383 }
2384};
2385LocalTokenGroup.prototype.contextual = TokenGroup.prototype.fallback = TokenGroup.prototype.extend = false;
2386var ExternalTokenizer = class {
2387 /**
2388 Create a tokenizer. The first argument is the function that,
2389 given an input stream, scans for the types of tokens it
2390 recognizes at the stream's position, and calls
2391 [`acceptToken`](#lr.InputStream.acceptToken) when it finds
2392 one.
2393 */
2394 constructor(token, options = {}) {
2395 this.token = token;
2396 this.contextual = !!options.contextual;
2397 this.fallback = !!options.fallback;
2398 this.extend = !!options.extend;
2399 }
2400};
2401function readToken(data, input, stack, group, precTable, precOffset) {
2402 let state = 0, groupMask = 1 << group, { dialect } = stack.p.parser;
2403 scan: for (; ; ) {
2404 if ((groupMask & data[state]) == 0)
2405 break;
2406 let accEnd = data[state + 1];
2407 for (let i = state + 3; i < accEnd; i += 2)
2408 if ((data[i + 1] & groupMask) > 0) {
2409 let term = data[i];
2410 if (dialect.allows(term) && (input.token.value == -1 || input.token.value == term || overrides(term, input.token.value, precTable, precOffset))) {
2411 input.acceptToken(term);
2412 break;
2413 }
2414 }
2415 let next = input.next, low = 0, high = data[state + 2];
2416 if (input.next < 0 && high > low && data[accEnd + high * 3 - 3] == 65535) {
2417 state = data[accEnd + high * 3 - 1];
2418 continue scan;
2419 }
2420 for (; low < high; ) {
2421 let mid = low + high >> 1;
2422 let index = accEnd + mid + (mid << 1);
2423 let from = data[index], to = data[index + 1] || 65536;
2424 if (next < from)
2425 high = mid;
2426 else if (next >= to)
2427 low = mid + 1;
2428 else {
2429 state = data[index + 2];
2430 input.advance();
2431 continue scan;
2432 }
2433 }
2434 break;
2435 }
2436}
2437function findOffset(data, start, term) {
2438 for (let i = start, next; (next = data[i]) != 65535; i++)
2439 if (next == term)
2440 return i - start;
2441 return -1;
2442}
2443function overrides(token, prev, tableData, tableOffset) {
2444 let iPrev = findOffset(tableData, tableOffset, prev);
2445 return iPrev < 0 || findOffset(tableData, tableOffset, token) < iPrev;
2446}
2447var verbose = typeof process != "undefined" && process.env && /\bparse\b/.test(process.env.LOG);
2448var stackIDs = null;
2449function cutAt(tree, pos, side) {
2450 let cursor = tree.cursor(IterMode.IncludeAnonymous);
2451 cursor.moveTo(pos);
2452 for (; ; ) {
2453 if (!(side < 0 ? cursor.childBefore(pos) : cursor.childAfter(pos)))
2454 for (; ; ) {
2455 if ((side < 0 ? cursor.to < pos : cursor.from > pos) && !cursor.type.isError)
2456 return side < 0 ? Math.max(0, Math.min(
2457 cursor.to - 1,
2458 pos - 25
2459 /* Lookahead.Margin */
2460 )) : Math.min(tree.length, Math.max(
2461 cursor.from + 1,
2462 pos + 25
2463 /* Lookahead.Margin */
2464 ));
2465 if (side < 0 ? cursor.prevSibling() : cursor.nextSibling())
2466 break;
2467 if (!cursor.parent())
2468 return side < 0 ? 0 : tree.length;
2469 }
2470 }
2471}
2472var FragmentCursor = class {
2473 constructor(fragments, nodeSet) {
2474 this.fragments = fragments;
2475 this.nodeSet = nodeSet;
2476 this.i = 0;
2477 this.fragment = null;
2478 this.safeFrom = -1;
2479 this.safeTo = -1;
2480 this.trees = [];
2481 this.start = [];
2482 this.index = [];
2483 this.nextFragment();
2484 }
2485 nextFragment() {
2486 let fr = this.fragment = this.i == this.fragments.length ? null : this.fragments[this.i++];
2487 if (fr) {
2488 this.safeFrom = fr.openStart ? cutAt(fr.tree, fr.from + fr.offset, 1) - fr.offset : fr.from;
2489 this.safeTo = fr.openEnd ? cutAt(fr.tree, fr.to + fr.offset, -1) - fr.offset : fr.to;
2490 while (this.trees.length) {
2491 this.trees.pop();
2492 this.start.pop();
2493 this.index.pop();
2494 }
2495 this.trees.push(fr.tree);
2496 this.start.push(-fr.offset);
2497 this.index.push(0);
2498 this.nextStart = this.safeFrom;
2499 } else {
2500 this.nextStart = 1e9;
2501 }
2502 }
2503 // `pos` must be >= any previously given `pos` for this cursor
2504 nodeAt(pos) {
2505 if (pos < this.nextStart)
2506 return null;
2507 while (this.fragment && this.safeTo <= pos)
2508 this.nextFragment();
2509 if (!this.fragment)
2510 return null;
2511 for (; ; ) {
2512 let last = this.trees.length - 1;
2513 if (last < 0) {
2514 this.nextFragment();
2515 return null;
2516 }
2517 let top = this.trees[last], index = this.index[last];
2518 if (index == top.children.length) {
2519 this.trees.pop();
2520 this.start.pop();
2521 this.index.pop();
2522 continue;
2523 }
2524 let next = top.children[index];
2525 let start = this.start[last] + top.positions[index];
2526 if (start > pos) {
2527 this.nextStart = start;
2528 return null;
2529 }
2530 if (next instanceof Tree) {
2531 if (start == pos) {
2532 if (start < this.safeFrom)
2533 return null;
2534 let end = start + next.length;
2535 if (end <= this.safeTo) {
2536 let lookAhead = next.prop(NodeProp.lookAhead);
2537 if (!lookAhead || end + lookAhead < this.fragment.to)
2538 return next;
2539 }
2540 }
2541 this.index[last]++;
2542 if (start + next.length >= Math.max(this.safeFrom, pos)) {
2543 this.trees.push(next);
2544 this.start.push(start);
2545 this.index.push(0);
2546 }
2547 } else {
2548 this.index[last]++;
2549 this.nextStart = start + next.length;
2550 }
2551 }
2552 }
2553};
2554var TokenCache = class {
2555 constructor(parser2, stream) {
2556 this.stream = stream;
2557 this.tokens = [];
2558 this.mainToken = null;
2559 this.actions = [];
2560 this.tokens = parser2.tokenizers.map((_) => new CachedToken());
2561 }
2562 getActions(stack) {
2563 let actionIndex = 0;
2564 let main = null;
2565 let { parser: parser2 } = stack.p, { tokenizers } = parser2;
2566 let mask = parser2.stateSlot(
2567 stack.state,
2568 3
2569 /* ParseState.TokenizerMask */
2570 );
2571 let context = stack.curContext ? stack.curContext.hash : 0;
2572 let lookAhead = 0;
2573 for (let i = 0; i < tokenizers.length; i++) {
2574 if ((1 << i & mask) == 0)
2575 continue;
2576 let tokenizer = tokenizers[i], token = this.tokens[i];
2577 if (main && !tokenizer.fallback)
2578 continue;
2579 if (tokenizer.contextual || token.start != stack.pos || token.mask != mask || token.context != context) {
2580 this.updateCachedToken(token, tokenizer, stack);
2581 token.mask = mask;
2582 token.context = context;
2583 }
2584 if (token.lookAhead > token.end + 25)
2585 lookAhead = Math.max(token.lookAhead, lookAhead);
2586 if (token.value != 0) {
2587 let startIndex = actionIndex;
2588 if (token.extended > -1)
2589 actionIndex = this.addActions(stack, token.extended, token.end, actionIndex);
2590 actionIndex = this.addActions(stack, token.value, token.end, actionIndex);
2591 if (!tokenizer.extend) {
2592 main = token;
2593 if (actionIndex > startIndex)
2594 break;
2595 }
2596 }
2597 }
2598 while (this.actions.length > actionIndex)
2599 this.actions.pop();
2600 if (lookAhead)
2601 stack.setLookAhead(lookAhead);
2602 if (!main && stack.pos == this.stream.end) {
2603 main = new CachedToken();
2604 main.value = stack.p.parser.eofTerm;
2605 main.start = main.end = stack.pos;
2606 actionIndex = this.addActions(stack, main.value, main.end, actionIndex);
2607 }
2608 this.mainToken = main;
2609 return this.actions;
2610 }
2611 getMainToken(stack) {
2612 if (this.mainToken)
2613 return this.mainToken;
2614 let main = new CachedToken(), { pos, p } = stack;
2615 main.start = pos;
2616 main.end = Math.min(pos + 1, p.stream.end);
2617 main.value = pos == p.stream.end ? p.parser.eofTerm : 0;
2618 return main;
2619 }
2620 updateCachedToken(token, tokenizer, stack) {
2621 let start = this.stream.clipPos(stack.pos);
2622 tokenizer.token(this.stream.reset(start, token), stack);
2623 if (token.value > -1) {
2624 let { parser: parser2 } = stack.p;
2625 for (let i = 0; i < parser2.specialized.length; i++)
2626 if (parser2.specialized[i] == token.value) {
2627 let result = parser2.specializers[i](this.stream.read(token.start, token.end), stack);
2628 if (result >= 0 && stack.p.parser.dialect.allows(result >> 1)) {
2629 if ((result & 1) == 0)
2630 token.value = result >> 1;
2631 else
2632 token.extended = result >> 1;
2633 break;
2634 }
2635 }
2636 } else {
2637 token.value = 0;
2638 token.end = this.stream.clipPos(start + 1);
2639 }
2640 }
2641 putAction(action, token, end, index) {
2642 for (let i = 0; i < index; i += 3)
2643 if (this.actions[i] == action)
2644 return index;
2645 this.actions[index++] = action;
2646 this.actions[index++] = token;
2647 this.actions[index++] = end;
2648 return index;
2649 }
2650 addActions(stack, token, end, index) {
2651 let { state } = stack, { parser: parser2 } = stack.p, { data } = parser2;
2652 for (let set = 0; set < 2; set++) {
2653 for (let i = parser2.stateSlot(
2654 state,
2655 set ? 2 : 1
2656 /* ParseState.Actions */
2657 ); ; i += 3) {
2658 if (data[i] == 65535) {
2659 if (data[i + 1] == 1) {
2660 i = pair(data, i + 2);
2661 } else {
2662 if (index == 0 && data[i + 1] == 2)
2663 index = this.putAction(pair(data, i + 2), token, end, index);
2664 break;
2665 }
2666 }
2667 if (data[i] == token)
2668 index = this.putAction(pair(data, i + 1), token, end, index);
2669 }
2670 }
2671 return index;
2672 }
2673};
2674var Parse = class {
2675 constructor(parser2, input, fragments, ranges) {
2676 this.parser = parser2;
2677 this.input = input;
2678 this.ranges = ranges;
2679 this.recovering = 0;
2680 this.nextStackID = 9812;
2681 this.minStackPos = 0;
2682 this.reused = [];
2683 this.stoppedAt = null;
2684 this.lastBigReductionStart = -1;
2685 this.lastBigReductionSize = 0;
2686 this.bigReductionCount = 0;
2687 this.stream = new InputStream(input, ranges);
2688 this.tokens = new TokenCache(parser2, this.stream);
2689 this.topTerm = parser2.top[1];
2690 let { from } = ranges[0];
2691 this.stacks = [Stack.start(this, parser2.top[0], from)];
2692 this.fragments = fragments.length && this.stream.end - from > parser2.bufferLength * 4 ? new FragmentCursor(fragments, parser2.nodeSet) : null;
2693 }
2694 get parsedPos() {
2695 return this.minStackPos;
2696 }
2697 // Move the parser forward. This will process all parse stacks at
2698 // `this.pos` and try to advance them to a further position. If no
2699 // stack for such a position is found, it'll start error-recovery.
2700 //
2701 // When the parse is finished, this will return a syntax tree. When
2702 // not, it returns `null`.
2703 advance() {
2704 let stacks = this.stacks, pos = this.minStackPos;
2705 let newStacks = this.stacks = [];
2706 let stopped, stoppedTokens;
2707 if (this.bigReductionCount > 300 && stacks.length == 1) {
2708 let [s] = stacks;
2709 while (s.forceReduce() && s.stack.length && s.stack[s.stack.length - 2] >= this.lastBigReductionStart) {
2710 }
2711 this.bigReductionCount = this.lastBigReductionSize = 0;
2712 }
2713 for (let i = 0; i < stacks.length; i++) {
2714 let stack = stacks[i];
2715 for (; ; ) {
2716 this.tokens.mainToken = null;
2717 if (stack.pos > pos) {
2718 newStacks.push(stack);
2719 } else if (this.advanceStack(stack, newStacks, stacks)) {
2720 continue;
2721 } else {
2722 if (!stopped) {
2723 stopped = [];
2724 stoppedTokens = [];
2725 }
2726 stopped.push(stack);
2727 let tok = this.tokens.getMainToken(stack);
2728 stoppedTokens.push(tok.value, tok.end);
2729 }
2730 break;
2731 }
2732 }
2733 if (!newStacks.length) {
2734 let finished = stopped && findFinished(stopped);
2735 if (finished) {
2736 if (verbose)
2737 console.log("Finish with " + this.stackID(finished));
2738 return this.stackToTree(finished);
2739 }
2740 if (this.parser.strict) {
2741 if (verbose && stopped)
2742 console.log("Stuck with token " + (this.tokens.mainToken ? this.parser.getName(this.tokens.mainToken.value) : "none"));
2743 throw new SyntaxError("No parse at " + pos);
2744 }
2745 if (!this.recovering)
2746 this.recovering = 5;
2747 }
2748 if (this.recovering && stopped) {
2749 let finished = this.stoppedAt != null && stopped[0].pos > this.stoppedAt ? stopped[0] : this.runRecovery(stopped, stoppedTokens, newStacks);
2750 if (finished) {
2751 if (verbose)
2752 console.log("Force-finish " + this.stackID(finished));
2753 return this.stackToTree(finished.forceAll());
2754 }
2755 }
2756 if (this.recovering) {
2757 let maxRemaining = this.recovering == 1 ? 1 : this.recovering * 3;
2758 if (newStacks.length > maxRemaining) {
2759 newStacks.sort((a, b) => b.score - a.score);
2760 while (newStacks.length > maxRemaining)
2761 newStacks.pop();
2762 }
2763 if (newStacks.some((s) => s.reducePos > pos))
2764 this.recovering--;
2765 } else if (newStacks.length > 1) {
2766 outer: for (let i = 0; i < newStacks.length - 1; i++) {
2767 let stack = newStacks[i];
2768 for (let j = i + 1; j < newStacks.length; j++) {
2769 let other = newStacks[j];
2770 if (stack.sameState(other) || stack.buffer.length > 500 && other.buffer.length > 500) {
2771 if ((stack.score - other.score || stack.buffer.length - other.buffer.length) > 0) {
2772 newStacks.splice(j--, 1);
2773 } else {
2774 newStacks.splice(i--, 1);
2775 continue outer;
2776 }
2777 }
2778 }
2779 }
2780 if (newStacks.length > 12) {
2781 newStacks.sort((a, b) => b.score - a.score);
2782 newStacks.splice(
2783 12,
2784 newStacks.length - 12
2785 /* Rec.MaxStackCount */
2786 );
2787 }
2788 }
2789 this.minStackPos = newStacks[0].pos;
2790 for (let i = 1; i < newStacks.length; i++)
2791 if (newStacks[i].pos < this.minStackPos)
2792 this.minStackPos = newStacks[i].pos;
2793 return null;
2794 }
2795 stopAt(pos) {
2796 if (this.stoppedAt != null && this.stoppedAt < pos)
2797 throw new RangeError("Can't move stoppedAt forward");
2798 this.stoppedAt = pos;
2799 }
2800 // Returns an updated version of the given stack, or null if the
2801 // stack can't advance normally. When `split` and `stacks` are
2802 // given, stacks split off by ambiguous operations will be pushed to
2803 // `split`, or added to `stacks` if they move `pos` forward.
2804 advanceStack(stack, stacks, split) {
2805 let start = stack.pos, { parser: parser2 } = this;
2806 let base = verbose ? this.stackID(stack) + " -> " : "";
2807 if (this.stoppedAt != null && start > this.stoppedAt)
2808 return stack.forceReduce() ? stack : null;
2809 if (this.fragments) {
2810 let strictCx = stack.curContext && stack.curContext.tracker.strict, cxHash = strictCx ? stack.curContext.hash : 0;
2811 for (let cached = this.fragments.nodeAt(start); cached; ) {
2812 let match = this.parser.nodeSet.types[cached.type.id] == cached.type ? parser2.getGoto(stack.state, cached.type.id) : -1;
2813 if (match > -1 && cached.length && (!strictCx || (cached.prop(NodeProp.contextHash) || 0) == cxHash)) {
2814 stack.useNode(cached, match);
2815 if (verbose)
2816 console.log(base + this.stackID(stack) + ` (via reuse of ${parser2.getName(cached.type.id)})`);
2817 return true;
2818 }
2819 if (!(cached instanceof Tree) || cached.children.length == 0 || cached.positions[0] > 0)
2820 break;
2821 let inner = cached.children[0];
2822 if (inner instanceof Tree && cached.positions[0] == 0)
2823 cached = inner;
2824 else
2825 break;
2826 }
2827 }
2828 let defaultReduce = parser2.stateSlot(
2829 stack.state,
2830 4
2831 /* ParseState.DefaultReduce */
2832 );
2833 if (defaultReduce > 0) {
2834 stack.reduce(defaultReduce);
2835 if (verbose)
2836 console.log(base + this.stackID(stack) + ` (via always-reduce ${parser2.getName(
2837 defaultReduce & 65535
2838 /* Action.ValueMask */
2839 )})`);
2840 return true;
2841 }
2842 if (stack.stack.length >= 8400) {
2843 while (stack.stack.length > 6e3 && stack.forceReduce()) {
2844 }
2845 }
2846 let actions = this.tokens.getActions(stack);
2847 for (let i = 0; i < actions.length; ) {
2848 let action = actions[i++], term = actions[i++], end = actions[i++];
2849 let last = i == actions.length || !split;
2850 let localStack = last ? stack : stack.split();
2851 let main = this.tokens.mainToken;
2852 localStack.apply(action, term, main ? main.start : localStack.pos, end);
2853 if (verbose)
2854 console.log(base + this.stackID(localStack) + ` (via ${(action & 65536) == 0 ? "shift" : `reduce of ${parser2.getName(
2855 action & 65535
2856 /* Action.ValueMask */
2857 )}`} for ${parser2.getName(term)} @ ${start}${localStack == stack ? "" : ", split"})`);
2858 if (last)
2859 return true;
2860 else if (localStack.pos > start)
2861 stacks.push(localStack);
2862 else
2863 split.push(localStack);
2864 }
2865 return false;
2866 }
2867 // Advance a given stack forward as far as it will go. Returns the
2868 // (possibly updated) stack if it got stuck, or null if it moved
2869 // forward and was given to `pushStackDedup`.
2870 advanceFully(stack, newStacks) {
2871 let pos = stack.pos;
2872 for (; ; ) {
2873 if (!this.advanceStack(stack, null, null))
2874 return false;
2875 if (stack.pos > pos) {
2876 pushStackDedup(stack, newStacks);
2877 return true;
2878 }
2879 }
2880 }
2881 runRecovery(stacks, tokens, newStacks) {
2882 let finished = null, restarted = false;
2883 for (let i = 0; i < stacks.length; i++) {
2884 let stack = stacks[i], token = tokens[i << 1], tokenEnd = tokens[(i << 1) + 1];
2885 let base = verbose ? this.stackID(stack) + " -> " : "";
2886 if (stack.deadEnd) {
2887 if (restarted)
2888 continue;
2889 restarted = true;
2890 stack.restart();
2891 if (verbose)
2892 console.log(base + this.stackID(stack) + " (restarted)");
2893 let done = this.advanceFully(stack, newStacks);
2894 if (done)
2895 continue;
2896 }
2897 let force = stack.split(), forceBase = base;
2898 for (let j = 0; j < 10 && force.forceReduce(); j++) {
2899 if (verbose)
2900 console.log(forceBase + this.stackID(force) + " (via force-reduce)");
2901 let done = this.advanceFully(force, newStacks);
2902 if (done)
2903 break;
2904 if (verbose)
2905 forceBase = this.stackID(force) + " -> ";
2906 }
2907 for (let insert of stack.recoverByInsert(token)) {
2908 if (verbose)
2909 console.log(base + this.stackID(insert) + " (via recover-insert)");
2910 this.advanceFully(insert, newStacks);
2911 }
2912 if (this.stream.end > stack.pos) {
2913 if (tokenEnd == stack.pos) {
2914 tokenEnd++;
2915 token = 0;
2916 }
2917 stack.recoverByDelete(token, tokenEnd);
2918 if (verbose)
2919 console.log(base + this.stackID(stack) + ` (via recover-delete ${this.parser.getName(token)})`);
2920 pushStackDedup(stack, newStacks);
2921 } else if (!finished || finished.score < force.score) {
2922 finished = force;
2923 }
2924 }
2925 return finished;
2926 }
2927 // Convert the stack's buffer to a syntax tree.
2928 stackToTree(stack) {
2929 stack.close();
2930 return Tree.build({
2931 buffer: StackBufferCursor.create(stack),
2932 nodeSet: this.parser.nodeSet,
2933 topID: this.topTerm,
2934 maxBufferLength: this.parser.bufferLength,
2935 reused: this.reused,
2936 start: this.ranges[0].from,
2937 length: stack.pos - this.ranges[0].from,
2938 minRepeatType: this.parser.minRepeatTerm
2939 });
2940 }
2941 stackID(stack) {
2942 let id2 = (stackIDs || (stackIDs = /* @__PURE__ */ new WeakMap())).get(stack);
2943 if (!id2)
2944 stackIDs.set(stack, id2 = String.fromCodePoint(this.nextStackID++));
2945 return id2 + stack;
2946 }
2947};
2948function pushStackDedup(stack, newStacks) {
2949 for (let i = 0; i < newStacks.length; i++) {
2950 let other = newStacks[i];
2951 if (other.pos == stack.pos && other.sameState(stack)) {
2952 if (newStacks[i].score < stack.score)
2953 newStacks[i] = stack;
2954 return;
2955 }
2956 }
2957 newStacks.push(stack);
2958}
2959var Dialect = class {
2960 constructor(source, flags, disabled) {
2961 this.source = source;
2962 this.flags = flags;
2963 this.disabled = disabled;
2964 }
2965 allows(term) {
2966 return !this.disabled || this.disabled[term] == 0;
2967 }
2968};
2969var id = (x) => x;
2970var ContextTracker = class {
2971 /**
2972 Define a context tracker.
2973 */
2974 constructor(spec) {
2975 this.start = spec.start;
2976 this.shift = spec.shift || id;
2977 this.reduce = spec.reduce || id;
2978 this.reuse = spec.reuse || id;
2979 this.hash = spec.hash || (() => 0);
2980 this.strict = spec.strict !== false;
2981 }
2982};
2983var LRParser = class _LRParser extends Parser {
2984 /**
2985 @internal
2986 */
2987 constructor(spec) {
2988 super();
2989 this.wrappers = [];
2990 if (spec.version != 14)
2991 throw new RangeError(`Parser version (${spec.version}) doesn't match runtime version (${14})`);
2992 let nodeNames = spec.nodeNames.split(" ");
2993 this.minRepeatTerm = nodeNames.length;
2994 for (let i = 0; i < spec.repeatNodeCount; i++)
2995 nodeNames.push("");
2996 let topTerms = Object.keys(spec.topRules).map((r) => spec.topRules[r][1]);
2997 let nodeProps = [];
2998 for (let i = 0; i < nodeNames.length; i++)
2999 nodeProps.push([]);
3000 function setProp(nodeID, prop, value) {
3001 nodeProps[nodeID].push([prop, prop.deserialize(String(value))]);
3002 }
3003 if (spec.nodeProps)
3004 for (let propSpec of spec.nodeProps) {
3005 let prop = propSpec[0];
3006 if (typeof prop == "string")
3007 prop = NodeProp[prop];
3008 for (let i = 1; i < propSpec.length; ) {
3009 let next = propSpec[i++];
3010 if (next >= 0) {
3011 setProp(next, prop, propSpec[i++]);
3012 } else {
3013 let value = propSpec[i + -next];
3014 for (let j = -next; j > 0; j--)
3015 setProp(propSpec[i++], prop, value);
3016 i++;
3017 }
3018 }
3019 }
3020 this.nodeSet = new NodeSet(nodeNames.map((name2, i) => NodeType.define({
3021 name: i >= this.minRepeatTerm ? void 0 : name2,
3022 id: i,
3023 props: nodeProps[i],
3024 top: topTerms.indexOf(i) > -1,
3025 error: i == 0,
3026 skipped: spec.skippedNodes && spec.skippedNodes.indexOf(i) > -1
3027 })));
3028 if (spec.propSources)
3029 this.nodeSet = this.nodeSet.extend(...spec.propSources);
3030 this.strict = false;
3031 this.bufferLength = DefaultBufferLength;
3032 let tokenArray = decodeArray(spec.tokenData);
3033 this.context = spec.context;
3034 this.specializerSpecs = spec.specialized || [];
3035 this.specialized = new Uint16Array(this.specializerSpecs.length);
3036 for (let i = 0; i < this.specializerSpecs.length; i++)
3037 this.specialized[i] = this.specializerSpecs[i].term;
3038 this.specializers = this.specializerSpecs.map(getSpecializer);
3039 this.states = decodeArray(spec.states, Uint32Array);
3040 this.data = decodeArray(spec.stateData);
3041 this.goto = decodeArray(spec.goto);
3042 this.maxTerm = spec.maxTerm;
3043 this.tokenizers = spec.tokenizers.map((value) => typeof value == "number" ? new TokenGroup(tokenArray, value) : value);
3044 this.topRules = spec.topRules;
3045 this.dialects = spec.dialects || {};
3046 this.dynamicPrecedences = spec.dynamicPrecedences || null;
3047 this.tokenPrecTable = spec.tokenPrec;
3048 this.termNames = spec.termNames || null;
3049 this.maxNode = this.nodeSet.types.length - 1;
3050 this.dialect = this.parseDialect();
3051 this.top = this.topRules[Object.keys(this.topRules)[0]];
3052 }
3053 createParse(input, fragments, ranges) {
3054 let parse = new Parse(this, input, fragments, ranges);
3055 for (let w of this.wrappers)
3056 parse = w(parse, input, fragments, ranges);
3057 return parse;
3058 }
3059 /**
3060 Get a goto table entry @internal
3061 */
3062 getGoto(state, term, loose = false) {
3063 let table = this.goto;
3064 if (term >= table[0])
3065 return -1;
3066 for (let pos = table[term + 1]; ; ) {
3067 let groupTag = table[pos++], last = groupTag & 1;
3068 let target = table[pos++];
3069 if (last && loose)
3070 return target;
3071 for (let end = pos + (groupTag >> 1); pos < end; pos++)
3072 if (table[pos] == state)
3073 return target;
3074 if (last)
3075 return -1;
3076 }
3077 }
3078 /**
3079 Check if this state has an action for a given terminal @internal
3080 */
3081 hasAction(state, terminal) {
3082 let data = this.data;
3083 for (let set = 0; set < 2; set++) {
3084 for (let i = this.stateSlot(
3085 state,
3086 set ? 2 : 1
3087 /* ParseState.Actions */
3088 ), next; ; i += 3) {
3089 if ((next = data[i]) == 65535) {
3090 if (data[i + 1] == 1)
3091 next = data[i = pair(data, i + 2)];
3092 else if (data[i + 1] == 2)
3093 return pair(data, i + 2);
3094 else
3095 break;
3096 }
3097 if (next == terminal || next == 0)
3098 return pair(data, i + 1);
3099 }
3100 }
3101 return 0;
3102 }
3103 /**
3104 @internal
3105 */
3106 stateSlot(state, slot) {
3107 return this.states[state * 6 + slot];
3108 }
3109 /**
3110 @internal
3111 */
3112 stateFlag(state, flag) {
3113 return (this.stateSlot(
3114 state,
3115 0
3116 /* ParseState.Flags */
3117 ) & flag) > 0;
3118 }
3119 /**
3120 @internal
3121 */
3122 validAction(state, action) {
3123 return !!this.allActions(state, (a) => a == action ? true : null);
3124 }
3125 /**
3126 @internal
3127 */
3128 allActions(state, action) {
3129 let deflt = this.stateSlot(
3130 state,
3131 4
3132 /* ParseState.DefaultReduce */
3133 );
3134 let result = deflt ? action(deflt) : void 0;
3135 for (let i = this.stateSlot(
3136 state,
3137 1
3138 /* ParseState.Actions */
3139 ); result == null; i += 3) {
3140 if (this.data[i] == 65535) {
3141 if (this.data[i + 1] == 1)
3142 i = pair(this.data, i + 2);
3143 else
3144 break;
3145 }
3146 result = action(pair(this.data, i + 1));
3147 }
3148 return result;
3149 }
3150 /**
3151 Get the states that can follow this one through shift actions or
3152 goto jumps. @internal
3153 */
3154 nextStates(state) {
3155 let result = [];
3156 for (let i = this.stateSlot(
3157 state,
3158 1
3159 /* ParseState.Actions */
3160 ); ; i += 3) {
3161 if (this.data[i] == 65535) {
3162 if (this.data[i + 1] == 1)
3163 i = pair(this.data, i + 2);
3164 else
3165 break;
3166 }
3167 if ((this.data[i + 2] & 65536 >> 16) == 0) {
3168 let value = this.data[i + 1];
3169 if (!result.some((v, i2) => i2 & 1 && v == value))
3170 result.push(this.data[i], value);
3171 }
3172 }
3173 return result;
3174 }
3175 /**
3176 Configure the parser. Returns a new parser instance that has the
3177 given settings modified. Settings not provided in `config` are
3178 kept from the original parser.
3179 */
3180 configure(config) {
3181 let copy = Object.assign(Object.create(_LRParser.prototype), this);
3182 if (config.props)
3183 copy.nodeSet = this.nodeSet.extend(...config.props);
3184 if (config.top) {
3185 let info = this.topRules[config.top];
3186 if (!info)
3187 throw new RangeError(`Invalid top rule name ${config.top}`);
3188 copy.top = info;
3189 }
3190 if (config.tokenizers)
3191 copy.tokenizers = this.tokenizers.map((t2) => {
3192 let found = config.tokenizers.find((r) => r.from == t2);
3193 return found ? found.to : t2;
3194 });
3195 if (config.specializers) {
3196 copy.specializers = this.specializers.slice();
3197 copy.specializerSpecs = this.specializerSpecs.map((s, i) => {
3198 let found = config.specializers.find((r) => r.from == s.external);
3199 if (!found)
3200 return s;
3201 let spec = Object.assign(Object.assign({}, s), { external: found.to });
3202 copy.specializers[i] = getSpecializer(spec);
3203 return spec;
3204 });
3205 }
3206 if (config.contextTracker)
3207 copy.context = config.contextTracker;
3208 if (config.dialect)
3209 copy.dialect = this.parseDialect(config.dialect);
3210 if (config.strict != null)
3211 copy.strict = config.strict;
3212 if (config.wrap)
3213 copy.wrappers = copy.wrappers.concat(config.wrap);
3214 if (config.bufferLength != null)
3215 copy.bufferLength = config.bufferLength;
3216 return copy;
3217 }
3218 /**
3219 Tells you whether any [parse wrappers](#lr.ParserConfig.wrap)
3220 are registered for this parser.
3221 */
3222 hasWrappers() {
3223 return this.wrappers.length > 0;
3224 }
3225 /**
3226 Returns the name associated with a given term. This will only
3227 work for all terms when the parser was generated with the
3228 `--names` option. By default, only the names of tagged terms are
3229 stored.
3230 */
3231 getName(term) {
3232 return this.termNames ? this.termNames[term] : String(term <= this.maxNode && this.nodeSet.types[term].name || term);
3233 }
3234 /**
3235 The eof term id is always allocated directly after the node
3236 types. @internal
3237 */
3238 get eofTerm() {
3239 return this.maxNode + 1;
3240 }
3241 /**
3242 The type of top node produced by the parser.
3243 */
3244 get topNode() {
3245 return this.nodeSet.types[this.top[1]];
3246 }
3247 /**
3248 @internal
3249 */
3250 dynamicPrecedence(term) {
3251 let prec = this.dynamicPrecedences;
3252 return prec == null ? 0 : prec[term] || 0;
3253 }
3254 /**
3255 @internal
3256 */
3257 parseDialect(dialect) {
3258 let values = Object.keys(this.dialects), flags = values.map(() => false);
3259 if (dialect)
3260 for (let part of dialect.split(" ")) {
3261 let id2 = values.indexOf(part);
3262 if (id2 >= 0)
3263 flags[id2] = true;
3264 }
3265 let disabled = null;
3266 for (let i = 0; i < values.length; i++)
3267 if (!flags[i]) {
3268 for (let j = this.dialects[values[i]], id2; (id2 = this.data[j++]) != 65535; )
3269 (disabled || (disabled = new Uint8Array(this.maxTerm + 1)))[id2] = 1;
3270 }
3271 return new Dialect(dialect, flags, disabled);
3272 }
3273 /**
3274 Used by the output of the parser generator. Not available to
3275 user code. @hide
3276 */
3277 static deserialize(spec) {
3278 return new _LRParser(spec);
3279 }
3280};
3281function pair(data, off) {
3282 return data[off] | data[off + 1] << 16;
3283}
3284function findFinished(stacks) {
3285 let best = null;
3286 for (let stack of stacks) {
3287 let stopped = stack.p.stoppedAt;
3288 if ((stack.pos == stack.p.stream.end || stopped != null && stack.pos > stopped) && stack.p.parser.stateFlag(
3289 stack.state,
3290 2
3291 /* StateFlag.Accepting */
3292 ) && (!best || best.score < stack.score))
3293 best = stack;
3294 }
3295 return best;
3296}
3297function getSpecializer(spec) {
3298 if (spec.external) {
3299 let mask = spec.extend ? 1 : 0;
3300 return (value, stack) => spec.external(value, stack) << 1 | mask;
3301 }
3302 return spec.get;
3303}
3304
3305// node_modules/@lezer/highlight/dist/index.js
3306var nextTagID = 0;
3307var Tag = class _Tag {
3308 /**
3309 @internal
3310 */
3311 constructor(name2, set, base, modified) {
3312 this.name = name2;
3313 this.set = set;
3314 this.base = base;
3315 this.modified = modified;
3316 this.id = nextTagID++;
3317 }
3318 toString() {
3319 let { name: name2 } = this;
3320 for (let mod of this.modified)
3321 if (mod.name)
3322 name2 = `${mod.name}(${name2})`;
3323 return name2;
3324 }
3325 static define(nameOrParent, parent) {
3326 let name2 = typeof nameOrParent == "string" ? nameOrParent : "?";
3327 if (nameOrParent instanceof _Tag)
3328 parent = nameOrParent;
3329 if (parent === null || parent === void 0 ? void 0 : parent.base)
3330 throw new Error("Can not derive from a modified tag");
3331 let tag = new _Tag(name2, [], null, []);
3332 tag.set.push(tag);
3333 if (parent)
3334 for (let t2 of parent.set)
3335 tag.set.push(t2);
3336 return tag;
3337 }
3338 /**
3339 Define a tag _modifier_, which is a function that, given a tag,
3340 will return a tag that is a subtag of the original. Applying the
3341 same modifier to a twice tag will return the same value (`m1(t1)
3342 == m1(t1)`) and applying multiple modifiers will, regardless or
3343 order, produce the same tag (`m1(m2(t1)) == m2(m1(t1))`).
3344
3345 When multiple modifiers are applied to a given base tag, each
3346 smaller set of modifiers is registered as a parent, so that for
3347 example `m1(m2(m3(t1)))` is a subtype of `m1(m2(t1))`,
3348 `m1(m3(t1)`, and so on.
3349 */
3350 static defineModifier(name2) {
3351 let mod = new Modifier(name2);
3352 return (tag) => {
3353 if (tag.modified.indexOf(mod) > -1)
3354 return tag;
3355 return Modifier.get(tag.base || tag, tag.modified.concat(mod).sort((a, b) => a.id - b.id));
3356 };
3357 }
3358};
3359var nextModifierID = 0;
3360var Modifier = class _Modifier {
3361 constructor(name2) {
3362 this.name = name2;
3363 this.instances = [];
3364 this.id = nextModifierID++;
3365 }
3366 static get(base, mods) {
3367 if (!mods.length)
3368 return base;
3369 let exists = mods[0].instances.find((t2) => t2.base == base && sameArray(mods, t2.modified));
3370 if (exists)
3371 return exists;
3372 let set = [], tag = new Tag(base.name, set, base, mods);
3373 for (let m of mods)
3374 m.instances.push(tag);
3375 let configs = powerSet(mods);
3376 for (let parent of base.set)
3377 if (!parent.modified.length)
3378 for (let config of configs)
3379 set.push(_Modifier.get(parent, config));
3380 return tag;
3381 }
3382};
3383function sameArray(a, b) {
3384 return a.length == b.length && a.every((x, i) => x == b[i]);
3385}
3386function powerSet(array) {
3387 let sets = [[]];
3388 for (let i = 0; i < array.length; i++) {
3389 for (let j = 0, e = sets.length; j < e; j++) {
3390 sets.push(sets[j].concat(array[i]));
3391 }
3392 }
3393 return sets.sort((a, b) => b.length - a.length);
3394}
3395function styleTags(spec) {
3396 let byName = /* @__PURE__ */ Object.create(null);
3397 for (let prop in spec) {
3398 let tags2 = spec[prop];
3399 if (!Array.isArray(tags2))
3400 tags2 = [tags2];
3401 for (let part of prop.split(" "))
3402 if (part) {
3403 let pieces = [], mode = 2, rest = part;
3404 for (let pos = 0; ; ) {
3405 if (rest == "..." && pos > 0 && pos + 3 == part.length) {
3406 mode = 1;
3407 break;
3408 }
3409 let m = /^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(rest);
3410 if (!m)
3411 throw new RangeError("Invalid path: " + part);
3412 pieces.push(m[0] == "*" ? "" : m[0][0] == '"' ? JSON.parse(m[0]) : m[0]);
3413 pos += m[0].length;
3414 if (pos == part.length)
3415 break;
3416 let next = part[pos++];
3417 if (pos == part.length && next == "!") {
3418 mode = 0;
3419 break;
3420 }
3421 if (next != "/")
3422 throw new RangeError("Invalid path: " + part);
3423 rest = part.slice(pos);
3424 }
3425 let last = pieces.length - 1, inner = pieces[last];
3426 if (!inner)
3427 throw new RangeError("Invalid path: " + part);
3428 let rule = new Rule(tags2, mode, last > 0 ? pieces.slice(0, last) : null);
3429 byName[inner] = rule.sort(byName[inner]);
3430 }
3431 }
3432 return ruleNodeProp.add(byName);
3433}
3434var ruleNodeProp = new NodeProp({
3435 combine(a, b) {
3436 let cur, root, take;
3437 while (a || b) {
3438 if (!a || b && a.depth >= b.depth) {
3439 take = b;
3440 b = b.next;
3441 } else {
3442 take = a;
3443 a = a.next;
3444 }
3445 if (cur && cur.mode == take.mode && !take.context && !cur.context)
3446 continue;
3447 let copy = new Rule(take.tags, take.mode, take.context);
3448 if (cur)
3449 cur.next = copy;
3450 else
3451 root = copy;
3452 cur = copy;
3453 }
3454 return root;
3455 }
3456});
3457var Rule = class {
3458 constructor(tags2, mode, context, next) {
3459 this.tags = tags2;
3460 this.mode = mode;
3461 this.context = context;
3462 this.next = next;
3463 }
3464 get opaque() {
3465 return this.mode == 0;
3466 }
3467 get inherit() {
3468 return this.mode == 1;
3469 }
3470 sort(other) {
3471 if (!other || other.depth < this.depth) {
3472 this.next = other;
3473 return this;
3474 }
3475 other.next = this.sort(other.next);
3476 return other;
3477 }
3478 get depth() {
3479 return this.context ? this.context.length : 0;
3480 }
3481};
3482Rule.empty = new Rule([], 2, null);
3483function tagHighlighter(tags2, options) {
3484 let map = /* @__PURE__ */ Object.create(null);
3485 for (let style of tags2) {
3486 if (!Array.isArray(style.tag))
3487 map[style.tag.id] = style.class;
3488 else
3489 for (let tag of style.tag)
3490 map[tag.id] = style.class;
3491 }
3492 let { scope, all = null } = options || {};
3493 return {
3494 style: (tags3) => {
3495 let cls = all;
3496 for (let tag of tags3) {
3497 for (let sub of tag.set) {
3498 let tagClass = map[sub.id];
3499 if (tagClass) {
3500 cls = cls ? cls + " " + tagClass : tagClass;
3501 break;
3502 }
3503 }
3504 }
3505 return cls;
3506 },
3507 scope
3508 };
3509}
3510var t = Tag.define;
3511var comment = t();
3512var name = t();
3513var typeName = t(name);
3514var propertyName = t(name);
3515var literal = t();
3516var string = t(literal);
3517var number = t(literal);
3518var content = t();
3519var heading = t(content);
3520var keyword = t();
3521var operator = t();
3522var punctuation = t();
3523var bracket = t(punctuation);
3524var meta = t();
3525var tags = {
3526 /**
3527 A comment.
3528 */
3529 comment,
3530 /**
3531 A line [comment](#highlight.tags.comment).
3532 */
3533 lineComment: t(comment),
3534 /**
3535 A block [comment](#highlight.tags.comment).
3536 */
3537 blockComment: t(comment),
3538 /**
3539 A documentation [comment](#highlight.tags.comment).
3540 */
3541 docComment: t(comment),
3542 /**
3543 Any kind of identifier.
3544 */
3545 name,
3546 /**
3547 The [name](#highlight.tags.name) of a variable.
3548 */
3549 variableName: t(name),
3550 /**
3551 A type [name](#highlight.tags.name).
3552 */
3553 typeName,
3554 /**
3555 A tag name (subtag of [`typeName`](#highlight.tags.typeName)).
3556 */
3557 tagName: t(typeName),
3558 /**
3559 A property or field [name](#highlight.tags.name).
3560 */
3561 propertyName,
3562 /**
3563 An attribute name (subtag of [`propertyName`](#highlight.tags.propertyName)).
3564 */
3565 attributeName: t(propertyName),
3566 /**
3567 The [name](#highlight.tags.name) of a class.
3568 */
3569 className: t(name),
3570 /**
3571 A label [name](#highlight.tags.name).
3572 */
3573 labelName: t(name),
3574 /**
3575 A namespace [name](#highlight.tags.name).
3576 */
3577 namespace: t(name),
3578 /**
3579 The [name](#highlight.tags.name) of a macro.
3580 */
3581 macroName: t(name),
3582 /**
3583 A literal value.
3584 */
3585 literal,
3586 /**
3587 A string [literal](#highlight.tags.literal).
3588 */
3589 string,
3590 /**
3591 A documentation [string](#highlight.tags.string).
3592 */
3593 docString: t(string),
3594 /**
3595 A character literal (subtag of [string](#highlight.tags.string)).
3596 */
3597 character: t(string),
3598 /**
3599 An attribute value (subtag of [string](#highlight.tags.string)).
3600 */
3601 attributeValue: t(string),
3602 /**
3603 A number [literal](#highlight.tags.literal).
3604 */
3605 number,
3606 /**
3607 An integer [number](#highlight.tags.number) literal.
3608 */
3609 integer: t(number),
3610 /**
3611 A floating-point [number](#highlight.tags.number) literal.
3612 */
3613 float: t(number),
3614 /**
3615 A boolean [literal](#highlight.tags.literal).
3616 */
3617 bool: t(literal),
3618 /**
3619 Regular expression [literal](#highlight.tags.literal).
3620 */
3621 regexp: t(literal),
3622 /**
3623 An escape [literal](#highlight.tags.literal), for example a
3624 backslash escape in a string.
3625 */
3626 escape: t(literal),
3627 /**
3628 A color [literal](#highlight.tags.literal).
3629 */
3630 color: t(literal),
3631 /**
3632 A URL [literal](#highlight.tags.literal).
3633 */
3634 url: t(literal),
3635 /**
3636 A language keyword.
3637 */
3638 keyword,
3639 /**
3640 The [keyword](#highlight.tags.keyword) for the self or this
3641 object.
3642 */
3643 self: t(keyword),
3644 /**
3645 The [keyword](#highlight.tags.keyword) for null.
3646 */
3647 null: t(keyword),
3648 /**
3649 A [keyword](#highlight.tags.keyword) denoting some atomic value.
3650 */
3651 atom: t(keyword),
3652 /**
3653 A [keyword](#highlight.tags.keyword) that represents a unit.
3654 */
3655 unit: t(keyword),
3656 /**
3657 A modifier [keyword](#highlight.tags.keyword).
3658 */
3659 modifier: t(keyword),
3660 /**
3661 A [keyword](#highlight.tags.keyword) that acts as an operator.
3662 */
3663 operatorKeyword: t(keyword),
3664 /**
3665 A control-flow related [keyword](#highlight.tags.keyword).
3666 */
3667 controlKeyword: t(keyword),
3668 /**
3669 A [keyword](#highlight.tags.keyword) that defines something.
3670 */
3671 definitionKeyword: t(keyword),
3672 /**
3673 A [keyword](#highlight.tags.keyword) related to defining or
3674 interfacing with modules.
3675 */
3676 moduleKeyword: t(keyword),
3677 /**
3678 An operator.
3679 */
3680 operator,
3681 /**
3682 An [operator](#highlight.tags.operator) that dereferences something.
3683 */
3684 derefOperator: t(operator),
3685 /**
3686 Arithmetic-related [operator](#highlight.tags.operator).
3687 */
3688 arithmeticOperator: t(operator),
3689 /**
3690 Logical [operator](#highlight.tags.operator).
3691 */
3692 logicOperator: t(operator),
3693 /**
3694 Bit [operator](#highlight.tags.operator).
3695 */
3696 bitwiseOperator: t(operator),
3697 /**
3698 Comparison [operator](#highlight.tags.operator).
3699 */
3700 compareOperator: t(operator),
3701 /**
3702 [Operator](#highlight.tags.operator) that updates its operand.
3703 */
3704 updateOperator: t(operator),
3705 /**
3706 [Operator](#highlight.tags.operator) that defines something.
3707 */
3708 definitionOperator: t(operator),
3709 /**
3710 Type-related [operator](#highlight.tags.operator).
3711 */
3712 typeOperator: t(operator),
3713 /**
3714 Control-flow [operator](#highlight.tags.operator).
3715 */
3716 controlOperator: t(operator),
3717 /**
3718 Program or markup punctuation.
3719 */
3720 punctuation,
3721 /**
3722 [Punctuation](#highlight.tags.punctuation) that separates
3723 things.
3724 */
3725 separator: t(punctuation),
3726 /**
3727 Bracket-style [punctuation](#highlight.tags.punctuation).
3728 */
3729 bracket,
3730 /**
3731 Angle [brackets](#highlight.tags.bracket) (usually `<` and `>`
3732 tokens).
3733 */
3734 angleBracket: t(bracket),
3735 /**
3736 Square [brackets](#highlight.tags.bracket) (usually `[` and `]`
3737 tokens).
3738 */
3739 squareBracket: t(bracket),
3740 /**
3741 Parentheses (usually `(` and `)` tokens). Subtag of
3742 [bracket](#highlight.tags.bracket).
3743 */
3744 paren: t(bracket),
3745 /**
3746 Braces (usually `{` and `}` tokens). Subtag of
3747 [bracket](#highlight.tags.bracket).
3748 */
3749 brace: t(bracket),
3750 /**
3751 Content, for example plain text in XML or markup documents.
3752 */
3753 content,
3754 /**
3755 [Content](#highlight.tags.content) that represents a heading.
3756 */
3757 heading,
3758 /**
3759 A level 1 [heading](#highlight.tags.heading).
3760 */
3761 heading1: t(heading),
3762 /**
3763 A level 2 [heading](#highlight.tags.heading).
3764 */
3765 heading2: t(heading),
3766 /**
3767 A level 3 [heading](#highlight.tags.heading).
3768 */
3769 heading3: t(heading),
3770 /**
3771 A level 4 [heading](#highlight.tags.heading).
3772 */
3773 heading4: t(heading),
3774 /**
3775 A level 5 [heading](#highlight.tags.heading).
3776 */
3777 heading5: t(heading),
3778 /**
3779 A level 6 [heading](#highlight.tags.heading).
3780 */
3781 heading6: t(heading),
3782 /**
3783 A prose [content](#highlight.tags.content) separator (such as a horizontal rule).
3784 */
3785 contentSeparator: t(content),
3786 /**
3787 [Content](#highlight.tags.content) that represents a list.
3788 */
3789 list: t(content),
3790 /**
3791 [Content](#highlight.tags.content) that represents a quote.
3792 */
3793 quote: t(content),
3794 /**
3795 [Content](#highlight.tags.content) that is emphasized.
3796 */
3797 emphasis: t(content),
3798 /**
3799 [Content](#highlight.tags.content) that is styled strong.
3800 */
3801 strong: t(content),
3802 /**
3803 [Content](#highlight.tags.content) that is part of a link.
3804 */
3805 link: t(content),
3806 /**
3807 [Content](#highlight.tags.content) that is styled as code or
3808 monospace.
3809 */
3810 monospace: t(content),
3811 /**
3812 [Content](#highlight.tags.content) that has a strike-through
3813 style.
3814 */
3815 strikethrough: t(content),
3816 /**
3817 Inserted text in a change-tracking format.
3818 */
3819 inserted: t(),
3820 /**
3821 Deleted text.
3822 */
3823 deleted: t(),
3824 /**
3825 Changed text.
3826 */
3827 changed: t(),
3828 /**
3829 An invalid or unsyntactic element.
3830 */
3831 invalid: t(),
3832 /**
3833 Metadata or meta-instruction.
3834 */
3835 meta,
3836 /**
3837 [Metadata](#highlight.tags.meta) that applies to the entire
3838 document.
3839 */
3840 documentMeta: t(meta),
3841 /**
3842 [Metadata](#highlight.tags.meta) that annotates or adds
3843 attributes to a given syntactic element.
3844 */
3845 annotation: t(meta),
3846 /**
3847 Processing instruction or preprocessor directive. Subtag of
3848 [meta](#highlight.tags.meta).
3849 */
3850 processingInstruction: t(meta),
3851 /**
3852 [Modifier](#highlight.Tag^defineModifier) that indicates that a
3853 given element is being defined. Expected to be used with the
3854 various [name](#highlight.tags.name) tags.
3855 */
3856 definition: Tag.defineModifier("definition"),
3857 /**
3858 [Modifier](#highlight.Tag^defineModifier) that indicates that
3859 something is constant. Mostly expected to be used with
3860 [variable names](#highlight.tags.variableName).
3861 */
3862 constant: Tag.defineModifier("constant"),
3863 /**
3864 [Modifier](#highlight.Tag^defineModifier) used to indicate that
3865 a [variable](#highlight.tags.variableName) or [property
3866 name](#highlight.tags.propertyName) is being called or defined
3867 as a function.
3868 */
3869 function: Tag.defineModifier("function"),
3870 /**
3871 [Modifier](#highlight.Tag^defineModifier) that can be applied to
3872 [names](#highlight.tags.name) to indicate that they belong to
3873 the language's standard environment.
3874 */
3875 standard: Tag.defineModifier("standard"),
3876 /**
3877 [Modifier](#highlight.Tag^defineModifier) that indicates a given
3878 [names](#highlight.tags.name) is local to some scope.
3879 */
3880 local: Tag.defineModifier("local"),
3881 /**
3882 A generic variant [modifier](#highlight.Tag^defineModifier) that
3883 can be used to tag language-specific alternative variants of
3884 some common tag. It is recommended for themes to define special
3885 forms of at least the [string](#highlight.tags.string) and
3886 [variable name](#highlight.tags.variableName) tags, since those
3887 come up a lot.
3888 */
3889 special: Tag.defineModifier("special")
3890};
3891for (let name2 in tags) {
3892 let val = tags[name2];
3893 if (val instanceof Tag)
3894 val.name = name2;
3895}
3896var classHighlighter = tagHighlighter([
3897 { tag: tags.link, class: "tok-link" },
3898 { tag: tags.heading, class: "tok-heading" },
3899 { tag: tags.emphasis, class: "tok-emphasis" },
3900 { tag: tags.strong, class: "tok-strong" },
3901 { tag: tags.keyword, class: "tok-keyword" },
3902 { tag: tags.atom, class: "tok-atom" },
3903 { tag: tags.bool, class: "tok-bool" },
3904 { tag: tags.url, class: "tok-url" },
3905 { tag: tags.labelName, class: "tok-labelName" },
3906 { tag: tags.inserted, class: "tok-inserted" },
3907 { tag: tags.deleted, class: "tok-deleted" },
3908 { tag: tags.literal, class: "tok-literal" },
3909 { tag: tags.string, class: "tok-string" },
3910 { tag: tags.number, class: "tok-number" },
3911 { tag: [tags.regexp, tags.escape, tags.special(tags.string)], class: "tok-string2" },
3912 { tag: tags.variableName, class: "tok-variableName" },
3913 { tag: tags.local(tags.variableName), class: "tok-variableName tok-local" },
3914 { tag: tags.definition(tags.variableName), class: "tok-variableName tok-definition" },
3915 { tag: tags.special(tags.variableName), class: "tok-variableName2" },
3916 { tag: tags.definition(tags.propertyName), class: "tok-propertyName tok-definition" },
3917 { tag: tags.typeName, class: "tok-typeName" },
3918 { tag: tags.namespace, class: "tok-namespace" },
3919 { tag: tags.className, class: "tok-className" },
3920 { tag: tags.macroName, class: "tok-macroName" },
3921 { tag: tags.propertyName, class: "tok-propertyName" },
3922 { tag: tags.operator, class: "tok-operator" },
3923 { tag: tags.comment, class: "tok-comment" },
3924 { tag: tags.meta, class: "tok-meta" },
3925 { tag: tags.invalid, class: "tok-invalid" },
3926 { tag: tags.punctuation, class: "tok-punctuation" }
3927]);
3928
3929// node_modules/@gdquest/lezer-gdscript/dist/index.mjs
3930var indent = 140;
3931var dedent = 141;
3932var newline = 142;
3933var blankLineStart = 143;
3934var newlineBracketed = 144;
3935var eof = 145;
3936var ParenL = 10;
3937var CallParamsLiteralExpressionNode = 11;
3938var CallParamsExpressionNode = 25;
3939var ArrayExpressionNode = 27;
3940var BracketL = 32;
3941var CallExpressionNode = 59;
3942var DictionaryExpressionNode = 63;
3943var BraceL = 64;
3944var GroupedExpressionNode = 66;
3945var CallParamsParameterNode = 70;
3946var bracketed = /* @__PURE__ */ new Set([
3947 GroupedExpressionNode,
3948 ArrayExpressionNode,
3949 DictionaryExpressionNode,
3950 CallExpressionNode,
3951 CallParamsExpressionNode,
3952 CallParamsLiteralExpressionNode,
3953 CallParamsParameterNode
3954]);
3955var newline2 = "\n".charCodeAt(0);
3956var carriageReturn = "\r".charCodeAt(0);
3957var space = " ".charCodeAt(0);
3958var tab = " ".charCodeAt(0);
3959var hash = "#".charCodeAt(0);
3960var IndentLevel = class {
3961 constructor(parent, depth) {
3962 this.parent = parent;
3963 this.depth = depth;
3964 this.hash = (parent ? parent.hash + parent.hash << 8 : 0) + depth + (depth << 4);
3965 }
3966};
3967var topIndent = new IndentLevel(null, 0);
3968function isLineBreak(ch) {
3969 return ch === newline2 || ch === carriageReturn;
3970}
3971var newlines = new ExternalTokenizer(
3972 (input, stack) => {
3973 let prev;
3974 if (input.next < 0) {
3975 input.acceptToken(eof);
3976 } else if (stack.context.depth < 0) {
3977 if (isLineBreak(input.next)) {
3978 input.acceptToken(newlineBracketed, 1);
3979 }
3980 } else if (((prev = input.peek(-1)) < 0 || isLineBreak(prev)) && stack.canShift(blankLineStart)) {
3981 let spaces = 0;
3982 while (input.next === space || input.next === tab) {
3983 input.advance();
3984 spaces++;
3985 }
3986 if (input.next === newline2 || input.next === carriageReturn || input.next === hash) {
3987 input.acceptToken(blankLineStart, -spaces);
3988 }
3989 } else if (isLineBreak(input.next)) {
3990 input.acceptToken(newline, 1);
3991 }
3992 },
3993 { contextual: true }
3994);
3995function countIndent(space2) {
3996 let depth = 0;
3997 for (let i = 0; i < space2.length; i++)
3998 depth += space2.charCodeAt(i) === tab ? 8 - depth % 8 : 1;
3999 return depth;
4000}
4001var trackIndent = new ContextTracker({
4002 start: topIndent,
4003 reduce(context, term) {
4004 return context.depth < 0 && bracketed.has(term) ? context.parent : context;
4005 },
4006 shift(context, term, stack, input) {
4007 switch (term) {
4008 case indent:
4009 return new IndentLevel(
4010 context,
4011 countIndent(input.read(input.pos, stack.pos))
4012 );
4013 case dedent:
4014 return context.parent;
4015 case ParenL:
4016 case BracketL:
4017 case BraceL:
4018 return new IndentLevel(context, -1);
4019 default:
4020 return context;
4021 }
4022 },
4023 hash(context) {
4024 return context.hash;
4025 }
4026});
4027var indentation = new ExternalTokenizer((input, stack) => {
4028 const contextDepth = stack.context.depth;
4029 if (contextDepth < 0)
4030 return;
4031 const prev = input.peek(-1);
4032 if (!(prev === newline2 || prev === carriageReturn)) {
4033 return;
4034 }
4035 let chars = 0;
4036 let depth = 0;
4037 while (true) {
4038 if (input.next === space) {
4039 depth++;
4040 } else if (input.next === tab) {
4041 depth += 8 - depth % 8;
4042 } else {
4043 break;
4044 }
4045 input.advance();
4046 chars += 1;
4047 }
4048 if (depth !== contextDepth && input.next !== newline2 && input.next !== carriageReturn && input.next !== hash) {
4049 if (depth < contextDepth) {
4050 input.acceptToken(dedent, -chars);
4051 } else {
4052 input.acceptToken(indent);
4053 }
4054 }
4055});
4056var gdscriptHighlighting = styleTags({
4057 "for while if elif else return break continue pass assert await match case": tags.controlKeyword,
4058 "in not and or is del": tags.operatorKeyword,
4059 "func class class_name extends const var": tags.definitionKeyword,
4060 "preload load": tags.moduleKeyword,
4061 "as PI TAU INF NaN": tags.keyword,
4062 True: tags.bool,
4063 False: tags.bool,
4064 Null: tags.bool,
4065 Comment: tags.lineComment,
4066 Number: tags.number,
4067 String: tags.string,
4068 UpdateOp: tags.updateOperator,
4069 ArithOp: tags.arithmeticOperator,
4070 BitOp: tags.bitwiseOperator,
4071 CompareOp: tags.compareOperator,
4072 AssignOp: tags.definitionOperator,
4073 "ClassNode/Identifier ClassNode/ExtendsStatement/Identifier VariableNode/TypeCast/Type/Identifier": tags.definition(tags.className),
4074 "( )": tags.paren,
4075 "[ ]": tags.squareBracket,
4076 "{ }": tags.brace,
4077 ".": tags.derefOperator,
4078 ", ;": tags.separator
4079});
4080var spec_Identifier = { __proto__: null, PI: 34, TAU: 36, INF: 38, NaN: 40, assert: 48, var: 70, const: 80, await: 86, in: 116, as: 122, func: 138, preload: 162, is: 176, class_name: 186, extends: 190, signal: 194, pass: 198, return: 202, class: 214, if: 222, elif: 226, else: 230, for: 234, match: 238, while: 254 };
4081var parser = LRParser.deserialize({
4082 version: 14,
4083 states: "KtQ`QUOOP#rOQOOOOQQ'#Cq'#CqOOQQ'#Ch'#ChO#wQUO'#CbO#|QUO'#CaO&OQYO'#CyO&lQUO'#CzO&qQUO'#CxO(pQYO'#FmO*hQUO'#CwO*oQYO'#FmO*|QUO'#DOOOQQ'#Fq'#FqO,lQYO'#C`O,dQYO'#C}O,yQUO'#DmO(wQUO'#DpOOQQ'#EQ'#EQO(wQUO'#EYOOQQ'#Fm'#FmOOQQ'#C`'#C`O.jQUO'#C_OOQR'#C_'#C_O.uQVO'#EmOOQR'#Ei'#EiOOQR'#Fg'#FgOOQR'#FQ'#FQQ`QUOOOOQQ'#Cl'#ClO1kQUO'#DOO1pQUO'#DTO(wQUO'#DWO1uQUO'#ElO1zQUO'#EOO1zQUO'#CsO2PQUO'#E[O2UQUO'#E^O2ZQUO'#E`OOQQ'#Eb'#EbO(wQUO'#EdO2`QUO'#EjO,yQUO'#EnO2eQUO'#EtO2jQUO'#EvO,yQUO'#FOP2oOUO'#FfPOOO)CAY)CAYO2zQUO,58|O3iQUO'#DQOOQQ,59q,59qO(wQUO,59iOOQQ,5:T,5:TO3nQUO'#CuO3uQYO,59fO5uQUO'#FTO5zQYO,59dOOQQ,59c,59cO8QQUO,59cOOQQ'#FU'#FUO8VQUO'#DOO8bQYO'#FlO8oQUO'#DrO8tQUO,59cO,yQUO,5:XOOQQ-E9S-E9SO8{QUO,59jO9QQUO,59oO9VQUO,5;UO9[QUO,5;WO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,59tO(wQUO,5:nO(wQUO,59tO9aQUO,59tO3iQUO,5:UO9fQUO,5:qO:uQYO'#DoO;PQUO'#FtO;XQUO,5:XO;^QYO,5:[OOQQ,5:t,5:tOOQR'#Dy'#DyOOQR'#Ef'#EfO;eQUO'#FYO.jQUO,5;ROOQR,58y,58yOOQR'#FZ'#FZO<UQVO,5;XOOQR,5;X,5;XO,yQUO'#EpO>zQUO'#ErOOQR-E9O-E9OO?PQYO,59jO?[QYO,59oOOQQ,59r,59rO8oQUO,5;WOOQQ,5:j,5:jOOQQ,59_,59_OOQQ,5:v,5:vOOQQ,5:x,5:xO?gQUO,5:zO?uQYO,5;OO@SQUO,5;UO@[QYO,5;YO@fQUO,5;`O@kQUO,5;bO@[QYO,5;jPOOO,5<Q,5<QP@pOQO,5<QP@uOUO,5<QOAoQUO'#CgOOQQ1G.h1G.hOOQQ'#DS'#DSOOQQ,59l,59lOB}QYO1G/TOOQQ,59a,59aOCqQUO,59aOCvQUO'#FSOC{QYO1G/QOOQQ'#Cy'#CyOOQQ,5;o,5;oOOQQ-E9R-E9ROOQQ1G.}1G.}OE{QUO,5<WOFVQUO,5<WOFbQUO'#DtOFjQbO'#FuOFrQUO,5:^OFwQUO1G.}OF|QUO1G/sOGRQYO1G/UOG^QYO1G/ZO@SQUO1G0pO8oQUO1G0rOOQQ1G/`1G/`OI]QYO1G/`OIdQYO1G/`OK_QYO1G/`OMYQYO1G/`OMaQYO1G/`O! [QYO1G/`O! cQYO1G/`O!#ZQYO1G/`O!#eQYO1G/`O!#oQYO1G0YO!$qQYO1G/`O(wQUO1G/`OOQQ1G/p1G/pOOQQ'#EX'#EXOOQQ1G0]1G0]O,yQUO,59iO(wQUO,5:ZO!%qQUO,5<`O!%xQUO,5<`OOQQ1G/s1G/sOOQQ1G/v1G/vOOQQ,5;t,5;tOOQQ-E9W-E9WOOQR1G0m1G0mOOQR-E9X-E9XOOQR1G0s1G0sO@[QYO,5;[O!&QQUO'#DwOOQR,5;^,5;^OOQQ1G/U1G/UOOQQ1G/Z1G/ZO>zQUO1G0rOOQQ1G0f1G0fOOQR1G0p1G0pO>zQUO1G0pOOQR1G0t1G0tO,yQUO1G0zO!&XQUO1G0|OOQR1G1U1G1UPOOO1G1l1G1lP!&^OQO1G1lO!&cQUO'#FhOOQQ,59R,59RO!&kQUO,59ROOQQ1G.{1G.{OOQQ,5;n,5;nOOQQ-E9Q-E9QO!&pQYO,5;sO!&}QUO1G1rOOQQ-E9V-E9VO!'XQYO'#DVO!'jQYO'#FvO!'xQUO'#FvOOQQ,5:`,5:`O!(QQUO,5:`O3iQUO'#DvOOQQ,5<a,5<aOOQQ1G/x1G/xOOQQ7+$i7+$iOOQQ7+%_7+%_OOQQ7+$p7+$pOOQQ7+$u7+$uOOQR7+&[7+&[O>zQUO7+&[O>zQUO7+&^O(wQUO7+%tO!)QQYO7+$zO!+bQYO1G/TO!+lQYO1G/uOOQQ,5;q,5;qO!+vQUO1G1zOOQQ-E9T-E9TOOQR1G0v1G0vO!+}QVO'#DxOOQR'#D}'#D}OOQR,5:c,5:cOOQR7+&^7+&^O@[QYO7+&fO!+}QVO7+&hPOOO7+'W7+'WO!,SQUO,5<SO!,ZQUO,5<SOOQQ1G.m1G.mP(wQUO'#FXO(wQUO,5:aO!,cQUO,5<bO!,kQUO,5<bOOQQ1G/z1G/zOOQQ,5:b,5:bO!,sQYO'#EmOOQR<<Iv<<IvOOQR<<Ix<<IxO!/wQYO<<I`P,yQUO'#FVOOQQ'#D{'#D{O`QUO'#DzOOQR,5:d,5:dOOQR<<JQ<<JQO!0nQUO<<JSOOQQ,5;m,5;mO!0{QUO1G1nOOQQ-E9P-E9PO!1SQYO1G/{O!1^QYO,5;rOOQQ,5;r,5;rO!1lQUO1G1|OOQQ-E9U-E9UO!1tQYO,5;XO!3tQVO,5:fOOQQ'#E{'#E{OOQQ'#E|'#E|OOQQ'#E}'#E}OOQQ'#Ey'#EyO>zQUO'#ExOOQR'#F['#F[O!4OQVOAN?nO!4cQUO'#EzP@}QUO'#FRP!4hQUO'#FWOOQR'#D|'#D|OOQR1G0Q1G0QOOQR,5;d,5;dOOQR-E9Y-E9YOOQRG25YG25YOOQQ,5;f,5;fO!4mQYO'#CyO,yQUO'#EYO,yQUO'#DWO,yQUO,59iO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO,yQUO,59tO!4zQYO1G/TO!5UQYO1G/`O!5uQYO1G/`O!6fQYO1G/`O!7VQYO1G/`O!7vQYO1G/`O!8gQYO1G/`O!9WQYO1G/`O!;XQYO1G/`O!;cQYO1G/`O!;mQYO1G/`O,yQUO1G/`O!<^QUO'#DwOFrQUO1G0rOFrQUO1G0pOFrQUO7+&[OFrQUO7+&^O,yQUO7+%tO!>VQYO7+$zO!>vQYO7+&fO!@UQYO<<I`O!@lQYO'#C}O!@tQUO,59tOFrQUO'#ErO8oQUO,5;WO!@yQUO,5;UO!>vQYO,5;YO!>vQYO,5;jO!@yQUO1G0pO8oQUO1G0rO!ARQYO1G0YO!>vQYO,5;[O,yQUO1G0zO!AYQUO'#ElO!A_QUO'#EjO,yQUO'#EnO,yQUO'#FOO!AdQUO,5;UO!AiQUO,5;WO(wQUO,5:nO,yQUO'#EpO!AnQUO,5;`O!AsQUO'#DOO!BUQUO'#Et",
4084 stateData: "!Bq~OPOS$XOS$UOS$TPQ~OVSOWUOYaO]RO^RO_ROamObmOcmOdmOhsOpYOsnOxoO{pO!ZcO!b`O!gqO!srO!ubO!}cO#PtO#RuO#TvO#VwO#XxO#_yO#czO#i{O#k|O#s}O$]RO$^RO$_QO$bVO$cVO~O$T!OO~OW!QO~OV#xXs#xXx#xX!g#xX#[TX#_#xX$STX$VTX~OY!VOu!ROomX}!eX!O!eX!P!eX!Q!eX!R!eX!S!eX!T!eX!U!eX!V!eX!W!eX!X!eX!Y!eX!Z!eX![!eX!_!eX!w!eX!z!eXf!eX!`!eX~O$f!TO$g!TO#[!eX$S!eX$V!eXj!eXX!eX!x!eX~P$hOW!WO~Oo!XO~O}$aX!O$aX!P$aX!Q$aX!R$aX!S$aX!T$aX!U$aX!V$aX!W$aX!X$aX!Y$aX!Z$aX![$aX!_$aX!w$aX!z$aX#[$aX$S$aX$V$aX$f$aX$g$aXf$aXj$aXu$aXX$aX!x$aX!`$aX~Oo!XO~P&vOVSOWUOYaO]RO^RO_ROamObmOcmOdmOpYOsnOxoO{pO!ZcO!b`O!g!`O!srO!ubO!}cO$]RO$^RO$_QO$bVO$cVO~Oj!ZO~P(wOY!VOp!aO!b!bO~P&vOVSOs!dOx!eO!g!gO#_!fO~O}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO!V!pO!W!pO!X!qO!Y!qO!Z!tO![!sO!_!uO!w!rO!z!vO$f!TO$g!TO~O#[SX$SSX$VSX~P+_OVSOW&wOYaO]RO^RO_ROamObmOcmOdmOpYOsnOxoO{&yO!Z&xO!b`O!g!`O!srO!ubO!}&xO$]RO$^RO$_QO$bVO$cVO~O#[#OO$S!|O$V!}O~O#e#UO#g#VOV#aXW#aXY#aX]#aX^#aX_#aXa#aXb#aXc#aXd#aXh#aXp#aXs#aXx#aX{#aX!Z#aX!b#aX!g#aX!s#aX!u#aX!}#aX#P#aX#R#aX#T#aX#V#aX#X#aX#_#aX#c#aX#i#aX#k#aX#s#aX$P#aX$]#aX$^#aX$_#aX$b#aX$c#aX$R#aX$V#aX$l#aX~OW#XO~OW#YO~OW#[O~OY!VO~OW#_O~OW#`O~OW#aO~OW#cO~OW#eO~OW#fO~OP#iO$S#hO$X#jO~OY#kOVUasUaxUa!gUa#[Ua#_Ua$SUa$VUa~OW#mO~OX#pO~P(wO$d#rOona}na!Ona!Pna!Qna!Rna!Sna!Tna!Una!Vna!Wna!Xna!Yna!Zna![na!_na!wna!zna#[na$Sna$Vna$fna$gnafnajnaunaXna!xna!`na~OW#tO~Oo!XOYlapla}la!Ola!Pla!Qla!Rla!Sla!Tla!Ula!Vla!Wla!Xla!Yla!Zla![la!_la!bla!wla!zla#[la$Sla$Vla$fla$glaflajlaulaXla!xla!`la~Oj#wO~OVSOs!dOx!eO~Of#xOj$`XX$`X~P+_OY#zO~Oj#wO~P(wOW$PO~OW$QO~OW$RO~OW$SO~O![$aO~OW$cO~O}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SO!V'TO!W'TO!X'UO!Y'UO!Z'nO!['VO!_!uO!w(PO!z!vO$f&zO~Ou$fO$g$eO~P9kOf$gO!`$hX~O!`$iO~OX$jO~P+_OhsO#PtO#RuO#TvO#VwO#XxO#[#|X$S#|X$V#|X~P(wO#e#UO#g#VOV#aaW#aaY#aa]#aa^#aa_#aaa#aab#aac#aad#aah#aap#aas#aax#aa{#aa!Z#aa!b#aa!g#aa!s#aa!u#aa!}#aa#P#aa#R#aa#T#aa#V#aa#X#aa#_#aa#c#aa#i#aa#k#aa#s#aa$P#aa$]#aa$^#aa$_#aa$b#aa$c#aa$R#aa$V#aa$l#aa~Ou$qO~Ou!RO$fra$gra~Ou!RO$fwa$gwa~OY!VO#[#Sa$S#Sa$V#Sa~O#[#Wa$S#Wa$V#Wa~P+_Ou$qO#RuO~Ou$qO$g&zO~P9kO![$zO~Ou${O~O$S$}O~OP%OO$S$}O~O]RO^RO_ROamObmOcmOdmO$]RO$^RO$_QO~OX%QO~P@}O}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO!V!pO!W!pO!X!qO!Y!qO!Z!tO![!sO!_!uO!w!rO!z!vO~O#[qi$Sqi$Vqi$fqi$gqifqijqiXqi!xqi!`qi~PAvOX%SO~OW%TO~O$d#rOoni}ni!Oni!Pni!Qni!Rni!Sni!Tni!Uni!Vni!Wni!Xni!Yni!Zni![ni!_ni!wni!zni#[ni$Sni$Vni$fni$gnifnijniuniXni!xni!`ni~Oj$`aX$`a~P(wOf%WOj$`aX$`a~OW%YOX%]O~O$k%_Ou$iX~Ou'dO~Oj%bO~O!`%cO~Ou!RO$fri$gri~Ou!RO$fwi$gwi~O}!hO!P|i!Q|i!R|i!S|i!T|i!U|i!V|i!W|i!X|i!Y|i!Z|i![|i!_|i!w|i!z|i#[|i$S|i$V|i$f|i$g|if|ij|iX|i!x|i!`|i~O!O|i~PGiO!O!iO~PGiO}!hO!O!iO!P!jO!R|i!S|i!T|i!U|i!V|i!W|i!X|i!Y|i!Z|i![|i!_|i!w|i!z|i#[|i$S|i$V|i$f|i$g|if|ij|iX|i!x|i!`|i~O!Q|i~PIkO}!hO!O!iO!P!jO!Q!kO!T!nO!U!oO!R|i!V|i!W|i!X|i!Y|i!Z|i![|i!_|i!w|i!z|i#[|i$S|i$V|i$f|i$g|if|ij|iX|i!x|i!`|i~O!S!mO~PKfO!S|i~PKfO}!hO!O!iO!P!jO!Q!kO!R|i!S|i!T|i!V|i!W|i!X|i!Y|i!Z|i![|i!_|i!w|i!z|i#[|i$S|i$V|i$f|i$g|if|ij|iX|i!x|i!`|i~O!U!oO~PMhO!Q!kO~PIkO}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO!Z!tO![!sO!z!vO!X|i!Y|i!_|i!w|i#[|i$S|i$V|i$f|i$g|if|ij|iX|i!x|i!`|i~O!V|i!W|i~P! jO!V!pO!W!pO~P! jO!x%iO~P+_O!V|i!W|i!X|i!Y|i!Z|i![|i!_|i!w|i!z|i$f|i$g|if|i!`|i~O}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO#[|i$S|i$V|ij|iX|i!x|i~P!#vO!`$ha~P,yOf%nO!`$ha~O$S!|O~P`O$S!|O~O$S%wO~Of%xOX$[X~OX%zO~Of#{aj#{aX#{a~P+_Oj$`iX$`i~P(wOu!ROXyXfyX$fyX$gyX~Of%}O$f%|O$g%|OX$jX~Of%}OX$jX~OX&PO~O!V|q!W|q!X|q!Y|q!Z|q![|q!_|q!w|q!z|q$f|q$g|qf|q!`|q~O}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO#[|q$S|q$V|qj|qX|q!x|q~P!(VO}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SO!V'TO!W'TO!X'UO!Y'UO!Z'nO!['VO!_!uO!w(PO!z!vOuqi$fqi$gqi~Of!ci!`!ci~P!*QOf!ci!`!ci~P+_O!`$hi~P,yO$Q&WO~OX$[a~P@}Of&^OX$[a~OW%YOX$ja~Of&cOX$ja~O#e(QO#g'oOf#aXj#aX}#aX!O#aX!P#aX!Q#aX!R#aX!S#aX!T#aX!U#aX!V#aX!W#aX!X#aX!Y#aX!Z#aX![#aX!_#aX!w#aX!z#aX$f#aX$g#aXu#aXX#aX#[#aX$S#aX$V#aX!x#aX!`#aX~O}!hO!O!iO!P!jO!Q!kO!R!lO!S!mO!T!nO!U!oO!V!pO!W!pO!X!qO!Y!qO!Z!tO![!sO!w!rO!z!vO~O!_!vy#[!vy$S!vy$V!vy$f!vy$g!vyf!vyj!vyX!vy!x!vy!`!vy~P!.sOW&gOs&nO$l&iO~P@}OX$[i~P@}OX!iif!ii~P+_O$f%|O$g%|OX#zaf#za~OW%YOX$ji~O#e(QO#g'oOf#aaj#aa}#aa!O#aa!P#aa!Q#aa!R#aa!S#aa!T#aa!U#aa!V#aa!W#aa!X#aa!Y#aa!Z#aa![#aa!_#aa!w#aa!z#aa$f#aa$g#aau#aaX#aa#[#aa$S#aa$V#aa!x#aa!`#aa~O$R&qO$V&rO~P`OW&gOs&nO$R&qO$V!}O$l&iO~P@}OW&vO~OW%YO~O$f&zO$g&zOu!eX~P$hOfqi!`qi~P!*QO}&{Ou|i!O|i!P|i!Q|i!R|i!S|i!T|i!U|i~P!#vO}&{O!O&|Ou|i!P|i!Q|i!R|i!S|i!T|i!U|i~P!#vO}&{O!O&|O!P&}Ou|i!Q|i!R|i!S|i!T|i!U|i~P!#vO}&{O!O&|O!P&}O!Q'OO!S'QO!T'RO!U'SOu|i!R|i~P!#vO}&{O!O&|O!P&}O!Q'OO!T'RO!U'SOu|i!R|i!S|i~P!#vO}&{O!O&|O!P&}O!Q'OO!U'SOu|i!R|i!S|i!T|i~P!#vO}&{O!O&|O!P&}O!Q'OOu|i!R|i!S|i!T|i!U|i~P!#vO}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SO!Z'nO!['VO!z!vOu|i!X|i!Y|i!_|i!w|i$f|i$g|if|i!`|i~O!V|i!W|i~P!9wO!V'TO!W'TO~P!9wO}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SOu|i~P!#vOVSOWUOYaOhsOpYOsnOxoO{pO!ZcO!b`O!g'yO!srO!ubO!}cO#PtO#RuO#TvO#VwO#XxO#_'zO#c'{O#i(TO#k|O#s'|O$S!|O$bVO$cVO~P@}O}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SOu|q~P!(VOu'dO$g&zO~P9kO}&{O!O&|O!P&}O!Q'OO!R'PO!S'QO!T'RO!U'SO!V'TO!W'TO!X'UO!Y'UO!Z'nO!['VO!w(PO!z!vO~Ou!vy!_!vy$f!vy$g!vyf!vy!`!vy~P!?QO$f&zO$g&zO~O!['cO~Ou'dO#RuO~O!x'iO~P+_OW'pO~OW'qO~OW'tO~OW'uO~O!['xO~OVSOs!dOx!eO!g(OO#_'}O~OW(RO~O$^$]]!V!X!Z^_$_!uW$du!}o$l}!O!P!x!w~",
4085 goto: "Ac$kPPP$l$t%P%YPPPP&t&wPPP(jPPPP(jP%PP*VP*e+z-a.yPP*e0`P1uP2W0`P2a*eP*ePPPPPPPPPPPPPP*e*ePP*eP4O*e*e*eP4X4`4h4k5m5q6O6R6X5m*eP*eP*ePP*eP6_*eP%PP6bP%PP%PP%PP6w7QP$l7YP7Y7Y7bP7lP7rP7YP7YP7z8O8S8S8S8S7YP8W8b8h8n8u:e:k:r:x;O;YPPPPPPPPP;`;c;mPPP;p;yPPP?bPP@yAPA`]jOl$q&X&f'd[fOl$q&X&f'dR$k#O_eOl#O$q&X&f'd^TOl#O$q&X&f'd#o!]Y[`acpxz}!T!V!^!a!b!h!i!j!k!l!m!n!o!p!q!r!s#U#x$a$e$f$g$z%W%i%n%{%|&V&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'i'x'{'|(P(Q(SR#l!Q#vdOY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(QQ%P#kU&]%x&^&oT&h&[&m$TROY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#k#x$a$e$f$g$q$z%W%i%n%x%{%|&V&X&[&^&f&m&o&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(QU!UUZ&wQ#]rQ#^sR$v#a#wdOY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(Q#wZOY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(Q#vWOY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(QR#u!X#wXOY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(Q#w]OY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(QU!SU%Y&wQ$s#XQ$t#YQ%d$PR%e$QQ#n!RQ$b!uR&Q%_#v]OY`aclpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$q$z%W%i%n%{%|&V&X&f&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'd'i'x'{'|(P(QQ%Z#zV&a%}&c&pS!x`!bV%m$g%n&VZ#{!`#[$S'p'uQ%[#zV&b%}&c&pR%`#{S$r#V'oS$w#c'qS$y#d'rS$|#g'sQ%a#|W%f$R$x'f'tS%p$p'wS%t$u'eS&S%g'gS&T%h'hS&Z%u'kR&s&kT%s$q'dQ#QfQ$m#PS%q$q'dR%v${R&Y%qQ&X%qR&[%vQ&r&fR&u&mR$d!v^eOl#O$q&X&f'dQ$x#cQ%g$RQ'f'qR'g'tQ#QfQ$m#PR&u&m]gOl$q&X&f'd]iOl$q&X&f'dYhOl$q&X&fR&R'dX#Rh#S&R&eS#Th&RT$o#S&eT&l&[&mT&k&[&mT&j&[&mQlOS#Wl&fR&f&XQ%y%PR&_%yQ#s!WR%U#sS!YWXR#v!YY[Ol$q&X&f#j!^Y`acpxz}!T!V!a!b!h!i!j!k!l!m!n!o!p!q!r!s#O#U#x$a$e$f$g$z%W%i%n%{%|&V&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'i'x'{'|(P(QU!c[!^(SR(S'dQ$h!xR%o$hS&O%Z%[R&d&OQ#y!_R%X#yQ#PfR$l#PQ#ShS$n#S&eR&e&RQ&m&[R&t&mR!PPWkOl&X&fT%r$q'dR%R#kQ![YQ#q!VR#}!a^^Ol#O$q&X&f'dU!_Y!V!aY!w`!b$g%n&VQ!zaS!{c&xS#Zp&yQ#bxQ#dzQ#g}Q#o!TS$T!h&{Q$U!iQ$V!jQ$W!kQ$X!lQ$Y!mQ$Z!nQ$[!oQ$]!pQ$^!qQ$_!rQ$`!sQ$p#UU%V#x%W%{Q%j$aQ%k$eQ%l$fQ%u$zQ&U%iQ&`%|Q'W&zQ'X&|Q'Y&}Q'Z'OQ'['PQ']'QQ'^'RQ'_'SQ'`'TQ'a'UQ'b'VQ'j'cQ'k'xQ'l'iQ'r'{Q's'|Q'v(PR'w(Q!h_OYaclpx!T!V!a!h!i!j!k!l!m!n!o!p!q!r!s#O#x$a$f$q%W%i%{%|&X&f'd(P!_'m`z}!b#U$e$g$z%n&V&x&y&z&{&|&}'O'P'Q'R'S'T'U'V'c'i'x'{'|(QQ!y`R$O!bQ#|!`Q$u#[Q%h$SQ'e'pR'h'uR%^#z",
4086 nodeNames: "\u26A0 Comment Script SimpleStatement SmallStatement StandaloneAnnotationNode AnnotationNode @ Identifier ) ( CallParamsLiteralExpressionNode LiteralExpressionNode True False Null BuiltinConstants PI TAU INF NaN String , AssertNode assert CallParamsExpressionNode ] ArrayExpressionNode SubscriptExpressionNode VariableName GetNodeExpressionNode . [ AssignmentExpressionNode VariableNode var TypeCast : Type ConstantNode const ParameterNode AwaitExpressionNode await BinaryOperatorExpressionNode ArithOp ArithOp ArithOp BitOp CompareOp BitOp BitOp BitOp AndOp LogicOp OrOp LogicOp NotOp in CallExpressionNode CastExpressionNode as } DictionaryExpressionNode { DictionaryEntry GroupedExpressionNode IdentifierExpressionNode LambdaExpressionNode func CallParamsParameterNode AssignmentExpressionNode FunctionReturnType Body SuiteNodeBody Newline SuiteNode Indent Dedent ExpressionNodeBody PreloadExpressionNode preload SelfExpressionNode SelfToken TernaryOperatorExpressionNode TernaryOp TernaryOp TypeTestExpressionNode is ClassName UnaryOperatorNode ArithOp ClassNameStatement class_name ExtendsStatement extends SignalStatement signal PassStatement pass ReturnNode return Eof StatementGroup ; CompoundStatement ClassNode class FunctionNode IfNode IfClause if ElifClause elif ElseClause else ForNode for MatchNode match MatchBranchNode PatternNode VarPatternNode IdentifierPatternNode LiteralPatternNode WildcardPatternNode WhileNode while",
4087 maxTerm: 166,
4088 context: trackIndent,
4089 nodeProps: [
4090 ["group", -2, 3, 105, "Statement", -18, 12, 27, 28, 30, 33, 42, 44, 59, 60, 63, 66, 67, 68, 80, 82, 84, 87, 90, "ExpressionNode", -3, 34, 39, 41, "AssignableNode"],
4091 ["openedBy", 9, "("],
4092 ["closedBy", 10, ")"]
4093 ],
4094 propSources: [gdscriptHighlighting],
4095 skippedNodes: [0, 1],
4096 repeatNodeCount: 11,
4097 tokenData: "Ae~R|XY#{pq#{qr$Wrs$est(Vtu(quv(vvw)Vwx)jxy-[yz-az{-f{|-y|}.T}!O.Y!O!P.l!P!Q/w!Q!R0R!R![0s![!]2e!]!^2l!^!_2q!_!`3U!`!a3^!a!b3z!b!c4S!c!}4X!}#O4j#P#Q4o#Q#R4t#R#S4|#T#U5a#U#Y4X#Y#Z6t#Z#b4X#b#c9U#c#d<S#d#g4X#g#h=O#h#i>z#i#o4X#o#p@v#p#q@{#q#rA`~$QQ$X~XY#{pq#{R$]P!}P!_!`$`Q$eO!RQ~$hXOY$eZ]$e^r$ers%Ts#O$e#O#P%u#P;'S$e;'S;=`(P<%lO$e~%YX$_~OY$eZ]$e^r$ers%Ts#O$e#O#P%u#P;'S$e;'S;=`(P<%lO$e~%xVO#i$e#i#j&_#j#l$e#l#m&z#m;'S$e;'S;=`(P<%lO$e~&bS!Q![&n!c!i&n#T#Z&n#o#p'd~&qR!Q![&z!c!i&z#T#Z&z~&}R!Q!['W!c!i'W#T#Z'W~'ZR!Q![$e!c!i$e#T#Z$e~'gR!Q!['p!c!i'p#T#Z'p~'sS!Q!['p!c!i'p#T#Z'p#q#r$e~(SP;=`<%l$e~([TP~OY(VZ](V^;'S(V;'S;=`(k<%lO(V~(nP;=`<%l(V~(vO$b~R(}P$cP!OQ!_!`)QQ)VO$fQ~)[Q!U~vw)b!_!`)Q~)gP!W~!_!`)Q~)mXOY)jZ])j^w)jwx*Yx#O)j#O#P*z#P;'S)j;'S;=`-U<%lO)j~*_X$_~OY)jZ])j^w)jwx*Yx#O)j#O#P*z#P;'S)j;'S;=`-U<%lO)j~*}VO#i)j#i#j+d#j#l)j#l#m,P#m;'S)j;'S;=`-U<%lO)j~+gS!Q![+s!c!i+s#T#Z+s#o#p,i~+vR!Q![,P!c!i,P#T#Z,P~,SR!Q![,]!c!i,]#T#Z,]~,`R!Q![)j!c!i)j#T#Z)j~,lR!Q![,u!c!i,u#T#Z,u~,xS!Q![,u!c!i,u#T#Z,u#q#r)j~-XP;=`<%l)j~-aOY~~-fOX~~-kQ!OQz{-q!_!`)Q~-vP}~!_!`)QR.QP!}P!PQ!_!`)Q~.YOf~V.aQ!}P!PQ!_!`)Q!`!a.gS.lO$kS~.qPo~!Q![.t~.yS$^~!Q![.t!g!h/V#R#S/q#X#Y/V~/YQ{|/`}!O/`~/cP!Q![/f~/kQ$^~!Q![/f#R#S/`~/tP!Q![.t~0OP$d~!OQ!_!`)Q~0WX$]~!O!P/q!Q![0s!d!e1_!g!h/V!z!{1v#R#S1X#U#V1_#X#Y/V#l#m1v~0xT$]~!O!P/q!Q![0s!g!h/V#R#S1X#X#Y/V~1[P!Q![0s~1bQ!Q!R1h!R!S1h~1mR$]~!Q!R1h!R!S1h#R#S1_~1yR!Q![2S!c!i2S#T#Z2S~2XS$]~!Q![2S!c!i2S#R#S1v#T#Z2S~2lOu~!x~~2qO#[~~2vQ!RQ!^!_2|!_!`$`~3RP!Q~!_!`)Q~3ZP$g~!_!`$`~3cQ!RQ!_!`$`!`!a3i~3nQ!Q~!_!`)Q!`!a3tQ3wP!_!`)Q~4PP!w~!a!b3t~4XOV~~4^SW~!Q![4X!c!}4X#R#S4X#T#o4X~4oOp~~4tOj~~4yP!T~!_!`)Q~5TSW~$l~!Q![4X!c!}4X#R#S4X#T#o4X~5fUW~!Q![4X!c!}4X#R#S4X#T#b4X#b#c5x#c#o4X~5}UW~!Q![4X!c!}4X#R#S4X#T#W4X#W#X6a#X#o4X~6hS!V~W~!Q![4X!c!}4X#R#S4X#T#o4X~6yTW~!Q![4X!c!}4X#R#S4X#T#U7Y#U#o4X~7_UW~!Q![4X!c!}4X#R#S4X#T#`4X#`#a7q#a#o4X~7vUW~!Q![4X!c!}4X#R#S4X#T#g4X#g#h8Y#h#o4X~8_UW~!Q![4X!c!}4X#R#S4X#T#X4X#X#Y8q#Y#o4X~8xS^~W~!Q![4X!c!}4X#R#S4X#T#o4X~9ZWW~!Q![4X!c!}4X#R#S4X#T#c4X#c#d9s#d#i4X#i#j:o#j#o4X~9xUW~!Q![4X!c!}4X#R#S4X#T#h4X#h#i:[#i#o4X~:cS!Z~W~!Q![4X!c!}4X#R#S4X#T#o4X~:tUW~!Q![4X!c!}4X#R#S4X#T#`4X#`#a;W#a#o4X~;]UW~!Q![4X!c!}4X#R#S4X#T#`4X#`#a;o#a#o4X~;vS_~W~!Q![4X!c!}4X#R#S4X#T#o4X~<XUW~!Q![4X!c!}4X#R#S4X#T#f4X#f#g<k#g#o4X~<rS!X~W~!Q![4X!c!}4X#R#S4X#T#o4X~=TUW~!Q![4X!c!}4X#R#S4X#T#X4X#X#Y=g#Y#o4X~=lUW~!Q![4X!c!}4X#R#S4X#T#`4X#`#a>O#a#o4X~>TUW~!Q![4X!c!}4X#R#S4X#T#Y4X#Y#Z>g#Z#o4X~>nS!u~W~!Q![4X!c!}4X#R#S4X#T#o4X~?PUW~!Q![4X!c!}4X#R#S4X#T#f4X#f#g?c#g#o4X~?hUW~!Q![4X!c!}4X#R#S4X#T#i4X#i#j?z#j#o4X~@PUW~!Q![4X!c!}4X#R#S4X#T#X4X#X#Y@c#Y#o4X~@jS]~W~!Q![4X!c!}4X#R#S4X#T#o4X~@{O!b~~AQQ!S~!_!`)Q#p#qAW~A]P!Y~!_!`)Q~AeO!`~",
4098 tokenizers: [indentation, newlines, 0, 1, 2],
4099 topRules: { "Script": [0, 2] },
4100 specialized: [{ term: 8, get: (value) => spec_Identifier[value] || -1 }],
4101 tokenPrec: 3645
4102});
4103export {
4104 parser
4105};