From e471646d2a206a1289c66724affa54676ec4288b Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Sun, 21 Sep 2025 16:56:45 -0400 Subject: [PATCH 001/140] test windows --- .github/workflows/build.yml | 5 +---- .github/workflows/ci.yml | 2 +- crates/loader/src/loader.rs | 16 ++++++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62b45485..2131305f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,10 +74,7 @@ jobs: run: | printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV - if [[ '${{ matrix.platform }}' =~ ^windows ]]; then - # Prevent race condition (see #2041) - printf 'RUST_TEST_THREADS=1\n' >> $GITHUB_ENV - elif [[ '${{ matrix.cross }}' == true ]]; then + if [[ '${{ matrix.cross }}' == true ]]; then for target in armv7-unknown-linux-gnueabihf i686-unknown-linux-gnu powerpc64-unknown-linux-gnu; do camel_target=${target//-/_}; target_cc=${target/-unknown/} printf 'CC_%s=%s\n' "$camel_target" "${target_cc/v7/}-gcc" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f10394b2..a4452316 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ on: - LICENSE - cli/src/templates push: - branches: [master] + # branches: [master] paths-ignore: - docs/** - "**/README.md" diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index cbff2fc6..b2d424a7 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -908,7 +908,23 @@ impl Loader { let out = format!("-out:{}", output_path.to_str().unwrap()); command.arg(if self.debug_build { "-LDd" } else { "-LD" }); command.arg("-utf-8"); + + // Use output directory for object files to avoid conflicts in parallel tests + let output_dir = output_path.parent().unwrap(); + let pid = std::process::id(); + let tid = format!("{:?}", std::thread::current().id()) + .replace("ThreadId(", "") + .replace(")", ""); + + // Create a unique subdirectory for this compilation to avoid conflicts + let obj_dir = output_dir.join(format!("obj_{pid}_{tid}")); + std::fs::create_dir_all(&obj_dir).unwrap(); + + // Use /Fo with directory path (must end with \) for multiple source files + let fo_arg = format!("/Fo{}\\", obj_dir.to_str().unwrap()); + command.arg(fo_arg); command.args(cc_config.get_files()); + command.arg("-link").arg(out); } else { command.arg("-Werror=implicit-function-declaration"); From 92efd26380b103547678950c9d1a813aa8fb7efe Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Sun, 21 Sep 2025 16:56:45 -0400 Subject: [PATCH 002/140] fix(loader): allow parallel compilation on windows --- .github/workflows/build.yml | 5 +---- crates/loader/src/loader.rs | 25 +++++++++++++++++++++++-- crates/xtask/src/test.rs | 6 ------ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 62b45485..2131305f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -74,10 +74,7 @@ jobs: run: | printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV - if [[ '${{ matrix.platform }}' =~ ^windows ]]; then - # Prevent race condition (see #2041) - printf 'RUST_TEST_THREADS=1\n' >> $GITHUB_ENV - elif [[ '${{ matrix.cross }}' == true ]]; then + if [[ '${{ matrix.cross }}' == true ]]; then for target in armv7-unknown-linux-gnueabihf i686-unknown-linux-gnu powerpc64-unknown-linux-gnu; do camel_target=${target//-/_}; target_cc=${target/-unknown/} printf 'CC_%s=%s\n' "$camel_target" "${target_cc/v7/}-gcc" diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index cbff2fc6..39099797 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -904,12 +904,27 @@ impl Loader { let output_path = config.output_path.as_ref().unwrap(); - if compiler.is_like_msvc() { + let temp_dir = if compiler.is_like_msvc() { let out = format!("-out:{}", output_path.to_str().unwrap()); command.arg(if self.debug_build { "-LDd" } else { "-LD" }); command.arg("-utf-8"); + + // Windows creates intermediate files when compiling (.exp, .lib, .obj), which causes + // issues when multiple processes are compiling in the same directory. This creates a + // temporary directory for those files to go into, which is deleted after compilation. + let temp_dir = output_path.parent().unwrap().join(format!( + "tmp_{}_{:?}", + std::process::id(), + std::thread::current().id() + )); + std::fs::create_dir_all(&temp_dir).unwrap(); + + command.arg(format!("/Fo{}\\", temp_dir.display())); command.args(cc_config.get_files()); command.arg("-link").arg(out); + command.arg(format!("/IMPLIB:{}.lib", temp_dir.join("temp").display())); + + Some(temp_dir) } else { command.arg("-Werror=implicit-function-declaration"); if cfg!(any(target_os = "macos", target_os = "ios")) { @@ -921,12 +936,18 @@ impl Loader { } command.args(cc_config.get_files()); command.arg("-o").arg(output_path); - } + + None + }; let output = command.output().with_context(|| { format!("Failed to execute the C compiler with the following command:\n{command:?}") })?; + if let Some(temp_dir) = temp_dir { + let _ = fs::remove_dir_all(temp_dir); + } + FileExt::unlock(lock_file)?; fs::remove_file(lock_path)?; diff --git a/crates/xtask/src/test.rs b/crates/xtask/src/test.rs index 467245dc..6b8d8243 100644 --- a/crates/xtask/src/test.rs +++ b/crates/xtask/src/test.rs @@ -73,9 +73,6 @@ pub fn run(args: &Test) -> Result<()> { .arg("--no-run") .arg("--message-format=json"); - #[cfg(target_os = "windows")] - cargo_cmd.arg("--").arg("--test-threads=1"); - let cargo_cmd = cargo_cmd.stdout(Stdio::piped()).spawn()?; let jq_cmd = Command::new("jq") @@ -103,9 +100,6 @@ pub fn run(args: &Test) -> Result<()> { } cargo_cmd.args(&args.args); - #[cfg(target_os = "windows")] - cargo_cmd.arg("--").arg("--test-threads=1"); - if args.nocapture { #[cfg(not(target_os = "windows"))] cargo_cmd.arg("--"); From c5b22a1dc66bdeaed99596497dac7194d1da809f Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Mon, 29 Sep 2025 04:39:44 -0400 Subject: [PATCH 003/140] ci: split cross compilation and emscripten tag read --- .github/workflows/build.yml | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2131305f..7697ac8f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,22 +70,23 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 - - name: Set up environment + - name: Set up cross-compilation + if: matrix.cross run: | - printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV + for target in armv7-unknown-linux-gnueabihf i686-unknown-linux-gnu powerpc64-unknown-linux-gnu; do + camel_target=${target//-/_}; target_cc=${target/-unknown/} + printf 'CC_%s=%s\n' "$camel_target" "${target_cc/v7/}-gcc" + printf 'AR_%s=%s\n' "$camel_target" "${target_cc/v7/}-ar" + printf 'CARGO_TARGET_%s_LINKER=%s\n' "${camel_target^^}" "${target_cc/v7/}-gcc" + done >> $GITHUB_ENV + { + printf 'CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm -L /usr/arm-linux-gnueabihf\n' + printf 'CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64 -L /usr/powerpc64-linux-gnu\n' + } >> $GITHUB_ENV - if [[ '${{ matrix.cross }}' == true ]]; then - for target in armv7-unknown-linux-gnueabihf i686-unknown-linux-gnu powerpc64-unknown-linux-gnu; do - camel_target=${target//-/_}; target_cc=${target/-unknown/} - printf 'CC_%s=%s\n' "$camel_target" "${target_cc/v7/}-gcc" - printf 'AR_%s=%s\n' "$camel_target" "${target_cc/v7/}-ar" - printf 'CARGO_TARGET_%s_LINKER=%s\n' "${camel_target^^}" "${target_cc/v7/}-gcc" - done >> $GITHUB_ENV - { - printf 'CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm -L /usr/arm-linux-gnueabihf\n' - printf 'CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64 -L /usr/powerpc64-linux-gnu\n' - } >> $GITHUB_ENV - fi + - name: Get emscripten version + if: contains(matrix.features, 'wasm') + run: printf 'EMSCRIPTEN_VERSION=%s\n' "$(> $GITHUB_ENV - name: Install Emscripten if: contains(matrix.features, 'wasm') From 1dc4804b6eed75d59b31cc7080d770f6a5ca85b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Sep 2025 22:50:35 +0000 Subject: [PATCH 004/140] build(deps): bump the cargo group with 2 updates Bumps the cargo group with 2 updates: [memchr](https://github.com/BurntSushi/memchr) and [regex](https://github.com/rust-lang/regex). Updates `memchr` from 2.7.5 to 2.7.6 - [Commits](https://github.com/BurntSushi/memchr/compare/2.7.5...2.7.6) Updates `regex` from 1.11.2 to 1.11.3 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.11.2...1.11.3) --- updated-dependencies: - dependency-name: memchr dependency-version: 2.7.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: regex dependency-version: 1.11.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 12 ++++++------ Cargo.toml | 4 ++-- lib/Cargo.toml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07246ee0..65cfb44c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1108,9 +1108,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memfd" @@ -1448,9 +1448,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -1460,9 +1460,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", diff --git a/Cargo.toml b/Cargo.toml index c9c21300..23d11357 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,11 +130,11 @@ indexmap = "2.11.4" indoc = "2.0.6" libloading = "0.8.9" log = { version = "0.4.28", features = ["std"] } -memchr = "2.7.5" +memchr = "2.7.6" once_cell = "1.21.3" pretty_assertions = "1.4.1" rand = "0.8.5" -regex = "1.11.2" +regex = "1.11.3" regex-syntax = "0.8.6" rustc-hash = "2.1.1" semver = { version = "1.0.27", features = ["serde"] } diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 45434a7a..64a9e8eb 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -47,7 +47,7 @@ std = ["regex/std", "regex/perf", "regex-syntax/unicode"] wasm = ["std", "wasmtime-c-api"] [dependencies] -regex = { version = "1.11.2", default-features = false, features = ["unicode"] } +regex = { version = "1.11.3", default-features = false, features = ["unicode"] } regex-syntax = { version = "0.8.6", default-features = false } tree-sitter-language.workspace = true streaming-iterator = "0.1.9" From 0cf6e7c5074e20781d8c4540bc71ab905843a24b Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Wed, 1 Oct 2025 09:33:38 +0300 Subject: [PATCH 005/140] fix(cli): prevent crash when parsing stdin When we are parsing stdin via a pipe or heredoc, the source count is 0 (unsigned) so the XML output crashes while trying to subtract from it. --- crates/cli/src/parse.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 61e4a86f..4b941fe3 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -230,13 +230,23 @@ impl ParseSummary { } } -#[derive(Serialize, Debug, Default)] +#[derive(Serialize, Debug)] pub struct ParseStats { pub parse_summaries: Vec, pub cumulative_stats: Stats, pub source_count: usize, } +impl Default for ParseStats { + fn default() -> Self { + Self { + parse_summaries: Vec::new(), + cumulative_stats: Stats::default(), + source_count: 1, + } + } +} + #[derive(Serialize, ValueEnum, Debug, Copy, Clone, Default, Eq, PartialEq)] pub enum ParseDebugType { #[default] From 0f5ccc4aba64096b74b7875fbc53d285515650ac Mon Sep 17 00:00:00 2001 From: Mihai-Daniel Potirniche Date: Sat, 4 Oct 2025 14:41:13 +0300 Subject: [PATCH 006/140] Fix typo --- crates/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 6f64c801..5b1948e2 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1078,7 +1078,7 @@ impl Parse { lib_info.as_ref(), ) .with_context(|| { - anyhow!("Failed to load langauge for path \"{}\"", path.display()) + anyhow!("Failed to load language for path \"{}\"", path.display()) })?; parse::parse_file_at_path( From 7d0e029e37a0c18d2a04bede09028a4f03c17d28 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sat, 4 Oct 2025 10:39:28 +0300 Subject: [PATCH 007/140] chore: add schema for node-types.json --- .../src/assets/schemas/node-types.schema.json | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 docs/src/assets/schemas/node-types.schema.json diff --git a/docs/src/assets/schemas/node-types.schema.json b/docs/src/assets/schemas/node-types.schema.json new file mode 100644 index 00000000..7ea8a5af --- /dev/null +++ b/docs/src/assets/schemas/node-types.schema.json @@ -0,0 +1,108 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Tree-sitter node types specification", + "type": "array", + "items": { + "$ref": "#/definitions/NodeInfo" + }, + "definitions": { + "NodeInfo": { + "type": "object", + "required": [ + "type", + "named" + ], + "properties": { + "type": { + "type": "string" + }, + "named": { + "type": "boolean" + }, + "root": { + "type": "boolean", + "default": false + }, + "extra": { + "type": "boolean", + "default": false + }, + "fields": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/FieldInfo" + } + }, + "children": { + "$ref": "#/definitions/FieldInfo" + }, + "subtypes": { + "type": "array", + "items": { + "$ref": "#/definitions/NodeType" + } + } + }, + "oneOf": [ + { + "description": "Regular node", + "properties": { + "subtypes": false + } + }, + { + "description": "Supertype node", + "required": [ + "subtypes" + ], + "properties": { + "children": false, + "fields": false + } + } + ] + }, + "NodeType": { + "type": "object", + "required": [ + "type", + "named" + ], + "properties": { + "type": { + "type": "string", + "description": "The kind of node type" + }, + "named": { + "type": "boolean", + "description": "Whether the node type is named" + } + } + }, + "FieldInfo": { + "type": "object", + "required": [ + "multiple", + "required", + "types" + ], + "properties": { + "multiple": { + "type": "boolean", + "default": false + }, + "required": { + "type": "boolean", + "default": true + }, + "types": { + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/NodeType" + } + } + } + } + } +} From 3355825a687d6334d72c789cdbcc8417dd80920f Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 6 Oct 2025 18:03:18 -0400 Subject: [PATCH 008/140] fix(cli): don't load languages for `build` command --- crates/cli/src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 5b1948e2..ad7667c2 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -939,9 +939,6 @@ impl Build { loader.force_rebuild(true); - let config = Config::load(None)?; - let loader_config = config.get()?; - loader.find_all_languages(&loader_config).unwrap(); loader .compile_parser_at_path(&grammar_path, output_path, flags) .unwrap(); From ae54350c768bef373c92791d782d12f7c86425be Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Thu, 9 Oct 2025 18:08:59 -0400 Subject: [PATCH 009/140] fix(generate): Add missing fields to `NodeInfoJson` sorting This ensures a deterministic ordering for node-types.json --- crates/generate/src/node_types.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/generate/src/node_types.rs b/crates/generate/src/node_types.rs index 748a3d58..8b7eb397 100644 --- a/crates/generate/src/node_types.rs +++ b/crates/generate/src/node_types.rs @@ -784,6 +784,9 @@ pub fn generate_node_types_json( a_is_leaf.cmp(&b_is_leaf) }) .then_with(|| a.kind.cmp(&b.kind)) + .then_with(|| a.named.cmp(&b.named)) + .then_with(|| a.root.cmp(&b.root)) + .then_with(|| a.extra.cmp(&b.extra)) }); result.dedup(); Ok(result) From 00d172bf9f13a187756761ab300c9b5c05e4360d Mon Sep 17 00:00:00 2001 From: WillLillis Date: Mon, 6 Oct 2025 00:26:24 -0400 Subject: [PATCH 010/140] fix(generate): correct display of precedence for `--report-states-for-rule` --- crates/generate/src/build_tables/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/generate/src/build_tables/item.rs b/crates/generate/src/build_tables/item.rs index 0beb3e3c..cd70ce74 100644 --- a/crates/generate/src/build_tables/item.rs +++ b/crates/generate/src/build_tables/item.rs @@ -204,7 +204,7 @@ impl fmt::Display for ParseItemDisplay<'_> { || step.reserved_word_set_id != ReservedWordSetId::default() { write!(f, " (")?; - if step.precedence.is_none() { + if !step.precedence.is_none() { write!(f, " {}", step.precedence)?; } if let Some(associativity) = step.associativity { From 262f1782cc6d6194b9010c92274e8127e0432e50 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sat, 11 Oct 2025 17:33:47 -0400 Subject: [PATCH 011/140] fix(generate): ensure deterministic iteration order for symbol aliases while constructing node-types.json --- crates/generate/src/node_types.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/generate/src/node_types.rs b/crates/generate/src/node_types.rs index 8b7eb397..f50af44f 100644 --- a/crates/generate/src/node_types.rs +++ b/crates/generate/src/node_types.rs @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use anyhow::Result; use serde::Serialize; @@ -378,11 +378,11 @@ pub fn get_variable_info( fn get_aliases_by_symbol( syntax_grammar: &SyntaxGrammar, default_aliases: &AliasMap, -) -> HashMap>> { +) -> HashMap>> { let mut aliases_by_symbol = HashMap::new(); for (symbol, alias) in default_aliases { aliases_by_symbol.insert(*symbol, { - let mut aliases = HashSet::new(); + let mut aliases = BTreeSet::new(); aliases.insert(Some(alias.clone())); aliases }); @@ -391,7 +391,7 @@ fn get_aliases_by_symbol( if !default_aliases.contains_key(extra_symbol) { aliases_by_symbol .entry(*extra_symbol) - .or_insert_with(HashSet::new) + .or_insert_with(BTreeSet::new) .insert(None); } } @@ -400,7 +400,7 @@ fn get_aliases_by_symbol( for step in &production.steps { aliases_by_symbol .entry(step.symbol) - .or_insert_with(HashSet::new) + .or_insert_with(BTreeSet::new) .insert( step.alias .as_ref() @@ -531,7 +531,7 @@ pub fn generate_node_types_json( let aliases_by_symbol = get_aliases_by_symbol(syntax_grammar, default_aliases); - let empty = HashSet::new(); + let empty = BTreeSet::new(); let extra_names = syntax_grammar .extra_symbols .iter() @@ -590,7 +590,7 @@ pub fn generate_node_types_json( } else if !syntax_grammar.variables_to_inline.contains(&symbol) { // If a rule is aliased under multiple names, then its information // contributes to multiple entries in the final JSON. - for alias in aliases_by_symbol.get(&symbol).unwrap_or(&HashSet::new()) { + for alias in aliases_by_symbol.get(&symbol).unwrap_or(&BTreeSet::new()) { let kind; let is_named; if let Some(alias) = alias { From b3bc7701cd09171635454b32ca37307354248d4a Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sat, 11 Oct 2025 17:51:48 -0400 Subject: [PATCH 012/140] refactor(generate): make `AliasMap` use `BTreeMap` over `HashMap` --- crates/generate/src/generate.rs | 4 ++-- crates/generate/src/rules.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/generate/src/generate.rs b/crates/generate/src/generate.rs index 09e6e389..c4a1ec84 100644 --- a/crates/generate/src/generate.rs +++ b/crates/generate/src/generate.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, sync::LazyLock}; +use std::{collections::BTreeMap, sync::LazyLock}; #[cfg(feature = "load")] use std::{ env, fs, @@ -57,7 +57,7 @@ struct JSONOutput { syntax_grammar: SyntaxGrammar, lexical_grammar: LexicalGrammar, inlines: InlinedProductionMap, - simple_aliases: HashMap, + simple_aliases: BTreeMap, variable_info: Vec, } diff --git a/crates/generate/src/rules.rs b/crates/generate/src/rules.rs index cd4aa482..a8499166 100644 --- a/crates/generate/src/rules.rs +++ b/crates/generate/src/rules.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fmt}; +use std::{collections::BTreeMap, fmt}; use serde::Serialize; use smallbitvec::SmallBitVec; @@ -34,7 +34,7 @@ pub enum Precedence { Name(String), } -pub type AliasMap = HashMap; +pub type AliasMap = BTreeMap; #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize)] pub struct MetadataParams { From da5926d6f571475625bd631c593b255c437e9135 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 21:09:27 +0000 Subject: [PATCH 013/140] build(deps): bump the cargo group across 1 directory with 4 updates Bumps the cargo group with 4 updates in the / directory: [anstyle](https://github.com/rust-cli/anstyle), [cc](https://github.com/rust-lang/cc-rs), [thiserror](https://github.com/dtolnay/thiserror) and [widestring](https://github.com/VoidStarKat/widestring-rs). Updates `anstyle` from 1.0.11 to 1.0.13 - [Commits](https://github.com/rust-cli/anstyle/compare/v1.0.11...v1.0.13) Updates `cc` from 1.2.39 to 1.2.41 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.39...cc-v1.2.41) Updates `thiserror` from 2.0.16 to 2.0.17 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/2.0.16...2.0.17) Updates `widestring` from 1.2.0 to 1.2.1 - [Release notes](https://github.com/VoidStarKat/widestring-rs/releases) - [Changelog](https://github.com/VoidStarKat/widestring-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/VoidStarKat/widestring-rs/compare/v1.2.0...v1.2.1) --- updated-dependencies: - dependency-name: anstyle dependency-version: 1.0.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: cc dependency-version: 1.2.41 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: thiserror dependency-version: 2.0.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: widestring dependency-version: 1.2.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 38 +++++++++++++++++++------------------- Cargo.toml | 6 +++--- crates/cli/Cargo.toml | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65cfb44c..14838fdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -192,9 +192,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.39" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "shlex", @@ -309,7 +309,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -658,9 +658,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "fnv" @@ -1771,11 +1771,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -1791,9 +1791,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -1976,7 +1976,7 @@ dependencies = [ "serde_json", "smallbitvec", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "topological-sort", ] @@ -1986,7 +1986,7 @@ version = "0.26.0" dependencies = [ "regex", "streaming-iterator", - "thiserror 2.0.16", + "thiserror 2.0.17", "tree-sitter", ] @@ -2023,7 +2023,7 @@ dependencies = [ "memchr", "regex", "streaming-iterator", - "thiserror 2.0.16", + "thiserror 2.0.17", "tree-sitter", ] @@ -2300,7 +2300,7 @@ dependencies = [ "pulley-interpreter", "smallvec", "target-lexicon", - "thiserror 2.0.16", + "thiserror 2.0.17", "wasmparser", "wasmtime-environ", "wasmtime-versioned-export-macros", @@ -2439,9 +2439,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi-util" @@ -2465,7 +2465,7 @@ dependencies = [ "regalloc2", "smallvec", "target-lexicon", - "thiserror 2.0.16", + "thiserror 2.0.17", "wasmparser", "wasmtime-cranelift", "wasmtime-environ", diff --git a/Cargo.toml b/Cargo.toml index 23d11357..1d5454e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,10 +103,10 @@ codegen-units = 256 [workspace.dependencies] ansi_colours = "1.2.3" -anstyle = "1.0.11" +anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.39" +cc = "1.2.41" clap = { version = "4.5.48", features = [ "cargo", "derive", @@ -144,7 +144,7 @@ similar = "2.7.0" smallbitvec = "2.6.0" streaming-iterator = "0.1.9" tempfile = "3.23.0" -thiserror = "2.0.16" +thiserror = "2.0.17" tiny_http = "0.12.0" topological-sort = "0.2.2" unindent = "0.2.4" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index cebbacd3..d8df92c8 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -73,7 +73,7 @@ tree-sitter-tags.workspace = true [dev-dependencies] encoding_rs = "0.8.35" -widestring = "1.2.0" +widestring = "1.2.1" tree_sitter_proc_macro = { path = "src/tests/proc_macro", package = "tree-sitter-tests-proc-macro" } tempfile.workspace = true From bdee2c2dd3c618de2dcb1e5967fa40477eede53e Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Fri, 3 Oct 2025 20:11:52 +0300 Subject: [PATCH 014/140] ci: use macos-15-intel runner The macos-13 runner will soon be removed. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7697ac8f..8c5af22f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,7 +41,7 @@ jobs: - { platform: windows-x64 , target: x86_64-pc-windows-msvc , os: windows-2025 } - { platform: windows-x86 , target: i686-pc-windows-msvc , os: windows-2025 } - { platform: macos-arm64 , target: aarch64-apple-darwin , os: macos-15 } - - { platform: macos-x64 , target: x86_64-apple-darwin , os: macos-13 } + - { platform: macos-x64 , target: x86_64-apple-darwin , os: macos-15-intel } - { platform: wasm32 , target: wasm32-unknown-unknown , os: ubuntu-24.04 } # Extra features From e344837e35002c93d8805f3c9e0b51e24cca5f8f Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Tue, 14 Oct 2025 17:52:32 -0400 Subject: [PATCH 015/140] fix(rust): minor cleanup in generate code --- crates/generate/src/build_tables/build_parse_table.rs | 9 +++------ crates/generate/src/build_tables/minimize_parse_table.rs | 4 +--- crates/generate/src/build_tables/token_conflicts.rs | 2 +- crates/generate/src/prepare_grammar/expand_tokens.rs | 4 ++-- .../src/prepare_grammar/extract_default_aliases.rs | 4 +--- crates/generate/src/prepare_grammar/extract_tokens.rs | 2 +- lib/binding_rust/lib.rs | 6 +++--- 7 files changed, 12 insertions(+), 19 deletions(-) diff --git a/crates/generate/src/build_tables/build_parse_table.rs b/crates/generate/src/build_tables/build_parse_table.rs index c832157a..66f29609 100644 --- a/crates/generate/src/build_tables/build_parse_table.rs +++ b/crates/generate/src/build_tables/build_parse_table.rs @@ -81,7 +81,7 @@ pub enum ParseTableBuilderError { StateCount(usize), } -#[derive(Default, Debug, Serialize)] +#[derive(Default, Debug, Serialize, Error)] pub struct ConflictError { pub symbol_sequence: Vec, pub conflicting_lookahead: String, @@ -89,7 +89,7 @@ pub struct ConflictError { pub possible_resolutions: Vec, } -#[derive(Default, Debug, Serialize)] +#[derive(Default, Debug, Serialize, Error)] pub struct Interpretation { pub preceding_symbols: Vec, pub variable_name: String, @@ -108,7 +108,7 @@ pub enum Resolution { AddConflict { symbols: Vec }, } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Error)] pub struct AmbiguousExtraError { pub parent_symbols: Vec, } @@ -238,9 +238,6 @@ impl std::fmt::Display for AmbiguousExtraError { } } -impl std::error::Error for ConflictError {} -impl std::error::Error for AmbiguousExtraError {} - impl<'a> ParseTableBuilder<'a> { fn new( syntax_grammar: &'a SyntaxGrammar, diff --git a/crates/generate/src/build_tables/minimize_parse_table.rs b/crates/generate/src/build_tables/minimize_parse_table.rs index 1d70625e..6c26f1c4 100644 --- a/crates/generate/src/build_tables/minimize_parse_table.rs +++ b/crates/generate/src/build_tables/minimize_parse_table.rs @@ -306,9 +306,7 @@ impl Minimizer<'_> { return true; } - for (i, action1) in actions1.iter().enumerate() { - let action2 = &actions2[i]; - + for (action1, action2) in actions1.iter().zip(actions2.iter()) { // Two shift actions are equivalent if their destinations are in the same group. if let ( ParseAction::Shift { diff --git a/crates/generate/src/build_tables/token_conflicts.rs b/crates/generate/src/build_tables/token_conflicts.rs index bacac1b4..d72effd4 100644 --- a/crates/generate/src/build_tables/token_conflicts.rs +++ b/crates/generate/src/build_tables/token_conflicts.rs @@ -28,7 +28,7 @@ pub struct TokenConflictMap<'a> { impl<'a> TokenConflictMap<'a> { /// Create a token conflict map based on a lexical grammar, which describes the structure - /// each token, and a `following_token` map, which indicates which tokens may be appear + /// of each token, and a `following_token` map, which indicates which tokens may be appear /// immediately after each other token. /// /// This analyzes the possible kinds of overlap between each pair of tokens and stores diff --git a/crates/generate/src/prepare_grammar/expand_tokens.rs b/crates/generate/src/prepare_grammar/expand_tokens.rs index 2762b41c..4d8b4f11 100644 --- a/crates/generate/src/prepare_grammar/expand_tokens.rs +++ b/crates/generate/src/prepare_grammar/expand_tokens.rs @@ -27,7 +27,7 @@ pub enum ExpandTokensError { "The rule `{0}` matches the empty string. Tree-sitter does not support syntactic rules that match the empty string unless they are used only as the grammar's start rule. - " +" )] EmptyString(String), #[error(transparent)] @@ -189,7 +189,7 @@ impl NfaBuilder { } Rule::String(s) => { for c in s.chars().rev() { - self.push_advance(CharacterSet::empty().add_char(c), next_state_id); + self.push_advance(CharacterSet::from_char(c), next_state_id); next_state_id = self.nfa.last_state_id(); } Ok(!s.is_empty()) diff --git a/crates/generate/src/prepare_grammar/extract_default_aliases.rs b/crates/generate/src/prepare_grammar/extract_default_aliases.rs index 68ea1e48..cc977362 100644 --- a/crates/generate/src/prepare_grammar/extract_default_aliases.rs +++ b/crates/generate/src/prepare_grammar/extract_default_aliases.rs @@ -69,9 +69,7 @@ pub(super) fn extract_default_aliases( SymbolType::External => &mut external_status_list[symbol.index], SymbolType::NonTerminal => &mut non_terminal_status_list[symbol.index], SymbolType::Terminal => &mut terminal_status_list[symbol.index], - SymbolType::End | SymbolType::EndOfNonTerminalExtra => { - panic!("Unexpected end token") - } + SymbolType::End | SymbolType::EndOfNonTerminalExtra => panic!("Unexpected end token"), }; status.appears_unaliased = true; } diff --git a/crates/generate/src/prepare_grammar/extract_tokens.rs b/crates/generate/src/prepare_grammar/extract_tokens.rs index b74a8e84..a1fddbe6 100644 --- a/crates/generate/src/prepare_grammar/extract_tokens.rs +++ b/crates/generate/src/prepare_grammar/extract_tokens.rs @@ -153,7 +153,7 @@ pub(super) fn extract_tokens( } } - let mut external_tokens = Vec::new(); + let mut external_tokens = Vec::with_capacity(grammar.external_tokens.len()); for external_token in grammar.external_tokens { let rule = symbol_replacer.replace_symbols_in_rule(&external_token.rule); if let Rule::Symbol(symbol) = rule { diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index cf22eb72..a02fa173 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -3190,9 +3190,9 @@ impl QueryCursor { /// The zero max start depth value can be used as a special behavior and /// it helps to destructure a subtree by staying on a node and using /// captures for interested parts. Note that the zero max start depth - /// only limit a search depth for a pattern's root node but other nodes - /// that are parts of the pattern may be searched at any depth what - /// defined by the pattern structure. + /// only limits a search depth for a pattern's root node but other nodes + /// that are parts of the pattern may be searched at any depth depending on + /// what is defined by the pattern structure. /// /// Set to `None` to remove the maximum start depth. #[doc(alias = "ts_query_cursor_set_max_start_depth")] From 87d778a1c6ded60e9c0622539ccf23b4f47632df Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 19 Oct 2025 23:16:42 -0400 Subject: [PATCH 016/140] fix(rust): apply `Self` usage in struct definition lint --- crates/cli/src/test.rs | 2 +- crates/cli/src/tests/helpers/query_helpers.rs | 2 +- crates/generate/src/parse_grammar.rs | 26 +++++++++---------- crates/generate/src/rules.rs | 10 +++---- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index f192f51b..f107cb07 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -65,7 +65,7 @@ static POINT_REGEX: LazyLock = pub enum TestEntry { Group { name: String, - children: Vec, + children: Vec, file_path: Option, }, Example { diff --git a/crates/cli/src/tests/helpers/query_helpers.rs b/crates/cli/src/tests/helpers/query_helpers.rs index bc5617e8..e648ac8e 100644 --- a/crates/cli/src/tests/helpers/query_helpers.rs +++ b/crates/cli/src/tests/helpers/query_helpers.rs @@ -12,7 +12,7 @@ pub struct Pattern { named: bool, field: Option<&'static str>, capture: Option, - children: Vec, + children: Vec, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/crates/generate/src/parse_grammar.rs b/crates/generate/src/parse_grammar.rs index f95eaba4..c48477f0 100644 --- a/crates/generate/src/parse_grammar.rs +++ b/crates/generate/src/parse_grammar.rs @@ -18,7 +18,7 @@ use crate::{ #[allow(clippy::upper_case_acronyms)] enum RuleJSON { ALIAS { - content: Box, + content: Box, named: bool, value: String, }, @@ -34,46 +34,46 @@ enum RuleJSON { name: String, }, CHOICE { - members: Vec, + members: Vec, }, FIELD { name: String, - content: Box, + content: Box, }, SEQ { - members: Vec, + members: Vec, }, REPEAT { - content: Box, + content: Box, }, REPEAT1 { - content: Box, + content: Box, }, PREC_DYNAMIC { value: i32, - content: Box, + content: Box, }, PREC_LEFT { value: PrecedenceValueJSON, - content: Box, + content: Box, }, PREC_RIGHT { value: PrecedenceValueJSON, - content: Box, + content: Box, }, PREC { value: PrecedenceValueJSON, - content: Box, + content: Box, }, TOKEN { - content: Box, + content: Box, }, IMMEDIATE_TOKEN { - content: Box, + content: Box, }, RESERVED { context_name: String, - content: Box, + content: Box, }, } diff --git a/crates/generate/src/rules.rs b/crates/generate/src/rules.rs index a8499166..05a0c426 100644 --- a/crates/generate/src/rules.rs +++ b/crates/generate/src/rules.rs @@ -60,15 +60,15 @@ pub enum Rule { Pattern(String, String), NamedSymbol(String), Symbol(Symbol), - Choice(Vec), + Choice(Vec), Metadata { params: MetadataParams, - rule: Box, + rule: Box, }, - Repeat(Box), - Seq(Vec), + Repeat(Box), + Seq(Vec), Reserved { - rule: Box, + rule: Box, context_name: String, }, } From a2f2b16acb67a7659331ab12ab7cfbef4567ba31 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Mon, 6 Oct 2025 01:53:00 -0400 Subject: [PATCH 017/140] fix(xtask): require `version` argument for `bump-version` command --- crates/xtask/src/bump.rs | 100 +-------------------------------------- crates/xtask/src/main.rs | 4 +- 2 files changed, 4 insertions(+), 100 deletions(-) diff --git a/crates/xtask/src/bump.rs b/crates/xtask/src/bump.rs index 7e5f5dcd..02254274 100644 --- a/crates/xtask/src/bump.rs +++ b/crates/xtask/src/bump.rs @@ -2,7 +2,7 @@ use std::{cmp::Ordering, path::Path}; use anyhow::{anyhow, Context, Result}; use indoc::indoc; -use semver::{BuildMetadata, Prerelease, Version}; +use semver::{Prerelease, Version}; use crate::{create_commit, BumpVersion}; @@ -48,7 +48,6 @@ pub fn run(args: BumpVersion) -> Result<()> { String::from_utf8_lossy(&output.stderr) ); } - let latest_tag_sha = String::from_utf8(output.stdout)?.trim().to_string(); let workspace_toml_version = Version::parse(&fetch_workspace_version()?)?; @@ -65,102 +64,7 @@ pub fn run(args: BumpVersion) -> Result<()> { return Ok(()); } - let output = std::process::Command::new("git") - .args(["rev-list", &format!("{latest_tag_sha}..HEAD")]) - .output()?; - if !output.status.success() { - anyhow::bail!( - "Failed to get commits: {}", - String::from_utf8_lossy(&output.stderr) - ); - } - let commits = String::from_utf8(output.stdout)? - .lines() - .map(|s| s.to_string()) - .collect::>(); - - let mut should_increment_patch = false; - let mut should_increment_minor = false; - - for commit_sha in commits { - let output = std::process::Command::new("git") - .args(["log", "-1", "--format=%s", &commit_sha]) - .output()?; - if !output.status.success() { - continue; - } - let message = String::from_utf8(output.stdout)?.trim().to_string(); - - let output = std::process::Command::new("git") - .args([ - "diff-tree", - "--no-commit-id", - "--name-only", - "-r", - &commit_sha, - ]) - .output()?; - if !output.status.success() { - continue; - } - - let mut source_code_changed = false; - for path in String::from_utf8(output.stdout)?.lines() { - let path = Path::new(path); - if path.extension().is_some_and(|ext| { - ext.eq_ignore_ascii_case("rs") - || ext.eq_ignore_ascii_case("js") - || ext.eq_ignore_ascii_case("c") - }) { - source_code_changed = true; - break; - } - } - - if source_code_changed { - should_increment_patch = true; - - let Some((prefix, _)) = message.split_once(':') else { - continue; - }; - - let convention = if prefix.contains('(') { - prefix.split_once('(').unwrap().0 - } else { - prefix - }; - - if ["feat", "feat!"].contains(&convention) || prefix.ends_with('!') { - should_increment_minor = true; - } - } - } - - let next_version = if let Some(version) = args.version { - version - } else { - let mut next_version = current_version.clone(); - if should_increment_minor { - next_version.minor += 1; - next_version.patch = 0; - next_version.pre = Prerelease::EMPTY; - next_version.build = BuildMetadata::EMPTY; - } else if should_increment_patch { - next_version.patch += 1; - next_version.pre = Prerelease::EMPTY; - next_version.build = BuildMetadata::EMPTY; - } else { - return Err(anyhow!(format!( - "No source code changed since {current_version}" - ))); - } - next_version - }; - if next_version <= current_version { - return Err(anyhow!(format!( - "Next version {next_version} must be greater than current version {current_version}" - ))); - } + let next_version = args.version; println!("Bumping from {current_version} to {next_version}"); update_crates(¤t_version, &next_version)?; diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 57f81dae..46b2e796 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -94,8 +94,8 @@ struct BuildWasm { #[derive(Args)] struct BumpVersion { /// The version to bump to. - #[arg(long, short)] - version: Option, + #[arg(index = 1, required = true)] + version: Version, } #[derive(Args)] From 605e58006351ff2d133e69dfc617268ab9887a8d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Oct 2025 22:41:26 +0000 Subject: [PATCH 018/140] ci: bump the actions group across 1 directory with 3 updates Bumps the actions group with 3 updates in the / directory: [actions/upload-artifact](https://github.com/actions/upload-artifact), [actions/download-artifact](https://github.com/actions/download-artifact) and [actions/setup-node](https://github.com/actions/setup-node). Updates `actions/upload-artifact` from 4 to 5 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v4...v5) Updates `actions/download-artifact` from 5 to 6 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v5...v6) Updates `actions/setup-node` from 5 to 6 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/download-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c5af22f..38fd72af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: - name: Upload CLI artifact if: "!matrix.no-run" - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: tree-sitter.${{ matrix.platform }} path: target/${{ matrix.target }}/release/tree-sitter${{ contains(matrix.target, 'windows') && '.exe' || '' }} @@ -287,7 +287,7 @@ jobs: - name: Upload Wasm artifacts if: matrix.platform == 'linux-x64' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: tree-sitter.wasm path: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6dc78f09..e89b0035 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v5 - name: Download build artifacts - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v6 with: path: artifacts @@ -84,7 +84,7 @@ jobs: uses: actions/checkout@v5 - name: Set up Node - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: 20 registry-url: https://registry.npmjs.org From 77363a65c279f5c16611678b9dab135d040484ef Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 29 Oct 2025 12:30:59 +0100 Subject: [PATCH 019/140] build(deps): cargo update --- Cargo.lock | 534 ++++++++++++++++++++++++++++------------------------- 1 file changed, 286 insertions(+), 248 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14838fdc..d2c5d98a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -37,9 +37,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -91,6 +91,15 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "ar_archive_writer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" +dependencies = [ + "object 0.32.2", +] + [[package]] name = "arbitrary" version = "1.4.2" @@ -109,7 +118,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.12.1", @@ -132,7 +141,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -154,15 +163,24 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -180,9 +198,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "bytes" @@ -192,9 +210,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.41" +version = "1.2.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" +checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" dependencies = [ "find-msvc-tools", "shlex", @@ -217,9 +235,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -246,9 +264,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" dependencies = [ "clap_builder", "clap_derive", @@ -256,9 +274,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" dependencies = [ "anstream", "anstyle", @@ -268,18 +286,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.58" +version = "4.5.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75bf0b32ad2e152de789bb635ea4d3078f6b838ad7974143e99b99f45a04af4a" +checksum = "2348487adcd4631696ced64ccdb40d38ac4d31cae7f2eec8817fcea1b9d1c43c" dependencies = [ "clap", ] [[package]] name = "clap_complete_nushell" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a0c951694691e65bf9d421d597d68416c22de9632e884c28412cb8cd8b73dce" +checksum = "811159f339691baacdf7d534df2946b9d217014081099e23d31d887d99521e70" dependencies = [ "clap", "clap_complete", @@ -287,9 +305,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", @@ -299,9 +317,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "cobs" @@ -419,7 +437,7 @@ dependencies = [ "cranelift-entity", "cranelift-isle", "gimli", - "hashbrown", + "hashbrown 0.15.5", "log", "pulley-interpreter", "regalloc2", @@ -523,13 +541,13 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ - "dispatch", + "dispatch2", "nix", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ] [[package]] @@ -553,10 +571,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "dispatch" -version = "0.2.0" +name = "dispatch2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", +] [[package]] name = "displaydoc" @@ -616,12 +640,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -719,19 +743,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.3+wasi-0.2.4", + "wasip2", ] [[package]] @@ -761,6 +785,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "heck" version = "0.5.0" @@ -769,11 +799,11 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -793,9 +823,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -806,9 +836,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -819,11 +849,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -834,42 +863,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -906,21 +931,24 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.0", "serde", "serde_core", ] [[package]] name = "indoc" -version = "2.0.6" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] [[package]] name = "inotify" @@ -928,7 +956,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "inotify-sys", "libc", ] @@ -944,9 +972,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -1005,9 +1033,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -1053,9 +1081,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" @@ -1064,7 +1092,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.0", + "windows-link", ] [[package]] @@ -1081,15 +1109,15 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "log" @@ -1118,7 +1146,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" dependencies = [ - "rustix 1.0.8", + "rustix 1.1.2", ] [[package]] @@ -1129,14 +1157,14 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -1151,7 +1179,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -1173,7 +1201,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "fsevent-sys", "inotify", "kqueue", @@ -1206,9 +1234,9 @@ checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" [[package]] name = "objc2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ "objc2-encode", ] @@ -1221,14 +1249,23 @@ checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "object" version = "0.36.7" @@ -1236,7 +1273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "crc32fast", - "hashbrown", + "hashbrown 0.15.5", "indexmap", "memchr", ] @@ -1249,9 +1286,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "pathdiff" @@ -1313,9 +1350,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -1351,28 +1388,29 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "psm" -version = "0.1.26" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" +checksum = "d11f2fedc3b7dafdc2851bc52f277377c5473d378859be234bc7ebb593144d01" dependencies = [ + "ar_archive_writer", "cc", ] @@ -1389,9 +1427,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -1440,7 +1478,7 @@ checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734" dependencies = [ "allocator-api2", "bumpalo", - "hashbrown", + "hashbrown 0.15.5", "log", "rustc-hash 2.1.1", "smallvec", @@ -1448,9 +1486,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -1460,9 +1498,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -1471,9 +1509,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "relative-path" @@ -1558,7 +1596,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -1567,17 +1605,23 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "ryu" version = "1.0.20" @@ -1605,9 +1649,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.224" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aaeb1e94f53b16384af593c71e20b095e958dab1d26939c1b70645c5cfbcc0b" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -1615,18 +1659,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.224" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f39390fa6346e24defbcdd3d9544ba8a19985d0af74df8501fbfe9a64341ab" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.224" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ff78ab5e8561c9a675bfc1785cb07ae721f0ee53329a595cefd8c04c2ac4e0" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -1694,9 +1738,9 @@ checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "streaming-iterator" @@ -1712,9 +1756,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.106" +version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", @@ -1734,9 +1778,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" +checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" [[package]] name = "tempfile" @@ -1745,10 +1789,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", - "rustix 1.0.8", - "windows-sys 0.61.0", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -1823,9 +1867,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -1833,18 +1877,31 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ "indexmap", "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ "winnow", ] @@ -1961,7 +2018,7 @@ name = "tree-sitter-generate" version = "0.26.0" dependencies = [ "anyhow", - "bitflags 2.9.4", + "bitflags 2.10.0", "dunce", "indexmap", "indoc", @@ -2038,9 +2095,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-segmentation" @@ -2050,9 +2107,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unindent" @@ -2107,44 +2164,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.3+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2152,22 +2197,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -2188,8 +2233,8 @@ version = "0.229.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc3b1f053f5d41aa55640a1fa9b6d1b8a9e4418d118ce308d20e24ff3575a8c" dependencies = [ - "bitflags 2.9.4", - "hashbrown", + "bitflags 2.10.0", + "hashbrown 0.15.5", "indexmap", "semver", "serde", @@ -2214,22 +2259,22 @@ checksum = "57373e1d8699662fb791270ac5dfac9da5c14f618ecf940cdb29dc3ad9472a3c" dependencies = [ "addr2line", "anyhow", - "bitflags 2.9.4", + "bitflags 2.10.0", "bumpalo", "cc", "cfg-if", - "hashbrown", + "hashbrown 0.15.5", "indexmap", "libc", "log", "mach2", "memfd", - "object", + "object 0.36.7", "once_cell", "postcard", "psm", "pulley-interpreter", - "rustix 1.0.8", + "rustix 1.1.2", "serde", "serde_derive", "smallvec", @@ -2296,7 +2341,7 @@ dependencies = [ "gimli", "itertools 0.14.0", "log", - "object", + "object 0.36.7", "pulley-interpreter", "smallvec", "target-lexicon", @@ -2318,7 +2363,7 @@ dependencies = [ "gimli", "indexmap", "log", - "object", + "object 0.36.7", "postcard", "serde", "serde_derive", @@ -2338,7 +2383,7 @@ dependencies = [ "anyhow", "cc", "cfg-if", - "rustix 1.0.8", + "rustix 1.1.2", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", "windows-sys 0.59.0", @@ -2391,7 +2436,7 @@ dependencies = [ "anyhow", "cranelift-codegen", "gimli", - "object", + "object 0.36.7", "target-lexicon", "wasmparser", "wasmtime-cranelift", @@ -2401,9 +2446,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -2411,9 +2456,9 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" +checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" dependencies = [ "core-foundation", "jni", @@ -2445,11 +2490,11 @@ checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2473,15 +2518,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -2516,16 +2555,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.0", + "windows-link", ] [[package]] @@ -2561,19 +2600,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -2590,9 +2629,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -2608,9 +2647,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -2626,9 +2665,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -2638,9 +2677,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -2656,9 +2695,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -2674,9 +2713,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -2692,9 +2731,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -2710,9 +2749,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" @@ -2725,15 +2764,15 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.45.0" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "xtask" @@ -2759,11 +2798,10 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -2771,9 +2809,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -2783,18 +2821,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -2824,15 +2862,15 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -2841,9 +2879,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -2852,9 +2890,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", From 70cde4a1100d64cb19ed4915f23575ef8f4d9c74 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 29 Oct 2025 12:33:31 +0100 Subject: [PATCH 020/140] ci(dependabot): only update patch releases for cargo --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 328f241d..c75a67e6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -14,6 +14,10 @@ updates: groups: cargo: patterns: ["*"] + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major", "version-update:semver-minor"] + - package-ecosystem: "github-actions" directory: "/" schedule: @@ -28,6 +32,7 @@ updates: groups: actions: patterns: ["*"] + - package-ecosystem: "npm" versioning-strategy: increase directories: From 6188010f53bf8c4d75a961a54f1e1fe13436dc1e Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 29 Oct 2025 12:45:01 +0100 Subject: [PATCH 021/140] build(deps): bump rquickjs to v0.10.0 --- Cargo.lock | 132 ++++++++++++------------------------- crates/generate/Cargo.toml | 2 +- 2 files changed, 44 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d2c5d98a..1639883b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,29 +112,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" -[[package]] -name = "bindgen" -version = "0.69.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" -dependencies = [ - "bitflags 2.10.0", - "cexpr", - "clang-sys", - "itertools 0.12.1", - "lazy_static", - "lazycell", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn", - "which", -] - [[package]] name = "bindgen" version = "0.72.1" @@ -150,7 +127,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash 2.1.1", + "rustc-hash", "shlex", "syn", ] @@ -361,9 +338,9 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" dependencies = [ "unicode-segmentation", ] @@ -441,7 +418,7 @@ dependencies = [ "log", "pulley-interpreter", "regalloc2", - "rustc-hash 2.1.1", + "rustc-hash", "serde", "smallvec", "target-lexicon", @@ -698,6 +675,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -781,7 +764,7 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", "serde", ] @@ -790,6 +773,11 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "heck" @@ -976,15 +964,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -1061,18 +1040,6 @@ dependencies = [ "libc", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leb128fmt" version = "0.1.0" @@ -1304,28 +1271,29 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_shared", + "serde", ] [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ + "fastrand", "phf_shared", - "rand", ] [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ "siphasher", ] @@ -1480,7 +1448,7 @@ dependencies = [ "bumpalo", "hashbrown 0.15.5", "log", - "rustc-hash 2.1.1", + "rustc-hash", "smallvec", ] @@ -1515,9 +1483,12 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "relative-path" -version = "1.9.3" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" +checksum = "bca40a312222d8ba74837cb474edef44b37f561da5f773981007a10bbaa992b0" +dependencies = [ + "serde", +] [[package]] name = "rgb" @@ -1530,9 +1501,9 @@ dependencies = [ [[package]] name = "rquickjs" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5227859c4dfc83f428e58f9569bf439e628c8d139020e7faff437e6f5abaa0" +checksum = "a135375fbac5ba723bb6a48f432a72f81539cedde422f0121a86c7c4e96d8e0d" dependencies = [ "rquickjs-core", "rquickjs-macro", @@ -1540,10 +1511,11 @@ dependencies = [ [[package]] name = "rquickjs-core" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82e0ca83028ad5b533b53b96c395bbaab905a5774de4aaf1004eeacafa3d85d" +checksum = "bccb7121a123865c8ace4dea42e7ed84d78b90cbaf4ca32c59849d8d210c9672" dependencies = [ + "hashbrown 0.16.0", "phf", "relative-path", "rquickjs-sys", @@ -1551,9 +1523,9 @@ dependencies = [ [[package]] name = "rquickjs-macro" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4d2eccd988a924a470a76fbd81a191b22d1f5f4f4619cf5662a8c1ab4ca1db7" +checksum = "89f93602cc3112c7f30bf5f29e722784232138692c7df4c52ebbac7e035d900d" dependencies = [ "convert_case", "fnv", @@ -1570,20 +1542,14 @@ dependencies = [ [[package]] name = "rquickjs-sys" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fed0097b0b4fbb2a87f6dd3b995a7c64ca56de30007eb7e867dfdfc78324ba5" +checksum = "57b1b6528590d4d65dc86b5159eae2d0219709546644c66408b2441696d1d725" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", ] -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -1946,7 +1912,7 @@ dependencies = [ name = "tree-sitter" version = "0.26.0" dependencies = [ - "bindgen 0.72.1", + "bindgen", "cc", "regex", "regex-syntax", @@ -2027,7 +1993,7 @@ dependencies = [ "regex", "regex-syntax", "rquickjs", - "rustc-hash 2.1.1", + "rustc-hash", "semver", "serde", "serde_json", @@ -2470,18 +2436,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix 0.38.44", -] - [[package]] name = "widestring" version = "1.2.1" @@ -2780,7 +2734,7 @@ version = "0.1.0" dependencies = [ "anstyle", "anyhow", - "bindgen 0.72.1", + "bindgen", "clap", "indoc", "notify", diff --git a/crates/generate/Cargo.toml b/crates/generate/Cargo.toml index 1588763d..09fc1850 100644 --- a/crates/generate/Cargo.toml +++ b/crates/generate/Cargo.toml @@ -34,7 +34,7 @@ log.workspace = true pathdiff = { version = "0.2.3", optional = true } regex.workspace = true regex-syntax.workspace = true -rquickjs = { version = "0.9.0", optional = true, features = [ +rquickjs = { version = "0.10.0", optional = true, features = [ "bindgen", "loader", "macro", From ecc787e221ff0b0b0c8cdea64775bfa0d6444ba0 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 4 Oct 2025 11:51:40 -0400 Subject: [PATCH 022/140] fix(test): correct language typo in test name --- crates/cli/src/tests/detect_language.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/tests/detect_language.rs b/crates/cli/src/tests/detect_language.rs index c94b30b4..c543c31e 100644 --- a/crates/cli/src/tests/detect_language.rs +++ b/crates/cli/src/tests/detect_language.rs @@ -90,7 +90,7 @@ fn detect_language_by_first_line_regex() { } #[test] -fn detect_langauge_by_double_barrel_file_extension() { +fn detect_language_by_double_barrel_file_extension() { let blade_dir = tree_sitter_dir( r#"{ "grammars": [ From b8f52210f973b0080d3f334af92abf9c9d27f898 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 5 Oct 2025 01:42:01 -0400 Subject: [PATCH 023/140] perf: reduce needless allocations --- crates/cli/src/parse.rs | 10 ++++++---- crates/generate/src/render.rs | 12 ++++++------ crates/highlight/src/highlight.rs | 8 +++++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 4b941fe3..84bf0e85 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -674,10 +674,9 @@ pub fn parse_file_at_path( width = max_path_length )?; if let Some(node) = first_error { - let start = node.start_position(); - let end = node.end_position(); - let mut node_text = String::new(); - for c in node.kind().chars() { + let node_kind = node.kind(); + let mut node_text = String::with_capacity(node_kind.len()); + for c in node_kind.chars() { if let Some(escaped) = escape_invisible(c) { node_text += escaped; } else { @@ -694,6 +693,9 @@ pub fn parse_file_at_path( } else { write!(&mut stdout, "{node_text}")?; } + + let start = node.start_position(); + let end = node.end_position(); write!( &mut stdout, " [{}, {}] - [{}, {}])", diff --git a/crates/generate/src/render.rs b/crates/generate/src/render.rs index e4aea008..bcfc832e 100644 --- a/crates/generate/src/render.rs +++ b/crates/generate/src/render.rs @@ -34,6 +34,8 @@ macro_rules! add { macro_rules! add_whitespace { ($this:tt) => {{ + // 4 bytes per char, 2 spaces per indent level + $this.buffer.reserve(4 * 2 * $this.indent_level); for _ in 0..$this.indent_level { write!(&mut $this.buffer, " ").unwrap(); } @@ -688,13 +690,14 @@ impl Generator { flat_field_map.push((field_name.clone(), *location)); } } + let field_map_len = flat_field_map.len(); field_map_ids.push(( self.get_field_map_id( - flat_field_map.clone(), + flat_field_map, &mut flat_field_maps, &mut next_flat_field_map_index, ), - flat_field_map.len(), + field_map_len, )); } } @@ -962,10 +965,7 @@ impl Generator { large_char_set_ix = Some(char_set_ix); } - let mut line_break = "\n".to_string(); - for _ in 0..self.indent_level + 2 { - line_break.push_str(" "); - } + let line_break = format!("\n{}", " ".repeat(self.indent_level + 2)); let has_positive_condition = large_char_set_ix.is_some() || !asserted_chars.is_empty(); let has_negative_condition = !negated_chars.is_empty(); diff --git a/crates/highlight/src/highlight.rs b/crates/highlight/src/highlight.rs index bb81fc08..9a78d1ac 100644 --- a/crates/highlight/src/highlight.rs +++ b/crates/highlight/src/highlight.rs @@ -344,11 +344,13 @@ impl HighlightConfiguration { locals_query: &str, ) -> Result { // Concatenate the query strings, keeping track of the start offset of each section. - let mut query_source = String::new(); + let mut query_source = String::with_capacity( + injection_query.len() + locals_query.len() + highlights_query.len(), + ); query_source.push_str(injection_query); - let locals_query_offset = query_source.len(); + let locals_query_offset = injection_query.len(); query_source.push_str(locals_query); - let highlights_query_offset = query_source.len(); + let highlights_query_offset = injection_query.len() + locals_query.len(); query_source.push_str(highlights_query); // Construct a single query by concatenating the three query strings, but record the From 097c2d4f05c3b91132374c33068046beb5feeee7 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Fri, 31 Oct 2025 21:20:17 -0400 Subject: [PATCH 024/140] fix(cli): remove `--emit=lib` generate option This also replaces the `--emit` option with an `--no-parser` flag. The default value is false, meaning a parser is still generated by default. --- crates/cli/src/init.rs | 10 ++++----- crates/cli/src/main.rs | 27 +++++------------------ crates/cli/src/templates/cmakelists.cmake | 4 ++-- crates/cli/src/templates/makefile | 4 ++-- docs/src/cli/generate.md | 8 ++----- 5 files changed, 17 insertions(+), 36 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 53ab84f3..62923441 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -572,14 +572,14 @@ pub fn generate_grammar_files( .replace( indoc! {r" $(PARSER): $(SRC_DIR)/grammar.json - $(TS) generate $^ + $(TS) generate $^ "}, indoc! {r" $(SRC_DIR)/grammar.json: grammar.js - $(TS) generate --emit=json $^ + $(TS) generate --no-parser $^ $(PARSER): $(SRC_DIR)/grammar.json - $(TS) generate --emit=parser $^ + $(TS) generate $^ "} ); write_file(path, contents)?; @@ -627,14 +627,14 @@ pub fn generate_grammar_files( add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/grammar.js" COMMAND "${TREE_SITTER_CLI}" generate grammar.js - --emit=json + --no-parser WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating grammar.json") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json - --emit=parser --abi=${TREE_SITTER_ABI_VERSION} + --abi=${TREE_SITTER_ABI_VERSION} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating parser.c") "#} diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index ad7667c2..26595f41 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -88,17 +88,6 @@ struct Init { pub grammar_path: Option, } -#[derive(Clone, Debug, Default, ValueEnum, PartialEq, Eq)] -enum GenerationEmit { - /// Generate `grammar.json` and `node-types.json` - Json, - /// Generate `parser.c` and related files - #[default] - Parser, - /// Compile to a library - Lib, -} - #[derive(Args)] #[command(alias = "gen", alias = "g")] struct Generate { @@ -121,12 +110,11 @@ struct Generate { ) )] pub abi_version: Option, - /// What generated files to emit + /// Only generate `grammar.json` and `node-types.json` #[arg(long)] - #[clap(value_enum, default_value_t=GenerationEmit::Parser)] - pub emit: GenerationEmit, - /// Deprecated: use --emit=lib. - #[arg(long, short = 'b', conflicts_with = "emit")] + pub no_parser: bool, + /// Compile all defined languages in the current dir + #[arg(long, short = 'b')] pub build: bool, /// Compile a parser in debug mode #[arg(long, short = '0')] @@ -862,9 +850,6 @@ impl Generate { version.parse().expect("invalid abi version flag") } }); - if self.build { - warn!("--build is deprecated, use --emit=lib instead"); - } if let Err(err) = tree_sitter_generate::generate_parser_in_directory( current_dir, @@ -873,7 +858,7 @@ impl Generate { abi_version, self.report_states_for_rule.as_deref(), self.js_runtime.as_deref(), - self.emit != GenerationEmit::Json, + !self.no_parser, if self.disable_optimizations { OptLevel::empty() } else { @@ -889,7 +874,7 @@ impl Generate { Err(anyhow!(err.to_string())).with_context(|| "Error when generating parser")?; } } - if self.emit == GenerationEmit::Lib || self.build { + if self.build { if let Some(path) = self.libdir { loader = loader::Loader::with_parser_lib_path(path); } diff --git a/crates/cli/src/templates/cmakelists.cmake b/crates/cli/src/templates/cmakelists.cmake index c2fd82fd..b0f4f790 100644 --- a/crates/cli/src/templates/cmakelists.cmake +++ b/crates/cli/src/templates/cmakelists.cmake @@ -22,14 +22,14 @@ find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/grammar.js" COMMAND "${TREE_SITTER_CLI}" generate grammar.js - --emit=json + --no-parser WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating grammar.json") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json - --emit=parser --abi=${TREE_SITTER_ABI_VERSION} + --abi=${TREE_SITTER_ABI_VERSION} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating parser.c") diff --git a/crates/cli/src/templates/makefile b/crates/cli/src/templates/makefile index 847381c5..b42dab97 100644 --- a/crates/cli/src/templates/makefile +++ b/crates/cli/src/templates/makefile @@ -73,10 +73,10 @@ $(LANGUAGE_NAME).pc: bindings/c/$(LANGUAGE_NAME).pc.in -e 's|@CMAKE_INSTALL_PREFIX@|$(PREFIX)|' $< > $@ $(SRC_DIR)/grammar.json: grammar.js - $(TS) generate --emit=json $^ + $(TS) generate --no-parser $^ $(PARSER): $(SRC_DIR)/grammar.json - $(TS) generate --emit=parser $^ + $(TS) generate $^ install: all install -d '$(DESTDIR)$(DATADIR)'/tree-sitter/queries/KEBAB_PARSER_NAME '$(DESTDIR)$(INCLUDEDIR)'/tree_sitter '$(DESTDIR)$(PCLIBDIR)' '$(DESTDIR)$(LIBDIR)' diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 02fcec00..9014e0ea 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -30,13 +30,9 @@ what keywords were extracted, what states were split and why, and the entry poin The ABI to use for parser generation. The default is ABI 15, with ABI 14 being a supported target. -### `--emit` +### `--no-parser` -What generated files to emit. Possible values: - -- `json`: Generate `grammar.json` and `node-types.json` -- `parser` (default): Generate `parser.c` and related files. -- `lib`: Compile to a library (equivalent of the deprecated `--build` option) +Only generate `grammar.json` and `node-types.json` ### `-0/--debug-build` From 8444cc3deb8fc4ddd283e7ae4c08bd5e79610938 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 2 Nov 2025 11:29:24 +0100 Subject: [PATCH 025/140] fix(docs): remove multilingual config field Problem: "deploy docs" always pulls in the `latest` release of `mdbook`, which now is a v0.5.0 prerelease with breaking changes -- including removing an (apparently unused) `multilingual` config field in the TOML that is now an error (another breaking change). Solution: Delete the line. Add `workflow_dispatch` to the docs workflow in case follow-up changes are needed; see https://github.com/rust-lang/mdBook/blob/master/CHANGELOG.md#05-migration-guide --- .github/workflows/docs.yml | 1 + docs/book.toml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 30fe914e..70f59a30 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -3,6 +3,7 @@ on: push: branches: [master] paths: [docs/**] + workflow_dispatch: jobs: deploy-docs: diff --git a/docs/book.toml b/docs/book.toml index 664a1f24..0894c988 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -4,7 +4,6 @@ authors = [ "Amaan Qureshi ", ] language = "en" -multilingual = false src = "src" title = "Tree-sitter" From 18a5243933402ad8fe22063a591ec3afe6e5dff3 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 2 Nov 2025 23:18:31 +0100 Subject: [PATCH 026/140] ci(docs): pin mdbook to latest release --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 70f59a30..7c1d2c1d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | jq_expr='.assets[] | select(.name | contains("x86_64-unknown-linux-gnu")) | .browser_download_url' - url=$(gh api repos/rust-lang/mdbook/releases/latest --jq "$jq_expr") + url=$(gh api repos/rust-lang/mdbook/releases/v0.4.52 --jq "$jq_expr") mkdir mdbook curl -sSL "$url" | tar -xz -C mdbook printf '%s/mdbook\n' "$PWD" >> "$GITHUB_PATH" From ef03a3f8fe0ceb6cbea6a7adbafd42971f532c62 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 2 Nov 2025 18:13:19 -0500 Subject: [PATCH 027/140] fix(ci): correct mdbook release url --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 7c1d2c1d..fb23b271 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -26,7 +26,7 @@ jobs: GH_TOKEN: ${{ github.token }} run: | jq_expr='.assets[] | select(.name | contains("x86_64-unknown-linux-gnu")) | .browser_download_url' - url=$(gh api repos/rust-lang/mdbook/releases/v0.4.52 --jq "$jq_expr") + url=$(gh api repos/rust-lang/mdbook/releases/tags/v0.4.52 --jq "$jq_expr") mkdir mdbook curl -sSL "$url" | tar -xz -C mdbook printf '%s/mdbook\n' "$PWD" >> "$GITHUB_PATH" From 944386d25f088b8ac849dc7060d4ac80bb3e3702 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 27 Sep 2025 19:12:53 -0400 Subject: [PATCH 028/140] refactor(test): clean up test filtering logic Also, only update the expected output of a case when it is skipped if the `update` flag has been passed --- crates/cli/src/test.rs | 43 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index f107cb07..f5cc5de4 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -421,12 +421,11 @@ impl TestCorrection { } /// This will return false if we want to "fail fast". It will bail and not parse any more tests. -#[allow(clippy::too_many_arguments)] fn run_tests( parser: &mut Parser, test_entry: TestEntry, opts: &mut TestOptions, - mut indent_level: u32, + indent_level: u32, failures: &mut Vec, corrected_entries: &mut Vec, has_parse_errors: &mut bool, @@ -660,7 +659,6 @@ fn run_tests( return Ok(true); } - indent_level += 1; let failure_count = failures.len(); let mut has_printed = false; @@ -680,16 +678,10 @@ fn run_tests( } }; - let should_skip = |entry: &TestEntry, opts: &TestOptions| match entry { - TestEntry::Example { - name, file_name, .. - } => !matches_filter(name, file_name, opts), - TestEntry::Group { .. } => false, - }; - for child in children { if let TestEntry::Example { ref name, + ref file_name, ref input, ref output, ref attributes_str, @@ -698,29 +690,30 @@ fn run_tests( .. } = child { - if should_skip(&child, opts) { - let input = String::from_utf8(input.clone()).unwrap(); - let output = format_sexp(output, 0); - corrected_entries.push(TestCorrection::new( - name, - input, - output, - attributes_str, - header_delim_len, - divider_delim_len, - )); + if !matches_filter(name, file_name, opts) { + if opts.update { + let input = String::from_utf8(input.clone()).unwrap(); + let output = format_sexp(output, 0); + corrected_entries.push(TestCorrection::new( + name, + input, + output, + attributes_str, + header_delim_len, + divider_delim_len, + )); + } opts.test_num += 1; - continue; } } - if !has_printed && indent_level > 1 { + if !has_printed && indent_level > 0 { has_printed = true; writeln!( opts.output, "{}{name}:", - " ".repeat((indent_level - 1) as usize) + " ".repeat(indent_level as usize) )?; opts.parse_rates.push((false, None)); } @@ -728,7 +721,7 @@ fn run_tests( parser, child, opts, - indent_level, + indent_level + 1, failures, corrected_entries, has_parse_errors, From 6a8676f335c986d93d2236162b466529256fb672 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 28 Sep 2025 22:25:30 -0400 Subject: [PATCH 029/140] refactor(test): generalize printing of test diff keys and diffs --- crates/cli/src/fuzz.rs | 10 +-- crates/cli/src/test.rs | 99 +++++++++++++++++++---------- crates/cli/src/tests/corpus_test.rs | 14 ++-- 3 files changed, 76 insertions(+), 47 deletions(-) diff --git a/crates/cli/src/fuzz.rs b/crates/cli/src/fuzz.rs index 24806fca..f1524825 100644 --- a/crates/cli/src/fuzz.rs +++ b/crates/cli/src/fuzz.rs @@ -25,7 +25,7 @@ use crate::{ random::Rand, }, parse::perform_edit, - test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields, TestEntry}, + test::{parse_tests, strip_sexp_fields, DiffKey, TestDiff, TestEntry}, }; pub static LOG_ENABLED: LazyLock = LazyLock::new(|| env::var("TREE_SITTER_LOG").is_ok()); @@ -183,8 +183,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -276,8 +276,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output && !test.error { println!("Incorrect parse for {test_name} - seed {seed}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index f5cc5de4..b19d7afd 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -317,49 +317,78 @@ pub fn check_queries_at_path(language: &Language, path: &Path) -> Result<()> { Ok(()) } -pub fn print_diff_key() { - println!( - "\ncorrect / {} / {}", - paint(Some(AnsiColor::Green), "expected"), - paint(Some(AnsiColor::Red), "unexpected") - ); +pub struct DiffKey; + +impl std::fmt::Display for DiffKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "\ncorrect / {} / {}", + paint(Some(AnsiColor::Green), "expected"), + paint(Some(AnsiColor::Red), "unexpected") + )?; + Ok(()) + } } -pub fn print_diff(actual: &str, expected: &str, use_color: bool) { - let diff = TextDiff::from_lines(actual, expected); - for diff in diff.iter_all_changes() { - match diff.tag() { - ChangeTag::Equal => { - if use_color { - print!("{diff}"); - } else { - print!(" {diff}"); +pub struct TestDiff<'a> { + pub actual: &'a str, + pub expected: &'a str, + pub use_color: bool, +} + +impl<'a> TestDiff<'a> { + #[must_use] + pub const fn new(actual: &'a str, expected: &'a str, use_color: bool) -> Self { + Self { + actual, + expected, + use_color, + } + } +} + +impl std::fmt::Display for TestDiff<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let diff = TextDiff::from_lines(self.actual, self.expected); + for diff in diff.iter_all_changes() { + match diff.tag() { + ChangeTag::Equal => { + if self.use_color { + write!(f, "{diff}")?; + } else { + write!(f, " {diff}")?; + } } - } - ChangeTag::Insert => { - if use_color { - print!("{}", paint(Some(AnsiColor::Green), diff.as_str().unwrap())); - } else { - print!("+{diff}"); + ChangeTag::Insert => { + if self.use_color { + write!( + f, + "{}", + paint(Some(AnsiColor::Green), diff.as_str().unwrap()) + )?; + } else { + write!(f, "+{diff}")?; + } + if diff.missing_newline() { + writeln!(f)?; + } } - if diff.missing_newline() { - println!(); - } - } - ChangeTag::Delete => { - if use_color { - print!("{}", paint(Some(AnsiColor::Red), diff.as_str().unwrap())); - } else { - print!("-{diff}"); - } - if diff.missing_newline() { - println!(); + ChangeTag::Delete => { + if self.use_color { + write!(f, "{}", paint(Some(AnsiColor::Red), diff.as_str().unwrap()))?; + } else { + write!(f, "-{diff}")?; + } + if diff.missing_newline() { + writeln!(f)?; + } } } } - } - println!(); + Ok(()) + } } struct TestFailure { diff --git a/crates/cli/src/tests/corpus_test.rs b/crates/cli/src/tests/corpus_test.rs index fe2e2943..de797401 100644 --- a/crates/cli/src/tests/corpus_test.rs +++ b/crates/cli/src/tests/corpus_test.rs @@ -16,7 +16,7 @@ use crate::{ LOG_GRAPH_ENABLED, START_SEED, }, parse::perform_edit, - test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields}, + test::{parse_tests, strip_sexp_fields, DiffKey, TestDiff}, tests::{ allocations, helpers::fixtures::{fixtures_dir, get_language, get_test_language, SCRATCH_BASE_DIR}, @@ -209,8 +209,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -297,8 +297,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect parse for {test_name} - seed {seed}"); - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + println!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); return false; } @@ -428,8 +428,8 @@ fn test_feature_corpus_files() { if actual_output == test.output { true } else { - print_diff_key(); - print_diff(&actual_output, &test.output, true); + println!("{DiffKey}"); + print!("{}", TestDiff::new(&actual_output, &test.output, true)); println!(); false } From f02d7e7e335dc4d9355d4d2ca61729368bc4e959 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 28 Sep 2025 22:57:56 -0400 Subject: [PATCH 030/140] feat(test): display test results in JSON format --- crates/cli/src/fuzz.rs | 8 +- crates/cli/src/main.rs | 198 ++++--- crates/cli/src/query.rs | 70 ++- crates/cli/src/test.rs | 794 ++++++++++++++++++++-------- crates/cli/src/test_highlight.rs | 68 +-- crates/cli/src/test_tags.rs | 68 +-- crates/cli/src/tests/corpus_test.rs | 12 +- 7 files changed, 799 insertions(+), 419 deletions(-) diff --git a/crates/cli/src/fuzz.rs b/crates/cli/src/fuzz.rs index f1524825..39ad7691 100644 --- a/crates/cli/src/fuzz.rs +++ b/crates/cli/src/fuzz.rs @@ -183,8 +183,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - println!("{DiffKey}"); - println!("{}", TestDiff::new(&actual_output, &test.output, true)); + DiffKey::print(); + println!("{}", TestDiff::new(&actual_output, &test.output)); println!(); return false; } @@ -276,8 +276,8 @@ pub fn fuzz_language_corpus( if actual_output != test.output && !test.error { println!("Incorrect parse for {test_name} - seed {seed}"); - println!("{DiffKey}"); - println!("{}", TestDiff::new(&actual_output, &test.output, true)); + DiffKey::print(); + println!("{}", TestDiff::new(&actual_output, &test.output)); println!(); return false; } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 26595f41..e5cc7317 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -24,11 +24,12 @@ use tree_sitter_cli::{ input::{get_input, get_tmp_source_file, CliInput}, logger, parse::{self, ParseDebugType, ParseFileOptions, ParseOutput, ParseTheme}, - playground, query, + playground, + query::{self, QueryFileOptions}, tags::{self, TagsOptions}, - test::{self, TestOptions, TestStats}, - test_highlight, test_tags, util, version, - version::BumpLevel, + test::{self, TestOptions, TestStats, TestSummary}, + test_highlight, test_tags, util, + version::{self, BumpLevel}, wasm, }; use tree_sitter_config::Config; @@ -328,6 +329,9 @@ struct Test { /// Show only the pass-fail overview tree #[arg(long)] pub overview_only: bool, + /// Output the test summary in a JSON output + #[arg(long)] + pub json_summary: bool, } #[derive(Args)] @@ -1150,6 +1154,28 @@ impl Parse { } } +/// In case an error is encountered, prints out the contents of `test_summary` and +/// propagates the error +fn check_test( + test_result: Result<()>, + test_summary: &TestSummary, + json_summary: bool, +) -> Result<()> { + if let Err(e) = test_result { + if json_summary { + let json_summary = serde_json::to_string_pretty(test_summary) + .expect("Failed to encode summary to JSON"); + println!("{json_summary}"); + } else { + println!("{test_summary}"); + } + + Err(e)?; + } + + Ok(()) +} + impl Test { fn run(self, mut loader: loader::Loader, current_dir: &Path) -> Result<()> { let config = Config::load(self.config_path)?; @@ -1194,15 +1220,18 @@ impl Test { parser.set_language(language)?; let test_dir = current_dir.join("test"); - let mut stats = parse::Stats::default(); + let mut test_summary = TestSummary::new( + color, + stat, + self.update, + self.overview_only, + self.json_summary, + ); // Run the corpus tests. Look for them in `test/corpus`. let test_corpus_dir = test_dir.join("corpus"); if test_corpus_dir.is_dir() { - let mut output = String::new(); - let mut rates = Vec::new(); - let mut opts = TestOptions { - output: &mut output, + let opts = TestOptions { path: test_corpus_dir, debug: self.debug, debug_graph: self.debug_graph, @@ -1213,51 +1242,67 @@ impl Test { open_log: self.open_log, languages: languages.iter().map(|(l, n)| (n.as_str(), l)).collect(), color, - test_num: 1, - parse_rates: &mut rates, - stat_display: stat, - stats: &mut stats, show_fields: self.show_fields, overview_only: self.overview_only, }; - test::run_tests_at_path(&mut parser, &mut opts)?; - println!("\n{stats}"); + check_test( + test::run_tests_at_path(&mut parser, &opts, &mut test_summary), + &test_summary, + self.json_summary, + )?; + test_summary.test_num = 1; } // Check that all of the queries are valid. - test::check_queries_at_path(language, ¤t_dir.join("queries"))?; + let query_dir = current_dir.join("queries"); + check_test( + test::check_queries_at_path(language, &query_dir), + &test_summary, + self.json_summary, + )?; + test_summary.test_num = 1; // Run the syntax highlighting tests. let test_highlight_dir = test_dir.join("highlight"); if test_highlight_dir.is_dir() { let mut highlighter = Highlighter::new(); highlighter.parser = parser; - test_highlight::test_highlights( - &loader, - &config.get()?, - &mut highlighter, - &test_highlight_dir, - color, + check_test( + test_highlight::test_highlights( + &loader, + &config.get()?, + &mut highlighter, + &test_highlight_dir, + &mut test_summary, + ), + &test_summary, + self.json_summary, )?; parser = highlighter.parser; + test_summary.test_num = 1; } let test_tag_dir = test_dir.join("tags"); if test_tag_dir.is_dir() { let mut tags_context = TagsContext::new(); tags_context.parser = parser; - test_tags::test_tags( - &loader, - &config.get()?, - &mut tags_context, - &test_tag_dir, - color, + check_test( + test_tags::test_tags( + &loader, + &config.get()?, + &mut tags_context, + &test_tag_dir, + &mut test_summary, + ), + &test_summary, + self.json_summary, )?; + test_summary.test_num = 1; } // For the rest of the queries, find their tests and run them - for entry in walkdir::WalkDir::new(current_dir.join("queries")) + for entry in walkdir::WalkDir::new(&query_dir) .into_iter() .filter_map(|e| e.ok()) .filter(|e| e.file_type().is_file()) @@ -1280,27 +1325,41 @@ impl Test { }) .collect::>(); if !entries.is_empty() { - println!("{stem}:"); + test_summary.query_results.add_group(stem); } - for entry in entries { + test_summary.test_num = 1; + let opts = QueryFileOptions::default(); + for entry in &entries { let path = entry.path(); - query::query_file_at_path( - language, - path, - &path.display().to_string(), - path, - false, - None, - None, - true, - false, - false, - false, + check_test( + query::query_file_at_path( + language, + path, + &path.display().to_string(), + path, + &opts, + Some(&mut test_summary), + ), + &test_summary, + self.json_summary, )?; } + if !entries.is_empty() { + test_summary.query_results.pop_traversal(); + } } } + test_summary.test_num = 1; + + if self.json_summary { + let json_summary = serde_json::to_string_pretty(&test_summary) + .expect("Failed to encode test summary to JSON"); + println!("{json_summary}"); + } else { + println!("{test_summary}"); + } + Ok(()) } } @@ -1407,19 +1466,22 @@ impl Query { lib_info.as_ref(), )?; + let opts = QueryFileOptions { + ordered_captures: self.captures, + byte_range, + point_range, + quiet: self.quiet, + print_time: self.time, + stdin: false, + }; for path in paths { query::query_file_at_path( &language, &path, &path.display().to_string(), query_path, - self.captures, - byte_range.clone(), - point_range.clone(), - self.test, - self.quiet, - self.time, - false, + &opts, + None, )?; } } @@ -1447,19 +1509,15 @@ impl Query { .map(|(l, _)| l.clone()) .ok_or_else(|| anyhow!("No language found"))? }; - query::query_file_at_path( - language, - &path, - &name, - query_path, - self.captures, + let opts = QueryFileOptions { + ordered_captures: self.captures, byte_range, point_range, - self.test, - self.quiet, - self.time, - true, - )?; + quiet: self.quiet, + print_time: self.time, + stdin: true, + }; + query::query_file_at_path(language, &path, &name, query_path, &opts, None)?; fs::remove_file(path)?; } CliInput::Stdin(contents) => { @@ -1469,19 +1527,15 @@ impl Query { let path = get_tmp_source_file(&contents)?; let language = loader.select_language(&path, current_dir, None, lib_info.as_ref())?; - query::query_file_at_path( - &language, - &path, - "stdin", - query_path, - self.captures, + let opts = QueryFileOptions { + ordered_captures: self.captures, byte_range, point_range, - self.test, - self.quiet, - self.time, - true, - )?; + quiet: self.quiet, + print_time: self.time, + stdin: true, + }; + query::query_file_at_path(&language, &path, "stdin", query_path, &opts, None)?; fs::remove_file(path)?; } } diff --git a/crates/cli/src/query.rs b/crates/cli/src/query.rs index ea074b75..c58e5f34 100644 --- a/crates/cli/src/query.rs +++ b/crates/cli/src/query.rs @@ -6,30 +6,33 @@ use std::{ time::Instant, }; -use anstyle::AnsiColor; use anyhow::{Context, Result}; use log::warn; use streaming_iterator::StreamingIterator; use tree_sitter::{Language, Parser, Point, Query, QueryCursor}; use crate::{ - logger::paint, query_testing::{self, to_utf8_point}, + test::{TestInfo, TestOutcome, TestResult, TestSummary}, }; -#[allow(clippy::too_many_arguments)] +#[derive(Default)] +pub struct QueryFileOptions { + pub ordered_captures: bool, + pub byte_range: Option>, + pub point_range: Option>, + pub quiet: bool, + pub print_time: bool, + pub stdin: bool, +} + pub fn query_file_at_path( language: &Language, path: &Path, name: &str, query_path: &Path, - ordered_captures: bool, - byte_range: Option>, - point_range: Option>, - should_test: bool, - quiet: bool, - print_time: bool, - stdin: bool, + opts: &QueryFileOptions, + test_summary: Option<&mut TestSummary>, ) -> Result<()> { let stdout = io::stdout(); let mut stdout = stdout.lock(); @@ -39,19 +42,20 @@ pub fn query_file_at_path( let query = Query::new(language, &query_source).with_context(|| "Query compilation failed")?; let mut query_cursor = QueryCursor::new(); - if let Some(range) = byte_range { - query_cursor.set_byte_range(range); + if let Some(ref range) = opts.byte_range { + query_cursor.set_byte_range(range.clone()); } - if let Some(range) = point_range { - query_cursor.set_point_range(range); + if let Some(ref range) = opts.point_range { + query_cursor.set_point_range(range.clone()); } let mut parser = Parser::new(); parser.set_language(language)?; let mut results = Vec::new(); + let should_test = test_summary.is_some(); - if !should_test && !stdin { + if !should_test && !opts.stdin { writeln!(&mut stdout, "{name}")?; } @@ -60,12 +64,12 @@ pub fn query_file_at_path( let tree = parser.parse(&source_code, None).unwrap(); let start = Instant::now(); - if ordered_captures { + if opts.ordered_captures { let mut captures = query_cursor.captures(&query, tree.root_node(), source_code.as_slice()); while let Some((mat, capture_index)) = captures.next() { let capture = mat.captures[*capture_index]; let capture_name = &query.capture_names()[capture.index as usize]; - if !quiet && !should_test { + if !opts.quiet && !should_test { writeln!( &mut stdout, " pattern: {:>2}, capture: {} - {capture_name}, start: {}, end: {}, text: `{}`", @@ -85,14 +89,14 @@ pub fn query_file_at_path( } else { let mut matches = query_cursor.matches(&query, tree.root_node(), source_code.as_slice()); while let Some(m) = matches.next() { - if !quiet && !should_test { + if !opts.quiet && !should_test { writeln!(&mut stdout, " pattern: {}", m.pattern_index)?; } for capture in m.captures { let start = capture.node.start_position(); let end = capture.node.end_position(); let capture_name = &query.capture_names()[capture.index as usize]; - if !quiet && !should_test { + if !opts.quiet && !should_test { if end.row == start.row { writeln!( &mut stdout, @@ -119,26 +123,38 @@ pub fn query_file_at_path( warn!("Query exceeded maximum number of in-progress captures!"); } if should_test { - let path_name = if stdin { + let path_name = if opts.stdin { "stdin" } else { Path::new(&path).file_name().unwrap().to_str().unwrap() }; + // Invariant: `test_summary` will always be `Some` when `should_test` is true + let test_summary = test_summary.unwrap(); match query_testing::assert_expected_captures(&results, path, &mut parser, language) { Ok(assertion_count) => { - println!( - " ✓ {} ({} assertions)", - paint(Some(AnsiColor::Green), path_name), - assertion_count - ); + test_summary.query_results.add_case(TestResult { + name: path_name.to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionPassed { assertion_count }, + test_num: test_summary.test_num, + }, + }); } Err(e) => { - println!(" ✗ {}", paint(Some(AnsiColor::Red), path_name)); + test_summary.query_results.add_case(TestResult { + name: path_name.to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionFailed { + error: e.to_string(), + }, + test_num: test_summary.test_num, + }, + }); return Err(e); } } } - if print_time { + if opts.print_time { writeln!(&mut stdout, "{:?}", start.elapsed())?; } diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index b19d7afd..90629b15 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -1,7 +1,7 @@ use std::{ collections::BTreeMap, ffi::OsStr, - fmt::Write as _, + fmt::Display as _, fs, io::{self, Write}, path::{Path, PathBuf}, @@ -18,6 +18,7 @@ use regex::{ bytes::{Regex as ByteRegex, RegexBuilder as ByteRegexBuilder}, Regex, }; +use serde::Serialize; use similar::{ChangeTag, TextDiff}; use tree_sitter::{format_sexp, Language, LogType, Parser, Query, Tree}; use walkdir::WalkDir; @@ -114,7 +115,7 @@ impl Default for TestAttributes { } } -#[derive(ValueEnum, Default, Copy, Clone, PartialEq, Eq)] +#[derive(ValueEnum, Default, Debug, Copy, Clone, PartialEq, Eq, Serialize)] pub enum TestStats { All, #[default] @@ -123,7 +124,6 @@ pub enum TestStats { } pub struct TestOptions<'a> { - pub output: &'a mut String, pub path: PathBuf, pub debug: bool, pub debug_graph: bool, @@ -134,17 +134,453 @@ pub struct TestOptions<'a> { pub open_log: bool, pub languages: BTreeMap<&'a str, &'a Language>, pub color: bool, - pub test_num: usize, - /// Whether a test ran for the nth line in `output`, the true parse rate, and the adjusted - /// parse rate - pub parse_rates: &'a mut Vec<(bool, Option<(f64, f64)>)>, - pub stat_display: TestStats, - pub stats: &'a mut Stats, pub show_fields: bool, pub overview_only: bool, } -pub fn run_tests_at_path(parser: &mut Parser, opts: &mut TestOptions) -> Result<()> { +/// A stateful object used to collect results from running a grammar's test suite +#[derive(Debug, Default, Serialize)] +pub struct TestSummary { + // Parse test results and associated data + #[serde(serialize_with = "serialize_as_array")] + pub parse_results: TestResultHierarchy, + pub parse_failures: Vec, + pub parse_stats: Stats, + #[serde(skip)] + pub has_parse_errors: bool, + #[serde(skip)] + pub parse_stat_display: TestStats, + + // Other test results + #[serde(serialize_with = "serialize_as_array")] + pub highlight_results: TestResultHierarchy, + #[serde(serialize_with = "serialize_as_array")] + pub tag_results: TestResultHierarchy, + #[serde(serialize_with = "serialize_as_array")] + pub query_results: TestResultHierarchy, + + // Data used during construction + #[serde(skip)] + pub test_num: usize, + // Options passed in from the CLI which control how the summary is displayed + #[serde(skip)] + pub color: bool, + #[serde(skip)] + pub overview_only: bool, + #[serde(skip)] + pub update: bool, + #[serde(skip)] + pub json: bool, +} + +impl TestSummary { + #[must_use] + pub fn new( + color: bool, + stat_display: TestStats, + parse_update: bool, + overview_only: bool, + json_summary: bool, + ) -> Self { + Self { + color, + parse_stat_display: stat_display, + update: parse_update, + overview_only, + json: json_summary, + test_num: 1, + ..Default::default() + } + } +} + +#[derive(Debug, Default)] +pub struct TestResultHierarchy { + root_group: Vec, + traversal_idxs: Vec, +} + +fn serialize_as_array(results: &TestResultHierarchy, serializer: S) -> Result +where + S: serde::Serializer, +{ + results.root_group.serialize(serializer) +} + +/// Stores arbitrarily nested parent test groups and child cases. Supports creation +/// in DFS traversal order +impl TestResultHierarchy { + /// Signifies the start of a new group's traversal during construction. + fn push_traversal(&mut self, idx: usize) { + self.traversal_idxs.push(idx); + } + + /// Signifies the end of the current group's traversal during construction. + /// Must be paired with a prior call to [`TestResultHierarchy::add_group`]. + pub fn pop_traversal(&mut self) { + self.traversal_idxs.pop(); + } + + /// Adds a new group as a child of the current group. Caller is responsible + /// for calling [`TestResultHierarchy::pop_traversal`] once the group is done + /// being traversed. + pub fn add_group(&mut self, group_name: &str) { + let new_group_idx = self.curr_group_len(); + self.push(TestResult { + name: group_name.to_string(), + info: TestInfo::Group { + children: Vec::new(), + }, + }); + self.push_traversal(new_group_idx); + } + + /// Adds a new test example as a child of the current group. + /// Asserts that `test_case.info` is not [`TestInfo::Group`]. + pub fn add_case(&mut self, test_case: TestResult) { + assert!(!matches!(test_case.info, TestInfo::Group { .. })); + self.push(test_case); + } + + /// Adds a new `TestResult` to the current group. + fn push(&mut self, result: TestResult) { + // If there are no traversal steps, we're adding to the root + if self.traversal_idxs.is_empty() { + self.root_group.push(result); + return; + } + + #[allow(clippy::manual_let_else)] + let mut curr_group = match self.root_group[self.traversal_idxs[0]].info { + TestInfo::Group { ref mut children } => children, + _ => unreachable!(), + }; + for idx in self.traversal_idxs.iter().skip(1) { + curr_group = match curr_group[*idx].info { + TestInfo::Group { ref mut children } => children, + _ => unreachable!(), + }; + } + + curr_group.push(result); + } + + fn curr_group_len(&self) -> usize { + if self.traversal_idxs.is_empty() { + return self.root_group.len(); + } + + #[allow(clippy::manual_let_else)] + let mut curr_group = match self.root_group[self.traversal_idxs[0]].info { + TestInfo::Group { ref children } => children, + _ => unreachable!(), + }; + for idx in self.traversal_idxs.iter().skip(1) { + curr_group = match curr_group[*idx].info { + TestInfo::Group { ref children } => children, + _ => unreachable!(), + }; + } + curr_group.len() + } + + #[allow(clippy::iter_without_into_iter)] + #[must_use] + pub fn iter(&self) -> TestResultIterWithDepth<'_> { + let mut stack = Vec::with_capacity(self.root_group.len()); + for child in self.root_group.iter().rev() { + stack.push((0, child)); + } + TestResultIterWithDepth { stack } + } +} + +pub struct TestResultIterWithDepth<'a> { + stack: Vec<(usize, &'a TestResult)>, +} + +impl<'a> Iterator for TestResultIterWithDepth<'a> { + type Item = (usize, &'a TestResult); + + fn next(&mut self) -> Option { + self.stack.pop().inspect(|(depth, result)| { + if let TestInfo::Group { children } = &result.info { + for child in children.iter().rev() { + self.stack.push((depth + 1, child)); + } + } + }) + } +} + +#[derive(Debug, Serialize)] +pub struct TestResult { + pub name: String, + #[serde(flatten)] + pub info: TestInfo, +} + +#[derive(Debug, Serialize)] +#[serde(untagged)] +pub enum TestInfo { + Group { + children: Vec, + }, + ParseTest { + outcome: TestOutcome, + // True parse rate, adjusted parse rate + #[serde(serialize_with = "serialize_parse_rates")] + parse_rate: Option<(f64, f64)>, + test_num: usize, + }, + AssertionTest { + outcome: TestOutcome, + test_num: usize, + }, +} + +fn serialize_parse_rates( + parse_rate: &Option<(f64, f64)>, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + match parse_rate { + None => serializer.serialize_none(), + Some((first, _)) => serializer.serialize_some(first), + } +} + +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +pub enum TestOutcome { + // Parse outcomes + Passed, + Failed, + Updated, + Skipped, + Platform, + + // Highlight/Tag/Query outcomes + AssertionPassed { assertion_count: usize }, + AssertionFailed { error: String }, +} + +impl TestSummary { + fn fmt_parse_results(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let (count, total_adj_parse_time) = self + .parse_results + .iter() + .filter_map(|(_, result)| match result.info { + TestInfo::Group { .. } => None, + TestInfo::ParseTest { parse_rate, .. } => parse_rate, + _ => unreachable!(), + }) + .fold((0usize, 0.0f64), |(count, rate_accum), (_, adj_rate)| { + (count + 1, rate_accum + adj_rate) + }); + + let avg = total_adj_parse_time / count as f64; + let std_dev = { + let variance = self + .parse_results + .iter() + .filter_map(|(_, result)| match result.info { + TestInfo::Group { .. } => None, + TestInfo::ParseTest { parse_rate, .. } => parse_rate, + _ => unreachable!(), + }) + .map(|(_, rate_i)| (rate_i - avg).powi(2)) + .sum::() + / count as f64; + variance.sqrt() + }; + + for (depth, entry) in self.parse_results.iter() { + write!(f, "{}", " ".repeat(depth + 1))?; + match &entry.info { + TestInfo::Group { .. } => writeln!(f, "{}:", entry.name)?, + TestInfo::ParseTest { + outcome, + parse_rate, + test_num, + } => { + let (color, result_char) = match outcome { + TestOutcome::Passed => (AnsiColor::Green, "✓"), + TestOutcome::Failed => (AnsiColor::Red, "✗"), + TestOutcome::Updated => (AnsiColor::Blue, "✓"), + TestOutcome::Skipped => (AnsiColor::Yellow, "⌀"), + TestOutcome::Platform => (AnsiColor::Magenta, "⌀"), + _ => unreachable!(), + }; + let stat_display = match (self.parse_stat_display, parse_rate) { + (TestStats::TotalOnly, _) | (_, None) => String::new(), + (display, Some((true_rate, adj_rate))) => { + let mut stats = if display == TestStats::All { + format!(" ({true_rate:.3} bytes/ms)") + } else { + String::new() + }; + // 3 standard deviations below the mean, aka the "Empirical Rule" + if *adj_rate < 3.0f64.mul_add(-std_dev, avg) { + stats += &paint( + self.color.then_some(AnsiColor::Yellow), + &format!( + " -- Warning: Slow parse rate ({true_rate:.3} bytes/ms)" + ), + ); + } + stats + } + }; + writeln!( + f, + "{test_num:>3}. {result_char} {}{stat_display}", + paint(self.color.then_some(color), &entry.name), + )?; + } + TestInfo::AssertionTest { .. } => unreachable!(), + } + } + + // Parse failure info + if !self.parse_failures.is_empty() && self.update && !self.has_parse_errors { + writeln!( + f, + "\n{} update{}:\n", + self.parse_failures.len(), + if self.parse_failures.len() == 1 { + "" + } else { + "s" + } + )?; + + for (i, TestFailure { name, .. }) in self.parse_failures.iter().enumerate() { + writeln!(f, " {}. {name}", i + 1)?; + } + } else if !self.parse_failures.is_empty() && !self.overview_only { + if !self.has_parse_errors { + writeln!( + f, + "\n{} failure{}:", + self.parse_failures.len(), + if self.parse_failures.len() == 1 { + "" + } else { + "s" + } + )?; + } + + if self.color { + DiffKey.fmt(f)?; + } + for ( + i, + TestFailure { + name, + actual, + expected, + is_cst, + }, + ) in self.parse_failures.iter().enumerate() + { + if expected == "NO ERROR" { + writeln!(f, "\n {}. {name}:\n", i + 1)?; + writeln!(f, " Expected an ERROR node, but got:")?; + let actual = if *is_cst { + actual + } else { + &format_sexp(actual, 2) + }; + writeln!( + f, + " {}", + paint(self.color.then_some(AnsiColor::Red), actual) + )?; + } else { + writeln!(f, "\n {}. {name}:", i + 1)?; + if *is_cst { + writeln!( + f, + "{}", + TestDiff::new(actual, expected).with_color(self.color) + )?; + } else { + writeln!( + f, + "{}", + TestDiff::new(&format_sexp(actual, 2), &format_sexp(expected, 2)) + .with_color(self.color,) + )?; + } + } + } + } else { + writeln!(f)?; + } + + Ok(()) + } +} + +impl std::fmt::Display for TestSummary { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.fmt_parse_results(f)?; + + let mut render_assertion_results = + |name: &str, results: &TestResultHierarchy| -> std::fmt::Result { + writeln!(f, "{name}:")?; + for (depth, entry) in results.iter() { + write!(f, "{}", " ".repeat(depth + 2))?; + match &entry.info { + TestInfo::Group { .. } => writeln!(f, "{}", entry.name)?, + TestInfo::AssertionTest { outcome, test_num } => match outcome { + TestOutcome::AssertionPassed { assertion_count } => writeln!( + f, + "{:>3}. ✓ {} ({assertion_count} assertions)", + test_num, + paint(self.color.then_some(AnsiColor::Green), &entry.name) + )?, + TestOutcome::AssertionFailed { error } => { + writeln!( + f, + "{:>3}. ✗ {}", + test_num, + paint(self.color.then_some(AnsiColor::Red), &entry.name) + )?; + writeln!(f, "{} {error}", " ".repeat(depth + 1))?; + } + _ => unreachable!(), + }, + TestInfo::ParseTest { .. } => unreachable!(), + } + } + Ok(()) + }; + + if !self.highlight_results.root_group.is_empty() { + render_assertion_results("syntax highlighting", &self.highlight_results)?; + } + + if !self.tag_results.root_group.is_empty() { + render_assertion_results("tags", &self.tag_results)?; + } + + if !self.query_results.root_group.is_empty() { + render_assertion_results("queries", &self.query_results)?; + } + + Ok(()) + } +} + +pub fn run_tests_at_path( + parser: &mut Parser, + opts: &TestOptions, + test_summary: &mut TestSummary, +) -> Result<()> { let test_entry = parse_tests(&opts.path)?; let mut _log_session = None; @@ -159,140 +595,26 @@ pub fn run_tests_at_path(parser: &mut Parser, opts: &mut TestOptions) -> Result< }))); } - let mut failures = Vec::new(); let mut corrected_entries = Vec::new(); - let mut has_parse_errors = false; run_tests( parser, test_entry, opts, - 0, - &mut failures, + test_summary, &mut corrected_entries, - &mut has_parse_errors, + true, )?; - let (count, total_adj_parse_time) = opts - .parse_rates - .iter() - .flat_map(|(_, rates)| rates) - .fold((0usize, 0.0f64), |(count, rate_accum), (_, adj_rate)| { - (count + 1, rate_accum + adj_rate) - }); - - let avg = total_adj_parse_time / count as f64; - let std_dev = { - let variance = opts - .parse_rates - .iter() - .flat_map(|(_, rates)| rates) - .map(|(_, rate_i)| (rate_i - avg).powi(2)) - .sum::() - / count as f64; - variance.sqrt() - }; - - for ((is_test, rates), out_line) in opts.parse_rates.iter().zip(opts.output.lines()) { - let stat_display = if !is_test { - // Test group, no actual parsing took place - String::new() - } else { - match (opts.stat_display, rates) { - (TestStats::TotalOnly, _) | (_, None) => String::new(), - (display, Some((true_rate, adj_rate))) => { - let mut stats = if display == TestStats::All { - format!(" ({true_rate:.3} bytes/ms)") - } else { - String::new() - }; - // 3 standard deviations below the mean, aka the "Empirical Rule" - if *adj_rate < 3.0f64.mul_add(-std_dev, avg) { - stats += &paint( - opts.color.then_some(AnsiColor::Yellow), - &format!(" -- Warning: Slow parse rate ({true_rate:.3} bytes/ms)"), - ); - } - stats - } - } - }; - println!("{out_line}{stat_display}"); - } - parser.stop_printing_dot_graphs(); - if failures.is_empty() { + if test_summary.parse_failures.is_empty() || (opts.update && !test_summary.has_parse_errors) { Ok(()) - } else if opts.update && !has_parse_errors { - println!( - "\n{} update{}:\n", - failures.len(), - if failures.len() == 1 { "" } else { "s" } - ); - - for (i, TestFailure { name, .. }) in failures.iter().enumerate() { - println!(" {}. {name}", i + 1); - } - - Ok(()) - } else { - has_parse_errors = opts.update && has_parse_errors; - - if !opts.overview_only { - if !has_parse_errors { - println!( - "\n{} failure{}:", - failures.len(), - if failures.len() == 1 { "" } else { "s" } - ); - } - - if opts.color { - print_diff_key(); - } - for ( - i, - TestFailure { - name, - actual, - expected, - is_cst, - }, - ) in failures.iter().enumerate() - { - if expected == "NO ERROR" { - println!("\n {}. {name}:\n", i + 1); - println!(" Expected an ERROR node, but got:"); - let actual = if *is_cst { - actual - } else { - &format_sexp(actual, 2) - }; - println!(" {}", paint(opts.color.then_some(AnsiColor::Red), actual)); - } else { - println!("\n {}. {name}:", i + 1); - if *is_cst { - print_diff(actual, expected, opts.color); - } else { - print_diff( - &format_sexp(actual, 2), - &format_sexp(expected, 2), - opts.color, - ); - } - } - } - } else { - println!(); - } - - if has_parse_errors { - Err(anyhow!(indoc! {" + } else if opts.update && test_summary.has_parse_errors { + Err(anyhow!(indoc! {" Some tests failed to parse with unexpected `ERROR` or `MISSING` nodes, as shown above, and cannot be updated automatically. Either fix the grammar or manually update the tests if this is expected."})) - } else { - Err(anyhow!("")) - } + } else { + Err(anyhow!("")) } } @@ -331,21 +653,34 @@ impl std::fmt::Display for DiffKey { } } +impl DiffKey { + /// Writes [`DiffKey`] to stdout + pub fn print() { + println!("{Self}"); + } +} + pub struct TestDiff<'a> { pub actual: &'a str, pub expected: &'a str, - pub use_color: bool, + pub color: bool, } impl<'a> TestDiff<'a> { #[must_use] - pub const fn new(actual: &'a str, expected: &'a str, use_color: bool) -> Self { + pub const fn new(actual: &'a str, expected: &'a str) -> Self { Self { actual, expected, - use_color, + color: true, } } + + #[must_use] + pub const fn with_color(mut self, color: bool) -> Self { + self.color = color; + self + } } impl std::fmt::Display for TestDiff<'_> { @@ -354,14 +689,14 @@ impl std::fmt::Display for TestDiff<'_> { for diff in diff.iter_all_changes() { match diff.tag() { ChangeTag::Equal => { - if self.use_color { + if self.color { write!(f, "{diff}")?; } else { write!(f, " {diff}")?; } } ChangeTag::Insert => { - if self.use_color { + if self.color { write!( f, "{}", @@ -375,7 +710,7 @@ impl std::fmt::Display for TestDiff<'_> { } } ChangeTag::Delete => { - if self.use_color { + if self.color { write!(f, "{}", paint(Some(AnsiColor::Red), diff.as_str().unwrap()))?; } else { write!(f, "-{diff}")?; @@ -391,7 +726,8 @@ impl std::fmt::Display for TestDiff<'_> { } } -struct TestFailure { +#[derive(Debug, Serialize)] +pub struct TestFailure { name: String, actual: String, expected: String, @@ -453,11 +789,10 @@ impl TestCorrection { fn run_tests( parser: &mut Parser, test_entry: TestEntry, - opts: &mut TestOptions, - indent_level: u32, - failures: &mut Vec, + opts: &TestOptions, + test_summary: &mut TestSummary, corrected_entries: &mut Vec, - has_parse_errors: &mut bool, + is_root: bool, ) -> Result { match test_entry { TestEntry::Example { @@ -471,29 +806,29 @@ fn run_tests( attributes, .. } => { - write!(opts.output, "{}", " ".repeat(indent_level as usize))?; - if attributes.skip { - writeln!( - opts.output, - "{:>3}. ⌀ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Yellow), &name), - )?; - opts.parse_rates.push((true, None)); - opts.test_num += 1; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Skipped, + parse_rate: None, + test_num: test_summary.test_num, + }, + }); + test_summary.test_num += 1; return Ok(true); } if !attributes.platform { - writeln!( - opts.output, - "{:>3}. ⌀ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Magenta), &name), - )?; - opts.parse_rates.push((true, None)); - opts.test_num += 1; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Platform, + parse_rate: None, + test_num: test_summary.test_num, + }, + }); + test_summary.test_num += 1; return Ok(true); } @@ -507,28 +842,30 @@ fn run_tests( } let start = std::time::Instant::now(); let tree = parser.parse(&input, None).unwrap(); - { + let parse_rate = { let parse_time = start.elapsed(); let true_parse_rate = tree.root_node().byte_range().len() as f64 / (parse_time.as_nanos() as f64 / 1_000_000.0); let adj_parse_rate = adjusted_parse_rate(&tree, parse_time); - opts.parse_rates - .push((true, Some((true_parse_rate, adj_parse_rate)))); - opts.stats.total_parses += 1; - opts.stats.total_duration += parse_time; - opts.stats.total_bytes += tree.root_node().byte_range().len(); - } + test_summary.parse_stats.total_parses += 1; + test_summary.parse_stats.total_duration += parse_time; + test_summary.parse_stats.total_bytes += tree.root_node().byte_range().len(); + + Some((true_parse_rate, adj_parse_rate)) + }; if attributes.error { if tree.root_node().has_error() { - writeln!( - opts.output, - "{:>3}. ✓ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Green), &name), - )?; - opts.stats.successful_parses += 1; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Passed, + parse_rate, + test_num: test_summary.test_num, + }, + }); + test_summary.parse_stats.successful_parses += 1; if opts.update { let input = String::from_utf8(input.clone()).unwrap(); let output = if attributes.cst { @@ -563,18 +900,25 @@ fn run_tests( divider_delim_len, )); } - writeln!( - opts.output, - "{:>3}. ✗ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Red), &name), - )?; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Failed, + parse_rate, + test_num: test_summary.test_num, + }, + }); let actual = if attributes.cst { render_test_cst(&input, &tree)? } else { tree.root_node().to_sexp() }; - failures.push(TestFailure::new(&name, actual, "NO ERROR", attributes.cst)); + test_summary.parse_failures.push(TestFailure::new( + &name, + actual, + "NO ERROR", + attributes.cst, + )); } if attributes.fail_fast { @@ -591,13 +935,15 @@ fn run_tests( } if actual == output { - writeln!( - opts.output, - "{:>3}. ✓ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Green), &name), - )?; - opts.stats.successful_parses += 1; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Passed, + parse_rate, + test_num: test_summary.test_num, + }, + }); + test_summary.parse_stats.successful_parses += 1; if opts.update { let input = String::from_utf8(input.clone()).unwrap(); let output = if attributes.cst { @@ -628,7 +974,7 @@ fn run_tests( // are intended to have errors, hence why this // check isn't shown above if actual.contains("ERROR") || actual.contains("MISSING") { - *has_parse_errors = true; + test_summary.has_parse_errors = true; // keep the original `expected` output if the actual output has an // error @@ -649,22 +995,31 @@ fn run_tests( header_delim_len, divider_delim_len, )); - writeln!( - opts.output, - "{:>3}. ✓ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Blue), &name), - )?; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Updated, + parse_rate, + test_num: test_summary.test_num, + }, + }); } } else { - writeln!( - opts.output, - "{:>3}. ✗ {}", - opts.test_num, - paint(opts.color.then_some(AnsiColor::Red), &name), - )?; + test_summary.parse_results.add_case(TestResult { + name: name.clone(), + info: TestInfo::ParseTest { + outcome: TestOutcome::Failed, + parse_rate, + test_num: test_summary.test_num, + }, + }); } - failures.push(TestFailure::new(&name, actual, &output, attributes.cst)); + test_summary.parse_failures.push(TestFailure::new( + &name, + actual, + &output, + attributes.cst, + )); if attributes.fail_fast { return Ok(false); @@ -677,7 +1032,7 @@ fn run_tests( parser.set_language(opts.languages.values().next().unwrap())?; } } - opts.test_num += 1; + test_summary.test_num += 1; } TestEntry::Group { name, @@ -688,8 +1043,8 @@ fn run_tests( return Ok(true); } - let failure_count = failures.len(); - let mut has_printed = false; + let failure_count = test_summary.parse_failures.len(); + let mut ran_test_in_group = false; let matches_filter = |name: &str, file_name: &Option, opts: &TestOptions| { if let (Some(test_file_path), Some(filter_file_name)) = (file_name, &opts.file_name) @@ -733,35 +1088,26 @@ fn run_tests( )); } - opts.test_num += 1; + test_summary.test_num += 1; continue; } } - if !has_printed && indent_level > 0 { - has_printed = true; - writeln!( - opts.output, - "{}{name}:", - " ".repeat(indent_level as usize) - )?; - opts.parse_rates.push((false, None)); + + if !ran_test_in_group && !is_root { + test_summary.parse_results.add_group(&name); + ran_test_in_group = true; } - if !run_tests( - parser, - child, - opts, - indent_level + 1, - failures, - corrected_entries, - has_parse_errors, - )? { + if !run_tests(parser, child, opts, test_summary, corrected_entries, false)? { // fail fast return Ok(false); } } + // Now that we're done traversing the children of the current group, pop + // the index + test_summary.parse_results.pop_traversal(); if let Some(file_path) = file_path { - if opts.update && failures.len() - failure_count > 0 { + if opts.update && test_summary.parse_failures.len() - failure_count > 0 { write_tests(&file_path, corrected_entries)?; } corrected_entries.clear(); diff --git a/crates/cli/src/test_highlight.rs b/crates/cli/src/test_highlight.rs index 156cd047..d96f90c2 100644 --- a/crates/cli/src/test_highlight.rs +++ b/crates/cli/src/test_highlight.rs @@ -1,14 +1,13 @@ use std::{fs, path::Path}; -use anstyle::AnsiColor; use anyhow::{anyhow, Result}; use tree_sitter::Point; use tree_sitter_highlight::{Highlight, HighlightConfiguration, HighlightEvent, Highlighter}; use tree_sitter_loader::{Config, Loader}; use crate::{ - logger::paint, query_testing::{parse_position_comments, to_utf8_point, Assertion, Utf8Point}, + test::{TestInfo, TestOutcome, TestResult, TestSummary}, util, }; @@ -48,19 +47,7 @@ pub fn test_highlights( loader_config: &Config, highlighter: &mut Highlighter, directory: &Path, - use_color: bool, -) -> Result<()> { - println!("syntax highlighting:"); - test_highlights_indented(loader, loader_config, highlighter, directory, use_color, 2) -} - -fn test_highlights_indented( - loader: &Loader, - loader_config: &Config, - highlighter: &mut Highlighter, - directory: &Path, - use_color: bool, - indent_level: usize, + test_summary: &mut TestSummary, ) -> Result<()> { let mut failed = false; @@ -68,25 +55,22 @@ fn test_highlights_indented( let highlight_test_file = highlight_test_file?; let test_file_path = highlight_test_file.path(); let test_file_name = highlight_test_file.file_name(); - print!( - "{indent:indent_level$}", - indent = "", - indent_level = indent_level * 2 - ); if test_file_path.is_dir() && test_file_path.read_dir()?.next().is_some() { - println!("{}:", test_file_name.to_string_lossy()); - if test_highlights_indented( + test_summary + .highlight_results + .add_group(test_file_name.to_string_lossy().as_ref()); + if test_highlights( loader, loader_config, highlighter, &test_file_path, - use_color, - indent_level + 1, + test_summary, ) .is_err() { failed = true; } + test_summary.highlight_results.pop_traversal(); } else { let (language, language_config) = loader .language_configuration_for_file_name(&test_file_path)? @@ -111,30 +95,28 @@ fn test_highlights_indented( fs::read(&test_file_path)?.as_slice(), ) { Ok(assertion_count) => { - println!( - "✓ {} ({assertion_count} assertions)", - paint( - use_color.then_some(AnsiColor::Green), - test_file_name.to_string_lossy().as_ref() - ), - ); + test_summary.highlight_results.add_case(TestResult { + name: test_file_name.to_string_lossy().to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionPassed { assertion_count }, + test_num: test_summary.test_num, + }, + }); } Err(e) => { - println!( - "✗ {}", - paint( - use_color.then_some(AnsiColor::Red), - test_file_name.to_string_lossy().as_ref() - ) - ); - println!( - "{indent:indent_level$} {e}", - indent = "", - indent_level = indent_level * 2 - ); + test_summary.highlight_results.add_case(TestResult { + name: test_file_name.to_string_lossy().to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionFailed { + error: e.to_string(), + }, + test_num: test_summary.test_num, + }, + }); failed = true; } } + test_summary.test_num += 1; } } diff --git a/crates/cli/src/test_tags.rs b/crates/cli/src/test_tags.rs index 9b3ed683..882718e5 100644 --- a/crates/cli/src/test_tags.rs +++ b/crates/cli/src/test_tags.rs @@ -1,13 +1,12 @@ use std::{fs, path::Path}; -use anstyle::AnsiColor; use anyhow::{anyhow, Result}; use tree_sitter_loader::{Config, Loader}; use tree_sitter_tags::{TagsConfiguration, TagsContext}; use crate::{ - logger::paint, query_testing::{parse_position_comments, to_utf8_point, Assertion, Utf8Point}, + test::{TestInfo, TestOutcome, TestResult, TestSummary}, util, }; @@ -47,19 +46,7 @@ pub fn test_tags( loader_config: &Config, tags_context: &mut TagsContext, directory: &Path, - use_color: bool, -) -> Result<()> { - println!("tags:"); - test_tags_indented(loader, loader_config, tags_context, directory, use_color, 2) -} - -pub fn test_tags_indented( - loader: &Loader, - loader_config: &Config, - tags_context: &mut TagsContext, - directory: &Path, - use_color: bool, - indent_level: usize, + test_summary: &mut TestSummary, ) -> Result<()> { let mut failed = false; @@ -67,25 +54,22 @@ pub fn test_tags_indented( let tag_test_file = tag_test_file?; let test_file_path = tag_test_file.path(); let test_file_name = tag_test_file.file_name(); - print!( - "{indent:indent_level$}", - indent = "", - indent_level = indent_level * 2 - ); if test_file_path.is_dir() && test_file_path.read_dir()?.next().is_some() { - println!("{}:", test_file_name.to_string_lossy()); - if test_tags_indented( + test_summary + .tag_results + .add_group(test_file_name.to_string_lossy().as_ref()); + if test_tags( loader, loader_config, tags_context, &test_file_path, - use_color, - indent_level + 1, + test_summary, ) .is_err() { failed = true; } + test_summary.tag_results.pop_traversal(); } else { let (language, language_config) = loader .language_configuration_for_file_name(&test_file_path)? @@ -104,30 +88,28 @@ pub fn test_tags_indented( fs::read(&test_file_path)?.as_slice(), ) { Ok(assertion_count) => { - println!( - "✓ {} ({assertion_count} assertions)", - paint( - use_color.then_some(AnsiColor::Green), - test_file_name.to_string_lossy().as_ref() - ), - ); + test_summary.tag_results.add_case(TestResult { + name: test_file_name.to_string_lossy().to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionPassed { assertion_count }, + test_num: test_summary.test_num, + }, + }); } Err(e) => { - println!( - "✗ {}", - paint( - use_color.then_some(AnsiColor::Red), - test_file_name.to_string_lossy().as_ref() - ) - ); - println!( - "{indent:indent_level$} {e}", - indent = "", - indent_level = indent_level * 2 - ); + test_summary.tag_results.add_case(TestResult { + name: test_file_name.to_string_lossy().to_string(), + info: TestInfo::AssertionTest { + outcome: TestOutcome::AssertionFailed { + error: e.to_string(), + }, + test_num: test_summary.test_num, + }, + }); failed = true; } } + test_summary.test_num += 1; } } diff --git a/crates/cli/src/tests/corpus_test.rs b/crates/cli/src/tests/corpus_test.rs index de797401..ba3fd68e 100644 --- a/crates/cli/src/tests/corpus_test.rs +++ b/crates/cli/src/tests/corpus_test.rs @@ -209,8 +209,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect initial parse for {test_name}"); - println!("{DiffKey}"); - println!("{}", TestDiff::new(&actual_output, &test.output, true)); + DiffKey::print(); + println!("{}", TestDiff::new(&actual_output, &test.output)); println!(); return false; } @@ -297,8 +297,8 @@ pub fn test_language_corpus( if actual_output != test.output { println!("Incorrect parse for {test_name} - seed {seed}"); - println!("{DiffKey}"); - println!("{}", TestDiff::new(&actual_output, &test.output, true)); + DiffKey::print(); + println!("{}", TestDiff::new(&actual_output, &test.output)); println!(); return false; } @@ -428,8 +428,8 @@ fn test_feature_corpus_files() { if actual_output == test.output { true } else { - println!("{DiffKey}"); - print!("{}", TestDiff::new(&actual_output, &test.output, true)); + DiffKey::print(); + print!("{}", TestDiff::new(&actual_output, &test.output)); println!(); false } From fe67521b3d71eb992baa9d54145b93f068187bbd Mon Sep 17 00:00:00 2001 From: WillLillis Date: Mon, 29 Sep 2025 02:52:48 -0400 Subject: [PATCH 031/140] refactor(cli)!: deprecate `json` flags in favor of `json-summary` --- crates/cli/src/main.rs | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index e5cc7317..dbd74a14 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -129,9 +129,12 @@ struct Generate { /// Produce a report of the states for the given rule, use `-` to report every rule #[arg(long)] pub report_states_for_rule: Option, - /// Report conflicts in a JSON format - #[arg(long)] + /// Deprecated: use --json-summary + #[arg(long, conflicts_with = "json_summary")] pub json: bool, + /// Report conflicts in a JSON format + #[arg(long, conflicts_with = "json")] + pub json_summary: bool, /// The name or path of the JavaScript runtime to use for generating parsers #[cfg(not(feature = "qjs-rt"))] #[arg( @@ -249,9 +252,12 @@ struct Parse { /// Open `log.html` in the default browser, if `--debug-graph` is supplied #[arg(long)] pub open_log: bool, - /// Output parsing results in a JSON format - #[arg(long, short = 'j')] + /// Deprecated: use --json-summary + #[arg(long, short = 'j', conflicts_with = "json_summary")] pub json: bool, + /// Output parsing results in a JSON format + #[arg(long, conflicts_with = "json")] + pub json_summary: bool, /// The path to an alternative config.json file #[arg(long)] pub config_path: Option, @@ -855,6 +861,13 @@ impl Generate { } }); + let json_summary = if self.json { + warn!("--json is deprecated, use --json-summary instead"); + true + } else { + self.json_summary + }; + if let Err(err) = tree_sitter_generate::generate_parser_in_directory( current_dir, self.output.as_deref(), @@ -869,7 +882,7 @@ impl Generate { OptLevel::default() }, ) { - if self.json { + if json_summary { eprintln!("{}", serde_json::to_string_pretty(&err)?); // Exit early to prevent errors from being printed a second time in the caller std::process::exit(1); @@ -940,13 +953,19 @@ impl Parse { fn run(self, mut loader: loader::Loader, current_dir: &Path) -> Result<()> { let config = Config::load(self.config_path)?; let color = env::var("NO_COLOR").map_or(true, |v| v != "1"); + let json_summary = if self.json { + warn!("--json is deprecated, use --json-summary instead"); + true + } else { + self.json_summary + }; let output = if self.output_dot { ParseOutput::Dot } else if self.output_xml { ParseOutput::Xml } else if self.output_cst { ParseOutput::Cst - } else if self.quiet || self.json { + } else if self.quiet || json_summary { ParseOutput::Quiet } else { ParseOutput::Normal @@ -1142,7 +1161,7 @@ impl Parse { if should_track_stats { println!("\n{}", stats.cumulative_stats); } - if self.json { + if json_summary { println!("{}", serde_json::to_string_pretty(&stats)?); } From ff255a2354fabe8ec36a3a936e70cf9b73f05126 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Wed, 1 Oct 2025 04:34:54 -0400 Subject: [PATCH 032/140] test: add coverage for new test aggregation method --- crates/cli/src/test.rs | 290 ++++++++++++++++++++++++++++++++++++++++ crates/cli/src/tests.rs | 2 + 2 files changed, 292 insertions(+) diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index 90629b15..18d07d23 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -1453,6 +1453,10 @@ fn parse_test_content(name: String, content: &str, file_path: Option) - #[cfg(test)] mod tests { + use serde_json::json; + + use crate::tests::get_language; + use super::*; #[test] @@ -2110,4 +2114,290 @@ Test with cst marker } ); } + + fn clear_parse_rate(result: &mut TestResult) { + let test_case_info = &mut result.info; + match test_case_info { + TestInfo::ParseTest { + ref mut parse_rate, .. + } => { + assert!(parse_rate.is_some()); + *parse_rate = None; + } + TestInfo::Group { .. } | TestInfo::AssertionTest { .. } => { + panic!("Unexpected test result") + } + } + } + + #[test] + fn run_tests_simple() { + let mut parser = Parser::new(); + let language = get_language("c"); + parser + .set_language(&language) + .expect("Failed to set language"); + let mut languages = BTreeMap::new(); + languages.insert("c", &language); + let opts = TestOptions { + path: PathBuf::from("foo"), + debug: true, + debug_graph: false, + include: None, + exclude: None, + file_name: None, + update: false, + open_log: false, + languages, + color: true, + show_fields: false, + overview_only: false, + }; + + // NOTE: The following test cases are combined to work around a race condition + // in the loader + { + let test_entry = TestEntry::Group { + name: "foo".to_string(), + file_path: None, + children: vec![TestEntry::Example { + name: "C Test 1".to_string(), + input: b"1;\n".to_vec(), + output: "(translation_unit (expression_statement (number_literal)))" + .to_string(), + header_delim_len: 25, + divider_delim_len: 3, + has_fields: false, + attributes_str: String::new(), + attributes: TestAttributes::default(), + file_name: None, + }], + }; + + let mut test_summary = TestSummary::new(true, TestStats::All, false, false, false); + let mut corrected_entries = Vec::new(); + run_tests( + &mut parser, + test_entry, + &opts, + &mut test_summary, + &mut corrected_entries, + true, + ) + .expect("Failed to run tests"); + + // parse rates will always be different, so we need to clear out these + // fields to reliably assert equality below + clear_parse_rate(&mut test_summary.parse_results.root_group[0]); + test_summary.parse_stats.total_duration = Duration::from_secs(0); + + let json_results = serde_json::to_string(&test_summary).unwrap(); + + assert_eq!( + json_results, + json!({ + "parse_results": [ + { + "name": "C Test 1", + "outcome": "Passed", + "parse_rate": null, + "test_num": 1 + } + ], + "parse_failures": [], + "parse_stats": { + "successful_parses": 1, + "total_parses": 1, + "total_bytes": 3, + "total_duration": { + "secs": 0, + "nanos": 0, + } + }, + "highlight_results": [], + "tag_results": [], + "query_results": [] + }) + .to_string() + ); + } + { + let test_entry = TestEntry::Group { + name: "corpus".to_string(), + file_path: None, + children: vec![ + TestEntry::Group { + name: "group1".to_string(), + // This test passes + children: vec![TestEntry::Example { + name: "C Test 1".to_string(), + input: b"1;\n".to_vec(), + output: "(translation_unit (expression_statement (number_literal)))" + .to_string(), + header_delim_len: 25, + divider_delim_len: 3, + has_fields: false, + attributes_str: String::new(), + attributes: TestAttributes::default(), + file_name: None, + }], + file_path: None, + }, + TestEntry::Group { + name: "group2".to_string(), + children: vec![ + // This test passes + TestEntry::Example { + name: "C Test 2".to_string(), + input: b"1;\n".to_vec(), + output: + "(translation_unit (expression_statement (number_literal)))" + .to_string(), + header_delim_len: 25, + divider_delim_len: 3, + has_fields: false, + attributes_str: String::new(), + attributes: TestAttributes::default(), + file_name: None, + }, + // This test fails, and is marked with fail-fast + TestEntry::Example { + name: "C Test 3".to_string(), + input: b"1;\n".to_vec(), + output: + "(translation_unit (expression_statement (string_literal)))" + .to_string(), + header_delim_len: 25, + divider_delim_len: 3, + has_fields: false, + attributes_str: String::new(), + attributes: TestAttributes { + fail_fast: true, + ..Default::default() + }, + file_name: None, + }, + ], + file_path: None, + }, + // This group never runs because of the previous failure + TestEntry::Group { + name: "group3".to_string(), + // This test fails, and is marked with fail-fast + children: vec![TestEntry::Example { + name: "C Test 4".to_string(), + input: b"1;\n".to_vec(), + output: "(translation_unit (expression_statement (number_literal)))" + .to_string(), + header_delim_len: 25, + divider_delim_len: 3, + has_fields: false, + attributes_str: String::new(), + attributes: TestAttributes::default(), + file_name: None, + }], + file_path: None, + }, + ], + }; + + let mut test_summary = TestSummary::new(true, TestStats::All, false, false, false); + let mut corrected_entries = Vec::new(); + run_tests( + &mut parser, + test_entry, + &opts, + &mut test_summary, + &mut corrected_entries, + true, + ) + .expect("Failed to run tests"); + + // parse rates will always be different, so we need to clear out these + // fields to reliably assert equality below + { + let test_group_1_info = &mut test_summary.parse_results.root_group[0].info; + match test_group_1_info { + TestInfo::Group { + ref mut children, .. + } => clear_parse_rate(&mut children[0]), + TestInfo::ParseTest { .. } | TestInfo::AssertionTest { .. } => { + panic!("Unexpected test result"); + } + } + let test_group_2_info = &mut test_summary.parse_results.root_group[1].info; + match test_group_2_info { + TestInfo::Group { + ref mut children, .. + } => { + clear_parse_rate(&mut children[0]); + clear_parse_rate(&mut children[1]); + } + TestInfo::ParseTest { .. } | TestInfo::AssertionTest { .. } => { + panic!("Unexpected test result"); + } + } + test_summary.parse_stats.total_duration = Duration::from_secs(0); + } + + let json_results = serde_json::to_string(&test_summary).unwrap(); + + assert_eq!( + json_results, + json!({ + "parse_results": [ + { + "name": "group1", + "children": [ + { + "name": "C Test 1", + "outcome": "Passed", + "parse_rate": null, + "test_num": 1 + } + ] + }, + { + "name": "group2", + "children": [ + { + "name": "C Test 2", + "outcome": "Passed", + "parse_rate": null, + "test_num": 2 + }, + { + "name": "C Test 3", + "outcome": "Failed", + "parse_rate": null, + "test_num": 3 + } + ] + } + ], + "parse_failures": [ + { + "name": "C Test 3", + "actual": "(translation_unit (expression_statement (number_literal)))", + "expected": "(translation_unit (expression_statement (string_literal)))", + "is_cst": false, + } + ], + "parse_stats": { + "successful_parses": 2, + "total_parses": 3, + "total_bytes": 9, + "total_duration": { + "secs": 0, + "nanos": 0, + } + }, + "highlight_results": [], + "tag_results": [], + "query_results": [] + }) + .to_string() + ); + } + } } diff --git a/crates/cli/src/tests.rs b/crates/cli/src/tests.rs index 9fc1c71b..2439be38 100644 --- a/crates/cli/src/tests.rs +++ b/crates/cli/src/tests.rs @@ -26,6 +26,8 @@ pub use crate::fuzz::{ ITERATION_COUNT, }; +pub use helpers::fixtures::get_language; + /// This is a simple wrapper around [`tree_sitter_generate::generate_parser_for_grammar`], because /// our tests do not need to pass in a version number, only the grammar JSON. fn generate_parser(grammar_json: &str) -> GenerateResult<(String, String)> { From 86e2fd23378727e760d7e2e7963dbf5be329412d Mon Sep 17 00:00:00 2001 From: WillLillis Date: Thu, 2 Oct 2025 01:27:59 -0400 Subject: [PATCH 033/140] fix(cli): correct behavior of parse `--stat` and `--json-summary` flags --- crates/cli/src/main.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index dbd74a14..23056be7 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -227,7 +227,7 @@ struct Parse { #[arg(long = "cst", short = 'c')] pub output_cst: bool, /// Show parsing statistic - #[arg(long, short)] + #[arg(long, short, conflicts_with = "json", conflicts_with = "json_summary")] pub stat: bool, /// Interrupt the parsing process by timeout (µs) #[arg(long)] @@ -253,10 +253,15 @@ struct Parse { #[arg(long)] pub open_log: bool, /// Deprecated: use --json-summary - #[arg(long, short = 'j', conflicts_with = "json_summary")] + #[arg( + long, + short = 'j', + conflicts_with = "json_summary", + conflicts_with = "stat" + )] pub json: bool, /// Output parsing results in a JSON format - #[arg(long, conflicts_with = "json")] + #[arg(long, conflicts_with = "json", conflicts_with = "stat")] pub json_summary: bool, /// The path to an alternative config.json file #[arg(long)] @@ -1039,7 +1044,7 @@ impl Parse { let mut update_stats = |stats: &mut parse::ParseStats| { let parse_result = stats.parse_summaries.last().unwrap(); - if should_track_stats { + if should_track_stats || json_summary { stats.cumulative_stats.total_parses += 1; if parse_result.successful { stats.cumulative_stats.successful_parses += 1; From d546e28abfb295a7d1039dbd6a23498bd487719c Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 12 Oct 2025 04:06:22 -0400 Subject: [PATCH 034/140] fix(cli): mark `report_states_for_rule` and `json`/`json_summary` flags for `generate` command as conflicting --- crates/cli/src/main.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 23056be7..9f895987 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -127,13 +127,21 @@ struct Generate { #[arg(long, short, value_name = "DIRECTORY")] pub output: Option, /// Produce a report of the states for the given rule, use `-` to report every rule - #[arg(long)] + #[arg(long, conflicts_with = "json", conflicts_with = "json_summary")] pub report_states_for_rule: Option, /// Deprecated: use --json-summary - #[arg(long, conflicts_with = "json_summary")] + #[arg( + long, + conflicts_with = "json_summary", + conflicts_with = "report_states_for_rule" + )] pub json: bool, /// Report conflicts in a JSON format - #[arg(long, conflicts_with = "json")] + #[arg( + long, + conflicts_with = "json", + conflicts_with = "report_states_for_rule" + )] pub json_summary: bool, /// The name or path of the JavaScript runtime to use for generating parsers #[cfg(not(feature = "qjs-rt"))] From c7b5f89392495fa144a504f28028f5e320ededa8 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Fri, 31 Oct 2025 18:23:21 -0400 Subject: [PATCH 035/140] feat(xtask): generate JSON schema for cli `TestSummary` --- Cargo.lock | 65 +++++ Cargo.toml | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/parse.rs | 3 +- crates/cli/src/test.rs | 35 ++- crates/xtask/Cargo.toml | 2 + crates/xtask/src/main.rs | 4 + crates/xtask/src/test_schema.rs | 25 ++ .../assets/schemas/test-summary.schema.json | 247 ++++++++++++++++++ 9 files changed, 376 insertions(+), 7 deletions(-) create mode 100644 crates/xtask/src/test_schema.rs create mode 100644 docs/src/assets/schemas/test-summary.schema.json diff --git a/Cargo.lock b/Cargo.lock index 1639883b..b351edac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -576,6 +576,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "either" version = "1.15.0" @@ -1438,6 +1444,26 @@ dependencies = [ "getrandom 0.2.16", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "regalloc2" version = "0.12.2" @@ -1603,6 +1629,31 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +dependencies = [ + "dyn-clone", + "ref-cast", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + [[package]] name = "semver" version = "1.0.27" @@ -1643,6 +1694,17 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_json" version = "1.0.145" @@ -1947,6 +2009,7 @@ dependencies = [ "pretty_assertions", "rand", "regex", + "schemars", "semver", "serde", "serde_json", @@ -2740,8 +2803,10 @@ dependencies = [ "notify", "notify-debouncer-full", "regex", + "schemars", "semver", "serde_json", + "tree-sitter-cli", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1d5454e5..5473d9a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -137,6 +137,7 @@ rand = "0.8.5" regex = "1.11.3" regex-syntax = "0.8.6" rustc-hash = "2.1.1" +schemars = "1.0.4" semver = { version = "1.0.27", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = { version = "1.0.145", features = ["preserve_order"] } diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index d8df92c8..31626eb2 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -54,6 +54,7 @@ log.workspace = true memchr.workspace = true rand.workspace = true regex.workspace = true +schemars.workspace = true semver.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 84bf0e85..1023b0fc 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -11,6 +11,7 @@ use anstyle::{AnsiColor, Color, RgbColor}; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; use log::info; +use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use tree_sitter::{ ffi, InputEdit, Language, LogType, ParseOptions, ParseState, Parser, Point, Range, Tree, @@ -19,7 +20,7 @@ use tree_sitter::{ use crate::{fuzz::edits::Edit, logger::paint, util}; -#[derive(Debug, Default, Serialize)] +#[derive(Debug, Default, Serialize, JsonSchema)] pub struct Stats { pub successful_parses: usize, pub total_parses: usize, diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index 18d07d23..3753dcea 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -18,6 +18,7 @@ use regex::{ bytes::{Regex as ByteRegex, RegexBuilder as ByteRegexBuilder}, Regex, }; +use schemars::{JsonSchema, Schema, SchemaGenerator}; use serde::Serialize; use similar::{ChangeTag, TextDiff}; use tree_sitter::{format_sexp, Language, LogType, Parser, Query, Tree}; @@ -139,36 +140,47 @@ pub struct TestOptions<'a> { } /// A stateful object used to collect results from running a grammar's test suite -#[derive(Debug, Default, Serialize)] +#[derive(Debug, Default, Serialize, JsonSchema)] pub struct TestSummary { // Parse test results and associated data + #[schemars(schema_with = "schema_as_array")] #[serde(serialize_with = "serialize_as_array")] pub parse_results: TestResultHierarchy, pub parse_failures: Vec, pub parse_stats: Stats, + #[schemars(skip)] #[serde(skip)] pub has_parse_errors: bool, + #[schemars(skip)] #[serde(skip)] pub parse_stat_display: TestStats, // Other test results + #[schemars(schema_with = "schema_as_array")] #[serde(serialize_with = "serialize_as_array")] pub highlight_results: TestResultHierarchy, + #[schemars(schema_with = "schema_as_array")] #[serde(serialize_with = "serialize_as_array")] pub tag_results: TestResultHierarchy, + #[schemars(schema_with = "schema_as_array")] #[serde(serialize_with = "serialize_as_array")] pub query_results: TestResultHierarchy, // Data used during construction + #[schemars(skip)] #[serde(skip)] pub test_num: usize, // Options passed in from the CLI which control how the summary is displayed + #[schemars(skip)] #[serde(skip)] pub color: bool, + #[schemars(skip)] #[serde(skip)] pub overview_only: bool, + #[schemars(skip)] #[serde(skip)] pub update: bool, + #[schemars(skip)] #[serde(skip)] pub json: bool, } @@ -194,7 +206,7 @@ impl TestSummary { } } -#[derive(Debug, Default)] +#[derive(Debug, Default, JsonSchema)] pub struct TestResultHierarchy { root_group: Vec, traversal_idxs: Vec, @@ -207,6 +219,10 @@ where results.root_group.serialize(serializer) } +fn schema_as_array(gen: &mut SchemaGenerator) -> Schema { + gen.subschema_for::>() +} + /// Stores arbitrarily nested parent test groups and child cases. Supports creation /// in DFS traversal order impl TestResultHierarchy { @@ -313,14 +329,16 @@ impl<'a> Iterator for TestResultIterWithDepth<'a> { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, JsonSchema)] pub struct TestResult { pub name: String, + #[schemars(flatten)] #[serde(flatten)] pub info: TestInfo, } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, JsonSchema)] +#[schemars(untagged)] #[serde(untagged)] pub enum TestInfo { Group { @@ -329,6 +347,7 @@ pub enum TestInfo { ParseTest { outcome: TestOutcome, // True parse rate, adjusted parse rate + #[schemars(schema_with = "parse_rate_schema")] #[serde(serialize_with = "serialize_parse_rates")] parse_rate: Option<(f64, f64)>, test_num: usize, @@ -352,7 +371,11 @@ where } } -#[derive(Debug, Clone, Eq, PartialEq, Serialize)] +fn parse_rate_schema(gen: &mut SchemaGenerator) -> Schema { + gen.subschema_for::>() +} + +#[derive(Debug, Clone, Eq, PartialEq, Serialize, JsonSchema)] pub enum TestOutcome { // Parse outcomes Passed, @@ -726,7 +749,7 @@ impl std::fmt::Display for TestDiff<'_> { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, JsonSchema)] pub struct TestFailure { name: String, actual: String, diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml index 607d64ad..90134d03 100644 --- a/crates/xtask/Cargo.toml +++ b/crates/xtask/Cargo.toml @@ -21,7 +21,9 @@ bindgen = { version = "0.72.0" } clap.workspace = true indoc.workspace = true regex.workspace = true +schemars.workspace = true semver.workspace = true serde_json.workspace = true +tree-sitter-cli = { path = "../cli/" } notify = "8.2.0" notify-debouncer-full = "0.6.0" diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 46b2e796..3814cf66 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -7,6 +7,7 @@ mod embed_sources; mod fetch; mod generate; mod test; +mod test_schema; mod upgrade_wasmtime; use std::{path::Path, process::Command}; @@ -40,6 +41,8 @@ enum Commands { GenerateBindings, /// Generates the fixtures for testing tree-sitter. GenerateFixtures(GenerateFixtures), + /// Generates the JSON schema for the test runner summary. + GenerateTestSchema, /// Generate the list of exports from Tree-sitter Wasm files. GenerateWasmExports, /// Run the test suite @@ -236,6 +239,7 @@ fn run() -> Result<()> { Commands::GenerateFixtures(generate_fixtures_options) => { generate::run_fixtures(&generate_fixtures_options)?; } + Commands::GenerateTestSchema => test_schema::run_test_schema()?, Commands::GenerateWasmExports => generate::run_wasm_exports()?, Commands::Test(test_options) => test::run(&test_options)?, Commands::TestWasm => test::run_wasm()?, diff --git a/crates/xtask/src/test_schema.rs b/crates/xtask/src/test_schema.rs new file mode 100644 index 00000000..a2f65ed2 --- /dev/null +++ b/crates/xtask/src/test_schema.rs @@ -0,0 +1,25 @@ +use std::path::PathBuf; + +use anyhow::Result; +use serde_json::to_writer_pretty; + +use tree_sitter_cli::test::TestSummary; + +pub fn run_test_schema() -> Result<()> { + let schema = schemars::schema_for!(TestSummary); + + let xtask_path: PathBuf = env!("CARGO_MANIFEST_DIR").into(); + let schema_path = xtask_path + .parent() + .unwrap() + .parent() + .unwrap() + .join("docs") + .join("src") + .join("assets") + .join("schemas") + .join("test-summary.schema.json"); + let mut file = std::fs::File::create(schema_path)?; + + Ok(to_writer_pretty(&mut file, &schema)?) +} diff --git a/docs/src/assets/schemas/test-summary.schema.json b/docs/src/assets/schemas/test-summary.schema.json new file mode 100644 index 00000000..6211d60c --- /dev/null +++ b/docs/src/assets/schemas/test-summary.schema.json @@ -0,0 +1,247 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "TestSummary", + "description": "A stateful object used to collect results from running a grammar's test suite", + "type": "object", + "properties": { + "parse_results": { + "type": "array", + "items": { + "$ref": "#/$defs/TestResult" + } + }, + "parse_failures": { + "type": "array", + "items": { + "$ref": "#/$defs/TestFailure" + } + }, + "parse_stats": { + "$ref": "#/$defs/Stats" + }, + "highlight_results": { + "type": "array", + "items": { + "$ref": "#/$defs/TestResult" + } + }, + "tag_results": { + "type": "array", + "items": { + "$ref": "#/$defs/TestResult" + } + }, + "query_results": { + "type": "array", + "items": { + "$ref": "#/$defs/TestResult" + } + } + }, + "required": [ + "parse_results", + "parse_failures", + "parse_stats", + "highlight_results", + "tag_results", + "query_results" + ], + "$defs": { + "TestResult": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "required": [ + "name" + ], + "anyOf": [ + { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/$defs/TestResult" + } + } + }, + "required": [ + "children" + ] + }, + { + "type": "object", + "properties": { + "outcome": { + "$ref": "#/$defs/TestOutcome" + }, + "parse_rate": { + "type": [ + "number", + "null" + ], + "format": "double" + }, + "test_num": { + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "outcome", + "parse_rate", + "test_num" + ] + }, + { + "type": "object", + "properties": { + "outcome": { + "$ref": "#/$defs/TestOutcome" + }, + "test_num": { + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "outcome", + "test_num" + ] + } + ] + }, + "TestOutcome": { + "oneOf": [ + { + "type": "string", + "enum": [ + "Passed", + "Failed", + "Updated", + "Skipped", + "Platform" + ] + }, + { + "type": "object", + "properties": { + "AssertionPassed": { + "type": "object", + "properties": { + "assertion_count": { + "type": "integer", + "format": "uint", + "minimum": 0 + } + }, + "required": [ + "assertion_count" + ] + } + }, + "required": [ + "AssertionPassed" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "AssertionFailed": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + }, + "required": [ + "error" + ] + } + }, + "required": [ + "AssertionFailed" + ], + "additionalProperties": false + } + ] + }, + "TestFailure": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "actual": { + "type": "string" + }, + "expected": { + "type": "string" + }, + "is_cst": { + "type": "boolean" + } + }, + "required": [ + "name", + "actual", + "expected", + "is_cst" + ] + }, + "Stats": { + "type": "object", + "properties": { + "successful_parses": { + "type": "integer", + "format": "uint", + "minimum": 0 + }, + "total_parses": { + "type": "integer", + "format": "uint", + "minimum": 0 + }, + "total_bytes": { + "type": "integer", + "format": "uint", + "minimum": 0 + }, + "total_duration": { + "$ref": "#/$defs/Duration" + } + }, + "required": [ + "successful_parses", + "total_parses", + "total_bytes", + "total_duration" + ] + }, + "Duration": { + "type": "object", + "properties": { + "secs": { + "type": "integer", + "format": "uint64", + "minimum": 0 + }, + "nanos": { + "type": "integer", + "format": "uint32", + "minimum": 0 + } + }, + "required": [ + "secs", + "nanos" + ] + } + } +} \ No newline at end of file From 419a5a7305d157c530bacebe3fff03282a37dc3f Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 13 Oct 2025 01:49:00 -0400 Subject: [PATCH 036/140] fix(generate): don't short-circuit within `extend_sorted` --- crates/generate/src/node_types.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/generate/src/node_types.rs b/crates/generate/src/node_types.rs index f50af44f..0a964105 100644 --- a/crates/generate/src/node_types.rs +++ b/crates/generate/src/node_types.rs @@ -829,12 +829,12 @@ fn extend_sorted<'a, T>(vec: &mut Vec, values: impl IntoIterator Date: Tue, 4 Nov 2025 09:37:58 +0000 Subject: [PATCH 037/140] build(deps): bump the cargo group across 1 directory with 6 updates Bumps the cargo group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [cc](https://github.com/rust-lang/cc-rs) | `1.2.43` | `1.2.44` | | [clap](https://github.com/clap-rs/clap) | `4.5.50` | `4.5.51` | | [clap_complete](https://github.com/clap-rs/clap) | `4.5.59` | `4.5.60` | | [clap_complete_nushell](https://github.com/clap-rs/clap) | `4.5.9` | `4.5.10` | | [etcetera](https://github.com/lunacookies/etcetera) | `0.10.0` | `0.11.0` | | [wasmparser](https://github.com/bytecodealliance/wasm-tools) | `0.229.0` | `0.240.0` | Updates `cc` from 1.2.43 to 1.2.44 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.43...cc-v1.2.44) Updates `clap` from 4.5.50 to 4.5.51 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.50...clap_complete-v4.5.51) Updates `clap_complete` from 4.5.59 to 4.5.60 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.59...clap_complete-v4.5.60) Updates `clap_complete_nushell` from 4.5.9 to 4.5.10 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete_nushell-v4.5.9...clap_complete_nushell-v4.5.10) Updates `etcetera` from 0.10.0 to 0.11.0 - [Release notes](https://github.com/lunacookies/etcetera/releases) - [Commits](https://github.com/lunacookies/etcetera/compare/v0.10.0...v0.11.0) Updates `wasmparser` from 0.229.0 to 0.240.0 - [Release notes](https://github.com/bytecodealliance/wasm-tools/releases) - [Commits](https://github.com/bytecodealliance/wasm-tools/commits) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.44 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap dependency-version: 4.5.51 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-version: 4.5.60 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete_nushell dependency-version: 4.5.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: etcetera dependency-version: 0.11.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: wasmparser dependency-version: 0.240.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 65 ++++++++++++++++++++++++++++-------------------------- Cargo.toml | 12 +++++----- 2 files changed, 40 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b351edac..8cf0a189 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.43" +version = "1.2.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "739eb0f94557554b3ca9a86d2d37bebd49c5e6d0c1d2bda35ba5bdac830befc2" +checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" dependencies = [ "find-msvc-tools", "shlex", @@ -241,9 +241,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -263,18 +263,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.59" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2348487adcd4631696ced64ccdb40d38ac4d31cae7f2eec8817fcea1b9d1c43c" +checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" dependencies = [ "clap", ] [[package]] name = "clap_complete_nushell" -version = "4.5.9" +version = "4.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "811159f339691baacdf7d534df2946b9d217014081099e23d31d887d99521e70" +checksum = "685bc86fd34b7467e0532a4f8435ab107960d69a243785ef0275e571b35b641a" dependencies = [ "clap", "clap_complete", @@ -633,13 +633,12 @@ dependencies = [ [[package]] name = "etcetera" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c7b13d0780cb82722fd59f6f57f925e143427e4a75313a6c77243bf5326ae6" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" dependencies = [ "cfg-if", - "home", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -791,15 +790,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "html-escape" version = "0.2.13" @@ -2026,7 +2016,7 @@ dependencies = [ "tree-sitter-tests-proc-macro", "unindent", "walkdir", - "wasmparser", + "wasmparser 0.240.0", "webbrowser", "widestring", ] @@ -2253,7 +2243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38ba1d491ecacb085a2552025c10a675a6fddcbd03b1fc9b36c536010ce265d2" dependencies = [ "leb128fmt", - "wasmparser", + "wasmparser 0.229.0", ] [[package]] @@ -2269,6 +2259,19 @@ dependencies = [ "serde", ] +[[package]] +name = "wasmparser" +version = "0.240.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap", + "semver", + "serde", +] + [[package]] name = "wasmprinter" version = "0.229.0" @@ -2277,7 +2280,7 @@ checksum = "d25dac01892684a99b8fbfaf670eb6b56edea8a096438c75392daeb83156ae2e" dependencies = [ "anyhow", "termcolor", - "wasmparser", + "wasmparser 0.229.0", ] [[package]] @@ -2309,7 +2312,7 @@ dependencies = [ "smallvec", "sptr", "target-lexicon", - "wasmparser", + "wasmparser 0.229.0", "wasmtime-asm-macros", "wasmtime-cranelift", "wasmtime-environ", @@ -2375,7 +2378,7 @@ dependencies = [ "smallvec", "target-lexicon", "thiserror 2.0.17", - "wasmparser", + "wasmparser 0.229.0", "wasmtime-environ", "wasmtime-versioned-export-macros", ] @@ -2399,7 +2402,7 @@ dependencies = [ "smallvec", "target-lexicon", "wasm-encoder", - "wasmparser", + "wasmparser 0.229.0", "wasmprinter", ] @@ -2467,7 +2470,7 @@ dependencies = [ "gimli", "object 0.36.7", "target-lexicon", - "wasmparser", + "wasmparser 0.229.0", "wasmtime-cranelift", "wasmtime-environ", "winch-codegen", @@ -2528,7 +2531,7 @@ dependencies = [ "smallvec", "target-lexicon", "thiserror 2.0.17", - "wasmparser", + "wasmparser 0.229.0", "wasmtime-cranelift", "wasmtime-environ", ] diff --git a/Cargo.toml b/Cargo.toml index 5473d9a1..521ad684 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,8 +106,8 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.41" -clap = { version = "4.5.48", features = [ +cc = "1.2.44" +clap = { version = "4.5.51", features = [ "cargo", "derive", "env", @@ -115,13 +115,13 @@ clap = { version = "4.5.48", features = [ "string", "unstable-styles", ] } -clap_complete = "4.5.58" -clap_complete_nushell = "4.5.8" +clap_complete = "4.5.60" +clap_complete_nushell = "4.5.10" crc32fast = "1.5.0" ctor = "0.2.9" ctrlc = { version = "3.5.0", features = ["termination"] } dialoguer = { version = "0.11.0", features = ["fuzzy-select"] } -etcetera = "0.10.0" +etcetera = "0.11.0" fs4 = "0.12.0" glob = "0.3.3" heck = "0.5.0" @@ -150,7 +150,7 @@ tiny_http = "0.12.0" topological-sort = "0.2.2" unindent = "0.2.4" walkdir = "2.5.0" -wasmparser = "0.229.0" +wasmparser = "0.240.0" webbrowser = "1.0.5" tree-sitter = { version = "0.26.0", path = "./lib" } From 361287fb56bd9a649281f6d2cf27e4a3b745fb4d Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 3 Nov 2025 01:46:05 -0500 Subject: [PATCH 038/140] fix(cli)!: deprecate `--build` flag for `generate` command --- crates/cli/src/main.rs | 7 ++++--- docs/src/cli/generate.md | 11 ----------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 9f895987..d9f8c174 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -114,13 +114,13 @@ struct Generate { /// Only generate `grammar.json` and `node-types.json` #[arg(long)] pub no_parser: bool, - /// Compile all defined languages in the current dir + /// Deprecated: use the `build` command #[arg(long, short = 'b')] pub build: bool, - /// Compile a parser in debug mode + /// Deprecated: use the `build` command #[arg(long, short = '0')] pub debug_build: bool, - /// The path to the directory containing the parser library + /// Deprecated: use the `build` command #[arg(long, value_name = "PATH")] pub libdir: Option, /// The path to output the generated source files @@ -905,6 +905,7 @@ impl Generate { } } if self.build { + warn!("--build is deprecated, use the `build` command"); if let Some(path) = self.libdir { loader = loader::Loader::with_parser_lib_path(path); } diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 9014e0ea..32c8437a 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -34,17 +34,6 @@ The ABI to use for parser generation. The default is ABI 15, with ABI 14 being a Only generate `grammar.json` and `node-types.json` -### `-0/--debug-build` - -Compile the parser with debug flags enabled. This is useful when debugging issues that require a debugger like `gdb` or `lldb`. - -### `--libdir ` - -The directory to place the compiled parser(s) in. -On Unix systems, the default path is `$XDG_CACHE_HOME/tree-sitter` if `$XDG_CACHE_HOME` is set, -otherwise `$HOME/.config/tree-sitter` is used. On Windows, the default path is `%LOCALAPPDATA%\tree-sitter` if available, -otherwise `$HOME\AppData\Local\tree-sitter` is used. - ### `-o/--output` The directory to place the generated parser in. The default is `src/` in the current directory. From 13ff3935ac902ce050d29559072f31e4b4876536 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 21:22:31 +0000 Subject: [PATCH 039/140] build(deps): bump the cargo group with 3 updates Bumps the cargo group with 3 updates: [cc](https://github.com/rust-lang/cc-rs), [libloading](https://github.com/nagisa/rust_libloading) and [schemars](https://github.com/GREsau/schemars). Updates `cc` from 1.2.44 to 1.2.45 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.44...cc-v1.2.45) Updates `libloading` from 0.8.9 to 0.9.0 - [Commits](https://github.com/nagisa/rust_libloading/compare/0.8.9...0.9.0) Updates `schemars` from 1.0.4 to 1.0.5 - [Release notes](https://github.com/GREsau/schemars/releases) - [Changelog](https://github.com/GREsau/schemars/blob/master/CHANGELOG.md) - [Commits](https://github.com/GREsau/schemars/compare/v1.0.4...v1.0.5) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.45 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: libloading dependency-version: 0.9.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo - dependency-name: schemars dependency-version: 1.0.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 26 ++++++++++++++++++-------- Cargo.toml | 6 +++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cf0a189..4021396a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.44" +version = "1.2.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" dependencies = [ "find-msvc-tools", "shlex", @@ -236,7 +236,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading", + "libloading 0.8.9", ] [[package]] @@ -1058,6 +1058,16 @@ dependencies = [ "windows-link", ] +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link", +] + [[package]] name = "libm" version = "0.2.15" @@ -1621,9 +1631,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" dependencies = [ "dyn-clone", "ref-cast", @@ -1634,9 +1644,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80" +checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" dependencies = [ "proc-macro2", "quote", @@ -2079,7 +2089,7 @@ dependencies = [ "etcetera", "fs4", "indoc", - "libloading", + "libloading 0.9.0", "log", "once_cell", "regex", diff --git a/Cargo.toml b/Cargo.toml index 521ad684..5afc53b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.44" +cc = "1.2.45" clap = { version = "4.5.51", features = [ "cargo", "derive", @@ -128,7 +128,7 @@ heck = "0.5.0" html-escape = "0.2.13" indexmap = "2.11.4" indoc = "2.0.6" -libloading = "0.8.9" +libloading = "0.9.0" log = { version = "0.4.28", features = ["std"] } memchr = "2.7.6" once_cell = "1.21.3" @@ -137,7 +137,7 @@ rand = "0.8.5" regex = "1.11.3" regex-syntax = "0.8.6" rustc-hash = "2.1.1" -schemars = "1.0.4" +schemars = "1.0.5" semver = { version = "1.0.27", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } serde_json = { version = "1.0.145", features = ["preserve_order"] } From 7657cc9d356e922790e0cb9648f3d3dc8880761c Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Wed, 12 Nov 2025 00:02:44 -0500 Subject: [PATCH 040/140] fix(dsl): add `ReservedRule` to `Rule` type definition --- crates/cli/npm/dsl.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/cli/npm/dsl.d.ts b/crates/cli/npm/dsl.d.ts index 3ad9ea2a..accdb95f 100644 --- a/crates/cli/npm/dsl.d.ts +++ b/crates/cli/npm/dsl.d.ts @@ -29,6 +29,7 @@ type Rule = | PrecRule | Repeat1Rule | RepeatRule + | ReservedRule | SeqRule | StringRule | SymbolRule From 12a31536e1f8d1afdd2add375139cb31ac0e1c1a Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Wed, 12 Nov 2025 15:55:28 +0100 Subject: [PATCH 041/140] fix(docs): don't show mdbook help popup when using query editor --- docs/src/assets/js/playground.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/assets/js/playground.js b/docs/src/assets/js/playground.js index 595fe565..2b4b5708 100644 --- a/docs/src/assets/js/playground.js +++ b/docs/src/assets/js/playground.js @@ -146,8 +146,9 @@ window.initializePlayground = async (opts) => { }); queryEditor.on('keydown', (_, event) => { - if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') { - event.stopPropagation(); // Prevent mdBook from going back/forward + const key = event.key; + if (key === 'ArrowLeft' || key === 'ArrowRight' || key === '?') { + event.stopPropagation(); // Prevent mdBook from going back/forward, or showing help } }); From 67cb3cb88146dd9ce3a098e33ac0374b5ce1e22d Mon Sep 17 00:00:00 2001 From: WillLillis Date: Fri, 3 Oct 2025 22:32:50 -0400 Subject: [PATCH 042/140] refactor(loader)!: transition from anyhow to thiserror --- Cargo.lock | 2 +- crates/loader/Cargo.toml | 2 +- crates/loader/src/loader.rs | 714 +++++++++++++++++++++++------------- 3 files changed, 471 insertions(+), 247 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4021396a..90c00db3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2084,7 +2084,6 @@ version = "0.1.5" name = "tree-sitter-loader" version = "0.26.0" dependencies = [ - "anyhow", "cc", "etcetera", "fs4", @@ -2097,6 +2096,7 @@ dependencies = [ "serde", "serde_json", "tempfile", + "thiserror 2.0.16", "tree-sitter", "tree-sitter-highlight", "tree-sitter-tags", diff --git a/crates/loader/Cargo.toml b/crates/loader/Cargo.toml index ba6aa0f4..cecae218 100644 --- a/crates/loader/Cargo.toml +++ b/crates/loader/Cargo.toml @@ -28,7 +28,6 @@ wasm = ["tree-sitter/wasm"] default = ["tree-sitter-highlight", "tree-sitter-tags"] [dependencies] -anyhow.workspace = true cc.workspace = true etcetera.workspace = true fs4.workspace = true @@ -41,6 +40,7 @@ semver.workspace = true serde.workspace = true serde_json.workspace = true tempfile.workspace = true +thiserror.workspace = true tree-sitter = { workspace = true } tree-sitter-highlight = { workspace = true, optional = true } diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 39099797..08d6af84 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -14,11 +14,9 @@ use std::{ path::{Path, PathBuf}, process::Command, sync::LazyLock, - time::SystemTime, + time::{SystemTime, SystemTimeError}, }; -use anyhow::Error; -use anyhow::{anyhow, Context, Result}; use etcetera::BaseStrategy as _; use fs4::fs_std::FileExt; use libloading::{Library, Symbol}; @@ -27,11 +25,14 @@ use once_cell::unsync::OnceCell; use regex::{Regex, RegexBuilder}; use semver::Version; use serde::{Deserialize, Deserializer, Serialize}; +use thiserror::Error; use tree_sitter::Language; #[cfg(any(feature = "tree-sitter-highlight", feature = "tree-sitter-tags"))] use tree_sitter::QueryError; #[cfg(feature = "tree-sitter-highlight")] use tree_sitter::QueryErrorKind; +#[cfg(feature = "wasm")] +use tree_sitter::WasmError; #[cfg(feature = "tree-sitter-highlight")] use tree_sitter_highlight::HighlightConfiguration; #[cfg(feature = "tree-sitter-tags")] @@ -40,6 +41,210 @@ use tree_sitter_tags::{Error as TagsError, TagsConfiguration}; static GRAMMAR_NAME_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""name":\s*"(.*?)""#).unwrap()); +pub type LoaderResult = Result; + +#[derive(Debug, Error)] +pub enum LoaderError { + #[error(transparent)] + Compiler(CompilerError), + #[error("Parser compilation failed.\nStdout: {0}\nStderr: {1}")] + Compilation(String, String), + #[error("Failed to execute curl for {0} -- {1}")] + Curl(String, std::io::Error), + #[error("Failed to load language in current directory:\n{0}")] + CurrentDirectoryLoad(Box), + #[error("External file path {0} is outside of parser directory {1}")] + ExternalFile(String, String), + #[error("Failed to extract archive {0} to {1}")] + Extraction(String, String), + #[error("Failed to load language for file name {0}:\n{1}")] + FileNameLoad(String, Box), + #[error("Failed to parse the language name from grammar.json at {0}")] + GrammarJSON(String), + #[error(transparent)] + HomeDir(#[from] etcetera::HomeDirError), + #[error(transparent)] + IO(IoError), + #[error(transparent)] + Library(LibraryError), + #[error("Failed to compare binary and source timestamps:\n{0}")] + ModifiedTime(Box), + #[error("No language found")] + NoLanguage, + #[error(transparent)] + Query(LoaderQueryError), + #[error(transparent)] + ScannerSymbols(ScannerSymbolError), + #[error("Failed to load language for scope '{0}':\n{1}")] + ScopeLoad(String, Box), + #[error(transparent)] + Serialization(#[from] serde_json::Error), + #[error(transparent)] + Symbol(SymbolError), + #[error(transparent)] + Tags(#[from] TagsError), + #[error("Failed to execute tar for {0} -- {1}")] + Tar(String, std::io::Error), + #[error(transparent)] + Time(#[from] SystemTimeError), + #[error("Unknown scope '{0}'")] + UnknownScope(String), + #[error("Failed to download wasi-sdk from {0}")] + WasiSDKDownload(String), + #[error(transparent)] + WasiSDKClang(#[from] WasiSDKClangError), + #[error("Unsupported platform for wasi-sdk")] + WasiSDKPlatform, + #[cfg(feature = "wasm")] + #[error(transparent)] + Wasm(#[from] WasmError), + #[error("Failed to run wasi-sdk clang -- {0}")] + WasmCompiler(std::io::Error), + #[error("wasi-sdk clang command failed: {0}")] + WasmCompilation(String), +} + +#[derive(Debug, Error)] +pub struct CompilerError { + pub error: std::io::Error, + pub command: Box, +} + +impl std::fmt::Display for CompilerError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Failed to execute the C compiler with the following command:\n{:?}\nError: {}", + *self.command, self.error + )?; + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct IoError { + pub error: std::io::Error, + pub path: Option, +} + +impl IoError { + fn new(error: std::io::Error, path: Option<&Path>) -> Self { + Self { + error, + path: path.map(|p| p.to_string_lossy().to_string()), + } + } +} + +impl std::fmt::Display for IoError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.error)?; + if let Some(ref path) = self.path { + write!(f, " ({path})")?; + } + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct LibraryError { + pub error: libloading::Error, + pub path: String, +} + +impl std::fmt::Display for LibraryError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Error opening dynamic library {} -- {}", + self.path, self.error + )?; + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct LoaderQueryError { + pub error: QueryError, + pub file: Option, +} + +impl std::fmt::Display for LoaderQueryError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(ref path) = self.file { + writeln!(f, "Error in query file {path}:")?; + } + write!(f, "{}", self.error)?; + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct SymbolError { + pub error: libloading::Error, + pub symbol_name: String, + pub path: String, +} + +impl std::fmt::Display for SymbolError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Failed to load symbol {} from {} -- {}", + self.symbol_name, self.path, self.error + )?; + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct ScannerSymbolError { + pub missing: Vec, +} + +impl std::fmt::Display for ScannerSymbolError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!( + f, + "Missing required functions in the external scanner, parsing won't work without these!\n" + )?; + for symbol in &self.missing { + writeln!(f, " `{symbol}`")?; + } + writeln!( + f, + "You can read more about this at https://tree-sitter.github.io/tree-sitter/creating-parsers/4-external-scanners\n" + )?; + Ok(()) + } +} + +#[derive(Debug, Error)] +pub struct WasiSDKClangError { + pub wasi_sdk_dir: String, + pub possible_executables: Vec<&'static str>, + download: bool, +} + +impl std::fmt::Display for WasiSDKClangError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.download { + write!( + f, + "Failed to find clang executable in downloaded wasi-sdk at '{}'.", + self.wasi_sdk_dir + )?; + } else { + write!(f, "TREE_SITTER_WASI_SDK_PATH is set to '{}', but no clang executable found in 'bin/' directory.", self.wasi_sdk_dir)?; + } + + let possible_exes = self.possible_executables.join(", "); + write!(f, " Looked for: {possible_exes}.")?; + + Ok(()) + } +} + #[derive(Default, Deserialize, Serialize)] pub struct Config { #[serde(default)] @@ -143,9 +348,10 @@ pub struct TreeSitterJSON { } impl TreeSitterJSON { - pub fn from_file(path: &Path) -> Result { - Ok(serde_json::from_str(&fs::read_to_string( - path.join("tree-sitter.json"), + pub fn from_file(path: &Path) -> LoaderResult { + let path = path.join("tree-sitter.json"); + Ok(serde_json::from_str(&fs::read_to_string(&path).map_err( + |e| LoaderError::IO(IoError::new(e, Some(path.as_path()))), )?)?) } @@ -432,7 +638,7 @@ impl<'a> CompileConfig<'a> { unsafe impl Sync for Loader {} impl Loader { - pub fn new() -> Result { + pub fn new() -> LoaderResult { let parser_lib_path = if let Ok(path) = env::var("TREE_SITTER_LIBDIR") { PathBuf::from(path) } else { @@ -441,7 +647,9 @@ impl Loader { .cache_dir() // `$HOME/Library/Caches/` .join("tree-sitter"); if legacy_apple_path.exists() && legacy_apple_path.is_dir() { - std::fs::remove_dir_all(legacy_apple_path)?; + std::fs::remove_dir_all(&legacy_apple_path).map_err(|e| { + LoaderError::IO(IoError::new(e, Some(legacy_apple_path.as_path()))) + })?; } } @@ -491,7 +699,7 @@ impl Loader { self.highlight_names.lock().unwrap().clone() } - pub fn find_all_languages(&mut self, config: &Config) -> Result<()> { + pub fn find_all_languages(&mut self, config: &Config) -> LoaderResult<()> { if config.parser_directories.is_empty() { warn!(concat!( "You have not configured any parser directories!\n", @@ -503,7 +711,7 @@ impl Loader { for parser_container_dir in &config.parser_directories { if let Ok(entries) = fs::read_dir(parser_container_dir) { for entry in entries { - let entry = entry?; + let entry = entry.map_err(|e| LoaderError::IO(IoError::new(e, None)))?; if let Some(parser_dir_name) = entry.file_name().to_str() { if parser_dir_name.starts_with("tree-sitter-") { self.find_language_configurations_at_path( @@ -519,7 +727,7 @@ impl Loader { Ok(()) } - pub fn languages_at_path(&mut self, path: &Path) -> Result> { + pub fn languages_at_path(&mut self, path: &Path) -> LoaderResult> { if let Ok(configurations) = self.find_language_configurations_at_path(path, true) { let mut language_ids = configurations .iter() @@ -530,7 +738,7 @@ impl Loader { language_ids .into_iter() .map(|(id, name)| Ok((self.language_for_id(id)?, name))) - .collect::>>() + .collect::>>() } else { Ok(Vec::new()) } @@ -547,7 +755,7 @@ impl Loader { pub fn language_configuration_for_scope( &self, scope: &str, - ) -> Result> { + ) -> LoaderResult> { for configuration in &self.language_configurations { if configuration.scope.as_ref().is_some_and(|s| s == scope) { let language = self.language_for_id(configuration.language_id)?; @@ -560,14 +768,19 @@ impl Loader { pub fn language_configuration_for_first_line_regex( &self, path: &Path, - ) -> Result> { + ) -> LoaderResult> { self.language_configuration_ids_by_first_line_regex .iter() .try_fold(None, |_, (regex, ids)| { if let Some(regex) = Self::regex(Some(regex)) { - let file = fs::File::open(path)?; + let file = fs::File::open(path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(path))))?; let reader = BufReader::new(file); - let first_line = reader.lines().next().transpose()?; + let first_line = reader + .lines() + .next() + .transpose() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(path))))?; if let Some(first_line) = first_line { if regex.is_match(&first_line) && !ids.is_empty() { let configuration = &self.language_configurations[ids[0]]; @@ -584,7 +797,7 @@ impl Loader { pub fn language_configuration_for_file_name( &self, path: &Path, - ) -> Result> { + ) -> LoaderResult> { // Find all the language configurations that match this file name // or a suffix of the file name. let configuration_ids = path @@ -611,8 +824,8 @@ impl Loader { // If multiple language configurations match, then determine which // one to use by applying the configurations' content regexes. else { - let file_contents = fs::read(path) - .with_context(|| format!("Failed to read path {}", path.display()))?; + let file_contents = + fs::read(path).map_err(|e| LoaderError::IO(IoError::new(e, Some(path))))?; let file_contents = String::from_utf8_lossy(&file_contents); let mut best_score = -2isize; let mut best_configuration_id = None; @@ -656,7 +869,7 @@ impl Loader { pub fn language_configuration_for_injection_string( &self, string: &str, - ) -> Result> { + ) -> LoaderResult> { let mut best_match_length = 0; let mut best_match_position = None; for (i, configuration) in self.language_configurations.iter().enumerate() { @@ -683,11 +896,11 @@ impl Loader { pub fn language_for_configuration( &self, configuration: &LanguageConfiguration, - ) -> Result { + ) -> LoaderResult { self.language_for_id(configuration.language_id) } - fn language_for_id(&self, id: usize) -> Result { + fn language_for_id(&self, id: usize) -> LoaderResult { let (path, language, externals) = &self.languages_by_id[id]; language .get_or_try_init(|| { @@ -706,20 +919,23 @@ impl Loader { grammar_path: &Path, output_path: PathBuf, flags: &[&str], - ) -> Result<()> { + ) -> LoaderResult<()> { let src_path = grammar_path.join("src"); let mut config = CompileConfig::new(&src_path, None, Some(output_path)); config.flags = flags; self.load_language_at_path(config).map(|_| ()) } - pub fn load_language_at_path(&self, mut config: CompileConfig) -> Result { + pub fn load_language_at_path(&self, mut config: CompileConfig) -> LoaderResult { let grammar_path = config.src_path.join("grammar.json"); config.name = Self::grammar_json_name(&grammar_path)?; self.load_language_at_path_with_name(config) } - pub fn load_language_at_path_with_name(&self, mut config: CompileConfig) -> Result { + pub fn load_language_at_path_with_name( + &self, + mut config: CompileConfig, + ) -> LoaderResult { let mut lib_name = config.name.clone(); let language_fn_name = format!("tree_sitter_{}", config.name.replace('-', "_")); if self.debug_build { @@ -732,7 +948,9 @@ impl Loader { } if config.output_path.is_none() { - fs::create_dir_all(&self.parser_lib_path)?; + fs::create_dir_all(&self.parser_lib_path).map_err(|e| { + LoaderError::IO(IoError::new(e, Some(self.parser_lib_path.as_path()))) + })?; } let mut recompile = self.force_rebuild || config.output_path.is_some(); // if specified, always recompile @@ -766,8 +984,7 @@ impl Loader { ); if !recompile { - recompile = needs_recompile(&output_path, &paths_to_check) - .with_context(|| "Failed to compare source and binary timestamps")?; + recompile = needs_recompile(&output_path, &paths_to_check)?; } #[cfg(feature = "wasm")] @@ -784,7 +1001,8 @@ impl Loader { )?; } - let wasm_bytes = fs::read(&output_path)?; + let wasm_bytes = fs::read(&output_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(output_path.as_path()))))?; return Ok(wasm_store.load_language(&config.name, &wasm_bytes)?); } @@ -808,33 +1026,42 @@ impl Loader { if lock_file.try_lock_exclusive().is_err() { // if we can't acquire the lock, another process is compiling the parser, wait for // it and don't recompile - lock_file.lock_exclusive()?; + lock_file + .lock_exclusive() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))?; recompile = false; } else { // if we can acquire the lock, check if the lock file is older than 30 seconds, a // run that was interrupted and left the lock file behind should not block // subsequent runs - let time = lock_file.metadata()?.modified()?.elapsed()?.as_secs(); + let time = lock_file + .metadata() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))? + .modified() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))? + .elapsed()? + .as_secs(); if time > 30 { - fs::remove_file(&lock_path)?; + fs::remove_file(&lock_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))?; recompile = true; } } } if recompile { - fs::create_dir_all(lock_path.parent().unwrap()).with_context(|| { - format!( - "Failed to create directory {}", - lock_path.parent().unwrap().display() - ) - })?; + let parent_path = lock_path.parent().unwrap(); + fs::create_dir_all(parent_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(parent_path))))?; let lock_file = fs::OpenOptions::new() .create(true) .truncate(true) .write(true) - .open(&lock_path)?; - lock_file.lock_exclusive()?; + .open(&lock_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))?; + lock_file + .lock_exclusive() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path.as_path()))))?; self.compile_parser_to_dylib(&config, &lock_file, &lock_path)?; @@ -846,17 +1073,22 @@ impl Loader { Self::load_language(&output_path, &language_fn_name) } - pub fn load_language(path: &Path, function_name: &str) -> Result { - let library = unsafe { Library::new(path) } - .with_context(|| format!("Error opening dynamic library {}", path.display()))?; + pub fn load_language(path: &Path, function_name: &str) -> LoaderResult { + let library = unsafe { Library::new(path) }.map_err(|e| { + LoaderError::Library(LibraryError { + error: e, + path: path.to_string_lossy().to_string(), + }) + })?; let language = unsafe { let language_fn = library .get:: Language>>(function_name.as_bytes()) - .with_context(|| { - format!( - "Failed to load symbol {function_name} from {}", - path.display() - ) + .map_err(|e| { + LoaderError::Symbol(SymbolError { + error: e, + symbol_name: function_name.to_string(), + path: path.to_string_lossy().to_string(), + }) })?; language_fn() }; @@ -869,7 +1101,7 @@ impl Loader { config: &CompileConfig, lock_file: &fs::File, lock_path: &Path, - ) -> Result<(), Error> { + ) -> LoaderResult<()> { let mut cc_config = cc::Build::new(); cc_config .cargo_metadata(false) @@ -940,30 +1172,34 @@ impl Loader { None }; - let output = command.output().with_context(|| { - format!("Failed to execute the C compiler with the following command:\n{command:?}") + let output = command.output().map_err(|e| { + LoaderError::Compiler(CompilerError { + error: e, + command: Box::new(command), + }) })?; if let Some(temp_dir) = temp_dir { let _ = fs::remove_dir_all(temp_dir); } - FileExt::unlock(lock_file)?; - fs::remove_file(lock_path)?; + FileExt::unlock(lock_file) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path))))?; + fs::remove_file(lock_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(lock_path))))?; if output.status.success() { Ok(()) } else { - Err(anyhow!( - "Parser compilation failed.\nStdout: {}\nStderr: {}", - String::from_utf8_lossy(&output.stdout), - String::from_utf8_lossy(&output.stderr) + Err(LoaderError::Compilation( + String::from_utf8_lossy(&output.stdout).to_string(), + String::from_utf8_lossy(&output.stderr).to_string(), )) } } #[cfg(unix)] - fn check_external_scanner(&self, name: &str, library_path: &Path) -> Result<()> { + fn check_external_scanner(&self, name: &str, library_path: &Path) -> LoaderResult<()> { let prefix = if cfg!(any(target_os = "macos", target_os = "ios")) { "_" } else { @@ -1015,22 +1251,9 @@ impl Loader { } if !must_have.is_empty() { - let missing = must_have - .iter() - .map(|f| format!(" `{f}`")) - .collect::>() - .join("\n"); - - return Err(anyhow!(format!( - indoc::indoc! {" - Missing required functions in the external scanner, parsing won't work without these! - - {} - - You can read more about this at https://tree-sitter.github.io/tree-sitter/creating-parsers/4-external-scanners - "}, - missing, - ))); + return Err(LoaderError::ScannerSymbols(ScannerSymbolError { + missing: must_have, + })); } } } @@ -1039,7 +1262,7 @@ impl Loader { } #[cfg(windows)] - fn check_external_scanner(&self, _name: &str, _library_path: &Path) -> Result<()> { + fn check_external_scanner(&self, _name: &str, _library_path: &Path) -> LoaderResult<()> { // TODO: there's no nm command on windows, whoever wants to implement this can and should :) // let mut must_have = vec![ @@ -1059,7 +1282,7 @@ impl Loader { src_path: &Path, scanner_filename: Option<&Path>, output_path: &Path, - ) -> Result<(), Error> { + ) -> LoaderResult<()> { let clang_executable = self.ensure_wasi_sdk_exists()?; let output_name = "output.wasm"; @@ -1085,17 +1308,17 @@ impl Loader { command.arg(scanner_filename); } - let output = command.output().context("Failed to run wasi-sdk clang")?; + let output = command.output().map_err(LoaderError::WasmCompiler)?; if !output.status.success() { - return Err(anyhow!( - "wasi-sdk clang command failed: {}", - String::from_utf8_lossy(&output.stderr) + return Err(LoaderError::WasmCompilation( + String::from_utf8_lossy(&output.stderr).to_string(), )); } - fs::rename(src_path.join(output_name), output_path) - .context("failed to rename Wasm output file")?; + let current_path = src_path.join(output_name); + fs::rename(¤t_path, output_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(current_path.as_path()))))?; Ok(()) } @@ -1105,7 +1328,7 @@ impl Loader { &self, archive_path: &Path, destination: &Path, - ) -> Result<(), Error> { + ) -> LoaderResult<()> { let status = Command::new("tar") .arg("-xzf") .arg(archive_path) @@ -1113,13 +1336,12 @@ impl Loader { .arg("-C") .arg(destination) .status() - .with_context(|| format!("Failed to execute tar for {}", archive_path.display()))?; + .map_err(|e| LoaderError::Tar(archive_path.to_string_lossy().to_string(), e))?; if !status.success() { - return Err(anyhow!( - "Failed to extract archive {} to {}", - archive_path.display(), - destination.display() + return Err(LoaderError::Extraction( + archive_path.to_string_lossy().to_string(), + destination.to_string_lossy().to_string(), )); } @@ -1130,7 +1352,7 @@ impl Loader { /// and returns the path to the `clang` executable. /// /// If `TREE_SITTER_WASI_SDK_PATH` is set, it will use that path to look for the clang executable. - fn ensure_wasi_sdk_exists(&self) -> Result { + fn ensure_wasi_sdk_exists(&self) -> LoaderResult { let possible_executables = if cfg!(windows) { vec![ "clang.exe", @@ -1151,18 +1373,18 @@ impl Loader { } } - return Err(anyhow!( - "TREE_SITTER_WASI_SDK_PATH is set to '{}', but no clang executable found in 'bin/' directory. \ - Looked for: {}", - wasi_sdk_dir.display(), - possible_executables.join(", ") - )); + return Err(LoaderError::WasiSDKClang(WasiSDKClangError { + wasi_sdk_dir: wasi_sdk_dir.to_string_lossy().to_string(), + possible_executables, + download: false, + })); } let cache_dir = etcetera::choose_base_strategy()? .cache_dir() .join("tree-sitter"); - fs::create_dir_all(&cache_dir)?; + fs::create_dir_all(&cache_dir) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(cache_dir.as_path()))))?; let wasi_sdk_dir = cache_dir.join("wasi-sdk"); @@ -1173,7 +1395,8 @@ impl Loader { } } - fs::create_dir_all(&wasi_sdk_dir)?; + fs::create_dir_all(&wasi_sdk_dir) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(wasi_sdk_dir.as_path()))))?; let arch_os = if cfg!(target_os = "macos") { if cfg!(target_arch = "aarch64") { @@ -1194,7 +1417,7 @@ impl Loader { "x86_64-linux" } } else { - return Err(anyhow!("Unsupported platform for wasi-sdk")); + return Err(LoaderError::WasiSDKPlatform); }; let sdk_filename = format!("wasi-sdk-25.0-{arch_os}.tar.gz"); @@ -1212,15 +1435,14 @@ impl Loader { .arg(&temp_tar_path) .arg(&sdk_url) .status() - .with_context(|| format!("Failed to execute curl for {sdk_url}"))?; + .map_err(|e| LoaderError::Curl(sdk_url.clone(), e))?; if !status.success() { - return Err(anyhow!("Failed to download wasi-sdk from {sdk_url}",)); + return Err(LoaderError::WasiSDKDownload(sdk_url)); } info!("Extracting wasi-sdk to {}...", wasi_sdk_dir.display()); - self.extract_tar_gz_with_strip(&temp_tar_path, &wasi_sdk_dir) - .context("Failed to extract wasi-sdk archive")?; + self.extract_tar_gz_with_strip(&temp_tar_path, &wasi_sdk_dir)?; fs::remove_file(temp_tar_path).ok(); for exe in &possible_executables { @@ -1230,11 +1452,11 @@ impl Loader { } } - Err(anyhow!( - "Failed to find clang executable in downloaded wasi-sdk at '{}'. Looked for: {}", - wasi_sdk_dir.display(), - possible_executables.join(", ") - )) + Err(LoaderError::WasiSDKClang(WasiSDKClangError { + wasi_sdk_dir: wasi_sdk_dir.to_string_lossy().to_string(), + possible_executables, + download: true, + })) } #[must_use] @@ -1274,115 +1496,121 @@ impl Loader { &mut self, parser_path: &Path, set_current_path_config: bool, - ) -> Result<&[LanguageConfiguration]> { + ) -> LoaderResult<&[LanguageConfiguration]> { let initial_language_configuration_count = self.language_configurations.len(); - let ts_json = TreeSitterJSON::from_file(parser_path); - if let Ok(config) = ts_json { - let language_count = self.languages_by_id.len(); - for grammar in config.grammars { - // Determine the path to the parser directory. This can be specified in - // the tree-sitter.json, but defaults to the directory containing the - // tree-sitter.json. - let language_path = parser_path.join(grammar.path.unwrap_or(PathBuf::from("."))); + match TreeSitterJSON::from_file(parser_path) { + Ok(config) => { + let language_count = self.languages_by_id.len(); + for grammar in config.grammars { + // Determine the path to the parser directory. This can be specified in + // the tree-sitter.json, but defaults to the directory containing the + // tree-sitter.json. + let language_path = + parser_path.join(grammar.path.unwrap_or(PathBuf::from("."))); - // Determine if a previous language configuration in this package.json file - // already uses the same language. - let mut language_id = None; - for (id, (path, _, _)) in - self.languages_by_id.iter().enumerate().skip(language_count) - { - if language_path == *path { - language_id = Some(id); + // Determine if a previous language configuration in this package.json file + // already uses the same language. + let mut language_id = None; + for (id, (path, _, _)) in + self.languages_by_id.iter().enumerate().skip(language_count) + { + if language_path == *path { + language_id = Some(id); + } } - } - // If not, add a new language path to the list. - let language_id = if let Some(language_id) = language_id { - language_id - } else { - self.languages_by_id.push(( + // If not, add a new language path to the list. + let language_id = if let Some(language_id) = language_id { + language_id + } else { + self.languages_by_id.push(( language_path, OnceCell::new(), - grammar.external_files.clone().into_vec().map(|files| { - files.into_iter() - .map(|path| { - let path = parser_path.join(path); - // prevent p being above/outside of parser_path - if path.starts_with(parser_path) { - Ok(path) - } else { - Err(anyhow!( - "External file path {} is outside of parser directory {}", path.display(), parser_path.display(), - )) - } - }) - .collect::>>() - }).transpose()?, + grammar + .external_files + .clone() + .into_vec() + .map(|files| { + files + .into_iter() + .map(|path| { + let path = parser_path.join(path); + // prevent p being above/outside of parser_path + if path.starts_with(parser_path) { + Ok(path) + } else { + Err(LoaderError::ExternalFile( + path.to_string_lossy().to_string(), + parser_path.to_string_lossy().to_string(), + )) + } + }) + .collect::>>() + }) + .transpose()?, )); - self.languages_by_id.len() - 1 - }; + self.languages_by_id.len() - 1 + }; - let configuration = LanguageConfiguration { - root_path: parser_path.to_path_buf(), - language_name: grammar.name, - scope: Some(grammar.scope), - language_id, - file_types: grammar.file_types.unwrap_or_default(), - content_regex: Self::regex(grammar.content_regex.as_deref()), - first_line_regex: Self::regex(grammar.first_line_regex.as_deref()), - injection_regex: Self::regex(grammar.injection_regex.as_deref()), - injections_filenames: grammar.injections.into_vec(), - locals_filenames: grammar.locals.into_vec(), - tags_filenames: grammar.tags.into_vec(), - highlights_filenames: grammar.highlights.into_vec(), - #[cfg(feature = "tree-sitter-highlight")] - highlight_config: OnceCell::new(), - #[cfg(feature = "tree-sitter-tags")] - tags_config: OnceCell::new(), - #[cfg(feature = "tree-sitter-highlight")] - highlight_names: &self.highlight_names, - #[cfg(feature = "tree-sitter-highlight")] - use_all_highlight_names: self.use_all_highlight_names, - _phantom: PhantomData, - }; + let configuration = LanguageConfiguration { + root_path: parser_path.to_path_buf(), + language_name: grammar.name, + scope: Some(grammar.scope), + language_id, + file_types: grammar.file_types.unwrap_or_default(), + content_regex: Self::regex(grammar.content_regex.as_deref()), + first_line_regex: Self::regex(grammar.first_line_regex.as_deref()), + injection_regex: Self::regex(grammar.injection_regex.as_deref()), + injections_filenames: grammar.injections.into_vec(), + locals_filenames: grammar.locals.into_vec(), + tags_filenames: grammar.tags.into_vec(), + highlights_filenames: grammar.highlights.into_vec(), + #[cfg(feature = "tree-sitter-highlight")] + highlight_config: OnceCell::new(), + #[cfg(feature = "tree-sitter-tags")] + tags_config: OnceCell::new(), + #[cfg(feature = "tree-sitter-highlight")] + highlight_names: &self.highlight_names, + #[cfg(feature = "tree-sitter-highlight")] + use_all_highlight_names: self.use_all_highlight_names, + _phantom: PhantomData, + }; - for file_type in &configuration.file_types { - self.language_configuration_ids_by_file_type - .entry(file_type.clone()) - .or_default() - .push(self.language_configurations.len()); - } - if let Some(first_line_regex) = &configuration.first_line_regex { - self.language_configuration_ids_by_first_line_regex - .entry(first_line_regex.to_string()) - .or_default() - .push(self.language_configurations.len()); - } + for file_type in &configuration.file_types { + self.language_configuration_ids_by_file_type + .entry(file_type.clone()) + .or_default() + .push(self.language_configurations.len()); + } + if let Some(first_line_regex) = &configuration.first_line_regex { + self.language_configuration_ids_by_first_line_regex + .entry(first_line_regex.to_string()) + .or_default() + .push(self.language_configurations.len()); + } - self.language_configurations.push(unsafe { - mem::transmute::, LanguageConfiguration<'static>>( - configuration, - ) - }); + self.language_configurations.push(unsafe { + mem::transmute::, LanguageConfiguration<'static>>( + configuration, + ) + }); - if set_current_path_config && self.language_configuration_in_current_path.is_none() - { - self.language_configuration_in_current_path = - Some(self.language_configurations.len() - 1); + if set_current_path_config + && self.language_configuration_in_current_path.is_none() + { + self.language_configuration_in_current_path = + Some(self.language_configurations.len() - 1); + } } } - } else if let Err(e) = ts_json { - match e.downcast_ref::() { - // This is noisy, and not really an issue. - Some(e) if e.kind() == std::io::ErrorKind::NotFound => {} - _ => { - warn!( - "Failed to parse {} -- {e}", - parser_path.join("tree-sitter.json").display() - ); - } + Err(LoaderError::Serialization(e)) => { + warn!( + "Failed to parse {} -- {e}", + parser_path.join("tree-sitter.json").display() + ); } + _ => {} } // If we didn't find any language configurations in the tree-sitter.json file, @@ -1432,32 +1660,21 @@ impl Loader { pattern.and_then(|r| RegexBuilder::new(r).multi_line(true).build().ok()) } - fn grammar_json_name(grammar_path: &Path) -> Result { - let file = fs::File::open(grammar_path).with_context(|| { - format!("Failed to open grammar.json at {}", grammar_path.display()) - })?; + fn grammar_json_name(grammar_path: &Path) -> LoaderResult { + let file = fs::File::open(grammar_path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(grammar_path))))?; let first_three_lines = BufReader::new(file) .lines() .take(3) - .collect::, _>>() - .with_context(|| { - format!( - "Failed to read the first three lines of grammar.json at {}", - grammar_path.display() - ) - })? + .collect::, std::io::Error>>() + .map_err(|_| LoaderError::GrammarJSON(grammar_path.to_string_lossy().to_string()))? .join("\n"); let name = GRAMMAR_NAME_REGEX .captures(&first_three_lines) .and_then(|c| c.get(1)) - .ok_or_else(|| { - anyhow!( - "Failed to parse the language name from grammar.json at {}", - grammar_path.display() - ) - })?; + .ok_or_else(|| LoaderError::GrammarJSON(grammar_path.to_string_lossy().to_string()))?; Ok(name.as_str().to_string()) } @@ -1469,34 +1686,34 @@ impl Loader { scope: Option<&str>, // path to dynamic library, name of language lib_info: Option<&(PathBuf, &str)>, - ) -> Result { + ) -> LoaderResult { if let Some((ref lib_path, language_name)) = lib_info { let language_fn_name = format!("tree_sitter_{}", language_name.replace('-', "_")); Self::load_language(lib_path, &language_fn_name) } else if let Some(scope) = scope { if let Some(config) = self .language_configuration_for_scope(scope) - .with_context(|| format!("Failed to load language for scope '{scope}'"))? + .map_err(|e| LoaderError::ScopeLoad(scope.to_string(), Box::new(e)))? { Ok(config.0) } else { - Err(anyhow!("Unknown scope '{scope}'")) + Err(LoaderError::UnknownScope(scope.to_string())) } - } else if let Some((lang, _)) = self - .language_configuration_for_file_name(path) - .with_context(|| { - format!( - "Failed to load language for file name {}", - path.file_name().unwrap().to_string_lossy() - ) - })? + } else if let Some((lang, _)) = + self.language_configuration_for_file_name(path) + .map_err(|e| { + LoaderError::FileNameLoad( + path.file_name().unwrap().to_string_lossy().to_string(), + Box::new(e), + ) + })? { Ok(lang) } else if let Some(id) = self.language_configuration_in_current_path { Ok(self.language_for_id(self.language_configurations[id].language_id)?) } else if let Some(lang) = self .languages_at_path(current_dir) - .with_context(|| "Failed to load language in current directory")? + .map_err(|e| LoaderError::CurrentDirectoryLoad(Box::new(e)))? .first() .cloned() { @@ -1504,7 +1721,7 @@ impl Loader { } else if let Some(lang) = self.language_configuration_for_first_line_regex(path)? { Ok(lang.0) } else { - Err(anyhow!("No language found")) + Err(LoaderError::NoLanguage) } } @@ -1539,7 +1756,7 @@ impl LanguageConfiguration<'_> { &self, language: Language, paths: Option<&[PathBuf]>, - ) -> Result> { + ) -> LoaderResult> { let (highlights_filenames, injections_filenames, locals_filenames) = match paths { Some(paths) => ( Some( @@ -1604,7 +1821,9 @@ impl LanguageConfiguration<'_> { &locals_query, ) .map_err(|error| match error.kind { - QueryErrorKind::Language => Error::from(error), + QueryErrorKind::Language => { + LoaderError::Query(LoaderQueryError { error, file: None }) + } _ => { if error.offset < injections_query.len() { Self::include_path_in_query_error( @@ -1647,7 +1866,7 @@ impl LanguageConfiguration<'_> { } #[cfg(feature = "tree-sitter-tags")] - pub fn tags_config(&self, language: Language) -> Result> { + pub fn tags_config(&self, language: Language) -> LoaderResult> { self.tags_config .get_or_try_init(|| { let (tags_query, tags_ranges) = @@ -1691,7 +1910,7 @@ impl LanguageConfiguration<'_> { ranges: &[(PathBuf, Range)], source: &str, start_offset: usize, - ) -> Error { + ) -> LoaderError { let offset_within_section = error.offset - start_offset; let (path, range) = ranges .iter() @@ -1701,7 +1920,10 @@ impl LanguageConfiguration<'_> { error.row = source[range.start..offset_within_section] .matches('\n') .count(); - Error::from(error).context(format!("Error in query file {}", path.display())) + LoaderError::Query(LoaderQueryError { + error, + file: Some(path.to_string_lossy().to_string()), + }) } #[allow(clippy::type_complexity)] @@ -1710,7 +1932,7 @@ impl LanguageConfiguration<'_> { &self, paths: Option<&[PathBuf]>, default_path: &str, - ) -> Result<(String, Vec<(PathBuf, Range)>)> { + ) -> LoaderResult<(String, Vec<(PathBuf, Range)>)> { let mut query = String::new(); let mut path_ranges = Vec::new(); if let Some(paths) = paths { @@ -1718,7 +1940,7 @@ impl LanguageConfiguration<'_> { let abs_path = self.root_path.join(path); let prev_query_len = query.len(); query += &fs::read_to_string(&abs_path) - .with_context(|| format!("Failed to read query file {}", path.display()))?; + .map_err(|e| LoaderError::IO(IoError::new(e, Some(abs_path.as_path()))))?; path_ranges.push((path.clone(), prev_query_len..query.len())); } } else { @@ -1738,7 +1960,7 @@ impl LanguageConfiguration<'_> { let path = queries_path.join(default_path); if path.exists() { query = fs::read_to_string(&path) - .with_context(|| format!("Failed to read query file {}", path.display()))?; + .map_err(|e| LoaderError::IO(IoError::new(e, Some(path.as_path()))))?; path_ranges.push((PathBuf::from(default_path), 0..query.len())); } } @@ -1747,20 +1969,22 @@ impl LanguageConfiguration<'_> { } } -fn needs_recompile(lib_path: &Path, paths_to_check: &[PathBuf]) -> Result { +fn needs_recompile(lib_path: &Path, paths_to_check: &[PathBuf]) -> LoaderResult { if !lib_path.exists() { return Ok(true); } - let lib_mtime = mtime(lib_path) - .with_context(|| format!("Failed to read mtime of {}", lib_path.display()))?; + let lib_mtime = mtime(lib_path).map_err(|e| LoaderError::ModifiedTime(Box::new(e)))?; for path in paths_to_check { - if mtime(path)? > lib_mtime { + if mtime(path).map_err(|e| LoaderError::ModifiedTime(Box::new(e)))? > lib_mtime { return Ok(true); } } Ok(false) } -fn mtime(path: &Path) -> Result { - Ok(fs::metadata(path)?.modified()?) +fn mtime(path: &Path) -> LoaderResult { + fs::metadata(path) + .map_err(|e| LoaderError::IO(IoError::new(e, Some(path))))? + .modified() + .map_err(|e| LoaderError::IO(IoError::new(e, Some(path)))) } From db2d221ae9d5521e1e6527f3426d8d15b091fd9d Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 4 Oct 2025 00:48:35 -0400 Subject: [PATCH 043/140] fix(generate): remove leftover imports of anyhow --- Cargo.lock | 1 - crates/generate/Cargo.toml | 1 - crates/generate/src/generate.rs | 1 - crates/generate/src/node_types.rs | 1 - crates/generate/src/parse_grammar.rs | 1 - crates/generate/src/prepare_grammar.rs | 1 - crates/generate/src/prepare_grammar/expand_tokens.rs | 1 - crates/generate/src/prepare_grammar/extract_tokens.rs | 1 - crates/generate/src/prepare_grammar/flatten_grammar.rs | 1 - crates/generate/src/prepare_grammar/intern_symbols.rs | 1 - crates/generate/src/prepare_grammar/process_inlines.rs | 1 - 11 files changed, 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90c00db3..1297ecd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2046,7 +2046,6 @@ dependencies = [ name = "tree-sitter-generate" version = "0.26.0" dependencies = [ - "anyhow", "bitflags 2.10.0", "dunce", "indexmap", diff --git a/crates/generate/Cargo.toml b/crates/generate/Cargo.toml index 09fc1850..5e93bf40 100644 --- a/crates/generate/Cargo.toml +++ b/crates/generate/Cargo.toml @@ -25,7 +25,6 @@ load = ["dep:semver"] qjs-rt = ["load", "rquickjs", "pathdiff"] [dependencies] -anyhow.workspace = true bitflags = "2.9.4" dunce = "1.0.5" indexmap.workspace = true diff --git a/crates/generate/src/generate.rs b/crates/generate/src/generate.rs index c4a1ec84..612a5fa8 100644 --- a/crates/generate/src/generate.rs +++ b/crates/generate/src/generate.rs @@ -7,7 +7,6 @@ use std::{ process::{Command, Stdio}, }; -use anyhow::Result; use bitflags::bitflags; use log::warn; use node_types::VariableInfo; diff --git a/crates/generate/src/node_types.rs b/crates/generate/src/node_types.rs index 0a964105..2dde0c49 100644 --- a/crates/generate/src/node_types.rs +++ b/crates/generate/src/node_types.rs @@ -1,6 +1,5 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; -use anyhow::Result; use serde::Serialize; use thiserror::Error; diff --git a/crates/generate/src/parse_grammar.rs b/crates/generate/src/parse_grammar.rs index c48477f0..de8f0a97 100644 --- a/crates/generate/src/parse_grammar.rs +++ b/crates/generate/src/parse_grammar.rs @@ -1,6 +1,5 @@ use std::collections::HashSet; -use anyhow::Result; use log::warn; use regex::Regex; use serde::{Deserialize, Serialize}; diff --git a/crates/generate/src/prepare_grammar.rs b/crates/generate/src/prepare_grammar.rs index 8c35c741..58e0869c 100644 --- a/crates/generate/src/prepare_grammar.rs +++ b/crates/generate/src/prepare_grammar.rs @@ -12,7 +12,6 @@ use std::{ mem, }; -use anyhow::Result; pub use expand_tokens::ExpandTokensError; pub use extract_tokens::ExtractTokensError; pub use flatten_grammar::FlattenGrammarError; diff --git a/crates/generate/src/prepare_grammar/expand_tokens.rs b/crates/generate/src/prepare_grammar/expand_tokens.rs index 4d8b4f11..acfb9ba3 100644 --- a/crates/generate/src/prepare_grammar/expand_tokens.rs +++ b/crates/generate/src/prepare_grammar/expand_tokens.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use regex_syntax::{ hir::{Class, Hir, HirKind}, ParserBuilder, diff --git a/crates/generate/src/prepare_grammar/extract_tokens.rs b/crates/generate/src/prepare_grammar/extract_tokens.rs index a1fddbe6..a7b4f227 100644 --- a/crates/generate/src/prepare_grammar/extract_tokens.rs +++ b/crates/generate/src/prepare_grammar/extract_tokens.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use anyhow::Result; use serde::Serialize; use thiserror::Error; diff --git a/crates/generate/src/prepare_grammar/flatten_grammar.rs b/crates/generate/src/prepare_grammar/flatten_grammar.rs index cb0f1dae..3bec17bf 100644 --- a/crates/generate/src/prepare_grammar/flatten_grammar.rs +++ b/crates/generate/src/prepare_grammar/flatten_grammar.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use anyhow::Result; use serde::Serialize; use thiserror::Error; diff --git a/crates/generate/src/prepare_grammar/intern_symbols.rs b/crates/generate/src/prepare_grammar/intern_symbols.rs index 241e6e99..92f0f095 100644 --- a/crates/generate/src/prepare_grammar/intern_symbols.rs +++ b/crates/generate/src/prepare_grammar/intern_symbols.rs @@ -1,4 +1,3 @@ -use anyhow::Result; use log::warn; use serde::Serialize; use thiserror::Error; diff --git a/crates/generate/src/prepare_grammar/process_inlines.rs b/crates/generate/src/prepare_grammar/process_inlines.rs index f20e182d..d4b7dc18 100644 --- a/crates/generate/src/prepare_grammar/process_inlines.rs +++ b/crates/generate/src/prepare_grammar/process_inlines.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use anyhow::Result; use serde::Serialize; use thiserror::Error; From 7eb23d9f3cae0876dec541f06da633b066f583e7 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 4 Oct 2025 01:22:02 -0400 Subject: [PATCH 044/140] refactor(config)!: transition from anyhow to thiserror --- Cargo.lock | 2 +- crates/config/Cargo.toml | 2 +- crates/config/src/tree_sitter_config.rs | 79 ++++++++++++++++++++----- 3 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1297ecd3..726289b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2035,11 +2035,11 @@ dependencies = [ name = "tree-sitter-config" version = "0.26.0" dependencies = [ - "anyhow", "etcetera", "log", "serde", "serde_json", + "thiserror 2.0.16", ] [[package]] diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index b9bc239e..641b434b 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -20,8 +20,8 @@ path = "src/tree_sitter_config.rs" workspace = true [dependencies] -anyhow.workspace = true etcetera.workspace = true log.workspace = true serde.workspace = true serde_json.workspace = true +thiserror.workspace = true diff --git a/crates/config/src/tree_sitter_config.rs b/crates/config/src/tree_sitter_config.rs index 85dc003d..17b1d384 100644 --- a/crates/config/src/tree_sitter_config.rs +++ b/crates/config/src/tree_sitter_config.rs @@ -1,12 +1,54 @@ #![cfg_attr(not(any(test, doctest)), doc = include_str!("../README.md"))] -use std::{env, fs, path::PathBuf}; +use std::{ + env, fs, + path::{Path, PathBuf}, +}; -use anyhow::{Context, Result}; use etcetera::BaseStrategy as _; use log::warn; use serde::{Deserialize, Serialize}; use serde_json::Value; +use thiserror::Error; + +pub type ConfigResult = Result; + +#[derive(Debug, Error)] +pub enum ConfigError { + #[error("Bad JSON config {0} -- {1}")] + ConfigRead(String, serde_json::Error), + #[error(transparent)] + HomeDir(#[from] etcetera::HomeDirError), + #[error(transparent)] + IO(IoError), + #[error(transparent)] + Serialization(#[from] serde_json::Error), +} + +#[derive(Debug, Error)] +pub struct IoError { + pub error: std::io::Error, + pub path: Option, +} + +impl IoError { + fn new(error: std::io::Error, path: Option<&Path>) -> Self { + Self { + error, + path: path.map(|p| p.to_string_lossy().to_string()), + } + } +} + +impl std::fmt::Display for IoError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.error)?; + if let Some(ref path) = self.path { + write!(f, " ({path})")?; + } + Ok(()) + } +} /// Holds the contents of tree-sitter's configuration file. /// @@ -23,7 +65,7 @@ pub struct Config { } impl Config { - pub fn find_config_file() -> Result> { + pub fn find_config_file() -> ConfigResult> { if let Ok(path) = env::var("TREE_SITTER_DIR") { let mut path = PathBuf::from(path); path.push("config.json"); @@ -46,8 +88,12 @@ impl Config { .join("tree-sitter") .join("config.json"); if legacy_apple_path.is_file() { - fs::create_dir_all(xdg_path.parent().unwrap())?; - fs::rename(&legacy_apple_path, &xdg_path)?; + let xdg_dir = xdg_path.parent().unwrap(); + fs::create_dir_all(xdg_dir) + .map_err(|e| ConfigError::IO(IoError::new(e, Some(xdg_dir))))?; + fs::rename(&legacy_apple_path, &xdg_path).map_err(|e| { + ConfigError::IO(IoError::new(e, Some(legacy_apple_path.as_path()))) + })?; warn!( "Your config.json file has been automatically migrated from \"{}\" to \"{}\"", legacy_apple_path.display(), @@ -67,7 +113,7 @@ impl Config { Ok(None) } - fn xdg_config_file() -> Result { + fn xdg_config_file() -> ConfigResult { let xdg_path = etcetera::choose_base_strategy()? .config_dir() .join("tree-sitter") @@ -84,7 +130,7 @@ impl Config { /// [`etcetera::choose_base_strategy`](https://docs.rs/etcetera/*/etcetera/#basestrategy) /// - `$HOME/.tree-sitter/config.json` as a fallback from where tree-sitter _used_ to store /// its configuration - pub fn load(path: Option) -> Result { + pub fn load(path: Option) -> ConfigResult { let location = if let Some(path) = path { path } else if let Some(path) = Self::find_config_file()? { @@ -94,9 +140,9 @@ impl Config { }; let content = fs::read_to_string(&location) - .with_context(|| format!("Failed to read {}", location.to_string_lossy()))?; + .map_err(|e| ConfigError::IO(IoError::new(e, Some(location.as_path()))))?; let config = serde_json::from_str(&content) - .with_context(|| format!("Bad JSON config {}", location.to_string_lossy()))?; + .map_err(|e| ConfigError::ConfigRead(location.to_string_lossy().to_string(), e))?; Ok(Self { location, config }) } @@ -106,7 +152,7 @@ impl Config { /// disk. /// /// (Note that this is typically only done by the `tree-sitter init-config` command.) - pub fn initial() -> Result { + pub fn initial() -> ConfigResult { let location = if let Ok(path) = env::var("TREE_SITTER_DIR") { let mut path = PathBuf::from(path); path.push("config.json"); @@ -119,17 +165,20 @@ impl Config { } /// Saves this configuration to the file that it was originally loaded from. - pub fn save(&self) -> Result<()> { + pub fn save(&self) -> ConfigResult<()> { let json = serde_json::to_string_pretty(&self.config)?; - fs::create_dir_all(self.location.parent().unwrap())?; - fs::write(&self.location, json)?; + let config_dir = self.location.parent().unwrap(); + fs::create_dir_all(config_dir) + .map_err(|e| ConfigError::IO(IoError::new(e, Some(config_dir))))?; + fs::write(&self.location, json) + .map_err(|e| ConfigError::IO(IoError::new(e, Some(self.location.as_path()))))?; Ok(()) } /// Parses a component-specific configuration from the configuration file. The type `C` must /// be [deserializable](https://docs.rs/serde/*/serde/trait.Deserialize.html) from a JSON /// object, and must only include the fields relevant to that component. - pub fn get(&self) -> Result + pub fn get(&self) -> ConfigResult where C: for<'de> Deserialize<'de>, { @@ -140,7 +189,7 @@ impl Config { /// Adds a component-specific configuration to the configuration file. The type `C` must be /// [serializable](https://docs.rs/serde/*/serde/trait.Serialize.html) into a JSON object, and /// must only include the fields relevant to that component. - pub fn add(&mut self, config: C) -> Result<()> + pub fn add(&mut self, config: C) -> ConfigResult<()> where C: Serialize, { From 61c21aa408710019fc81c14a9b213dd762d5c5bd Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 4 Oct 2025 03:21:20 -0400 Subject: [PATCH 045/140] refactor(generate)!: include path when available in IO errors --- crates/generate/src/generate.rs | 138 +++++++++++++++++++------------- crates/generate/src/quickjs.rs | 6 +- 2 files changed, 87 insertions(+), 57 deletions(-) diff --git a/crates/generate/src/generate.rs b/crates/generate/src/generate.rs index 612a5fa8..6a005637 100644 --- a/crates/generate/src/generate.rs +++ b/crates/generate/src/generate.rs @@ -80,8 +80,8 @@ pub type GenerateResult = Result; pub enum GenerateError { #[error("Error with specified path -- {0}")] GrammarPath(String), - #[error("{0}")] - IO(String), + #[error(transparent)] + IO(IoError), #[cfg(feature = "load")] #[error(transparent)] LoadGrammarFile(#[from] LoadGrammarError), @@ -100,9 +100,28 @@ pub enum GenerateError { SuperTypeCycle(#[from] SuperTypeCycleError), } -impl From for GenerateError { - fn from(value: std::io::Error) -> Self { - Self::IO(value.to_string()) +#[derive(Debug, Error, Serialize)] +pub struct IoError { + pub error: String, + pub path: Option, +} + +impl IoError { + fn new(error: &std::io::Error, path: Option<&Path>) -> Self { + Self { + error: error.to_string(), + path: path.map(|p| p.to_string_lossy().to_string()), + } + } +} + +impl std::fmt::Display for IoError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.error)?; + if let Some(ref path) = self.path { + write!(f, " ({path})")?; + } + Ok(()) } } @@ -117,18 +136,11 @@ pub enum LoadGrammarError { #[error("Failed to load grammar.js -- {0}")] LoadJSGrammarFile(#[from] JSError), #[error("Failed to load grammar.json -- {0}")] - IO(String), + IO(IoError), #[error("Unknown grammar file extension: {0:?}")] FileExtension(PathBuf), } -#[cfg(feature = "load")] -impl From for LoadGrammarError { - fn from(value: std::io::Error) -> Self { - Self::IO(value.to_string()) - } -} - #[cfg(feature = "load")] #[derive(Debug, Error, Serialize)] pub enum ParseVersionError { @@ -136,8 +148,8 @@ pub enum ParseVersionError { Version(String), #[error("{0}")] JSON(String), - #[error("{0}")] - IO(String), + #[error(transparent)] + IO(IoError), } #[cfg(feature = "load")] @@ -152,8 +164,21 @@ pub enum JSError { JSRuntimeUtf8 { runtime: String, error: String }, #[error("`{runtime}` process exited with status {code}")] JSRuntimeExit { runtime: String, code: i32 }, - #[error("{0}")] - IO(String), + #[error("Failed to open stdin for `{runtime}`")] + JSRuntimeStdin { runtime: String }, + #[error("Failed to write {item} to `{runtime}`'s stdin -- {error}")] + JSRuntimeWrite { + runtime: String, + item: String, + error: String, + }, + #[error("Failed to read output from `{runtime}` -- {error}")] + JSRuntimeRead { runtime: String, error: String }, + #[error(transparent)] + IO(IoError), + #[cfg(feature = "qjs-rt")] + #[error("Failed to get relative path")] + RelativePath, #[error("Could not parse this package's version as semver -- {0}")] Semver(String), #[error("Failed to serialze grammar JSON -- {0}")] @@ -163,13 +188,6 @@ pub enum JSError { QuickJS(String), } -#[cfg(feature = "load")] -impl From for JSError { - fn from(value: std::io::Error) -> Self { - Self::IO(value.to_string()) - } -} - #[cfg(feature = "load")] impl From for JSError { fn from(value: serde_json::Error) -> Self { @@ -230,7 +248,8 @@ where .try_exists() .map_err(|e| GenerateError::GrammarPath(e.to_string()))? { - fs::create_dir_all(&path_buf)?; + fs::create_dir_all(&path_buf) + .map_err(|e| GenerateError::IO(IoError::new(&e, Some(path_buf.as_path()))))?; repo_path = path_buf; repo_path.join("grammar.js") } else { @@ -247,15 +266,12 @@ where let header_path = src_path.join("tree_sitter"); // Ensure that the output directory exists - fs::create_dir_all(&src_path)?; + fs::create_dir_all(&src_path) + .map_err(|e| GenerateError::IO(IoError::new(&e, Some(src_path.as_path()))))?; if grammar_path.file_name().unwrap() != "grammar.json" { - fs::write(src_path.join("grammar.json"), &grammar_json).map_err(|e| { - GenerateError::IO(format!( - "Failed to write grammar.json to {} -- {e}", - src_path.display() - )) - })?; + fs::write(src_path.join("grammar.json"), &grammar_json) + .map_err(|e| GenerateError::IO(IoError::new(&e, Some(src_path.as_path()))))?; } // If our job is only to generate `grammar.json` and not `parser.c`, stop here. @@ -297,7 +313,8 @@ where write_file(&src_path.join("parser.c"), c_code)?; write_file(&src_path.join("node-types.json"), node_types_json)?; - fs::create_dir_all(&header_path)?; + fs::create_dir_all(&header_path) + .map_err(|e| GenerateError::IO(IoError::new(&e, Some(header_path.as_path()))))?; write_file(&header_path.join("alloc.h"), ALLOC_HEADER)?; write_file(&header_path.join("array.h"), ARRAY_HEADER)?; write_file(&header_path.join("parser.h"), PARSER_HEADER)?; @@ -413,9 +430,8 @@ fn read_grammar_version(repo_path: &Path) -> Result, ParseVersio let json = path .exists() .then(|| { - let contents = fs::read_to_string(path.as_path()).map_err(|e| { - ParseVersionError::IO(format!("Failed to read `{}` -- {e}", path.display())) - })?; + let contents = fs::read_to_string(path.as_path()) + .map_err(|e| ParseVersionError::IO(IoError::new(&e, Some(path.as_path()))))?; serde_json::from_str::(&contents).map_err(|e| { ParseVersionError::JSON(format!("Failed to parse `{}` -- {e}", path.display())) }) @@ -449,14 +465,16 @@ pub fn load_grammar_file( } match grammar_path.extension().and_then(|e| e.to_str()) { Some("js") => Ok(load_js_grammar_file(grammar_path, js_runtime)?), - Some("json") => Ok(fs::read_to_string(grammar_path)?), + Some("json") => Ok(fs::read_to_string(grammar_path) + .map_err(|e| LoadGrammarError::IO(IoError::new(&e, Some(grammar_path))))?), _ => Err(LoadGrammarError::FileExtension(grammar_path.to_owned()))?, } } #[cfg(feature = "load")] fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> JSResult { - let grammar_path = dunce::canonicalize(grammar_path)?; + let grammar_path = dunce::canonicalize(grammar_path) + .map_err(|e| JSError::IO(IoError::new(&e, Some(grammar_path))))?; #[cfg(feature = "qjs-rt")] if js_runtime == Some("native") { @@ -497,7 +515,9 @@ fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> JSResu let mut js_stdin = js_process .stdin .take() - .ok_or_else(|| JSError::IO(format!("Failed to open stdin for `{js_runtime}`")))?; + .ok_or_else(|| JSError::JSRuntimeStdin { + runtime: js_runtime.to_string(), + })?; let cli_version = Version::parse(env!("CARGO_PKG_VERSION"))?; write!( @@ -507,21 +527,26 @@ fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> JSResu globalThis.TREE_SITTER_CLI_VERSION_PATCH = {};", cli_version.major, cli_version.minor, cli_version.patch, ) - .map_err(|e| { - JSError::IO(format!( - "Failed to write tree-sitter version to `{js_runtime}`'s stdin -- {e}" - )) - })?; - js_stdin.write(include_bytes!("./dsl.js")).map_err(|e| { - JSError::IO(format!( - "Failed to write grammar dsl to `{js_runtime}`'s stdin -- {e}" - )) + .map_err(|e| JSError::JSRuntimeWrite { + runtime: js_runtime.to_string(), + item: "tree-sitter version".to_string(), + error: e.to_string(), })?; + js_stdin + .write(include_bytes!("./dsl.js")) + .map_err(|e| JSError::JSRuntimeWrite { + runtime: js_runtime.to_string(), + item: "grammar dsl".to_string(), + error: e.to_string(), + })?; drop(js_stdin); let output = js_process .wait_with_output() - .map_err(|e| JSError::IO(format!("Failed to read output from `{js_runtime}` -- {e}")))?; + .map_err(|e| JSError::JSRuntimeRead { + runtime: js_runtime.to_string(), + error: e.to_string(), + })?; match output.status.code() { Some(0) => { let stdout = String::from_utf8(output.stdout).map_err(|e| JSError::JSRuntimeUtf8 { @@ -537,9 +562,15 @@ fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> JSResu grammar_json = &stdout[pos + 1..]; let mut stdout = std::io::stdout().lock(); - stdout.write_all(node_output.as_bytes())?; - stdout.write_all(b"\n")?; - stdout.flush()?; + stdout + .write_all(node_output.as_bytes()) + .map_err(|e| JSError::IO(IoError::new(&e, None)))?; + stdout + .write_all(b"\n") + .map_err(|e| JSError::IO(IoError::new(&e, None)))?; + stdout + .flush() + .map_err(|e| JSError::IO(IoError::new(&e, None)))?; } Ok(serde_json::to_string_pretty(&serde_json::from_str::< @@ -559,8 +590,7 @@ fn load_js_grammar_file(grammar_path: &Path, js_runtime: Option<&str>) -> JSResu #[cfg(feature = "load")] pub fn write_file(path: &Path, body: impl AsRef<[u8]>) -> GenerateResult<()> { - fs::write(path, body) - .map_err(|e| GenerateError::IO(format!("Failed to write {:?} -- {e}", path.file_name()))) + fs::write(path, body).map_err(|e| GenerateError::IO(IoError::new(&e, Some(path)))) } #[cfg(test)] diff --git a/crates/generate/src/quickjs.rs b/crates/generate/src/quickjs.rs index 689615fc..848030e8 100644 --- a/crates/generate/src/quickjs.rs +++ b/crates/generate/src/quickjs.rs @@ -10,7 +10,7 @@ use rquickjs::{ Context, Ctx, Function, Module, Object, Runtime, Type, Value, }; -use super::{JSError, JSResult}; +use super::{IoError, JSError, JSResult}; const DSL: &[u8] = include_bytes!("dsl.js"); @@ -266,10 +266,10 @@ pub fn execute_native_runtime(grammar_path: &Path) -> JSResult { let loader = ScriptLoader::default().with_extension("mjs"); runtime.set_loader(resolver, loader); - let cwd = std::env::current_dir()?; + let cwd = std::env::current_dir().map_err(|e| JSError::IO(IoError::new(&e, None)))?; let relative_path = pathdiff::diff_paths(grammar_path, &cwd) .map(|p| p.to_string_lossy().to_string()) - .ok_or_else(|| JSError::IO("Failed to get relative path".to_string()))?; + .ok_or(JSError::RelativePath)?; context.with(|ctx| -> JSResult { let globals = ctx.globals(); From 0df2916920760371a73e7618c40c88221f0329f9 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Fri, 31 Oct 2025 11:58:20 +0100 Subject: [PATCH 046/140] bulild(deps): cargo update --- Cargo.lock | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 726289b9..03146c9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,22 +67,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1401,9 +1401,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -1784,9 +1784,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.108" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -2039,7 +2039,7 @@ dependencies = [ "log", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -2095,7 +2095,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tree-sitter", "tree-sitter-highlight", "tree-sitter-tags", @@ -2123,9 +2123,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" From 57e3a7b2ca5837677c7198d47207d6e15eaa7a73 Mon Sep 17 00:00:00 2001 From: Valeriy Kosikhin Date: Mon, 17 Nov 2025 15:17:25 +0300 Subject: [PATCH 047/140] fix(loader): set correct runtime host for cc while cross-compiling Pass the BUILD_TARGET variable from the build environment as 'host' for the cc crate. Otherwise, when cross-compiled, cc will keep looking for a cross-compiler instead of the native one on the target system. Signed-off-by: Valeriy Kosikhin --- crates/loader/src/loader.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 08d6af84..cf2c1a77 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -557,7 +557,6 @@ impl Config { } const BUILD_TARGET: &str = env!("BUILD_TARGET"); -const BUILD_HOST: &str = env!("BUILD_HOST"); pub struct LanguageConfiguration<'a> { pub scope: Option, @@ -1107,7 +1106,10 @@ impl Loader { .cargo_metadata(false) .cargo_warnings(false) .target(BUILD_TARGET) - .host(BUILD_HOST) + // BUILD_TARGET from the build environment becomes a runtime host for cc. + // Otherwise, when cross compiled, cc will keep looking for a cross-compiler + // on the target system instead of the native compiler. + .host(BUILD_TARGET) .debug(self.debug_build) .file(&config.parser_path) .includes(&config.header_paths) From 3072d35ed5f7dcd01a67c9ee04264e8bd9a730f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 21:13:38 +0000 Subject: [PATCH 048/140] build(deps): bump the cargo group with 2 updates Bumps the cargo group with 2 updates: [cc](https://github.com/rust-lang/cc-rs) and [wasmparser](https://github.com/bytecodealliance/wasm-tools). Updates `cc` from 1.2.45 to 1.2.46 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.45...cc-v1.2.46) Updates `wasmparser` from 0.240.0 to 0.241.2 - [Release notes](https://github.com/bytecodealliance/wasm-tools/releases) - [Commits](https://github.com/bytecodealliance/wasm-tools/commits) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.46 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: wasmparser dependency-version: 0.241.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 14 +++++++------- Cargo.toml | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03146c9b..ce5d678b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.45" +version = "1.2.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" +checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" dependencies = [ "find-msvc-tools", "shlex", @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "fnv" @@ -2026,7 +2026,7 @@ dependencies = [ "tree-sitter-tests-proc-macro", "unindent", "walkdir", - "wasmparser 0.240.0", + "wasmparser 0.241.2", "webbrowser", "widestring", ] @@ -2270,9 +2270,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.240.0" +version = "0.241.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b722dcf61e0ea47440b53ff83ccb5df8efec57a69d150e4f24882e4eba7e24a4" +checksum = "46d90019b1afd4b808c263e428de644f3003691f243387d30d673211ee0cb8e8" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", diff --git a/Cargo.toml b/Cargo.toml index 5afc53b5..cc3520fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.45" +cc = "1.2.46" clap = { version = "4.5.51", features = [ "cargo", "derive", @@ -150,7 +150,7 @@ tiny_http = "0.12.0" topological-sort = "0.2.2" unindent = "0.2.4" walkdir = "2.5.0" -wasmparser = "0.240.0" +wasmparser = "0.241.2" webbrowser = "1.0.5" tree-sitter = { version = "0.26.0", path = "./lib" } From f3012a999d94c65254a6fd91e4da0928e1369c99 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Mon, 13 Oct 2025 23:07:05 +0200 Subject: [PATCH 049/140] feat(bindings): expose the queries dynamically Available in the Rust, Python, and Node bindings Co-authored-by: ObserverOfTime --- crates/cli/src/init.rs | 223 +++++++++++++++++++++---- crates/cli/src/templates/.editorconfig | 2 +- crates/cli/src/templates/__init__.py | 33 ++-- crates/cli/src/templates/__init__.pyi | 18 +- crates/cli/src/templates/build.rs | 17 ++ crates/cli/src/templates/index.d.ts | 39 ++++- crates/cli/src/templates/index.js | 26 ++- crates/cli/src/templates/lib.rs | 19 ++- crates/loader/src/loader.rs | 34 ++-- 9 files changed, 335 insertions(+), 76 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 62923441..deb64292 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -14,7 +14,11 @@ use semver::Version; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; use tree_sitter_generate::write_file; -use tree_sitter_loader::{Author, Bindings, Grammar, Links, Metadata, PathsJSON, TreeSitterJSON}; +use tree_sitter_loader::{ + Author, Bindings, Grammar, Links, Metadata, PathsJSON, TreeSitterJSON, + DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME, DEFAULT_INJECTIONS_QUERY_FILE_NAME, + DEFAULT_LOCALS_QUERY_FILE_NAME, DEFAULT_TAGS_QUERY_FILE_NAME, +}; const CLI_VERSION: &str = env!("CARGO_PKG_VERSION"); const CLI_VERSION_PLACEHOLDER: &str = "CLI_VERSION"; @@ -60,6 +64,11 @@ const AUTHOR_EMAIL_PLACEHOLDER_GRAMMAR: &str = " PARSER_AUTHOR_EMAIL"; const FUNDING_URL_PLACEHOLDER: &str = "FUNDING_URL"; +const HIGHLIGHTS_QUERY_PATH_PLACEHOLDER: &str = "HIGHLIGHTS_QUERY_PATH"; +const INJECTIONS_QUERY_PATH_PLACEHOLDER: &str = "INJECTIONS_QUERY_PATH"; +const LOCALS_QUERY_PATH_PLACEHOLDER: &str = "LOCALS_QUERY_PATH"; +const TAGS_QUERY_PATH_PLACEHOLDER: &str = "TAGS_QUERY_PATH"; + const GRAMMAR_JS_TEMPLATE: &str = include_str!("./templates/grammar.js"); const PACKAGE_JSON_TEMPLATE: &str = include_str!("./templates/package.json"); const GITIGNORE_TEMPLATE: &str = include_str!("./templates/gitignore"); @@ -205,6 +214,10 @@ struct GenerateOpts<'a> { camel_parser_name: &'a str, title_parser_name: &'a str, class_name: &'a str, + highlights_query_path: &'a str, + injections_query_path: &'a str, + locals_query_path: &'a str, + tags_query_path: &'a str, } pub fn generate_grammar_files( @@ -255,6 +268,20 @@ pub fn generate_grammar_files( .clone() .unwrap_or_else(|| format!("TreeSitter{}", language_name.to_upper_camel_case())); + fn pathsjson_to_variable<'a>(paths_json: &'a PathsJSON, default: &'a PathBuf) -> &'a str { + match paths_json { + PathsJSON::Empty => Some(default), + PathsJSON::Single(path_buf) => Some(path_buf), + PathsJSON::Multiple(paths) => paths.first(), + } + .map_or("", |path| path.as_os_str().to_str().unwrap_or("")) + } + + let default_highlights_path = Path::new("queries").join(DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME); + let default_injections_path = Path::new("queries").join(DEFAULT_INJECTIONS_QUERY_FILE_NAME); + let default_locals_path = Path::new("queries").join(DEFAULT_LOCALS_QUERY_FILE_NAME); + let default_tags_path = Path::new("queries").join(DEFAULT_TAGS_QUERY_FILE_NAME); + let generate_opts = GenerateOpts { author_name: authors .map(|a| a.first().map(|a| a.name.as_str())) @@ -281,6 +308,22 @@ pub fn generate_grammar_files( camel_parser_name: &camel_name, title_parser_name: &title_name, class_name: &class_name, + highlights_query_path: pathsjson_to_variable( + &tree_sitter_config.grammars[0].highlights, + &default_highlights_path, + ), + injections_query_path: pathsjson_to_variable( + &tree_sitter_config.grammars[0].injections, + &default_injections_path, + ), + locals_query_path: pathsjson_to_variable( + &tree_sitter_config.grammars[0].locals, + &default_locals_path, + ), + tags_query_path: pathsjson_to_variable( + &tree_sitter_config.grammars[0].tags, + &default_tags_path, + ), }; // Create package.json @@ -388,8 +431,47 @@ pub fn generate_grammar_files( // Generate Rust bindings if tree_sitter_config.bindings.rust { missing_path(bindings_dir.join("rust"), create_dir)?.apply(|path| { - missing_path(path.join("lib.rs"), |path| { + missing_path_else(path.join("lib.rs"), allow_update, |path| { generate_file(path, LIB_RS_TEMPLATE, language_name, &generate_opts) + }, |path| { + let mut contents = fs::read_to_string(path)?; + if !contents.contains("#[cfg(with_highlights_query)]") { + let replacement = indoc! {r#" + #[cfg(with_highlights_query)] + /// The syntax highlighting query for this grammar. + pub const HIGHLIGHTS_QUERY: &str = include_str!("../../HIGHLIGHTS_QUERY_PATH"); + + #[cfg(with_injections_query)] + /// The language injection query for this grammar. + pub const INJECTIONS_QUERY: &str = include_str!("../../INJECTIONS_QUERY_PATH"); + + #[cfg(with_locals_query)] + /// The local variable query for this grammar. + pub const LOCALS_QUERY: &str = include_str!("../../LOCALS_QUERY_PATH"); + + #[cfg(with_tags_query)] + /// The symbol tagging query for this grammar. + pub const TAGS_QUERY: &str = include_str!("../../TAGS_QUERY_PATH"); + "#} + .replace("HIGHLIGHTS_QUERY_PATH", generate_opts.highlights_query_path) + .replace("INJECTIONS_QUERY_PATH", generate_opts.injections_query_path) + .replace("LOCALS_QUERY_PATH", generate_opts.locals_query_path) + .replace("TAGS_QUERY_PATH", generate_opts.tags_query_path); + contents = contents + .replace( + indoc! {r#" + // NOTE: uncomment these to include any queries that this grammar contains: + + // pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); + // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); + // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); + // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); + "#}, + &replacement, + ); + } + write_file(path, contents)?; + Ok(()) })?; missing_path_else( @@ -397,27 +479,29 @@ pub fn generate_grammar_files( allow_update, |path| generate_file(path, BUILD_RS_TEMPLATE, language_name, &generate_opts), |path| { - let replacement = indoc!{r#" - c_config.flag("-utf-8"); + let mut contents = fs::read_to_string(path)?; + if !contents.contains("wasm32-unknown-unknown") { + let replacement = indoc!{r#" + c_config.flag("-utf-8"); - if std::env::var("TARGET").unwrap() == "wasm32-unknown-unknown" { - let Ok(wasm_headers) = std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS") else { - panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS must be set by the language crate"); - }; - let Ok(wasm_src) = - std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_SRC").map(std::path::PathBuf::from) - else { - panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_SRC must be set by the language crate"); - }; + if std::env::var("TARGET").unwrap() == "wasm32-unknown-unknown" { + let Ok(wasm_headers) = std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS") else { + panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_HEADERS must be set by the language crate"); + }; + let Ok(wasm_src) = + std::env::var("DEP_TREE_SITTER_LANGUAGE_WASM_SRC").map(std::path::PathBuf::from) + else { + panic!("Environment variable DEP_TREE_SITTER_LANGUAGE_WASM_SRC must be set by the language crate"); + }; - c_config.include(&wasm_headers); - c_config.files([ - wasm_src.join("stdio.c"), - wasm_src.join("stdlib.c"), - wasm_src.join("string.c"), - ]); - } - "#}; + c_config.include(&wasm_headers); + c_config.files([ + wasm_src.join("stdio.c"), + wasm_src.join("stdlib.c"), + wasm_src.join("string.c"), + ]); + } + "#}; let indented_replacement = replacement .lines() @@ -425,11 +509,48 @@ pub fn generate_grammar_files( .collect::>() .join("\n"); - let mut contents = fs::read_to_string(path)?; - if !contents.contains("wasm32-unknown-unknown") { contents = contents.replace(r#" c_config.flag("-utf-8");"#, &indented_replacement); } + // Introduce configuration variables for dynamic query inclusion + if !contents.contains("with_highlights_query") { + let replaced = indoc! {r#" + c_config.compile("tree-sitter-KEBAB_PARSER_NAME"); + }"#} + .replace("KEBAB_PARSER_NAME", &language_name.to_kebab_case()); + + let replacement = indoc! {r#" + c_config.compile("tree-sitter-KEBAB_PARSER_NAME"); + + println!("cargo:rustc-check-cfg=cfg(with_highlights_query)"); + if !"HIGHLIGHTS_QUERY_PATH".is_empty() && std::path::Path::new("HIGHLIGHTS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_highlights_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_injections_query)"); + if !"INJECTIONS_QUERY_PATH".is_empty() && std::path::Path::new("INJECTIONS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_injections_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_locals_query)"); + if !"LOCALS_QUERY_PATH".is_empty() && std::path::Path::new("LOCALS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_locals_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_tags_query)"); + if !"TAGS_QUERY_PATH".is_empty() && std::path::Path::new("TAGS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_tags_query"); + } + }"#} + .replace("KEBAB_PARSER_NAME", &language_name.to_kebab_case()) + .replace("HIGHLIGHTS_QUERY_PATH", generate_opts.highlights_query_path) + .replace("INJECTIONS_QUERY_PATH", generate_opts.injections_query_path) + .replace("LOCALS_QUERY_PATH", generate_opts.locals_query_path) + .replace("TAGS_QUERY_PATH", generate_opts.tags_query_path); + + contents = contents.replace( + &replaced, + &replacement, + ); + } + write_file(path, contents)?; Ok(()) }, @@ -468,7 +589,7 @@ pub fn generate_grammar_files( |path| generate_file(path, INDEX_JS_TEMPLATE, language_name, &generate_opts), |path| { let contents = fs::read_to_string(path)?; - if !contents.contains("new URL") { + if !contents.contains("Object.defineProperty") { warn!("Replacing index.js"); generate_file(path, INDEX_JS_TEMPLATE, language_name, &generate_opts)?; } @@ -476,9 +597,19 @@ pub fn generate_grammar_files( }, )?; - missing_path(path.join("index.d.ts"), |path| { - generate_file(path, INDEX_D_TS_TEMPLATE, language_name, &generate_opts) - })?; + missing_path_else( + path.join("index.d.ts"), + allow_update, + |path| generate_file(path, INDEX_D_TS_TEMPLATE, language_name, &generate_opts), + |path| { + let contents = fs::read_to_string(path)?; + if !contents.contains("export default binding") { + warn!("Replacing index.d.ts"); + generate_file(path, INDEX_D_TS_TEMPLATE, language_name, &generate_opts)?; + } + Ok(()) + }, + )?; missing_path_else( path.join("binding_test.js"), @@ -717,9 +848,21 @@ pub fn generate_grammar_files( }, )?; - missing_path(lang_path.join("__init__.py"), |path| { - generate_file(path, INIT_PY_TEMPLATE, language_name, &generate_opts) - })?; + missing_path_else( + lang_path.join("__init__.py"), + allow_update, + |path| { + generate_file(path, INIT_PY_TEMPLATE, language_name, &generate_opts) + }, + |path| { + let contents = fs::read_to_string(path)?; + if !contents.contains("uncomment these to include any queries") { + warn!("Replacing __init__.py"); + generate_file(path, INIT_PY_TEMPLATE, language_name, &generate_opts)?; + } + Ok(()) + }, + )?; missing_path_else( lang_path.join("__init__.pyi"), @@ -727,7 +870,10 @@ pub fn generate_grammar_files( |path| generate_file(path, INIT_PYI_TEMPLATE, language_name, &generate_opts), |path| { let mut contents = fs::read_to_string(path)?; - if !contents.contains("CapsuleType") { + if contents.contains("uncomment these to include any queries") { + warn!("Replacing __init__.pyi"); + generate_file(path, INIT_PYI_TEMPLATE, language_name, &generate_opts)?; + } else if !contents.contains("CapsuleType") { contents = contents .replace( "from typing import Final", @@ -990,7 +1136,20 @@ fn generate_file( PARSER_VERSION_PLACEHOLDER, &generate_opts.version.to_string(), ) - .replace(PARSER_CLASS_NAME_PLACEHOLDER, generate_opts.class_name); + .replace(PARSER_CLASS_NAME_PLACEHOLDER, generate_opts.class_name) + .replace( + HIGHLIGHTS_QUERY_PATH_PLACEHOLDER, + generate_opts.highlights_query_path, + ) + .replace( + INJECTIONS_QUERY_PATH_PLACEHOLDER, + generate_opts.injections_query_path, + ) + .replace( + LOCALS_QUERY_PATH_PLACEHOLDER, + generate_opts.locals_query_path, + ) + .replace(TAGS_QUERY_PATH_PLACEHOLDER, generate_opts.tags_query_path); if let Some(name) = generate_opts.author_name { replacement = replacement.replace(AUTHOR_NAME_PLACEHOLDER, name); diff --git a/crates/cli/src/templates/.editorconfig b/crates/cli/src/templates/.editorconfig index 65330c40..c4650c59 100644 --- a/crates/cli/src/templates/.editorconfig +++ b/crates/cli/src/templates/.editorconfig @@ -7,7 +7,7 @@ charset = utf-8 indent_style = space indent_size = 2 -[*.js] +[*.{js,ts}] indent_style = space indent_size = 2 diff --git a/crates/cli/src/templates/__init__.py b/crates/cli/src/templates/__init__.py index fd137b0f..784887a7 100644 --- a/crates/cli/src/templates/__init__.py +++ b/crates/cli/src/templates/__init__.py @@ -6,32 +6,33 @@ from ._binding import language def _get_query(name, file): - query = _files(f"{__package__}.queries") / file - globals()[name] = query.read_text() + try: + query = _files(f"{__package__}") / file + globals()[name] = query.read_text() + except FileNotFoundError: + globals()[name] = None return globals()[name] def __getattr__(name): - # NOTE: uncomment these to include any queries that this grammar contains: - - # if name == "HIGHLIGHTS_QUERY": - # return _get_query("HIGHLIGHTS_QUERY", "highlights.scm") - # if name == "INJECTIONS_QUERY": - # return _get_query("INJECTIONS_QUERY", "injections.scm") - # if name == "LOCALS_QUERY": - # return _get_query("LOCALS_QUERY", "locals.scm") - # if name == "TAGS_QUERY": - # return _get_query("TAGS_QUERY", "tags.scm") + if name == "HIGHLIGHTS_QUERY": + return _get_query("HIGHLIGHTS_QUERY", "HIGHLIGHTS_QUERY_PATH") + if name == "INJECTIONS_QUERY": + return _get_query("INJECTIONS_QUERY", "INJECTIONS_QUERY_PATH") + if name == "LOCALS_QUERY": + return _get_query("LOCALS_QUERY", "LOCALS_QUERY_PATH") + if name == "TAGS_QUERY": + return _get_query("TAGS_QUERY", "TAGS_QUERY_PATH") raise AttributeError(f"module {__name__!r} has no attribute {name!r}") __all__ = [ "language", - # "HIGHLIGHTS_QUERY", - # "INJECTIONS_QUERY", - # "LOCALS_QUERY", - # "TAGS_QUERY", + "HIGHLIGHTS_QUERY", + "INJECTIONS_QUERY", + "LOCALS_QUERY", + "TAGS_QUERY", ] diff --git a/crates/cli/src/templates/__init__.pyi b/crates/cli/src/templates/__init__.pyi index 5c63215d..5c88ff6c 100644 --- a/crates/cli/src/templates/__init__.pyi +++ b/crates/cli/src/templates/__init__.pyi @@ -1,11 +1,17 @@ from typing import Final from typing_extensions import CapsuleType -# NOTE: uncomment these to include any queries that this grammar contains: +HIGHLIGHTS_QUERY: Final[str] | None +"""The syntax highlighting query for this grammar.""" -# HIGHLIGHTS_QUERY: Final[str] -# INJECTIONS_QUERY: Final[str] -# LOCALS_QUERY: Final[str] -# TAGS_QUERY: Final[str] +INJECTIONS_QUERY: Final[str] | None +"""The language injection query for this grammar.""" -def language() -> CapsuleType: ... +LOCALS_QUERY: Final[str] | None +"""The local variable query for this grammar.""" + +TAGS_QUERY: Final[str] | None +"""The symbol tagging query for this grammar.""" + +def language() -> CapsuleType: + """The tree-sitter language function for this grammar.""" diff --git a/crates/cli/src/templates/build.rs b/crates/cli/src/templates/build.rs index 272d8961..e3fffe4b 100644 --- a/crates/cli/src/templates/build.rs +++ b/crates/cli/src/templates/build.rs @@ -36,4 +36,21 @@ fn main() { } c_config.compile("tree-sitter-KEBAB_PARSER_NAME"); + + println!("cargo:rustc-check-cfg=cfg(with_highlights_query)"); + if !"HIGHLIGHTS_QUERY_PATH".is_empty() && std::path::Path::new("HIGHLIGHTS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_highlights_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_injections_query)"); + if !"INJECTIONS_QUERY_PATH".is_empty() && std::path::Path::new("INJECTIONS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_injections_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_locals_query)"); + if !"LOCALS_QUERY_PATH".is_empty() && std::path::Path::new("LOCALS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_locals_query"); + } + println!("cargo:rustc-check-cfg=cfg(with_tags_query)"); + if !"TAGS_QUERY_PATH".is_empty() && std::path::Path::new("TAGS_QUERY_PATH").exists() { + println!("cargo:rustc-cfg=with_tags_query"); + } } diff --git a/crates/cli/src/templates/index.d.ts b/crates/cli/src/templates/index.d.ts index 528e060f..24576d32 100644 --- a/crates/cli/src/templates/index.d.ts +++ b/crates/cli/src/templates/index.d.ts @@ -18,10 +18,43 @@ type NodeInfo = children: ChildNode[]; }); -type Language = { +/** + * The tree-sitter language object for this grammar. + * + * @see {@linkcode https://tree-sitter.github.io/node-tree-sitter/interfaces/Parser.Language.html Parser.Language} + * + * @example + * import Parser from "tree-sitter"; + * import CAMEL_PARSER_NAME from "tree-sitter-KEBAB_PARSER_NAME"; + * + * const parser = new Parser(); + * parser.setLanguage(CAMEL_PARSER_NAME); + */ +declare const binding: { + /** + * The inner language object. + * @private + */ language: unknown; + + /** + * The content of the `node-types.json` file for this grammar. + * + * @see {@linkplain https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types Static Node Types} + */ nodeTypeInfo: NodeInfo[]; + + /** The syntax highlighting query for this grammar. */ + HIGHLIGHTS_QUERY?: string; + + /** The language injection query for this grammar. */ + INJECTIONS_QUERY?: string; + + /** The local variable query for this grammar. */ + LOCALS_QUERY?: string; + + /** The symbol tagging query for this grammar. */ + TAGS_QUERY?: string; }; -declare const language: Language; -export = language; +export default binding; diff --git a/crates/cli/src/templates/index.js b/crates/cli/src/templates/index.js index 4b363040..b3edc2e3 100644 --- a/crates/cli/src/templates/index.js +++ b/crates/cli/src/templates/index.js @@ -1,3 +1,4 @@ +import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; const root = fileURLToPath(new URL("../..", import.meta.url)); @@ -8,8 +9,29 @@ const binding = typeof process.versions.bun === "string" : (await import("node-gyp-build")).default(root); try { - const nodeTypes = await import(`${root}/src/node-types.json`, {with: {type: "json"}}); + const nodeTypes = await import(`${root}/src/node-types.json`, { with: { type: "json" } }); binding.nodeTypeInfo = nodeTypes.default; -} catch (_) {} +} catch { } + +const queries = [ + ["HIGHLIGHTS_QUERY", `${root}/HIGHLIGHTS_QUERY_PATH`], + ["INJECTIONS_QUERY", `${root}/INJECTIONS_QUERY_PATH`], + ["LOCALS_QUERY", `${root}/LOCALS_QUERY_PATH`], + ["TAGS_QUERY", `${root}/TAGS_QUERY_PATH`], +]; + +for (const [prop, path] of queries) { + Object.defineProperty(binding, prop, { + configurable: true, + enumerable: true, + get() { + delete binding[prop]; + try { + binding[prop] = readFileSync(path, "utf8"); + } catch { } + return binding[prop]; + } + }); +} export default binding; diff --git a/crates/cli/src/templates/lib.rs b/crates/cli/src/templates/lib.rs index 8478f488..1e8c9ca3 100644 --- a/crates/cli/src/templates/lib.rs +++ b/crates/cli/src/templates/lib.rs @@ -32,12 +32,21 @@ pub const LANGUAGE: LanguageFn = unsafe { LanguageFn::from_raw(tree_sitter_PARSE /// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers/6-static-node-types pub const NODE_TYPES: &str = include_str!("../../src/node-types.json"); -// NOTE: uncomment these to include any queries that this grammar contains: +#[cfg(with_highlights_query)] +/// The syntax highlighting query for this grammar. +pub const HIGHLIGHTS_QUERY: &str = include_str!("../../HIGHLIGHTS_QUERY_PATH"); -// pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); -// pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); -// pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); -// pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); +#[cfg(with_injections_query)] +/// The language injection query for this grammar. +pub const INJECTIONS_QUERY: &str = include_str!("../../INJECTIONS_QUERY_PATH"); + +#[cfg(with_locals_query)] +/// The local variable query for this grammar. +pub const LOCALS_QUERY: &str = include_str!("../../LOCALS_QUERY_PATH"); + +#[cfg(with_tags_query)] +/// The symbol tagging query for this grammar. +pub const TAGS_QUERY: &str = include_str!("../../TAGS_QUERY_PATH"); #[cfg(test)] mod tests { diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index cf2c1a77..7c2e5226 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -245,6 +245,14 @@ impl std::fmt::Display for WasiSDKClangError { } } +pub const DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME: &str = "highlights.scm"; + +pub const DEFAULT_INJECTIONS_QUERY_FILE_NAME: &str = "injections.scm"; + +pub const DEFAULT_LOCALS_QUERY_FILE_NAME: &str = "locals.scm"; + +pub const DEFAULT_TAGS_QUERY_FILE_NAME: &str = "tags.scm"; + #[derive(Default, Deserialize, Serialize)] pub struct Config { #[serde(default)] @@ -1764,21 +1772,21 @@ impl LanguageConfiguration<'_> { Some( paths .iter() - .filter(|p| p.ends_with("highlights.scm")) + .filter(|p| p.ends_with(DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME)) .cloned() .collect::>(), ), Some( paths .iter() - .filter(|p| p.ends_with("tags.scm")) + .filter(|p| p.ends_with(DEFAULT_TAGS_QUERY_FILE_NAME)) .cloned() .collect::>(), ), Some( paths .iter() - .filter(|p| p.ends_with("locals.scm")) + .filter(|p| p.ends_with(DEFAULT_LOCALS_QUERY_FILE_NAME)) .cloned() .collect::>(), ), @@ -1793,7 +1801,7 @@ impl LanguageConfiguration<'_> { } else { self.highlights_filenames.as_deref() }, - "highlights.scm", + DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME, )?; let (injections_query, injection_ranges) = self.read_queries( if injections_filenames.is_some() { @@ -1801,7 +1809,7 @@ impl LanguageConfiguration<'_> { } else { self.injections_filenames.as_deref() }, - "injections.scm", + DEFAULT_INJECTIONS_QUERY_FILE_NAME, )?; let (locals_query, locals_ranges) = self.read_queries( if locals_filenames.is_some() { @@ -1809,7 +1817,7 @@ impl LanguageConfiguration<'_> { } else { self.locals_filenames.as_deref() }, - "locals.scm", + DEFAULT_LOCALS_QUERY_FILE_NAME, )?; if highlights_query.is_empty() { @@ -1871,10 +1879,12 @@ impl LanguageConfiguration<'_> { pub fn tags_config(&self, language: Language) -> LoaderResult> { self.tags_config .get_or_try_init(|| { - let (tags_query, tags_ranges) = - self.read_queries(self.tags_filenames.as_deref(), "tags.scm")?; - let (locals_query, locals_ranges) = - self.read_queries(self.locals_filenames.as_deref(), "locals.scm")?; + let (tags_query, tags_ranges) = self + .read_queries(self.tags_filenames.as_deref(), DEFAULT_TAGS_QUERY_FILE_NAME)?; + let (locals_query, locals_ranges) = self.read_queries( + self.locals_filenames.as_deref(), + DEFAULT_LOCALS_QUERY_FILE_NAME, + )?; if tags_query.is_empty() { Ok(None) } else { @@ -1947,7 +1957,9 @@ impl LanguageConfiguration<'_> { } } else { // highlights.scm is needed to test highlights, and tags.scm to test tags - if default_path == "highlights.scm" || default_path == "tags.scm" { + if default_path == DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME + || default_path == DEFAULT_TAGS_QUERY_FILE_NAME + { warn!( concat!( "You should add a `{}` entry pointing to the {} path in the `tree-sitter` ", From 0e1f715ef1b2b5b69530284f64b1969c4cb625a8 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Wed, 5 Nov 2025 15:16:33 +0100 Subject: [PATCH 050/140] Move PathsJSON method, reformat --- crates/cli/src/init.rs | 47 ++++++++++++++----------------------- crates/loader/src/loader.rs | 11 +++++++++ 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index deb64292..0164cc8f 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -268,15 +268,6 @@ pub fn generate_grammar_files( .clone() .unwrap_or_else(|| format!("TreeSitter{}", language_name.to_upper_camel_case())); - fn pathsjson_to_variable<'a>(paths_json: &'a PathsJSON, default: &'a PathBuf) -> &'a str { - match paths_json { - PathsJSON::Empty => Some(default), - PathsJSON::Single(path_buf) => Some(path_buf), - PathsJSON::Multiple(paths) => paths.first(), - } - .map_or("", |path| path.as_os_str().to_str().unwrap_or("")) - } - let default_highlights_path = Path::new("queries").join(DEFAULT_HIGHLIGHTS_QUERY_FILE_NAME); let default_injections_path = Path::new("queries").join(DEFAULT_INJECTIONS_QUERY_FILE_NAME); let default_locals_path = Path::new("queries").join(DEFAULT_LOCALS_QUERY_FILE_NAME); @@ -308,22 +299,18 @@ pub fn generate_grammar_files( camel_parser_name: &camel_name, title_parser_name: &title_name, class_name: &class_name, - highlights_query_path: pathsjson_to_variable( - &tree_sitter_config.grammars[0].highlights, - &default_highlights_path, - ), - injections_query_path: pathsjson_to_variable( - &tree_sitter_config.grammars[0].injections, - &default_injections_path, - ), - locals_query_path: pathsjson_to_variable( - &tree_sitter_config.grammars[0].locals, - &default_locals_path, - ), - tags_query_path: pathsjson_to_variable( - &tree_sitter_config.grammars[0].tags, - &default_tags_path, - ), + highlights_query_path: tree_sitter_config.grammars[0] + .highlights + .to_variable_value(&default_highlights_path), + injections_query_path: tree_sitter_config.grammars[0] + .injections + .to_variable_value(&default_injections_path), + locals_query_path: tree_sitter_config.grammars[0] + .locals + .to_variable_value(&default_locals_path), + tags_query_path: tree_sitter_config.grammars[0] + .tags + .to_variable_value(&default_tags_path), }; // Create package.json @@ -503,11 +490,11 @@ pub fn generate_grammar_files( } "#}; - let indented_replacement = replacement - .lines() - .map(|line| if line.is_empty() { line.to_string() } else { format!(" {line}") }) - .collect::>() - .join("\n"); + let indented_replacement = replacement + .lines() + .map(|line| if line.is_empty() { line.to_string() } else { format!(" {line}") }) + .collect::>() + .join("\n"); contents = contents.replace(r#" c_config.flag("-utf-8");"#, &indented_replacement); } diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 7c2e5226..28618be6 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -284,6 +284,17 @@ impl PathsJSON { const fn is_empty(&self) -> bool { matches!(self, Self::Empty) } + + /// Represent this set of paths as a string that can be included in templates + #[must_use] + pub fn to_variable_value<'a>(&'a self, default: &'a PathBuf) -> &'a str { + match self { + Self::Empty => Some(default), + Self::Single(path_buf) => Some(path_buf), + Self::Multiple(paths) => paths.first(), + } + .map_or("", |path| path.as_os_str().to_str().unwrap_or("")) + } } #[derive(Serialize, Deserialize, Clone)] From 877782a8a41d830f9e7f0f22dfcb67b3c2e50418 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sat, 1 Nov 2025 05:25:00 -0400 Subject: [PATCH 051/140] fix(docs): update cli docs to reflect changes to various subcommand arguments --- crates/cli/src/main.rs | 11 +++-------- docs/src/cli/fuzz.md | 12 ++++++++++++ docs/src/cli/generate.md | 6 +++++- docs/src/cli/highlight.md | 4 ++++ docs/src/cli/parse.md | 14 +++++++++++--- docs/src/cli/playground.md | 8 ++++---- docs/src/cli/query.md | 12 ++++++++++++ docs/src/cli/tags.md | 4 ++++ docs/src/cli/test.md | 12 ++++++++++++ docs/src/cli/version.md | 8 ++++++++ 10 files changed, 75 insertions(+), 16 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index d9f8c174..1c7fa957 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -261,15 +261,10 @@ struct Parse { #[arg(long)] pub open_log: bool, /// Deprecated: use --json-summary - #[arg( - long, - short = 'j', - conflicts_with = "json_summary", - conflicts_with = "stat" - )] + #[arg(long, conflicts_with = "json_summary", conflicts_with = "stat")] pub json: bool, /// Output parsing results in a JSON format - #[arg(long, conflicts_with = "json", conflicts_with = "stat")] + #[arg(long, short = 'j', conflicts_with = "json", conflicts_with = "stat")] pub json_summary: bool, /// The path to an alternative config.json file #[arg(long)] @@ -348,7 +343,7 @@ struct Test { /// Show only the pass-fail overview tree #[arg(long)] pub overview_only: bool, - /// Output the test summary in a JSON output + /// Output the test summary in a JSON format #[arg(long)] pub json_summary: bool, } diff --git a/docs/src/cli/fuzz.md b/docs/src/cli/fuzz.md index 1f79bc00..7f97f9ba 100644 --- a/docs/src/cli/fuzz.md +++ b/docs/src/cli/fuzz.md @@ -17,6 +17,18 @@ A list of test names to skip fuzzing. The directory containing the parser. This is primarily useful in multi-language repositories. +### `-p/--grammar-path` + +The path to the directory containing the grammar. + +### `--lib-path` + +The path to the parser's dynamic library. This is used instead of the cached or automatically generated dynamic library. + +### `--lang-name` + +If `--lib-path` is used, the name of the language used to extract the library's language function + ### `--edits ` The maximum number of edits to perform. The default is 3. diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 32c8437a..c373b1e2 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -44,7 +44,7 @@ Print the overview of states from the given rule. This is useful for debugging a item sets for all given states in a given rule. To solely view state count numbers for rules, pass in `-` for the rule argument. To view the overview of states for every rule, pass in `*` for the rule argument. -### `--json` +### `--json-summary` Report conflicts in a JSON format. @@ -54,3 +54,7 @@ The path to the JavaScript runtime executable to use when generating the parser. Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.0, you can also pass in `native` to use the native QuickJS runtime that comes bundled with the CLI. This avoids the dependency on a JavaScript runtime entirely. + +### `--disable-optimization` + +Disable optimizations when generating the parser. Currently, this only affects the merging of compatible parse states. diff --git a/docs/src/cli/highlight.md b/docs/src/cli/highlight.md index 1378e0f6..82c9e25c 100644 --- a/docs/src/cli/highlight.md +++ b/docs/src/cli/highlight.md @@ -57,3 +57,7 @@ The path to an alternative configuration (`config.json`) file. See [the init-con ### `-n/--test-number ` Highlight the contents of a specific test. + +### `-r/--rebuild` + +Force a rebuild of the parser before running the fuzzer. diff --git a/docs/src/cli/parse.md b/docs/src/cli/parse.md index 9f76b550..178d97b5 100644 --- a/docs/src/cli/parse.md +++ b/docs/src/cli/parse.md @@ -1,8 +1,8 @@ # `tree-sitter parse` The `parse` command parses source files using a Tree-sitter parser. You can pass any number of file paths and glob patterns -to `tree-sitter parse`, and it will parse all the given files. The command will exit with a non-zero status code if any -parse errors occurred. +to `tree-sitter parse`, and it will parse all the given files. If no paths are provided, input will be parsed from stdin. +The command will exit with a non-zero status code if any parse errors occurred. ```bash tree-sitter parse [OPTIONS] [PATHS]... # Aliases: p @@ -18,6 +18,14 @@ The path to a file that contains paths to source files to parse. The path to the directory containing the grammar. +### `-l/--lib-path` + +The path to the parser's dynamic library. This is used instead of the cached or automatically generated dynamic library. + +### `--lang-name` + +If `--lib-path` is used, the name of the language used to extract the library's language function + ### `--scope ` The language scope to use for parsing. This is useful when the language is ambiguous. @@ -81,7 +89,7 @@ in `UTF-16BE` or `UTF-16LE`. If no `BOM` is present, `UTF-8` is the default. One When using the `--debug-graph` option, open the log file in the default browser. -### `-j/--json` +### `-j/--json-summary` Output parsing results in a JSON format. diff --git a/docs/src/cli/playground.md b/docs/src/cli/playground.md index 0dbff469..7c2ef598 100644 --- a/docs/src/cli/playground.md +++ b/docs/src/cli/playground.md @@ -13,10 +13,6 @@ For this to work, you must have already built the parser as a Wasm module. This ## Options -### `-e/--export ` - -Export static playground files to the specified directory instead of serving them. - ### `-q/--quiet` Don't automatically open the playground in the default browser. @@ -24,3 +20,7 @@ Don't automatically open the playground in the default browser. ### `--grammar-path ` The path to the directory containing the grammar and wasm files. + +### `-e/--export ` + +Export static playground files to the specified directory instead of serving them. diff --git a/docs/src/cli/query.md b/docs/src/cli/query.md index ed96aa51..395ca486 100644 --- a/docs/src/cli/query.md +++ b/docs/src/cli/query.md @@ -12,6 +12,14 @@ tree-sitter query [OPTIONS] [PATHS]... # Aliases: q The path to the directory containing the grammar. +### `--lib-path` + +The path to the parser's dynamic library. This is used instead of the cached or automatically generated dynamic library. + +### `--lang-name` + +If `--lib-path` is used, the name of the language used to extract the library's language function + ### `-t/--time` Print the time taken to execute the query on the file. @@ -51,3 +59,7 @@ The path to an alternative configuration (`config.json`) file. See [the init-con ### `-n/--test-number ` Query the contents of a specific test. + +### `-r/--rebuild` + +Force a rebuild of the parser before executing the query. diff --git a/docs/src/cli/tags.md b/docs/src/cli/tags.md index 80ee1baa..a48fabb4 100644 --- a/docs/src/cli/tags.md +++ b/docs/src/cli/tags.md @@ -36,3 +36,7 @@ The path to an alternative configuration (`config.json`) file. See [the init-con ### `-n/--test-number ` Generate tags from the contents of a specific test. + +### `-r/--rebuild` + +Force a rebuild of the parser before running the tags. diff --git a/docs/src/cli/test.md b/docs/src/cli/test.md index c1724745..401bcd39 100644 --- a/docs/src/cli/test.md +++ b/docs/src/cli/test.md @@ -24,6 +24,14 @@ Only run tests from the given filename in the corpus. The path to the directory containing the grammar. +### `--lib-path` + +The path to the parser's dynamic library. This is used instead of the cached or automatically generated dynamic library. + +### `--lang-name` + +If `--lib-path` is used, the name of the language used to extract the library's language function + ### `-u/--update` Update the expected output of tests. @@ -78,3 +86,7 @@ Force a rebuild of the parser before running tests. ### `--overview-only` Only show the overview of the test results, and not the diff. + +### `--json-summary` + +Output the test summary in a JSON format. diff --git a/docs/src/cli/version.md b/docs/src/cli/version.md index e8f7a840..ab699d2a 100644 --- a/docs/src/cli/version.md +++ b/docs/src/cli/version.md @@ -42,3 +42,11 @@ tree-sitter version ### `-p/--grammar-path ` The path to the directory containing the grammar. + +### `--bump` + +Automatically bump the version. Possible values are: + +- `patch`: Bump the patch version. +- `minor`: Bump the minor version. +- `major`: Bump the major version. From 55b9a25c8449c58b28bfcc8e28b454529309ce7f Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Sun, 26 Oct 2025 16:51:08 +0100 Subject: [PATCH 052/140] docs: New page about ABI versions for parser users Closes #374. The statement about the intended backwards compatibility is purely speculative and provided as a "straw man" to help reviewers come up with a better description of the intended backwards compatibility. --- docs/src/SUMMARY.md | 1 + docs/src/using-parsers/7-abi-versions.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 docs/src/using-parsers/7-abi-versions.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 6e6eed94..231085ae 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -15,6 +15,7 @@ - [Predicates and Directives](./using-parsers/queries/3-predicates-and-directives.md) - [API](./using-parsers/queries/4-api.md) - [Static Node Types](./using-parsers/6-static-node-types.md) + - [ABI versions](./using-parsers/7-abi-versions.md) - [Creating Parsers](./creating-parsers/index.md) - [Getting Started](./creating-parsers/1-getting-started.md) - [The Grammar DSL](./creating-parsers/2-the-grammar-dsl.md) diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md new file mode 100644 index 00000000..6845a9c4 --- /dev/null +++ b/docs/src/using-parsers/7-abi-versions.md @@ -0,0 +1,19 @@ +# ABI versions + +Parsers generated with tree-sitter have an associated ABI version. This version specifies the shape of the C code that they contain, which they expose to applications. + +A given version of tree-sitter is only able to load parsers which have certain ABI versions: + +| tree-sitter version | Min parser ABI version | Max parser ABI version | +|---------------------|------------------------|------------------------| +| 0.14 | 9 | 9 | +| >=0.15.0, <=0.15.7 | 9 | 10 | +| >=0.15.8, <=0.16 | 9 | 11 | +| 0.17, 0.18 | 9 | 12 | +| >=0.19, <=0.20.2 | 13 | 13 | +| >=0.20.3, <=0.24 | 13 | 14 | +| >=0.25 | 13 | 15 | + +Tree-sitter developers aim to maintain compatibility with the previous ABI version at least. + +Parser authors are able to specify the ABI version they want to use by specifying it with the `--abi` option of the `tree-sitter generate` command. From 42e7e9c3e7bfe491f5cec80706dfa900bc86aeaa Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Wed, 5 Nov 2025 12:31:17 +0100 Subject: [PATCH 053/140] Integrate rewording suggestions --- docs/src/using-parsers/7-abi-versions.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md index 6845a9c4..7badf713 100644 --- a/docs/src/using-parsers/7-abi-versions.md +++ b/docs/src/using-parsers/7-abi-versions.md @@ -1,6 +1,6 @@ # ABI versions -Parsers generated with tree-sitter have an associated ABI version. This version specifies the shape of the C code that they contain, which they expose to applications. +Parsers generated with tree-sitter have an associated ABI version. This version establishes hard compatibility boundaries between the generated parser and the tree-sitter library. A given version of tree-sitter is only able to load parsers which have certain ABI versions: @@ -14,6 +14,7 @@ A given version of tree-sitter is only able to load parsers which have certain A | >=0.20.3, <=0.24 | 13 | 14 | | >=0.25 | 13 | 15 | -Tree-sitter developers aim to maintain compatibility with the previous ABI version at least. - -Parser authors are able to specify the ABI version they want to use by specifying it with the `--abi` option of the `tree-sitter generate` command. +By default, parsers are generated using the latest available ABI. Grammar authors can specify an older ABI via the `--abi` option to the `generate` command: +``` +tree-sitter generate --abi= +``` From 02508d557043740b2c2a9b0eea82aa324e3032f6 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Fri, 7 Nov 2025 08:01:01 +0100 Subject: [PATCH 054/140] Apply suggestions from code review Co-authored-by: Christian Clason --- docs/src/using-parsers/7-abi-versions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md index 7badf713..d9df678a 100644 --- a/docs/src/using-parsers/7-abi-versions.md +++ b/docs/src/using-parsers/7-abi-versions.md @@ -2,7 +2,7 @@ Parsers generated with tree-sitter have an associated ABI version. This version establishes hard compatibility boundaries between the generated parser and the tree-sitter library. -A given version of tree-sitter is only able to load parsers which have certain ABI versions: +A given version of the tree-sitter library is only able to load parsers which have certain ABI versions: | tree-sitter version | Min parser ABI version | Max parser ABI version | |---------------------|------------------------|------------------------| @@ -14,7 +14,7 @@ A given version of tree-sitter is only able to load parsers which have certain A | >=0.20.3, <=0.24 | 13 | 14 | | >=0.25 | 13 | 15 | -By default, parsers are generated using the latest available ABI. Grammar authors can specify an older ABI via the `--abi` option to the `generate` command: +By default, the tree-sitter CLI will generate parser using the latest available ABI for that version. Grammar authors can specify an older ABI (within the constraints _of the CLI_, which may be stricter than the library!) via the `--abi` option to the `generate` command: ``` tree-sitter generate --abi= ``` From 120f74723e694be4dc2f0033e01b24350dd73f19 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Thu, 20 Nov 2025 09:56:01 +0100 Subject: [PATCH 055/140] =?UTF-8?q?docs:=20fix=20typo=20in=20the=20page=20?= =?UTF-8?q?about=20ABI=C2=A0version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Of course I only catch that once they are already published… --- docs/src/using-parsers/7-abi-versions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md index d9df678a..30b6dcdf 100644 --- a/docs/src/using-parsers/7-abi-versions.md +++ b/docs/src/using-parsers/7-abi-versions.md @@ -14,7 +14,7 @@ A given version of the tree-sitter library is only able to load parsers which ha | >=0.20.3, <=0.24 | 13 | 14 | | >=0.25 | 13 | 15 | -By default, the tree-sitter CLI will generate parser using the latest available ABI for that version. Grammar authors can specify an older ABI (within the constraints _of the CLI_, which may be stricter than the library!) via the `--abi` option to the `generate` command: +By default, the tree-sitter CLI will generate parsers using the latest available ABI for that version. Grammar authors can specify an older ABI (within the constraints _of the CLI_, which may be stricter than the library!) via the `--abi` option to the `generate` command: ``` tree-sitter generate --abi= ``` From 60635e07299e167b82dd38d5f324955a7157d604 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Fri, 31 Oct 2025 15:28:58 +0200 Subject: [PATCH 056/140] fix(generate): add node_modules to quickjs resolver --- crates/generate/src/quickjs.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/generate/src/quickjs.rs b/crates/generate/src/quickjs.rs index 848030e8..b7960db2 100644 --- a/crates/generate/src/quickjs.rs +++ b/crates/generate/src/quickjs.rs @@ -261,6 +261,7 @@ pub fn execute_native_runtime(grammar_path: &Path) -> JSResult { let context = Context::full(&runtime)?; let resolver = FileResolver::default() + .with_path("./node_modules") .with_path("./") .with_pattern("{}.mjs"); let loader = ScriptLoader::default().with_extension("mjs"); From 320c0865e90d8599ed9d2fb5113913f133fef5f3 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Tue, 11 Nov 2025 04:27:23 -0500 Subject: [PATCH 057/140] feat(cli): don't bail after first version update fails --- crates/cli/src/version.rs | 41 ++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/crates/cli/src/version.rs b/crates/cli/src/version.rs index 39cd5481..e7601186 100644 --- a/crates/cli/src/version.rs +++ b/crates/cli/src/version.rs @@ -2,7 +2,7 @@ use std::{fs, path::PathBuf, process::Command}; use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; -use log::{info, warn}; +use log::{error, info, warn}; use regex::Regex; use semver::Version as SemverVersion; use std::cmp::Ordering; @@ -84,44 +84,57 @@ impl Version { let is_multigrammar = tree_sitter_json.grammars.len() > 1; - self.update_treesitter_json().with_context(|| { + let mut has_failure = false; + let mut record_failures = |result: anyhow::Result<()>| { + if let Err(e) = result { + has_failure = true; + error!("{e}"); + } + }; + + record_failures(self.update_treesitter_json().with_context(|| { format!( "Failed to update tree-sitter.json at {}", self.current_dir.display() ) - })?; - self.update_cargo_toml().with_context(|| { + })); + record_failures(self.update_cargo_toml().with_context(|| { format!( "Failed to update Cargo.toml at {}", self.current_dir.display() ) - })?; - self.update_package_json().with_context(|| { + })); + record_failures(self.update_package_json().with_context(|| { format!( "Failed to update package.json at {}", self.current_dir.display() ) - })?; - self.update_makefile(is_multigrammar).with_context(|| { + })); + record_failures(self.update_makefile(is_multigrammar).with_context(|| { format!( "Failed to update Makefile at {}", self.current_dir.display() ) - })?; - self.update_cmakelists_txt().with_context(|| { + })); + record_failures(self.update_cmakelists_txt().with_context(|| { format!( "Failed to update CMakeLists.txt at {}", self.current_dir.display() ) - })?; - self.update_pyproject_toml().with_context(|| { + })); + record_failures(self.update_pyproject_toml().with_context(|| { format!( "Failed to update pyproject.toml at {}", self.current_dir.display() ) - })?; + })); - Ok(()) + if has_failure { + // Return an empty error message to prevent double-reporting + Err(anyhow!("")) + } else { + Ok(()) + } } fn update_treesitter_json(&self) -> Result<()> { From d592b16ac0eb67d5e6cee060a3bfec451cf9b7ac Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Tue, 11 Nov 2025 04:32:37 -0500 Subject: [PATCH 058/140] fix(docs): list dependencies on external tooling for `version` command --- docs/src/cli/version.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/src/cli/version.md b/docs/src/cli/version.md index ab699d2a..c2d526a7 100644 --- a/docs/src/cli/version.md +++ b/docs/src/cli/version.md @@ -37,6 +37,11 @@ To print the current version without bumping it, use: tree-sitter version ``` +Note that some of the binding updates require access to external tooling: + +* Updating Cargo.toml and Cargo.lock bindings requires that `cargo` is installed. +* Updating package-lock.json requires that `npm` is installed. + ## Options ### `-p/--grammar-path ` From b095968dff0f606eed8b319db033b92e41109766 Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Wed, 12 Nov 2025 01:26:10 -0500 Subject: [PATCH 059/140] refactor(cli): clean up version updating code This commit adds proper error types when updating the version across files --- Cargo.lock | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/main.rs | 2 +- crates/cli/src/version.rs | 364 ++++++++++++++++++++------------------ 4 files changed, 195 insertions(+), 173 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce5d678b..5e95e3a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2016,6 +2016,7 @@ dependencies = [ "similar", "streaming-iterator", "tempfile", + "thiserror 2.0.17", "tiny_http", "tree-sitter", "tree-sitter-config", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 31626eb2..c10b4652 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -60,6 +60,7 @@ serde.workspace = true serde_json.workspace = true similar.workspace = true streaming-iterator.workspace = true +thiserror.workspace = true tiny_http.workspace = true walkdir.workspace = true wasmparser.workspace = true diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 1c7fa957..3f83bf5f 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1394,7 +1394,7 @@ impl Test { impl Version { fn run(self, current_dir: PathBuf) -> Result<()> { - version::Version::new(self.version, current_dir, self.bump).run() + Ok(version::Version::new(self.version, current_dir, self.bump).run()?) } } diff --git a/crates/cli/src/version.rs b/crates/cli/src/version.rs index e7601186..9406b58c 100644 --- a/crates/cli/src/version.rs +++ b/crates/cli/src/version.rs @@ -1,8 +1,7 @@ use std::{fs, path::PathBuf, process::Command}; -use anyhow::{anyhow, Context, Result}; use clap::ValueEnum; -use log::{error, info, warn}; +use log::{info, warn}; use regex::Regex; use semver::Version as SemverVersion; use std::cmp::Ordering; @@ -22,6 +21,36 @@ pub struct Version { pub bump: Option, } +#[derive(thiserror::Error, Debug)] +pub enum VersionError { + #[error(transparent)] + Json(#[from] serde_json::Error), + #[error(transparent)] + Io(#[from] std::io::Error), + #[error("Failed to update one or more files:\n\n{0}")] + Update(UpdateErrors), +} + +#[derive(thiserror::Error, Debug)] +pub struct UpdateErrors(Vec); + +impl std::fmt::Display for UpdateErrors { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for error in &self.0 { + writeln!(f, "{error}\n")?; + } + Ok(()) + } +} + +#[derive(thiserror::Error, Debug)] +pub enum UpdateError { + #[error("Failed to update {1}:\n{0}")] + Io(std::io::Error, PathBuf), + #[error("Failed to run `{0}`:\n{1}")] + Command(&'static str, String), +} + impl Version { #[must_use] pub const fn new( @@ -36,7 +65,7 @@ impl Version { } } - pub fn run(mut self) -> Result<()> { + pub fn run(mut self) -> Result<(), VersionError> { let tree_sitter_json = self.current_dir.join("tree-sitter.json"); let tree_sitter_json = @@ -84,111 +113,100 @@ impl Version { let is_multigrammar = tree_sitter_json.grammars.len() > 1; - let mut has_failure = false; - let mut record_failures = |result: anyhow::Result<()>| { + let mut errors = Vec::new(); + + // Helper to push errors into the errors vector, returns true if an error was pushed + let mut push_err = |result: Result<(), UpdateError>| -> bool { if let Err(e) = result { - has_failure = true; - error!("{e}"); + errors.push(e); + return true; } + false }; - record_failures(self.update_treesitter_json().with_context(|| { - format!( - "Failed to update tree-sitter.json at {}", - self.current_dir.display() - ) - })); - record_failures(self.update_cargo_toml().with_context(|| { - format!( - "Failed to update Cargo.toml at {}", - self.current_dir.display() - ) - })); - record_failures(self.update_package_json().with_context(|| { - format!( - "Failed to update package.json at {}", - self.current_dir.display() - ) - })); - record_failures(self.update_makefile(is_multigrammar).with_context(|| { - format!( - "Failed to update Makefile at {}", - self.current_dir.display() - ) - })); - record_failures(self.update_cmakelists_txt().with_context(|| { - format!( - "Failed to update CMakeLists.txt at {}", - self.current_dir.display() - ) - })); - record_failures(self.update_pyproject_toml().with_context(|| { - format!( - "Failed to update pyproject.toml at {}", - self.current_dir.display() - ) - })); + push_err(self.update_treesitter_json()); - if has_failure { - // Return an empty error message to prevent double-reporting - Err(anyhow!("")) - } else { + // Only update Cargo.lock if Cargo.toml was updated + push_err(self.update_cargo_toml()).then(|| push_err(self.update_cargo_lock())); + + // Only update package-lock.json if package.json was updated + push_err(self.update_package_json()).then(|| push_err(self.update_package_lock_json())); + + push_err(self.update_makefile(is_multigrammar)); + push_err(self.update_cmakelists_txt()); + push_err(self.update_pyproject_toml()); + + if errors.is_empty() { Ok(()) + } else { + Err(VersionError::Update(UpdateErrors(errors))) } } - fn update_treesitter_json(&self) -> Result<()> { - let tree_sitter_json = &fs::read_to_string(self.current_dir.join("tree-sitter.json"))?; + fn update_file_with(&self, path: &PathBuf, update_fn: F) -> Result<(), UpdateError> + where + F: Fn(&str) -> String, + { + let content = fs::read_to_string(path).map_err(|e| UpdateError::Io(e, path.clone()))?; + let updated_content = update_fn(&content); + fs::write(path, updated_content).map_err(|e| UpdateError::Io(e, path.clone())) + } - let tree_sitter_json = tree_sitter_json - .lines() - .map(|line| { - if line.contains("\"version\":") { - let prefix_index = line.find("\"version\":").unwrap() + "\"version\":".len(); - let start_quote = line[prefix_index..].find('"').unwrap() + prefix_index + 1; - let end_quote = line[start_quote + 1..].find('"').unwrap() + start_quote + 1; + fn update_treesitter_json(&self) -> Result<(), UpdateError> { + let json_path = self.current_dir.join("tree-sitter.json"); + self.update_file_with(&json_path, |content| { + content + .lines() + .map(|line| { + if line.contains("\"version\":") { + let prefix_index = + line.find("\"version\":").unwrap() + "\"version\":".len(); + let start_quote = + line[prefix_index..].find('"').unwrap() + prefix_index + 1; + let end_quote = + line[start_quote + 1..].find('"').unwrap() + start_quote + 1; - format!( - "{}{}{}", - &line[..start_quote], - self.version.as_ref().unwrap(), - &line[end_quote..] - ) - } else { - line.to_string() - } - }) - .collect::>() - .join("\n") - + "\n"; + format!( + "{}{}{}", + &line[..start_quote], + self.version.as_ref().unwrap(), + &line[end_quote..] + ) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + }) + } - fs::write(self.current_dir.join("tree-sitter.json"), tree_sitter_json)?; + fn update_cargo_toml(&self) -> Result<(), UpdateError> { + let cargo_toml_path = self.current_dir.join("Cargo.toml"); + if !cargo_toml_path.exists() { + return Ok(()); + } + + self.update_file_with(&cargo_toml_path, |content| { + content + .lines() + .map(|line| { + if line.starts_with("version =") { + format!("version = \"{}\"", self.version.as_ref().unwrap()) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + })?; Ok(()) } - fn update_cargo_toml(&self) -> Result<()> { - if !self.current_dir.join("Cargo.toml").exists() { - return Ok(()); - } - - let cargo_toml = fs::read_to_string(self.current_dir.join("Cargo.toml"))?; - - let cargo_toml = cargo_toml - .lines() - .map(|line| { - if line.starts_with("version =") { - format!("version = \"{}\"", self.version.as_ref().unwrap()) - } else { - line.to_string() - } - }) - .collect::>() - .join("\n") - + "\n"; - - fs::write(self.current_dir.join("Cargo.toml"), cargo_toml)?; - + fn update_cargo_lock(&self) -> Result<(), UpdateError> { if self.current_dir.join("Cargo.lock").exists() { let Ok(cmd) = Command::new("cargo") .arg("generate-lockfile") @@ -201,8 +219,9 @@ impl Version { if !cmd.status.success() { let stderr = String::from_utf8_lossy(&cmd.stderr); - return Err(anyhow!( - "Failed to run `cargo generate-lockfile`:\n{stderr}" + return Err(UpdateError::Command( + "cargo generate-lockfile", + stderr.to_string(), )); } } @@ -210,37 +229,43 @@ impl Version { Ok(()) } - fn update_package_json(&self) -> Result<()> { - if !self.current_dir.join("package.json").exists() { + fn update_package_json(&self) -> Result<(), UpdateError> { + let package_json_path = self.current_dir.join("package.json"); + if !package_json_path.exists() { return Ok(()); } - let package_json = &fs::read_to_string(self.current_dir.join("package.json"))?; + self.update_file_with(&package_json_path, |content| { + content + .lines() + .map(|line| { + if line.contains("\"version\":") { + let prefix_index = + line.find("\"version\":").unwrap() + "\"version\":".len(); + let start_quote = + line[prefix_index..].find('"').unwrap() + prefix_index + 1; + let end_quote = + line[start_quote + 1..].find('"').unwrap() + start_quote + 1; - let package_json = package_json - .lines() - .map(|line| { - if line.contains("\"version\":") { - let prefix_index = line.find("\"version\":").unwrap() + "\"version\":".len(); - let start_quote = line[prefix_index..].find('"').unwrap() + prefix_index + 1; - let end_quote = line[start_quote + 1..].find('"').unwrap() + start_quote + 1; + format!( + "{}{}{}", + &line[..start_quote], + self.version.as_ref().unwrap(), + &line[end_quote..] + ) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + })?; - format!( - "{}{}{}", - &line[..start_quote], - self.version.as_ref().unwrap(), - &line[end_quote..] - ) - } else { - line.to_string() - } - }) - .collect::>() - .join("\n") - + "\n"; - - fs::write(self.current_dir.join("package.json"), package_json)?; + Ok(()) + } + fn update_package_lock_json(&self) -> Result<(), UpdateError> { if self.current_dir.join("package-lock.json").exists() { let Ok(cmd) = Command::new("npm") .arg("install") @@ -253,82 +278,77 @@ impl Version { if !cmd.status.success() { let stderr = String::from_utf8_lossy(&cmd.stderr); - return Err(anyhow!("Failed to run `npm install`:\n{stderr}")); + return Err(UpdateError::Command("npm install", stderr.to_string())); } } Ok(()) } - fn update_makefile(&self, is_multigrammar: bool) -> Result<()> { - let makefile = if is_multigrammar { - if !self.current_dir.join("common").join("common.mak").exists() { - return Ok(()); - } - - fs::read_to_string(self.current_dir.join("Makefile"))? + fn update_makefile(&self, is_multigrammar: bool) -> Result<(), UpdateError> { + let makefile_path = if is_multigrammar { + self.current_dir.join("common").join("common.mak") } else { - if !self.current_dir.join("Makefile").exists() { - return Ok(()); - } - - fs::read_to_string(self.current_dir.join("Makefile"))? + self.current_dir.join("Makefile") }; - let makefile = makefile - .lines() - .map(|line| { - if line.starts_with("VERSION") { - format!("VERSION := {}", self.version.as_ref().unwrap()) - } else { - line.to_string() - } - }) - .collect::>() - .join("\n") - + "\n"; - - fs::write(self.current_dir.join("Makefile"), makefile)?; + self.update_file_with(&makefile_path, |content| { + content + .lines() + .map(|line| { + if line.starts_with("VERSION") { + format!("VERSION := {}", self.version.as_ref().unwrap()) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + })?; Ok(()) } - fn update_cmakelists_txt(&self) -> Result<()> { - if !self.current_dir.join("CMakeLists.txt").exists() { + fn update_cmakelists_txt(&self) -> Result<(), UpdateError> { + let cmake_lists_path = self.current_dir.join("CMakeLists.txt"); + if !cmake_lists_path.exists() { return Ok(()); } - let cmake = fs::read_to_string(self.current_dir.join("CMakeLists.txt"))?; - - let re = Regex::new(r#"(\s*VERSION\s+)"[0-9]+\.[0-9]+\.[0-9]+""#)?; - let cmake = re.replace(&cmake, format!(r#"$1"{}""#, self.version.as_ref().unwrap())); - - fs::write(self.current_dir.join("CMakeLists.txt"), cmake.as_bytes())?; + self.update_file_with(&cmake_lists_path, |content| { + let re = Regex::new(r#"(\s*VERSION\s+)"[0-9]+\.[0-9]+\.[0-9]+""#) + .expect("Failed to compile regex"); + re.replace( + content, + format!(r#"$1"{}""#, self.version.as_ref().unwrap()), + ) + .to_string() + })?; Ok(()) } - fn update_pyproject_toml(&self) -> Result<()> { - if !self.current_dir.join("pyproject.toml").exists() { + fn update_pyproject_toml(&self) -> Result<(), UpdateError> { + let pyproject_toml_path = self.current_dir.join("pyproject.toml"); + if !pyproject_toml_path.exists() { return Ok(()); } - let pyproject_toml = fs::read_to_string(self.current_dir.join("pyproject.toml"))?; - - let pyproject_toml = pyproject_toml - .lines() - .map(|line| { - if line.starts_with("version =") { - format!("version = \"{}\"", self.version.as_ref().unwrap()) - } else { - line.to_string() - } - }) - .collect::>() - .join("\n") - + "\n"; - - fs::write(self.current_dir.join("pyproject.toml"), pyproject_toml)?; + self.update_file_with(&pyproject_toml_path, |content| { + content + .lines() + .map(|line| { + if line.starts_with("version =") { + format!("version = \"{}\"", self.version.as_ref().unwrap()) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + })?; Ok(()) } From 0d656de98b524a8a20b66e23c08841df4f7e119d Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Thu, 13 Nov 2025 00:09:44 -0500 Subject: [PATCH 060/140] feat(cli): update zig bindings with `version` command --- crates/cli/src/version.rs | 41 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/cli/src/version.rs b/crates/cli/src/version.rs index 9406b58c..757306c7 100644 --- a/crates/cli/src/version.rs +++ b/crates/cli/src/version.rs @@ -135,6 +135,7 @@ impl Version { push_err(self.update_makefile(is_multigrammar)); push_err(self.update_cmakelists_txt()); push_err(self.update_pyproject_toml()); + push_err(self.update_zig_zon()); if errors.is_empty() { Ok(()) @@ -352,4 +353,44 @@ impl Version { Ok(()) } + + fn update_zig_zon(&self) -> Result<(), UpdateError> { + let zig_zon_path = self.current_dir.join("build.zig.zon"); + if !zig_zon_path.exists() { + return Ok(()); + } + + self.update_file_with(&zig_zon_path, |content| { + let zig_version_prefix = ".version ="; + content + .lines() + .map(|line| { + if line + .trim_start_matches(|c: char| c.is_ascii_whitespace()) + .starts_with(zig_version_prefix) + { + let prefix_index = + line.find(zig_version_prefix).unwrap() + zig_version_prefix.len(); + let start_quote = + line[prefix_index..].find('"').unwrap() + prefix_index + 1; + let end_quote = + line[start_quote + 1..].find('"').unwrap() + start_quote + 1; + + format!( + "{}{}{}", + &line[..start_quote], + self.version.as_ref().unwrap(), + &line[end_quote..] + ) + } else { + line.to_string() + } + }) + .collect::>() + .join("\n") + + "\n" + })?; + + Ok(()) + } } From e92a7803eb8835551d48467ba20a139185c61e09 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Thu, 20 Nov 2025 01:10:44 -0500 Subject: [PATCH 061/140] fix(docs): final updates before 0.26.1 - Indicate where xtask looks for wasi-sdk - Indicate where `build --wasm` looks for and downloads wasi-sdk binary to - Mark native runtime as experimental, describe limitations - Note ABI 13 support limitations - Mention that `test --wasm` and `parse --wasm` require `--features=wasm` build --- docs/src/6-contributing.md | 14 ++++++++++++++ docs/src/cli/build.md | 8 +++++++- docs/src/cli/generate.md | 5 +++-- docs/src/cli/parse.md | 2 +- docs/src/cli/test.md | 2 +- docs/src/using-parsers/7-abi-versions.md | 14 ++++++++------ 6 files changed, 34 insertions(+), 11 deletions(-) diff --git a/docs/src/6-contributing.md b/docs/src/6-contributing.md index 001d6337..a99ddc09 100644 --- a/docs/src/6-contributing.md +++ b/docs/src/6-contributing.md @@ -83,6 +83,18 @@ cargo xtask generate-fixtures --wasm cargo xtask test-wasm ``` +#### Wasm Stdlib + +The tree-sitter Wasm stdlib can be built via xtask: + +```sh +cargo xtask build-wasm-stdlib +``` + +This command looks for the [Wasi SDK][wasi_sdk] indicated by the `TREE_SITTER_WASI_SDK_PATH` +environment variable. If you don't have the binary, it can be downloaded from wasi-sdk's [releases][wasi-sdk-releases] +page. + ### Debugging The test script has a number of useful flags. You can list them all by running `cargo xtask test -h`. @@ -220,4 +232,6 @@ and the tree-sitter module is fetched from [here][js url]. This, along with the [pypi]: https://pypi.org [rust]: https://rustup.rs [ts repo]: https://github.com/tree-sitter/tree-sitter +[wasi_sdk]: https://github.com/WebAssembly/wasi-sdk +[wasi-sdk-releases]: https://github.com/WebAssembly/wasi-sdk/releases [web-ts]: https://www.npmjs.com/package/web-tree-sitter diff --git a/docs/src/cli/build.md b/docs/src/cli/build.md index 0ad4a922..6863f926 100644 --- a/docs/src/cli/build.md +++ b/docs/src/cli/build.md @@ -18,7 +18,9 @@ will attempt to build the parser in the current working directory. ### `-w/--wasm` -Compile the parser as a Wasm module. +Compile the parser as a Wasm module. This command looks for the [Wasi SDK][wasi_sdk] indicated by the `TREE_SITTER_WASI_SDK_PATH` +environment variable. If you don't have the binary, the CLI will attempt to download it for you to `/tree-sitter/wasi-sdk/`, where +`` is resolved according to the [XDG base directory][XDG] or Window's [Known_Folder_Locations][Known_Folder]. ### `-o/--output` @@ -36,3 +38,7 @@ in the external scanner does so using their allocator. ### `-0/--debug` Compile the parser with debug flags enabled. This is useful when debugging issues that require a debugger like `gdb` or `lldb`. + +[Known_Folder]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid +[wasi_sdk]: https://github.com/WebAssembly/wasi-sdk +[XDG]: https://specifications.freedesktop.org/basedir/latest/ diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index c373b1e2..6175381f 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -52,8 +52,9 @@ Report conflicts in a JSON format. The path to the JavaScript runtime executable to use when generating the parser. The default is `node`. Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.0, you can -also pass in `native` to use the native QuickJS runtime that comes bundled with the CLI. This avoids -the dependency on a JavaScript runtime entirely. +also pass in `native` to use the experimental native QuickJS runtime that comes bundled with the CLI. +This avoids the dependency on a JavaScript runtime entirely. The native QuickJS runtime is compatible +with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base grammars, the native runtime can be used *after* running `npm install`. ### `--disable-optimization` diff --git a/docs/src/cli/parse.md b/docs/src/cli/parse.md index 178d97b5..f18c2edb 100644 --- a/docs/src/cli/parse.md +++ b/docs/src/cli/parse.md @@ -45,7 +45,7 @@ The graphs are constructed with [graphviz dot][dot], and the output is written t ### `--wasm` -Compile and run the parser as a Wasm module. +Compile and run the parser as a Wasm module (only if the tree-sitter CLI was built with `--features=wasm`). ### `--dot` diff --git a/docs/src/cli/test.md b/docs/src/cli/test.md index 401bcd39..f8b8a02d 100644 --- a/docs/src/cli/test.md +++ b/docs/src/cli/test.md @@ -55,7 +55,7 @@ The graphs are constructed with [graphviz dot][dot], and the output is written t ### `--wasm` -Compile and run the parser as a Wasm module. +Compile and run the parser as a Wasm module (only if the tree-sitter CLI was built with `--features=wasm`). ### `--open-log` diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md index 30b6dcdf..34347938 100644 --- a/docs/src/using-parsers/7-abi-versions.md +++ b/docs/src/using-parsers/7-abi-versions.md @@ -1,8 +1,9 @@ # ABI versions -Parsers generated with tree-sitter have an associated ABI version. This version establishes hard compatibility boundaries between the generated parser and the tree-sitter library. +Parsers generated with tree-sitter have an associated ABI version, which establishes hard compatibility boundaries +between the generated parser and the tree-sitter library. -A given version of the tree-sitter library is only able to load parsers which have certain ABI versions: +A given version of the tree-sitter library is only able to load parsers generated with supported ABI versions: | tree-sitter version | Min parser ABI version | Max parser ABI version | |---------------------|------------------------|------------------------| @@ -14,7 +15,8 @@ A given version of the tree-sitter library is only able to load parsers which ha | >=0.20.3, <=0.24 | 13 | 14 | | >=0.25 | 13 | 15 | -By default, the tree-sitter CLI will generate parsers using the latest available ABI for that version. Grammar authors can specify an older ABI (within the constraints _of the CLI_, which may be stricter than the library!) via the `--abi` option to the `generate` command: -``` -tree-sitter generate --abi= -``` +By default, the tree-sitter CLI will generate parsers using the latest available ABI for that version, but an older ABI (supported by the CLI) can be selected by passing the [`--abi` option][abi_option] to the `generate` command. + +Note that the ABI version range supported by the CLI can be smaller than for the library: When a new ABI version is released, older versions will be phased out over a deprecation period, which starts with no longer being able to generate parsers with the oldest ABI version. + +[abi_option]: ../cli/generate.md#--abi-version From 5880df47e26a500022b5bbe89832e039ab1d1049 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:19:08 +0000 Subject: [PATCH 062/140] ci: bump actions/checkout from 5 to 6 in the actions group Bumps the actions group with 1 update: [actions/checkout](https://github.com/actions/checkout). Updates `actions/checkout` from 5 to 6 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/backport.yml | 2 +- .github/workflows/bindgen.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/ci.yml | 2 +- .github/workflows/docs.yml | 2 +- .github/workflows/nvim_ts.yml | 4 ++-- .github/workflows/release.yml | 6 +++--- .github/workflows/response.yml | 4 ++-- .github/workflows/reviewers_remove.yml | 2 +- .github/workflows/sanitize.yml | 2 +- .github/workflows/spam.yml | 2 +- .github/workflows/wasm_exports.yml | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 83992a3f..e747a012 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Create app token uses: actions/create-github-app-token@v2 diff --git a/.github/workflows/bindgen.yml b/.github/workflows/bindgen.yml index deee3757..1b0d20af 100644 --- a/.github/workflows/bindgen.yml +++ b/.github/workflows/bindgen.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up stable Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 38fd72af..2a9dd910 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,7 +68,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up cross-compilation if: matrix.cross diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f10394b2..97a7e378 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up stable Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index fb23b271..0e4baebf 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 diff --git a/.github/workflows/nvim_ts.yml b/.github/workflows/nvim_ts.yml index 9dea5304..88e3371f 100644 --- a/.github/workflows/nvim_ts.yml +++ b/.github/workflows/nvim_ts.yml @@ -28,9 +28,9 @@ jobs: NVIM: ${{ matrix.os == 'windows-latest' && 'nvim-win64\\bin\\nvim.exe' || 'nvim' }} NVIM_TS_DIR: nvim-treesitter steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: repository: nvim-treesitter/nvim-treesitter path: ${{ env.NVIM_TS_DIR }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e89b0035..11b0d27b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: contents: write steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Download build artifacts uses: actions/download-artifact@v6 @@ -61,7 +61,7 @@ jobs: needs: release steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 @@ -81,7 +81,7 @@ jobs: directory: [crates/cli/npm, lib/binding_web] steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up Node uses: actions/setup-node@v6 diff --git a/.github/workflows/response.yml b/.github/workflows/response.yml index 31e039c8..54dd2021 100644 --- a/.github/workflows/response.yml +++ b/.github/workflows/response.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout script - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: sparse-checkout: .github/scripts/close_unresponsive.js sparse-checkout-cone-mode: false @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout script - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: sparse-checkout: .github/scripts/remove_response_label.js sparse-checkout-cone-mode: false diff --git a/.github/workflows/reviewers_remove.yml b/.github/workflows/reviewers_remove.yml index 94e8c058..3a389ed4 100644 --- a/.github/workflows/reviewers_remove.yml +++ b/.github/workflows/reviewers_remove.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout script - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: sparse-checkout: .github/scripts/reviewers_remove.js sparse-checkout-cone-mode: false diff --git a/.github/workflows/sanitize.yml b/.github/workflows/sanitize.yml index 2239c673..2f8851dc 100644 --- a/.github/workflows/sanitize.yml +++ b/.github/workflows/sanitize.yml @@ -15,7 +15,7 @@ jobs: TREE_SITTER: ${{ github.workspace }}/target/release/tree-sitter steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Install UBSAN library run: sudo apt-get update -y && sudo apt-get install -y libubsan1 diff --git a/.github/workflows/spam.yml b/.github/workflows/spam.yml index ce3d5e1d..eb1d4a46 100644 --- a/.github/workflows/spam.yml +++ b/.github/workflows/spam.yml @@ -16,7 +16,7 @@ jobs: if: github.event.label.name == 'spam' steps: - name: Checkout script - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: sparse-checkout: .github/scripts/close_spam.js sparse-checkout-cone-mode: false diff --git a/.github/workflows/wasm_exports.yml b/.github/workflows/wasm_exports.yml index d04e1052..af48cf8a 100644 --- a/.github/workflows/wasm_exports.yml +++ b/.github/workflows/wasm_exports.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Set up stable Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 From de92a9b4c92b2bf329293070a2ccc87b04f13bc3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 21:19:40 +0000 Subject: [PATCH 063/140] build(deps): bump the cargo group with 4 updates Bumps the cargo group with 4 updates: [cc](https://github.com/rust-lang/cc-rs), [clap](https://github.com/clap-rs/clap), [clap_complete](https://github.com/clap-rs/clap) and [indexmap](https://github.com/indexmap-rs/indexmap). Updates `cc` from 1.2.46 to 1.2.47 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.46...cc-v1.2.47) Updates `clap` from 4.5.51 to 4.5.53 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.51...clap_complete-v4.5.53) Updates `clap_complete` from 4.5.60 to 4.5.61 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.60...clap_complete-v4.5.61) Updates `indexmap` from 2.12.0 to 2.12.1 - [Changelog](https://github.com/indexmap-rs/indexmap/blob/main/RELEASES.md) - [Commits](https://github.com/indexmap-rs/indexmap/compare/2.12.0...2.12.1) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.47 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap dependency-version: 4.5.53 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-version: 4.5.61 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: indexmap dependency-version: 2.12.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 28 ++++++++++++++-------------- Cargo.toml | 8 ++++---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e95e3a6..cf5962b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.46" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ "find-msvc-tools", "shlex", @@ -241,9 +241,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.51" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", "clap_derive", @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.51" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstream", "anstyle", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.60" +version = "4.5.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" +checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992" dependencies = [ "clap", ] @@ -775,9 +775,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ "allocator-api2", "equivalent", @@ -915,12 +915,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -1541,7 +1541,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bccb7121a123865c8ace4dea42e7ed84d78b90cbaf4ca32c59849d8d210c9672" dependencies = [ - "hashbrown 0.16.0", + "hashbrown 0.16.1", "phf", "relative-path", "rquickjs-sys", diff --git a/Cargo.toml b/Cargo.toml index cc3520fe..c5438b7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,8 +106,8 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.46" -clap = { version = "4.5.51", features = [ +cc = "1.2.47" +clap = { version = "4.5.53", features = [ "cargo", "derive", "env", @@ -115,7 +115,7 @@ clap = { version = "4.5.51", features = [ "string", "unstable-styles", ] } -clap_complete = "4.5.60" +clap_complete = "4.5.61" clap_complete_nushell = "4.5.10" crc32fast = "1.5.0" ctor = "0.2.9" @@ -126,7 +126,7 @@ fs4 = "0.12.0" glob = "0.3.3" heck = "0.5.0" html-escape = "0.2.13" -indexmap = "2.11.4" +indexmap = "2.12.1" indoc = "2.0.6" libloading = "0.9.0" log = { version = "0.4.28", features = ["std"] } From 882aa867ebe213f04d3c41e415648c56f912f250 Mon Sep 17 00:00:00 2001 From: skewb1k Date: Mon, 24 Nov 2025 22:41:04 +0300 Subject: [PATCH 064/140] docs: remove manual bindings update steps for scanner Since 66dab20462fcaf2b7ffe77a46af16419a1aded2a, bindings automatically detect external scanner, making the instructions for manual updating outdated. Avoids confusion about missing commented lines in Rust bindings. --- docs/src/creating-parsers/4-external-scanners.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/src/creating-parsers/4-external-scanners.md b/docs/src/creating-parsers/4-external-scanners.md index 7d63d04b..05268df7 100644 --- a/docs/src/creating-parsers/4-external-scanners.md +++ b/docs/src/creating-parsers/4-external-scanners.md @@ -23,10 +23,7 @@ grammar({ }); ``` -Then, add another C source file to your project. Its path must be src/scanner.c for the CLI to recognize it. Be sure to add -this file to the sources section of your `binding.gyp` file so that it will be included when your project is compiled by -Node.js and uncomment the appropriate block in your bindings/rust/build.rs file so that it will be included in your Rust -crate. +Then, add another C source file to your project. Its path must be src/scanner.c for the CLI to recognize it. In this new source file, define an [`enum`][enum] type containing the names of all of your external tokens. The ordering of this enum must match the order in your grammar's `externals` array; the actual names do not matter. From d64b863030ff4235181a81d727695562da2c412a Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 22 Nov 2025 12:02:46 +0100 Subject: [PATCH 065/140] build(deps): bump wasi-sdk to v29 --- crates/loader/src/loader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 28618be6..3234abee 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1441,9 +1441,9 @@ impl Loader { return Err(LoaderError::WasiSDKPlatform); }; - let sdk_filename = format!("wasi-sdk-25.0-{arch_os}.tar.gz"); + let sdk_filename = format!("wasi-sdk-29.0-{arch_os}.tar.gz"); let sdk_url = format!( - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-25/{sdk_filename}", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/{sdk_filename}", ); info!("Downloading wasi-sdk from {sdk_url}..."); From 829733a35e24577238a81851815db199d11f7ed1 Mon Sep 17 00:00:00 2001 From: Riley Bruins Date: Sat, 22 Nov 2025 17:36:37 -0800 Subject: [PATCH 066/140] fix(query): prevent infinite loop with `+` and `?` quantifiers **Problem:** A query with a `?` quantifier followed by a `+` quantifier would hang at 100% CPU usage while iterating through a tree, regardless of the source content. **Solution:** Collect all quantifiers in one step, and then add the required repeat/optional step logic *after* we have determined the composite quantifier we need to use for the current step. --- crates/cli/src/tests/query_test.rs | 20 ++++++++++ lib/src/query.c | 64 +++++++++++++++++------------- 2 files changed, 57 insertions(+), 27 deletions(-) diff --git a/crates/cli/src/tests/query_test.rs b/crates/cli/src/tests/query_test.rs index b59a1f42..4eb74f6c 100644 --- a/crates/cli/src/tests/query_test.rs +++ b/crates/cli/src/tests/query_test.rs @@ -5032,6 +5032,26 @@ fn test_query_quantified_captures() { ("comment.documentation", "// quuz"), ], }, + Row { + description: "multiple quantifiers should not hang query parsing", + language: get_language("c"), + code: indoc! {" + // foo + // bar + // baz + "}, + pattern: r" + ((comment) ?+ @comment) + ", + // This should be identical to the `*` quantifier. + captures: &[ + ("comment", "// foo"), + ("comment", "// foo"), + ("comment", "// foo"), + ("comment", "// bar"), + ("comment", "// baz"), + ], + }, ]; allocations::record(|| { diff --git a/lib/src/query.c b/lib/src/query.c index 56e32873..d1695549 100644 --- a/lib/src/query.c +++ b/lib/src/query.c @@ -2736,12 +2736,6 @@ static TSQueryError ts_query__parse_pattern( stream_advance(stream); stream_skip_whitespace(stream); - - QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false); - repeat_step.alternative_index = starting_step_index; - repeat_step.is_pass_through = true; - repeat_step.alternative_is_immediate = true; - array_push(&self->steps, repeat_step); } // Parse the zero-or-more repetition operator. @@ -2750,21 +2744,6 @@ static TSQueryError ts_query__parse_pattern( stream_advance(stream); stream_skip_whitespace(stream); - - QueryStep repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false); - repeat_step.alternative_index = starting_step_index; - repeat_step.is_pass_through = true; - repeat_step.alternative_is_immediate = true; - array_push(&self->steps, repeat_step); - - // Stop when `step->alternative_index` is `NONE` or it points to - // `repeat_step` or beyond. Note that having just been pushed, - // `repeat_step` occupies slot `self->steps.size - 1`. - QueryStep *step = array_get(&self->steps, starting_step_index); - while (step->alternative_index != NONE && step->alternative_index < self->steps.size - 1) { - step = array_get(&self->steps, step->alternative_index); - } - step->alternative_index = self->steps.size; } // Parse the optional operator. @@ -2773,12 +2752,6 @@ static TSQueryError ts_query__parse_pattern( stream_advance(stream); stream_skip_whitespace(stream); - - QueryStep *step = array_get(&self->steps, starting_step_index); - while (step->alternative_index != NONE && step->alternative_index < self->steps.size) { - step = array_get(&self->steps, step->alternative_index); - } - step->alternative_index = self->steps.size; } // Parse an '@'-prefixed capture pattern @@ -2822,6 +2795,43 @@ static TSQueryError ts_query__parse_pattern( } } + QueryStep repeat_step; + QueryStep *step; + switch (quantifier) { + case TSQuantifierOneOrMore: + repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false); + repeat_step.alternative_index = starting_step_index; + repeat_step.is_pass_through = true; + repeat_step.alternative_is_immediate = true; + array_push(&self->steps, repeat_step); + break; + case TSQuantifierZeroOrMore: + repeat_step = query_step__new(WILDCARD_SYMBOL, depth, false); + repeat_step.alternative_index = starting_step_index; + repeat_step.is_pass_through = true; + repeat_step.alternative_is_immediate = true; + array_push(&self->steps, repeat_step); + + // Stop when `step->alternative_index` is `NONE` or it points to + // `repeat_step` or beyond. Note that having just been pushed, + // `repeat_step` occupies slot `self->steps.size - 1`. + step = array_get(&self->steps, starting_step_index); + while (step->alternative_index != NONE && step->alternative_index < self->steps.size - 1) { + step = array_get(&self->steps, step->alternative_index); + } + step->alternative_index = self->steps.size; + break; + case TSQuantifierZeroOrOne: + step = array_get(&self->steps, starting_step_index); + while (step->alternative_index != NONE && step->alternative_index < self->steps.size) { + step = array_get(&self->steps, step->alternative_index); + } + step->alternative_index = self->steps.size; + break; + default: + break; + } + capture_quantifiers_mul(capture_quantifiers, quantifier); return 0; From f6d17fdb040636d84548e5da96f06c4c8d72eefd Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Sat, 22 Nov 2025 00:00:21 +0100 Subject: [PATCH 067/140] fix(node): bump tree-sitter dep to 0.25 in bindings Sets the dependency `tree-sitter` to version 0.25 in the NodeJS bindings generated by default, so that `npm run test` passes. --- crates/cli/src/init.rs | 2 +- crates/cli/src/templates/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 0164cc8f..6d821f04 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -337,7 +337,7 @@ pub fn generate_grammar_files( "tree-sitter-cli":"#}, indoc! {r#" "prebuildify": "^6.0.1", - "tree-sitter": "^0.22.4", + "tree-sitter": "^0.25.0", "tree-sitter-cli":"#}, ); if !contents.contains("module") { diff --git a/crates/cli/src/templates/package.json b/crates/cli/src/templates/package.json index 95f5b638..d9dbbd33 100644 --- a/crates/cli/src/templates/package.json +++ b/crates/cli/src/templates/package.json @@ -38,11 +38,11 @@ }, "devDependencies": { "prebuildify": "^6.0.1", - "tree-sitter": "^0.22.4", + "tree-sitter": "^0.25.0", "tree-sitter-cli": "^CLI_VERSION" }, "peerDependencies": { - "tree-sitter": "^0.22.4" + "tree-sitter": "^0.25.0" }, "peerDependenciesMeta": { "tree-sitter": { From c1a0f4878103b3db6dbb889e5f88864207c58b4e Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 23 Nov 2025 01:39:56 -0500 Subject: [PATCH 068/140] fix(cli): return error if `--wasm` flag is passed when the wasm feature is disabled This applies to the `parse` and `test` commands, but not `build` as it doesn't require the wasm feature. Also, hide the `--wasm` options if from the `--help` output if the feature is disabled. --- crates/cli/src/main.rs | 44 ++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 3f83bf5f..e97c9cce 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -223,7 +223,7 @@ struct Parse { #[arg(long, short = 'D')] pub debug_graph: bool, /// Compile parsers to Wasm instead of native dynamic libraries - #[arg(long)] + #[arg(long, hide = cfg!(not(feature = "wasm")))] pub wasm: bool, /// Output the parse data with graphviz dot #[arg(long = "dot")] @@ -323,7 +323,7 @@ struct Test { #[arg(long, short = 'D')] pub debug_graph: bool, /// Compile parsers to Wasm instead of native dynamic libraries - #[arg(long)] + #[arg(long, hide = cfg!(not(feature = "wasm")))] pub wasm: bool, /// Open `log.html` in the default browser, if `--debug-graph` is supplied #[arg(long)] @@ -589,6 +589,20 @@ pub enum Shell { Nushell, } +/// Complete `action` if the wasm feature is enabled, otherwise return an error +macro_rules! checked_wasm { + ($action:block) => { + #[cfg(feature = "wasm")] + { + $action + } + #[cfg(not(feature = "wasm"))] + { + Err(anyhow!("--wasm flag specified, but this build of tree-sitter-cli does not include the wasm feature"))?; + } + }; +} + impl InitConfig { fn run() -> Result<()> { if let Ok(Some(config_path)) = Config::find_config_file() { @@ -1005,13 +1019,14 @@ impl Parse { loader.debug_build(self.debug_build); loader.force_rebuild(self.rebuild || self.grammar_path.is_some()); - #[cfg(feature = "wasm")] if self.wasm { - let engine = tree_sitter::wasmtime::Engine::default(); - parser - .set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap()) - .unwrap(); - loader.use_wasm(&engine); + checked_wasm!({ + let engine = tree_sitter::wasmtime::Engine::default(); + parser + .set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap()) + .unwrap(); + loader.use_wasm(&engine); + }); } let timeout = self.timeout.unwrap_or_default(); @@ -1215,13 +1230,14 @@ impl Test { let mut parser = Parser::new(); - #[cfg(feature = "wasm")] if self.wasm { - let engine = tree_sitter::wasmtime::Engine::default(); - parser - .set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap()) - .unwrap(); - loader.use_wasm(&engine); + checked_wasm!({ + let engine = tree_sitter::wasmtime::Engine::default(); + parser + .set_wasm_store(tree_sitter::WasmStore::new(&engine).unwrap()) + .unwrap(); + loader.use_wasm(&engine); + }); } if self.lib_path.is_none() && self.lang_name.is_some() { From dcef0cc0eec9da28a5586b92b8e69bd07d1a2fac Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 23 Nov 2025 02:58:05 -0500 Subject: [PATCH 069/140] fix(cli): correct query match limit warning condition --- crates/cli/src/query.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/query.rs b/crates/cli/src/query.rs index c58e5f34..fec85bd2 100644 --- a/crates/cli/src/query.rs +++ b/crates/cli/src/query.rs @@ -119,7 +119,7 @@ pub fn query_file_at_path( } } } - if !query_cursor.did_exceed_match_limit() { + if query_cursor.did_exceed_match_limit() { warn!("Query exceeded maximum number of in-progress captures!"); } if should_test { From 14b4708018ee7fe3236e1d965ba589530a3374b6 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sun, 23 Nov 2025 01:23:16 +0200 Subject: [PATCH 070/140] fix(loader): write Wasm lib directly to lib dir Problem: `fs::rename` fails if the parser directory and the Tree-sitter library directory are on different file systems. Solution: Write the library file directly to the final directory. --- crates/loader/src/loader.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 3234abee..ddfbc617 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1306,11 +1306,10 @@ impl Loader { ) -> LoaderResult<()> { let clang_executable = self.ensure_wasi_sdk_exists()?; - let output_name = "output.wasm"; let mut command = Command::new(&clang_executable); command.current_dir(src_path).args([ "-o", - output_name, + output_path.to_str().unwrap(), "-fPIC", "-shared", if self.debug_build { "-g" } else { "-Os" }, @@ -1337,10 +1336,6 @@ impl Loader { )); } - let current_path = src_path.join(output_name); - fs::rename(¤t_path, output_path) - .map_err(|e| LoaderError::IO(IoError::new(e, Some(current_path.as_path()))))?; - Ok(()) } From df8b62fc509d45e2ebbfa1574a9818beca19eec5 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Wed, 26 Nov 2025 02:40:19 -0500 Subject: [PATCH 071/140] feat(xtask): bring wasi-sdk treatment up to par with the loader The loader package's `ensure_wasi_sdk_exists` private method checks for the wasi-sdk, fetching it if it can't be found. This logic was re-implemented in xtask for `build-wasm-stdlib`, but without the fetching functionality. We can have nice things in xtask too! Rather than make this function a public member of `tree-sitter-loader`, we just re-implement and leave a nice comment asking people to keep the two in sync. --- Cargo.lock | 2 + crates/loader/src/loader.rs | 11 ++- crates/loader/wasi-sdk-version | 1 + crates/xtask/Cargo.toml | 2 + crates/xtask/src/build_wasm.rs | 147 +++++++++++++++++++++++++++++---- 5 files changed, 144 insertions(+), 19 deletions(-) create mode 100644 crates/loader/wasi-sdk-version diff --git a/Cargo.lock b/Cargo.lock index cf5962b0..111b9d46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2812,6 +2812,7 @@ dependencies = [ "anyhow", "bindgen", "clap", + "etcetera", "indoc", "notify", "notify-debouncer-full", @@ -2820,6 +2821,7 @@ dependencies = [ "semver", "serde_json", "tree-sitter-cli", + "tree-sitter-loader", ] [[package]] diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index ddfbc617..00108506 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -41,6 +41,8 @@ use tree_sitter_tags::{Error as TagsError, TagsConfiguration}; static GRAMMAR_NAME_REGEX: LazyLock = LazyLock::new(|| Regex::new(r#""name":\s*"(.*?)""#).unwrap()); +const WASI_SDK_VERSION: &str = include_str!("../wasi-sdk-version").trim_ascii(); + pub type LoaderResult = Result; #[derive(Debug, Error)] @@ -223,7 +225,7 @@ impl std::fmt::Display for ScannerSymbolError { pub struct WasiSDKClangError { pub wasi_sdk_dir: String, pub possible_executables: Vec<&'static str>, - download: bool, + pub download: bool, } impl std::fmt::Display for WasiSDKClangError { @@ -1436,9 +1438,12 @@ impl Loader { return Err(LoaderError::WasiSDKPlatform); }; - let sdk_filename = format!("wasi-sdk-29.0-{arch_os}.tar.gz"); + let sdk_filename = format!("wasi-sdk-{WASI_SDK_VERSION}-{arch_os}.tar.gz"); + let wasi_sdk_major_version = WASI_SDK_VERSION + .trim_end_matches(char::is_numeric) // trim minor version... + .trim_end_matches('.'); // ...and '.' separator let sdk_url = format!( - "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-29/{sdk_filename}", + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-{wasi_sdk_major_version}/{sdk_filename}", ); info!("Downloading wasi-sdk from {sdk_url}..."); diff --git a/crates/loader/wasi-sdk-version b/crates/loader/wasi-sdk-version new file mode 100644 index 00000000..231f5c77 --- /dev/null +++ b/crates/loader/wasi-sdk-version @@ -0,0 +1 @@ +29.0 diff --git a/crates/xtask/Cargo.toml b/crates/xtask/Cargo.toml index 90134d03..17972317 100644 --- a/crates/xtask/Cargo.toml +++ b/crates/xtask/Cargo.toml @@ -19,11 +19,13 @@ anstyle.workspace = true anyhow.workspace = true bindgen = { version = "0.72.0" } clap.workspace = true +etcetera.workspace = true indoc.workspace = true regex.workspace = true schemars.workspace = true semver.workspace = true serde_json.workspace = true tree-sitter-cli = { path = "../cli/" } +tree-sitter-loader = { path = "../loader/" } notify = "8.2.0" notify-debouncer-full = "0.6.0" diff --git a/crates/xtask/src/build_wasm.rs b/crates/xtask/src/build_wasm.rs index 8b1f78d5..183718a6 100644 --- a/crates/xtask/src/build_wasm.rs +++ b/crates/xtask/src/build_wasm.rs @@ -8,13 +8,15 @@ use std::{ time::Duration, }; -use anyhow::{anyhow, Error, Result}; +use anyhow::{anyhow, Result}; +use etcetera::BaseStrategy as _; use indoc::indoc; use notify::{ event::{AccessKind, AccessMode}, EventKind, RecursiveMode, }; use notify_debouncer_full::new_debouncer; +use tree_sitter_loader::{IoError, LoaderError, WasiSDKClangError}; use crate::{ bail_on_err, embed_sources::embed_sources_in_map, watch_wasm, BuildWasm, EMSCRIPTEN_TAG, @@ -50,6 +52,8 @@ const EXPORTED_RUNTIME_METHODS: [&str; 20] = [ "LE_HEAP_STORE_I64", ]; +const WASI_SDK_VERSION: &str = include_str!("../../loader/wasi-sdk-version").trim_ascii(); + pub fn run_wasm(args: &BuildWasm) -> Result<()> { let mut emscripten_flags = if args.debug { vec!["-O0", "--minify", "0"] @@ -309,9 +313,17 @@ fn build_wasm(cmd: &mut Command, edit_tsd: bool) -> Result<()> { Ok(()) } -/// This gets the path to the `clang` binary in the WASI SDK specified by the -/// `TREE_SITTER_WASI_SDK_PATH` environment variable. -fn get_wasi_binary() -> Result { +/// This ensures that the wasi-sdk is available, downloading and extracting it if necessary, +/// and returns the path to the `clang` executable. +/// +/// If `TREE_SITTER_WASI_SDK_PATH` is set, it will use that path to look for the clang executable. +/// +/// Note that this is just a minimially modified version of +/// `tree_sitter_loader::ensure_wasi_sdk_exists`. In the loader, this functionality is implemented +/// as a private method of `Loader`. Rather than add this to the public API, we just +/// re-implement it. Any fixes and/or modifications made to the loader's copy should be reflected +/// here. +pub fn ensure_wasi_sdk_exists() -> Result { let possible_executables = if cfg!(windows) { vec![ "clang.exe", @@ -332,19 +344,122 @@ fn get_wasi_binary() -> Result { } } - return Err(anyhow!( - "TREE_SITTER_WASI_SDK_PATH is set to '{}', but no clang executable found in 'bin/' directory. \ - Looked for: {}", - wasi_sdk_dir.display(), - possible_executables.join(", ") - )); + Err(LoaderError::WasiSDKClang(WasiSDKClangError { + wasi_sdk_dir: wasi_sdk_dir.to_string_lossy().to_string(), + possible_executables: possible_executables.clone(), + download: false, + }))?; } - Err(anyhow!( - "TREE_SITTER_WASI_SDK_PATH environment variable is not set. \ - Please install the WASI SDK from https://github.com/WebAssembly/wasi-sdk/releases \ - and set TREE_SITTER_WASI_SDK_PATH to the installation directory." - )) + let cache_dir = etcetera::choose_base_strategy()? + .cache_dir() + .join("tree-sitter"); + fs::create_dir_all(&cache_dir).map_err(|error| { + LoaderError::IO(IoError { + error, + path: Some(cache_dir.to_string_lossy().to_string()), + }) + })?; + + let wasi_sdk_dir = cache_dir.join("wasi-sdk"); + + for exe in &possible_executables { + let clang_exe = wasi_sdk_dir.join("bin").join(exe); + if clang_exe.exists() { + return Ok(clang_exe); + } + } + + fs::create_dir_all(&wasi_sdk_dir).map_err(|error| { + LoaderError::IO(IoError { + error, + path: Some(wasi_sdk_dir.to_string_lossy().to_string()), + }) + })?; + + let arch_os = if cfg!(target_os = "macos") { + if cfg!(target_arch = "aarch64") { + "arm64-macos" + } else { + "x86_64-macos" + } + } else if cfg!(target_os = "windows") { + if cfg!(target_arch = "aarch64") { + "arm64-windows" + } else { + "x86_64-windows" + } + } else if cfg!(target_os = "linux") { + if cfg!(target_arch = "aarch64") { + "arm64-linux" + } else { + "x86_64-linux" + } + } else { + Err(LoaderError::WasiSDKPlatform)? + }; + + let sdk_filename = format!("wasi-sdk-{WASI_SDK_VERSION}-{arch_os}.tar.gz"); + let wasi_sdk_major_version = WASI_SDK_VERSION + .trim_end_matches(char::is_numeric) // trim minor version... + .trim_end_matches('.'); // ...and '.' separator + let sdk_url = format!( + "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-{wasi_sdk_major_version}/{sdk_filename}", + ); + + eprintln!("Downloading wasi-sdk from {sdk_url}..."); + let temp_tar_path = cache_dir.join(sdk_filename); + + let status = Command::new("curl") + .arg("-f") + .arg("-L") + .arg("-o") + .arg(&temp_tar_path) + .arg(&sdk_url) + .status() + .map_err(|e| LoaderError::Curl(sdk_url.clone(), e))?; + + if !status.success() { + Err(LoaderError::WasiSDKDownload(sdk_url))?; + } + + eprintln!("Extracting wasi-sdk to {}...", wasi_sdk_dir.display()); + extract_tar_gz_with_strip(&temp_tar_path, &wasi_sdk_dir)?; + + fs::remove_file(temp_tar_path).ok(); + for exe in &possible_executables { + let clang_exe = wasi_sdk_dir.join("bin").join(exe); + if clang_exe.exists() { + return Ok(clang_exe); + } + } + + Err(LoaderError::WasiSDKClang(WasiSDKClangError { + wasi_sdk_dir: wasi_sdk_dir.to_string_lossy().to_string(), + possible_executables, + download: true, + }))? +} + +/// Extracts a tar.gz archive with `tar`, stripping the first path component. +fn extract_tar_gz_with_strip(archive_path: &Path, destination: &Path) -> Result<()> { + let status = Command::new("tar") + .arg("-xzf") + .arg(archive_path) + .arg("--strip-components=1") + .arg("-C") + .arg(destination) + .status() + .map_err(|e| LoaderError::Tar(archive_path.to_string_lossy().to_string(), e))?; + + if !status.success() { + Err(LoaderError::Extraction( + archive_path.to_string_lossy().to_string(), + destination.to_string_lossy().to_string(), + ))?; + } + + Ok(()) } pub fn run_wasm_stdlib() -> Result<()> { @@ -353,7 +468,7 @@ pub fn run_wasm_stdlib() -> Result<()> { .map(|line| format!("-Wl,--export={}", &line[1..line.len() - 2])) .collect::>(); - let clang_exe = get_wasi_binary()?; + let clang_exe = ensure_wasi_sdk_exists()?; let output = Command::new(&clang_exe) .args([ From 3f85f65e3f3bbd47d10eb2e227294ccee7948719 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 00:00:10 +0000 Subject: [PATCH 072/140] build(deps): bump the cargo group with 2 updates Bumps the cargo group with 2 updates: [cc](https://github.com/rust-lang/cc-rs) and [wasmparser](https://github.com/bytecodealliance/wasm-tools). Updates `cc` from 1.2.47 to 1.2.48 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.47...cc-v1.2.48) Updates `wasmparser` from 0.241.2 to 0.242.0 - [Release notes](https://github.com/bytecodealliance/wasm-tools/releases) - [Commits](https://github.com/bytecodealliance/wasm-tools/commits) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.48 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: wasmparser dependency-version: 0.242.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 111b9d46..b7b45028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.47" +version = "1.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" dependencies = [ "find-msvc-tools", "shlex", @@ -2027,7 +2027,7 @@ dependencies = [ "tree-sitter-tests-proc-macro", "unindent", "walkdir", - "wasmparser 0.241.2", + "wasmparser 0.242.0", "webbrowser", "widestring", ] @@ -2271,9 +2271,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.241.2" +version = "0.242.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46d90019b1afd4b808c263e428de644f3003691f243387d30d673211ee0cb8e8" +checksum = "ed3c6e611f4cd748d85c767815823b777dc56afca793fcda27beae4e85028849" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", diff --git a/Cargo.toml b/Cargo.toml index c5438b7a..71cf0253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.47" +cc = "1.2.48" clap = { version = "4.5.53", features = [ "cargo", "derive", @@ -150,7 +150,7 @@ tiny_http = "0.12.0" topological-sort = "0.2.2" unindent = "0.2.4" walkdir = "2.5.0" -wasmparser = "0.241.2" +wasmparser = "0.242.0" webbrowser = "1.0.5" tree-sitter = { version = "0.26.0", path = "./lib" } From 7d3feeae9a7e1d543a94747b3de8f07ee1128daa Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 2 Oct 2025 17:21:50 +0200 Subject: [PATCH 073/140] cli: Do not validate UTF-8 boundaries when query results are not being tested Co-authored-by: Kirill Bulatov Co-authored-by: dino Co-authored-by: Max Brunsfeld Co-authored-by: John Tur --- crates/cli/src/query.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/cli/src/query.rs b/crates/cli/src/query.rs index fec85bd2..7343049f 100644 --- a/crates/cli/src/query.rs +++ b/crates/cli/src/query.rs @@ -80,11 +80,13 @@ pub fn query_file_at_path( capture.node.utf8_text(&source_code).unwrap_or("") )?; } - results.push(query_testing::CaptureInfo { - name: (*capture_name).to_string(), - start: to_utf8_point(capture.node.start_position(), source_code.as_slice()), - end: to_utf8_point(capture.node.end_position(), source_code.as_slice()), - }); + if should_test { + results.push(query_testing::CaptureInfo { + name: (*capture_name).to_string(), + start: to_utf8_point(capture.node.start_position(), source_code.as_slice()), + end: to_utf8_point(capture.node.end_position(), source_code.as_slice()), + }); + } } } else { let mut matches = query_cursor.matches(&query, tree.root_node(), source_code.as_slice()); @@ -111,11 +113,13 @@ pub fn query_file_at_path( )?; } } - results.push(query_testing::CaptureInfo { - name: (*capture_name).to_string(), - start: to_utf8_point(capture.node.start_position(), source_code.as_slice()), - end: to_utf8_point(capture.node.end_position(), source_code.as_slice()), - }); + if should_test { + results.push(query_testing::CaptureInfo { + name: (*capture_name).to_string(), + start: to_utf8_point(capture.node.start_position(), source_code.as_slice()), + end: to_utf8_point(capture.node.end_position(), source_code.as_slice()), + }); + } } } } From c0b1710f8a92b6cd7aded5301301979746da8bc7 Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Thu, 2 Oct 2025 19:02:05 +0200 Subject: [PATCH 074/140] Add containing range APIs to query cursor Co-authored-by: Kirill Bulatov Co-authored-by: Max Brunsfeld Co-authored-by: dino Co-authored-by: John Tur Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Co-authored-by: dino Co-authored-by: Will Lillis --- crates/cli/src/main.rs | 26 ++++++ crates/cli/src/query.rs | 8 ++ crates/cli/src/tests/query_test.rs | 58 ++++++++++++ crates/xtask/src/check_wasm_exports.rs | 4 +- docs/src/cli/query.md | 10 +++ lib/binding_rust/bindings.rs | 16 ++++ lib/binding_rust/lib.rs | 38 ++++++++ lib/binding_web/lib/tree-sitter.c | 36 ++++++++ lib/binding_web/lib/web-tree-sitter.d.ts | 4 +- lib/binding_web/src/query.ts | 64 +++++++++++++ lib/binding_web/test/query.test.ts | 58 ++++++++++++ lib/include/tree_sitter/api.h | 22 +++++ lib/src/query.c | 110 ++++++++++++++++------- 13 files changed, 420 insertions(+), 34 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index e97c9cce..3ba22e45 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -448,6 +448,14 @@ struct Query { /// The range of rows in which the query will be executed #[arg(long)] pub row_range: Option, + /// The range of byte offsets in which the query will be executed. Only the matches that are fully contained within the provided + /// byte range will be returned. + #[arg(long)] + pub containing_byte_range: Option, + /// The range of rows in which the query will be executed. Only the matches that are fully contained within the provided row range + /// will be returned. + #[arg(long)] + pub containing_row_range: Option, /// Select a language by the scope instead of a file extension #[arg(long)] pub scope: Option, @@ -1486,6 +1494,18 @@ impl Query { let end = parts.next().unwrap().parse().ok()?; Some(Point::new(start, 0)..Point::new(end, 0)) }); + let containing_byte_range = self.containing_byte_range.as_ref().and_then(|range| { + let mut parts = range.split(':'); + let start = parts.next()?.parse().ok()?; + let end = parts.next().unwrap().parse().ok()?; + Some(start..end) + }); + let containing_point_range = self.containing_row_range.as_ref().and_then(|range| { + let mut parts = range.split(':'); + let start = parts.next()?.parse().ok()?; + let end = parts.next().unwrap().parse().ok()?; + Some(Point::new(start, 0)..Point::new(end, 0)) + }); let cancellation_flag = util::cancel_on_signal(); @@ -1514,6 +1534,8 @@ impl Query { ordered_captures: self.captures, byte_range, point_range, + containing_byte_range, + containing_point_range, quiet: self.quiet, print_time: self.time, stdin: false, @@ -1557,6 +1579,8 @@ impl Query { ordered_captures: self.captures, byte_range, point_range, + containing_byte_range, + containing_point_range, quiet: self.quiet, print_time: self.time, stdin: true, @@ -1575,6 +1599,8 @@ impl Query { ordered_captures: self.captures, byte_range, point_range, + containing_byte_range, + containing_point_range, quiet: self.quiet, print_time: self.time, stdin: true, diff --git a/crates/cli/src/query.rs b/crates/cli/src/query.rs index 7343049f..54674115 100644 --- a/crates/cli/src/query.rs +++ b/crates/cli/src/query.rs @@ -21,6 +21,8 @@ pub struct QueryFileOptions { pub ordered_captures: bool, pub byte_range: Option>, pub point_range: Option>, + pub containing_byte_range: Option>, + pub containing_point_range: Option>, pub quiet: bool, pub print_time: bool, pub stdin: bool, @@ -48,6 +50,12 @@ pub fn query_file_at_path( if let Some(ref range) = opts.point_range { query_cursor.set_point_range(range.clone()); } + if let Some(ref range) = opts.containing_byte_range { + query_cursor.set_containing_byte_range(range.clone()); + } + if let Some(ref range) = opts.containing_point_range { + query_cursor.set_containing_point_range(range.clone()); + } let mut parser = Parser::new(); parser.set_language(language)?; diff --git a/crates/cli/src/tests/query_test.rs b/crates/cli/src/tests/query_test.rs index 4eb74f6c..3f1467e5 100644 --- a/crates/cli/src/tests/query_test.rs +++ b/crates/cli/src/tests/query_test.rs @@ -2669,6 +2669,64 @@ fn test_query_matches_within_range_of_long_repetition() { }); } +#[test] +fn test_query_matches_contained_within_range() { + allocations::record(|| { + let language = get_language("json"); + let query = Query::new( + &language, + r#" + ("[" @l_bracket "]" @r_bracket) + ("{" @l_brace "}" @r_brace) + "#, + ) + .unwrap(); + + let source = r#" + [ + {"key1": "value1"}, + {"key2": "value2"}, + {"key3": "value3"}, + {"key4": "value4"}, + {"key5": "value5"}, + {"key6": "value6"}, + {"key7": "value7"}, + {"key8": "value8"}, + {"key9": "value9"}, + {"key10": "value10"}, + {"key11": "value11"}, + {"key12": "value12"}, + ] + "# + .unindent(); + + let mut parser = Parser::new(); + parser.set_language(&language).unwrap(); + let tree = parser.parse(&source, None).unwrap(); + + let expected_matches = [ + (1, vec![("l_brace", "{"), ("r_brace", "}")]), + (1, vec![("l_brace", "{"), ("r_brace", "}")]), + ]; + { + let mut cursor = QueryCursor::new(); + let matches = cursor + .set_containing_point_range(Point::new(5, 0)..Point::new(7, 0)) + .matches(&query, tree.root_node(), source.as_bytes()); + assert_eq!(collect_matches(matches, &query, &source), &expected_matches); + } + { + let mut cursor = QueryCursor::new(); + let matches = cursor.set_containing_byte_range(78..120).matches( + &query, + tree.root_node(), + source.as_bytes(), + ); + assert_eq!(collect_matches(matches, &query, &source), &expected_matches); + } + }); +} + #[test] fn test_query_matches_different_queries_same_cursor() { allocations::record(|| { diff --git a/crates/xtask/src/check_wasm_exports.rs b/crates/xtask/src/check_wasm_exports.rs index 124725b7..c93f7cd3 100644 --- a/crates/xtask/src/check_wasm_exports.rs +++ b/crates/xtask/src/check_wasm_exports.rs @@ -16,7 +16,7 @@ use notify_debouncer_full::new_debouncer; use crate::{bail_on_err, watch_wasm, CheckWasmExports}; -const EXCLUDES: [&str; 23] = [ +const EXCLUDES: [&str; 25] = [ // Unneeded because the JS side has its own way of implementing it "ts_node_child_by_field_name", "ts_node_edit", @@ -44,6 +44,8 @@ const EXCLUDES: [&str; 23] = [ "ts_query_cursor_delete", "ts_query_cursor_match_limit", "ts_query_cursor_remove_match", + "ts_query_cursor_set_point_range", + "ts_query_cursor_set_containing_byte_range", ]; pub fn run(args: &CheckWasmExports) -> Result<()> { diff --git a/docs/src/cli/query.md b/docs/src/cli/query.md index 395ca486..08ff2654 100644 --- a/docs/src/cli/query.md +++ b/docs/src/cli/query.md @@ -36,10 +36,20 @@ The path to a file that contains paths to source files in which the query will b The range of byte offsets in which the query will be executed. The format is `start_byte:end_byte`. +### `--containing-byte-range ` + +The range of byte offsets in which the query will be executed. Only the matches that are fully contained within the provided +byte range will be returned. + ### `--row-range ` The range of rows in which the query will be executed. The format is `start_row:end_row`. +### `--containing-row-range ` + +The range of rows in which the query will be executed. Only the matches that are fully contained within the provided row range +will be returned. + ### `--scope ` The language scope to use for parsing and querying. This is useful when the language is ambiguous. diff --git a/lib/binding_rust/bindings.rs b/lib/binding_rust/bindings.rs index 3feb8409..ec00a7c6 100644 --- a/lib/binding_rust/bindings.rs +++ b/lib/binding_rust/bindings.rs @@ -712,6 +712,22 @@ extern "C" { end_point: TSPoint, ) -> bool; } +extern "C" { + #[doc = " Set the byte range within which all matches must be fully contained.\n\n Set the range of bytes in which matches will be searched for. In contrast to\n `ts_query_cursor_set_byte_range`, this will restrict the query cursor to only return\n matches where _all_ nodes are _fully_ contained within the given range. Both functions\n can be used together, e.g. to search for any matches that intersect line 5000, as\n long as they are fully contained within lines 4500-5500"] + pub fn ts_query_cursor_set_containing_byte_range( + self_: *mut TSQueryCursor, + start_byte: u32, + end_byte: u32, + ) -> bool; +} +extern "C" { + #[doc = " Set the point range within which all matches must be fully contained.\n\n Set the range of bytes in which matches will be searched for. In contrast to\n `ts_query_cursor_set_point_range`, this will restrict the query cursor to only return\n matches where _all_ nodes are _fully_ contained within the given range. Both functions\n can be used together, e.g. to search for any matches that intersect line 5000, as\n long as they are fully contained within lines 4500-5500"] + pub fn ts_query_cursor_set_containing_point_range( + self_: *mut TSQueryCursor, + start_point: TSPoint, + end_point: TSPoint, + ) -> bool; +} extern "C" { #[doc = " Advance to the next match of the currently running query.\n\n If there is a match, write it to `*match` and return `true`.\n Otherwise, return `false`."] pub fn ts_query_cursor_next_match(self_: *mut TSQueryCursor, match_: *mut TSQueryMatch) diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index a02fa173..bf86cf74 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -3181,6 +3181,44 @@ impl QueryCursor { self } + /// Set the byte range within which all matches must be fully contained. + /// + /// Set the range of bytes in which matches will be searched for. In contrast to + /// `ts_query_cursor_set_byte_range`, this will restrict the query cursor to only return + /// matches where _all_ nodes are _fully_ contained within the given range. Both functions + /// can be used together, e.g. to search for any matches that intersect line 5000, as + /// long as they are fully contained within lines 4500-5500 + #[doc(alias = "ts_query_cursor_set_containing_byte_range")] + pub fn set_containing_byte_range(&mut self, range: ops::Range) -> &mut Self { + unsafe { + ffi::ts_query_cursor_set_containing_byte_range( + self.ptr.as_ptr(), + range.start as u32, + range.end as u32, + ); + } + self + } + + /// Set the point range within which all matches must be fully contained. + /// + /// Set the range of bytes in which matches will be searched for. In contrast to + /// `ts_query_cursor_set_point_range`, this will restrict the query cursor to only return + /// matches where _all_ nodes are _fully_ contained within the given range. Both functions + /// can be used together, e.g. to search for any matches that intersect line 5000, as + /// long as they are fully contained within lines 4500-5500 + #[doc(alias = "ts_query_cursor_set_containing_point_range")] + pub fn set_containing_point_range(&mut self, range: ops::Range) -> &mut Self { + unsafe { + ffi::ts_query_cursor_set_containing_point_range( + self.ptr.as_ptr(), + range.start.into(), + range.end.into(), + ); + } + self + } + /// Set the maximum start depth for a query cursor. /// /// This prevents cursors from exploring children nodes at a certain depth. diff --git a/lib/binding_web/lib/tree-sitter.c b/lib/binding_web/lib/tree-sitter.c index db6c108b..828132ac 100644 --- a/lib/binding_web/lib/tree-sitter.c +++ b/lib/binding_web/lib/tree-sitter.c @@ -874,6 +874,12 @@ void ts_query_matches_wasm( uint32_t end_column, uint32_t start_index, uint32_t end_index, + uint32_t start_containing_row, + uint32_t start_containing_column, + uint32_t end_containing_row, + uint32_t end_containing_column, + uint32_t start_containing_index, + uint32_t end_containing_index, uint32_t match_limit, uint32_t max_start_depth ) { @@ -889,8 +895,20 @@ void ts_query_matches_wasm( TSNode node = unmarshal_node(tree); TSPoint start_point = {start_row, code_unit_to_byte(start_column)}; TSPoint end_point = {end_row, code_unit_to_byte(end_column)}; + TSPoint start_containing_point = {start_containing_row, code_unit_to_byte(start_containing_column)}; + TSPoint end_containing_point = {end_containing_row, code_unit_to_byte(end_containing_column)}; ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point); ts_query_cursor_set_byte_range(scratch_query_cursor, start_index, end_index); + ts_query_cursor_set_containing_point_range( + scratch_query_cursor, + start_containing_point, + end_containing_point + ); + ts_query_cursor_set_containing_byte_range( + scratch_query_cursor, + start_containing_index, + end_containing_index + ); ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit); ts_query_cursor_set_max_start_depth(scratch_query_cursor, max_start_depth); @@ -932,6 +950,12 @@ void ts_query_captures_wasm( uint32_t end_column, uint32_t start_index, uint32_t end_index, + uint32_t start_containing_row, + uint32_t start_containing_column, + uint32_t end_containing_row, + uint32_t end_containing_column, + uint32_t start_containing_index, + uint32_t end_containing_index, uint32_t match_limit, uint32_t max_start_depth ) { @@ -944,8 +968,20 @@ void ts_query_captures_wasm( TSNode node = unmarshal_node(tree); TSPoint start_point = {start_row, code_unit_to_byte(start_column)}; TSPoint end_point = {end_row, code_unit_to_byte(end_column)}; + TSPoint start_containing_point = {start_containing_row, code_unit_to_byte(start_containing_column)}; + TSPoint end_containing_point = {end_containing_row, code_unit_to_byte(end_containing_column)}; ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point); ts_query_cursor_set_byte_range(scratch_query_cursor, start_index, end_index); + ts_query_cursor_set_containing_point_range( + scratch_query_cursor, + start_containing_point, + end_containing_point + ); + ts_query_cursor_set_containing_byte_range( + scratch_query_cursor, + start_containing_index, + end_containing_index + ); ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit); ts_query_cursor_set_max_start_depth(scratch_query_cursor, max_start_depth); ts_query_cursor_exec(scratch_query_cursor, self, node); diff --git a/lib/binding_web/lib/web-tree-sitter.d.ts b/lib/binding_web/lib/web-tree-sitter.d.ts index c19d7bf4..c1e0e0dd 100644 --- a/lib/binding_web/lib/web-tree-sitter.d.ts +++ b/lib/binding_web/lib/web-tree-sitter.d.ts @@ -175,8 +175,8 @@ interface WasmModule { _ts_node_is_extra_wasm(_0: number): number; _ts_node_parse_state_wasm(_0: number): number; _ts_node_next_parse_state_wasm(_0: number): number; - _ts_query_matches_wasm(_0: number, _1: number, _2: number, _3: number, _4: number, _5: number, _6: number, _7: number, _8: number, _9: number): void; - _ts_query_captures_wasm(_0: number, _1: number, _2: number, _3: number, _4: number, _5: number, _6: number, _7: number, _8: number, _9: number): void; + _ts_query_matches_wasm(_0: number, _1: number, _2: number, _3: number, _4: number, _5: number, _6: number, _7: number, _8: number, _9: number, _10: number, _11: number, _12: number, _13: number, _14: number, _15: number): void; + _ts_query_captures_wasm(_0: number, _1: number, _2: number, _3: number, _4: number, _5: number, _6: number, _7: number, _8: number, _9: number, _10: number, _11: number, _12: number, _13: number, _14: number, _15: number): void; _memset(_0: number, _1: number, _2: number): number; _memcpy(_0: number, _1: number, _2: number): number; _memmove(_0: number, _1: number, _2: number): number; diff --git a/lib/binding_web/src/query.ts b/lib/binding_web/src/query.ts index 6f3064a8..b9cd1971 100644 --- a/lib/binding_web/src/query.ts +++ b/lib/binding_web/src/query.ts @@ -20,12 +20,32 @@ export interface QueryOptions { /** The end position of the range to query */ endPosition?: Point; + /** The start position of the range to query Only the matches that are fully + * contained within provided range will be returned. + **/ + startContainingPosition?: Point; + + /** The end position of the range to query Only the matches that are fully + * contained within provided range will be returned. + **/ + endContainingPosition?: Point; + /** The start index of the range to query */ startIndex?: number; /** The end index of the range to query */ endIndex?: number; + /** The start index of the range to query Only the matches that are fully + * contained within provided range will be returned. + **/ + startContainingIndex?: number; + + /** The end index of the range to query Only the matches that are fully + * contained within provided range will be returned. + **/ + endContainingIndex?: number; + /** * The maximum number of in-progress matches for this query. * The limit must be > 0 and <= 65536. @@ -695,6 +715,10 @@ export class Query { const endPosition = options.endPosition ?? ZERO_POINT; const startIndex = options.startIndex ?? 0; const endIndex = options.endIndex ?? 0; + const startContainingPosition = options.startContainingPosition ?? ZERO_POINT; + const endContainingPosition = options.endContainingPosition ?? ZERO_POINT; + const startContainingIndex = options.startContainingIndex ?? 0; + const endContainingIndex = options.endContainingIndex ?? 0; const matchLimit = options.matchLimit ?? 0xFFFFFFFF; const maxStartDepth = options.maxStartDepth ?? 0xFFFFFFFF; const progressCallback = options.progressCallback; @@ -715,6 +739,18 @@ export class Query { throw new Error('`startPosition` cannot be greater than `endPosition`'); } + if (endContainingIndex !== 0 && startContainingIndex > endContainingIndex) { + throw new Error('`startContainingIndex` cannot be greater than `endContainingIndex`'); + } + + if (endContainingPosition !== ZERO_POINT && ( + startContainingPosition.row > endContainingPosition.row || + (startContainingPosition.row === endContainingPosition.row && + startContainingPosition.column > endContainingPosition.column) + )) { + throw new Error('`startContainingPosition` cannot be greater than `endContainingPosition`'); + } + if (progressCallback) { C.currentQueryProgressCallback = progressCallback; } @@ -730,6 +766,12 @@ export class Query { endPosition.column, startIndex, endIndex, + startContainingPosition.row, + startContainingPosition.column, + endContainingPosition.row, + endContainingPosition.column, + startContainingIndex, + endContainingIndex, matchLimit, maxStartDepth, ); @@ -788,6 +830,10 @@ export class Query { const endPosition = options.endPosition ?? ZERO_POINT; const startIndex = options.startIndex ?? 0; const endIndex = options.endIndex ?? 0; + const startContainingPosition = options.startContainingPosition ?? ZERO_POINT; + const endContainingPosition = options.endContainingPosition ?? ZERO_POINT; + const startContainingIndex = options.startContainingIndex ?? 0; + const endContainingIndex = options.endContainingIndex ?? 0; const matchLimit = options.matchLimit ?? 0xFFFFFFFF; const maxStartDepth = options.maxStartDepth ?? 0xFFFFFFFF; const progressCallback = options.progressCallback; @@ -808,6 +854,18 @@ export class Query { throw new Error('`startPosition` cannot be greater than `endPosition`'); } + if (endContainingIndex !== 0 && startContainingIndex > endContainingIndex) { + throw new Error('`startContainingIndex` cannot be greater than `endContainingIndex`'); + } + + if (endContainingPosition !== ZERO_POINT && ( + startContainingPosition.row > endContainingPosition.row || + (startContainingPosition.row === endContainingPosition.row && + startContainingPosition.column > endContainingPosition.column) + )) { + throw new Error('`startContainingPosition` cannot be greater than `endContainingPosition`'); + } + if (progressCallback) { C.currentQueryProgressCallback = progressCallback; } @@ -823,6 +881,12 @@ export class Query { endPosition.column, startIndex, endIndex, + startContainingPosition.row, + startContainingPosition.column, + endContainingPosition.row, + endContainingPosition.column, + startContainingIndex, + endContainingIndex, matchLimit, maxStartDepth, ); diff --git a/lib/binding_web/test/query.test.ts b/lib/binding_web/test/query.test.ts index ad6a6660..f90e9464 100644 --- a/lib/binding_web/test/query.test.ts +++ b/lib/binding_web/test/query.test.ts @@ -96,6 +96,64 @@ describe('Query', () => { ]); }); + it('can search in contained within point ranges', () => { + tree = parser.parse(`[ + {"key1": "value1"}, + {"key2": "value2"}, + {"key3": "value3"}, + {"key4": "value4"}, + {"key5": "value5"}, + {"key6": "value6"}, + {"key7": "value7"}, + {"key8": "value8"}, + {"key9": "value9"}, + {"key10": "value10"}, + {"key11": "value11"}, + {"key12": "value12"}, +]`)!; + query = new Query(JavaScript, '("[" @l_bracket "]" @r_bracket) ("{" @l_brace "}" @r_brace)'); + const matches = query.matches( + tree.rootNode, + { + startContainingPosition: { row: 5, column: 0 }, + endContainingPosition: { row: 7, column: 0 }, + } + ); + expect(formatMatches(matches)).toEqual([ + { patternIndex: 1, captures: [{ patternIndex: 1, name: 'l_brace', text: '{' }, { patternIndex: 1, name: 'r_brace', text: '}' },] }, + { patternIndex: 1, captures: [{ patternIndex: 1, name: 'l_brace', text: '{' }, { patternIndex: 1, name: 'r_brace', text: '}' },] }, + ]); + }); + + it('can search in contained within byte ranges', () => { + tree = parser.parse(`[ + {"key1": "value1"}, + {"key2": "value2"}, + {"key3": "value3"}, + {"key4": "value4"}, + {"key5": "value5"}, + {"key6": "value6"}, + {"key7": "value7"}, + {"key8": "value8"}, + {"key9": "value9"}, + {"key10": "value10"}, + {"key11": "value11"}, + {"key12": "value12"}, +]`)!; + query = new Query(JavaScript, '("[" @l_bracket "]" @r_bracket) ("{" @l_brace "}" @r_brace)'); + const matches = query.matches( + tree.rootNode, + { + startContainingIndex: 290, + endContainingIndex: 432, + } + ); + expect(formatMatches(matches)).toEqual([ + { patternIndex: 1, captures: [{ patternIndex: 1, name: 'l_brace', text: '{' }, { patternIndex: 1, name: 'r_brace', text: '}' },] }, + { patternIndex: 1, captures: [{ patternIndex: 1, name: 'l_brace', text: '{' }, { patternIndex: 1, name: 'r_brace', text: '}' },] }, + ]); + }); + it('handles predicates that compare the text of capture to literal strings', () => { tree = parser.parse(` giraffe(1, 2, []); diff --git a/lib/include/tree_sitter/api.h b/lib/include/tree_sitter/api.h index 264d405d..22c85d48 100644 --- a/lib/include/tree_sitter/api.h +++ b/lib/include/tree_sitter/api.h @@ -1101,6 +1101,28 @@ bool ts_query_cursor_set_byte_range(TSQueryCursor *self, uint32_t start_byte, ui */ bool ts_query_cursor_set_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point); +/** + * Set the byte range within which all matches must be fully contained. + * + * Set the range of bytes in which matches will be searched for. In contrast to + * `ts_query_cursor_set_byte_range`, this will restrict the query cursor to only return + * matches where _all_ nodes are _fully_ contained within the given range. Both functions + * can be used together, e.g. to search for any matches that intersect line 5000, as + * long as they are fully contained within lines 4500-5500 + */ +bool ts_query_cursor_set_containing_byte_range(TSQueryCursor *self, uint32_t start_byte, uint32_t end_byte); + +/** + * Set the point range within which all matches must be fully contained. + * + * Set the range of bytes in which matches will be searched for. In contrast to + * `ts_query_cursor_set_point_range`, this will restrict the query cursor to only return + * matches where _all_ nodes are _fully_ contained within the given range. Both functions + * can be used together, e.g. to search for any matches that intersect line 5000, as + * long as they are fully contained within lines 4500-5500 + */ +bool ts_query_cursor_set_containing_point_range(TSQueryCursor *self, TSPoint start_point, TSPoint end_point); + /** * Advance to the next match of the currently running query. * diff --git a/lib/src/query.c b/lib/src/query.c index d1695549..7a8b855b 100644 --- a/lib/src/query.c +++ b/lib/src/query.c @@ -318,10 +318,8 @@ struct TSQueryCursor { CaptureListPool capture_list_pool; uint32_t depth; uint32_t max_start_depth; - uint32_t start_byte; - uint32_t end_byte; - TSPoint start_point; - TSPoint end_point; + TSRange included_range; + TSRange containing_range; uint32_t next_state_id; const TSQueryCursorOptions *query_options; TSQueryCursorState query_state; @@ -1336,7 +1334,7 @@ static void ts_query__perform_analysis( // of the query pattern. bool does_match = false; - // ERROR nodes can appear anywhere, so if the step is + // ERROR nodes can appear anywhere, so if the step is // looking for an ERROR node, consider it potentially matchable. if (step->symbol == ts_builtin_sym_error) { does_match = true; @@ -3155,10 +3153,18 @@ TSQueryCursor *ts_query_cursor_new(void) { .states = array_new(), .finished_states = array_new(), .capture_list_pool = capture_list_pool_new(), - .start_byte = 0, - .end_byte = UINT32_MAX, - .start_point = {0, 0}, - .end_point = POINT_MAX, + .included_range = { + .start_point = {0, 0}, + .end_point = POINT_MAX, + .start_byte = 0, + .end_byte = UINT32_MAX, + }, + .containing_range = { + .start_point = {0, 0}, + .end_point = POINT_MAX, + .start_byte = 0, + .end_byte = UINT32_MAX, + }, .max_start_depth = UINT32_MAX, .operation_count = 0, }; @@ -3266,8 +3272,8 @@ bool ts_query_cursor_set_byte_range( if (start_byte > end_byte) { return false; } - self->start_byte = start_byte; - self->end_byte = end_byte; + self->included_range.start_byte = start_byte; + self->included_range.end_byte = end_byte; return true; } @@ -3282,8 +3288,40 @@ bool ts_query_cursor_set_point_range( if (point_gt(start_point, end_point)) { return false; } - self->start_point = start_point; - self->end_point = end_point; + self->included_range.start_point = start_point; + self->included_range.end_point = end_point; + return true; +} + +bool ts_query_cursor_set_containing_byte_range( + TSQueryCursor *self, + uint32_t start_byte, + uint32_t end_byte +) { + if (end_byte == 0) { + end_byte = UINT32_MAX; + } + if (start_byte > end_byte) { + return false; + } + self->containing_range.start_byte = start_byte; + self->containing_range.end_byte = end_byte; + return true; +} + +bool ts_query_cursor_set_containing_point_range( + TSQueryCursor *self, + TSPoint start_point, + TSPoint end_point +) { + if (end_point.row == 0 && end_point.column == 0) { + end_point = POINT_MAX; + } + if (point_gt(start_point, end_point)) { + return false; + } + self->containing_range.start_point = start_point; + self->containing_range.end_point = end_point; return true; } @@ -3314,8 +3352,8 @@ static bool ts_query_cursor__first_in_progress_capture( TSNode node = array_get(captures, state->consumed_capture_count)->node; if ( - ts_node_end_byte(node) <= self->start_byte || - point_lte(ts_node_end_point(node), self->start_point) + ts_node_end_byte(node) <= self->included_range.start_byte || + point_lte(ts_node_end_point(node), self->included_range.start_point) ) { state->consumed_capture_count++; i--; @@ -3771,28 +3809,38 @@ static inline bool ts_query_cursor__advance( bool is_empty = start_byte == end_byte; bool parent_precedes_range = !ts_node_is_null(parent_node) && ( - ts_node_end_byte(parent_node) <= self->start_byte || - point_lte(ts_node_end_point(parent_node), self->start_point) + ts_node_end_byte(parent_node) <= self->included_range.start_byte || + point_lte(ts_node_end_point(parent_node), self->included_range.start_point) ); bool parent_follows_range = !ts_node_is_null(parent_node) && ( - ts_node_start_byte(parent_node) >= self->end_byte || - point_gte(ts_node_start_point(parent_node), self->end_point) + ts_node_start_byte(parent_node) >= self->included_range.end_byte || + point_gte(ts_node_start_point(parent_node), self->included_range.end_point) ); bool node_precedes_range = parent_precedes_range || - end_byte < self->start_byte || - point_lt(end_point, self->start_point) || - (!is_empty && end_byte == self->start_byte) || - (!is_empty && point_eq(end_point, self->start_point)); + end_byte < self->included_range.start_byte || + point_lt(end_point, self->included_range.start_point) || + (!is_empty && end_byte == self->included_range.start_byte) || + (!is_empty && point_eq(end_point, self->included_range.start_point)); bool node_follows_range = parent_follows_range || ( - start_byte >= self->end_byte || - point_gte(start_point, self->end_point) + start_byte >= self->included_range.end_byte || + point_gte(start_point, self->included_range.end_point) ); bool parent_intersects_range = !parent_precedes_range && !parent_follows_range; bool node_intersects_range = !node_precedes_range && !node_follows_range; + bool node_within_containing_range = + start_byte >= self->containing_range.start_byte && + point_gte(start_point, self->containing_range.start_point) && + end_byte <= self->containing_range.end_byte && + point_lte(end_point, self->containing_range.end_point); + bool node_intersects_containing_range = + end_byte > self->containing_range.start_byte && + point_gt(end_point, self->containing_range.start_point) && + start_byte < self->containing_range.end_byte && + point_lt(start_point, self->containing_range.end_point); - if (self->on_visible_node) { + if (node_within_containing_range && self->on_visible_node) { TSSymbol symbol = ts_node_symbol(node); bool is_named = ts_node_is_named(node); bool is_missing = ts_node_is_missing(node); @@ -4182,7 +4230,7 @@ static inline bool ts_query_cursor__advance( } } - if (ts_query_cursor__should_descend(self, node_intersects_range)) { + if (node_intersects_containing_range && ts_query_cursor__should_descend(self, node_intersects_range)) { switch (ts_tree_cursor_goto_first_child_internal(&self->cursor)) { case TreeCursorStepVisible: self->depth++; @@ -4304,12 +4352,12 @@ bool ts_query_cursor_next_capture( TSNode node = array_get(captures, state->consumed_capture_count)->node; bool node_precedes_range = ( - ts_node_end_byte(node) <= self->start_byte || - point_lte(ts_node_end_point(node), self->start_point) + ts_node_end_byte(node) <= self->included_range.start_byte || + point_lte(ts_node_end_point(node), self->included_range.start_point) ); bool node_follows_range = ( - ts_node_start_byte(node) >= self->end_byte || - point_gte(ts_node_start_point(node), self->end_point) + ts_node_start_byte(node) >= self->included_range.end_byte || + point_gte(ts_node_start_point(node), self->included_range.end_point) ); bool node_outside_of_range = node_precedes_range || node_follows_range; From be8fe690d8858df9f900ec8bb9506ade3425271f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 6 Oct 2025 09:41:03 -0700 Subject: [PATCH 075/140] Clean up node range tracking in query_cursor__advance --- lib/src/query.c | 81 +++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/lib/src/query.c b/lib/src/query.c index 7a8b855b..e378910a 100644 --- a/lib/src/query.c +++ b/lib/src/query.c @@ -3678,6 +3678,31 @@ static inline bool ts_query_cursor__should_descend( return false; } +bool range_intersects(const TSRange *a, const TSRange *b) { + bool is_empty = a->start_byte == a->end_byte; + return ( + ( + a->end_byte > b->start_byte || + (is_empty && a->end_byte == b->start_byte) + ) && + ( + point_gt(a->end_point, b->start_point) || + (is_empty && point_eq(a->end_point, b->start_point)) + ) && + a->start_byte < b->end_byte && + point_lt(a->start_point, b->end_point) + ); +} + +bool range_within(const TSRange *a, const TSRange *b) { + return ( + a->start_byte >= b->start_byte && + point_gte(a->start_point, b->start_point) && + a->end_byte <= b->end_byte && + point_lte(a->end_point, b->end_point) + ); +} + // Walk the tree, processing patterns until at least one pattern finishes, // If one or more patterns finish, return `true` and store their states in the // `finished_states` array. Multiple patterns can finish on the same node. If @@ -3798,47 +3823,29 @@ static inline bool ts_query_cursor__advance( // Enter a new node. else { - // Get the properties of the current node. TSNode node = ts_tree_cursor_current_node(&self->cursor); TSNode parent_node = ts_tree_cursor_parent_node(&self->cursor); - uint32_t start_byte = ts_node_start_byte(node); - uint32_t end_byte = ts_node_end_byte(node); - TSPoint start_point = ts_node_start_point(node); - TSPoint end_point = ts_node_end_point(node); - bool is_empty = start_byte == end_byte; - - bool parent_precedes_range = !ts_node_is_null(parent_node) && ( - ts_node_end_byte(parent_node) <= self->included_range.start_byte || - point_lte(ts_node_end_point(parent_node), self->included_range.start_point) - ); - bool parent_follows_range = !ts_node_is_null(parent_node) && ( - ts_node_start_byte(parent_node) >= self->included_range.end_byte || - point_gte(ts_node_start_point(parent_node), self->included_range.end_point) - ); - bool node_precedes_range = - parent_precedes_range || - end_byte < self->included_range.start_byte || - point_lt(end_point, self->included_range.start_point) || - (!is_empty && end_byte == self->included_range.start_byte) || - (!is_empty && point_eq(end_point, self->included_range.start_point)); - - bool node_follows_range = parent_follows_range || ( - start_byte >= self->included_range.end_byte || - point_gte(start_point, self->included_range.end_point) - ); - bool parent_intersects_range = !parent_precedes_range && !parent_follows_range; - bool node_intersects_range = !node_precedes_range && !node_follows_range; - bool node_within_containing_range = - start_byte >= self->containing_range.start_byte && - point_gte(start_point, self->containing_range.start_point) && - end_byte <= self->containing_range.end_byte && - point_lte(end_point, self->containing_range.end_point); + bool parent_intersects_range = + ts_node_is_null(parent_node) || + range_intersects(&(TSRange) { + .start_point = ts_node_start_point(parent_node), + .end_point = ts_node_end_point(parent_node), + .start_byte = ts_node_start_byte(parent_node), + .end_byte = ts_node_end_byte(parent_node), + }, &self->included_range); + TSRange node_range = (TSRange) { + .start_point = ts_node_start_point(node), + .end_point = ts_node_end_point(node), + .start_byte = ts_node_start_byte(node), + .end_byte = ts_node_end_byte(node), + }; + bool node_intersects_range = + parent_intersects_range && range_intersects(&node_range, &self->included_range); bool node_intersects_containing_range = - end_byte > self->containing_range.start_byte && - point_gt(end_point, self->containing_range.start_point) && - start_byte < self->containing_range.end_byte && - point_lt(start_point, self->containing_range.end_point); + range_intersects(&node_range, &self->containing_range); + bool node_within_containing_range = + range_within(&node_range, &self->containing_range); if (node_within_containing_range && self->on_visible_node) { TSSymbol symbol = ts_node_symbol(node); From 888f57657d6dfdd6340052b29920e22a0aaabc2a Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 1 Dec 2025 21:12:35 -0500 Subject: [PATCH 076/140] fix(cli): improve error reporting for invalid range arguments to `query` command --- crates/cli/src/main.rs | 58 +++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 3ba22e45..20255d62 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1482,30 +1482,11 @@ impl Query { loader.find_all_languages(&loader_config)?; let query_path = Path::new(&self.query_path); - let byte_range = self.byte_range.as_ref().and_then(|range| { - let mut parts = range.split(':'); - let start = parts.next()?.parse().ok()?; - let end = parts.next().unwrap().parse().ok()?; - Some(start..end) - }); - let point_range = self.row_range.as_ref().and_then(|range| { - let mut parts = range.split(':'); - let start = parts.next()?.parse().ok()?; - let end = parts.next().unwrap().parse().ok()?; - Some(Point::new(start, 0)..Point::new(end, 0)) - }); - let containing_byte_range = self.containing_byte_range.as_ref().and_then(|range| { - let mut parts = range.split(':'); - let start = parts.next()?.parse().ok()?; - let end = parts.next().unwrap().parse().ok()?; - Some(start..end) - }); - let containing_point_range = self.containing_row_range.as_ref().and_then(|range| { - let mut parts = range.split(':'); - let start = parts.next()?.parse().ok()?; - let end = parts.next().unwrap().parse().ok()?; - Some(Point::new(start, 0)..Point::new(end, 0)) - }); + let byte_range = parse_range(&self.byte_range, |x| x)?; + let point_range = parse_range(&self.row_range, |row| Point::new(row, 0))?; + let containing_byte_range = parse_range(&self.containing_byte_range, |x| x)?; + let containing_point_range = + parse_range(&self.containing_row_range, |row| Point::new(row, 0))?; let cancellation_flag = util::cancel_on_signal(); @@ -2106,3 +2087,32 @@ fn get_lib_info<'a>( None } } + +/// Parse a range string of the form "start:end" into an optional Range. +fn parse_range( + range_str: &Option, + make: impl Fn(usize) -> T, +) -> Result>> { + if let Some(range) = range_str.as_ref() { + let err_msg = format!("Invalid range '{range}', expected 'start:end'"); + let mut parts = range.split(':'); + + let Some(part) = parts.next() else { + Err(anyhow!(err_msg))? + }; + let Ok(start) = part.parse::() else { + Err(anyhow!(err_msg))? + }; + + let Some(part) = parts.next() else { + Err(anyhow!(err_msg))? + }; + let Ok(end) = part.parse::() else { + Err(anyhow!(err_msg))? + }; + + Ok(Some(make(start)..make(end))) + } else { + Ok(None) + } +} From 6b6040961cc8f7348a6b0d649770d11f1a719c19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Nov 2025 21:38:17 +0000 Subject: [PATCH 077/140] build(deps): bump js-yaml from 4.1.0 to 4.1.1 in /lib/binding_web Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1. - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.1.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- lib/binding_web/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index e5c20f7d..29f4595f 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -2611,9 +2611,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { From 3ff8edf9e81e804ab20068e22e989a3a25b29ad4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 15 Nov 2025 10:34:45 +0000 Subject: [PATCH 078/140] build(deps): bump js-yaml from 4.1.0 to 4.1.1 in /crates/cli/eslint Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.0 to 4.1.1. - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.1.1 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- crates/cli/eslint/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/cli/eslint/package-lock.json b/crates/cli/eslint/package-lock.json index 585a4f99..60559b10 100644 --- a/crates/cli/eslint/package-lock.json +++ b/crates/cli/eslint/package-lock.json @@ -805,9 +805,9 @@ "peer": true }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "peer": true, "dependencies": { From f450ce4f6e104e1b43e44a2db770371747bf562c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 03:42:22 +0000 Subject: [PATCH 079/140] build(deps): bump vite from 7.1.5 to 7.1.11 in /lib/binding_web Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.5 to 7.1.11. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v7.1.11/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 7.1.11 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- lib/binding_web/package-lock.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index 29f4595f..bc34efaa 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -1211,6 +1211,7 @@ "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.12.0" } @@ -1261,6 +1262,7 @@ "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.44.1", "@typescript-eslint/types": "8.44.1", @@ -1628,6 +1630,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2010,6 +2013,7 @@ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3501,6 +3505,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3570,6 +3575,7 @@ "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" @@ -3603,6 +3609,7 @@ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3653,11 +3660,12 @@ } }, "node_modules/vite": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", - "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", + "version": "7.2.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.6.tgz", + "integrity": "sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -3774,6 +3782,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3787,6 +3796,7 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", From a8f25fa4412db3d699ac1057200dccc5b0d0b0cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Nov 2025 01:32:43 +0000 Subject: [PATCH 080/140] build(deps): bump glob from 10.4.5 to 10.5.0 in /lib/binding_web Bumps [glob](https://github.com/isaacs/node-glob) from 10.4.5 to 10.5.0. - [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md) - [Commits](https://github.com/isaacs/node-glob/compare/v10.4.5...v10.5.0) --- updated-dependencies: - dependency-name: glob dependency-version: 10.5.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- lib/binding_web/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index bc34efaa..53c89f97 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -2354,9 +2354,9 @@ } }, "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", "dev": true, "license": "ISC", "dependencies": { From 053b2645024cfdad40b0c6ccf7ab4e1b6df386fc Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 6 Dec 2025 12:07:30 +0100 Subject: [PATCH 081/140] build(deps): cargo update --- Cargo.lock | 76 +++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7b45028..db44d925 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,9 +181,9 @@ checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" @@ -1008,9 +1008,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -1044,9 +1044,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -1094,9 +1094,9 @@ checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "mach2" @@ -1130,9 +1130,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", @@ -1784,9 +1784,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.110" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -1914,9 +1914,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.7" +version = "0.23.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +checksum = "5a9b7ac41d92f2d2803f233e297127bac397df7b337e0460a1cc39d6c006dee4" dependencies = [ "indexmap", "toml_datetime", @@ -1941,9 +1941,9 @@ checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1952,9 +1952,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -1963,9 +1963,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", ] @@ -2160,9 +2160,9 @@ dependencies = [ [[package]] name = "utf8-width" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" +checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" [[package]] name = "utf8_iter" @@ -2203,9 +2203,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -2216,9 +2216,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2226,9 +2226,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", @@ -2239,9 +2239,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -2488,9 +2488,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -2785,9 +2785,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -2855,18 +2855,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", From e6bfed33ee453fa0bdd95f9f210c4c04dbab0113 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 6 Dec 2025 11:16:02 +0000 Subject: [PATCH 082/140] build(deps): bump the npm group across 1 directory with 7 updates Bumps the npm group with 7 updates in the /lib/binding_web directory: | Package | From | To | | --- | --- | --- | | [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) | `9.36.0` | `9.39.1` | | [@types/emscripten](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/emscripten) | `1.41.2` | `1.41.5` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `24.5.2` | `24.10.1` | | [esbuild](https://github.com/evanw/esbuild) | `0.25.10` | `0.27.0` | | [eslint](https://github.com/eslint/eslint) | `9.36.0` | `9.39.1` | | [tsx](https://github.com/privatenumber/tsx) | `4.20.5` | `4.21.0` | | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) | `8.44.1` | `8.48.1` | Updates `@eslint/js` from 9.36.0 to 9.39.1 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/commits/v9.39.1/packages/js) Updates `@types/emscripten` from 1.41.2 to 1.41.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/emscripten) Updates `@types/node` from 24.5.2 to 24.10.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `esbuild` from 0.25.10 to 0.27.0 - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md) - [Commits](https://github.com/evanw/esbuild/compare/v0.25.10...v0.27.0) Updates `eslint` from 9.36.0 to 9.39.1 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.36.0...v9.39.1) Updates `tsx` from 4.20.5 to 4.21.0 - [Release notes](https://github.com/privatenumber/tsx/releases) - [Changelog](https://github.com/privatenumber/tsx/blob/master/release.config.cjs) - [Commits](https://github.com/privatenumber/tsx/compare/v4.20.5...v4.21.0) Updates `typescript-eslint` from 8.44.1 to 8.48.1 - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.1/packages/typescript-eslint) --- updated-dependencies: - dependency-name: "@eslint/js" dependency-version: 9.39.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm - dependency-name: "@types/emscripten" dependency-version: 1.41.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm - dependency-name: "@types/node" dependency-version: 24.10.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm - dependency-name: esbuild dependency-version: 0.27.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm - dependency-name: eslint dependency-version: 9.39.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm - dependency-name: tsx dependency-version: 4.21.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm - dependency-name: typescript-eslint dependency-version: 8.48.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm ... Signed-off-by: dependabot[bot] --- lib/binding_web/package-lock.json | 1145 ++++++++++++++++++----------- lib/binding_web/package.json | 14 +- 2 files changed, 712 insertions(+), 447 deletions(-) diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index 53c89f97..c4ab9e4f 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -9,17 +9,17 @@ "version": "0.26.0", "license": "MIT", "devDependencies": { - "@eslint/js": "^9.20.0", - "@types/emscripten": "^1.40.0", - "@types/node": "^24.3.0", + "@eslint/js": "^9.39.1", + "@types/emscripten": "^1.41.5", + "@types/node": "^24.10.1", "@vitest/coverage-v8": "^3.0.5", "dts-buddy": "^0.6.2", - "esbuild": "^0.25.0", - "eslint": "^9.20.0", + "esbuild": "^0.27.0", + "eslint": "^9.39.1", "source-map": "^0.7.4", - "tsx": "^4.19.2", + "tsx": "^4.21.0", "typescript": "^5.7.3", - "typescript-eslint": "^8.23.0", + "typescript-eslint": "^8.48.1", "vitest": "^3.0.5" } }, @@ -98,9 +98,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", - "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", "cpu": [ "ppc64" ], @@ -115,9 +115,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", - "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", "cpu": [ "arm" ], @@ -132,9 +132,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", - "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", "cpu": [ "arm64" ], @@ -149,9 +149,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", - "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", "cpu": [ "x64" ], @@ -166,9 +166,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", - "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", "cpu": [ "arm64" ], @@ -183,9 +183,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", - "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", "cpu": [ "x64" ], @@ -200,9 +200,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", - "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", "cpu": [ "arm64" ], @@ -217,9 +217,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", - "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", "cpu": [ "x64" ], @@ -234,9 +234,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", - "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", "cpu": [ "arm" ], @@ -251,9 +251,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", - "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", "cpu": [ "arm64" ], @@ -268,9 +268,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", - "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", "cpu": [ "ia32" ], @@ -285,9 +285,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", - "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", "cpu": [ "loong64" ], @@ -302,9 +302,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", - "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", "cpu": [ "mips64el" ], @@ -319,9 +319,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", - "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", "cpu": [ "ppc64" ], @@ -336,9 +336,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", - "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", "cpu": [ "riscv64" ], @@ -353,9 +353,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", - "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", "cpu": [ "s390x" ], @@ -370,9 +370,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", - "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", "cpu": [ "x64" ], @@ -387,9 +387,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", - "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", "cpu": [ "arm64" ], @@ -404,9 +404,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", - "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", "cpu": [ "x64" ], @@ -421,9 +421,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", - "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", "cpu": [ "arm64" ], @@ -438,9 +438,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", - "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", "cpu": [ "x64" ], @@ -455,9 +455,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", - "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", "cpu": [ "arm64" ], @@ -472,9 +472,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", - "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", "cpu": [ "x64" ], @@ -489,9 +489,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", - "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", "cpu": [ "arm64" ], @@ -506,9 +506,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", - "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", "cpu": [ "ia32" ], @@ -523,9 +523,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", - "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", "cpu": [ "x64" ], @@ -582,13 +582,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", - "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -597,19 +597,22 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", - "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -644,9 +647,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz", - "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "dev": true, "license": "MIT", "engines": { @@ -657,9 +660,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -667,13 +670,13 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -838,44 +841,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1185,9 +1150,9 @@ "license": "MIT" }, "node_modules/@types/emscripten": { - "version": "1.41.2", - "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.2.tgz", - "integrity": "sha512-0EVXosRnffZuF+rsMM1ZVbfpwpvL2/hWycYQ/0GaH/VaoSJvcSmMl6fiPel9TZXHL3EhANxzqKOVFC6NFXyn8A==", + "version": "1.41.5", + "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.41.5.tgz", + "integrity": "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q==", "dev": true, "license": "MIT" }, @@ -1206,28 +1171,28 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.5.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.5.2.tgz", - "integrity": "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==", + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "undici-types": "~7.12.0" + "undici-types": "~7.16.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz", - "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.48.1.tgz", + "integrity": "sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.44.1", - "@typescript-eslint/type-utils": "8.44.1", - "@typescript-eslint/utils": "8.44.1", - "@typescript-eslint/visitor-keys": "8.44.1", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/type-utils": "8.48.1", + "@typescript-eslint/utils": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -1241,7 +1206,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.44.1", + "@typescript-eslint/parser": "^8.48.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } @@ -1257,17 +1222,17 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz", - "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.48.1.tgz", + "integrity": "sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.44.1", - "@typescript-eslint/types": "8.44.1", - "@typescript-eslint/typescript-estree": "8.44.1", - "@typescript-eslint/visitor-keys": "8.44.1", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4" }, "engines": { @@ -1283,14 +1248,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz", - "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz", + "integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.44.1", - "@typescript-eslint/types": "^8.44.1", + "@typescript-eslint/tsconfig-utils": "^8.48.1", + "@typescript-eslint/types": "^8.48.1", "debug": "^4.3.4" }, "engines": { @@ -1305,14 +1270,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz", - "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz", + "integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.1", - "@typescript-eslint/visitor-keys": "8.44.1" + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1323,9 +1288,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz", - "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz", + "integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==", "dev": true, "license": "MIT", "engines": { @@ -1340,15 +1305,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz", - "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.48.1.tgz", + "integrity": "sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.1", - "@typescript-eslint/typescript-estree": "8.44.1", - "@typescript-eslint/utils": "8.44.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/utils": "8.48.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -1365,9 +1330,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz", - "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", + "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", "dev": true, "license": "MIT", "engines": { @@ -1379,21 +1344,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz", - "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz", + "integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.1", - "@typescript-eslint/tsconfig-utils": "8.44.1", - "@typescript-eslint/types": "8.44.1", - "@typescript-eslint/visitor-keys": "8.44.1", + "@typescript-eslint/project-service": "8.48.1", + "@typescript-eslint/tsconfig-utils": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", + "tinyglobby": "^0.2.15", "ts-api-utils": "^2.1.0" }, "engines": { @@ -1434,16 +1398,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz", - "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz", + "integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.1", - "@typescript-eslint/types": "8.44.1", - "@typescript-eslint/typescript-estree": "8.44.1" + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1458,13 +1422,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz", - "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", + "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/types": "8.48.1", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -1741,19 +1705,6 @@ "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1953,9 +1904,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.25.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", - "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1966,32 +1917,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.10", - "@esbuild/android-arm": "0.25.10", - "@esbuild/android-arm64": "0.25.10", - "@esbuild/android-x64": "0.25.10", - "@esbuild/darwin-arm64": "0.25.10", - "@esbuild/darwin-x64": "0.25.10", - "@esbuild/freebsd-arm64": "0.25.10", - "@esbuild/freebsd-x64": "0.25.10", - "@esbuild/linux-arm": "0.25.10", - "@esbuild/linux-arm64": "0.25.10", - "@esbuild/linux-ia32": "0.25.10", - "@esbuild/linux-loong64": "0.25.10", - "@esbuild/linux-mips64el": "0.25.10", - "@esbuild/linux-ppc64": "0.25.10", - "@esbuild/linux-riscv64": "0.25.10", - "@esbuild/linux-s390x": "0.25.10", - "@esbuild/linux-x64": "0.25.10", - "@esbuild/netbsd-arm64": "0.25.10", - "@esbuild/netbsd-x64": "0.25.10", - "@esbuild/openbsd-arm64": "0.25.10", - "@esbuild/openbsd-x64": "0.25.10", - "@esbuild/openharmony-arm64": "0.25.10", - "@esbuild/sunos-x64": "0.25.10", - "@esbuild/win32-arm64": "0.25.10", - "@esbuild/win32-ia32": "0.25.10", - "@esbuild/win32-x64": "0.25.10" + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" } }, "node_modules/escape-string-regexp": { @@ -2008,26 +1959,25 @@ } }, "node_modules/eslint": { - "version": "9.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz", - "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.1", - "@eslint/core": "^0.15.2", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.36.0", - "@eslint/plugin-kit": "^0.3.5", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", @@ -2190,36 +2140,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2234,16 +2154,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -2257,19 +2167,6 @@ "node": ">=16.0.0" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2520,16 +2417,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2764,30 +2651,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2985,19 +2848,6 @@ "dev": true, "license": "ISC" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -3047,27 +2897,6 @@ "node": ">=6" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3088,17 +2917,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rollup": { "version": "4.49.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", @@ -3139,30 +2957,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -3543,19 +3337,6 @@ "node": ">=14.0.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -3570,14 +3351,14 @@ } }, "node_modules/tsx": { - "version": "4.20.5", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.5.tgz", - "integrity": "sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "esbuild": "~0.25.0", + "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -3619,16 +3400,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.44.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.1.tgz", - "integrity": "sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==", + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.48.1.tgz", + "integrity": "sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.44.1", - "@typescript-eslint/parser": "8.44.1", - "@typescript-eslint/typescript-estree": "8.44.1", - "@typescript-eslint/utils": "8.44.1" + "@typescript-eslint/eslint-plugin": "8.48.1", + "@typescript-eslint/parser": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1", + "@typescript-eslint/utils": "8.48.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3643,9 +3424,9 @@ } }, "node_modules/undici-types": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.12.0.tgz", - "integrity": "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, @@ -3758,6 +3539,490 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, "node_modules/vite/node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index 8faf9ecb..04a19c5d 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -69,17 +69,17 @@ "web-tree-sitter.d.cts.map" ], "devDependencies": { - "@eslint/js": "^9.20.0", - "@types/emscripten": "^1.40.0", - "@types/node": "^24.3.0", + "@eslint/js": "^9.39.1", + "@types/emscripten": "^1.41.5", + "@types/node": "^24.10.1", "@vitest/coverage-v8": "^3.0.5", "dts-buddy": "^0.6.2", - "esbuild": "^0.25.0", - "eslint": "^9.20.0", + "esbuild": "^0.27.0", + "eslint": "^9.39.1", "source-map": "^0.7.4", - "tsx": "^4.19.2", + "tsx": "^4.21.0", "typescript": "^5.7.3", - "typescript-eslint": "^8.23.0", + "typescript-eslint": "^8.48.1", "vitest": "^3.0.5" }, "scripts": { From bec7c3272b7b05bc316e179f5eb0db1a3792ff59 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 7 Dec 2025 04:09:22 -0500 Subject: [PATCH 083/140] fix(loader)!: correct arguments passed to `select_language` --- crates/cli/src/main.rs | 27 ++++++++++++++++++--------- crates/loader/src/loader.rs | 14 ++++++++++---- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 20255d62..81a67991 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1109,7 +1109,7 @@ impl Parse { let path = Path::new(&path); let language = loader .select_language( - path, + Some(path), current_dir, self.scope.as_deref(), lib_info.as_ref(), @@ -1140,7 +1140,12 @@ impl Parse { let language = if let Some(ref lib_path) = self.lib_path { &loader - .select_language(lib_path, current_dir, None, lib_info.as_ref()) + .select_language( + None, + current_dir, + self.scope.as_deref(), + lib_info.as_ref(), + ) .with_context(|| { anyhow!( "Failed to load language for path \"{}\"", @@ -1174,8 +1179,12 @@ impl Parse { let path = get_tmp_source_file(&contents)?; let name = "stdin"; - let language = - loader.select_language(&path, current_dir, None, lib_info.as_ref())?; + let language = loader.select_language( + None, + current_dir, + self.scope.as_deref(), + lib_info.as_ref(), + )?; parse::parse_file_at_path( &mut parser, @@ -1256,7 +1265,7 @@ impl Test { let lib_info = get_lib_info(self.lib_path.as_ref(), self.lang_name.as_ref(), current_dir); &loader - .select_language(lib_path, current_dir, None, lib_info.as_ref()) + .select_language(None, current_dir, None, lib_info.as_ref()) .with_context(|| { anyhow!( "Failed to load language for path \"{}\"", @@ -1437,7 +1446,7 @@ impl Fuzz { let lang_name = lib_info.1.to_string(); &( loader - .select_language(lib_path, current_dir, None, Some(&lib_info)) + .select_language(None, current_dir, None, Some(&lib_info)) .with_context(|| { anyhow!( "Failed to load language for path \"{}\"", @@ -1505,7 +1514,7 @@ impl Query { match input { CliInput::Paths(paths) => { let language = loader.select_language( - Path::new(&paths[0]), + Some(Path::new(&paths[0])), current_dir, self.scope.as_deref(), lib_info.as_ref(), @@ -1541,7 +1550,7 @@ impl Query { let languages = loader.languages_at_path(current_dir)?; let language = if let Some(ref lib_path) = self.lib_path { &loader - .select_language(lib_path, current_dir, None, lib_info.as_ref()) + .select_language(None, current_dir, None, lib_info.as_ref()) .with_context(|| { anyhow!( "Failed to load language for path \"{}\"", @@ -1575,7 +1584,7 @@ impl Query { let path = get_tmp_source_file(&contents)?; let language = - loader.select_language(&path, current_dir, None, lib_info.as_ref())?; + loader.select_language(None, current_dir, None, lib_info.as_ref())?; let opts = QueryFileOptions { ordered_captures: self.captures, byte_range, diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 00108506..16819cc4 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1702,7 +1702,7 @@ impl Loader { pub fn select_language( &mut self, - path: &Path, + path: Option<&Path>, current_dir: &Path, scope: Option<&str>, // path to dynamic library, name of language @@ -1720,7 +1720,7 @@ impl Loader { } else { Err(LoaderError::UnknownScope(scope.to_string())) } - } else if let Some((lang, _)) = + } else if let Some((lang, _)) = if let Some(path) = path { self.language_configuration_for_file_name(path) .map_err(|e| { LoaderError::FileNameLoad( @@ -1728,7 +1728,9 @@ impl Loader { Box::new(e), ) })? - { + } else { + None + } { Ok(lang) } else if let Some(id) = self.language_configuration_in_current_path { Ok(self.language_for_id(self.language_configurations[id].language_id)?) @@ -1739,7 +1741,11 @@ impl Loader { .cloned() { Ok(lang.0) - } else if let Some(lang) = self.language_configuration_for_first_line_regex(path)? { + } else if let Some(lang) = if let Some(path) = path { + self.language_configuration_for_first_line_regex(path)? + } else { + None + } { Ok(lang.0) } else { Err(LoaderError::NoLanguage) From 3182efeccc5de2f50d4611466607222a29a4b059 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Wed, 1 Oct 2025 11:39:37 +0300 Subject: [PATCH 084/140] feat(bindings): add byproducts to cmake --- crates/cli/src/init.rs | 7 +++++-- crates/cli/src/templates/cmakelists.cmake | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 6d821f04..9eacdb25 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -743,13 +743,16 @@ pub fn generate_grammar_files( "#}, indoc! {r#" add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" + "${CMAKE_CURRENT_SOURCE_DIR}/src/node-types.json" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/grammar.js" - COMMAND "${TREE_SITTER_CLI}" generate grammar.js - --no-parser + COMMAND "${TREE_SITTER_CLI}" generate grammar.js --no-parser WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating grammar.json") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" + BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/parser.h" + "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/alloc.h" + "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/array.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json --abi=${TREE_SITTER_ABI_VERSION} diff --git a/crates/cli/src/templates/cmakelists.cmake b/crates/cli/src/templates/cmakelists.cmake index b0f4f790..06acbc8f 100644 --- a/crates/cli/src/templates/cmakelists.cmake +++ b/crates/cli/src/templates/cmakelists.cmake @@ -20,13 +20,16 @@ include(GNUInstallDirs) find_program(TREE_SITTER_CLI tree-sitter DOC "Tree-sitter CLI") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" + "${CMAKE_CURRENT_SOURCE_DIR}/src/node-types.json" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/grammar.js" - COMMAND "${TREE_SITTER_CLI}" generate grammar.js - --no-parser + COMMAND "${TREE_SITTER_CLI}" generate grammar.js --no-parser WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMMENT "Generating grammar.json") add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/parser.c" + BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/parser.h" + "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/alloc.h" + "${CMAKE_CURRENT_SOURCE_DIR}/src/tree_sitter/array.h" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/grammar.json" COMMAND "${TREE_SITTER_CLI}" generate src/grammar.json --abi=${TREE_SITTER_ABI_VERSION} From 8ca17d1bb174633fca8cf662483b4ff145a2eba6 Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Sun, 28 Sep 2025 10:44:05 +0300 Subject: [PATCH 085/140] ci(release): enable trusted publishing & attestations --- .github/workflows/release.yml | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 11b0d27b..2d692c02 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,8 @@ jobs: runs-on: ubuntu-latest needs: build permissions: + id-token: write + attestations: write contents: write steps: - name: Checkout repository @@ -47,9 +49,16 @@ jobs: rm -rf artifacts ls -l target/ + - name: Generate attestations + uses: actions/attest-build-provenance@v3 + with: + subject-path: | + target/tree-sitter-*.gz + target/web-tree-sitter.tar.gz + - name: Create release run: |- - gh release create ${{ github.ref_name }} \ + gh release create $GITHUB_REF_NAME \ target/tree-sitter-*.gz \ target/web-tree-sitter.tar.gz env: @@ -58,6 +67,10 @@ jobs: crates_io: name: Publish packages to Crates.io runs-on: ubuntu-latest + environment: crates + permissions: + id-token: write + contents: read needs: release steps: - name: Checkout repository @@ -66,14 +79,22 @@ jobs: - name: Set up Rust uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Set up registry token + id: auth + uses: rust-lang/crates-io-auth-action@v1 + - name: Publish crates to Crates.io uses: katyo/publish-crates@v2 with: - registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} + registry-token: ${{ steps.auth.outputs.token }} npm: name: Publish packages to npmjs.com runs-on: ubuntu-latest + environment: npm + permissions: + id-token: write + contents: read needs: release strategy: fail-fast: false @@ -106,5 +127,3 @@ jobs: - name: Publish to npmjs.com working-directory: ${{ matrix.directory }} run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From b9c2d1dc8900e8ee9a5d9e04d3f135c8638d2b3f Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Tue, 5 Aug 2025 22:40:48 +0300 Subject: [PATCH 086/140] feat(bindings): add Java bindings --- crates/cli/src/init.rs | 128 +++++++++++++++++--- crates/cli/src/main.rs | 10 ++ crates/cli/src/templates/.editorconfig | 6 +- crates/cli/src/templates/binding.java | 65 +++++++++++ crates/cli/src/templates/gitattributes | 4 + crates/cli/src/templates/gitignore | 1 + crates/cli/src/templates/pom.xml | 154 +++++++++++++++++++++++++ crates/cli/src/templates/test.java | 12 ++ crates/loader/src/loader.rs | 11 +- 9 files changed, 369 insertions(+), 22 deletions(-) create mode 100644 crates/cli/src/templates/binding.java create mode 100644 crates/cli/src/templates/pom.xml create mode 100644 crates/cli/src/templates/test.java diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 9eacdb25..b0cdb586 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -36,6 +36,8 @@ const PARSER_CLASS_NAME_PLACEHOLDER: &str = "PARSER_CLASS_NAME"; const PARSER_DESCRIPTION_PLACEHOLDER: &str = "PARSER_DESCRIPTION"; const PARSER_LICENSE_PLACEHOLDER: &str = "PARSER_LICENSE"; +const PARSER_NS_PLACEHOLDER: &str = "PARSER_NS"; +const PARSER_NS_CLEANED_PLACEHOLDER: &str = "PARSER_NS_CLEANED"; const PARSER_URL_PLACEHOLDER: &str = "PARSER_URL"; const PARSER_URL_STRIPPED_PLACEHOLDER: &str = "PARSER_URL_STRIPPED"; const PARSER_VERSION_PLACEHOLDER: &str = "PARSER_VERSION"; @@ -58,6 +60,11 @@ const AUTHOR_BLOCK_RS: &str = "\nauthors = ["; const AUTHOR_NAME_PLACEHOLDER_RS: &str = "PARSER_AUTHOR_NAME"; const AUTHOR_EMAIL_PLACEHOLDER_RS: &str = " PARSER_AUTHOR_EMAIL"; +const AUTHOR_BLOCK_JAVA: &str = "\n "; +const AUTHOR_NAME_PLACEHOLDER_JAVA: &str = "\n PARSER_AUTHOR_NAME"; +const AUTHOR_EMAIL_PLACEHOLDER_JAVA: &str = "\n PARSER_AUTHOR_EMAIL"; +const AUTHOR_URL_PLACEHOLDER_JAVA: &str = "\n PARSER_AUTHOR_URL"; + const AUTHOR_BLOCK_GRAMMAR: &str = "\n * @author "; const AUTHOR_NAME_PLACEHOLDER_GRAMMAR: &str = "PARSER_AUTHOR_NAME"; const AUTHOR_EMAIL_PLACEHOLDER_GRAMMAR: &str = " PARSER_AUTHOR_EMAIL"; @@ -107,6 +114,10 @@ const TEST_BINDING_PY_TEMPLATE: &str = include_str!("./templates/test_binding.py const PACKAGE_SWIFT_TEMPLATE: &str = include_str!("./templates/package.swift"); const TESTS_SWIFT_TEMPLATE: &str = include_str!("./templates/tests.swift"); +const POM_XML_TEMPLATE: &str = include_str!("./templates/pom.xml"); +const BINDING_JAVA_TEMPLATE: &str = include_str!("./templates/binding.java"); +const TEST_JAVA_TEMPLATE: &str = include_str!("./templates/test.java"); + const BUILD_ZIG_TEMPLATE: &str = include_str!("./templates/build.zig"); const BUILD_ZIG_ZON_TEMPLATE: &str = include_str!("./templates/build.zig.zon"); const ROOT_ZIG_TEMPLATE: &str = include_str!("./templates/root.zig"); @@ -134,6 +145,7 @@ pub struct JsonConfigOpts { pub email: Option, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, + pub namespace: Option, pub bindings: Bindings, } @@ -174,7 +186,7 @@ impl JsonConfigOpts { }), funding: self.funding, }), - namespace: None, + namespace: self.namespace, }, bindings: self.bindings, } @@ -197,6 +209,7 @@ impl Default for JsonConfigOpts { author: String::new(), email: None, url: None, + namespace: None, bindings: Bindings::default(), } } @@ -218,6 +231,7 @@ struct GenerateOpts<'a> { injections_query_path: &'a str, locals_query_path: &'a str, tags_query_path: &'a str, + namespace: Option<&'a str>, } pub fn generate_grammar_files( @@ -311,6 +325,7 @@ pub fn generate_grammar_files( tags_query_path: tree_sitter_config.grammars[0] .tags .to_variable_value(&default_tags_path), + namespace: tree_sitter_config.metadata.namespace.as_deref(), }; // Create package.json @@ -1048,6 +1063,45 @@ pub fn generate_grammar_files( })?; } + // Generate Java bindings + if tree_sitter_config.bindings.java { + missing_path(repo_path.join("pom.xml"), |path| { + generate_file(path, POM_XML_TEMPLATE, language_name, &generate_opts) + })?; + + missing_path(bindings_dir.join("java"), create_dir)?.apply(|path| { + missing_path(path.join("main"), create_dir)?.apply(|path| { + let package_path = generate_opts + .namespace + .unwrap_or("io.github.treesitter") + .replace(['-', '_'], "") + .split('.') + .fold(path.to_path_buf(), |path, dir| path.join(dir)) + .join("jtreesitter") + .join(language_name.to_lowercase().replace('_', "")); + missing_path(package_path, create_dir)?.apply(|path| { + missing_path(path.join(format!("{class_name}.java")), |path| { + generate_file(path, BINDING_JAVA_TEMPLATE, language_name, &generate_opts) + })?; + + Ok(()) + })?; + + Ok(()) + })?; + + missing_path(path.join("test"), create_dir)?.apply(|path| { + missing_path(path.join(format!("{class_name}Test.java")), |path| { + generate_file(path, TEST_JAVA_TEMPLATE, language_name, &generate_opts) + })?; + + Ok(()) + })?; + + Ok(()) + })?; + } + Ok(()) } @@ -1097,6 +1151,15 @@ fn generate_file( ) -> Result<()> { let filename = path.file_name().unwrap().to_str().unwrap(); + let lower_parser_name = if path + .extension() + .is_some_and(|e| e.eq_ignore_ascii_case("java")) + { + language_name.to_snake_case().replace('_', "") + } else { + language_name.to_snake_case() + }; + let mut replacement = template .replace( CAMEL_PARSER_NAME_PLACEHOLDER, @@ -1110,14 +1173,11 @@ fn generate_file( UPPER_PARSER_NAME_PLACEHOLDER, &language_name.to_shouty_snake_case(), ) - .replace( - LOWER_PARSER_NAME_PLACEHOLDER, - &language_name.to_snake_case(), - ) .replace( KEBAB_PARSER_NAME_PLACEHOLDER, &language_name.to_kebab_case(), ) + .replace(LOWER_PARSER_NAME_PLACEHOLDER, &lower_parser_name) .replace(PARSER_NAME_PLACEHOLDER, language_name) .replace(CLI_VERSION_PLACEHOLDER, CLI_VERSION) .replace(RUST_BINDING_VERSION_PLACEHOLDER, RUST_BINDING_VERSION) @@ -1157,6 +1217,9 @@ fn generate_file( "Cargo.toml" => { replacement = replacement.replace(AUTHOR_NAME_PLACEHOLDER_RS, ""); } + "pom.xml" => { + replacement = replacement.replace(AUTHOR_NAME_PLACEHOLDER_JAVA, ""); + } _ => {} } } @@ -1182,30 +1245,52 @@ fn generate_file( "Cargo.toml" => { replacement = replacement.replace(AUTHOR_EMAIL_PLACEHOLDER_RS, ""); } + "pom.xml" => { + replacement = replacement.replace(AUTHOR_EMAIL_PLACEHOLDER_JAVA, ""); + } _ => {} } } - if filename == "package.json" { - if let Some(url) = generate_opts.author_url { + match (generate_opts.author_url, filename) { + (Some(url), "package.json" | "pom.xml") => { replacement = replacement.replace(AUTHOR_URL_PLACEHOLDER, url); - } else { + } + (None, "package.json") => { replacement = replacement.replace(AUTHOR_URL_PLACEHOLDER_JS, ""); } + (None, "pom.xml") => { + replacement = replacement.replace(AUTHOR_URL_PLACEHOLDER_JAVA, ""); + } + _ => {} } if generate_opts.author_name.is_none() && generate_opts.author_email.is_none() && generate_opts.author_url.is_none() - && filename == "package.json" { - if let Some(start_idx) = replacement.find(AUTHOR_BLOCK_JS) { - if let Some(end_idx) = replacement[start_idx..] - .find("},") - .map(|i| i + start_idx + 2) - { - replacement.replace_range(start_idx..end_idx, ""); + match filename { + "package.json" => { + if let Some(start_idx) = replacement.find(AUTHOR_BLOCK_JS) { + if let Some(end_idx) = replacement[start_idx..] + .find("},") + .map(|i| i + start_idx + 2) + { + replacement.replace_range(start_idx..end_idx, ""); + } + } } + "pom.xml" => { + if let Some(start_idx) = replacement.find(AUTHOR_BLOCK_JAVA) { + if let Some(end_idx) = replacement[start_idx..] + .find("") + .map(|i| i + start_idx + 12) + { + replacement.replace_range(start_idx..end_idx, ""); + } + } + } + _ => {} } } else if generate_opts.author_name.is_none() && generate_opts.author_email.is_none() { match filename { @@ -1286,6 +1371,19 @@ fn generate_file( ); } + if let Some(namespace) = generate_opts.namespace { + replacement = replacement + .replace( + PARSER_NS_CLEANED_PLACEHOLDER, + &namespace.replace(['-', '_'], ""), + ) + .replace(PARSER_NS_PLACEHOLDER, namespace); + } else { + replacement = replacement + .replace(PARSER_NS_CLEANED_PLACEHOLDER, "io.github.treesitter") + .replace(PARSER_NS_PLACEHOLDER, "io.github.tree-sitter"); + } + if let Some(funding_url) = generate_opts.funding { match filename { "pyproject.toml" | "package.json" => { diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 81a67991..937e54b4 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -772,6 +772,14 @@ impl Init { .map(|e| Some(e.trim().to_string())) }; + let namespace = || { + Input::::with_theme(&ColorfulTheme::default()) + .with_prompt("Package namespace") + .default("io.github.tree-sitter".to_string()) + .allow_empty(true) + .interact() + }; + let bindings = || { let languages = Bindings::default().languages(); @@ -801,6 +809,7 @@ impl Init { "author", "email", "url", + "namespace", "bindings", "exit", ]; @@ -821,6 +830,7 @@ impl Init { "author" => opts.author = author()?, "email" => opts.email = email()?, "url" => opts.url = url()?, + "namespace" => opts.namespace = Some(namespace()?), "bindings" => opts.bindings = bindings()?, "exit" => break, _ => unreachable!(), diff --git a/crates/cli/src/templates/.editorconfig b/crates/cli/src/templates/.editorconfig index c4650c59..ff17b12f 100644 --- a/crates/cli/src/templates/.editorconfig +++ b/crates/cli/src/templates/.editorconfig @@ -3,7 +3,7 @@ root = true [*] charset = utf-8 -[*.{json,toml,yml,gyp}] +[*.{json,toml,yml,gyp,xml}] indent_style = space indent_size = 2 @@ -31,6 +31,10 @@ indent_size = 4 indent_style = space indent_size = 4 +[*.java] +indent_style = space +indent_size = 4 + [*.go] indent_style = tab indent_size = 8 diff --git a/crates/cli/src/templates/binding.java b/crates/cli/src/templates/binding.java new file mode 100644 index 00000000..704064a0 --- /dev/null +++ b/crates/cli/src/templates/binding.java @@ -0,0 +1,65 @@ +package PARSER_NS_CLEANED.jtreesitter.LOWER_PARSER_NAME; + +import java.lang.foreign.*; + +public final class PARSER_CLASS_NAME { + private static final ValueLayout VOID_PTR = + ValueLayout.ADDRESS.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE, ValueLayout.JAVA_BYTE)); + private static final FunctionDescriptor FUNC_DESC = FunctionDescriptor.of(VOID_PTR); + private static final Linker LINKER = Linker.nativeLinker(); + private static final PARSER_CLASS_NAME INSTANCE = new PARSER_CLASS_NAME(); + + private final Arena arena = Arena.ofAuto(); + private volatile SymbolLookup lookup = null; + + private PARSER_CLASS_NAME() {} + + /** + * Get the tree-sitter language for this grammar. + */ + public static MemorySegment language() { + if (INSTANCE.lookup == null) + INSTANCE.lookup = INSTANCE.findLibrary(); + return language(INSTANCE.lookup); + } + + /** + * Get the tree-sitter language for this grammar. + * + * The {@linkplain Arena} used in the {@code lookup} + * must not be closed while the language is being used. + */ + public static MemorySegment language(SymbolLookup lookup) { + return call(lookup, "tree_sitter_PARSER_NAME"); + } + + private SymbolLookup findLibrary() { + try { + var library = System.mapLibraryName("tree-sitter-KEBAB_PARSER_NAME"); + return SymbolLookup.libraryLookup(library, arena); + } catch (IllegalArgumentException ex1) { + try { + System.loadLibrary("tree-sitter-KEBAB_PARSER_NAME"); + return SymbolLookup.loaderLookup(); + } catch (UnsatisfiedLinkError ex2) { + ex1.addSuppressed(ex2); + throw ex1; + } + } + } + + private static UnsatisfiedLinkError unresolved(String name) { + return new UnsatisfiedLinkError("Unresolved symbol: %s".formatted(name)); + } + + @SuppressWarnings("SameParameterValue") + private static MemorySegment call(SymbolLookup lookup, String name) throws UnsatisfiedLinkError { + var address = lookup.find(name).orElseThrow(() -> unresolved(name)); + try { + var function = LINKER.downcallHandle(address, FUNC_DESC); + return (MemorySegment) function.invokeExact(); + } catch (Throwable e) { + throw new RuntimeException("Call to %s failed".formatted(name), e); + } + } +} diff --git a/crates/cli/src/templates/gitattributes b/crates/cli/src/templates/gitattributes index 7772c942..027ac707 100644 --- a/crates/cli/src/templates/gitattributes +++ b/crates/cli/src/templates/gitattributes @@ -40,3 +40,7 @@ Package.resolved linguist-generated bindings/zig/* linguist-generated build.zig linguist-generated build.zig.zon linguist-generated + +# Java bindings +pom.xml linguist-generated +bindings/java/** linguist-generated diff --git a/crates/cli/src/templates/gitignore b/crates/cli/src/templates/gitignore index bc9e191a..7c0cb7f5 100644 --- a/crates/cli/src/templates/gitignore +++ b/crates/cli/src/templates/gitignore @@ -45,3 +45,4 @@ zig-out/ *.tar.gz *.tgz *.zip +*.jar diff --git a/crates/cli/src/templates/pom.xml b/crates/cli/src/templates/pom.xml new file mode 100644 index 00000000..661fe42b --- /dev/null +++ b/crates/cli/src/templates/pom.xml @@ -0,0 +1,154 @@ + + + 4.0.0 + PARSER_NS + jtreesitter-KEBAB_PARSER_NAME + JTreeSitter CAMEL_PARSER_NAME + PARSER_VERSION + PARSER_DESCRIPTION + PARSER_URL + + + PARSER_LICENSE + https://spdx.org/licenses/PARSER_LICENSE.html + + + + + PARSER_AUTHOR_NAME + PARSER_AUTHOR_EMAIL + PARSER_AUTHOR_URL + + + + PARSER_URL + scm:git:git://PARSER_URL_STRIPPED.git + scm:git:ssh://PARSER_URL_STRIPPED.git + + + 23 + UTF-8 + true + true + false + true + + + + io.github.tree-sitter + jtreesitter + 0.26.0 + true + + + org.junit.jupiter + junit-jupiter-api + 6.0.1 + test + + + + bindings/java/main + bindings/java/test + + + maven-surefire-plugin + 3.5.4 + + + ${project.build.directory}/reports/surefire + + --enable-native-access=ALL-UNNAMED + + + + maven-javadoc-plugin + 3.12.0 + + + + jar + + + + + public + true + true + all,-missing + + + + maven-source-plugin + 3.3.1 + + + + jar-no-fork + + + + + + maven-gpg-plugin + 3.2.8 + + + verify + + sign + + + true + + --no-tty + --pinentry-mode + loopback + + + + + + + io.github.mavenplugins + central-publishing-maven-plugin + 1.1.1 + + + deploy + + publish + + + validated + ${publish.auto} + ${publish.skip} + ${project.artifactId}-${project.version}.zip + ${project.artifactId}-${project.version}.zip + + + + true + + + + + + ci + + + env.CI + true + + + + false + true + false + + + + diff --git a/crates/cli/src/templates/test.java b/crates/cli/src/templates/test.java new file mode 100644 index 00000000..8bf81ea0 --- /dev/null +++ b/crates/cli/src/templates/test.java @@ -0,0 +1,12 @@ +import io.github.treesitter.jtreesitter.Language; +import PARSER_NS_CLEANED.jtreesitter.LOWER_PARSER_NAME.PARSER_CLASS_NAME; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class PARSER_CLASS_NAMETest { + @Test + public void testCanLoadLanguage() { + assertDoesNotThrow(() -> new Language(PARSER_CLASS_NAME.language())); + } +} diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 16819cc4..d64b89de 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -450,7 +450,6 @@ pub struct Links { pub struct Bindings { pub c: bool, pub go: bool, - #[serde(skip)] pub java: bool, #[serde(skip)] pub kotlin: bool, @@ -464,12 +463,12 @@ pub struct Bindings { impl Bindings { /// return available languages and its default enabled state. #[must_use] - pub const fn languages(&self) -> [(&'static str, bool); 7] { + pub const fn languages(&self) -> [(&'static str, bool); 8] { [ ("c", true), ("go", true), - // Comment out Java and Kotlin until the bindings are actually available. - // ("java", false), + ("java", false), + // Comment out Kotlin until the bindings are actually available. // ("kotlin", false), ("node", true), ("python", true), @@ -500,8 +499,8 @@ impl Bindings { match v { "c" => out.c = true, "go" => out.go = true, - // Comment out Java and Kotlin until the bindings are actually available. - // "java" => out.java = true, + "java" => out.java = true, + // Comment out Kotlin until the bindings are actually available. // "kotlin" => out.kotlin = true, "node" => out.node = true, "python" => out.python = true, From d861e2bcd9f9ca087cbc1de74acfc54c31395e7b Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Mon, 8 Dec 2025 18:43:15 +0200 Subject: [PATCH 087/140] docs(cli): list Java & Zig binding files --- docs/src/cli/init.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/src/cli/init.md b/docs/src/cli/init.md index 2d7d6847..b3b802eb 100644 --- a/docs/src/cli/init.md +++ b/docs/src/cli/init.md @@ -115,11 +115,11 @@ Each key is a language name, and the value is a boolean. - `c` (default: `true`) - `go` (default: `true`) - `java` (default: `false`) -- `kotlin` (default: `false`) - `node` (default: `true`) - `python` (default: `true`) - `rust` (default: `true`) - `swift` (default: `false`) +- `zig` (default: `false`) ## Binding Files @@ -153,6 +153,12 @@ if you have one. - `bindings/node/index.d.ts` — This file provides type hints for your parser when used in TypeScript. - `bindings/node/binding_test.js` — This file contains a test for the Node.js package. +### Java + +- `pom.xml` - This file is the manifest of the Maven package. +- `bindings/java/main/namespace/language/TreeSitterLanguage.java` - This file wraps your language in a Java class. +- `bindings/java/test/namespace/language/TreeSitterLanguageTest.java` - This file contains a test for the Java package. + ### Python - `pyproject.toml` — This file is the manifest of the Python package. @@ -175,6 +181,13 @@ if you have one. - `bindings/swift/TreeSitterLanguage/language.h` — This file wraps your language in a Swift module when used in Swift. - `bindings/swift/TreeSitterLanguageTests/TreeSitterLanguageTests.swift` — This file contains a test for the Swift package. +### Zig + +- `build.zig` - This file tells Zig how to compile your language. +- `build.zig.zon` - This file is the manifest of the Zig package. +- `bindings/zig/root.zig` - This file wraps your language in a Zig module. +- `bindings/zig/test.zig` - This file contains a test for the Zig package. + ### Additional Files Additionally, there's a few other files that are generated when you run `tree-sitter init`, From 974be3bb30282fdf545c5724bf4367786519a1b6 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 8 Dec 2025 15:15:38 -0500 Subject: [PATCH 088/140] fix(rust): specify workspace dependency of `tree-sitter-language` crate as "0.1" If a rust project depends on both the tree-sitter lib bindings and the language crate, cargo needs to be able to resolve a common version of the tree-sitter-language crate. Specifying exactly "0.1.5" for the lib bindings is overly restrictive, and could lead to future headaches. By specifying "0.1", any "0.1.x" version should be available to resolve to. --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 71cf0253..9461cbf0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -160,4 +160,4 @@ tree-sitter-config = { version = "0.26.0", path = "./crates/config" } tree-sitter-highlight = { version = "0.26.0", path = "./crates/highlight" } tree-sitter-tags = { version = "0.26.0", path = "./crates/tags" } -tree-sitter-language = { version = "0.1.5", path = "./crates/language" } +tree-sitter-language = { version = "0.1", path = "./crates/language" } From b0afbf376224724ba97c68a54e36b63b71939695 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:07:59 +0000 Subject: [PATCH 089/140] build(deps): bump wasmparser from 0.242.0 to 0.243.0 in the cargo group Bumps the cargo group with 1 update: [wasmparser](https://github.com/bytecodealliance/wasm-tools). Updates `wasmparser` from 0.242.0 to 0.243.0 - [Release notes](https://github.com/bytecodealliance/wasm-tools/releases) - [Commits](https://github.com/bytecodealliance/wasm-tools/commits) --- updated-dependencies: - dependency-name: wasmparser dependency-version: 0.243.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db44d925..103fb39a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2027,7 +2027,7 @@ dependencies = [ "tree-sitter-tests-proc-macro", "unindent", "walkdir", - "wasmparser 0.242.0", + "wasmparser 0.243.0", "webbrowser", "widestring", ] @@ -2271,9 +2271,9 @@ dependencies = [ [[package]] name = "wasmparser" -version = "0.242.0" +version = "0.243.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3c6e611f4cd748d85c767815823b777dc56afca793fcda27beae4e85028849" +checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d" dependencies = [ "bitflags 2.10.0", "hashbrown 0.15.5", diff --git a/Cargo.toml b/Cargo.toml index 9461cbf0..9faa4041 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -150,7 +150,7 @@ tiny_http = "0.12.0" topological-sort = "0.2.2" unindent = "0.2.4" walkdir = "2.5.0" -wasmparser = "0.242.0" +wasmparser = "0.243.0" webbrowser = "1.0.5" tree-sitter = { version = "0.26.0", path = "./lib" } From 8a3dcc6155a9faae677544303b6bc0caf1aef296 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 8 Dec 2025 16:06:45 -0500 Subject: [PATCH 090/140] release 0.26.1 --- CMakeLists.txt | 2 +- Cargo.lock | 14 +++++++------- Cargo.toml | 14 +++++++------- Makefile | 2 +- build.zig.zon | 2 +- crates/cli/npm/package-lock.json | 4 ++-- crates/cli/npm/package.json | 2 +- docs/src/cli/generate.md | 2 +- flake.nix | 2 +- lib/binding_web/package-lock.json | 4 ++-- lib/binding_web/package.json | 2 +- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f0d1d813..dd5cff28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13) project(tree-sitter - VERSION "0.26.0" + VERSION "0.26.1" DESCRIPTION "An incremental parsing system for programming tools" HOMEPAGE_URL "https://tree-sitter.github.io/tree-sitter/" LANGUAGES C) diff --git a/Cargo.lock b/Cargo.lock index 103fb39a..3382fe2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1972,7 +1972,7 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.26.0" +version = "0.26.1" dependencies = [ "bindgen", "cc", @@ -1986,7 +1986,7 @@ dependencies = [ [[package]] name = "tree-sitter-cli" -version = "0.26.0" +version = "0.26.1" dependencies = [ "ansi_colours", "anstyle", @@ -2034,7 +2034,7 @@ dependencies = [ [[package]] name = "tree-sitter-config" -version = "0.26.0" +version = "0.26.1" dependencies = [ "etcetera", "log", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "tree-sitter-generate" -version = "0.26.0" +version = "0.26.1" dependencies = [ "bitflags 2.10.0", "dunce", @@ -2068,7 +2068,7 @@ dependencies = [ [[package]] name = "tree-sitter-highlight" -version = "0.26.0" +version = "0.26.1" dependencies = [ "regex", "streaming-iterator", @@ -2082,7 +2082,7 @@ version = "0.1.5" [[package]] name = "tree-sitter-loader" -version = "0.26.0" +version = "0.26.1" dependencies = [ "cc", "etcetera", @@ -2104,7 +2104,7 @@ dependencies = [ [[package]] name = "tree-sitter-tags" -version = "0.26.0" +version = "0.26.1" dependencies = [ "memchr", "regex", diff --git a/Cargo.toml b/Cargo.toml index 9faa4041..9d16282f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.26.0" +version = "0.26.1" authors = [ "Max Brunsfeld ", "Amaan Qureshi ", @@ -153,11 +153,11 @@ walkdir = "2.5.0" wasmparser = "0.243.0" webbrowser = "1.0.5" -tree-sitter = { version = "0.26.0", path = "./lib" } -tree-sitter-generate = { version = "0.26.0", path = "./crates/generate" } -tree-sitter-loader = { version = "0.26.0", path = "./crates/loader" } -tree-sitter-config = { version = "0.26.0", path = "./crates/config" } -tree-sitter-highlight = { version = "0.26.0", path = "./crates/highlight" } -tree-sitter-tags = { version = "0.26.0", path = "./crates/tags" } +tree-sitter = { version = "0.26.1", path = "./lib" } +tree-sitter-generate = { version = "0.26.1", path = "./crates/generate" } +tree-sitter-loader = { version = "0.26.1", path = "./crates/loader" } +tree-sitter-config = { version = "0.26.1", path = "./crates/config" } +tree-sitter-highlight = { version = "0.26.1", path = "./crates/highlight" } +tree-sitter-tags = { version = "0.26.1", path = "./crates/tags" } tree-sitter-language = { version = "0.1", path = "./crates/language" } diff --git a/Makefile b/Makefile index f8106fa0..7d1f326f 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 0.26.0 +VERSION := 0.26.1 DESCRIPTION := An incremental parsing system for programming tools HOMEPAGE_URL := https://tree-sitter.github.io/tree-sitter/ diff --git a/build.zig.zon b/build.zig.zon index 48e52686..b68d7d53 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .tree_sitter, .fingerprint = 0x841224b447ac0d4f, - .version = "0.26.0", + .version = "0.26.1", .minimum_zig_version = "0.14.1", .paths = .{ "build.zig", diff --git a/crates/cli/npm/package-lock.json b/crates/cli/npm/package-lock.json index ae8bddb6..083474f6 100644 --- a/crates/cli/npm/package-lock.json +++ b/crates/cli/npm/package-lock.json @@ -1,12 +1,12 @@ { "name": "tree-sitter-cli", - "version": "0.26.0", + "version": "0.26.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "tree-sitter-cli", - "version": "0.26.0", + "version": "0.26.1", "hasInstallScript": true, "license": "MIT", "bin": { diff --git a/crates/cli/npm/package.json b/crates/cli/npm/package.json index 23835503..6e3e6029 100644 --- a/crates/cli/npm/package.json +++ b/crates/cli/npm/package.json @@ -1,6 +1,6 @@ { "name": "tree-sitter-cli", - "version": "0.26.0", + "version": "0.26.1", "author": { "name": "Max Brunsfeld", "email": "maxbrunsfeld@gmail.com" diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 6175381f..b56bb798 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -51,7 +51,7 @@ Report conflicts in a JSON format. ### `--js-runtime ` The path to the JavaScript runtime executable to use when generating the parser. The default is `node`. -Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.0, you can +Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.1, you can also pass in `native` to use the experimental native QuickJS runtime that comes bundled with the CLI. This avoids the dependency on a JavaScript runtime entirely. The native QuickJS runtime is compatible with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base grammars, the native runtime can be used *after* running `npm install`. diff --git a/flake.nix b/flake.nix index be7d1bad..3333670c 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ eachSystem = lib.genAttrs systems; pkgsFor = inputs.nixpkgs.legacyPackages; - version = "0.26.0"; + version = "0.26.1"; fs = lib.fileset; src = fs.toSource { diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index c4ab9e4f..02372d26 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -1,12 +1,12 @@ { "name": "web-tree-sitter", - "version": "0.26.0", + "version": "0.26.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-tree-sitter", - "version": "0.26.0", + "version": "0.26.1", "license": "MIT", "devDependencies": { "@eslint/js": "^9.39.1", diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index 04a19c5d..772078ac 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -1,6 +1,6 @@ { "name": "web-tree-sitter", - "version": "0.26.0", + "version": "0.26.1", "description": "Tree-sitter bindings for the web", "repository": { "type": "git", From 744e556f7ea96087bd8cc2433a2d1ce951684204 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 21:13:08 +0000 Subject: [PATCH 091/140] build(deps): bump esbuild Bumps the npm group with 1 update in the /lib/binding_web directory: [esbuild](https://github.com/evanw/esbuild). Updates `esbuild` from 0.27.0 to 0.27.1 - [Release notes](https://github.com/evanw/esbuild/releases) - [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG.md) - [Commits](https://github.com/evanw/esbuild/compare/v0.27.0...v0.27.1) --- updated-dependencies: - dependency-name: esbuild dependency-version: 0.27.1 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm ... Signed-off-by: dependabot[bot] --- lib/binding_web/package-lock.json | 216 +++++++++++++++--------------- lib/binding_web/package.json | 2 +- 2 files changed, 109 insertions(+), 109 deletions(-) diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index 02372d26..ae02badc 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -14,7 +14,7 @@ "@types/node": "^24.10.1", "@vitest/coverage-v8": "^3.0.5", "dts-buddy": "^0.6.2", - "esbuild": "^0.27.0", + "esbuild": "^0.27.1", "eslint": "^9.39.1", "source-map": "^0.7.4", "tsx": "^4.21.0", @@ -98,9 +98,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", - "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", + "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", "cpu": [ "ppc64" ], @@ -115,9 +115,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", - "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", + "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", "cpu": [ "arm" ], @@ -132,9 +132,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", - "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", + "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", "cpu": [ "arm64" ], @@ -149,9 +149,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", - "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", + "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", "cpu": [ "x64" ], @@ -166,9 +166,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", - "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", + "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", "cpu": [ "arm64" ], @@ -183,9 +183,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", - "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", + "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", "cpu": [ "x64" ], @@ -200,9 +200,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", - "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", + "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", "cpu": [ "arm64" ], @@ -217,9 +217,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", - "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", + "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", "cpu": [ "x64" ], @@ -234,9 +234,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", - "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", + "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", "cpu": [ "arm" ], @@ -251,9 +251,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", - "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", + "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", "cpu": [ "arm64" ], @@ -268,9 +268,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", - "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", + "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", "cpu": [ "ia32" ], @@ -285,9 +285,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", - "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", + "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", "cpu": [ "loong64" ], @@ -302,9 +302,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", - "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", + "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", "cpu": [ "mips64el" ], @@ -319,9 +319,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", - "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", + "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", "cpu": [ "ppc64" ], @@ -336,9 +336,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", - "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", + "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", "cpu": [ "riscv64" ], @@ -353,9 +353,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", - "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", + "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", "cpu": [ "s390x" ], @@ -370,9 +370,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", - "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", + "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", "cpu": [ "x64" ], @@ -387,9 +387,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", - "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", + "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", "cpu": [ "arm64" ], @@ -404,9 +404,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", - "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", + "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", "cpu": [ "x64" ], @@ -421,9 +421,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", - "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", + "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", "cpu": [ "arm64" ], @@ -438,9 +438,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", - "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", + "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", "cpu": [ "x64" ], @@ -455,9 +455,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", - "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", + "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", "cpu": [ "arm64" ], @@ -472,9 +472,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", - "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", + "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", "cpu": [ "x64" ], @@ -489,9 +489,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", - "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", + "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", "cpu": [ "arm64" ], @@ -506,9 +506,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", - "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", + "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", "cpu": [ "ia32" ], @@ -523,9 +523,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", - "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", + "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", "cpu": [ "x64" ], @@ -1904,9 +1904,9 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", - "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", + "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1917,32 +1917,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.0", - "@esbuild/android-arm": "0.27.0", - "@esbuild/android-arm64": "0.27.0", - "@esbuild/android-x64": "0.27.0", - "@esbuild/darwin-arm64": "0.27.0", - "@esbuild/darwin-x64": "0.27.0", - "@esbuild/freebsd-arm64": "0.27.0", - "@esbuild/freebsd-x64": "0.27.0", - "@esbuild/linux-arm": "0.27.0", - "@esbuild/linux-arm64": "0.27.0", - "@esbuild/linux-ia32": "0.27.0", - "@esbuild/linux-loong64": "0.27.0", - "@esbuild/linux-mips64el": "0.27.0", - "@esbuild/linux-ppc64": "0.27.0", - "@esbuild/linux-riscv64": "0.27.0", - "@esbuild/linux-s390x": "0.27.0", - "@esbuild/linux-x64": "0.27.0", - "@esbuild/netbsd-arm64": "0.27.0", - "@esbuild/netbsd-x64": "0.27.0", - "@esbuild/openbsd-arm64": "0.27.0", - "@esbuild/openbsd-x64": "0.27.0", - "@esbuild/openharmony-arm64": "0.27.0", - "@esbuild/sunos-x64": "0.27.0", - "@esbuild/win32-arm64": "0.27.0", - "@esbuild/win32-ia32": "0.27.0", - "@esbuild/win32-x64": "0.27.0" + "@esbuild/aix-ppc64": "0.27.1", + "@esbuild/android-arm": "0.27.1", + "@esbuild/android-arm64": "0.27.1", + "@esbuild/android-x64": "0.27.1", + "@esbuild/darwin-arm64": "0.27.1", + "@esbuild/darwin-x64": "0.27.1", + "@esbuild/freebsd-arm64": "0.27.1", + "@esbuild/freebsd-x64": "0.27.1", + "@esbuild/linux-arm": "0.27.1", + "@esbuild/linux-arm64": "0.27.1", + "@esbuild/linux-ia32": "0.27.1", + "@esbuild/linux-loong64": "0.27.1", + "@esbuild/linux-mips64el": "0.27.1", + "@esbuild/linux-ppc64": "0.27.1", + "@esbuild/linux-riscv64": "0.27.1", + "@esbuild/linux-s390x": "0.27.1", + "@esbuild/linux-x64": "0.27.1", + "@esbuild/netbsd-arm64": "0.27.1", + "@esbuild/netbsd-x64": "0.27.1", + "@esbuild/openbsd-arm64": "0.27.1", + "@esbuild/openbsd-x64": "0.27.1", + "@esbuild/openharmony-arm64": "0.27.1", + "@esbuild/sunos-x64": "0.27.1", + "@esbuild/win32-arm64": "0.27.1", + "@esbuild/win32-ia32": "0.27.1", + "@esbuild/win32-x64": "0.27.1" } }, "node_modules/escape-string-regexp": { diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index 772078ac..afdcd599 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -74,7 +74,7 @@ "@types/node": "^24.10.1", "@vitest/coverage-v8": "^3.0.5", "dts-buddy": "^0.6.2", - "esbuild": "^0.27.0", + "esbuild": "^0.27.1", "eslint": "^9.39.1", "source-map": "^0.7.4", "tsx": "^4.21.0", From 8b8199775f96ca8642cf7860da46100875b38453 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 8 Dec 2025 17:38:17 -0500 Subject: [PATCH 092/140] 0.26.x Also bump the tree-sitter-language crate to 0.1.6 --- CMakeLists.txt | 2 +- Cargo.lock | 16 ++++++++-------- Cargo.toml | 14 +++++++------- Makefile | 2 +- build.zig.zon | 2 +- crates/cli/npm/package-lock.json | 4 ++-- crates/cli/npm/package.json | 2 +- crates/language/Cargo.toml | 2 +- docs/src/cli/generate.md | 2 +- flake.nix | 2 +- lib/binding_web/package-lock.json | 4 ++-- lib/binding_web/package.json | 2 +- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd5cff28..893a4d85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13) project(tree-sitter - VERSION "0.26.1" + VERSION "0.26.2" DESCRIPTION "An incremental parsing system for programming tools" HOMEPAGE_URL "https://tree-sitter.github.io/tree-sitter/" LANGUAGES C) diff --git a/Cargo.lock b/Cargo.lock index 3382fe2a..46245bae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1972,7 +1972,7 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.26.1" +version = "0.26.2" dependencies = [ "bindgen", "cc", @@ -1986,7 +1986,7 @@ dependencies = [ [[package]] name = "tree-sitter-cli" -version = "0.26.1" +version = "0.26.2" dependencies = [ "ansi_colours", "anstyle", @@ -2034,7 +2034,7 @@ dependencies = [ [[package]] name = "tree-sitter-config" -version = "0.26.1" +version = "0.26.2" dependencies = [ "etcetera", "log", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "tree-sitter-generate" -version = "0.26.1" +version = "0.26.2" dependencies = [ "bitflags 2.10.0", "dunce", @@ -2068,7 +2068,7 @@ dependencies = [ [[package]] name = "tree-sitter-highlight" -version = "0.26.1" +version = "0.26.2" dependencies = [ "regex", "streaming-iterator", @@ -2078,11 +2078,11 @@ dependencies = [ [[package]] name = "tree-sitter-language" -version = "0.1.5" +version = "0.1.6" [[package]] name = "tree-sitter-loader" -version = "0.26.1" +version = "0.26.2" dependencies = [ "cc", "etcetera", @@ -2104,7 +2104,7 @@ dependencies = [ [[package]] name = "tree-sitter-tags" -version = "0.26.1" +version = "0.26.2" dependencies = [ "memchr", "regex", diff --git a/Cargo.toml b/Cargo.toml index 9d16282f..0f42c350 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.26.1" +version = "0.26.2" authors = [ "Max Brunsfeld ", "Amaan Qureshi ", @@ -153,11 +153,11 @@ walkdir = "2.5.0" wasmparser = "0.243.0" webbrowser = "1.0.5" -tree-sitter = { version = "0.26.1", path = "./lib" } -tree-sitter-generate = { version = "0.26.1", path = "./crates/generate" } -tree-sitter-loader = { version = "0.26.1", path = "./crates/loader" } -tree-sitter-config = { version = "0.26.1", path = "./crates/config" } -tree-sitter-highlight = { version = "0.26.1", path = "./crates/highlight" } -tree-sitter-tags = { version = "0.26.1", path = "./crates/tags" } +tree-sitter = { version = "0.26.2", path = "./lib" } +tree-sitter-generate = { version = "0.26.2", path = "./crates/generate" } +tree-sitter-loader = { version = "0.26.2", path = "./crates/loader" } +tree-sitter-config = { version = "0.26.2", path = "./crates/config" } +tree-sitter-highlight = { version = "0.26.2", path = "./crates/highlight" } +tree-sitter-tags = { version = "0.26.2", path = "./crates/tags" } tree-sitter-language = { version = "0.1", path = "./crates/language" } diff --git a/Makefile b/Makefile index 7d1f326f..f4e1f20e 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 0.26.1 +VERSION := 0.26.2 DESCRIPTION := An incremental parsing system for programming tools HOMEPAGE_URL := https://tree-sitter.github.io/tree-sitter/ diff --git a/build.zig.zon b/build.zig.zon index b68d7d53..b78230e4 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .tree_sitter, .fingerprint = 0x841224b447ac0d4f, - .version = "0.26.1", + .version = "0.26.2", .minimum_zig_version = "0.14.1", .paths = .{ "build.zig", diff --git a/crates/cli/npm/package-lock.json b/crates/cli/npm/package-lock.json index 083474f6..034fa7ac 100644 --- a/crates/cli/npm/package-lock.json +++ b/crates/cli/npm/package-lock.json @@ -1,12 +1,12 @@ { "name": "tree-sitter-cli", - "version": "0.26.1", + "version": "0.26.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "tree-sitter-cli", - "version": "0.26.1", + "version": "0.26.2", "hasInstallScript": true, "license": "MIT", "bin": { diff --git a/crates/cli/npm/package.json b/crates/cli/npm/package.json index 6e3e6029..091bdc2e 100644 --- a/crates/cli/npm/package.json +++ b/crates/cli/npm/package.json @@ -1,6 +1,6 @@ { "name": "tree-sitter-cli", - "version": "0.26.1", + "version": "0.26.2", "author": { "name": "Max Brunsfeld", "email": "maxbrunsfeld@gmail.com" diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index 4de0f339..c86b55b2 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tree-sitter-language" description = "The tree-sitter Language type, used by the library and by language implementations" -version = "0.1.5" +version = "0.1.6" authors.workspace = true edition.workspace = true rust-version = "1.77" diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index b56bb798..a01347cb 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -51,7 +51,7 @@ Report conflicts in a JSON format. ### `--js-runtime ` The path to the JavaScript runtime executable to use when generating the parser. The default is `node`. -Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.1, you can +Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.2, you can also pass in `native` to use the experimental native QuickJS runtime that comes bundled with the CLI. This avoids the dependency on a JavaScript runtime entirely. The native QuickJS runtime is compatible with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base grammars, the native runtime can be used *after* running `npm install`. diff --git a/flake.nix b/flake.nix index 3333670c..f786bbdf 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ eachSystem = lib.genAttrs systems; pkgsFor = inputs.nixpkgs.legacyPackages; - version = "0.26.1"; + version = "0.26.2"; fs = lib.fileset; src = fs.toSource { diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index ae02badc..2333bc68 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -1,12 +1,12 @@ { "name": "web-tree-sitter", - "version": "0.26.1", + "version": "0.26.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-tree-sitter", - "version": "0.26.1", + "version": "0.26.2", "license": "MIT", "devDependencies": { "@eslint/js": "^9.39.1", diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index afdcd599..cee31219 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -1,6 +1,6 @@ { "name": "web-tree-sitter", - "version": "0.26.1", + "version": "0.26.2", "description": "Tree-sitter bindings for the web", "repository": { "type": "git", From 3bd44afcaa5770c9fb413cb9e168d3caa5da25d8 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Tue, 9 Dec 2025 22:20:22 +0100 Subject: [PATCH 093/140] docs(cli): fix wrong file path for Java bindings test The test is currently generated in the default (= unnamed) package. --- docs/src/cli/init.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/cli/init.md b/docs/src/cli/init.md index b3b802eb..75d9a152 100644 --- a/docs/src/cli/init.md +++ b/docs/src/cli/init.md @@ -157,7 +157,7 @@ if you have one. - `pom.xml` - This file is the manifest of the Maven package. - `bindings/java/main/namespace/language/TreeSitterLanguage.java` - This file wraps your language in a Java class. -- `bindings/java/test/namespace/language/TreeSitterLanguageTest.java` - This file contains a test for the Java package. +- `bindings/java/test/TreeSitterLanguageTest.java` - This file contains a test for the Java package. ### Python From 1b654ae35d07818cfd188d28c9e0dec9fe24c3bb Mon Sep 17 00:00:00 2001 From: ObserverOfTime Date: Wed, 10 Dec 2025 21:08:14 +0200 Subject: [PATCH 094/140] ci(release): use node 24 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d692c02..c3cf2d7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -107,7 +107,7 @@ jobs: - name: Set up Node uses: actions/setup-node@v6 with: - node-version: 20 + node-version: 24 registry-url: https://registry.npmjs.org - name: Set up Rust From 8caecbc13f62b7532b66ed8e367f537a280285b6 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 13 Dec 2025 12:35:58 +0100 Subject: [PATCH 095/140] build(deps): cargo update --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 46245bae..6e87f8ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.48" +version = "1.2.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" +checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" dependencies = [ "find-msvc-tools", "shlex", @@ -853,9 +853,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -867,9 +867,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -1721,9 +1721,9 @@ dependencies = [ [[package]] name = "shell-words" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" @@ -1914,9 +1914,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.8" +version = "0.23.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9b7ac41d92f2d2803f233e297127bac397df7b337e0460a1cc39d6c006dee4" +checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" dependencies = [ "indexmap", "toml_datetime", From cd4b6e2ef996d4baca12caadb78dffc8b55bc869 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 13 Dec 2025 13:01:32 +0100 Subject: [PATCH 096/140] 0.26.3 --- CMakeLists.txt | 2 +- Cargo.lock | 14 +++++++------- Cargo.toml | 14 +++++++------- Makefile | 2 +- build.zig.zon | 2 +- crates/cli/npm/package-lock.json | 4 ++-- crates/cli/npm/package.json | 2 +- docs/src/cli/generate.md | 2 +- flake.nix | 2 +- lib/binding_web/package-lock.json | 4 ++-- lib/binding_web/package.json | 2 +- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 893a4d85..ab0ceb74 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13) project(tree-sitter - VERSION "0.26.2" + VERSION "0.26.3" DESCRIPTION "An incremental parsing system for programming tools" HOMEPAGE_URL "https://tree-sitter.github.io/tree-sitter/" LANGUAGES C) diff --git a/Cargo.lock b/Cargo.lock index 6e87f8ea..37bd9595 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1972,7 +1972,7 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.26.2" +version = "0.26.3" dependencies = [ "bindgen", "cc", @@ -1986,7 +1986,7 @@ dependencies = [ [[package]] name = "tree-sitter-cli" -version = "0.26.2" +version = "0.26.3" dependencies = [ "ansi_colours", "anstyle", @@ -2034,7 +2034,7 @@ dependencies = [ [[package]] name = "tree-sitter-config" -version = "0.26.2" +version = "0.26.3" dependencies = [ "etcetera", "log", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "tree-sitter-generate" -version = "0.26.2" +version = "0.26.3" dependencies = [ "bitflags 2.10.0", "dunce", @@ -2068,7 +2068,7 @@ dependencies = [ [[package]] name = "tree-sitter-highlight" -version = "0.26.2" +version = "0.26.3" dependencies = [ "regex", "streaming-iterator", @@ -2082,7 +2082,7 @@ version = "0.1.6" [[package]] name = "tree-sitter-loader" -version = "0.26.2" +version = "0.26.3" dependencies = [ "cc", "etcetera", @@ -2104,7 +2104,7 @@ dependencies = [ [[package]] name = "tree-sitter-tags" -version = "0.26.2" +version = "0.26.3" dependencies = [ "memchr", "regex", diff --git a/Cargo.toml b/Cargo.toml index 0f42c350..e88e4edd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.26.2" +version = "0.26.3" authors = [ "Max Brunsfeld ", "Amaan Qureshi ", @@ -153,11 +153,11 @@ walkdir = "2.5.0" wasmparser = "0.243.0" webbrowser = "1.0.5" -tree-sitter = { version = "0.26.2", path = "./lib" } -tree-sitter-generate = { version = "0.26.2", path = "./crates/generate" } -tree-sitter-loader = { version = "0.26.2", path = "./crates/loader" } -tree-sitter-config = { version = "0.26.2", path = "./crates/config" } -tree-sitter-highlight = { version = "0.26.2", path = "./crates/highlight" } -tree-sitter-tags = { version = "0.26.2", path = "./crates/tags" } +tree-sitter = { version = "0.26.3", path = "./lib" } +tree-sitter-generate = { version = "0.26.3", path = "./crates/generate" } +tree-sitter-loader = { version = "0.26.3", path = "./crates/loader" } +tree-sitter-config = { version = "0.26.3", path = "./crates/config" } +tree-sitter-highlight = { version = "0.26.3", path = "./crates/highlight" } +tree-sitter-tags = { version = "0.26.3", path = "./crates/tags" } tree-sitter-language = { version = "0.1", path = "./crates/language" } diff --git a/Makefile b/Makefile index f4e1f20e..831933c0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 0.26.2 +VERSION := 0.26.3 DESCRIPTION := An incremental parsing system for programming tools HOMEPAGE_URL := https://tree-sitter.github.io/tree-sitter/ diff --git a/build.zig.zon b/build.zig.zon index b78230e4..aecd6fb8 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .tree_sitter, .fingerprint = 0x841224b447ac0d4f, - .version = "0.26.2", + .version = "0.26.3", .minimum_zig_version = "0.14.1", .paths = .{ "build.zig", diff --git a/crates/cli/npm/package-lock.json b/crates/cli/npm/package-lock.json index 034fa7ac..a85aa44a 100644 --- a/crates/cli/npm/package-lock.json +++ b/crates/cli/npm/package-lock.json @@ -1,12 +1,12 @@ { "name": "tree-sitter-cli", - "version": "0.26.2", + "version": "0.26.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "tree-sitter-cli", - "version": "0.26.2", + "version": "0.26.3", "hasInstallScript": true, "license": "MIT", "bin": { diff --git a/crates/cli/npm/package.json b/crates/cli/npm/package.json index 091bdc2e..d4ecb194 100644 --- a/crates/cli/npm/package.json +++ b/crates/cli/npm/package.json @@ -1,6 +1,6 @@ { "name": "tree-sitter-cli", - "version": "0.26.2", + "version": "0.26.3", "author": { "name": "Max Brunsfeld", "email": "maxbrunsfeld@gmail.com" diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index a01347cb..1362b0c4 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -51,7 +51,7 @@ Report conflicts in a JSON format. ### `--js-runtime ` The path to the JavaScript runtime executable to use when generating the parser. The default is `node`. -Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26.2, you can +Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26, you can also pass in `native` to use the experimental native QuickJS runtime that comes bundled with the CLI. This avoids the dependency on a JavaScript runtime entirely. The native QuickJS runtime is compatible with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base grammars, the native runtime can be used *after* running `npm install`. diff --git a/flake.nix b/flake.nix index f786bbdf..abdd3d01 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ eachSystem = lib.genAttrs systems; pkgsFor = inputs.nixpkgs.legacyPackages; - version = "0.26.2"; + version = "0.26.3"; fs = lib.fileset; src = fs.toSource { diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index 2333bc68..cdb08980 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -1,12 +1,12 @@ { "name": "web-tree-sitter", - "version": "0.26.2", + "version": "0.26.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-tree-sitter", - "version": "0.26.2", + "version": "0.26.3", "license": "MIT", "devDependencies": { "@eslint/js": "^9.39.1", diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index cee31219..57956509 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -1,6 +1,6 @@ { "name": "web-tree-sitter", - "version": "0.26.2", + "version": "0.26.3", "description": "Tree-sitter bindings for the web", "repository": { "type": "git", From 98de2bc1a87bd2e7ef7f299fbd8843400978efe4 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sat, 13 Dec 2025 13:46:48 +0100 Subject: [PATCH 097/140] feat: start working on v0.27 * bump tree-sitter crates to 0.27.0 * bump tree-sitter-language to 0.1.7 --- CMakeLists.txt | 2 +- Cargo.lock | 16 ++++++++-------- Cargo.toml | 14 +++++++------- Makefile | 2 +- build.zig.zon | 2 +- crates/cli/npm/package-lock.json | 4 ++-- crates/cli/npm/package.json | 2 +- crates/language/Cargo.toml | 2 +- flake.nix | 2 +- lib/binding_web/package-lock.json | 4 ++-- lib/binding_web/package.json | 2 +- 11 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab0ceb74..b40ac55a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.13) project(tree-sitter - VERSION "0.26.3" + VERSION "0.27.0" DESCRIPTION "An incremental parsing system for programming tools" HOMEPAGE_URL "https://tree-sitter.github.io/tree-sitter/" LANGUAGES C) diff --git a/Cargo.lock b/Cargo.lock index 37bd9595..eb0d8b4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1972,7 +1972,7 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.26.3" +version = "0.27.0" dependencies = [ "bindgen", "cc", @@ -1986,7 +1986,7 @@ dependencies = [ [[package]] name = "tree-sitter-cli" -version = "0.26.3" +version = "0.27.0" dependencies = [ "ansi_colours", "anstyle", @@ -2034,7 +2034,7 @@ dependencies = [ [[package]] name = "tree-sitter-config" -version = "0.26.3" +version = "0.27.0" dependencies = [ "etcetera", "log", @@ -2045,7 +2045,7 @@ dependencies = [ [[package]] name = "tree-sitter-generate" -version = "0.26.3" +version = "0.27.0" dependencies = [ "bitflags 2.10.0", "dunce", @@ -2068,7 +2068,7 @@ dependencies = [ [[package]] name = "tree-sitter-highlight" -version = "0.26.3" +version = "0.27.0" dependencies = [ "regex", "streaming-iterator", @@ -2078,11 +2078,11 @@ dependencies = [ [[package]] name = "tree-sitter-language" -version = "0.1.6" +version = "0.1.7" [[package]] name = "tree-sitter-loader" -version = "0.26.3" +version = "0.27.0" dependencies = [ "cc", "etcetera", @@ -2104,7 +2104,7 @@ dependencies = [ [[package]] name = "tree-sitter-tags" -version = "0.26.3" +version = "0.27.0" dependencies = [ "memchr", "regex", diff --git a/Cargo.toml b/Cargo.toml index e88e4edd..daf79bf5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ members = [ resolver = "2" [workspace.package] -version = "0.26.3" +version = "0.27.0" authors = [ "Max Brunsfeld ", "Amaan Qureshi ", @@ -153,11 +153,11 @@ walkdir = "2.5.0" wasmparser = "0.243.0" webbrowser = "1.0.5" -tree-sitter = { version = "0.26.3", path = "./lib" } -tree-sitter-generate = { version = "0.26.3", path = "./crates/generate" } -tree-sitter-loader = { version = "0.26.3", path = "./crates/loader" } -tree-sitter-config = { version = "0.26.3", path = "./crates/config" } -tree-sitter-highlight = { version = "0.26.3", path = "./crates/highlight" } -tree-sitter-tags = { version = "0.26.3", path = "./crates/tags" } +tree-sitter = { version = "0.27.0", path = "./lib" } +tree-sitter-generate = { version = "0.27.0", path = "./crates/generate" } +tree-sitter-loader = { version = "0.27.0", path = "./crates/loader" } +tree-sitter-config = { version = "0.27.0", path = "./crates/config" } +tree-sitter-highlight = { version = "0.27.0", path = "./crates/highlight" } +tree-sitter-tags = { version = "0.27.0", path = "./crates/tags" } tree-sitter-language = { version = "0.1", path = "./crates/language" } diff --git a/Makefile b/Makefile index 831933c0..d0b402f0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 0.26.3 +VERSION := 0.27.0 DESCRIPTION := An incremental parsing system for programming tools HOMEPAGE_URL := https://tree-sitter.github.io/tree-sitter/ diff --git a/build.zig.zon b/build.zig.zon index aecd6fb8..4ef5de16 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -1,7 +1,7 @@ .{ .name = .tree_sitter, .fingerprint = 0x841224b447ac0d4f, - .version = "0.26.3", + .version = "0.27.0", .minimum_zig_version = "0.14.1", .paths = .{ "build.zig", diff --git a/crates/cli/npm/package-lock.json b/crates/cli/npm/package-lock.json index a85aa44a..739e69f1 100644 --- a/crates/cli/npm/package-lock.json +++ b/crates/cli/npm/package-lock.json @@ -1,12 +1,12 @@ { "name": "tree-sitter-cli", - "version": "0.26.3", + "version": "0.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "tree-sitter-cli", - "version": "0.26.3", + "version": "0.27.0", "hasInstallScript": true, "license": "MIT", "bin": { diff --git a/crates/cli/npm/package.json b/crates/cli/npm/package.json index d4ecb194..d49abd46 100644 --- a/crates/cli/npm/package.json +++ b/crates/cli/npm/package.json @@ -1,6 +1,6 @@ { "name": "tree-sitter-cli", - "version": "0.26.3", + "version": "0.27.0", "author": { "name": "Max Brunsfeld", "email": "maxbrunsfeld@gmail.com" diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index c86b55b2..b6f5cdf8 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "tree-sitter-language" description = "The tree-sitter Language type, used by the library and by language implementations" -version = "0.1.6" +version = "0.1.7" authors.workspace = true edition.workspace = true rust-version = "1.77" diff --git a/flake.nix b/flake.nix index abdd3d01..4cea3f87 100644 --- a/flake.nix +++ b/flake.nix @@ -17,7 +17,7 @@ eachSystem = lib.genAttrs systems; pkgsFor = inputs.nixpkgs.legacyPackages; - version = "0.26.3"; + version = "0.27.0"; fs = lib.fileset; src = fs.toSource { diff --git a/lib/binding_web/package-lock.json b/lib/binding_web/package-lock.json index cdb08980..4ec07f7b 100644 --- a/lib/binding_web/package-lock.json +++ b/lib/binding_web/package-lock.json @@ -1,12 +1,12 @@ { "name": "web-tree-sitter", - "version": "0.26.3", + "version": "0.27.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "web-tree-sitter", - "version": "0.26.3", + "version": "0.27.0", "license": "MIT", "devDependencies": { "@eslint/js": "^9.39.1", diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json index 57956509..1bc53aad 100644 --- a/lib/binding_web/package.json +++ b/lib/binding_web/package.json @@ -1,6 +1,6 @@ { "name": "web-tree-sitter", - "version": "0.26.3", + "version": "0.27.0", "description": "Tree-sitter bindings for the web", "repository": { "type": "git", From 0574fcf2566b1a5f8e3624dd8faa7ff902cd898f Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Sun, 14 Dec 2025 12:19:19 +0100 Subject: [PATCH 098/140] docs(cli): include information on generated files --- docs/src/cli/generate.md | 26 ++++++++++++++++---------- docs/src/cli/init.md | 5 ----- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 1362b0c4..10941564 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -1,29 +1,35 @@ # `tree-sitter generate` -The most important command you'll use is `tree-sitter generate`. This command reads the `grammar.js` file in your current -working directory and creates a file called `src/parser.c`, which implements the parser. After making changes to your grammar, -just run `tree-sitter generate` again. +The most important command for grammar development is `tree-sitter generate`, which reads the grammar in structured form and outputs C files that can be compiled into a shared or static library (e.g., using the [`build`](./build,md) command). ```bash tree-sitter generate [OPTIONS] [GRAMMAR_PATH] # Aliases: gen, g ``` -The grammar path argument allows you to specify a path to a `grammar.js` JavaScript file, or `grammar.json` JSON file. -In case your `grammar.js` file is in a non-standard path, you can specify it yourself. But, if you are using a parser -where `grammar.json` was already generated, or it was hand-written, you can tell the CLI to generate the parser *based* -on this JSON file. This avoids relying on a JavaScript file and avoids the dependency on a JavaScript runtime. +The optional `GRAMMAR_PATH` argument should point to the structured grammar, in one of two forms: +- `grammar.js` a (ESM or CJS) JavaScript file; if the argument is omitted, it defaults to `./grammar.js`. +- `grammar.json` a structured representation of the grammar that is created as a byproduct of `generate`; this can be used to regenerate a missing `parser.c` without requiring a JavaScript runtime (useful when distributing parsers to consumers). If there is an ambiguity or *local ambiguity* in your grammar, Tree-sitter will detect it during parser generation, and -it will exit with a `Unresolved conflict` error message. To learn more about conflicts and how to handle them, check out +it will exit with a `Unresolved conflict` error message. To learn more about conflicts and how to handle them, see the section on [`Structuring Rules Well`](../creating-parsers/3-writing-the-grammar.md#structuring-rules-well) in the user guide. +## Generated files + +- `src/parser.c` implements the parser logic specified in the grammar. +- `src/tree_sitter/parser.h` provides basic C definitions that are used in the generated `parser.c` file. +- `src/tree_sitter/alloc.h` provides memory allocation macros that can be used in an external scanner. +- `src/tree_sitter/array.h` provides array macros that can be used in an external scanner. +- `src/grammar.json` contains a structured representation of the grammar; can be used to regenerate the parser without having to re-evaluate the `grammar.js`. +- `src/node-types.json` provides type information about individual syntax nodes; see the section on [`Static Node Types`](../using-parsers/6-static-node-types.md). + + ## Options ### `-l/--log` -Print the log of the parser generation process. This is really only useful if you know what you're doing, or are investigating -a bug in the CLI itself. It logs info such as what tokens are included in the error recovery state, +Print the log of the parser generation process. This includes information such as what tokens are included in the error recovery state, what keywords were extracted, what states were split and why, and the entry point state. ### `--abi ` diff --git a/docs/src/cli/init.md b/docs/src/cli/init.md index 75d9a152..5137e6e7 100644 --- a/docs/src/cli/init.md +++ b/docs/src/cli/init.md @@ -132,11 +132,6 @@ to be used from different language. Here is a list of these bindings files that - `CMakeLists.txt` — This file tells [`cmake`][cmake] how to compile your language. - `bindings/c/tree_sitter/tree-sitter-language.h` — This file provides the C interface of your language. - `bindings/c/tree-sitter-language.pc` — This file provides [pkg-config][pkg-config] metadata about your language's C library. -- `src/tree_sitter/parser.h` — This file provides some basic C definitions that are used in your generated `parser.c` file. -- `src/tree_sitter/alloc.h` — This file provides some memory allocation macros that are to be used in your external scanner, -if you have one. -- `src/tree_sitter/array.h` — This file provides some array macros that are to be used in your external scanner, -if you have one. ### Go From 642b56d9afe8e0e02c796ff11194dfe2bd0484ea Mon Sep 17 00:00:00 2001 From: skewb1k Date: Sun, 14 Dec 2025 21:55:18 +0300 Subject: [PATCH 099/140] fix(docs): remove conflicting --release cargo flag in contributing.md The argument '--release' cannot be used with '--profile ' --- docs/src/6-contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/6-contributing.md b/docs/src/6-contributing.md index a99ddc09..5fb8271f 100644 --- a/docs/src/6-contributing.md +++ b/docs/src/6-contributing.md @@ -51,7 +51,7 @@ cargo install --path crates/cli If you're going to be in a fast iteration cycle and would like the CLI to build faster, you can use the `release-dev` profile: ```sh -cargo build --release --profile release-dev +cargo build --profile release-dev # or cargo install --path crates/cli --profile release-dev ``` From 4ac2d5d2761552d322bd51e011ecb6bfbd7a9253 Mon Sep 17 00:00:00 2001 From: skewb1k Date: Mon, 15 Dec 2025 01:20:19 +0300 Subject: [PATCH 100/140] fix(cli): trailing whitespace after multiline text nodes in CST Problem: The CST printer emits trailing whitespace after multiline text nodes. With 1704c604bf663801876572fe08b746e787cd7fdb and `:cst` corpus tests this causes trailing spaces to appear on `test --update`. These spaces cannot be removed afterward, as the test runner expects an exact character-for-character match for CST tests. Solution: Print whitespace only if node is not multiline. --- crates/cli/src/parse.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 1023b0fc..292b3614 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -887,7 +887,7 @@ fn write_node_text( write!( out, "{}{}{}{}{}{}", - if multiline { "\n" } else { "" }, + if multiline { "\n" } else { " " }, if multiline { render_node_range(opts, cursor, is_named, true, total_width, node_range) } else { @@ -1011,10 +1011,9 @@ fn cst_render_node( } else { opts.parse_theme.node_kind }; - write!(out, "{}", paint(kind_color, node.kind()),)?; + write!(out, "{}", paint(kind_color, node.kind()))?; if node.child_count() == 0 { - write!(out, " ")?; // Node text from a pattern or external scanner write_node_text( opts, From 69676405719dc20eb6c57e8dd177d3cc3c267c69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 21:09:49 +0000 Subject: [PATCH 101/140] ci: bump the actions group with 2 updates Bumps the actions group with 2 updates: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact). Updates `actions/upload-artifact` from 5 to 6 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v5...v6) Updates `actions/download-artifact` from 6 to 7 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: actions/download-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/build.yml | 4 ++-- .github/workflows/release.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2a9dd910..5cde3db9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,7 +278,7 @@ jobs: - name: Upload CLI artifact if: "!matrix.no-run" - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: tree-sitter.${{ matrix.platform }} path: target/${{ matrix.target }}/release/tree-sitter${{ contains(matrix.target, 'windows') && '.exe' || '' }} @@ -287,7 +287,7 @@ jobs: - name: Upload Wasm artifacts if: matrix.platform == 'linux-x64' - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: tree-sitter.wasm path: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3cf2d7a..4f6f9d47 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: uses: actions/checkout@v6 - name: Download build artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: artifacts From eacb95c85da15005f091729f3225609d0db67963 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 14 Dec 2025 21:38:05 -0500 Subject: [PATCH 102/140] fix(cli): correct discrepancy with cst for `--no-ranges` --- crates/cli/src/parse.rs | 47 ++++++++++++++++------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 292b3614..b7936f0d 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -883,35 +883,24 @@ fn write_node_text( 0 }; let formatted_line = render_line_feed(line, opts); - if !opts.no_ranges { - write!( - out, - "{}{}{}{}{}{}", - if multiline { "\n" } else { " " }, - if multiline { - render_node_range(opts, cursor, is_named, true, total_width, node_range) - } else { - String::new() - }, - if multiline { - " ".repeat(indent_level + 1) - } else { - String::new() - }, - paint(quote_color, &String::from(quote)), - &paint(color, &render_node_text(&formatted_line)), - paint(quote_color, &String::from(quote)), - )?; - } else { - write!( - out, - "\n{}{}{}{}", - " ".repeat(indent_level + 1), - paint(quote_color, &String::from(quote)), - &paint(color, &render_node_text(&formatted_line)), - paint(quote_color, &String::from(quote)), - )?; - } + write!( + out, + "{}{}{}{}{}{}", + if multiline { "\n" } else { " " }, + if multiline && !opts.no_ranges { + render_node_range(opts, cursor, is_named, true, total_width, node_range) + } else { + String::new() + }, + if multiline { + " ".repeat(indent_level + 1) + } else { + String::new() + }, + paint(quote_color, &String::from(quote)), + paint(color, &render_node_text(&formatted_line)), + paint(quote_color, &String::from(quote)), + )?; } } From 6aa63a7213fd715266b30ed5055d376b90741c18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:09:51 +0000 Subject: [PATCH 103/140] ci: bump korthout/backport-action from 3 to 4 in the actions group Bumps the actions group with 1 update: [korthout/backport-action](https://github.com/korthout/backport-action). Updates `korthout/backport-action` from 3 to 4 - [Release notes](https://github.com/korthout/backport-action/releases) - [Commits](https://github.com/korthout/backport-action/compare/v3...v4) --- updated-dependencies: - dependency-name: korthout/backport-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/backport.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index e747a012..7caffa14 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -24,7 +24,7 @@ jobs: private-key: ${{ secrets.BACKPORT_KEY }} - name: Create backport PR - uses: korthout/backport-action@v3 + uses: korthout/backport-action@v4 with: pull_title: "${pull_title}" label_pattern: "^ci:backport ([^ ]+)$" From 24007727d42b4caceda3095ac685c463fae1ba1a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 21:09:40 +0000 Subject: [PATCH 104/140] build(deps): bump the cargo group with 2 updates Bumps the cargo group with 2 updates: [cc](https://github.com/rust-lang/cc-rs) and [clap_complete](https://github.com/clap-rs/clap). Updates `cc` from 1.2.49 to 1.2.50 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.49...cc-v1.2.50) Updates `clap_complete` from 4.5.61 to 4.5.62 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.61...clap_complete-v4.5.62) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.50 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-version: 4.5.62 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb0d8b4d..45298feb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.49" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "shlex", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.61" +version = "4.5.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39615915e2ece2550c0149addac32fb5bd312c657f43845bb9088cb9c8a7c992" +checksum = "004eef6b14ce34759aa7de4aea3217e368f463f46a3ed3764ca4b5a4404003b4" dependencies = [ "clap", ] diff --git a/Cargo.toml b/Cargo.toml index daf79bf5..7c090ca6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.48" +cc = "1.2.50" clap = { version = "4.5.53", features = [ "cargo", "derive", @@ -115,7 +115,7 @@ clap = { version = "4.5.53", features = [ "string", "unstable-styles", ] } -clap_complete = "4.5.61" +clap_complete = "4.5.62" clap_complete_nushell = "4.5.10" crc32fast = "1.5.0" ctor = "0.2.9" From a7d8c0cbb2dee01df314d70d856e10f3d96d66d6 Mon Sep 17 00:00:00 2001 From: kevin-hua-kraken Date: Tue, 23 Dec 2025 17:36:40 +0900 Subject: [PATCH 105/140] fix(playground): update query API --- docs/src/assets/js/playground.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/src/assets/js/playground.js b/docs/src/assets/js/playground.js index 2b4b5708..ef65c371 100644 --- a/docs/src/assets/js/playground.js +++ b/docs/src/assets/js/playground.js @@ -61,7 +61,7 @@ function initializeCustomSelect({ initialValue = null, addListeners = false }) { } window.initializePlayground = async (opts) => { - const { Parser, Language } = window.TreeSitter; + const { Parser, Language, Query } = window.TreeSitter; const { local } = opts; if (local) { @@ -357,11 +357,10 @@ window.initializePlayground = async (opts) => { marks.forEach((m) => m.clear()); if (tree && query) { - const captures = query.captures( - tree.rootNode, - { row: startRow, column: 0 }, - { row: endRow, column: 0 }, - ); + const captures = query.captures(tree.rootNode, { + startPosition: { row: startRow, column: 0 }, + endPosition: { row: endRow, column: 0 }, + }); let lastNodeId; for (const { name, node } of captures) { if (node.id === lastNodeId) continue; @@ -410,7 +409,7 @@ window.initializePlayground = async (opts) => { const queryText = queryEditor.getValue(); try { - query = parser.language.query(queryText); + query = new Query(parser.language, queryText); let match; let row = 0; From d5b82fbbab8a3ee11727445d8ed31d579755fe5a Mon Sep 17 00:00:00 2001 From: skewb1k Date: Tue, 23 Dec 2025 14:03:12 +0300 Subject: [PATCH 106/140] fix(cli): remove extra indentation with `--cst --no-ranges` --- crates/cli/src/parse.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index b7936f0d..71bee902 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -785,7 +785,7 @@ pub fn render_cst<'a, 'b: 'a>( .map(|(row, col)| (row as f64).log10() as usize + (col.len() as f64).log10() as usize + 1) .max() .unwrap_or(1); - let mut indent_level = 1; + let mut indent_level = usize::from(!opts.no_ranges); let mut did_visit_children = false; let mut in_error = false; loop { From f96d518ebfc37bbb829e1da22c0297aac803dd61 Mon Sep 17 00:00:00 2001 From: skewb1k Date: Tue, 23 Dec 2025 14:05:52 +0300 Subject: [PATCH 107/140] fix(cli): remove extra newline with `--cst` Makes CST output consistent with other formats. --- crates/cli/src/parse.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 71bee902..1a1d9723 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -515,7 +515,6 @@ pub fn parse_file_at_path( if opts.output == ParseOutput::Cst { render_cst(&source_code, &tree, &mut cursor, opts, &mut stdout)?; - println!(); } if opts.output == ParseOutput::Xml { From ba7350c7eeb439473a7fc6e7cbeabd381f7fc8b3 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Mon, 22 Dec 2025 14:13:05 +0100 Subject: [PATCH 108/140] docs(cli): better description of files generated by `init` --- docs/src/cli/generate.md | 2 +- docs/src/cli/index.md | 7 +- docs/src/cli/init.md | 169 ++++++++++++++++++++------------------- 3 files changed, 92 insertions(+), 86 deletions(-) diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 10941564..5ec02ad7 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -1,6 +1,6 @@ # `tree-sitter generate` -The most important command for grammar development is `tree-sitter generate`, which reads the grammar in structured form and outputs C files that can be compiled into a shared or static library (e.g., using the [`build`](./build,md) command). +The most important command for grammar development is `tree-sitter generate`, which reads the grammar in structured form and outputs C files that can be compiled into a shared or static library (e.g., using the [`build`](./build.md) command). ```bash tree-sitter generate [OPTIONS] [GRAMMAR_PATH] # Aliases: gen, g diff --git a/docs/src/cli/index.md b/docs/src/cli/index.md index 7c982b40..8b7659f0 100644 --- a/docs/src/cli/index.md +++ b/docs/src/cli/index.md @@ -1,4 +1,7 @@ # CLI Overview -Let's go over all of the functionality of the `tree-sitter` command line interface. -Once you feel that you have enough of a grasp on the CLI, you can move onto the grammar authoring section to learn more about writing your own parser. +The `tree-sitter` command-line interface is used to create, manage, test, and build tree-sitter parsers. It is controlled by + +- a personal `tree-sitter/config.json` config file generated by [`tree-sitter init-config`](./init-config.md) +- a parser `tree-sitter.json` config file generated by [`tree-sitter init`](./init.md). + diff --git a/docs/src/cli/init.md b/docs/src/cli/init.md index 5137e6e7..d45c8e09 100644 --- a/docs/src/cli/init.md +++ b/docs/src/cli/init.md @@ -8,30 +8,91 @@ we recommend using git for version control of your grammar. tree-sitter init [OPTIONS] # Aliases: i ``` -## Options +## Generated files -### `--update` +### Required files -Update outdated generated files, if needed. +The following required files are always created if missing: -### `-p/--grammar-path ` +- `tree-sitter.json` - The main configuration file that determines how `tree-sitter` interacts with the grammar. If missing, the `init` command will prompt the user for the required fields. See [below](./init.md#structure-of-tree-sitterjson) for the full documentation of the structure of this file. +- `package.json` - The `npm` manifest for the parser. This file is required for some `tree-sitter` subcommands, and if the grammar has dependencies (e.g., another published base grammar that this grammar extends). +- `grammar.js` - An empty template for the main grammar file; see [the section on creating parsers](../2-creating-parser). -The path to the directory containing the grammar. +### Language bindings + +Language bindings are files that allow your parser to be directly used by projects written in the respective language. +The following bindings are created if enabled in `tree-sitter.json`: + +#### C/C++ + +- `Makefile` — This file tells [`make`][make] how to compile your language. +- `CMakeLists.txt` — This file tells [`cmake`][cmake] how to compile your language. +- `bindings/c/tree_sitter/tree-sitter-language.h` — This file provides the C interface of your language. +- `bindings/c/tree-sitter-language.pc` — This file provides [pkg-config][pkg-config] metadata about your language's C library. + +#### Go + +- `go.mod` — This file is the manifest of the Go module. +- `bindings/go/binding.go` — This file wraps your language in a Go module. +- `bindings/go/binding_test.go` — This file contains a test for the Go package. + +#### Node + +- `binding.gyp` — This file tells Node.js how to compile your language. +- `bindings/node/binding.cc` — This file wraps your language in a JavaScript module for Node.js. +- `bindings/node/index.js` — This is the file that Node.js initially loads when using your language. +- `bindings/node/index.d.ts` — This file provides type hints for your parser when used in TypeScript. +- `bindings/node/binding_test.js` — This file contains a test for the Node.js package. + +#### Java + +- `pom.xml` - This file is the manifest of the Maven package. +- `bindings/java/main/namespace/language/TreeSitterLanguage.java` - This file wraps your language in a Java class. +- `bindings/java/test/TreeSitterLanguageTest.java` - This file contains a test for the Java package. + +#### Python + +- `pyproject.toml` — This file is the manifest of the Python package. +- `setup.py` — This file tells Python how to compile your language. +- `bindings/python/tree_sitter_language/binding.c` — This file wraps your language in a Python module. +- `bindings/python/tree_sitter_language/__init__.py` — This file tells Python how to load your language. +- `bindings/python/tree_sitter_language/__init__.pyi` — This file provides type hints for your parser when used in Python. +- `bindings/python/tree_sitter_language/py.typed` — This file provides type hints for your parser when used in Python. +- `bindings/python/tests/test_binding.py` — This file contains a test for the Python package. + +#### Rust + +- `Cargo.toml` — This file is the manifest of the Rust package. +- `bindings/rust/build.rs` — This file tells Rust how to compile your language. +- `bindings/rust/lib.rs` — This file wraps your language in a Rust crate when used in Rust. + +#### Swift + +- `Package.swift` — This file tells Swift how to compile your language. +- `bindings/swift/TreeSitterLanguage/language.h` — This file wraps your language in a Swift module when used in Swift. +- `bindings/swift/TreeSitterLanguageTests/TreeSitterLanguageTests.swift` — This file contains a test for the Swift package. + +#### Zig + +- `build.zig` - This file tells Zig how to compile your language. +- `build.zig.zon` - This file is the manifest of the Zig package. +- `bindings/zig/root.zig` - This file wraps your language in a Zig module. +- `bindings/zig/test.zig` - This file contains a test for the Zig package. + +### Additional files + +In addition, the following files are created that aim to improve the development experience: + +- `.editorconfig` — This file tells your editor how to format your code. More information about this file can be found [here][editorconfig]. +- `.gitattributes` — This file tells Git how to handle line endings and tells GitHub which files are generated. +- `.gitignore` — This file tells Git which files to ignore when committing changes. ## Structure of `tree-sitter.json` -The main file of interest for users to configure is `tree-sitter.json`, which tells the CLI information about your grammar, -such as the location of queries. - ### The `grammars` field This field is an array of objects, though you typically only need one object in this array unless your repo has -multiple grammars (for example, `Typescript` and `TSX`). - -### Example - -Typically, the objects in the `"tree-sitter"` array only needs to specify a few keys: - +multiple grammars (for example, `Typescript` and `TSX`), e.g., ```json { "tree-sitter": [ @@ -49,7 +110,7 @@ Typically, the objects in the `"tree-sitter"` array only needs to specify a few } ``` -#### Basic Fields +#### Basic fields These keys specify basic information about the parser: @@ -65,11 +126,11 @@ parser to files that should be checked for modifications during recompilation. This is useful during development to have changes to other files besides scanner.c be picked up by the cli. -#### Language Detection +#### Language detection These keys help to decide whether the language applies to a given file: -- `file-types` — An array of filename suffix strings. The grammar will be used for files whose names end with one of +- `file-types` — An array of filename suffix strings (not including the dot). The grammar will be used for files whose names end with one of these suffixes. Note that the suffix may match an *entire* filename. - `first-line-regex` — A regex pattern that will be tested against the first line of a file @@ -85,14 +146,14 @@ no `content-regex` will be preferred over this one. should be used for a potential *language injection* site. Language injection is described in more detail in [the relevant section](../3-syntax-highlighting.md#language-injection). -#### Query Paths +#### Query paths These keys specify relative paths from the directory containing `tree-sitter.json` to the files that control syntax highlighting: - `highlights` — Path to a *highlight query*. Default: `queries/highlights.scm` - `locals` — Path to a *local variable query*. Default: `queries/locals.scm`. - `injections` — Path to an *injection query*. Default: `queries/injections.scm`. -- `tags` — Path to an *tag query*. Default: `queries/tags.scm`. +- `tags` — Path to a *tag query*. Default: `queries/tags.scm`. ### The `metadata` field @@ -121,76 +182,18 @@ Each key is a language name, and the value is a boolean. - `swift` (default: `false`) - `zig` (default: `false`) -## Binding Files +## Options -When you run `tree-sitter init`, the CLI will also generate a number of files in your repository that allow for your parser -to be used from different language. Here is a list of these bindings files that are generated, and what their purpose is: +### `-u/--update` -### C/C++ +Update outdated generated files, if possible. -- `Makefile` — This file tells [`make`][make] how to compile your language. -- `CMakeLists.txt` — This file tells [`cmake`][cmake] how to compile your language. -- `bindings/c/tree_sitter/tree-sitter-language.h` — This file provides the C interface of your language. -- `bindings/c/tree-sitter-language.pc` — This file provides [pkg-config][pkg-config] metadata about your language's C library. +**Note:** Existing files that may have been edited manually are _not_ updated in general. To force an update to such files, remove them and call `tree-sitter init -u` again. -### Go +### `-p/--grammar-path ` -- `go.mod` — This file is the manifest of the Go module. -- `bindings/go/binding.go` — This file wraps your language in a Go module. -- `bindings/go/binding_test.go` — This file contains a test for the Go package. +The path to the directory containing the grammar. -### Node - -- `binding.gyp` — This file tells Node.js how to compile your language. -- `package.json` — This file is the manifest of the Node.js package. -- `bindings/node/binding.cc` — This file wraps your language in a JavaScript module for Node.js. -- `bindings/node/index.js` — This is the file that Node.js initially loads when using your language. -- `bindings/node/index.d.ts` — This file provides type hints for your parser when used in TypeScript. -- `bindings/node/binding_test.js` — This file contains a test for the Node.js package. - -### Java - -- `pom.xml` - This file is the manifest of the Maven package. -- `bindings/java/main/namespace/language/TreeSitterLanguage.java` - This file wraps your language in a Java class. -- `bindings/java/test/TreeSitterLanguageTest.java` - This file contains a test for the Java package. - -### Python - -- `pyproject.toml` — This file is the manifest of the Python package. -- `setup.py` — This file tells Python how to compile your language. -- `bindings/python/tree_sitter_language/binding.c` — This file wraps your language in a Python module. -- `bindings/python/tree_sitter_language/__init__.py` — This file tells Python how to load your language. - `bindings/python/tree_sitter_language/__init__.pyi` — This file provides type hints for your parser when used in Python. -- `bindings/python/tree_sitter_language/py.typed` — This file provides type hints for your parser when used in Python. -- `bindings/python/tests/test_binding.py` — This file contains a test for the Python package. - -### Rust - -- `Cargo.toml` — This file is the manifest of the Rust package. -- `bindings/rust/lib.rs` — This file wraps your language in a Rust crate when used in Rust. -- `bindings/rust/build.rs` — This file wraps the building process for the Rust crate. - -### Swift - -- `Package.swift` — This file tells Swift how to compile your language. -- `bindings/swift/TreeSitterLanguage/language.h` — This file wraps your language in a Swift module when used in Swift. -- `bindings/swift/TreeSitterLanguageTests/TreeSitterLanguageTests.swift` — This file contains a test for the Swift package. - -### Zig - -- `build.zig` - This file tells Zig how to compile your language. -- `build.zig.zon` - This file is the manifest of the Zig package. -- `bindings/zig/root.zig` - This file wraps your language in a Zig module. -- `bindings/zig/test.zig` - This file contains a test for the Zig package. - -### Additional Files - -Additionally, there's a few other files that are generated when you run `tree-sitter init`, -that aim to improve the development experience: - -- `.editorconfig` — This file tells your editor how to format your code. More information about this file can be found [here][editorconfig] -- `.gitattributes` — This file tells Git how to handle line endings, and tells GitHub what files are generated. -- `.gitignore` — This file tells Git what files to ignore when committing changes. [cmake]: https://cmake.org/cmake/help/latest [editorconfig]: https://editorconfig.org From 5208299bbb42661d306c2340cbdc829bf155856a Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 27 Dec 2025 00:43:33 -0500 Subject: [PATCH 109/140] fix(cli): set language in cwd for all usages of `highlight` command --- crates/cli/src/main.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 937e54b4..782f122e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1622,6 +1622,7 @@ impl Highlight { let loader_config = config.get()?; loader.find_all_languages(&loader_config)?; loader.force_rebuild(self.rebuild || self.grammar_path.is_some()); + let languages = loader.languages_at_path(current_dir)?; let cancellation_flag = util::cancel_on_signal(); @@ -1702,7 +1703,6 @@ impl Highlight { } => { let path = get_tmp_source_file(&contents)?; - let languages = loader.languages_at_path(current_dir)?; let language = languages .iter() .find(|(_, n)| language_names.contains(&Box::from(n.as_str()))) @@ -1733,7 +1733,6 @@ impl Highlight { if let (Some(l), Some(lc)) = (language.clone(), language_configuration) { (l, lc) } else { - let languages = loader.languages_at_path(current_dir)?; let language = languages .first() .map(|(l, _)| l.clone()) From 8e4f21aba0691f84df9fa23b20be1216b90ca802 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sat, 27 Dec 2025 02:51:22 -0500 Subject: [PATCH 110/140] fix(rust): address nightly clippy lint --- .../generate/src/prepare_grammar/process_inlines.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crates/generate/src/prepare_grammar/process_inlines.rs b/crates/generate/src/prepare_grammar/process_inlines.rs index d4b7dc18..460d2359 100644 --- a/crates/generate/src/prepare_grammar/process_inlines.rs +++ b/crates/generate/src/prepare_grammar/process_inlines.rs @@ -70,12 +70,13 @@ impl InlinedProductionMapBuilder { let production_map = production_indices_by_step_id .into_iter() .map(|(step_id, production_indices)| { - let production = step_id.variable_index.map_or_else( - || &productions[step_id.production_index], - |variable_index| { - &grammar.variables[variable_index].productions[step_id.production_index] - }, - ) as *const Production; + let production = + core::ptr::from_ref::(step_id.variable_index.map_or_else( + || &productions[step_id.production_index], + |variable_index| { + &grammar.variables[variable_index].productions[step_id.production_index] + }, + )); ((production, step_id.step_index as u32), production_indices) }) .collect(); From 62effdf1287a371fed30d25fcce9ac306e925b8c Mon Sep 17 00:00:00 2001 From: Firas al-Khalil Date: Fri, 26 Dec 2025 12:31:08 +0100 Subject: [PATCH 111/140] fix(cli): report context on compile fail --- crates/cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 782f122e..af4f13a7 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -984,7 +984,7 @@ impl Build { loader .compile_parser_at_path(&grammar_path, output_path, flags) - .unwrap(); + .context("Failed to compile parser")?; } Ok(()) } From 5293dd683ed69899c5cf0a215e09a86d0d814adf Mon Sep 17 00:00:00 2001 From: Firas al-Khalil Date: Fri, 26 Dec 2025 12:32:43 +0100 Subject: [PATCH 112/140] fix(cli): report library load failure Instead of panicking somehere else. This happens on concurrent builds of the the same grammar. --- crates/loader/src/loader.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index d64b89de..310fe319 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1089,6 +1089,26 @@ impl Loader { } } + // Ensure the dynamic library exists before trying to load it. This can + // happen in race conditions where we couldn't acquire the lock because + // another process was compiling but it still haven't finished by the + // time we reach this point, so the output file still doesn't exist. + // + // Instead of complaining about library load failure in `load_language`, + // inform the user about the precise issue. + if !output_path.exists() { + let msg = format!( + "Dynamic library `{}` not found after build attempt. \ + Are you running multiple processes building to the same output location?", + output_path.display() + ); + + return Err(LoaderError::IO(IoError::new( + std::io::Error::new(std::io::ErrorKind::NotFound, msg), + Some(output_path.as_path()), + ))); + } + Self::load_language(&output_path, &language_fn_name) } From 5d9605a91e74f4ba6fcaa7c0533c82919fd52d0c Mon Sep 17 00:00:00 2001 From: Firas al-Khalil Date: Fri, 26 Dec 2025 12:33:08 +0100 Subject: [PATCH 113/140] feat(cli): concurrent build of same grammar on different paths --- crates/loader/src/loader.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 310fe319..a6f10d54 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -8,6 +8,7 @@ use std::sync::Mutex; use std::{ collections::HashMap, env, fs, + hash::{Hash as _, Hasher as _}, io::{BufRead, BufReader}, marker::PhantomData, mem, @@ -1025,20 +1026,26 @@ impl Loader { return Ok(wasm_store.load_language(&config.name, &wasm_bytes)?); } + // Create a unique lock path based on the output path hash to prevent + // interference when multiple processes build the same grammar (by name) + // to different output locations + let lock_hash = { + let mut hasher = std::hash::DefaultHasher::new(); + output_path.hash(&mut hasher); + format!("{:x}", hasher.finish()) + }; + let lock_path = if env::var("CROSS_RUNNER").is_ok() { tempfile::tempdir() - .unwrap() + .expect("create a temp dir") .path() - .join("tree-sitter") - .join("lock") - .join(format!("{}.lock", config.name)) + .to_path_buf() } else { - etcetera::choose_base_strategy()? - .cache_dir() - .join("tree-sitter") - .join("lock") - .join(format!("{}.lock", config.name)) - }; + etcetera::choose_base_strategy()?.cache_dir() + } + .join("tree-sitter") + .join("lock") + .join(format!("{}-{lock_hash}.lock", config.name)); if let Ok(lock_file) = fs::OpenOptions::new().write(true).open(&lock_path) { recompile = false; From 82486d4b0af2a34fe98d50fb8a2425e1c479deee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Dec 2025 21:07:45 +0000 Subject: [PATCH 114/140] build(deps): bump the cargo group with 2 updates Bumps the cargo group with 2 updates: [cc](https://github.com/rust-lang/cc-rs) and [serde_json](https://github.com/serde-rs/json). Updates `cc` from 1.2.50 to 1.2.51 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.50...cc-v1.2.51) Updates `serde_json` from 1.0.145 to 1.0.147 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.145...v1.0.147) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.51 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: serde_json dependency-version: 1.0.147 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 26 +++++++++++++------------- Cargo.toml | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45298feb..9e220df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.50" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "shlex", @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "fnv" @@ -1614,12 +1614,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - [[package]] name = "same-file" version = "1.0.6" @@ -1707,16 +1701,16 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "indexmap", "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -2932,3 +2926,9 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zmij" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" diff --git a/Cargo.toml b/Cargo.toml index 7c090ca6..09b0830c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.50" +cc = "1.2.51" clap = { version = "4.5.53", features = [ "cargo", "derive", @@ -140,7 +140,7 @@ rustc-hash = "2.1.1" schemars = "1.0.5" semver = { version = "1.0.27", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } -serde_json = { version = "1.0.145", features = ["preserve_order"] } +serde_json = { version = "1.0.147", features = ["preserve_order"] } similar = "2.7.0" smallbitvec = "2.6.0" streaming-iterator = "0.1.9" From 93d793d24920db614b560c251b7ddff822597f21 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Sun, 28 Dec 2025 01:51:35 -0500 Subject: [PATCH 115/140] fix(cli): canonicalize build `--output` path This fixes a potential issue with the new lock file hashing mechanism, in which two different path literals pointing to the same location would hash to separate lock files, allowing a race condition. --- crates/cli/src/main.rs | 14 ++++++++++++-- crates/loader/src/loader.rs | 10 +++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index af4f13a7..35d8fcb7 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -955,11 +955,21 @@ impl Build { } else { let output_path = if let Some(ref path) = self.output { let path = Path::new(path); - if path.is_absolute() { + let full_path = if path.is_absolute() { path.to_path_buf() } else { current_dir.join(path) - } + }; + let parent_path = full_path + .parent() + .context("Output path must have a parent")?; + let name = full_path + .file_name() + .context("Ouput path must have a filename")?; + fs::create_dir_all(parent_path).context("Failed to create output path")?; + let mut canon_path = parent_path.canonicalize().context("Invalid output path")?; + canon_path.push(name); + canon_path } else { let file_name = grammar_path .file_stem() diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index a6f10d54..11c8b673 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1098,11 +1098,11 @@ impl Loader { // Ensure the dynamic library exists before trying to load it. This can // happen in race conditions where we couldn't acquire the lock because - // another process was compiling but it still haven't finished by the + // another process was compiling but it still hasn't finished by the // time we reach this point, so the output file still doesn't exist. // - // Instead of complaining about library load failure in `load_language`, - // inform the user about the precise issue. + // Instead of allowing the `load_language` call below to fail, return a + // clearer error to the user here. if !output_path.exists() { let msg = format!( "Dynamic library `{}` not found after build attempt. \ @@ -1110,10 +1110,10 @@ impl Loader { output_path.display() ); - return Err(LoaderError::IO(IoError::new( + Err(LoaderError::IO(IoError::new( std::io::Error::new(std::io::ErrorKind::NotFound, msg), Some(output_path.as_path()), - ))); + )))?; } Self::load_language(&output_path, &language_fn_name) From 0d4d8548091ccf0a38e9d1a747df3fe5dd44d465 Mon Sep 17 00:00:00 2001 From: skewb1k Date: Sat, 27 Dec 2025 08:33:18 +0300 Subject: [PATCH 116/140] feat(cli): make `test --update` rewrite all corpus files --- crates/cli/src/test.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index 3753dcea..a78629ab 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -1066,7 +1066,6 @@ fn run_tests( return Ok(true); } - let failure_count = test_summary.parse_failures.len(); let mut ran_test_in_group = false; let matches_filter = |name: &str, file_name: &Option, opts: &TestOptions| { @@ -1130,7 +1129,7 @@ fn run_tests( test_summary.parse_results.pop_traversal(); if let Some(file_path) = file_path { - if opts.update && test_summary.parse_failures.len() - failure_count > 0 { + if opts.update { write_tests(&file_path, corrected_entries)?; } corrected_entries.clear(); From 999e041d49e8f923ec4e63d7e4f4ad392294e82e Mon Sep 17 00:00:00 2001 From: skewb1k Date: Sat, 27 Dec 2025 08:34:18 +0300 Subject: [PATCH 117/140] docs: add tip about using `test --update` flag --- docs/src/creating-parsers/5-writing-tests.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/src/creating-parsers/5-writing-tests.md b/docs/src/creating-parsers/5-writing-tests.md index 0d0aeb60..438dc02a 100644 --- a/docs/src/creating-parsers/5-writing-tests.md +++ b/docs/src/creating-parsers/5-writing-tests.md @@ -87,6 +87,11 @@ The recommendation is to be comprehensive in adding tests. If it's a visible nod directory. It's typically a good idea to test all the permutations of each language construct. This increases test coverage, but doubly acquaints readers with a way to examine expected outputs and understand the "edges" of a language. +```admonish tip +After modifying the grammar, you can run `tree-sitter test -u` +to update all syntax trees in corpus files with current parser output. +``` + ## Attributes Tests can be annotated with a few `attributes`. Attributes must be put in the header, below the test name, and start with From a1893b44201d1bf3ce04a7ebd7aa57d3422cea9c Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 30 Dec 2025 17:11:16 +0100 Subject: [PATCH 118/140] build(deps): update rquickjs to 0.11.0 --- Cargo.lock | 92 +++++++++++++++++----------------- Cargo.toml | 2 +- crates/generate/Cargo.toml | 2 +- crates/generate/src/quickjs.rs | 1 + 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e220df0..9cb3dd33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" dependencies = [ "allocator-api2", ] @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.62" +version = "4.5.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004eef6b14ce34759aa7de4aea3217e368f463f46a3ed3764ca4b5a4404003b4" +checksum = "4c0da80818b2d95eca9aa614a30783e42f62bf5fdfee24e68cfb960b071ba8d1" dependencies = [ "clap", ] @@ -338,9 +338,9 @@ dependencies = [ [[package]] name = "convert_case" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ] @@ -980,9 +980,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jni" @@ -1119,7 +1119,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" dependencies = [ - "rustix 1.1.2", + "rustix 1.1.3", ] [[package]] @@ -1371,9 +1371,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] @@ -1527,9 +1527,9 @@ dependencies = [ [[package]] name = "rquickjs" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a135375fbac5ba723bb6a48f432a72f81539cedde422f0121a86c7c4e96d8e0d" +checksum = "c50dc6d6c587c339edb4769cf705867497a2baf0eca8b4645fa6ecd22f02c77a" dependencies = [ "rquickjs-core", "rquickjs-macro", @@ -1537,9 +1537,9 @@ dependencies = [ [[package]] name = "rquickjs-core" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bccb7121a123865c8ace4dea42e7ed84d78b90cbaf4ca32c59849d8d210c9672" +checksum = "b8bf7840285c321c3ab20e752a9afb95548c75cd7f4632a0627cea3507e310c1" dependencies = [ "hashbrown 0.16.1", "phf", @@ -1549,9 +1549,9 @@ dependencies = [ [[package]] name = "rquickjs-macro" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89f93602cc3112c7f30bf5f29e722784232138692c7df4c52ebbac7e035d900d" +checksum = "7106215ff41a5677b104906a13e1a440b880f4b6362b5dc4f3978c267fad2b80" dependencies = [ "convert_case", "fnv", @@ -1568,9 +1568,9 @@ dependencies = [ [[package]] name = "rquickjs-sys" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b1b6528590d4d65dc86b5159eae2d0219709546644c66408b2441696d1d725" +checksum = "27344601ef27460e82d6a4e1ecb9e7e99f518122095f3c51296da8e9be2b9d83" dependencies = [ "bindgen", "cc", @@ -1597,9 +1597,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", @@ -1625,9 +1625,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" dependencies = [ "dyn-clone", "ref-cast", @@ -1638,9 +1638,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301858a4023d78debd2353c7426dc486001bddc91ae31a76fb1f55132f7e2633" +checksum = "4908ad288c5035a8eb12cfdf0d49270def0a268ee162b75eeee0f85d155a7c45" dependencies = [ "proc-macro2", "quote", @@ -1778,9 +1778,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.111" +version = "2.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4" dependencies = [ "proc-macro2", "quote", @@ -1800,20 +1800,20 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.2", + "rustix 1.1.3", "windows-sys 0.61.2", ] @@ -1899,18 +1899,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", @@ -1920,9 +1920,9 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] @@ -1935,9 +1935,9 @@ checksum = "ea68304e134ecd095ac6c3574494fc62b909f416c4fca77e440530221e549d3d" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1957,9 +1957,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", ] @@ -2310,7 +2310,7 @@ dependencies = [ "postcard", "psm", "pulley-interpreter", - "rustix 1.1.2", + "rustix 1.1.3", "serde", "serde_derive", "smallvec", @@ -2419,7 +2419,7 @@ dependencies = [ "anyhow", "cc", "cfg-if", - "rustix 1.1.2", + "rustix 1.1.3", "wasmtime-asm-macros", "wasmtime-versioned-export-macros", "windows-sys 0.59.0", @@ -2929,6 +2929,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4a4e8e9dc5c62d159f04fcdbe07f4c3fb710415aab4754bf11505501e3251d" +checksum = "e9747e91771f56fd7893e1164abd78febd14a670ceec257caad15e051de35f06" diff --git a/Cargo.toml b/Cargo.toml index 09b0830c..9201c5fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ authors = [ "Amaan Qureshi ", ] edition = "2021" -rust-version = "1.84" +rust-version = "1.85" homepage = "https://tree-sitter.github.io/tree-sitter" repository = "https://github.com/tree-sitter/tree-sitter" license = "MIT" diff --git a/crates/generate/Cargo.toml b/crates/generate/Cargo.toml index 5e93bf40..e55be890 100644 --- a/crates/generate/Cargo.toml +++ b/crates/generate/Cargo.toml @@ -33,7 +33,7 @@ log.workspace = true pathdiff = { version = "0.2.3", optional = true } regex.workspace = true regex-syntax.workspace = true -rquickjs = { version = "0.10.0", optional = true, features = [ +rquickjs = { version = "0.11.0", optional = true, features = [ "bindgen", "loader", "macro", diff --git a/crates/generate/src/quickjs.rs b/crates/generate/src/quickjs.rs index b7960db2..d02781f9 100644 --- a/crates/generate/src/quickjs.rs +++ b/crates/generate/src/quickjs.rs @@ -97,6 +97,7 @@ impl Console { Type::Unknown => "unknown".to_string(), Type::Symbol | Type::Object + | Type::Proxy | Type::Array | Type::Function | Type::Constructor From 47ae0609661e2b9e531c76471f9bf6060870b207 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Wed, 31 Dec 2025 12:27:09 +0100 Subject: [PATCH 119/140] feat(quickjs): add console support for `Array` --- crates/generate/src/quickjs.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/generate/src/quickjs.rs b/crates/generate/src/quickjs.rs index d02781f9..99e77397 100644 --- a/crates/generate/src/quickjs.rs +++ b/crates/generate/src/quickjs.rs @@ -95,10 +95,27 @@ impl Console { Type::Module => "module".to_string(), Type::BigInt => v.get::().unwrap_or_else(|_| "BigInt".to_string()), Type::Unknown => "unknown".to_string(), + Type::Array => { + let js_vals = v + .as_array() + .unwrap() + .iter::>() + .filter_map(|x| x.ok()) + .map(|x| { + if x.is_string() { + format!("'{}'", Self::format_args(&[x])) + } else { + Self::format_args(&[x]) + } + }) + .collect::>() + .join(", "); + + format!("[ {js_vals} ]") + } Type::Symbol | Type::Object | Type::Proxy - | Type::Array | Type::Function | Type::Constructor | Type::Promise From f1288ea5c9d0dfc683a91e85d7e8c9177d32738b Mon Sep 17 00:00:00 2001 From: WillLillis Date: Fri, 26 Dec 2025 19:33:32 -0500 Subject: [PATCH 120/140] fix(cli): increase verbosity of `tree-sitter init -u` updates Also, use `info` logs rather than `warn` --- crates/cli/src/init.rs | 177 ++++++++++++++++++++++++----------------- 1 file changed, 105 insertions(+), 72 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index b0cdb586..2d37f8dd 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -8,7 +8,7 @@ use anyhow::{anyhow, Context, Result}; use crc32fast::hash as crc32; use heck::{ToKebabCase, ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase}; use indoc::{formatdoc, indoc}; -use log::warn; +use log::info; use rand::{thread_rng, Rng}; use semver::Version; use serde::{Deserialize, Serialize}; @@ -356,7 +356,7 @@ pub fn generate_grammar_files( "tree-sitter-cli":"#}, ); if !contents.contains("module") { - warn!("Updating package.json"); + info!("Migrating package.json to ESM"); contents = contents.replace( r#""repository":"#, indoc! {r#" @@ -378,6 +378,7 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if contents.contains("module.exports") { + info!("Migrating grammars.js to ESM"); contents = contents.replace("module.exports =", "export default"); write_file(path, contents)?; } @@ -393,10 +394,16 @@ pub fn generate_grammar_files( allow_update, |path| generate_file(path, GITIGNORE_TEMPLATE, language_name, &generate_opts), |path| { - let contents = fs::read_to_string(path)?; + let mut contents = fs::read_to_string(path)?; if !contents.contains("Zig artifacts") { - warn!("Replacing .gitignore"); - generate_file(path, GITIGNORE_TEMPLATE, language_name, &generate_opts)?; + info!("Adding zig entries to .gitignore"); + contents.push('\n'); + contents.push_str(indoc! {" + # Zig artifacts + .zig-cache/ + zig-cache/ + zig-out/ + "}); } Ok(()) }, @@ -409,8 +416,13 @@ pub fn generate_grammar_files( |path| generate_file(path, GITATTRIBUTES_TEMPLATE, language_name, &generate_opts), |path| { let mut contents = fs::read_to_string(path)?; - contents = contents.replace("bindings/c/* ", "bindings/c/** "); + let c_bindings_entry = "bindings/c/* "; + if contents.contains(c_bindings_entry) { + info!("Updating c bindings entry in .gitattributes"); + contents = contents.replace(c_bindings_entry, "bindings/c/** "); + } if !contents.contains("Zig bindings") { + info!("Adding zig entries to .gitattributes"); contents.push('\n'); contents.push_str(indoc! {" # Zig bindings @@ -438,39 +450,40 @@ pub fn generate_grammar_files( }, |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("#[cfg(with_highlights_query)]") { - let replacement = indoc! {r#" - #[cfg(with_highlights_query)] - /// The syntax highlighting query for this grammar. - pub const HIGHLIGHTS_QUERY: &str = include_str!("../../HIGHLIGHTS_QUERY_PATH"); + info!("Updating query constants in bindings/rust/lib.rs"); + let replacement = indoc! {r#" + #[cfg(with_highlights_query)] + /// The syntax highlighting query for this grammar. + pub const HIGHLIGHTS_QUERY: &str = include_str!("../../HIGHLIGHTS_QUERY_PATH"); - #[cfg(with_injections_query)] - /// The language injection query for this grammar. - pub const INJECTIONS_QUERY: &str = include_str!("../../INJECTIONS_QUERY_PATH"); + #[cfg(with_injections_query)] + /// The language injection query for this grammar. + pub const INJECTIONS_QUERY: &str = include_str!("../../INJECTIONS_QUERY_PATH"); - #[cfg(with_locals_query)] - /// The local variable query for this grammar. - pub const LOCALS_QUERY: &str = include_str!("../../LOCALS_QUERY_PATH"); + #[cfg(with_locals_query)] + /// The local variable query for this grammar. + pub const LOCALS_QUERY: &str = include_str!("../../LOCALS_QUERY_PATH"); - #[cfg(with_tags_query)] - /// The symbol tagging query for this grammar. - pub const TAGS_QUERY: &str = include_str!("../../TAGS_QUERY_PATH"); - "#} - .replace("HIGHLIGHTS_QUERY_PATH", generate_opts.highlights_query_path) - .replace("INJECTIONS_QUERY_PATH", generate_opts.injections_query_path) - .replace("LOCALS_QUERY_PATH", generate_opts.locals_query_path) - .replace("TAGS_QUERY_PATH", generate_opts.tags_query_path); - contents = contents - .replace( - indoc! {r#" - // NOTE: uncomment these to include any queries that this grammar contains: + #[cfg(with_tags_query)] + /// The symbol tagging query for this grammar. + pub const TAGS_QUERY: &str = include_str!("../../TAGS_QUERY_PATH"); + "#} + .replace("HIGHLIGHTS_QUERY_PATH", generate_opts.highlights_query_path) + .replace("INJECTIONS_QUERY_PATH", generate_opts.injections_query_path) + .replace("LOCALS_QUERY_PATH", generate_opts.locals_query_path) + .replace("TAGS_QUERY_PATH", generate_opts.tags_query_path); + contents = contents + .replace( + indoc! {r#" + // NOTE: uncomment these to include any queries that this grammar contains: - // pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); - // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); - // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); - // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); - "#}, - &replacement, - ); + // pub const HIGHLIGHTS_QUERY: &str = include_str!("../../queries/highlights.scm"); + // pub const INJECTIONS_QUERY: &str = include_str!("../../queries/injections.scm"); + // pub const LOCALS_QUERY: &str = include_str!("../../queries/locals.scm"); + // pub const TAGS_QUERY: &str = include_str!("../../queries/tags.scm"); + "#}, + &replacement, + ); } write_file(path, contents)?; Ok(()) @@ -483,6 +496,7 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("wasm32-unknown-unknown") { + info!("Adding wasm32-unknown-unknown target to bindings/rust/build.rs"); let replacement = indoc!{r#" c_config.flag("-utf-8"); @@ -503,19 +517,18 @@ pub fn generate_grammar_files( wasm_src.join("string.c"), ]); } - "#}; - - let indented_replacement = replacement + "#} .lines() .map(|line| if line.is_empty() { line.to_string() } else { format!(" {line}") }) .collect::>() .join("\n"); - contents = contents.replace(r#" c_config.flag("-utf-8");"#, &indented_replacement); + contents = contents.replace(r#" c_config.flag("-utf-8");"#, &replacement); } // Introduce configuration variables for dynamic query inclusion if !contents.contains("with_highlights_query") { + info!("Adding support for dynamic query inclusion to bindings/rust/build.rs"); let replaced = indoc! {r#" c_config.compile("tree-sitter-KEBAB_PARSER_NAME"); }"#} @@ -572,6 +585,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if contents.contains("\"LICENSE\"") { + info!("Adding LICENSE entry to bindings/rust/Cargo.toml"); write_file(path, contents.replace("\"LICENSE\"", "\"/LICENSE\""))?; } Ok(()) @@ -592,7 +606,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("Object.defineProperty") { - warn!("Replacing index.js"); + info!("Replacing index.js"); generate_file(path, INDEX_JS_TEMPLATE, language_name, &generate_opts)?; } Ok(()) @@ -606,7 +620,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("export default binding") { - warn!("Replacing index.d.ts"); + info!("Replacing index.d.ts"); generate_file(path, INDEX_D_TS_TEMPLATE, language_name, &generate_opts)?; } Ok(()) @@ -627,7 +641,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("import") { - warn!("Replacing binding_test.js"); + info!("Replacing binding_test.js"); generate_file( path, BINDING_TEST_JS_TEMPLATE, @@ -650,6 +664,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if contents.contains("fs.exists(") { + info!("Replacing `fs.exists` calls in binding.gyp"); write_file(path, contents.replace("fs.exists(", "fs.existsSync("))?; } Ok(()) @@ -662,14 +677,17 @@ pub fn generate_grammar_files( // Generate C bindings if tree_sitter_config.bindings.c { + let kebab_case_name = language_name.to_kebab_case(); missing_path(bindings_dir.join("c"), create_dir)?.apply(|path| { - let old_file = &path.join(format!("tree-sitter-{}.h", language_name.to_kebab_case())); + let header_name = format!("tree-sitter-{kebab_case_name}.h"); + let old_file = &path.join(&header_name); if allow_update && fs::exists(old_file).unwrap_or(false) { + info!("Removing bindings/c/{header_name}"); fs::remove_file(old_file)?; } missing_path(path.join("tree_sitter"), create_dir)?.apply(|include_path| { missing_path( - include_path.join(format!("tree-sitter-{}.h", language_name.to_kebab_case())), + include_path.join(&header_name), |path| { generate_file(path, PARSER_NAME_H_TEMPLATE, language_name, &generate_opts) }, @@ -678,7 +696,7 @@ pub fn generate_grammar_files( })?; missing_path( - path.join(format!("tree-sitter-{}.pc.in", language_name.to_kebab_case())), + path.join(format!("tree-sitter-{kebab_case_name}.pc.in")), |path| { generate_file( path, @@ -698,23 +716,27 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("cd '$(DESTDIR)$(LIBDIR)' && ln -sf") { - warn!("Replacing Makefile"); + info!("Replacing Makefile"); generate_file(path, MAKEFILE_TEMPLATE, language_name, &generate_opts)?; } else { - contents = contents - .replace( - indoc! {r" - $(PARSER): $(SRC_DIR)/grammar.json - $(TS) generate $^ - "}, - indoc! {r" - $(SRC_DIR)/grammar.json: grammar.js - $(TS) generate --no-parser $^ + let replaced = indoc! {r" + $(PARSER): $(SRC_DIR)/grammar.json + $(TS) generate $^ + "}; + if contents.contains(replaced) { + info!("Adding --no-parser target to Makefile"); + contents = contents + .replace( + replaced, + indoc! {r" + $(SRC_DIR)/grammar.json: grammar.js + $(TS) generate --no-parser $^ - $(PARSER): $(SRC_DIR)/grammar.json - $(TS) generate $^ - "} - ); + $(PARSER): $(SRC_DIR)/grammar.json + $(TS) generate $^ + "} + ); + } write_file(path, contents)?; } Ok(()) @@ -726,8 +748,8 @@ pub fn generate_grammar_files( allow_update, |path| generate_file(path, CMAKELISTS_TXT_TEMPLATE, language_name, &generate_opts), |path| { - let mut contents = fs::read_to_string(path)?; - contents = contents + let contents = fs::read_to_string(path)?; + let replaced_contents = contents .replace("add_custom_target(test", "add_custom_target(ts-test") .replace( &formatdoc! {r#" @@ -775,7 +797,10 @@ pub fn generate_grammar_files( COMMENT "Generating parser.c") "#} ); - write_file(path, contents)?; + if !replaced_contents.eq(&contents) { + info!("Updating CMakeLists.txt"); + write_file(path, replaced_contents)?; + } Ok(()) }, )?; @@ -811,7 +836,8 @@ pub fn generate_grammar_files( // Generate Python bindings if tree_sitter_config.bindings.python { missing_path(bindings_dir.join("python"), create_dir)?.apply(|path| { - let lang_path = path.join(format!("tree_sitter_{}", language_name.to_snake_case())); + let snake_case_grammar_name = format!("tree_sitter_{}", language_name.to_snake_case()); + let lang_path = path.join(&snake_case_grammar_name); missing_path(&lang_path, create_dir)?; missing_path_else( @@ -821,6 +847,7 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("PyModuleDef_Init") { + info!("Updating bindings/python/{snake_case_grammar_name}/binding.c"); contents = contents .replace("PyModule_Create", "PyModuleDef_Init") .replace( @@ -862,7 +889,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("uncomment these to include any queries") { - warn!("Replacing __init__.py"); + info!("Replacing __init__.py"); generate_file(path, INIT_PY_TEMPLATE, language_name, &generate_opts)?; } Ok(()) @@ -876,9 +903,10 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if contents.contains("uncomment these to include any queries") { - warn!("Replacing __init__.pyi"); + info!("Replacing __init__.pyi"); generate_file(path, INIT_PYI_TEMPLATE, language_name, &generate_opts)?; } else if !contents.contains("CapsuleType") { + info!("Updating __init__.pyi"); contents = contents .replace( "from typing import Final", @@ -910,6 +938,7 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("Parser(Language(") { + info!("Updating Language function in bindings/python/tests/test_binding.py"); contents = contents .replace("tree_sitter.Language(", "Parser(Language(") .replace(".language())\n", ".language()))\n") @@ -932,7 +961,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("build_ext") { - warn!("Replacing setup.py"); + info!("Replacing setup.py"); generate_file(path, SETUP_PY_TEMPLATE, language_name, &generate_opts)?; } Ok(()) @@ -953,6 +982,7 @@ pub fn generate_grammar_files( |path| { let mut contents = fs::read_to_string(path)?; if !contents.contains("cp310-*") { + info!("Updating dependencies in pyproject.toml"); contents = contents .replace(r#"build = "cp39-*""#, r#"build = "cp310-*""#) .replace(r#"python = ">=3.9""#, r#"python = ">=3.10""#) @@ -990,15 +1020,18 @@ pub fn generate_grammar_files( allow_update, |path| generate_file(path, PACKAGE_SWIFT_TEMPLATE, language_name, &generate_opts), |path| { - let mut contents = fs::read_to_string(path)?; - contents = contents + let contents = fs::read_to_string(path)?; + let replaced_contents = contents .replace( "https://github.com/ChimeHQ/SwiftTreeSitter", "https://github.com/tree-sitter/swift-tree-sitter", ) .replace("version: \"0.8.0\")", "version: \"0.9.0\")") .replace("(url:", "(name: \"SwiftTreeSitter\", url:"); - write_file(path, contents)?; + if !replaced_contents.eq(&contents) { + info!("Updating tree-sitter dependency in Package.swift"); + write_file(path, contents)?; + } Ok(()) }, )?; @@ -1016,7 +1049,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains("b.pkg_hash.len") { - warn!("Replacing build.zig"); + info!("Replacing build.zig"); generate_file(path, BUILD_ZIG_TEMPLATE, language_name, &generate_opts) } else { Ok(()) @@ -1031,7 +1064,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if !contents.contains(".name = .tree_sitter_") { - warn!("Replacing build.zig.zon"); + info!("Replacing build.zig.zon"); generate_file(path, BUILD_ZIG_ZON_TEMPLATE, language_name, &generate_opts) } else { Ok(()) @@ -1047,7 +1080,7 @@ pub fn generate_grammar_files( |path| { let contents = fs::read_to_string(path)?; if contents.contains("ts.Language") { - warn!("Replacing root.zig"); + info!("Replacing root.zig"); generate_file(path, ROOT_ZIG_TEMPLATE, language_name, &generate_opts) } else { Ok(()) From dd60d5cff079dbae8db798ce7272879dbd2ac9e8 Mon Sep 17 00:00:00 2001 From: WillLillis Date: Mon, 29 Dec 2025 14:12:25 -0500 Subject: [PATCH 121/140] feat(cli): fill in missing fields to tree-sitter.json when running `tree-sitter init -u` --- crates/cli/src/init.rs | 2 +- crates/cli/src/main.rs | 26 +++++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 2d37f8dd..00b7657b 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -123,7 +123,7 @@ const BUILD_ZIG_ZON_TEMPLATE: &str = include_str!("./templates/build.zig.zon"); const ROOT_ZIG_TEMPLATE: &str = include_str!("./templates/root.zig"); const TEST_ZIG_TEMPLATE: &str = include_str!("./templates/test.zig"); -const TREE_SITTER_JSON_SCHEMA: &str = +pub const TREE_SITTER_JSON_SCHEMA: &str = "https://tree-sitter.github.io/tree-sitter/assets/schemas/config.schema.json"; #[derive(Serialize, Deserialize, Clone)] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 35d8fcb7..fbf75b8e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -20,7 +20,7 @@ use tree_sitter_cli::{ LOG_GRAPH_ENABLED, START_SEED, }, highlight::{self, HighlightOptions}, - init::{generate_grammar_files, JsonConfigOpts}, + init::{generate_grammar_files, JsonConfigOpts, TREE_SITTER_JSON_SCHEMA}, input::{get_input, get_tmp_source_file, CliInput}, logger, parse::{self, ParseDebugType, ParseFileOptions, ParseOutput, ParseTheme}, @@ -867,10 +867,26 @@ impl Init { (opts.name.clone(), Some(opts)) } else { - let mut json = serde_json::from_str::( - &fs::read_to_string(current_dir.join("tree-sitter.json")) - .with_context(|| "Failed to read tree-sitter.json")?, - )?; + let old_config = fs::read_to_string(current_dir.join("tree-sitter.json")) + .with_context(|| "Failed to read tree-sitter.json")?; + + let mut json = serde_json::from_str::(&old_config)?; + if json.schema.is_none() { + json.schema = Some(TREE_SITTER_JSON_SCHEMA.to_string()); + } + + let new_config = format!("{}\n", serde_json::to_string_pretty(&json)?); + // Write the re-serialized config back, as newly added optional boolean fields + // will be included with explicit `false`s rather than implict `null`s + if self.update && !old_config.trim().eq(new_config.trim()) { + info!("Updating tree-sitter.json"); + fs::write( + current_dir.join("tree-sitter.json"), + serde_json::to_string_pretty(&json)?, + ) + .with_context(|| "Failed to write tree-sitter.json")?; + } + (json.grammars.swap_remove(0).name, None) }; From 17e3c7a5c56527a179fa6e37ce7ee934493e5047 Mon Sep 17 00:00:00 2001 From: skewb1k Date: Sun, 4 Jan 2026 09:03:09 +0300 Subject: [PATCH 122/140] fix(cli): restore test summary output for `tree-sitter test` Problem: After commit f02d7e7e335dc4d9355d4d2ca61729368bc4e959 the `tree-sitter test` command no longer printed the final test summary, leaving empty line. The `Stats` struct was embedded into `TestSummary`, and the explicit call to print it was removed. Solution: Print `parse_stats` from `TestSummary.fmt()` implementation. --- crates/cli/src/test.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/cli/src/test.rs b/crates/cli/src/test.rs index a78629ab..b568e4a3 100644 --- a/crates/cli/src/test.rs +++ b/crates/cli/src/test.rs @@ -595,6 +595,8 @@ impl std::fmt::Display for TestSummary { render_assertion_results("queries", &self.query_results)?; } + write!(f, "{}", self.parse_stats)?; + Ok(()) } } From f4ca3d95ca45f71116820a499ea3c199dfe981ea Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 6 Jan 2026 19:01:37 +0800 Subject: [PATCH 123/140] fix(wasm) add common definitions to stdlib (#5199) Also expose `strlen` through `string.h` instead of `stdio.h`. --- crates/language/wasm/include/stdint.h | 8 +++++++- crates/language/wasm/include/string.h | 2 ++ crates/language/wasm/src/stdio.c | 7 +------ crates/language/wasm/src/string.c | 6 ++++++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/crates/language/wasm/include/stdint.h b/crates/language/wasm/include/stdint.h index 5f7cb264..10cc35dc 100644 --- a/crates/language/wasm/include/stdint.h +++ b/crates/language/wasm/include/stdint.h @@ -23,9 +23,15 @@ typedef long unsigned int size_t; typedef long unsigned int uintptr_t; -#define UINT16_MAX 65535 +#define INT8_MAX 127 +#define INT16_MAX 32767 +#define INT32_MAX 2147483647L +#define INT64_MAX 9223372036854775807LL +#define UINT8_MAX 255 +#define UINT16_MAX 65535 #define UINT32_MAX 4294967295U +#define UINT64_MAX 18446744073709551615ULL #if defined(__wasm32__) diff --git a/crates/language/wasm/include/string.h b/crates/language/wasm/include/string.h index 2d576f08..10f11958 100644 --- a/crates/language/wasm/include/string.h +++ b/crates/language/wasm/include/string.h @@ -13,4 +13,6 @@ void *memset(void *dst, int value, size_t count); int strncmp(const char *left, const char *right, size_t n); +size_t strlen(const char *str); + #endif // TREE_SITTER_WASM_STRING_H_ diff --git a/crates/language/wasm/src/stdio.c b/crates/language/wasm/src/stdio.c index 3432699a..470c1ecc 100644 --- a/crates/language/wasm/src/stdio.c +++ b/crates/language/wasm/src/stdio.c @@ -1,4 +1,5 @@ #include +#include typedef struct { bool left_justify; // - @@ -105,12 +106,6 @@ static int ptr_to_str(void *ptr, char *buffer) { return 2 + len; } -size_t strlen(const char *str) { - const char *s = str; - while (*s) s++; - return s - str; -} - char *strncpy(char *dest, const char *src, size_t n) { char *d = dest; const char *s = src; diff --git a/crates/language/wasm/src/string.c b/crates/language/wasm/src/string.c index 0fcf4b85..2d0d9096 100644 --- a/crates/language/wasm/src/string.c +++ b/crates/language/wasm/src/string.c @@ -58,3 +58,9 @@ int strncmp(const char *left, const char *right, size_t n) { } return 0; } + +size_t strlen(const char *str) { + const char *s = str; + while (*s) s++; + return s - str; +} From cd6672701b413a38300af312c529ab78dbf23239 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Tue, 6 Jan 2026 12:36:03 +0100 Subject: [PATCH 124/140] fix(wasm): update wasm-stdlib.h --- lib/src/wasm/wasm-stdlib.h | 2297 +++++++++++++++++++----------------- 1 file changed, 1227 insertions(+), 1070 deletions(-) diff --git a/lib/src/wasm/wasm-stdlib.h b/lib/src/wasm/wasm-stdlib.h index 753a7abf..a8f55df8 100644 --- a/lib/src/wasm/wasm-stdlib.h +++ b/lib/src/wasm/wasm-stdlib.h @@ -1,920 +1,1013 @@ unsigned char STDLIB_WASM[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1a, 0x05, 0x60, - 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x06, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, - 0x02, 0x7c, 0x04, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, - 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, - 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, - 0x02, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, - 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, - 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, - 0x67, 0x65, 0x74, 0x00, 0x02, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, - 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, - 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, - 0x69, 0x74, 0x00, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x1f, 0x1e, 0x04, 0x04, 0x04, - 0x03, 0x00, 0x03, 0x02, 0x02, 0x03, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, - 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x80, 0x04, - 0x0b, 0x07, 0xad, 0x02, 0x1c, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, - 0x03, 0x0f, 0x5f, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x00, 0x05, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, - 0x65, 0x61, 0x70, 0x00, 0x06, 0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, - 0x00, 0x07, 0x04, 0x66, 0x72, 0x65, 0x65, 0x00, 0x08, 0x06, 0x63, 0x61, - 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x09, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, - 0x74, 0x00, 0x0d, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, - 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x00, 0x0c, 0x06, 0x73, - 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x00, 0x0e, 0x08, 0x69, 0x73, 0x77, 0x61, - 0x6c, 0x6e, 0x75, 0x6d, 0x00, 0x20, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, - 0x70, 0x68, 0x61, 0x00, 0x0f, 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, - 0x6e, 0x6b, 0x00, 0x1a, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, - 0x74, 0x00, 0x1b, 0x08, 0x69, 0x73, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, - 0x00, 0x19, 0x08, 0x69, 0x73, 0x77, 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, - 0x1f, 0x08, 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x17, - 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x1e, - 0x08, 0x74, 0x6f, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, 0x13, 0x08, - 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x15, 0x06, 0x6d, - 0x65, 0x6d, 0x63, 0x68, 0x72, 0x00, 0x11, 0x06, 0x6d, 0x65, 0x6d, 0x63, - 0x6d, 0x70, 0x00, 0x10, 0x07, 0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, - 0x00, 0x18, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x12, 0x07, - 0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x00, 0x1c, 0x07, 0x73, 0x74, - 0x72, 0x6e, 0x63, 0x6d, 0x70, 0x00, 0x16, 0x07, 0x73, 0x74, 0x72, 0x6e, - 0x63, 0x70, 0x79, 0x00, 0x1d, 0x08, 0x01, 0x04, 0x0c, 0x01, 0x01, 0x0a, - 0x8b, 0x28, 0x1e, 0x02, 0x00, 0x0b, 0x0d, 0x00, 0x41, 0xe8, 0xc2, 0x04, - 0x41, 0x00, 0x41, 0x14, 0xfc, 0x0b, 0x00, 0x0b, 0xa4, 0x01, 0x01, 0x03, - 0x7f, 0x41, 0xe8, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x45, 0x04, 0x40, 0x41, - 0xe8, 0xc2, 0x04, 0x41, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x41, 0x10, - 0x6b, 0x22, 0x00, 0x24, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, - 0x40, 0x20, 0x00, 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, - 0x01, 0x41, 0xff, 0xff, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x00, 0x28, - 0x02, 0x08, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, - 0x28, 0x02, 0x0c, 0x10, 0x07, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x01, - 0x41, 0x04, 0x10, 0x09, 0x22, 0x01, 0x45, 0x0d, 0x03, 0x20, 0x01, 0x20, - 0x02, 0x10, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0d, 0x04, 0x20, 0x00, - 0x28, 0x02, 0x08, 0x00, 0x0b, 0x41, 0xc7, 0x00, 0x10, 0x0b, 0x00, 0x0b, - 0x41, 0xc6, 0x00, 0x10, 0x0b, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x0b, - 0x00, 0x0b, 0x20, 0x02, 0x10, 0x08, 0x41, 0xc6, 0x00, 0x10, 0x0b, 0x00, - 0x0b, 0x20, 0x02, 0x10, 0x08, 0x20, 0x01, 0x10, 0x08, 0x41, 0xc7, 0x00, - 0x10, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x35, 0x01, 0x01, 0x7f, 0x41, 0xf0, - 0xc2, 0x04, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0xec, 0xc2, 0x04, 0x20, - 0x00, 0x36, 0x02, 0x00, 0x3f, 0x00, 0x21, 0x00, 0x20, 0x01, 0x41, 0xf8, - 0xc2, 0x04, 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xf4, - 0xc2, 0x04, 0x6a, 0x20, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, - 0xd7, 0x01, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00, - 0x02, 0x40, 0x41, 0xf8, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x22, 0x01, 0x45, - 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x20, 0x01, 0x28, 0x02, 0x00, 0x4d, - 0x04, 0x40, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x03, 0x40, 0x20, - 0x01, 0x28, 0x02, 0x04, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x01, 0x21, - 0x03, 0x20, 0x02, 0x22, 0x01, 0x28, 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, - 0x00, 0x0b, 0x0b, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x41, 0xf8, 0xc2, 0x04, - 0x20, 0x03, 0x1b, 0x20, 0x02, 0x28, 0x02, 0x04, 0x36, 0x02, 0x00, 0x20, - 0x02, 0x41, 0x08, 0x6a, 0x0f, 0x0b, 0x41, 0xf0, 0xc2, 0x04, 0x28, 0x02, - 0x00, 0x22, 0x01, 0x20, 0x00, 0x6a, 0x41, 0x0b, 0x6a, 0x41, 0x7c, 0x71, - 0x22, 0x02, 0x41, 0xf4, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x4b, 0x04, 0x40, - 0x20, 0x02, 0x41, 0xec, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x6b, 0x41, 0x80, - 0x80, 0x80, 0x02, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6b, 0x41, - 0x10, 0x76, 0x41, 0x01, 0x6a, 0x40, 0x00, 0x41, 0x7f, 0x46, 0x0d, 0x01, - 0x41, 0xf4, 0xc2, 0x04, 0x3f, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, - 0x41, 0xf0, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x21, 0x01, 0x0b, 0x20, 0x01, - 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0xf0, 0xc2, 0x04, 0x20, 0x02, 0x36, - 0x02, 0x00, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x04, 0x0b, 0x20, 0x04, - 0x0b, 0x41, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x04, 0x40, 0x41, 0xf0, 0xc2, - 0x04, 0x22, 0x01, 0x28, 0x02, 0x00, 0x20, 0x00, 0x41, 0x08, 0x6b, 0x22, - 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, - 0x71, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, 0x04, 0x6b, 0x41, 0xf8, 0xc2, - 0x04, 0x22, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x01, - 0x20, 0x02, 0x36, 0x02, 0x00, 0x0b, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, - 0x01, 0x6c, 0x22, 0x00, 0x10, 0x07, 0x41, 0x00, 0x20, 0x00, 0x10, 0x0d, - 0x0b, 0x47, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00, - 0x41, 0xf0, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x41, 0x08, 0x6b, - 0x22, 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, 0x41, - 0x7c, 0x71, 0x46, 0x04, 0x40, 0x41, 0xf0, 0xc2, 0x04, 0x20, 0x02, 0x36, - 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x07, 0x20, 0x00, 0x20, - 0x02, 0x28, 0x02, 0x00, 0x10, 0x0c, 0x0f, 0x0b, 0x20, 0x01, 0x10, 0x07, - 0x0b, 0x07, 0x00, 0x20, 0x00, 0x10, 0x02, 0x00, 0x0b, 0xbe, 0x07, 0x01, - 0x04, 0x7f, 0x02, 0x40, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x41, 0x20, - 0x4d, 0x04, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x45, - 0x72, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, - 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x05, - 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x01, - 0x3a, 0x00, 0x01, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x20, 0x01, 0x41, 0x02, - 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x41, 0x02, 0x6b, - 0x22, 0x05, 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, 0x20, 0x01, 0x2d, - 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x20, 0x01, - 0x41, 0x03, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x41, - 0x03, 0x6b, 0x22, 0x05, 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, 0x20, - 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x04, 0x6b, - 0x21, 0x05, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, - 0x04, 0x6a, 0x0c, 0x02, 0x0b, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, - 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x02, 0x21, 0x05, 0x20, - 0x01, 0x21, 0x03, 0x20, 0x00, 0x0b, 0x22, 0x04, 0x41, 0x03, 0x71, 0x22, - 0x02, 0x45, 0x04, 0x40, 0x02, 0x40, 0x20, 0x05, 0x41, 0x10, 0x49, 0x04, - 0x40, 0x20, 0x05, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x10, - 0x6b, 0x22, 0x02, 0x41, 0x10, 0x71, 0x45, 0x04, 0x40, 0x20, 0x04, 0x20, - 0x03, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x20, 0x03, 0x29, - 0x02, 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, - 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x21, 0x05, 0x0b, - 0x20, 0x02, 0x41, 0x10, 0x49, 0x0d, 0x00, 0x20, 0x05, 0x21, 0x02, 0x03, - 0x40, 0x20, 0x04, 0x20, 0x03, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, - 0x04, 0x20, 0x03, 0x29, 0x02, 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x20, - 0x03, 0x29, 0x02, 0x10, 0x37, 0x02, 0x10, 0x20, 0x04, 0x20, 0x03, 0x29, - 0x02, 0x18, 0x37, 0x02, 0x18, 0x20, 0x04, 0x41, 0x20, 0x6a, 0x21, 0x04, - 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x20, 0x6b, - 0x22, 0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, - 0x08, 0x4f, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, 0x29, 0x02, 0x00, 0x37, - 0x02, 0x00, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, - 0x08, 0x6a, 0x21, 0x03, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x71, 0x04, 0x40, - 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x04, - 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, - 0x0b, 0x20, 0x02, 0x41, 0x02, 0x71, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, - 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, 0x21, - 0x04, 0x20, 0x03, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x0b, 0x20, 0x02, 0x41, - 0x01, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, - 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, - 0x7f, 0x02, 0x40, 0x20, 0x05, 0x41, 0x20, 0x4f, 0x04, 0x40, 0x20, 0x04, - 0x20, 0x03, 0x28, 0x02, 0x00, 0x22, 0x01, 0x3a, 0x00, 0x00, 0x02, 0x40, - 0x02, 0x40, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x0e, 0x02, 0x00, 0x01, 0x03, - 0x0b, 0x20, 0x04, 0x20, 0x01, 0x41, 0x08, 0x76, 0x3a, 0x00, 0x01, 0x20, - 0x04, 0x20, 0x03, 0x41, 0x06, 0x6a, 0x29, 0x01, 0x00, 0x37, 0x02, 0x06, - 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, 0x41, 0x10, 0x74, 0x20, 0x01, - 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x02, 0x20, 0x03, 0x41, 0x12, 0x6a, - 0x21, 0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x03, 0x41, 0x0e, 0x6a, 0x28, - 0x01, 0x00, 0x21, 0x03, 0x41, 0x0e, 0x21, 0x05, 0x20, 0x04, 0x41, 0x12, - 0x6a, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x05, 0x6a, 0x29, - 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, - 0x41, 0x18, 0x74, 0x20, 0x01, 0x41, 0x08, 0x76, 0x72, 0x36, 0x02, 0x01, - 0x20, 0x03, 0x41, 0x11, 0x6a, 0x21, 0x01, 0x41, 0x0d, 0x21, 0x06, 0x20, - 0x03, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x03, 0x41, 0x0f, 0x21, - 0x05, 0x20, 0x04, 0x41, 0x11, 0x6a, 0x0c, 0x02, 0x0b, 0x02, 0x7f, 0x20, - 0x05, 0x41, 0x10, 0x49, 0x04, 0x40, 0x20, 0x04, 0x21, 0x02, 0x20, 0x03, - 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x20, 0x04, 0x20, 0x03, 0x28, 0x00, 0x01, 0x36, 0x00, 0x01, 0x20, - 0x04, 0x20, 0x03, 0x29, 0x00, 0x05, 0x37, 0x00, 0x05, 0x20, 0x04, 0x20, - 0x03, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20, 0x04, 0x20, 0x03, 0x2d, - 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x02, - 0x20, 0x03, 0x41, 0x10, 0x6a, 0x0b, 0x21, 0x01, 0x20, 0x05, 0x41, 0x08, - 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x01, 0x41, 0x10, - 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x01, 0x41, 0x08, 0x76, 0x3a, - 0x00, 0x01, 0x20, 0x04, 0x20, 0x03, 0x41, 0x07, 0x6a, 0x29, 0x00, 0x00, - 0x37, 0x02, 0x07, 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, 0x41, 0x08, - 0x74, 0x20, 0x01, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x03, 0x20, 0x03, - 0x41, 0x13, 0x6a, 0x21, 0x01, 0x41, 0x0f, 0x21, 0x06, 0x20, 0x03, 0x41, - 0x0f, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x03, 0x41, 0x0d, 0x21, 0x05, 0x20, - 0x04, 0x41, 0x13, 0x6a, 0x0b, 0x21, 0x02, 0x20, 0x04, 0x20, 0x06, 0x6a, - 0x20, 0x03, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, - 0x00, 0x37, 0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, - 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x04, 0x71, - 0x04, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, 0x36, 0x00, 0x00, - 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04, 0x6a, - 0x21, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x02, 0x71, 0x04, 0x40, 0x20, 0x02, - 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x02, 0x41, 0x02, - 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x0b, 0x20, - 0x05, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2d, - 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x0b, 0x86, 0x03, 0x02, - 0x03, 0x7f, 0x01, 0x7e, 0x20, 0x02, 0x41, 0x21, 0x4f, 0x04, 0x40, 0x20, - 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0b, 0x00, 0x20, 0x00, 0x0f, 0x0b, - 0x02, 0x40, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, - 0x00, 0x00, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x01, 0x6b, + 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7f, 0x60, 0x03, 0x7f, + 0x7f, 0x7f, 0x01, 0x7f, 0x02, 0x9e, 0x01, 0x05, 0x03, 0x65, 0x6e, 0x76, + 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x65, + 0x6e, 0x76, 0x19, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x01, 0x70, 0x00, 0x01, 0x16, 0x77, 0x61, 0x73, + 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, + 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73, + 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, + 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, + 0x76, 0x69, 0x65, 0x77, 0x31, 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, + 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72, + 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x00, 0x01, 0x03, 0x2b, 0x2a, + 0x02, 0x00, 0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, + 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x05, 0x05, 0x00, 0x03, 0x00, + 0x03, 0x05, 0x03, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x03, 0x05, 0x05, + 0x05, 0x03, 0x03, 0x00, 0x03, 0x03, 0x06, 0x0d, 0x02, 0x7f, 0x01, 0x41, + 0x80, 0x80, 0x04, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0xad, 0x02, + 0x1c, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x03, 0x0f, 0x5f, 0x5f, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x06, + 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x00, + 0x07, 0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x08, 0x04, 0x66, + 0x72, 0x65, 0x65, 0x00, 0x09, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x00, 0x0a, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x0b, + 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x00, 0x14, 0x08, 0x69, 0x73, + 0x77, 0x61, 0x6c, 0x6e, 0x75, 0x6d, 0x00, 0x2c, 0x08, 0x69, 0x73, 0x77, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x15, 0x08, 0x69, 0x73, 0x77, 0x62, + 0x6c, 0x61, 0x6e, 0x6b, 0x00, 0x23, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, + 0x67, 0x69, 0x74, 0x00, 0x24, 0x08, 0x69, 0x73, 0x77, 0x6c, 0x6f, 0x77, + 0x65, 0x72, 0x00, 0x20, 0x08, 0x69, 0x73, 0x77, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x00, 0x2b, 0x08, 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, + 0x00, 0x1d, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, 0x69, 0x67, 0x69, 0x74, + 0x00, 0x28, 0x08, 0x74, 0x6f, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, + 0x19, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x1b, + 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72, 0x00, 0x17, 0x06, 0x6d, 0x65, + 0x6d, 0x63, 0x6d, 0x70, 0x00, 0x16, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, + 0x79, 0x00, 0x21, 0x07, 0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x00, + 0x1e, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, 0x74, 0x00, 0x1f, 0x06, 0x73, + 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x18, 0x07, 0x73, 0x74, 0x72, 0x6e, + 0x63, 0x61, 0x74, 0x00, 0x25, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, + 0x70, 0x00, 0x1c, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x70, 0x79, 0x00, + 0x27, 0x08, 0x01, 0x05, 0x0a, 0xb0, 0x30, 0x2a, 0x02, 0x00, 0x0b, 0x03, + 0x00, 0x00, 0x0b, 0x0e, 0x00, 0x41, 0xec, 0xc2, 0x04, 0x41, 0x00, 0x41, + 0x84, 0x01, 0xfc, 0x0b, 0x00, 0x0b, 0x57, 0x01, 0x01, 0x7f, 0x02, 0x40, + 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, + 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, + 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x41, 0x01, 0x36, + 0x02, 0x00, 0x10, 0x91, 0x80, 0x80, 0x80, 0x00, 0x10, 0x83, 0x80, 0x80, + 0x80, 0x00, 0x10, 0x8d, 0x80, 0x80, 0x80, 0x00, 0x21, 0x00, 0x10, 0x93, + 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x0d, 0x01, 0x0f, 0x0b, 0x00, 0x0b, + 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x49, 0x01, + 0x01, 0x7f, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x41, 0xf4, + 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, + 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, + 0x3f, 0x00, 0x21, 0x00, 0x20, 0x01, 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, + 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xf8, 0xc2, 0x84, + 0x80, 0x00, 0x6a, 0x20, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, + 0xae, 0x02, 0x01, 0x04, 0x7f, 0x41, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, + 0x00, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, + 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x02, + 0x45, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x21, + 0x04, 0x0c, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x02, 0x28, 0x02, 0x04, 0x22, + 0x04, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x21, 0x03, 0x20, 0x04, 0x21, 0x02, + 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, 0x00, 0x0b, 0x0b, + 0x20, 0x04, 0x28, 0x02, 0x04, 0x21, 0x02, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x03, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xfc, 0xc2, + 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, + 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x04, 0x0b, 0x20, 0x04, 0x41, 0x08, + 0x6a, 0x0f, 0x0b, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, + 0x02, 0x41, 0xf8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, + 0x02, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, + 0x04, 0x41, 0x08, 0x6a, 0x22, 0x03, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, + 0x41, 0x7c, 0x71, 0x22, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x02, 0x23, 0x81, + 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, + 0x02, 0x00, 0x6b, 0x41, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x0d, 0x01, 0x20, + 0x00, 0x41, 0x7f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x01, 0x6a, 0x40, 0x00, + 0x41, 0x7f, 0x46, 0x0d, 0x01, 0x3f, 0x00, 0x21, 0x01, 0x23, 0x81, 0x80, + 0x80, 0x80, 0x00, 0x41, 0xf8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x01, + 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x04, 0x20, 0x00, 0x36, + 0x02, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, 0x84, + 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x03, 0x21, 0x01, + 0x0b, 0x20, 0x01, 0x0b, 0x5c, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x20, 0x00, + 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x78, 0x6a, 0x22, 0x01, 0x28, 0x02, + 0x00, 0x21, 0x02, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, + 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x22, 0x03, 0x28, 0x02, 0x00, 0x20, + 0x00, 0x20, 0x02, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x46, 0x0d, + 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, + 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x22, 0x03, 0x28, 0x02, 0x00, + 0x36, 0x02, 0x00, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x36, 0x02, 0x00, 0x0b, + 0x0b, 0x24, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6c, 0x22, 0x00, 0x10, 0x88, + 0x80, 0x80, 0x80, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, + 0x00, 0x20, 0x01, 0x41, 0x00, 0x20, 0x00, 0xfc, 0x0b, 0x00, 0x0b, 0x20, + 0x01, 0x0b, 0x79, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, + 0x00, 0x20, 0x00, 0x41, 0x78, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x21, + 0x03, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, + 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20, 0x03, 0x6a, + 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23, 0x81, 0x80, + 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, + 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80, 0x80, + 0x80, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, + 0x02, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x20, 0x00, 0x20, 0x02, 0xfc, 0x0a, + 0x00, 0x00, 0x0b, 0x20, 0x01, 0x0f, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80, + 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, + 0x80, 0x00, 0x00, 0x0b, 0xd5, 0x01, 0x01, 0x03, 0x7f, 0x23, 0x80, 0x80, + 0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x80, 0x80, 0x80, + 0x80, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x20, 0x00, 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, 0x8f, + 0x80, 0x80, 0x80, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x08, 0x41, + 0x01, 0x6a, 0x22, 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x28, 0x02, 0x0c, + 0x10, 0x88, 0x80, 0x80, 0x80, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20, + 0x01, 0x41, 0x04, 0x10, 0x8a, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x45, + 0x0d, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x8e, 0x80, 0x80, 0x80, 0x00, + 0x0d, 0x04, 0x20, 0x00, 0x28, 0x02, 0x08, 0x20, 0x01, 0x10, 0x84, 0x80, + 0x80, 0x80, 0x00, 0x21, 0x01, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x24, 0x80, + 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x0f, 0x0b, 0x41, 0xc7, 0x00, 0x10, + 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, + 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, + 0x80, 0x80, 0x00, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, + 0x00, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, + 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x10, 0x89, + 0x80, 0x80, 0x80, 0x00, 0x41, 0xc7, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x80, 0x80, + 0x80, 0x80, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0b, 0x11, 0x00, 0x20, + 0x00, 0x20, 0x01, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xff, 0xff, + 0x03, 0x71, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x82, 0x80, 0x80, 0x80, + 0x00, 0x00, 0x0b, 0xdf, 0x01, 0x01, 0x02, 0x7f, 0x41, 0x00, 0x41, 0x84, + 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, + 0x80, 0x80, 0x84, 0x80, 0x00, 0x21, 0x00, 0x02, 0x40, 0x02, 0x40, 0x41, + 0x80, 0x80, 0x84, 0x80, 0x00, 0x45, 0x0d, 0x00, 0x41, 0x80, 0x80, 0x84, + 0x80, 0x00, 0x41, 0x80, 0x80, 0x80, 0x80, 0x00, 0x6b, 0x21, 0x01, 0x0c, + 0x01, 0x0b, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x21, 0x01, 0x41, 0xf0, + 0xc3, 0x84, 0x80, 0x00, 0x41, 0xf0, 0xc3, 0x84, 0x80, 0x00, 0x6b, 0x41, + 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x01, 0x41, 0x80, 0x80, 0x84, 0x80, + 0x00, 0x4b, 0x22, 0x00, 0x1b, 0x21, 0x01, 0x41, 0xf0, 0xc3, 0x84, 0x80, + 0x00, 0x41, 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x00, 0x1b, 0x21, 0x00, + 0x0b, 0x41, 0x38, 0x41, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, + 0x41, 0x34, 0x20, 0x01, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, + 0x30, 0x20, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, 0x08, + 0x41, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, + 0x00, 0x41, 0x04, 0x41, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, + 0xc3, 0x84, 0x80, 0x00, 0x41, 0x0c, 0x41, 0x00, 0x28, 0x02, 0x80, 0xc3, + 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, 0x00, + 0x20, 0x01, 0x41, 0x80, 0x80, 0x80, 0x04, 0x20, 0x01, 0x41, 0x80, 0x80, + 0x80, 0x04, 0x49, 0x1b, 0x36, 0x02, 0xe8, 0xc2, 0x84, 0x80, 0x00, 0x0b, + 0x02, 0x00, 0x0b, 0x0e, 0x00, 0x10, 0x92, 0x80, 0x80, 0x80, 0x00, 0x10, + 0x92, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xcf, 0x01, 0x01, 0x03, 0x7f, 0x20, + 0x00, 0x21, 0x01, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, + 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x0d, 0x00, + 0x20, 0x00, 0x20, 0x00, 0x6b, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, + 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x01, 0x41, + 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, + 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, + 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, + 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x0d, 0x01, 0x0b, 0x20, + 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x7b, 0x6a, 0x21, + 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x41, 0x80, + 0x82, 0x84, 0x08, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x28, 0x02, + 0x00, 0x22, 0x03, 0x6b, 0x20, 0x03, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, + 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x46, 0x0d, 0x00, 0x0b, + 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x2d, + 0x00, 0x00, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x21, 0x02, 0x20, + 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b, 0x0b, 0x3e, + 0x00, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, + 0x20, 0x00, 0x41, 0x08, 0x76, 0x2d, 0x00, 0x80, 0x80, 0x84, 0x80, 0x00, + 0x41, 0x05, 0x74, 0x20, 0x00, 0x41, 0x03, 0x76, 0x41, 0x1f, 0x71, 0x72, + 0x2d, 0x00, 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x00, 0x41, 0x07, 0x71, + 0x76, 0x41, 0x01, 0x71, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0xfe, 0xff, 0x0b, + 0x49, 0x0b, 0x49, 0x01, 0x03, 0x7f, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, + 0x20, 0x02, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x2d, + 0x00, 0x00, 0x22, 0x04, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x47, + 0x0d, 0x01, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, + 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, + 0x00, 0x0c, 0x02, 0x0b, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, + 0x0b, 0x20, 0x03, 0x0b, 0xf6, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, + 0x00, 0x47, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, + 0x00, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, + 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, + 0x05, 0x0c, 0x03, 0x0b, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, + 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x04, 0x41, + 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, + 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, + 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, + 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, + 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, + 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7d, + 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, + 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, + 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, + 0x71, 0x46, 0x0d, 0x02, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, + 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x0c, + 0x01, 0x0b, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x04, 0x0b, 0x20, + 0x03, 0x45, 0x0d, 0x01, 0x02, 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, + 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x04, + 0x49, 0x0d, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, + 0x84, 0x08, 0x6c, 0x21, 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, + 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x73, 0x22, 0x02, 0x6b, 0x20, + 0x02, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, + 0x82, 0x84, 0x78, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, + 0x04, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, + 0xff, 0x01, 0x71, 0x21, 0x02, 0x03, 0x40, 0x02, 0x40, 0x20, 0x04, 0x2d, + 0x00, 0x00, 0x20, 0x02, 0x47, 0x0d, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, + 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x22, + 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, 0x0b, 0x67, 0x01, 0x02, 0x7f, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x02, 0x40, 0x20, 0x00, 0x2d, + 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x02, 0x41, + 0xff, 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, + 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, + 0x2d, 0x00, 0x00, 0x21, 0x02, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x03, + 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x01, + 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x20, 0x02, 0x41, 0xff, 0x01, + 0x71, 0x46, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03, 0x20, 0x02, 0x41, 0xff, + 0x01, 0x71, 0x6b, 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x10, 0x9a, + 0x80, 0x80, 0x80, 0x00, 0x0b, 0xa6, 0x02, 0x01, 0x07, 0x7f, 0x02, 0x40, + 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x20, 0x00, 0x20, + 0x00, 0x41, 0xff, 0x01, 0x71, 0x22, 0x02, 0x41, 0x03, 0x6e, 0x22, 0x03, + 0x41, 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71, 0x41, 0x02, 0x74, 0x28, + 0x02, 0xc0, 0x9e, 0x84, 0x80, 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x22, + 0x04, 0x2d, 0x00, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x41, 0xd6, 0x00, 0x6c, + 0x20, 0x03, 0x6a, 0x2d, 0x00, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x6c, 0x41, + 0x0b, 0x76, 0x41, 0x06, 0x70, 0x20, 0x04, 0x2d, 0x00, 0x90, 0xbe, 0x84, + 0x80, 0x00, 0x6a, 0x41, 0x02, 0x74, 0x28, 0x02, 0xd0, 0x9e, 0x84, 0x80, + 0x00, 0x22, 0x03, 0x41, 0x08, 0x75, 0x21, 0x04, 0x02, 0x40, 0x20, 0x03, + 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, + 0x04, 0x41, 0x00, 0x20, 0x03, 0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, 0x00, + 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x45, + 0x0d, 0x00, 0x20, 0x04, 0x41, 0x08, 0x76, 0x21, 0x04, 0x03, 0x40, 0x02, + 0x40, 0x20, 0x02, 0x20, 0x03, 0x41, 0x01, 0x76, 0x22, 0x05, 0x20, 0x04, + 0x6a, 0x22, 0x06, 0x41, 0x01, 0x74, 0x22, 0x07, 0x2d, 0x00, 0x90, 0xa6, + 0x84, 0x80, 0x00, 0x22, 0x08, 0x47, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x07, + 0x41, 0x90, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x01, 0x41, 0x02, + 0x74, 0x28, 0x02, 0xd0, 0x9e, 0x84, 0x80, 0x00, 0x22, 0x03, 0x41, 0xff, + 0x01, 0x71, 0x22, 0x04, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, 0x03, 0x41, + 0x08, 0x75, 0x41, 0x00, 0x20, 0x04, 0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, + 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, 0x01, 0x20, 0x01, 0x1b, 0x20, + 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x20, 0x02, 0x20, 0x08, + 0x49, 0x22, 0x08, 0x1b, 0x21, 0x04, 0x20, 0x05, 0x20, 0x03, 0x20, 0x05, + 0x6b, 0x20, 0x08, 0x1b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, + 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x01, 0x10, 0x9a, 0x80, 0x80, 0x80, + 0x00, 0x0b, 0x87, 0x01, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x0d, + 0x00, 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x2d, + 0x00, 0x00, 0x22, 0x03, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x03, 0x0c, 0x01, + 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, + 0x6a, 0x21, 0x02, 0x02, 0x40, 0x03, 0x40, 0x20, 0x03, 0x41, 0xff, 0x01, + 0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x47, 0x0d, 0x01, 0x20, + 0x04, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x41, 0x00, 0x46, 0x0d, 0x01, 0x20, + 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, + 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, + 0x6a, 0x21, 0x00, 0x20, 0x03, 0x0d, 0x00, 0x0b, 0x41, 0x00, 0x21, 0x03, + 0x0b, 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x21, 0x03, 0x0b, 0x20, 0x03, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, + 0x99, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x47, 0x0b, 0xb7, 0x0a, 0x01, + 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x21, 0x49, 0x0d, + 0x00, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, + 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x20, 0x01, + 0x46, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x01, 0x20, 0x02, 0x20, 0x00, 0x6a, + 0x22, 0x03, 0x6b, 0x41, 0x00, 0x20, 0x02, 0x41, 0x01, 0x74, 0x6b, 0x4b, + 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, + 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x20, + 0x00, 0x73, 0x41, 0x03, 0x71, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x20, 0x00, 0x20, 0x01, 0x4f, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x04, + 0x45, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, + 0x03, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, + 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x20, 0x02, + 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, + 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, + 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, + 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, + 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x02, + 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x02, + 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, + 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x41, + 0x7d, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, + 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x21, + 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, + 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x41, 0x04, 0x6a, + 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, + 0x7c, 0x6a, 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x04, 0x0d, + 0x00, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, + 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, + 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, + 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, + 0x20, 0x00, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, + 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, + 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, + 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, + 0x41, 0x7d, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, + 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, + 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, + 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, + 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x20, + 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x06, 0x41, 0x0c, 0x71, 0x41, 0x0c, 0x46, + 0x0d, 0x00, 0x20, 0x06, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x03, + 0x71, 0x21, 0x03, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, + 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, 0x20, 0x02, 0x6a, + 0x20, 0x04, 0x20, 0x02, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, + 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20, 0x03, 0x41, 0x7f, 0x6a, 0x22, + 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x06, 0x41, 0x0c, 0x49, 0x0d, 0x00, + 0x20, 0x01, 0x41, 0x70, 0x6a, 0x21, 0x05, 0x20, 0x00, 0x41, 0x70, 0x6a, + 0x21, 0x06, 0x03, 0x40, 0x20, 0x06, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, + 0x0c, 0x6a, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x22, 0x04, 0x41, 0x0c, 0x6a, + 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, + 0x04, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x41, 0x04, 0x6a, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x20, 0x04, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, + 0x20, 0x02, 0x41, 0x70, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x21, 0x03, 0x02, + 0x40, 0x20, 0x02, 0x41, 0x03, 0x71, 0x22, 0x04, 0x45, 0x0d, 0x00, 0x20, + 0x01, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x21, + 0x06, 0x20, 0x02, 0x21, 0x03, 0x03, 0x40, 0x20, 0x06, 0x20, 0x03, 0x6a, + 0x20, 0x05, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, + 0x03, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x04, 0x41, 0x7f, 0x6a, 0x22, + 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x02, + 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, + 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, 0x20, 0x03, 0x6a, 0x22, 0x01, 0x41, + 0x03, 0x6a, 0x20, 0x04, 0x20, 0x03, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x6a, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x20, + 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, + 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x20, 0x01, 0x20, 0x02, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, + 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x03, 0x0d, 0x00, 0x0c, 0x03, 0x0b, + 0x0b, 0x20, 0x05, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x05, + 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x41, 0x1c, 0x71, 0x41, 0x1c, 0x46, 0x0d, + 0x00, 0x20, 0x05, 0x20, 0x04, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, + 0x07, 0x71, 0x22, 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x05, 0x03, 0x40, + 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, + 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, + 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, + 0x04, 0x41, 0x1c, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, + 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, + 0x01, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x01, 0x41, 0x0c, 0x6a, + 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x20, + 0x01, 0x41, 0x10, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x41, 0x14, 0x6a, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x36, + 0x02, 0x00, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, 0x01, 0x41, 0x18, 0x6a, + 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x1c, 0x6a, 0x20, + 0x01, 0x41, 0x1c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, + 0x41, 0x20, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, + 0x20, 0x05, 0x41, 0x60, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x05, 0x41, 0x07, 0x71, 0x22, 0x02, 0x0d, 0x00, 0x20, 0x05, 0x21, 0x04, + 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x78, 0x71, 0x21, 0x04, 0x03, 0x40, + 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, + 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, + 0x05, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x20, + 0x01, 0x41, 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x02, 0x6a, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x20, 0x03, 0x41, 0x03, 0x6a, 0x20, 0x01, 0x41, 0x03, 0x6a, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, + 0x01, 0x41, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x05, 0x6a, 0x20, 0x01, 0x41, 0x05, 0x6a, 0x2d, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x20, 0x03, 0x41, 0x06, 0x6a, 0x20, 0x01, 0x41, 0x06, 0x6a, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x07, 0x6a, 0x20, + 0x01, 0x41, 0x07, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, + 0x20, 0x04, 0x41, 0x78, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20, + 0x00, 0x0b, 0x96, 0x03, 0x02, 0x03, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x02, + 0x40, 0x20, 0x02, 0x41, 0x21, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, + 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0b, 0x00, 0x20, 0x00, + 0x0f, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, + 0x00, 0x00, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x7f, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, - 0x00, 0x01, 0x20, 0x03, 0x41, 0x03, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, - 0x20, 0x03, 0x41, 0x02, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, + 0x00, 0x01, 0x20, 0x03, 0x41, 0x7d, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, + 0x20, 0x03, 0x41, 0x7e, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x07, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, - 0x20, 0x03, 0x41, 0x04, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, + 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, - 0x41, 0x03, 0x71, 0x22, 0x05, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x41, 0xff, + 0x41, 0x03, 0x71, 0x22, 0x04, 0x6a, 0x22, 0x05, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x22, 0x03, 0x36, 0x02, - 0x00, 0x20, 0x04, 0x20, 0x02, 0x20, 0x05, 0x6b, 0x41, 0x3c, 0x71, 0x22, - 0x02, 0x6a, 0x22, 0x01, 0x41, 0x04, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, - 0x20, 0x02, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x03, 0x36, - 0x02, 0x08, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x04, 0x20, 0x01, 0x41, - 0x08, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x0c, 0x6b, - 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x19, 0x49, 0x0d, 0x00, - 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x18, 0x20, 0x04, 0x20, 0x03, 0x36, - 0x02, 0x14, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x10, 0x20, 0x04, 0x20, - 0x03, 0x36, 0x02, 0x0c, 0x20, 0x01, 0x41, 0x10, 0x6b, 0x20, 0x03, 0x36, - 0x02, 0x00, 0x20, 0x01, 0x41, 0x14, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, - 0x20, 0x01, 0x41, 0x18, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, - 0x41, 0x1c, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x04, + 0x00, 0x20, 0x05, 0x20, 0x02, 0x20, 0x04, 0x6b, 0x41, 0x3c, 0x71, 0x22, + 0x01, 0x6a, 0x22, 0x02, 0x41, 0x7c, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, + 0x20, 0x01, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x03, 0x36, + 0x02, 0x08, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x04, 0x20, 0x02, 0x41, + 0x78, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x74, 0x6a, + 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x19, 0x49, 0x0d, 0x00, + 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x18, 0x20, 0x05, 0x20, 0x03, 0x36, + 0x02, 0x14, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x10, 0x20, 0x05, 0x20, + 0x03, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x41, 0x70, 0x6a, 0x20, 0x03, 0x36, + 0x02, 0x00, 0x20, 0x02, 0x41, 0x6c, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, + 0x20, 0x02, 0x41, 0x68, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, + 0x41, 0x64, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x05, 0x41, 0x04, 0x71, 0x41, 0x18, 0x72, 0x22, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x20, 0x49, 0x0d, 0x00, 0x20, 0x03, 0xad, 0x42, 0x81, 0x80, 0x80, 0x80, - 0x10, 0x7e, 0x21, 0x06, 0x20, 0x02, 0x20, 0x04, 0x6a, 0x21, 0x02, 0x03, - 0x40, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x18, 0x20, 0x02, 0x20, 0x06, - 0x37, 0x03, 0x10, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x08, 0x20, 0x02, - 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, - 0x20, 0x01, 0x41, 0x20, 0x6b, 0x22, 0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, - 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0xc5, 0x01, 0x01, 0x03, 0x7f, 0x02, 0x40, - 0x02, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, - 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x0f, 0x0b, - 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, - 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, - 0x02, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, - 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, - 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, - 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03, - 0x71, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x02, 0x20, - 0x01, 0x41, 0x05, 0x6b, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04, - 0x6a, 0x21, 0x01, 0x41, 0x80, 0x82, 0x84, 0x08, 0x20, 0x02, 0x41, 0x04, - 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x22, 0x03, 0x6b, 0x20, 0x03, 0x72, - 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, - 0x78, 0x46, 0x0d, 0x00, 0x0b, 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, - 0x21, 0x01, 0x20, 0x02, 0x2d, 0x00, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6a, - 0x21, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b, 0x0b, - 0x3e, 0x00, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4d, 0x04, 0x40, 0x20, - 0x00, 0x41, 0x03, 0x76, 0x41, 0x1f, 0x71, 0x20, 0x00, 0x41, 0x08, 0x76, - 0x41, 0x80, 0x80, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x41, 0x05, 0x74, 0x72, - 0x41, 0x80, 0x80, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x20, 0x00, 0x41, 0x07, - 0x71, 0x76, 0x41, 0x01, 0x71, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0xfe, 0xff, - 0x0b, 0x49, 0x0b, 0x43, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x45, - 0x0d, 0x00, 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x20, - 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x46, 0x04, 0x40, 0x20, 0x01, 0x41, - 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, - 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x01, 0x0c, 0x02, 0x0b, 0x0b, - 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, 0x0b, 0x20, 0x03, 0x0b, 0xe9, - 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, 0x05, 0x02, - 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x20, - 0x02, 0x45, 0x72, 0x45, 0x04, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x20, - 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x04, 0x40, 0x20, 0x00, 0x21, 0x03, - 0x20, 0x02, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x02, 0x41, 0x01, 0x6b, - 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, 0x05, 0x20, 0x00, 0x41, 0x01, 0x6a, - 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x04, 0x45, 0x72, 0x0d, 0x01, - 0x20, 0x03, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, - 0x0d, 0x02, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, - 0x21, 0x05, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, - 0x45, 0x20, 0x04, 0x45, 0x72, 0x0d, 0x01, 0x20, 0x03, 0x2d, 0x00, 0x00, - 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, - 0x03, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, 0x05, 0x20, 0x00, 0x41, - 0x03, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x04, 0x45, 0x72, - 0x0d, 0x01, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, - 0x71, 0x46, 0x0d, 0x02, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, - 0x02, 0x41, 0x04, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, 0x05, 0x0c, - 0x01, 0x0b, 0x20, 0x02, 0x21, 0x04, 0x20, 0x00, 0x21, 0x03, 0x0b, 0x20, - 0x05, 0x45, 0x0d, 0x01, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x22, 0x00, - 0x20, 0x03, 0x2d, 0x00, 0x00, 0x46, 0x20, 0x04, 0x41, 0x04, 0x49, 0x72, - 0x45, 0x04, 0x40, 0x20, 0x00, 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x21, - 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, 0x20, 0x03, 0x28, 0x02, - 0x00, 0x20, 0x00, 0x73, 0x22, 0x02, 0x6b, 0x20, 0x02, 0x72, 0x41, 0x80, - 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x47, - 0x0d, 0x02, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x04, 0x41, - 0x04, 0x6b, 0x22, 0x04, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x04, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x21, - 0x00, 0x03, 0x40, 0x20, 0x00, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x46, 0x04, - 0x40, 0x20, 0x03, 0x0f, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, - 0x20, 0x04, 0x41, 0x01, 0x6b, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x41, - 0x00, 0x0b, 0x58, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, - 0x00, 0x22, 0x02, 0x45, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, - 0x03, 0x47, 0x72, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, - 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x2d, - 0x00, 0x00, 0x21, 0x03, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x02, 0x45, - 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x01, 0x41, - 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x20, 0x03, 0x46, 0x0d, 0x00, 0x0b, - 0x0b, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x41, - 0x00, 0x10, 0x14, 0x0b, 0xa0, 0x02, 0x01, 0x07, 0x7f, 0x02, 0x40, 0x20, - 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, - 0x41, 0xff, 0x01, 0x71, 0x22, 0x05, 0x41, 0x03, 0x6e, 0x22, 0x02, 0x41, - 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71, 0x41, 0x02, 0x74, 0x41, 0xc0, - 0x9e, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x20, 0x02, 0x20, 0x00, 0x41, 0x08, - 0x76, 0x22, 0x02, 0x41, 0xa0, 0xa9, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x41, - 0xd6, 0x00, 0x6c, 0x6a, 0x41, 0xa0, 0xa9, 0x04, 0x6a, 0x2d, 0x00, 0x00, - 0x6c, 0x41, 0x0b, 0x76, 0x41, 0x06, 0x70, 0x20, 0x02, 0x41, 0x90, 0xbe, - 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x6a, 0x41, 0x02, 0x74, 0x41, 0xd0, 0x9e, - 0x04, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x03, 0x41, 0x08, 0x75, 0x21, 0x02, - 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4d, 0x04, - 0x40, 0x20, 0x02, 0x41, 0x00, 0x20, 0x01, 0x20, 0x03, 0x73, 0x6b, 0x71, - 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x22, - 0x03, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x41, 0x08, 0x76, 0x21, 0x02, 0x03, - 0x40, 0x20, 0x03, 0x41, 0x01, 0x76, 0x22, 0x06, 0x20, 0x02, 0x6a, 0x22, - 0x04, 0x41, 0x01, 0x74, 0x41, 0x90, 0xa6, 0x04, 0x6a, 0x22, 0x07, 0x2d, - 0x00, 0x00, 0x22, 0x08, 0x20, 0x05, 0x46, 0x04, 0x40, 0x20, 0x07, 0x2d, - 0x00, 0x01, 0x41, 0x02, 0x74, 0x41, 0xd0, 0x9e, 0x04, 0x6a, 0x28, 0x02, - 0x00, 0x22, 0x02, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4d, - 0x04, 0x40, 0x41, 0x00, 0x20, 0x01, 0x20, 0x03, 0x73, 0x6b, 0x20, 0x02, - 0x41, 0x08, 0x75, 0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, - 0x01, 0x20, 0x01, 0x1b, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x02, 0x20, - 0x04, 0x20, 0x05, 0x20, 0x08, 0x49, 0x22, 0x04, 0x1b, 0x21, 0x02, 0x20, - 0x06, 0x20, 0x03, 0x20, 0x06, 0x6b, 0x20, 0x04, 0x1b, 0x22, 0x03, 0x0d, - 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x41, 0x01, - 0x10, 0x14, 0x0b, 0x75, 0x01, 0x02, 0x7f, 0x20, 0x02, 0x45, 0x04, 0x40, - 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, - 0x03, 0x45, 0x04, 0x40, 0x41, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, - 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x21, - 0x02, 0x02, 0x40, 0x03, 0x40, 0x20, 0x02, 0x45, 0x20, 0x03, 0x20, 0x01, - 0x2d, 0x00, 0x00, 0x22, 0x04, 0x47, 0x20, 0x04, 0x45, 0x72, 0x72, 0x0d, - 0x01, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x21, 0x02, 0x20, 0x01, 0x41, 0x01, - 0x6a, 0x21, 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x00, - 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x0d, 0x00, 0x0b, 0x41, 0x00, - 0x21, 0x03, 0x0b, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, - 0x0b, 0x09, 0x00, 0x20, 0x00, 0x10, 0x13, 0x20, 0x00, 0x47, 0x0b, 0xa1, - 0x09, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x21, - 0x49, 0x04, 0x40, 0x20, 0x00, 0x20, 0x01, 0x46, 0x0d, 0x02, 0x20, 0x01, - 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x04, 0x6b, 0x41, 0x00, 0x20, 0x02, - 0x41, 0x01, 0x74, 0x6b, 0x4b, 0x0d, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, - 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, - 0x01, 0x73, 0x41, 0x03, 0x71, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x20, - 0x00, 0x20, 0x01, 0x49, 0x04, 0x40, 0x20, 0x03, 0x04, 0x40, 0x20, 0x02, - 0x21, 0x04, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x00, 0x41, - 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x04, 0x20, 0x00, 0x21, - 0x03, 0x0c, 0x02, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, - 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6b, - 0x21, 0x04, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, - 0x45, 0x04, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, - 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, - 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x21, 0x04, 0x20, - 0x00, 0x41, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, - 0x20, 0x01, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x04, - 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, - 0x02, 0x20, 0x02, 0x41, 0x03, 0x6b, 0x21, 0x04, 0x20, 0x00, 0x41, 0x03, - 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x41, - 0x03, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x03, - 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, + 0x10, 0x7e, 0x21, 0x06, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x21, 0x02, 0x03, + 0x40, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x18, + 0x6a, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x20, + 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x20, 0x06, 0x37, + 0x03, 0x00, 0x20, 0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, + 0x60, 0x6a, 0x22, 0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, + 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x9b, 0x80, 0x80, 0x80, 0x00, + 0x20, 0x00, 0x47, 0x0b, 0x85, 0x08, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x20, 0x4b, 0x0d, 0x00, + 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x45, 0x0d, + 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, + 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, + 0x04, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, + 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, + 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x03, + 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x02, 0x6a, + 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, + 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, + 0x02, 0x41, 0x7d, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x21, + 0x04, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, + 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, + 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x03, + 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x04, 0x6a, + 0x21, 0x05, 0x0c, 0x02, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x00, + 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, + 0x20, 0x02, 0x21, 0x03, 0x20, 0x00, 0x21, 0x04, 0x20, 0x01, 0x21, 0x05, + 0x0b, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x22, 0x02, 0x0d, 0x00, + 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20, + 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x70, + 0x6a, 0x22, 0x02, 0x41, 0x10, 0x71, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, + 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, + 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20, + 0x05, 0x41, 0x10, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x21, 0x03, 0x0b, 0x20, + 0x02, 0x41, 0x10, 0x49, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x03, 0x40, + 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, + 0x41, 0x08, 0x6a, 0x20, 0x05, 0x41, 0x08, 0x6a, 0x29, 0x02, 0x00, 0x37, + 0x02, 0x00, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x20, 0x05, 0x41, 0x10, 0x6a, + 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x41, 0x18, 0x6a, 0x20, + 0x05, 0x41, 0x18, 0x6a, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, + 0x41, 0x20, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x20, 0x6a, 0x21, 0x05, + 0x20, 0x02, 0x41, 0x60, 0x6a, 0x22, 0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, + 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x20, + 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x05, 0x41, + 0x08, 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x21, 0x04, 0x0b, + 0x02, 0x40, 0x20, 0x02, 0x41, 0x04, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, + 0x20, 0x05, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x05, 0x41, 0x04, + 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x0b, 0x02, + 0x40, 0x20, 0x02, 0x41, 0x02, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, + 0x05, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, + 0x21, 0x04, 0x20, 0x05, 0x41, 0x02, 0x6a, 0x21, 0x05, 0x0b, 0x20, 0x02, + 0x41, 0x01, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, + 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x20, 0x49, 0x0d, + 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x22, 0x03, 0x3a, 0x00, + 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x0e, 0x03, + 0x03, 0x00, 0x01, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x08, 0x76, + 0x3a, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x06, 0x6a, 0x29, 0x01, + 0x00, 0x37, 0x02, 0x06, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, + 0x10, 0x74, 0x20, 0x03, 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x02, 0x20, + 0x04, 0x41, 0x12, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x12, 0x6a, 0x21, + 0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0e, 0x6a, 0x28, 0x01, + 0x00, 0x21, 0x05, 0x41, 0x0e, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x04, + 0x20, 0x05, 0x41, 0x05, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, + 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, 0x18, 0x74, 0x20, 0x03, 0x41, + 0x08, 0x76, 0x72, 0x36, 0x02, 0x01, 0x20, 0x04, 0x41, 0x11, 0x6a, 0x21, + 0x02, 0x20, 0x05, 0x41, 0x11, 0x6a, 0x21, 0x01, 0x41, 0x0d, 0x21, 0x06, + 0x20, 0x05, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x05, 0x41, 0x0f, + 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, + 0x10, 0x4f, 0x0d, 0x00, 0x20, 0x04, 0x21, 0x02, 0x20, 0x05, 0x21, 0x01, + 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x00, 0x01, 0x36, 0x00, 0x01, 0x20, + 0x04, 0x20, 0x05, 0x29, 0x00, 0x05, 0x37, 0x00, 0x05, 0x20, 0x04, 0x20, + 0x05, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20, 0x04, 0x20, 0x05, 0x2d, + 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x02, + 0x20, 0x05, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x08, + 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x10, + 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x03, 0x41, 0x08, 0x76, 0x3a, + 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x07, 0x6a, 0x29, 0x00, 0x00, + 0x37, 0x02, 0x07, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, 0x08, + 0x74, 0x20, 0x03, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x03, 0x20, 0x04, + 0x41, 0x13, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x13, 0x6a, 0x21, 0x01, + 0x41, 0x0f, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0f, 0x6a, 0x28, 0x00, 0x00, + 0x21, 0x05, 0x41, 0x0d, 0x21, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x6a, + 0x20, 0x05, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, + 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, + 0x04, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, + 0x41, 0x04, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x02, + 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, + 0x00, 0x00, 0x20, 0x02, 0x41, 0x02, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, + 0x02, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x71, 0x45, 0x0d, + 0x00, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, + 0x20, 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x20, 0x46, 0x20, 0x00, + 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x10, 0xa2, 0x80, + 0x80, 0x80, 0x00, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, + 0x0a, 0x49, 0x0b, 0x4d, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x20, 0x00, 0x10, + 0x94, 0x80, 0x80, 0x80, 0x00, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, + 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x04, + 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, + 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, + 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, 0xfa, 0x03, 0x01, + 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, + 0x20, 0x01, 0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, + 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, + 0x04, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71, 0x0d, 0x00, + 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x0d, + 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, + 0x2d, 0x00, 0x00, 0x22, 0x03, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x03, + 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x05, + 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7f, + 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, + 0x41, 0x01, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, + 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, + 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x05, 0x20, 0x00, 0x41, + 0x02, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x05, 0x41, + 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x22, + 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, + 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, + 0x20, 0x04, 0x45, 0x0d, 0x06, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x21, 0x03, + 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, + 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, + 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, + 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, + 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, + 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x00, + 0x47, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, + 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, 0x21, + 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, 0x21, 0x02, + 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x02, 0x40, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x04, 0x0b, 0x20, 0x02, + 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, + 0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x00, 0x6b, 0x20, 0x00, 0x72, 0x41, + 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, + 0x47, 0x0d, 0x02, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, - 0x20, 0x02, 0x41, 0x04, 0x6b, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x02, 0x40, - 0x20, 0x03, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, - 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, - 0x01, 0x6b, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, - 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, - 0x04, 0x40, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, - 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x03, 0x6a, - 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x03, 0x21, - 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, - 0x02, 0x41, 0x03, 0x6b, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, - 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x41, 0x03, - 0x71, 0x45, 0x04, 0x40, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, - 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x22, - 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x41, - 0x04, 0x6b, 0x22, 0x04, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x03, - 0x71, 0x22, 0x03, 0x04, 0x40, 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x05, - 0x20, 0x00, 0x41, 0x04, 0x6b, 0x21, 0x06, 0x03, 0x40, 0x20, 0x02, 0x20, - 0x06, 0x6a, 0x20, 0x02, 0x20, 0x05, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, - 0x00, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x21, 0x02, 0x20, 0x03, 0x41, 0x01, - 0x6b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x04, 0x41, 0x0c, 0x49, - 0x0d, 0x00, 0x20, 0x01, 0x41, 0x10, 0x6b, 0x21, 0x05, 0x20, 0x00, 0x41, - 0x10, 0x6b, 0x21, 0x06, 0x03, 0x40, 0x20, 0x02, 0x20, 0x06, 0x6a, 0x22, - 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x02, 0x20, 0x05, 0x6a, 0x22, 0x04, 0x41, - 0x0c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, - 0x6a, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, - 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x28, 0x02, - 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x04, 0x28, 0x02, 0x00, 0x36, - 0x02, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6b, 0x22, 0x02, 0x41, 0x03, 0x4b, - 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x22, - 0x03, 0x41, 0x03, 0x71, 0x22, 0x05, 0x04, 0x40, 0x20, 0x01, 0x41, 0x01, - 0x6b, 0x21, 0x04, 0x20, 0x00, 0x41, 0x01, 0x6b, 0x21, 0x06, 0x03, 0x40, - 0x20, 0x03, 0x20, 0x06, 0x6a, 0x20, 0x03, 0x20, 0x04, 0x6a, 0x2d, 0x00, - 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6b, 0x21, 0x03, 0x20, - 0x05, 0x41, 0x01, 0x6b, 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, - 0x41, 0x04, 0x49, 0x0d, 0x02, 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x04, - 0x20, 0x00, 0x41, 0x04, 0x6b, 0x21, 0x05, 0x03, 0x40, 0x20, 0x03, 0x20, - 0x05, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x6a, 0x20, 0x03, 0x20, 0x04, 0x6a, - 0x22, 0x02, 0x41, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, - 0x01, 0x41, 0x02, 0x6a, 0x20, 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, - 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41, 0x01, - 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x20, 0x02, 0x2d, - 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6b, 0x22, 0x03, - 0x0d, 0x00, 0x0b, 0x0c, 0x02, 0x0b, 0x20, 0x04, 0x41, 0x04, 0x49, 0x0d, - 0x00, 0x20, 0x04, 0x41, 0x04, 0x6b, 0x22, 0x05, 0x41, 0x02, 0x76, 0x41, - 0x01, 0x6a, 0x41, 0x07, 0x71, 0x22, 0x02, 0x04, 0x40, 0x20, 0x04, 0x20, - 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x04, 0x03, 0x40, 0x20, 0x03, 0x20, - 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x04, 0x6a, - 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, - 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x41, 0x1c, - 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, - 0x36, 0x02, 0x00, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x04, 0x36, 0x02, - 0x04, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x08, 0x36, 0x02, 0x08, 0x20, - 0x03, 0x20, 0x01, 0x28, 0x02, 0x0c, 0x36, 0x02, 0x0c, 0x20, 0x03, 0x20, - 0x01, 0x28, 0x02, 0x10, 0x36, 0x02, 0x10, 0x20, 0x03, 0x20, 0x01, 0x28, - 0x02, 0x14, 0x36, 0x02, 0x14, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x18, - 0x36, 0x02, 0x18, 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x1c, 0x36, 0x02, - 0x1c, 0x20, 0x01, 0x41, 0x20, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x20, - 0x6a, 0x21, 0x03, 0x20, 0x04, 0x41, 0x20, 0x6b, 0x22, 0x04, 0x41, 0x03, - 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x00, 0x02, 0x40, - 0x20, 0x04, 0x41, 0x07, 0x71, 0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x04, - 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x41, 0x78, 0x71, 0x21, 0x05, - 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, - 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, - 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, 0x0b, - 0x0b, 0x20, 0x04, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, - 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x20, 0x01, - 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, - 0x02, 0x3a, 0x00, 0x02, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, - 0x00, 0x03, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x04, 0x3a, 0x00, 0x04, - 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x05, 0x3a, 0x00, 0x05, 0x20, 0x03, - 0x20, 0x01, 0x2d, 0x00, 0x06, 0x3a, 0x00, 0x06, 0x20, 0x03, 0x20, 0x01, - 0x2d, 0x00, 0x07, 0x3a, 0x00, 0x07, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x21, - 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x20, 0x05, 0x41, 0x08, - 0x6b, 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, 0x09, 0x00, - 0x20, 0x00, 0x10, 0x15, 0x20, 0x00, 0x47, 0x0b, 0x0d, 0x00, 0x20, 0x00, - 0x41, 0x20, 0x46, 0x20, 0x00, 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, 0x00, - 0x20, 0x00, 0x41, 0x30, 0x6b, 0x41, 0x0a, 0x49, 0x0b, 0x49, 0x01, 0x02, - 0x7f, 0x20, 0x00, 0x10, 0x0e, 0x20, 0x00, 0x6a, 0x21, 0x03, 0x02, 0x40, - 0x20, 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00, - 0x22, 0x04, 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, 0x00, - 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, - 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, 0x0b, - 0x0b, 0x20, 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, 0xe6, - 0x03, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, - 0x20, 0x00, 0x20, 0x01, 0x22, 0x03, 0x73, 0x41, 0x03, 0x71, 0x04, 0x40, - 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00, 0x47, - 0x21, 0x06, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, - 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x45, 0x04, 0x40, - 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x03, 0x2d, - 0x00, 0x00, 0x22, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x45, 0x04, 0x40, - 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, 0x01, 0x0c, 0x05, 0x0b, 0x20, - 0x00, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, - 0x01, 0x41, 0x00, 0x47, 0x21, 0x06, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x22, - 0x05, 0x41, 0x03, 0x71, 0x45, 0x20, 0x01, 0x45, 0x72, 0x45, 0x04, 0x40, - 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, - 0x20, 0x05, 0x45, 0x0d, 0x05, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, 0x04, - 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x00, 0x47, 0x21, 0x06, - 0x20, 0x03, 0x41, 0x02, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x20, - 0x01, 0x45, 0x72, 0x45, 0x04, 0x40, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, - 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x06, 0x20, - 0x00, 0x41, 0x03, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x03, 0x6b, 0x22, - 0x01, 0x41, 0x00, 0x47, 0x21, 0x06, 0x20, 0x03, 0x41, 0x03, 0x6a, 0x22, - 0x05, 0x41, 0x03, 0x71, 0x45, 0x20, 0x01, 0x45, 0x72, 0x45, 0x04, 0x40, - 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, - 0x20, 0x05, 0x45, 0x0d, 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, - 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x04, 0x6b, - 0x22, 0x02, 0x41, 0x00, 0x47, 0x21, 0x06, 0x0c, 0x03, 0x0b, 0x20, 0x05, - 0x21, 0x03, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x21, - 0x03, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x21, 0x03, - 0x20, 0x01, 0x21, 0x02, 0x0b, 0x20, 0x06, 0x45, 0x0d, 0x02, 0x20, 0x03, - 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x01, 0x0c, 0x04, - 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x41, 0x80, - 0x82, 0x84, 0x08, 0x20, 0x03, 0x28, 0x02, 0x00, 0x22, 0x01, 0x6b, 0x20, - 0x01, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, - 0x82, 0x84, 0x78, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x20, 0x01, 0x36, 0x02, - 0x00, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, 0x04, - 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x22, 0x02, 0x41, 0x03, - 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, 0x03, - 0x40, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x22, 0x01, 0x3a, 0x00, - 0x00, 0x20, 0x01, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x01, 0x0c, 0x03, - 0x0b, 0x20, 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, 0x01, - 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, - 0x0b, 0x0b, 0x41, 0x00, 0x21, 0x01, 0x0b, 0x20, 0x04, 0x41, 0x00, 0x20, - 0x01, 0x10, 0x0d, 0x1a, 0x20, 0x00, 0x0b, 0x17, 0x00, 0x20, 0x00, 0x41, - 0x30, 0x6b, 0x41, 0x0a, 0x49, 0x20, 0x00, 0x41, 0x20, 0x72, 0x41, 0xe1, - 0x00, 0x6b, 0x41, 0x06, 0x49, 0x72, 0x0b, 0x67, 0x01, 0x02, 0x7f, 0x20, - 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x7f, 0x20, 0x00, - 0x04, 0x40, 0x41, 0x8c, 0xc2, 0x04, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, - 0x41, 0x04, 0x6a, 0x22, 0x01, 0x28, 0x02, 0x00, 0x22, 0x02, 0x41, 0x00, - 0x20, 0x00, 0x20, 0x02, 0x47, 0x1b, 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, - 0x00, 0x20, 0x02, 0x1b, 0x0c, 0x01, 0x0b, 0x41, 0x00, 0x21, 0x00, 0x03, - 0x40, 0x20, 0x00, 0x41, 0x90, 0xc2, 0x04, 0x6a, 0x20, 0x00, 0x41, 0x04, - 0x6a, 0x21, 0x00, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x00, 0x41, - 0x04, 0x6b, 0x41, 0x7c, 0x71, 0x41, 0x90, 0xc2, 0x04, 0x6a, 0x0b, 0x41, - 0x00, 0x47, 0x0b, 0x1d, 0x01, 0x01, 0x7f, 0x41, 0x01, 0x21, 0x01, 0x20, - 0x00, 0x41, 0x30, 0x6b, 0x41, 0x0a, 0x4f, 0x04, 0x7f, 0x20, 0x00, 0x10, - 0x0f, 0x41, 0x00, 0x47, 0x05, 0x20, 0x01, 0x0b, 0x0b, 0x0b, 0xf1, 0x42, - 0x01, 0x00, 0x41, 0x80, 0x80, 0x04, 0x0b, 0xe8, 0x42, 0x12, 0x11, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x11, 0x22, 0x23, 0x24, 0x11, 0x25, 0x26, 0x27, 0x28, 0x29, - 0x2a, 0x2b, 0x2c, 0x11, 0x2d, 0x2e, 0x2f, 0x10, 0x10, 0x30, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x31, 0x32, 0x33, 0x10, 0x34, 0x35, 0x10, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x03, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, + 0x20, 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b, 0x20, + 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, + 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, + 0x41, 0x00, 0x21, 0x05, 0x0b, 0x02, 0x40, 0x20, 0x05, 0x45, 0x0d, 0x00, + 0x20, 0x03, 0x41, 0x00, 0x20, 0x05, 0xfc, 0x0b, 0x00, 0x0b, 0x20, 0x03, + 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0xa6, 0x80, + 0x80, 0x80, 0x00, 0x1a, 0x20, 0x00, 0x0b, 0x17, 0x00, 0x20, 0x00, 0x41, + 0x50, 0x6a, 0x41, 0x0a, 0x49, 0x20, 0x00, 0x41, 0x20, 0x72, 0x41, 0x9f, + 0x7f, 0x6a, 0x41, 0x06, 0x49, 0x72, 0x0b, 0x2a, 0x01, 0x03, 0x7f, 0x41, + 0x00, 0x21, 0x01, 0x03, 0x40, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x21, 0x02, + 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x03, 0x21, 0x01, 0x20, 0x02, 0x28, + 0x02, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x41, 0x02, + 0x75, 0x0b, 0x45, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20, 0x01, 0x45, 0x0d, + 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x00, 0x02, 0x40, 0x03, 0x40, + 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x00, 0x28, 0x02, 0x00, 0x22, 0x02, + 0x45, 0x0d, 0x01, 0x20, 0x02, 0x20, 0x01, 0x47, 0x0d, 0x00, 0x0b, 0x0b, + 0x20, 0x00, 0x41, 0x00, 0x20, 0x02, 0x1b, 0x0f, 0x0b, 0x20, 0x00, 0x20, + 0x00, 0x10, 0xa9, 0x80, 0x80, 0x80, 0x00, 0x41, 0x02, 0x74, 0x6a, 0x0b, + 0x1d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x0f, 0x0b, + 0x41, 0x90, 0xc2, 0x84, 0x80, 0x00, 0x20, 0x00, 0x10, 0xaa, 0x80, 0x80, + 0x80, 0x00, 0x41, 0x00, 0x47, 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0x01, + 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, 0x0a, 0x49, + 0x0d, 0x00, 0x20, 0x00, 0x10, 0x95, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, + 0x47, 0x21, 0x01, 0x0b, 0x20, 0x01, 0x0b, 0x0b, 0xfc, 0x42, 0x02, 0x00, + 0x41, 0x80, 0x80, 0x04, 0x0b, 0xe8, 0x42, 0x12, 0x11, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x11, 0x22, 0x23, 0x24, 0x11, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x11, 0x2d, 0x2e, 0x2f, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x31, 0x32, 0x33, 0x10, 0x34, 0x35, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x37, 0x11, 0x11, 0x11, 0x11, 0x38, 0x11, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x37, 0x11, + 0x11, 0x11, 0x11, 0x38, 0x11, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, 0x10, 0x10, 0x10, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x40, 0x41, 0x11, 0x42, 0x43, - 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x11, 0x4b, 0x4c, 0x4d, 0x4e, - 0x4f, 0x50, 0x51, 0x10, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x5b, 0x5c, 0x5d, 0x10, 0x5e, 0x5f, 0x60, 0x10, 0x11, 0x11, 0x11, - 0x61, 0x62, 0x63, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x11, 0x11, 0x11, 0x11, 0x64, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x65, + 0x10, 0x10, 0x10, 0x10, 0x11, 0x40, 0x41, 0x11, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x11, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x10, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x10, 0x5e, 0x5f, 0x60, 0x10, 0x11, 0x11, 0x11, 0x61, 0x62, + 0x63, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x64, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x65, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x66, - 0x67, 0x10, 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x66, 0x67, 0x10, + 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x6a, 0x11, 0x11, 0x6b, 0x10, 0x10, 0x10, 0x10, + 0x11, 0x11, 0x6a, 0x11, 0x11, 0x6b, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x6c, 0x6d, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6e, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x6c, 0x6d, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6f, 0x70, 0x71, - 0x72, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x73, 0x74, 0x75, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x76, 0x77, 0x10, 0x10, 0x10, 0x10, 0x78, - 0x10, 0x10, 0x79, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6f, 0x70, 0x71, 0x72, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x73, 0x74, 0x75, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x76, 0x77, 0x10, 0x10, 0x10, 0x10, 0x78, 0x10, 0x10, + 0x79, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xff, 0xff, 0x7f, - 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0x03, 0x00, 0x1f, 0x50, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xdf, 0xbc, 0x40, 0xd7, 0xff, 0xff, 0xfb, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xff, 0xff, 0x7f, 0xff, 0xff, + 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, - 0xff, 0xff, 0xff, 0x7f, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xbf, 0xb6, 0x00, 0xff, 0xff, 0xff, 0x87, 0x07, - 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xef, 0x1f, 0xfe, 0xe1, 0xff, 0x9f, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x07, 0x30, 0x04, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x1f, 0x00, - 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xdf, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xf8, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xdf, 0xe1, - 0xff, 0xcf, 0xff, 0xfe, 0xff, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xc5, - 0xe3, 0x9f, 0x59, 0x80, 0xb0, 0xcf, 0xff, 0x03, 0x10, 0xee, 0x87, 0xf9, - 0xff, 0xff, 0xfd, 0x6d, 0xc3, 0x87, 0x19, 0x02, 0x5e, 0xc0, 0xff, 0x3f, - 0x00, 0xee, 0xbf, 0xfb, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0xbf, 0x1b, 0x01, - 0x00, 0xcf, 0xff, 0x00, 0x1e, 0xee, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, - 0xe3, 0x9f, 0x19, 0xc0, 0xb0, 0xcf, 0xff, 0x02, 0x00, 0xec, 0xc7, 0x3d, - 0xd6, 0x18, 0xc7, 0xff, 0xc3, 0xc7, 0x1d, 0x81, 0x00, 0xc0, 0xff, 0x00, - 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xe3, 0xdf, 0x1d, 0x60, - 0x07, 0xcf, 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xef, - 0xe3, 0xdf, 0x1d, 0x60, 0x40, 0xcf, 0xff, 0x06, 0x00, 0xef, 0xdf, 0xfd, - 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdf, 0x5d, 0xf0, 0x80, 0xcf, 0xff, 0x00, - 0xfc, 0xec, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xfb, 0x2f, 0x7f, 0x80, 0x5f, - 0xff, 0xc0, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, - 0x07, 0x3f, 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf7, 0xff, - 0xff, 0xaf, 0xff, 0xff, 0x3b, 0x5f, 0x20, 0xff, 0xf3, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0xfe, 0xff, - 0xff, 0xff, 0x1f, 0xfe, 0xff, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7f, 0xf9, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, - 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc3, 0xff, 0x03, 0x00, 0x1f, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdf, 0xbc, 0x40, 0xd7, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, + 0xff, 0x7f, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xbf, 0xb6, 0x00, 0xff, 0xff, 0xff, 0x87, 0x07, 0x00, 0x00, + 0x00, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, + 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xef, 0x1f, 0xfe, 0xe1, 0xff, 0x9f, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x30, 0x04, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x1f, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x01, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xdf, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xdf, 0xe1, 0xff, 0xcf, + 0xff, 0xfe, 0xff, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xc5, 0xe3, 0x9f, + 0x59, 0x80, 0xb0, 0xcf, 0xff, 0x03, 0x10, 0xee, 0x87, 0xf9, 0xff, 0xff, + 0xfd, 0x6d, 0xc3, 0x87, 0x19, 0x02, 0x5e, 0xc0, 0xff, 0x3f, 0x00, 0xee, + 0xbf, 0xfb, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0xbf, 0x1b, 0x01, 0x00, 0xcf, + 0xff, 0x00, 0x1e, 0xee, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, + 0x19, 0xc0, 0xb0, 0xcf, 0xff, 0x02, 0x00, 0xec, 0xc7, 0x3d, 0xd6, 0x18, + 0xc7, 0xff, 0xc3, 0xc7, 0x1d, 0x81, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xef, + 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xe3, 0xdf, 0x1d, 0x60, 0x07, 0xcf, + 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xef, 0xe3, 0xdf, + 0x1d, 0x60, 0x40, 0xcf, 0xff, 0x06, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, + 0xff, 0xff, 0xe7, 0xdf, 0x5d, 0xf0, 0x80, 0xcf, 0xff, 0x00, 0xfc, 0xec, + 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xfb, 0x2f, 0x7f, 0x80, 0x5f, 0xff, 0xc0, + 0xff, 0x0c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x07, 0x3f, + 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf7, 0xff, 0xff, 0xaf, + 0xff, 0xff, 0x3b, 0x5f, 0x20, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xff, + 0x1f, 0xfe, 0xff, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0xf9, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x3d, 0x7f, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, + 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0xff, 0xff, - 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, - 0x01, 0xff, 0xdf, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, - 0x00, 0xff, 0xdf, 0x0d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, - 0xff, 0xff, 0x01, 0x80, 0x10, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, - 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f, 0xff, - 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xfe, 0xff, 0x1f, 0x00, 0xff, 0x03, 0xff, 0x03, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, 0x0f, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xbf, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x00, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x6f, - 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x3f, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xaa, 0xff, 0xff, 0xff, - 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x5f, 0xdc, 0x1f, 0xcf, - 0x0f, 0xff, 0x1f, 0xdc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xff, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x84, 0xfc, 0x2f, 0x3e, 0x50, 0xbd, 0xff, 0xf3, 0xe0, 0x43, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x78, 0x0c, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x3e, - 0x1f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x07, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x01, 0xff, + 0xdf, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, + 0xdf, 0x0d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, + 0x01, 0x80, 0x10, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f, 0xff, 0x01, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, + 0xff, 0x1f, 0x00, 0xff, 0x03, 0xff, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xef, 0xff, 0xef, 0x0f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, + 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x6f, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x1f, 0xff, - 0xff, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, - 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xfc, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x2f, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xe8, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, - 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x80, 0xff, - 0x03, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x00, 0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x38, 0xff, 0xff, 0x3c, - 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xf7, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x7f, 0xf8, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0x00, 0xf8, 0xe0, 0xff, 0xfd, 0x7f, 0x5f, 0xdb, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, - 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x1f, 0x00, 0x00, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, - 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xfc, 0xfc, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0xff, - 0xff, 0x7f, 0xff, 0xff, 0xb7, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x3f, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xaa, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x5f, 0xdc, 0x1f, 0xcf, 0x0f, 0xff, + 0x1f, 0xdc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xff, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, + 0xfc, 0x2f, 0x3e, 0x50, 0xbd, 0xff, 0xf3, 0xe0, 0x43, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x3e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x3f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xbf, - 0x91, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, - 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xf0, 0xef, - 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0x1f, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, - 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, - 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x00, 0xff, - 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, - 0x00, 0xc0, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc7, 0xff, 0x70, 0x00, 0xff, 0xff, 0xff, 0xff, 0x47, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0xff, - 0x17, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x9f, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbd, 0xff, - 0xbf, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, - 0x03, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19, 0x81, - 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, 0x07, 0xff, 0x83, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0x00, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0x7f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x11, 0x00, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, - 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xe7, 0xff, 0x07, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x78, 0x0c, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xe7, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x7f, - 0x7f, 0x01, 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, - 0xff, 0xff, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x7f, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xb4, 0xcb, 0x00, 0xff, - 0x03, 0xbf, 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x3e, 0x1f, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x1f, 0xff, 0xff, 0xff, + 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, 0x8f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xbf, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, + 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x80, 0xff, 0x03, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, + 0x3f, 0xff, 0x03, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x38, 0xff, 0xff, 0x3c, 0x00, 0x7e, + 0x7e, 0x7e, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x0f, 0x00, 0xff, 0x03, 0xf8, 0xff, 0xff, 0xe0, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf0, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x07, 0xff, 0x1f, 0xff, 0x01, 0xff, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xdf, 0x64, 0xde, 0xff, 0xeb, 0xef, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xe7, 0xdf, 0xdf, 0xff, 0xff, 0xff, - 0x7b, 0x5f, 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, - 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xdf, - 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, - 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xcf, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x3f, 0xff, 0x43, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x7f, 0xf8, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x7f, + 0x00, 0xf8, 0xe0, 0xff, 0xfd, 0x7f, 0x5f, 0xdb, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, + 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, + 0xfc, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xb7, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x08, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, - 0xff, 0x96, 0xfe, 0xf7, 0x0a, 0x84, 0xea, 0x96, 0xaa, 0x96, 0xf7, 0xf7, - 0x5e, 0xff, 0xfb, 0xff, 0x0f, 0xee, 0xfb, 0xff, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, + 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x3e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x91, 0xff, + 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0x00, 0xff, + 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xf0, 0xef, 0xfe, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0x1f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, + 0xff, 0x3f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0xbf, 0x1d, 0x00, 0x00, 0xe7, 0x02, - 0x00, 0x00, 0x79, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, - 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x39, 0xff, 0xff, 0x00, 0x18, 0xff, - 0xff, 0x01, 0x87, 0xff, 0xff, 0x00, 0xd4, 0xfe, 0xff, 0x00, 0xc3, 0x00, - 0x00, 0x01, 0xd2, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xcd, 0x00, - 0x00, 0x01, 0x4f, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcb, 0x00, - 0x00, 0x01, 0xcf, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x01, 0xd3, 0x00, - 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x01, 0xd5, 0x00, - 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, 0xd6, 0x00, 0x00, 0x01, 0xda, 0x00, - 0x00, 0x01, 0xd9, 0x00, 0x00, 0x01, 0xdb, 0x00, 0x00, 0x00, 0x38, 0x00, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xff, 0xff, 0x01, 0x9f, 0xff, - 0xff, 0x01, 0xc8, 0xff, 0xff, 0x02, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x33, 0xff, - 0xff, 0x00, 0x26, 0xff, 0xff, 0x01, 0x7e, 0xff, 0xff, 0x01, 0x2b, 0x2a, - 0x00, 0x01, 0x5d, 0xff, 0xff, 0x01, 0x28, 0x2a, 0x00, 0x00, 0x3f, 0x2a, - 0x00, 0x01, 0x3d, 0xff, 0xff, 0x01, 0x45, 0x00, 0x00, 0x01, 0x47, 0x00, - 0x00, 0x00, 0x1f, 0x2a, 0x00, 0x00, 0x1c, 0x2a, 0x00, 0x00, 0x1e, 0x2a, - 0x00, 0x00, 0x2e, 0xff, 0xff, 0x00, 0x32, 0xff, 0xff, 0x00, 0x36, 0xff, - 0xff, 0x00, 0x35, 0xff, 0xff, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x4b, 0xa5, - 0x00, 0x00, 0x31, 0xff, 0xff, 0x00, 0x28, 0xa5, 0x00, 0x00, 0x44, 0xa5, - 0x00, 0x00, 0x2f, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xff, 0x00, 0xf7, 0x29, - 0x00, 0x00, 0x41, 0xa5, 0x00, 0x00, 0xfd, 0x29, 0x00, 0x00, 0x2b, 0xff, - 0xff, 0x00, 0x2a, 0xff, 0xff, 0x00, 0xe7, 0x29, 0x00, 0x00, 0x43, 0xa5, - 0x00, 0x00, 0x2a, 0xa5, 0x00, 0x00, 0xbb, 0xff, 0xff, 0x00, 0x27, 0xff, - 0xff, 0x00, 0xb9, 0xff, 0xff, 0x00, 0x25, 0xff, 0xff, 0x00, 0x15, 0xa5, - 0x00, 0x00, 0x12, 0xa5, 0x00, 0x02, 0x24, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x01, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x54, 0x00, 0x00, 0x01, 0x74, 0x00, - 0x00, 0x01, 0x26, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x40, 0x00, - 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, 0xda, 0xff, 0xff, 0x00, 0xdb, 0xff, - 0xff, 0x00, 0xe1, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc1, 0xff, - 0xff, 0x01, 0x08, 0x00, 0x00, 0x00, 0xc2, 0xff, 0xff, 0x00, 0xc7, 0xff, - 0xff, 0x00, 0xd1, 0xff, 0xff, 0x00, 0xca, 0xff, 0xff, 0x00, 0xf8, 0xff, - 0xff, 0x00, 0xaa, 0xff, 0xff, 0x00, 0xb0, 0xff, 0xff, 0x00, 0x07, 0x00, - 0x00, 0x00, 0x8c, 0xff, 0xff, 0x01, 0xc4, 0xff, 0xff, 0x00, 0xa0, 0xff, - 0xff, 0x01, 0xf9, 0xff, 0xff, 0x02, 0x1a, 0x70, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, - 0xff, 0x01, 0x50, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, - 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x01, 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xd0, 0x97, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xff, - 0xff, 0x02, 0x05, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xf4, - 0xff, 0x00, 0x9e, 0xe7, 0xff, 0x00, 0xc2, 0x89, 0x00, 0x00, 0xdb, 0xe7, - 0xff, 0x00, 0x92, 0xe7, 0xff, 0x00, 0x93, 0xe7, 0xff, 0x00, 0x9c, 0xe7, - 0xff, 0x00, 0x9d, 0xe7, 0xff, 0x00, 0xa4, 0xe7, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x38, 0x8a, 0x00, 0x00, 0x04, 0x8a, 0x00, 0x00, 0xe6, 0x0e, - 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xc5, 0xff, 0xff, 0x01, 0x41, 0xe2, 0xff, 0x02, 0x1d, 0x8f, - 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x56, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x4a, 0x00, - 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, - 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0xb6, 0xff, - 0xff, 0x01, 0xf7, 0xff, 0xff, 0x00, 0xdb, 0xe3, 0xff, 0x01, 0x9c, 0xff, - 0xff, 0x01, 0x90, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x82, 0xff, - 0xff, 0x02, 0x05, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, - 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, 0x1c, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x01, 0xa3, 0xe2, 0xff, 0x01, 0x41, 0xdf, 0xff, 0x01, 0xba, 0xdf, - 0xff, 0x00, 0xe4, 0xff, 0xff, 0x02, 0x0b, 0xb1, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0xd6, 0xff, 0x01, 0x1a, 0xf1, - 0xff, 0x01, 0x19, 0xd6, 0xff, 0x00, 0xd5, 0xd5, 0xff, 0x00, 0xd8, 0xd5, - 0xff, 0x01, 0xe4, 0xd5, 0xff, 0x01, 0x03, 0xd6, 0xff, 0x01, 0xe1, 0xd5, - 0xff, 0x01, 0xe2, 0xd5, 0xff, 0x01, 0xc1, 0xd5, 0xff, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xa0, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, 0x0c, 0xbc, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xbc, 0x5a, - 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, 0xfc, 0x75, 0xff, 0x01, 0xd8, 0x5a, - 0xff, 0x00, 0x30, 0x00, 0x00, 0x01, 0xb1, 0x5a, 0xff, 0x01, 0xb5, 0x5a, - 0xff, 0x01, 0xbf, 0x5a, 0xff, 0x01, 0xee, 0x5a, 0xff, 0x01, 0xd6, 0x5a, - 0xff, 0x01, 0xeb, 0x5a, 0xff, 0x01, 0xd0, 0xff, 0xff, 0x01, 0xbd, 0x5a, - 0xff, 0x01, 0xc8, 0x75, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x68, - 0xff, 0x00, 0x60, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28, 0x00, - 0x00, 0x00, 0xd8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, - 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, - 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, - 0x00, 0x00, 0xde, 0xff, 0xff, 0x30, 0x0c, 0x31, 0x0d, 0x78, 0x0e, 0x7f, - 0x0f, 0x80, 0x10, 0x81, 0x11, 0x86, 0x12, 0x89, 0x13, 0x8a, 0x13, 0x8e, - 0x14, 0x8f, 0x15, 0x90, 0x16, 0x93, 0x13, 0x94, 0x17, 0x95, 0x18, 0x96, - 0x19, 0x97, 0x1a, 0x9a, 0x1b, 0x9c, 0x19, 0x9d, 0x1c, 0x9e, 0x1d, 0x9f, - 0x1e, 0xa6, 0x1f, 0xa9, 0x1f, 0xae, 0x1f, 0xb1, 0x20, 0xb2, 0x20, 0xb7, - 0x21, 0xbf, 0x22, 0xc5, 0x23, 0xc8, 0x23, 0xcb, 0x23, 0xdd, 0x24, 0xf2, - 0x23, 0xf6, 0x25, 0xf7, 0x26, 0x20, 0x2d, 0x3a, 0x2e, 0x3d, 0x2f, 0x3e, - 0x30, 0x3f, 0x31, 0x40, 0x31, 0x43, 0x32, 0x44, 0x33, 0x45, 0x34, 0x50, - 0x35, 0x51, 0x36, 0x52, 0x37, 0x53, 0x38, 0x54, 0x39, 0x59, 0x3a, 0x5b, - 0x3b, 0x5c, 0x3c, 0x61, 0x3d, 0x63, 0x3e, 0x65, 0x3f, 0x66, 0x40, 0x68, - 0x41, 0x69, 0x42, 0x6a, 0x40, 0x6b, 0x43, 0x6c, 0x44, 0x6f, 0x42, 0x71, - 0x45, 0x72, 0x46, 0x75, 0x47, 0x7d, 0x48, 0x82, 0x49, 0x87, 0x4a, 0x89, - 0x4b, 0x8a, 0x4c, 0x8b, 0x4c, 0x8c, 0x4d, 0x92, 0x4e, 0x9d, 0x4f, 0x9e, - 0x50, 0x45, 0x57, 0x7b, 0x1d, 0x7c, 0x1d, 0x7d, 0x1d, 0x7f, 0x58, 0x86, - 0x59, 0x88, 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x8c, 0x5b, 0x8e, 0x5c, 0x8f, - 0x5c, 0xac, 0x5d, 0xad, 0x5e, 0xae, 0x5e, 0xaf, 0x5e, 0xc2, 0x5f, 0xcc, - 0x60, 0xcd, 0x61, 0xce, 0x61, 0xcf, 0x62, 0xd0, 0x63, 0xd1, 0x64, 0xd5, - 0x65, 0xd6, 0x66, 0xd7, 0x67, 0xf0, 0x68, 0xf1, 0x69, 0xf2, 0x6a, 0xf3, - 0x6b, 0xf4, 0x6c, 0xf5, 0x6d, 0xf9, 0x6e, 0xfd, 0x2d, 0xfe, 0x2d, 0xff, - 0x2d, 0x50, 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54, 0x69, 0x55, - 0x69, 0x56, 0x69, 0x57, 0x69, 0x58, 0x69, 0x59, 0x69, 0x5a, 0x69, 0x5b, - 0x69, 0x5c, 0x69, 0x5d, 0x69, 0x5e, 0x69, 0x5f, 0x69, 0x82, 0x00, 0x83, - 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, - 0x00, 0xc0, 0x75, 0xcf, 0x76, 0x80, 0x89, 0x81, 0x8a, 0x82, 0x8b, 0x85, - 0x8c, 0x86, 0x8d, 0x70, 0x9d, 0x71, 0x9d, 0x76, 0x9e, 0x77, 0x9e, 0x78, - 0x9f, 0x79, 0x9f, 0x7a, 0xa0, 0x7b, 0xa0, 0x7c, 0xa1, 0x7d, 0xa1, 0xb3, - 0xa2, 0xba, 0xa3, 0xbb, 0xa3, 0xbc, 0xa4, 0xbe, 0xa5, 0xc3, 0xa2, 0xcc, - 0xa4, 0xda, 0xa6, 0xdb, 0xa6, 0xe5, 0x6a, 0xea, 0xa7, 0xeb, 0xa7, 0xec, - 0x6e, 0xf3, 0xa2, 0xf8, 0xa8, 0xf9, 0xa8, 0xfa, 0xa9, 0xfb, 0xa9, 0xfc, - 0xa4, 0x26, 0xb0, 0x2a, 0xb1, 0x2b, 0xb2, 0x4e, 0xb3, 0x84, 0x08, 0x62, - 0xba, 0x63, 0xbb, 0x64, 0xbc, 0x65, 0xbd, 0x66, 0xbe, 0x6d, 0xbf, 0x6e, - 0xc0, 0x6f, 0xc1, 0x70, 0xc2, 0x7e, 0xc3, 0x7f, 0xc3, 0x7d, 0xcf, 0x8d, - 0xd0, 0x94, 0xd1, 0xab, 0xd2, 0xac, 0xd3, 0xad, 0xd4, 0xb0, 0xd5, 0xb1, - 0xd6, 0xb2, 0xd7, 0xc4, 0xd8, 0xc5, 0xd9, 0xc6, 0xda, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x0d, 0x06, 0x06, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x0f, 0x10, 0x11, 0x12, 0x06, 0x13, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x14, 0x15, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x00, 0xff, 0xff, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0, + 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xc7, 0xff, 0x70, 0x00, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0xff, 0x17, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x9f, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbd, 0xff, 0xbf, 0xff, + 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xef, + 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19, 0x81, 0xe0, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbb, 0x07, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0x00, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x7f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x11, 0x00, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x01, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0xff, + 0x07, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xfc, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xe7, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x01, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x01, + 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, + 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xb4, 0xcb, 0x00, 0xff, 0x03, 0xbf, + 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, + 0x00, 0xff, 0x03, 0xf8, 0xff, 0xff, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf0, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0xff, 0x1f, 0xff, 0x01, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xdf, 0x64, 0xde, 0xff, 0xeb, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbf, 0xe7, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0x7b, 0x5f, + 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xfd, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xdf, 0xff, 0xff, + 0xff, 0xdf, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, + 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xcf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x3f, 0xff, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x08, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xff, 0x96, + 0xfe, 0xf7, 0x0a, 0x84, 0xea, 0x96, 0xaa, 0x96, 0xf7, 0xf7, 0x5e, 0xff, + 0xfb, 0xff, 0x0f, 0xee, 0xfb, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0x00, 0xbf, 0x1d, 0x00, 0x00, 0xe7, 0x02, 0x00, 0x00, + 0x79, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, + 0xfe, 0xff, 0xff, 0x01, 0x39, 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, 0x01, + 0x87, 0xff, 0xff, 0x00, 0xd4, 0xfe, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x01, + 0xd2, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x01, + 0x4f, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcb, 0x00, 0x00, 0x01, + 0xcf, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x01, + 0xd1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x01, 0xd5, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x01, 0xd6, 0x00, 0x00, 0x01, 0xda, 0x00, 0x00, 0x01, + 0xd9, 0x00, 0x00, 0x01, 0xdb, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0xb1, 0xff, 0xff, 0x01, 0x9f, 0xff, 0xff, 0x01, + 0xc8, 0xff, 0xff, 0x02, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x33, 0xff, 0xff, 0x00, + 0x26, 0xff, 0xff, 0x01, 0x7e, 0xff, 0xff, 0x01, 0x2b, 0x2a, 0x00, 0x01, + 0x5d, 0xff, 0xff, 0x01, 0x28, 0x2a, 0x00, 0x00, 0x3f, 0x2a, 0x00, 0x01, + 0x3d, 0xff, 0xff, 0x01, 0x45, 0x00, 0x00, 0x01, 0x47, 0x00, 0x00, 0x00, + 0x1f, 0x2a, 0x00, 0x00, 0x1c, 0x2a, 0x00, 0x00, 0x1e, 0x2a, 0x00, 0x00, + 0x2e, 0xff, 0xff, 0x00, 0x32, 0xff, 0xff, 0x00, 0x36, 0xff, 0xff, 0x00, + 0x35, 0xff, 0xff, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x4b, 0xa5, 0x00, 0x00, + 0x31, 0xff, 0xff, 0x00, 0x28, 0xa5, 0x00, 0x00, 0x44, 0xa5, 0x00, 0x00, + 0x2f, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xff, 0x00, 0xf7, 0x29, 0x00, 0x00, + 0x41, 0xa5, 0x00, 0x00, 0xfd, 0x29, 0x00, 0x00, 0x2b, 0xff, 0xff, 0x00, + 0x2a, 0xff, 0xff, 0x00, 0xe7, 0x29, 0x00, 0x00, 0x43, 0xa5, 0x00, 0x00, + 0x2a, 0xa5, 0x00, 0x00, 0xbb, 0xff, 0xff, 0x00, 0x27, 0xff, 0xff, 0x00, + 0xb9, 0xff, 0xff, 0x00, 0x25, 0xff, 0xff, 0x00, 0x15, 0xa5, 0x00, 0x00, + 0x12, 0xa5, 0x00, 0x02, 0x24, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x54, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, + 0x26, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, + 0x3f, 0x00, 0x00, 0x00, 0xda, 0xff, 0xff, 0x00, 0xdb, 0xff, 0xff, 0x00, + 0xe1, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc1, 0xff, 0xff, 0x01, + 0x08, 0x00, 0x00, 0x00, 0xc2, 0xff, 0xff, 0x00, 0xc7, 0xff, 0xff, 0x00, + 0xd1, 0xff, 0xff, 0x00, 0xca, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0x00, + 0xaa, 0xff, 0xff, 0x00, 0xb0, 0xff, 0xff, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x8c, 0xff, 0xff, 0x01, 0xc4, 0xff, 0xff, 0x00, 0xa0, 0xff, 0xff, 0x01, + 0xf9, 0xff, 0xff, 0x02, 0x1a, 0x70, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, + 0x50, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x01, + 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x0b, 0x00, 0x01, 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0xd0, 0x97, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x02, + 0x05, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xf4, 0xff, 0x00, + 0x9e, 0xe7, 0xff, 0x00, 0xc2, 0x89, 0x00, 0x00, 0xdb, 0xe7, 0xff, 0x00, + 0x92, 0xe7, 0xff, 0x00, 0x93, 0xe7, 0xff, 0x00, 0x9c, 0xe7, 0xff, 0x00, + 0x9d, 0xe7, 0xff, 0x00, 0xa4, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x8a, 0x00, 0x00, 0x04, 0x8a, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc5, 0xff, 0xff, 0x01, 0x41, 0xe2, 0xff, 0x02, 0x1d, 0x8f, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x01, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x4a, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x7e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0xb6, 0xff, 0xff, 0x01, + 0xf7, 0xff, 0xff, 0x00, 0xdb, 0xe3, 0xff, 0x01, 0x9c, 0xff, 0xff, 0x01, + 0x90, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x82, 0xff, 0xff, 0x02, + 0x05, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0x01, 0x1c, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, + 0xa3, 0xe2, 0xff, 0x01, 0x41, 0xdf, 0xff, 0x01, 0xba, 0xdf, 0xff, 0x00, + 0xe4, 0xff, 0xff, 0x02, 0x0b, 0xb1, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x09, 0xd6, 0xff, 0x01, 0x1a, 0xf1, 0xff, 0x01, + 0x19, 0xd6, 0xff, 0x00, 0xd5, 0xd5, 0xff, 0x00, 0xd8, 0xd5, 0xff, 0x01, + 0xe4, 0xd5, 0xff, 0x01, 0x03, 0xd6, 0xff, 0x01, 0xe1, 0xd5, 0xff, 0x01, + 0xe2, 0xd5, 0xff, 0x01, 0xc1, 0xd5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x02, 0x0c, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xbc, 0x5a, 0xff, 0x01, + 0xa0, 0x03, 0x00, 0x01, 0xfc, 0x75, 0xff, 0x01, 0xd8, 0x5a, 0xff, 0x00, + 0x30, 0x00, 0x00, 0x01, 0xb1, 0x5a, 0xff, 0x01, 0xb5, 0x5a, 0xff, 0x01, + 0xbf, 0x5a, 0xff, 0x01, 0xee, 0x5a, 0xff, 0x01, 0xd6, 0x5a, 0xff, 0x01, + 0xeb, 0x5a, 0xff, 0x01, 0xd0, 0xff, 0xff, 0x01, 0xbd, 0x5a, 0xff, 0x01, + 0xc8, 0x75, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x68, 0xff, 0x00, + 0x60, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28, 0x00, 0x00, 0x00, + 0xd8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, + 0xde, 0xff, 0xff, 0x30, 0x0c, 0x31, 0x0d, 0x78, 0x0e, 0x7f, 0x0f, 0x80, + 0x10, 0x81, 0x11, 0x86, 0x12, 0x89, 0x13, 0x8a, 0x13, 0x8e, 0x14, 0x8f, + 0x15, 0x90, 0x16, 0x93, 0x13, 0x94, 0x17, 0x95, 0x18, 0x96, 0x19, 0x97, + 0x1a, 0x9a, 0x1b, 0x9c, 0x19, 0x9d, 0x1c, 0x9e, 0x1d, 0x9f, 0x1e, 0xa6, + 0x1f, 0xa9, 0x1f, 0xae, 0x1f, 0xb1, 0x20, 0xb2, 0x20, 0xb7, 0x21, 0xbf, + 0x22, 0xc5, 0x23, 0xc8, 0x23, 0xcb, 0x23, 0xdd, 0x24, 0xf2, 0x23, 0xf6, + 0x25, 0xf7, 0x26, 0x20, 0x2d, 0x3a, 0x2e, 0x3d, 0x2f, 0x3e, 0x30, 0x3f, + 0x31, 0x40, 0x31, 0x43, 0x32, 0x44, 0x33, 0x45, 0x34, 0x50, 0x35, 0x51, + 0x36, 0x52, 0x37, 0x53, 0x38, 0x54, 0x39, 0x59, 0x3a, 0x5b, 0x3b, 0x5c, + 0x3c, 0x61, 0x3d, 0x63, 0x3e, 0x65, 0x3f, 0x66, 0x40, 0x68, 0x41, 0x69, + 0x42, 0x6a, 0x40, 0x6b, 0x43, 0x6c, 0x44, 0x6f, 0x42, 0x71, 0x45, 0x72, + 0x46, 0x75, 0x47, 0x7d, 0x48, 0x82, 0x49, 0x87, 0x4a, 0x89, 0x4b, 0x8a, + 0x4c, 0x8b, 0x4c, 0x8c, 0x4d, 0x92, 0x4e, 0x9d, 0x4f, 0x9e, 0x50, 0x45, + 0x57, 0x7b, 0x1d, 0x7c, 0x1d, 0x7d, 0x1d, 0x7f, 0x58, 0x86, 0x59, 0x88, + 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x8c, 0x5b, 0x8e, 0x5c, 0x8f, 0x5c, 0xac, + 0x5d, 0xad, 0x5e, 0xae, 0x5e, 0xaf, 0x5e, 0xc2, 0x5f, 0xcc, 0x60, 0xcd, + 0x61, 0xce, 0x61, 0xcf, 0x62, 0xd0, 0x63, 0xd1, 0x64, 0xd5, 0x65, 0xd6, + 0x66, 0xd7, 0x67, 0xf0, 0x68, 0xf1, 0x69, 0xf2, 0x6a, 0xf3, 0x6b, 0xf4, + 0x6c, 0xf5, 0x6d, 0xf9, 0x6e, 0xfd, 0x2d, 0xfe, 0x2d, 0xff, 0x2d, 0x50, + 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54, 0x69, 0x55, 0x69, 0x56, + 0x69, 0x57, 0x69, 0x58, 0x69, 0x59, 0x69, 0x5a, 0x69, 0x5b, 0x69, 0x5c, + 0x69, 0x5d, 0x69, 0x5e, 0x69, 0x5f, 0x69, 0x82, 0x00, 0x83, 0x00, 0x84, + 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0xc0, + 0x75, 0xcf, 0x76, 0x80, 0x89, 0x81, 0x8a, 0x82, 0x8b, 0x85, 0x8c, 0x86, + 0x8d, 0x70, 0x9d, 0x71, 0x9d, 0x76, 0x9e, 0x77, 0x9e, 0x78, 0x9f, 0x79, + 0x9f, 0x7a, 0xa0, 0x7b, 0xa0, 0x7c, 0xa1, 0x7d, 0xa1, 0xb3, 0xa2, 0xba, + 0xa3, 0xbb, 0xa3, 0xbc, 0xa4, 0xbe, 0xa5, 0xc3, 0xa2, 0xcc, 0xa4, 0xda, + 0xa6, 0xdb, 0xa6, 0xe5, 0x6a, 0xea, 0xa7, 0xeb, 0xa7, 0xec, 0x6e, 0xf3, + 0xa2, 0xf8, 0xa8, 0xf9, 0xa8, 0xfa, 0xa9, 0xfb, 0xa9, 0xfc, 0xa4, 0x26, + 0xb0, 0x2a, 0xb1, 0x2b, 0xb2, 0x4e, 0xb3, 0x84, 0x08, 0x62, 0xba, 0x63, + 0xbb, 0x64, 0xbc, 0x65, 0xbd, 0x66, 0xbe, 0x6d, 0xbf, 0x6e, 0xc0, 0x6f, + 0xc1, 0x70, 0xc2, 0x7e, 0xc3, 0x7f, 0xc3, 0x7d, 0xcf, 0x8d, 0xd0, 0x94, + 0xd1, 0xab, 0xd2, 0xac, 0xd3, 0xad, 0xd4, 0xb0, 0xd5, 0xb1, 0xd6, 0xb2, + 0xd7, 0xc4, 0xd8, 0xc5, 0xd9, 0xc6, 0xda, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0d, + 0x06, 0x06, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0f, + 0x10, 0x11, 0x12, 0x06, 0x13, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x14, 0x15, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, @@ -924,24 +1017,24 @@ unsigned char STDLIB_WASM[] = { 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x16, 0x17, 0x06, 0x06, 0x06, - 0x18, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x16, 0x17, 0x06, 0x06, 0x06, 0x18, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x19, 0x06, 0x06, 0x06, 0x06, 0x1a, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x1b, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x19, 0x06, + 0x06, 0x06, 0x06, 0x1a, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1b, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, @@ -951,9 +1044,9 @@ unsigned char STDLIB_WASM[] = { 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -962,45 +1055,45 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x2b, 0x5b, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x4a, 0x56, 0x56, 0x05, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x24, 0x50, 0x79, 0x31, 0x50, 0x31, 0x50, 0x31, 0x38, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x4e, 0x31, 0x02, 0x4e, 0x0d, 0x0d, 0x4e, 0x03, 0x4e, + 0x00, 0x24, 0x6e, 0x00, 0x4e, 0x31, 0x26, 0x6e, 0x51, 0x4e, 0x24, 0x50, + 0x4e, 0x39, 0x14, 0x81, 0x1b, 0x1d, 0x1d, 0x53, 0x31, 0x50, 0x31, 0x50, + 0x0d, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x1b, 0x53, 0x24, 0x50, 0x31, + 0x02, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x14, + 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x49, 0x03, 0x48, 0x03, + 0x78, 0x5c, 0x7b, 0x14, 0x00, 0x96, 0x0a, 0x01, 0x2b, 0x28, 0x06, 0x06, + 0x00, 0x2a, 0x06, 0x2a, 0x2a, 0x2b, 0x07, 0xbb, 0xb5, 0x2b, 0x1e, 0x00, + 0x2b, 0x07, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0xcd, 0x46, 0xcd, 0x2b, 0x00, 0x25, 0x2b, 0x07, + 0x01, 0x06, 0x01, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x55, 0x56, 0x56, + 0x02, 0x24, 0x81, 0x81, 0x81, 0x81, 0x81, 0x15, 0x81, 0x81, 0x81, 0x00, + 0x00, 0x2b, 0x00, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0x00, + 0x00, 0xcd, 0xcc, 0x01, 0x00, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x83, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xac, 0xac, 0xac, + 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, + 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x87, 0xa6, 0x87, 0xa6, 0x87, + 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x2a, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, - 0x2b, 0x5b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x4a, 0x56, 0x56, - 0x05, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x24, 0x50, 0x79, 0x31, 0x50, 0x31, 0x50, - 0x31, 0x38, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x02, 0x4e, 0x0d, 0x0d, 0x4e, - 0x03, 0x4e, 0x00, 0x24, 0x6e, 0x00, 0x4e, 0x31, 0x26, 0x6e, 0x51, 0x4e, - 0x24, 0x50, 0x4e, 0x39, 0x14, 0x81, 0x1b, 0x1d, 0x1d, 0x53, 0x31, 0x50, - 0x31, 0x50, 0x0d, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x1b, 0x53, 0x24, - 0x50, 0x31, 0x02, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, - 0x7b, 0x14, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x49, 0x03, - 0x48, 0x03, 0x78, 0x5c, 0x7b, 0x14, 0x00, 0x96, 0x0a, 0x01, 0x2b, 0x28, - 0x06, 0x06, 0x00, 0x2a, 0x06, 0x2a, 0x2a, 0x2b, 0x07, 0xbb, 0xb5, 0x2b, - 0x1e, 0x00, 0x2b, 0x07, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0xcd, 0x46, 0xcd, 0x2b, 0x00, 0x25, - 0x2b, 0x07, 0x01, 0x06, 0x01, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x55, - 0x56, 0x56, 0x02, 0x24, 0x81, 0x81, 0x81, 0x81, 0x81, 0x15, 0x81, 0x81, - 0x81, 0x00, 0x00, 0x2b, 0x00, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, - 0xd1, 0x00, 0x00, 0xcd, 0xcc, 0x01, 0x00, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, - 0x83, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xac, - 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x1c, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, - 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x87, 0xa6, 0x87, - 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, - 0xa6, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1008,136 +1101,136 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x0c, 0x00, 0x0c, 0x2a, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2a, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x0c, 0x00, 0x0c, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x6c, - 0x81, 0x15, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x6c, 0x03, - 0x41, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x2c, 0x56, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x6c, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x56, 0x7a, 0x9e, - 0x26, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x01, 0x2b, 0x2b, 0x4f, - 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x39, 0x2b, 0x2b, 0x55, 0x56, - 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x81, - 0x37, 0x75, 0x5b, 0x7b, 0x5c, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x02, 0xac, - 0x04, 0x00, 0x00, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b, 0x4f, - 0x56, 0x56, 0x2c, 0x2b, 0x2b, 0x56, 0x56, 0x32, 0x13, 0x81, 0x57, 0x00, - 0x6f, 0x81, 0x7e, 0xc9, 0xd7, 0x7e, 0x2d, 0x81, 0x81, 0x0e, 0x7e, 0x39, - 0x7f, 0x6f, 0x57, 0x00, 0x81, 0x81, 0x7e, 0x15, 0x00, 0x7e, 0x03, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, - 0x2b, 0x24, 0x2b, 0x97, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x80, 0x81, 0x81, 0x81, 0x81, 0x39, 0xbb, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, - 0x81, 0x81, 0x81, 0x81, 0xc9, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, - 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd0, 0x0d, 0x00, 0x4e, - 0x31, 0x02, 0xb4, 0xc1, 0xc1, 0xd7, 0xd7, 0x24, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0xd7, 0xd7, 0x53, 0xc1, 0x47, 0xd4, 0xd7, - 0xd7, 0xd7, 0x05, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, - 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, - 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x2b, 0x79, - 0x14, 0x5c, 0x7b, 0x5c, 0x2d, 0x79, 0x2a, 0x5c, 0x27, 0x5c, 0x7b, 0x5c, - 0x7b, 0x5c, 0x7b, 0xa4, 0x00, 0x0a, 0xb4, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, - 0x03, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x48, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, - 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x07, 0x00, 0x00, 0x00, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x6c, 0x81, 0x15, + 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x6c, 0x03, 0x41, 0x2b, + 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x2c, 0x56, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x56, 0x7a, 0x9e, 0x26, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x01, 0x2b, 0x2b, 0x4f, 0x56, 0x56, + 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, + 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x81, 0x37, 0x75, + 0x5b, 0x7b, 0x5c, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x02, 0xac, 0x04, 0x00, + 0x00, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, + 0x2c, 0x2b, 0x2b, 0x56, 0x56, 0x32, 0x13, 0x81, 0x57, 0x00, 0x6f, 0x81, + 0x7e, 0xc9, 0xd7, 0x7e, 0x2d, 0x81, 0x81, 0x0e, 0x7e, 0x39, 0x7f, 0x6f, + 0x57, 0x00, 0x81, 0x81, 0x7e, 0x15, 0x00, 0x7e, 0x03, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x24, + 0x2b, 0x97, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x39, 0xbb, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0xc9, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, + 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd0, 0x0d, 0x00, 0x4e, 0x31, 0x02, + 0xb4, 0xc1, 0xc1, 0xd7, 0xd7, 0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0xd7, 0xd7, 0x53, 0xc1, 0x47, 0xd4, 0xd7, 0xd7, 0xd7, + 0x05, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x7b, 0x5c, + 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, + 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x2b, 0x79, 0x14, 0x5c, + 0x7b, 0x5c, 0x2d, 0x79, 0x2a, 0x5c, 0x27, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, + 0x7b, 0xa4, 0x00, 0x0a, 0xb4, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x03, 0x2a, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x48, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x27, 0x51, 0x6f, 0x77, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, - 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x8e, 0x92, - 0x97, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xb4, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x27, 0x51, 0x6f, 0x77, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x8e, 0x92, 0x97, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, + 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1147,23 +1240,23 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc6, 0xc9, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0xc9, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, - 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1174,36 +1267,100 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, - 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, - 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, - 0x00, 0x02, 0x20, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x04, 0x20, 0x00, - 0x00, 0x05, 0x20, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, - 0x00, 0x09, 0x20, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x28, 0x20, 0x00, - 0x00, 0x29, 0x20, 0x00, 0x00, 0x5f, 0x20, 0x00, 0x00, 0x00, 0x30, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x01, 0x09, 0x70, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x02, 0x08, 0x6c, 0x61, 0x6e, 0x67, - 0x75, 0x61, 0x67, 0x65, 0x01, 0x03, 0x43, 0x31, 0x31, 0x00, 0x0c, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, - 0x05, 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x31, 0x39, 0x2e, 0x31, 0x2e, - 0x35, 0x2d, 0x77, 0x61, 0x73, 0x69, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x28, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2f, - 0x6c, 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, - 0x20, 0x61, 0x62, 0x34, 0x62, 0x35, 0x61, 0x32, 0x64, 0x62, 0x35, 0x38, - 0x32, 0x39, 0x35, 0x38, 0x61, 0x66, 0x31, 0x65, 0x65, 0x33, 0x30, 0x38, - 0x61, 0x37, 0x39, 0x30, 0x63, 0x66, 0x64, 0x62, 0x34, 0x32, 0x62, 0x64, - 0x32, 0x34, 0x37, 0x32, 0x30, 0x29, 0x00, 0x67, 0x0f, 0x74, 0x61, 0x72, + 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x85, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, + 0x20, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x05, + 0x20, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x09, + 0x20, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x28, 0x20, 0x00, 0x00, 0x29, + 0x20, 0x00, 0x00, 0x5f, 0x20, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x41, 0xe8, 0xc2, 0x04, 0x0b, 0x04, 0x00, 0x00, + 0x02, 0x00, 0x00, 0xb7, 0x05, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x0c, + 0x0b, 0x73, 0x74, 0x64, 0x6c, 0x69, 0x62, 0x2e, 0x77, 0x61, 0x73, 0x6d, + 0x01, 0xd9, 0x04, 0x2d, 0x00, 0x2a, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, + 0x65, 0x77, 0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67, 0x65, 0x74, + 0x01, 0x30, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, + 0x65, 0x74, 0x02, 0x2b, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, + 0x31, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x03, + 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x04, 0x13, 0x75, 0x6e, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x77, 0x65, 0x61, 0x6b, 0x3a, 0x6d, + 0x61, 0x69, 0x6e, 0x05, 0x12, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, + 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x06, + 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x07, 0x0a, 0x72, 0x65, 0x73, + 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x08, 0x06, 0x6d, 0x61, 0x6c, + 0x6c, 0x6f, 0x63, 0x09, 0x04, 0x66, 0x72, 0x65, 0x65, 0x0a, 0x06, 0x63, + 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x0b, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x0c, 0x05, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x0d, 0x0b, 0x5f, + 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x76, 0x6f, 0x69, 0x64, 0x0e, 0x0f, + 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, + 0x67, 0x65, 0x74, 0x0f, 0x15, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, + 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, + 0x65, 0x74, 0x10, 0x10, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x70, + 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x11, 0x0e, 0x5f, 0x5f, + 0x77, 0x61, 0x73, 0x69, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x74, 0x70, + 0x12, 0x05, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x13, 0x11, 0x5f, 0x5f, 0x77, + 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x74, 0x6f, + 0x72, 0x73, 0x14, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x15, 0x08, + 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x16, 0x06, 0x6d, 0x65, + 0x6d, 0x63, 0x6d, 0x70, 0x17, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72, + 0x18, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x19, 0x08, 0x74, 0x6f, + 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x1a, 0x07, 0x63, 0x61, 0x73, 0x65, + 0x6d, 0x61, 0x70, 0x1b, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, 0x65, + 0x72, 0x1c, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70, 0x1d, 0x08, + 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x1e, 0x07, 0x6d, 0x65, + 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x1f, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, + 0x74, 0x20, 0x08, 0x69, 0x73, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x21, + 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x22, 0x07, 0x69, 0x73, 0x62, + 0x6c, 0x61, 0x6e, 0x6b, 0x23, 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, + 0x6e, 0x6b, 0x24, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, + 0x25, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x26, 0x09, 0x5f, + 0x5f, 0x73, 0x74, 0x70, 0x6e, 0x63, 0x70, 0x79, 0x27, 0x07, 0x73, 0x74, + 0x72, 0x6e, 0x63, 0x70, 0x79, 0x28, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, + 0x69, 0x67, 0x69, 0x74, 0x29, 0x06, 0x77, 0x63, 0x73, 0x6c, 0x65, 0x6e, + 0x2a, 0x06, 0x77, 0x63, 0x73, 0x63, 0x68, 0x72, 0x2b, 0x08, 0x69, 0x73, + 0x77, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x08, 0x69, 0x73, 0x77, 0x61, + 0x6c, 0x6e, 0x75, 0x6d, 0x07, 0x33, 0x02, 0x00, 0x0f, 0x5f, 0x5f, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x01, 0x1f, 0x47, 0x4f, 0x54, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x5f, 0x5f, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x09, 0x11, 0x02, + 0x00, 0x07, 0x2e, 0x72, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x01, 0x05, 0x2e, + 0x64, 0x61, 0x74, 0x61, 0x00, 0x8e, 0x01, 0x09, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x65, 0x72, 0x73, 0x02, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, + 0x61, 0x67, 0x65, 0x01, 0x03, 0x43, 0x31, 0x31, 0x00, 0x0c, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, + 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x32, 0x31, 0x2e, 0x31, 0x2e, 0x34, + 0x2d, 0x77, 0x61, 0x73, 0x69, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x28, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2f, 0x6c, + 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, + 0x32, 0x32, 0x32, 0x66, 0x63, 0x31, 0x31, 0x66, 0x32, 0x62, 0x38, 0x66, + 0x32, 0x35, 0x66, 0x36, 0x61, 0x30, 0x66, 0x34, 0x39, 0x37, 0x36, 0x32, + 0x37, 0x32, 0x65, 0x66, 0x31, 0x62, 0x62, 0x37, 0x62, 0x66, 0x34, 0x39, + 0x35, 0x32, 0x31, 0x64, 0x29, 0x00, 0xa4, 0x01, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x06, 0x2b, 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x67, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2b, 0x0b, 0x62, 0x75, 0x6c, 0x6b, - 0x2d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2b, 0x08, 0x73, 0x69, 0x67, - 0x6e, 0x2d, 0x65, 0x78, 0x74, 0x2b, 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2b, 0x0a, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, 0x0f, - 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2d, - 0x6f, 0x70, 0x74 + 0x09, 0x2b, 0x0b, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x2b, 0x0f, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x2d, 0x6f, 0x70, 0x74, 0x2b, 0x16, 0x63, 0x61, 0x6c, + 0x6c, 0x2d, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x2d, 0x6f, + 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x6e, 0x67, 0x2b, 0x0e, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2b, + 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, + 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x73, 0x2b, 0x13, 0x6e, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x66, 0x70, 0x74, 0x6f, 0x69, 0x6e, + 0x74, 0x2b, 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2b, 0x08, 0x73, 0x69, 0x67, 0x6e, + 0x2d, 0x65, 0x78, 0x74 }; -unsigned int STDLIB_WASM_LEN = 14463; +unsigned int STDLIB_WASM_LEN = 16348; From eea85f4eff58d2e5a63ce6b197689bde2c1a5ac6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 16:19:58 +0000 Subject: [PATCH 125/140] build(deps): bump clap from 4.5.53 to 4.5.54 in the cargo group Bumps the cargo group with 1 update: [clap](https://github.com/clap-rs/clap). Updates `clap` from 4.5.53 to 4.5.54 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.53...clap_complete-v4.5.54) --- updated-dependencies: - dependency-name: clap dependency-version: 4.5.54 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cb3dd33..6973626b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,9 +241,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", "clap_derive", @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstream", "anstyle", diff --git a/Cargo.toml b/Cargo.toml index 9201c5fa..84dccaac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" cc = "1.2.51" -clap = { version = "4.5.53", features = [ +clap = { version = "4.5.54", features = [ "cargo", "derive", "env", From 630fa52717f2c575a53e21b1d324ade8e528b0bd Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Wed, 7 Jan 2026 23:27:37 +0000 Subject: [PATCH 126/140] fix(templates): fix python free-threading compatibility --- crates/cli/src/init.rs | 10 +++++++++- crates/cli/src/templates/setup.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 00b7657b..70ca25af 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -959,11 +959,19 @@ pub fn generate_grammar_files( allow_update, |path| generate_file(path, SETUP_PY_TEMPLATE, language_name, &generate_opts), |path| { - let contents = fs::read_to_string(path)?; + let mut contents = fs::read_to_string(path)?; if !contents.contains("build_ext") { info!("Replacing setup.py"); generate_file(path, SETUP_PY_TEMPLATE, language_name, &generate_opts)?; } + if !contents.contains(" and not get_config_var") { + info!("Updating Python free-threading support in setup.py"); + contents = contents.replace( + r#"startswith("cp"):"#, + r#"startswith("cp") and not get_config_var("Py_GIL_DISABLED"):"# + ); + write_file(path, contents)?; + } Ok(()) }, )?; diff --git a/crates/cli/src/templates/setup.py b/crates/cli/src/templates/setup.py index 7f92eaee..bcf184b7 100644 --- a/crates/cli/src/templates/setup.py +++ b/crates/cli/src/templates/setup.py @@ -32,7 +32,7 @@ class BuildExt(build_ext): class BdistWheel(bdist_wheel): def get_tag(self): python, abi, platform = super().get_tag() - if python.startswith("cp"): + if python.startswith("cp") and not get_config_var("Py_GIL_DISABLED"): python, abi = "cp310", "abi3" return python, abi, platform From aefae11c0ddab2e47d2a00aee00a257f93b8ef30 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sat, 10 Jan 2026 04:20:16 -0500 Subject: [PATCH 127/140] fix(build): define `_BSD_SOURCE` System endian conversion macros are gated behind this feature flag for older versions of GLIBC. `_BSD_SOURCE` and `_SVID_SOURCE` were deprecated and replaced with `_DEFAULT_SOURCE` starting with GLIBC 2.19. --- CMakeLists.txt | 2 +- Makefile | 2 +- Package.swift | 1 + build.zig | 1 + crates/xtask/src/build_wasm.rs | 1 + lib/binding_rust/build.rs | 1 + 6 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b40ac55a..f11895c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,7 +81,7 @@ set_target_properties(tree-sitter SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}" DEFINE_SYMBOL "") -target_compile_definitions(tree-sitter PRIVATE _POSIX_C_SOURCE=200112L _DEFAULT_SOURCE _DARWIN_C_SOURCE) +target_compile_definitions(tree-sitter PRIVATE _POSIX_C_SOURCE=200112L _DEFAULT_SOURCE _BSD_SOURCE _DARWIN_C_SOURCE) include(GNUInstallDirs) diff --git a/Makefile b/Makefile index d0b402f0..2098d275 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ OBJ := $(SRC:.c=.o) ARFLAGS := rcs CFLAGS ?= -O3 -Wall -Wextra -Wshadow -Wpedantic -Werror=incompatible-pointer-types override CFLAGS += -std=c11 -fPIC -fvisibility=hidden -override CFLAGS += -D_POSIX_C_SOURCE=200112L -D_DEFAULT_SOURCE -D_DARWIN_C_SOURCE +override CFLAGS += -D_POSIX_C_SOURCE=200112L -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_DARWIN_C_SOURCE override CFLAGS += -Ilib/src -Ilib/src/wasm -Ilib/include # ABI versioning diff --git a/Package.swift b/Package.swift index a92d3d14..fb6c6e95 100644 --- a/Package.swift +++ b/Package.swift @@ -27,6 +27,7 @@ let package = Package( .headerSearchPath("src"), .define("_POSIX_C_SOURCE", to: "200112L"), .define("_DEFAULT_SOURCE"), + .define("_BSD_SOURCE"), .define("_DARWIN_C_SOURCE"), ]), ], diff --git a/build.zig b/build.zig index bd7a0721..9bb1e818 100644 --- a/build.zig +++ b/build.zig @@ -40,6 +40,7 @@ pub fn build(b: *std.Build) !void { lib.root_module.addCMacro("_POSIX_C_SOURCE", "200112L"); lib.root_module.addCMacro("_DEFAULT_SOURCE", ""); + lib.root_module.addCMacro("_BSD_SOURCE", ""); lib.root_module.addCMacro("_DARWIN_C_SOURCE", ""); if (wasm) { diff --git a/crates/xtask/src/build_wasm.rs b/crates/xtask/src/build_wasm.rs index 183718a6..fbb231ce 100644 --- a/crates/xtask/src/build_wasm.rs +++ b/crates/xtask/src/build_wasm.rs @@ -199,6 +199,7 @@ pub fn run_wasm(args: &BuildWasm) -> Result<()> { "-D", "NDEBUG=", "-D", "_POSIX_C_SOURCE=200112L", "-D", "_DEFAULT_SOURCE=", + "-D", "_BSD_SOURCE=", "-D", "_DARWIN_C_SOURCE=", "-I", "lib/src", "-I", "lib/include", diff --git a/lib/binding_rust/build.rs b/lib/binding_rust/build.rs index 624001bc..57c5bc94 100644 --- a/lib/binding_rust/build.rs +++ b/lib/binding_rust/build.rs @@ -49,6 +49,7 @@ fn main() { .include(&include_path) .define("_POSIX_C_SOURCE", "200112L") .define("_DEFAULT_SOURCE", None) + .define("_BSD_SOURCE", None) .define("_DARWIN_C_SOURCE", None) .warnings(false) .file(src_path.join("lib.c")) From 6c05cdfb0c56db9c6bf6417352b7a12e1e26633a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:06:21 +0000 Subject: [PATCH 128/140] build(deps): bump the cargo group with 3 updates Bumps the cargo group with 3 updates: [cc](https://github.com/rust-lang/cc-rs), [clap_complete](https://github.com/clap-rs/clap) and [serde_json](https://github.com/serde-rs/json). Updates `cc` from 1.2.51 to 1.2.52 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.51...cc-v1.2.52) Updates `clap_complete` from 4.5.64 to 4.5.65 - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.64...clap_complete-v4.5.65) Updates `serde_json` from 1.0.148 to 1.0.149 - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.148...v1.0.149) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.52 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: clap_complete dependency-version: 4.5.65 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo - dependency-name: serde_json dependency-version: 1.0.149 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6973626b..4bb4214f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.51" +version = "1.2.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" dependencies = [ "find-msvc-tools", "shlex", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.64" +version = "4.5.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0da80818b2d95eca9aa614a30783e42f62bf5fdfee24e68cfb960b071ba8d1" +checksum = "430b4dc2b5e3861848de79627b2bedc9f3342c7da5173a14eaa5d0f8dc18ae5d" dependencies = [ "clap", ] @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" [[package]] name = "fnv" @@ -1701,9 +1701,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap", "itoa", diff --git a/Cargo.toml b/Cargo.toml index 84dccaac..5730ddf2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.51" +cc = "1.2.52" clap = { version = "4.5.54", features = [ "cargo", "derive", @@ -115,7 +115,7 @@ clap = { version = "4.5.54", features = [ "string", "unstable-styles", ] } -clap_complete = "4.5.62" +clap_complete = "4.5.65" clap_complete_nushell = "4.5.10" crc32fast = "1.5.0" ctor = "0.2.9" @@ -140,7 +140,7 @@ rustc-hash = "2.1.1" schemars = "1.0.5" semver = { version = "1.0.27", features = ["serde"] } serde = { version = "1.0.219", features = ["derive"] } -serde_json = { version = "1.0.147", features = ["preserve_order"] } +serde_json = { version = "1.0.149", features = ["preserve_order"] } similar = "2.7.0" smallbitvec = "2.6.0" streaming-iterator = "0.1.9" From 1a88b26a10f81e4623a82a8309bf1c48b1706954 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 12 Jan 2026 21:20:26 -0500 Subject: [PATCH 129/140] docs: note requirement to rebuild wasm stdlib --- docs/src/6-contributing.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/src/6-contributing.md b/docs/src/6-contributing.md index 5fb8271f..0fad6581 100644 --- a/docs/src/6-contributing.md +++ b/docs/src/6-contributing.md @@ -93,7 +93,8 @@ cargo xtask build-wasm-stdlib This command looks for the [Wasi SDK][wasi_sdk] indicated by the `TREE_SITTER_WASI_SDK_PATH` environment variable. If you don't have the binary, it can be downloaded from wasi-sdk's [releases][wasi-sdk-releases] -page. +page. Note that any changes to `crates/language/wasm/**` requires rebuilding the tree-sitter Wasm stdlib via +`cargo xtask build-wasm-stdlib`. ### Debugging From e64e74d5eda150043b0027a712b04d54d49d4cdd Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Mon, 12 Jan 2026 22:10:09 -0500 Subject: [PATCH 130/140] docs: adhere to 120 new word column limit for docs --- crates/cli/README.md | 9 ++++-- docs/src/3-syntax-highlighting.md | 5 ++- docs/src/4-code-navigation.md | 9 +++--- docs/src/cli/build.md | 7 +++-- docs/src/cli/dump-languages.md | 7 +++-- docs/src/cli/generate.md | 16 ++++++---- docs/src/cli/highlight.md | 3 +- docs/src/cli/index.md | 3 +- docs/src/cli/init.md | 14 ++++++--- docs/src/cli/parse.md | 6 ++-- docs/src/cli/playground.md | 4 +-- docs/src/cli/query.md | 7 +++-- docs/src/cli/tags.md | 3 +- docs/src/cli/test.md | 3 +- docs/src/cli/version.md | 8 ++--- .../src/creating-parsers/2-the-grammar-dsl.md | 24 +++++++------- .../creating-parsers/3-writing-the-grammar.md | 31 ++++++++++--------- .../creating-parsers/4-external-scanners.md | 24 +++++++------- docs/src/creating-parsers/5-writing-tests.md | 8 ++--- docs/src/creating-parsers/index.md | 4 +-- docs/src/index.md | 3 +- docs/src/using-parsers/2-basic-parsing.md | 11 ++++--- docs/src/using-parsers/3-advanced-parsing.md | 4 +-- docs/src/using-parsers/6-static-node-types.md | 6 ++-- docs/src/using-parsers/7-abi-versions.md | 7 +++-- docs/src/using-parsers/index.md | 4 +-- docs/src/using-parsers/queries/1-syntax.md | 16 +++++----- .../queries/3-predicates-and-directives.md | 12 +++---- 28 files changed, 143 insertions(+), 115 deletions(-) diff --git a/crates/cli/README.md b/crates/cli/README.md index 5a399f08..54d0ce07 100644 --- a/crates/cli/README.md +++ b/crates/cli/README.md @@ -7,7 +7,8 @@ [npmjs.com]: https://www.npmjs.org/package/tree-sitter-cli [npmjs.com badge]: https://img.shields.io/npm/v/tree-sitter-cli.svg?color=%23BF4A4A -The Tree-sitter CLI allows you to develop, test, and use Tree-sitter grammars from the command line. It works on `MacOS`, `Linux`, and `Windows`. +The Tree-sitter CLI allows you to develop, test, and use Tree-sitter grammars from the command line. It works on `MacOS`, +`Linux`, and `Windows`. ### Installation @@ -34,9 +35,11 @@ The `tree-sitter` binary itself has no dependencies, but specific commands have ### Commands -* `generate` - The `tree-sitter generate` command will generate a Tree-sitter parser based on the grammar in the current working directory. See [the documentation] for more information. +* `generate` - The `tree-sitter generate` command will generate a Tree-sitter parser based on the grammar in the current +working directory. See [the documentation] for more information. -* `test` - The `tree-sitter test` command will run the unit tests for the Tree-sitter parser in the current working directory. See [the documentation] for more information. +* `test` - The `tree-sitter test` command will run the unit tests for the Tree-sitter parser in the current working directory. +See [the documentation] for more information. * `parse` - The `tree-sitter parse` command will parse a file (or list of files) using Tree-sitter parsers. diff --git a/docs/src/3-syntax-highlighting.md b/docs/src/3-syntax-highlighting.md index de5308a0..c6356fbb 100644 --- a/docs/src/3-syntax-highlighting.md +++ b/docs/src/3-syntax-highlighting.md @@ -73,9 +73,8 @@ The behaviors of these three files are described in the next section. ## Queries -Tree-sitter's syntax highlighting system is based on *tree queries*, which are a general system for pattern-matching on Tree-sitter's -syntax trees. See [this section][pattern matching] of the documentation for more information -about tree queries. +Tree-sitter's syntax highlighting system is based on *tree queries*, which are a general system for pattern-matching on +Tree-sitter's syntax trees. See [this section][pattern matching] of the documentation for more information about tree queries. Syntax highlighting is controlled by *three* different types of query files that are usually included in the `queries` folder. The default names for the query files use the `.scm` file. We chose this extension because it commonly used for files written diff --git a/docs/src/4-code-navigation.md b/docs/src/4-code-navigation.md index 46d60307..02a9fa4d 100644 --- a/docs/src/4-code-navigation.md +++ b/docs/src/4-code-navigation.md @@ -3,7 +3,8 @@ Tree-sitter can be used in conjunction with its [query language][query language] as a part of code navigation systems. An example of such a system can be seen in the `tree-sitter tags` command, which emits a textual dump of the interesting syntactic nodes in its file argument. A notable application of this is GitHub's support for [search-based code navigation][gh search]. -This document exists to describe how to integrate with such systems, and how to extend this functionality to any language with a Tree-sitter grammar. +This document exists to describe how to integrate with such systems, and how to extend this functionality to any language +with a Tree-sitter grammar. ## Tagging and captures @@ -12,9 +13,9 @@ entities. Having found them, you use a syntax capture to label the entity and it The essence of a given tag lies in two pieces of data: the _role_ of the entity that is matched (i.e. whether it is a definition or a reference) and the _kind_ of that entity, which describes how the entity is used -(i.e. whether it's a class definition, function call, variable reference, and so on). Our convention is to use a syntax capture -following the `@role.kind` capture name format, and another inner capture, always called `@name`, that pulls out the name -of a given identifier. +(i.e. whether it's a class definition, function call, variable reference, and so on). Our convention is to use a syntax +capture following the `@role.kind` capture name format, and another inner capture, always called `@name`, that pulls out +the name of a given identifier. You may optionally include a capture named `@doc` to bind a docstring. For convenience purposes, the tagging system provides two built-in functions, `#select-adjacent!` and `#strip!` that are convenient for removing comment syntax from a docstring. diff --git a/docs/src/cli/build.md b/docs/src/cli/build.md index 6863f926..44ee8271 100644 --- a/docs/src/cli/build.md +++ b/docs/src/cli/build.md @@ -19,8 +19,8 @@ will attempt to build the parser in the current working directory. ### `-w/--wasm` Compile the parser as a Wasm module. This command looks for the [Wasi SDK][wasi_sdk] indicated by the `TREE_SITTER_WASI_SDK_PATH` -environment variable. If you don't have the binary, the CLI will attempt to download it for you to `/tree-sitter/wasi-sdk/`, where -`` is resolved according to the [XDG base directory][XDG] or Window's [Known_Folder_Locations][Known_Folder]. +environment variable. If you don't have the binary, the CLI will attempt to download it for you to `/tree-sitter/wasi-sdk/`, +where `` is resolved according to the [XDG base directory][XDG] or Window's [Known_Folder_Locations][Known_Folder]. ### `-o/--output` @@ -37,7 +37,8 @@ in the external scanner does so using their allocator. ### `-0/--debug` -Compile the parser with debug flags enabled. This is useful when debugging issues that require a debugger like `gdb` or `lldb`. +Compile the parser with debug flags enabled. This is useful when debugging issues that require a debugger like `gdb` or +`lldb`. [Known_Folder]: https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid [wasi_sdk]: https://github.com/WebAssembly/wasi-sdk diff --git a/docs/src/cli/dump-languages.md b/docs/src/cli/dump-languages.md index 1d1a6aaa..f29daa57 100644 --- a/docs/src/cli/dump-languages.md +++ b/docs/src/cli/dump-languages.md @@ -1,6 +1,8 @@ # `tree-sitter dump-languages` -The `dump-languages` command prints out a list of all the languages that the CLI knows about. This can be useful for debugging purposes, or for scripting. The paths to search comes from the config file's [`parser-directories`][parser-directories] object. +The `dump-languages` command prints out a list of all the languages that the CLI knows about. This can be useful for debugging +purposes, or for scripting. The paths to search comes from the config file's [`parser-directories`][parser-directories] +object. ```bash tree-sitter dump-languages [OPTIONS] # Aliases: langs @@ -10,6 +12,7 @@ tree-sitter dump-languages [OPTIONS] # Aliases: langs ### `--config-path` -The path to the configuration file. Ordinarily, the CLI will use the default location as explained in the [init-config](./init-config.md) command. This flag allows you to explicitly override that default, and use a config defined elsewhere. +The path to the configuration file. Ordinarily, the CLI will use the default location as explained in the [init-config](./init-config.md) +command. This flag allows you to explicitly override that default, and use a config defined elsewhere. [parser-directories]: ./init-config.md#parser-directories diff --git a/docs/src/cli/generate.md b/docs/src/cli/generate.md index 5ec02ad7..df9111f0 100644 --- a/docs/src/cli/generate.md +++ b/docs/src/cli/generate.md @@ -1,6 +1,7 @@ # `tree-sitter generate` -The most important command for grammar development is `tree-sitter generate`, which reads the grammar in structured form and outputs C files that can be compiled into a shared or static library (e.g., using the [`build`](./build.md) command). +The most important command for grammar development is `tree-sitter generate`, which reads the grammar in structured form +and outputs C files that can be compiled into a shared or static library (e.g., using the [`build`](./build.md) command). ```bash tree-sitter generate [OPTIONS] [GRAMMAR_PATH] # Aliases: gen, g @@ -8,7 +9,8 @@ tree-sitter generate [OPTIONS] [GRAMMAR_PATH] # Aliases: gen, g The optional `GRAMMAR_PATH` argument should point to the structured grammar, in one of two forms: - `grammar.js` a (ESM or CJS) JavaScript file; if the argument is omitted, it defaults to `./grammar.js`. -- `grammar.json` a structured representation of the grammar that is created as a byproduct of `generate`; this can be used to regenerate a missing `parser.c` without requiring a JavaScript runtime (useful when distributing parsers to consumers). +- `grammar.json` a structured representation of the grammar that is created as a byproduct of `generate`; this can be used +to regenerate a missing `parser.c` without requiring a JavaScript runtime (useful when distributing parsers to consumers). If there is an ambiguity or *local ambiguity* in your grammar, Tree-sitter will detect it during parser generation, and it will exit with a `Unresolved conflict` error message. To learn more about conflicts and how to handle them, see @@ -21,7 +23,8 @@ in the user guide. - `src/tree_sitter/parser.h` provides basic C definitions that are used in the generated `parser.c` file. - `src/tree_sitter/alloc.h` provides memory allocation macros that can be used in an external scanner. - `src/tree_sitter/array.h` provides array macros that can be used in an external scanner. -- `src/grammar.json` contains a structured representation of the grammar; can be used to regenerate the parser without having to re-evaluate the `grammar.js`. +- `src/grammar.json` contains a structured representation of the grammar; can be used to regenerate the parser without having +to re-evaluate the `grammar.js`. - `src/node-types.json` provides type information about individual syntax nodes; see the section on [`Static Node Types`](../using-parsers/6-static-node-types.md). @@ -29,8 +32,8 @@ in the user guide. ### `-l/--log` -Print the log of the parser generation process. This includes information such as what tokens are included in the error recovery state, -what keywords were extracted, what states were split and why, and the entry point state. +Print the log of the parser generation process. This includes information such as what tokens are included in the error +recovery state, what keywords were extracted, what states were split and why, and the entry point state. ### `--abi ` @@ -60,7 +63,8 @@ The path to the JavaScript runtime executable to use when generating the parser. Note that you can also set this with `TREE_SITTER_JS_RUNTIME`. Starting from version 0.26, you can also pass in `native` to use the experimental native QuickJS runtime that comes bundled with the CLI. This avoids the dependency on a JavaScript runtime entirely. The native QuickJS runtime is compatible -with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base grammars, the native runtime can be used *after* running `npm install`. +with ESM as well as with CommonJS in strict mode. If your grammar depends on `npm` to install dependencies such as base +grammars, the native runtime can be used *after* running `npm install`. ### `--disable-optimization` diff --git a/docs/src/cli/highlight.md b/docs/src/cli/highlight.md index 82c9e25c..1a4ed1f6 100644 --- a/docs/src/cli/highlight.md +++ b/docs/src/cli/highlight.md @@ -52,7 +52,8 @@ The path to the directory containing the grammar. ### `--config-path ` -The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more information. +The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more +information. ### `-n/--test-number ` diff --git a/docs/src/cli/index.md b/docs/src/cli/index.md index 8b7659f0..042c0196 100644 --- a/docs/src/cli/index.md +++ b/docs/src/cli/index.md @@ -1,6 +1,7 @@ # CLI Overview -The `tree-sitter` command-line interface is used to create, manage, test, and build tree-sitter parsers. It is controlled by +The `tree-sitter` command-line interface is used to create, manage, test, and build tree-sitter parsers. It is controlled +by - a personal `tree-sitter/config.json` config file generated by [`tree-sitter init-config`](./init-config.md) - a parser `tree-sitter.json` config file generated by [`tree-sitter init`](./init.md). diff --git a/docs/src/cli/init.md b/docs/src/cli/init.md index d45c8e09..568bc98f 100644 --- a/docs/src/cli/init.md +++ b/docs/src/cli/init.md @@ -14,8 +14,11 @@ tree-sitter init [OPTIONS] # Aliases: i The following required files are always created if missing: -- `tree-sitter.json` - The main configuration file that determines how `tree-sitter` interacts with the grammar. If missing, the `init` command will prompt the user for the required fields. See [below](./init.md#structure-of-tree-sitterjson) for the full documentation of the structure of this file. -- `package.json` - The `npm` manifest for the parser. This file is required for some `tree-sitter` subcommands, and if the grammar has dependencies (e.g., another published base grammar that this grammar extends). +- `tree-sitter.json` - The main configuration file that determines how `tree-sitter` interacts with the grammar. If missing, +the `init` command will prompt the user for the required fields. See [below](./init.md#structure-of-tree-sitterjson) for +the full documentation of the structure of this file. +- `package.json` - The `npm` manifest for the parser. This file is required for some `tree-sitter` subcommands, and if the +grammar has dependencies (e.g., another published base grammar that this grammar extends). - `grammar.js` - An empty template for the main grammar file; see [the section on creating parsers](../2-creating-parser). ### Language bindings @@ -130,8 +133,8 @@ be picked up by the cli. These keys help to decide whether the language applies to a given file: -- `file-types` — An array of filename suffix strings (not including the dot). The grammar will be used for files whose names end with one of -these suffixes. Note that the suffix may match an *entire* filename. +- `file-types` — An array of filename suffix strings (not including the dot). The grammar will be used for files whose names +end with one of these suffixes. Note that the suffix may match an *entire* filename. - `first-line-regex` — A regex pattern that will be tested against the first line of a file to determine whether this language applies to the file. If present, this regex will be used for any file whose @@ -188,7 +191,8 @@ Each key is a language name, and the value is a boolean. Update outdated generated files, if possible. -**Note:** Existing files that may have been edited manually are _not_ updated in general. To force an update to such files, remove them and call `tree-sitter init -u` again. +**Note:** Existing files that may have been edited manually are _not_ updated in general. To force an update to such files, +remove them and call `tree-sitter init -u` again. ### `-p/--grammar-path ` diff --git a/docs/src/cli/parse.md b/docs/src/cli/parse.md index f18c2edb..2e9bc835 100644 --- a/docs/src/cli/parse.md +++ b/docs/src/cli/parse.md @@ -78,7 +78,8 @@ Suppress main output. ### `--edits ...` -Apply edits after parsing the file. Edits are in the form of `row,col|position delcount insert_text` where row and col, or position are 0-indexed. +Apply edits after parsing the file. Edits are in the form of `row,col|position delcount insert_text` where row and col, +or position are 0-indexed. ### `--encoding ` @@ -95,7 +96,8 @@ Output parsing results in a JSON format. ### `--config-path ` -The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more information. +The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more +information. ### `-n/--test-number ` diff --git a/docs/src/cli/playground.md b/docs/src/cli/playground.md index 7c2ef598..c0bfb495 100644 --- a/docs/src/cli/playground.md +++ b/docs/src/cli/playground.md @@ -7,8 +7,8 @@ tree-sitter playground [OPTIONS] # Aliases: play, pg, web-ui ``` ```admonish note -For this to work, you must have already built the parser as a Wasm module. This can be done with the [`build`](./build.md) subcommand -(`tree-sitter build --wasm`). +For this to work, you must have already built the parser as a Wasm module. This can be done with the [`build`](./build.md) +subcommand (`tree-sitter build --wasm`). ``` ## Options diff --git a/docs/src/cli/query.md b/docs/src/cli/query.md index 08ff2654..fbd6dafd 100644 --- a/docs/src/cli/query.md +++ b/docs/src/cli/query.md @@ -47,8 +47,8 @@ The range of rows in which the query will be executed. The format is `start_row: ### `--containing-row-range ` -The range of rows in which the query will be executed. Only the matches that are fully contained within the provided row range -will be returned. +The range of rows in which the query will be executed. Only the matches that are fully contained within the provided row +range will be returned. ### `--scope ` @@ -64,7 +64,8 @@ Whether to run query tests or not. ### `--config-path ` -The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more information. +The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more +information. ### `-n/--test-number ` diff --git a/docs/src/cli/tags.md b/docs/src/cli/tags.md index a48fabb4..8275237e 100644 --- a/docs/src/cli/tags.md +++ b/docs/src/cli/tags.md @@ -31,7 +31,8 @@ The path to the directory containing the grammar. ### `--config-path ` -The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more information. +The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more +information. ### `-n/--test-number ` diff --git a/docs/src/cli/test.md b/docs/src/cli/test.md index f8b8a02d..7e662f60 100644 --- a/docs/src/cli/test.md +++ b/docs/src/cli/test.md @@ -63,7 +63,8 @@ When using the `--debug-graph` option, open the log file in the default browser. ### `--config-path ` -The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more information. +The path to an alternative configuration (`config.json`) file. See [the init-config command](./init-config.md) for more +information. ### `--show-fields` diff --git a/docs/src/cli/version.md b/docs/src/cli/version.md index c2d526a7..39cda84a 100644 --- a/docs/src/cli/version.md +++ b/docs/src/cli/version.md @@ -25,11 +25,9 @@ tree-sitter version --bump minor # minor bump tree-sitter version --bump major # major bump ``` -As a grammar author, you should keep the version of your grammar in sync across -different bindings. However, doing so manually is error-prone and tedious, so -this command takes care of the burden. If you are using a version control system, -it is recommended to commit the changes made by this command, and to tag the -commit with the new version. +As a grammar author, you should keep the version of your grammar in sync across different bindings. However, doing so manually +is error-prone and tedious, so this command takes care of the burden. If you are using a version control system, it is recommended +to commit the changes made by this command, and to tag the commit with the new version. To print the current version without bumping it, use: diff --git a/docs/src/creating-parsers/2-the-grammar-dsl.md b/docs/src/creating-parsers/2-the-grammar-dsl.md index d210619b..0592c6bd 100644 --- a/docs/src/creating-parsers/2-the-grammar-dsl.md +++ b/docs/src/creating-parsers/2-the-grammar-dsl.md @@ -17,8 +17,8 @@ DSL through the `RustRegex` class. Simply pass your regex pattern as a string: ``` Unlike JavaScript's builtin `RegExp` class, which takes a pattern and flags as separate arguments, `RustRegex` only - accepts a single pattern string. While it doesn't support separate flags, you can use inline flags within the pattern itself. - For more details about Rust's regex syntax and capabilities, check out the [Rust regex documentation][rust regex]. + accepts a single pattern string. While it doesn't support separate flags, you can use inline flags within the pattern + itself. For more details about Rust's regex syntax and capabilities, check out the [Rust regex documentation][rust regex]. ```admonish note Only a subset of the Regex engine is actually supported. This is due to certain features like lookahead and lookaround @@ -50,10 +50,10 @@ The previous `repeat` rule is implemented in `repeat1` but is included because i - **Options : `optional(rule)`** — This function creates a rule that matches *zero or one* occurrence of a given rule. It is analogous to the `[x]` (square bracket) syntax in EBNF notation. -- **Precedence : `prec(number, rule)`** — This function marks the given rule with a numerical precedence, which will be used -to resolve [*LR(1) Conflicts*][lr-conflict] at parser-generation time. When two rules overlap in a way that represents either -a true ambiguity or a *local* ambiguity given one token of lookahead, Tree-sitter will try to resolve the conflict by matching -the rule with the higher precedence. The default precedence of all rules is zero. This works similarly to the +- **Precedence : `prec(number, rule)`** — This function marks the given rule with a numerical precedence, which will be +used to resolve [*LR(1) Conflicts*][lr-conflict] at parser-generation time. When two rules overlap in a way that represents +either a true ambiguity or a *local* ambiguity given one token of lookahead, Tree-sitter will try to resolve the conflict +by matching the rule with the higher precedence. The default precedence of all rules is zero. This works similarly to the [precedence directives][yacc-prec] in Yacc grammars. This function can also be used to assign lexical precedence to a given @@ -115,8 +115,8 @@ want to create syntax tree nodes at runtime. - **`conflicts`** — an array of arrays of rule names. Each inner array represents a set of rules that's involved in an *LR(1) conflict* that is *intended to exist* in the grammar. When these conflicts occur at runtime, Tree-sitter will use -the GLR algorithm to explore all the possible interpretations. If *multiple* parses end up succeeding, Tree-sitter will pick -the subtree whose corresponding rule has the highest total *dynamic precedence*. +the GLR algorithm to explore all the possible interpretations. If *multiple* parses end up succeeding, Tree-sitter will +pick the subtree whose corresponding rule has the highest total *dynamic precedence*. - **`externals`** — an array of token names which can be returned by an [*external scanner*][external-scanners]. External scanners allow you to write custom C code which runs during the lexing @@ -139,10 +139,10 @@ for more details. array of reserved rules. The reserved rule in the array must be a terminal token meaning it must be a string, regex, token, or terminal rule. The reserved rule must also exist and be used in the grammar, specifying arbitrary tokens will not work. The *first* reserved word set in the object is the global word set, meaning it applies to every rule in every parse state. -However, certain keywords are contextual, depending on the rule. For example, in JavaScript, keywords are typically not allowed -as ordinary variables, however, they *can* be used as a property name. In this situation, the `reserved` function would be used, -and the word set to pass in would be the name of the word set that is declared in the `reserved` object that corresponds to an -empty array, signifying *no* keywords are reserved. +However, certain keywords are contextual, depending on the rule. For example, in JavaScript, keywords are typically not +allowed as ordinary variables, however, they *can* be used as a property name. In this situation, the `reserved` function +would be used, and the word set to pass in would be the name of the word set that is declared in the `reserved` object that +corresponds to an empty array, signifying *no* keywords are reserved. [bison-dprec]: https://www.gnu.org/software/bison/manual/html_node/Generalized-LR-Parsing.html [ebnf]: https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form diff --git a/docs/src/creating-parsers/3-writing-the-grammar.md b/docs/src/creating-parsers/3-writing-the-grammar.md index ebd2f5a4..5048ff5b 100644 --- a/docs/src/creating-parsers/3-writing-the-grammar.md +++ b/docs/src/creating-parsers/3-writing-the-grammar.md @@ -1,7 +1,7 @@ # Writing the Grammar -Writing a grammar requires creativity. There are an infinite number of CFGs (context-free grammars) that can be used to describe -any given language. To produce a good Tree-sitter parser, you need to create a grammar with two important properties: +Writing a grammar requires creativity. There are an infinite number of CFGs (context-free grammars) that can be used to +describe any given language. To produce a good Tree-sitter parser, you need to create a grammar with two important properties: 1. **An intuitive structure** — Tree-sitter's output is a [concrete syntax tree][cst]; each node in the tree corresponds directly to a [terminal or non-terminal symbol][non-terminal] in the grammar. So to produce an easy-to-analyze tree, there @@ -139,8 +139,8 @@ instead. It's often useful to check your progress by trying to parse some real c ## Structuring Rules Well Imagine that you were just starting work on the [Tree-sitter JavaScript parser][tree-sitter-javascript]. Naively, you might -try to directly mirror the structure of the [ECMAScript Language Spec][ecmascript-spec]. To illustrate the problem with this -approach, consider the following line of code: +try to directly mirror the structure of the [ECMAScript Language Spec][ecmascript-spec]. To illustrate the problem with +this approach, consider the following line of code: ```js return x + y; @@ -181,16 +181,17 @@ which are unrelated to the actual code. ## Standard Rule Names -Tree-sitter places no restrictions on how to name the rules of your grammar. It can be helpful, however, to follow certain conventions -used by many other established grammars in the ecosystem. Some of these well-established patterns are listed below: +Tree-sitter places no restrictions on how to name the rules of your grammar. It can be helpful, however, to follow certain +conventions used by many other established grammars in the ecosystem. Some of these well-established patterns are listed +below: - `source_file`: Represents an entire source file, this rule is commonly used as the root node for a grammar, -- `expression`/`statement`: Used to represent statements and expressions for a given language. Commonly defined as a choice between several -more specific sub-expression/sub-statement rules. +- `expression`/`statement`: Used to represent statements and expressions for a given language. Commonly defined as a choice +between several more specific sub-expression/sub-statement rules. - `block`: Used as the parent node for block scopes, with its children representing the block's contents. - `type`: Represents the types of a language such as `int`, `char`, and `void`. -- `identifier`: Used for constructs like variable names, function arguments, and object fields; this rule is commonly used as the `word` -token in grammars. +- `identifier`: Used for constructs like variable names, function arguments, and object fields; this rule is commonly used +as the `word` token in grammars. - `string`: Used to represent `"string literals"`. - `comment`: Used to represent comments, this rule is commonly used as an `extra`. @@ -308,9 +309,9 @@ This is where `prec.left` and `prec.right` come into use. We want to select the ## Using Conflicts -Sometimes, conflicts are actually desirable. In our JavaScript grammar, expressions and patterns can create intentional ambiguity. -A construct like `[x, y]` could be legitimately parsed as both an array literal (like in `let a = [x, y]`) or as a destructuring -pattern (like in `let [x, y] = arr`). +Sometimes, conflicts are actually desirable. In our JavaScript grammar, expressions and patterns can create intentional +ambiguity. A construct like `[x, y]` could be legitimately parsed as both an array literal (like in `let a = [x, y]`) or +as a destructuring pattern (like in `let [x, y] = arr`). ```js export default grammar({ @@ -564,8 +565,8 @@ as mentioned in the previous page, is `token(prec(N, ...))`. ## Keywords Many languages have a set of _keyword_ tokens (e.g. `if`, `for`, `return`), as well as a more general token (e.g. `identifier`) -that matches any word, including many of the keyword strings. For example, JavaScript has a keyword `instanceof`, which is -used as a binary operator, like this: +that matches any word, including many of the keyword strings. For example, JavaScript has a keyword `instanceof`, which +is used as a binary operator, like this: ```js if (a instanceof Something) b(); diff --git a/docs/src/creating-parsers/4-external-scanners.md b/docs/src/creating-parsers/4-external-scanners.md index 05268df7..6c89e221 100644 --- a/docs/src/creating-parsers/4-external-scanners.md +++ b/docs/src/creating-parsers/4-external-scanners.md @@ -143,10 +143,10 @@ the second argument, the current character will be treated as whitespace; whites associated with tokens emitted by the external scanner. - **`void (*mark_end)(TSLexer *)`** — A function for marking the end of the recognized token. This allows matching tokens -that require multiple characters of lookahead. By default, (if you don't call `mark_end`), any character that you moved past -using the `advance` function will be included in the size of the token. But once you call `mark_end`, then any later calls -to `advance` will _not_ increase the size of the returned token. You can call `mark_end` multiple times to increase the size -of the token. +that require multiple characters of lookahead. By default, (if you don't call `mark_end`), any character that you moved +past using the `advance` function will be included in the size of the token. But once you call `mark_end`, then any later +calls to `advance` will _not_ increase the size of the returned token. You can call `mark_end` multiple times to increase +the size of the token. - **`uint32_t (*get_column)(TSLexer *)`** — A function for querying the current column position of the lexer. It returns the number of codepoints since the start of the current line. The codepoint position is recalculated on every call to this @@ -185,9 +185,9 @@ if (valid_symbols[INDENT] || valid_symbols[DEDENT]) { ### Allocator -Instead of using libc's `malloc`, `calloc`, `realloc`, and `free`, you should use the versions prefixed with `ts_` from `tree_sitter/alloc.h`. -These macros can allow a potential consumer to override the default allocator with their own implementation, but by default -will use the libc functions. +Instead of using libc's `malloc`, `calloc`, `realloc`, and `free`, you should use the versions prefixed with `ts_` from +`tree_sitter/alloc.h`. These macros can allow a potential consumer to override the default allocator with their own implementation, +but by default will use the libc functions. As a consumer of the tree-sitter core library as well as any parser libraries that might use allocations, you can enable overriding the default allocator and have it use the same one as the library allocator, of which you can set with `ts_set_allocator`. @@ -195,7 +195,8 @@ To enable this overriding in scanners, you must compile them with the `TREE_SITT the library must be linked into your final app dynamically, since it needs to resolve the internal functions at runtime. If you are compiling an executable binary that uses the core library, but want to load parsers dynamically at runtime, then you will have to use a special linker flag on Unix. For non-Darwin systems, that would be `--dynamic-list` and for Darwin -systems, that would be `-exported_symbols_list`. The CLI does exactly this, so you can use it as a reference (check out `cli/build.rs`). +systems, that would be `-exported_symbols_list`. The CLI does exactly this, so you can use it as a reference (check out +`cli/build.rs`). For example, assuming you wanted to allocate 100 bytes for your scanner, you'd do so like the following example: @@ -293,9 +294,10 @@ bool tree_sitter_my_language_external_scanner_scan( ## Other External Scanner Details -External scanners have priority over Tree-sitter's normal lexing process. When a token listed in the externals array is valid -at a given position, the external scanner is called first. This makes external scanners a powerful way to override Tree-sitter's -default lexing behavior, especially for cases that can't be handled with regular lexical rules, parsing, or dynamic precedence. +External scanners have priority over Tree-sitter's normal lexing process. When a token listed in the externals array is +valid at a given position, the external scanner is called first. This makes external scanners a powerful way to override +Tree-sitter's default lexing behavior, especially for cases that can't be handled with regular lexical rules, parsing, or +dynamic precedence. During error recovery, Tree-sitter's first step is to call the external scanner's scan function with all tokens marked as valid. Your scanner should detect and handle this case appropriately. One simple approach is to add an unused "sentinel" diff --git a/docs/src/creating-parsers/5-writing-tests.md b/docs/src/creating-parsers/5-writing-tests.md index 438dc02a..33155cca 100644 --- a/docs/src/creating-parsers/5-writing-tests.md +++ b/docs/src/creating-parsers/5-writing-tests.md @@ -39,8 +39,8 @@ It only shows the *named* nodes, as described in [this section][named-vs-anonymo ``` The expected output section can also *optionally* show the [*field names*][node-field-names] associated with each child - node. To include field names in your tests, you write a node's field name followed by a colon, before the node itself in - the S-expression: + node. To include field names in your tests, you write a node's field name followed by a colon, before the node itself + in the S-expression: ```query (source_file @@ -104,8 +104,8 @@ you can repeat the attribute on a new line. The following attributes are available: -* `:cst` - This attribute specifies that the expected output should be in the form of a CST instead of the normal S-expression. This -CST matches the format given by `parse --cst`. +* `:cst` - This attribute specifies that the expected output should be in the form of a CST instead of the normal S-expression. +This CST matches the format given by `parse --cst`. * `:error` — This attribute will assert that the parse tree contains an error. It's useful to just validate that a certain input is invalid without displaying the whole parse tree, as such you should omit the parse tree below the `---` line. * `:fail-fast` — This attribute will stop the testing of additional cases if the test marked with this attribute fails. diff --git a/docs/src/creating-parsers/index.md b/docs/src/creating-parsers/index.md index 478cbeeb..4fb2c112 100644 --- a/docs/src/creating-parsers/index.md +++ b/docs/src/creating-parsers/index.md @@ -1,4 +1,4 @@ # Creating parsers -Developing Tree-sitter grammars can have a difficult learning curve, but once you get the hang of it, it can be fun and even -zen-like. This document will help you to get started and to develop a useful mental model. +Developing Tree-sitter grammars can have a difficult learning curve, but once you get the hang of it, it can be fun and +even zen-like. This document will help you to get started and to develop a useful mental model. diff --git a/docs/src/index.md b/docs/src/index.md index 5f9140a7..ee92966a 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -10,7 +10,8 @@ file and efficiently update the syntax tree as the source file is edited. Tree-s - **General** enough to parse any programming language - **Fast** enough to parse on every keystroke in a text editor - **Robust** enough to provide useful results even in the presence of syntax errors -- **Dependency-free** so that the runtime library (which is written in pure [C11](https://github.com/tree-sitter/tree-sitter/tree/master/lib)) can be embedded in any application +- **Dependency-free** so that the runtime library (which is written in pure [C11](https://github.com/tree-sitter/tree-sitter/tree/master/lib)) +can be embedded in any application ## Language Bindings diff --git a/docs/src/using-parsers/2-basic-parsing.md b/docs/src/using-parsers/2-basic-parsing.md index 77f6fb7a..8c425d6b 100644 --- a/docs/src/using-parsers/2-basic-parsing.md +++ b/docs/src/using-parsers/2-basic-parsing.md @@ -2,7 +2,8 @@ ## Providing the Code -In the example on the previous page, we parsed source code stored in a simple string using the `ts_parser_parse_string` function: +In the example on the previous page, we parsed source code stored in a simple string using the `ts_parser_parse_string` +function: ```c TSTree *ts_parser_parse_string( @@ -135,10 +136,10 @@ Consider a grammar rule like this: if_statement: $ => seq("if", "(", $._expression, ")", $._statement); ``` -A syntax node representing an `if_statement` in this language would have 5 children: the condition expression, the body statement, -as well as the `if`, `(`, and `)` tokens. The expression and the statement would be marked as _named_ nodes, because they -have been given explicit names in the grammar. But the `if`, `(`, and `)` nodes would _not_ be named nodes, because they -are represented in the grammar as simple strings. +A syntax node representing an `if_statement` in this language would have 5 children: the condition expression, the body +statement, as well as the `if`, `(`, and `)` tokens. The expression and the statement would be marked as _named_ nodes, +because they have been given explicit names in the grammar. But the `if`, `(`, and `)` nodes would _not_ be named nodes, +because they are represented in the grammar as simple strings. You can check whether any given node is named: diff --git a/docs/src/using-parsers/3-advanced-parsing.md b/docs/src/using-parsers/3-advanced-parsing.md index bffd35ea..c1c92e24 100644 --- a/docs/src/using-parsers/3-advanced-parsing.md +++ b/docs/src/using-parsers/3-advanced-parsing.md @@ -19,8 +19,8 @@ typedef struct { void ts_tree_edit(TSTree *, const TSInputEdit *); ``` -Then, you can call `ts_parser_parse` again, passing in the old tree. This will create a new tree that internally shares structure -with the old tree. +Then, you can call `ts_parser_parse` again, passing in the old tree. This will create a new tree that internally shares +structure with the old tree. When you edit a syntax tree, the positions of its nodes will change. If you have stored any `TSNode` instances outside of the `TSTree`, you must update their positions separately, using the same `TSInputEdit` value, in order to update their diff --git a/docs/src/using-parsers/6-static-node-types.md b/docs/src/using-parsers/6-static-node-types.md index 5976d0bc..171f4314 100644 --- a/docs/src/using-parsers/6-static-node-types.md +++ b/docs/src/using-parsers/6-static-node-types.md @@ -108,9 +108,9 @@ In Tree-sitter grammars, there are usually certain rules that represent abstract "type", "declaration"). In the `grammar.js` file, these are often written as [hidden rules][hidden rules] whose definition is a simple [`choice`][grammar dsl] where each member is just a single symbol. -Normally, hidden rules are not mentioned in the node types file, since they don't appear in the syntax tree. But if you add -a hidden rule to the grammar's [`supertypes` list][grammar dsl], then it _will_ show up in the node -types file, with the following special entry: +Normally, hidden rules are not mentioned in the node types file, since they don't appear in the syntax tree. But if you +add a hidden rule to the grammar's [`supertypes` list][grammar dsl], then it _will_ show up in the node types file, with +the following special entry: - `"subtypes"` — An array of objects that specify the _types_ of nodes that this 'supertype' node can wrap. diff --git a/docs/src/using-parsers/7-abi-versions.md b/docs/src/using-parsers/7-abi-versions.md index 34347938..1db42a5d 100644 --- a/docs/src/using-parsers/7-abi-versions.md +++ b/docs/src/using-parsers/7-abi-versions.md @@ -15,8 +15,11 @@ A given version of the tree-sitter library is only able to load parsers generate | >=0.20.3, <=0.24 | 13 | 14 | | >=0.25 | 13 | 15 | -By default, the tree-sitter CLI will generate parsers using the latest available ABI for that version, but an older ABI (supported by the CLI) can be selected by passing the [`--abi` option][abi_option] to the `generate` command. +By default, the tree-sitter CLI will generate parsers using the latest available ABI for that version, but an older ABI +(supported by the CLI) can be selected by passing the [`--abi` option][abi_option] to the `generate` command. -Note that the ABI version range supported by the CLI can be smaller than for the library: When a new ABI version is released, older versions will be phased out over a deprecation period, which starts with no longer being able to generate parsers with the oldest ABI version. +Note that the ABI version range supported by the CLI can be smaller than for the library: When a new ABI version is released, +older versions will be phased out over a deprecation period, which starts with no longer being able to generate parsers +with the oldest ABI version. [abi_option]: ../cli/generate.md#--abi-version diff --git a/docs/src/using-parsers/index.md b/docs/src/using-parsers/index.md index 48d61599..5b2c146d 100644 --- a/docs/src/using-parsers/index.md +++ b/docs/src/using-parsers/index.md @@ -6,8 +6,8 @@ the core concepts remain the same. Tree-sitter's parsing functionality is implemented through its C API, with all functions documented in the [tree_sitter/api.h][api.h] header file, but if you're working in another language, you can use one of the following bindings found [here](../index.md#language-bindings), -each providing idiomatic access to Tree-sitter's functionality. Of these bindings, the official ones have their own API docs -hosted online at the following pages: +each providing idiomatic access to Tree-sitter's functionality. Of these bindings, the official ones have their own API +doc hosted online at the following pages: - [Go][go] - [Java] diff --git a/docs/src/using-parsers/queries/1-syntax.md b/docs/src/using-parsers/queries/1-syntax.md index 0f02be61..2e0a8853 100644 --- a/docs/src/using-parsers/queries/1-syntax.md +++ b/docs/src/using-parsers/queries/1-syntax.md @@ -1,9 +1,9 @@ # Query Syntax -A _query_ consists of one or more _patterns_, where each pattern is an [S-expression][s-exp] that matches a certain set of -nodes in a syntax tree. The expression to match a given node consists of a pair of parentheses containing two things: the -node's type, and optionally, a series of other S-expressions that match the node's children. For example, this pattern would -match any `binary_expression` node whose children are both `number_literal` nodes: +A _query_ consists of one or more _patterns_, where each pattern is an [S-expression][s-exp] that matches a certain set +of nodes in a syntax tree. The expression to match a given node consists of a pair of parentheses containing two things: +the node's type, and optionally, a series of other S-expressions that match the node's children. For example, this pattern +would match any `binary_expression` node whose children are both `number_literal` nodes: ```query (binary_expression (number_literal) (number_literal)) @@ -99,10 +99,10 @@ by `(ERROR)` queries. Specific missing node types can also be queried: ### Supertype Nodes Some node types are marked as _supertypes_ in a grammar. A supertype is a node type that contains multiple -subtypes. For example, in the [JavaScript grammar example][grammar], `expression` is a supertype that can represent any kind -of expression, such as a `binary_expression`, `call_expression`, or `identifier`. You can use supertypes in queries to match -any of their subtypes, rather than having to list out each subtype individually. For example, this pattern would match any -kind of expression, even though it's not a visible node in the syntax tree: +subtypes. For example, in the [JavaScript grammar example][grammar], `expression` is a supertype that can represent any +kind of expression, such as a `binary_expression`, `call_expression`, or `identifier`. You can use supertypes in queries +to match any of their subtypes, rather than having to list out each subtype individually. For example, this pattern would +match any kind of expression, even though it's not a visible node in the syntax tree: ```query (expression) @any-expression diff --git a/docs/src/using-parsers/queries/3-predicates-and-directives.md b/docs/src/using-parsers/queries/3-predicates-and-directives.md index 88e01e01..1f9aeada 100644 --- a/docs/src/using-parsers/queries/3-predicates-and-directives.md +++ b/docs/src/using-parsers/queries/3-predicates-and-directives.md @@ -128,15 +128,15 @@ This pattern would match any builtin variable that is not a local variable, beca # Directives -Similar to predicates, directives are a way to associate arbitrary metadata with a pattern. The only difference between predicates -and directives is that directives end in a `!` character instead of `?` character. +Similar to predicates, directives are a way to associate arbitrary metadata with a pattern. The only difference between +predicates and directives is that directives end in a `!` character instead of `?` character. Tree-sitter's CLI supports the following directives by default: ## The `set!` directive -This directive allows you to associate key-value pairs with a pattern. The key and value can be any arbitrary text that you -see fit. +This directive allows you to associate key-value pairs with a pattern. The key and value can be any arbitrary text that +you see fit. ```query ((comment) @injection.content @@ -156,8 +156,8 @@ another capture are preserved. It takes two arguments, both of which are capture ### The `#strip!` directive The `#strip!` directive allows you to remove text from a capture. It takes two arguments: the first is the capture to strip -text from, and the second is a regular expression to match against the text. Any text matched by the regular expression will -be removed from the text associated with the capture. +text from, and the second is a regular expression to match against the text. Any text matched by the regular expression +will be removed from the text associated with the capture. For an example on the `#select-adjacent!` and `#strip!` directives, view the [code navigation](../../4-code-navigation.md#examples) documentation. From 5808350bfee9891583394c642e8f257ce3c73539 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Thu, 15 Jan 2026 04:30:55 -0500 Subject: [PATCH 131/140] fix(docs): appease clippy regarding spacing in README --- crates/cli/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/cli/README.md b/crates/cli/README.md index 54d0ce07..e3ef899e 100644 --- a/crates/cli/README.md +++ b/crates/cli/README.md @@ -36,10 +36,10 @@ The `tree-sitter` binary itself has no dependencies, but specific commands have ### Commands * `generate` - The `tree-sitter generate` command will generate a Tree-sitter parser based on the grammar in the current -working directory. See [the documentation] for more information. + working directory. See [the documentation] for more information. * `test` - The `tree-sitter test` command will run the unit tests for the Tree-sitter parser in the current working directory. -See [the documentation] for more information. + See [the documentation] for more information. * `parse` - The `tree-sitter parse` command will parse a file (or list of files) using Tree-sitter parsers. From 5d290a2a75fc05bb9c7e6758d9f125cadf3834c2 Mon Sep 17 00:00:00 2001 From: Christian Clason Date: Thu, 15 Jan 2026 10:35:32 +0100 Subject: [PATCH 132/140] fix(wasm): regenerate stdlib with wasm-opt Problem: Output of `cargo xtask build-wasm-stdlib` depends on whether `wasm-opt` is installed (since `clang` will use it by default if it finds it). Solution: Install it and rerun the xtask. --- lib/src/wasm/wasm-stdlib.h | 2282 +++++++++++++++++------------------- 1 file changed, 1076 insertions(+), 1206 deletions(-) diff --git a/lib/src/wasm/wasm-stdlib.h b/lib/src/wasm/wasm-stdlib.h index a8f55df8..082ef4c2 100644 --- a/lib/src/wasm/wasm-stdlib.h +++ b/lib/src/wasm/wasm-stdlib.h @@ -1,1013 +1,942 @@ unsigned char STDLIB_WASM[] = { - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x06, 0x60, + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x1a, 0x05, 0x60, + 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, - 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x60, 0x00, 0x01, 0x7f, 0x60, 0x03, 0x7f, - 0x7f, 0x7f, 0x01, 0x7f, 0x02, 0x9e, 0x01, 0x05, 0x03, 0x65, 0x6e, 0x76, - 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x65, - 0x6e, 0x76, 0x19, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x5f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x01, 0x70, 0x00, 0x01, 0x16, 0x77, 0x61, 0x73, - 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, - 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73, - 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, - 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, - 0x76, 0x69, 0x65, 0x77, 0x31, 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, 0x00, 0x16, 0x77, - 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, - 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72, - 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x00, 0x01, 0x03, 0x2b, 0x2a, - 0x02, 0x00, 0x02, 0x02, 0x01, 0x03, 0x01, 0x00, 0x00, 0x01, 0x04, 0x00, - 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x05, 0x05, 0x00, 0x03, 0x00, - 0x03, 0x05, 0x03, 0x05, 0x05, 0x03, 0x05, 0x03, 0x03, 0x03, 0x05, 0x05, - 0x05, 0x03, 0x03, 0x00, 0x03, 0x03, 0x06, 0x0d, 0x02, 0x7f, 0x01, 0x41, - 0x80, 0x80, 0x04, 0x0b, 0x7f, 0x00, 0x41, 0x00, 0x0b, 0x07, 0xad, 0x02, - 0x1c, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, - 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, 0x03, 0x0f, 0x5f, 0x5f, - 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x06, - 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x00, - 0x07, 0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x08, 0x04, 0x66, - 0x72, 0x65, 0x65, 0x00, 0x09, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x6f, 0x63, - 0x00, 0x0a, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x0b, - 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x00, 0x14, 0x08, 0x69, 0x73, - 0x77, 0x61, 0x6c, 0x6e, 0x75, 0x6d, 0x00, 0x2c, 0x08, 0x69, 0x73, 0x77, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x15, 0x08, 0x69, 0x73, 0x77, 0x62, - 0x6c, 0x61, 0x6e, 0x6b, 0x00, 0x23, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, - 0x67, 0x69, 0x74, 0x00, 0x24, 0x08, 0x69, 0x73, 0x77, 0x6c, 0x6f, 0x77, - 0x65, 0x72, 0x00, 0x20, 0x08, 0x69, 0x73, 0x77, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x00, 0x2b, 0x08, 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, - 0x00, 0x1d, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, 0x69, 0x67, 0x69, 0x74, - 0x00, 0x28, 0x08, 0x74, 0x6f, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, - 0x19, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x00, 0x1b, - 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72, 0x00, 0x17, 0x06, 0x6d, 0x65, - 0x6d, 0x63, 0x6d, 0x70, 0x00, 0x16, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, - 0x79, 0x00, 0x21, 0x07, 0x6d, 0x65, 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x00, - 0x1e, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, 0x74, 0x00, 0x1f, 0x06, 0x73, - 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x18, 0x07, 0x73, 0x74, 0x72, 0x6e, - 0x63, 0x61, 0x74, 0x00, 0x25, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, - 0x70, 0x00, 0x1c, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x70, 0x79, 0x00, - 0x27, 0x08, 0x01, 0x05, 0x0a, 0xb0, 0x30, 0x2a, 0x02, 0x00, 0x0b, 0x03, - 0x00, 0x00, 0x0b, 0x0e, 0x00, 0x41, 0xec, 0xc2, 0x04, 0x41, 0x00, 0x41, - 0x84, 0x01, 0xfc, 0x0b, 0x00, 0x0b, 0x57, 0x01, 0x01, 0x7f, 0x02, 0x40, - 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, - 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, - 0x80, 0x00, 0x41, 0xec, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x41, 0x01, 0x36, - 0x02, 0x00, 0x10, 0x91, 0x80, 0x80, 0x80, 0x00, 0x10, 0x83, 0x80, 0x80, - 0x80, 0x00, 0x10, 0x8d, 0x80, 0x80, 0x80, 0x00, 0x21, 0x00, 0x10, 0x93, - 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x0d, 0x01, 0x0f, 0x0b, 0x00, 0x0b, - 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x49, 0x01, - 0x01, 0x7f, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x41, 0xf4, - 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, - 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x00, 0x36, 0x02, 0x00, - 0x3f, 0x00, 0x21, 0x00, 0x20, 0x01, 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, - 0x6a, 0x41, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0xf8, 0xc2, 0x84, - 0x80, 0x00, 0x6a, 0x20, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, - 0xae, 0x02, 0x01, 0x04, 0x7f, 0x41, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, - 0x00, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, - 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, 0x02, - 0x45, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x20, - 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x21, - 0x04, 0x0c, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x02, 0x28, 0x02, 0x04, 0x22, - 0x04, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x21, 0x03, 0x20, 0x04, 0x21, 0x02, - 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, 0x00, 0x0b, 0x0b, - 0x20, 0x04, 0x28, 0x02, 0x04, 0x21, 0x02, 0x02, 0x40, 0x02, 0x40, 0x20, - 0x03, 0x0d, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xfc, 0xc2, - 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, - 0x20, 0x03, 0x20, 0x02, 0x36, 0x02, 0x04, 0x0b, 0x20, 0x04, 0x41, 0x08, - 0x6a, 0x0f, 0x0b, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x22, - 0x02, 0x41, 0xf8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, - 0x02, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x22, - 0x04, 0x41, 0x08, 0x6a, 0x22, 0x03, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, - 0x41, 0x7c, 0x71, 0x22, 0x02, 0x4f, 0x0d, 0x00, 0x20, 0x02, 0x23, 0x81, - 0x80, 0x80, 0x80, 0x00, 0x41, 0xf0, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x28, - 0x02, 0x00, 0x6b, 0x41, 0x80, 0x80, 0x80, 0x02, 0x4a, 0x0d, 0x01, 0x20, - 0x00, 0x41, 0x7f, 0x6a, 0x41, 0x10, 0x76, 0x41, 0x01, 0x6a, 0x40, 0x00, - 0x41, 0x7f, 0x46, 0x0d, 0x01, 0x3f, 0x00, 0x21, 0x01, 0x23, 0x81, 0x80, - 0x80, 0x80, 0x00, 0x41, 0xf8, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x01, - 0x41, 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x04, 0x20, 0x00, 0x36, - 0x02, 0x00, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, 0x84, - 0x80, 0x00, 0x6a, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x03, 0x21, 0x01, - 0x0b, 0x20, 0x01, 0x0b, 0x5c, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x20, 0x00, - 0x45, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x78, 0x6a, 0x22, 0x01, 0x28, 0x02, - 0x00, 0x21, 0x02, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, - 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x22, 0x03, 0x28, 0x02, 0x00, 0x20, - 0x00, 0x20, 0x02, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x46, 0x0d, - 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, - 0x41, 0xfc, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x22, 0x03, 0x28, 0x02, 0x00, - 0x36, 0x02, 0x00, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x36, 0x02, 0x00, 0x0b, - 0x0b, 0x24, 0x00, 0x20, 0x01, 0x20, 0x00, 0x6c, 0x22, 0x00, 0x10, 0x88, - 0x80, 0x80, 0x80, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, - 0x00, 0x20, 0x01, 0x41, 0x00, 0x20, 0x00, 0xfc, 0x0b, 0x00, 0x0b, 0x20, - 0x01, 0x0b, 0x79, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, - 0x00, 0x20, 0x00, 0x41, 0x78, 0x6a, 0x22, 0x02, 0x28, 0x02, 0x00, 0x21, - 0x03, 0x02, 0x40, 0x23, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, - 0x84, 0x80, 0x00, 0x6a, 0x28, 0x02, 0x00, 0x20, 0x00, 0x20, 0x03, 0x6a, - 0x41, 0x03, 0x6a, 0x41, 0x7c, 0x71, 0x47, 0x0d, 0x00, 0x23, 0x81, 0x80, - 0x80, 0x80, 0x00, 0x41, 0xf4, 0xc2, 0x84, 0x80, 0x00, 0x6a, 0x20, 0x02, - 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80, 0x80, - 0x80, 0x00, 0x21, 0x01, 0x02, 0x40, 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, - 0x02, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x20, 0x00, 0x20, 0x02, 0xfc, 0x0a, - 0x00, 0x00, 0x0b, 0x20, 0x01, 0x0f, 0x0b, 0x20, 0x01, 0x10, 0x88, 0x80, - 0x80, 0x80, 0x00, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x90, 0x80, 0x80, - 0x80, 0x00, 0x00, 0x0b, 0xd5, 0x01, 0x01, 0x03, 0x7f, 0x23, 0x80, 0x80, - 0x80, 0x80, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x80, 0x80, 0x80, - 0x80, 0x00, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, - 0x20, 0x00, 0x41, 0x08, 0x6a, 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, 0x8f, - 0x80, 0x80, 0x80, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x28, 0x02, 0x08, 0x41, - 0x01, 0x6a, 0x22, 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x28, 0x02, 0x0c, - 0x10, 0x88, 0x80, 0x80, 0x80, 0x00, 0x22, 0x02, 0x45, 0x0d, 0x02, 0x20, - 0x01, 0x41, 0x04, 0x10, 0x8a, 0x80, 0x80, 0x80, 0x00, 0x22, 0x01, 0x45, - 0x0d, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x8e, 0x80, 0x80, 0x80, 0x00, - 0x0d, 0x04, 0x20, 0x00, 0x28, 0x02, 0x08, 0x20, 0x01, 0x10, 0x84, 0x80, - 0x80, 0x80, 0x00, 0x21, 0x01, 0x20, 0x00, 0x41, 0x10, 0x6a, 0x24, 0x80, - 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x0f, 0x0b, 0x41, 0xc7, 0x00, 0x10, - 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, - 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, - 0x80, 0x80, 0x00, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, - 0x00, 0x41, 0xc6, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, 0x00, 0x00, 0x0b, - 0x20, 0x02, 0x10, 0x89, 0x80, 0x80, 0x80, 0x00, 0x20, 0x01, 0x10, 0x89, - 0x80, 0x80, 0x80, 0x00, 0x41, 0xc7, 0x00, 0x10, 0x8c, 0x80, 0x80, 0x80, - 0x00, 0x00, 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x10, 0x80, 0x80, - 0x80, 0x80, 0x00, 0x41, 0xff, 0xff, 0x03, 0x71, 0x0b, 0x11, 0x00, 0x20, - 0x00, 0x20, 0x01, 0x10, 0x81, 0x80, 0x80, 0x80, 0x00, 0x41, 0xff, 0xff, - 0x03, 0x71, 0x0b, 0x0b, 0x00, 0x20, 0x00, 0x10, 0x82, 0x80, 0x80, 0x80, - 0x00, 0x00, 0x0b, 0xdf, 0x01, 0x01, 0x02, 0x7f, 0x41, 0x00, 0x41, 0x84, - 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, - 0x80, 0x80, 0x84, 0x80, 0x00, 0x21, 0x00, 0x02, 0x40, 0x02, 0x40, 0x41, - 0x80, 0x80, 0x84, 0x80, 0x00, 0x45, 0x0d, 0x00, 0x41, 0x80, 0x80, 0x84, - 0x80, 0x00, 0x41, 0x80, 0x80, 0x80, 0x80, 0x00, 0x6b, 0x21, 0x01, 0x0c, - 0x01, 0x0b, 0x23, 0x80, 0x80, 0x80, 0x80, 0x00, 0x21, 0x01, 0x41, 0xf0, - 0xc3, 0x84, 0x80, 0x00, 0x41, 0xf0, 0xc3, 0x84, 0x80, 0x00, 0x6b, 0x41, - 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x01, 0x41, 0x80, 0x80, 0x84, 0x80, - 0x00, 0x4b, 0x22, 0x00, 0x1b, 0x21, 0x01, 0x41, 0xf0, 0xc3, 0x84, 0x80, - 0x00, 0x41, 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x00, 0x1b, 0x21, 0x00, - 0x0b, 0x41, 0x38, 0x41, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, - 0x41, 0x34, 0x20, 0x01, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, - 0x30, 0x20, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, 0x08, - 0x41, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, - 0x00, 0x41, 0x04, 0x41, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, - 0xc3, 0x84, 0x80, 0x00, 0x41, 0x0c, 0x41, 0x00, 0x28, 0x02, 0x80, 0xc3, - 0x84, 0x80, 0x00, 0x36, 0x02, 0x84, 0xc3, 0x84, 0x80, 0x00, 0x41, 0x00, - 0x20, 0x01, 0x41, 0x80, 0x80, 0x80, 0x04, 0x20, 0x01, 0x41, 0x80, 0x80, - 0x80, 0x04, 0x49, 0x1b, 0x36, 0x02, 0xe8, 0xc2, 0x84, 0x80, 0x00, 0x0b, - 0x02, 0x00, 0x0b, 0x0e, 0x00, 0x10, 0x92, 0x80, 0x80, 0x80, 0x00, 0x10, - 0x92, 0x80, 0x80, 0x80, 0x00, 0x0b, 0xcf, 0x01, 0x01, 0x03, 0x7f, 0x20, - 0x00, 0x21, 0x01, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, - 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x0d, 0x00, - 0x20, 0x00, 0x20, 0x00, 0x6b, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, + 0x02, 0x7c, 0x04, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, + 0x77, 0x31, 0x08, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67, 0x65, 0x74, 0x00, + 0x02, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, + 0x0e, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, + 0x67, 0x65, 0x74, 0x00, 0x02, 0x16, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, + 0x69, 0x65, 0x77, 0x31, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, + 0x69, 0x74, 0x00, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x06, 0x6d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x02, 0x00, 0x02, 0x03, 0x1f, 0x1e, 0x04, 0x04, 0x04, + 0x03, 0x00, 0x03, 0x02, 0x02, 0x03, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x06, 0x08, 0x01, 0x7f, 0x01, 0x41, 0x80, 0x80, 0x04, + 0x0b, 0x07, 0xad, 0x02, 0x1c, 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x00, + 0x03, 0x0f, 0x5f, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x03, 0x00, 0x06, 0x5f, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x00, 0x05, 0x0a, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x68, + 0x65, 0x61, 0x70, 0x00, 0x06, 0x06, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, + 0x00, 0x07, 0x04, 0x66, 0x72, 0x65, 0x65, 0x00, 0x08, 0x06, 0x63, 0x61, + 0x6c, 0x6c, 0x6f, 0x63, 0x00, 0x09, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x00, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x00, + 0x0c, 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x6e, 0x75, 0x6d, 0x00, 0x20, + 0x08, 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x00, 0x0d, 0x08, + 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x00, 0x1a, 0x08, 0x69, + 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, 0x00, 0x1b, 0x08, 0x69, 0x73, + 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x00, 0x18, 0x08, 0x69, 0x73, 0x77, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x00, 0x1f, 0x08, 0x69, 0x73, 0x77, 0x75, + 0x70, 0x70, 0x65, 0x72, 0x00, 0x15, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, + 0x69, 0x67, 0x69, 0x74, 0x00, 0x1e, 0x08, 0x74, 0x6f, 0x77, 0x6c, 0x6f, + 0x77, 0x65, 0x72, 0x00, 0x11, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, + 0x65, 0x72, 0x00, 0x13, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72, 0x00, + 0x0f, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x6d, 0x70, 0x00, 0x0e, 0x06, 0x6d, + 0x65, 0x6d, 0x63, 0x70, 0x79, 0x00, 0x19, 0x07, 0x6d, 0x65, 0x6d, 0x6d, + 0x6f, 0x76, 0x65, 0x00, 0x16, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, 0x74, + 0x00, 0x17, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x00, 0x10, 0x07, + 0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x00, 0x1c, 0x07, 0x73, 0x74, + 0x72, 0x6e, 0x63, 0x6d, 0x70, 0x00, 0x14, 0x07, 0x73, 0x74, 0x72, 0x6e, + 0x63, 0x70, 0x79, 0x00, 0x1d, 0x08, 0x01, 0x04, 0x0c, 0x01, 0x02, 0x0a, + 0x8d, 0x2a, 0x1e, 0x02, 0x00, 0x0b, 0x0e, 0x00, 0x41, 0xec, 0xc2, 0x04, + 0x41, 0x00, 0x41, 0x84, 0x01, 0xfc, 0x0b, 0x00, 0x0b, 0xfd, 0x01, 0x01, + 0x03, 0x7f, 0x41, 0xec, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x45, 0x04, 0x40, + 0x41, 0xec, 0xc2, 0x04, 0x41, 0x01, 0x36, 0x02, 0x00, 0x41, 0x84, 0xc3, + 0x04, 0x41, 0x84, 0xc3, 0x04, 0x36, 0x02, 0x00, 0x41, 0xbc, 0xc3, 0x04, + 0x41, 0x00, 0x36, 0x02, 0x00, 0x41, 0xb8, 0xc3, 0x04, 0x41, 0x80, 0x80, + 0x04, 0x36, 0x02, 0x00, 0x41, 0xb4, 0xc3, 0x04, 0x41, 0x80, 0x80, 0x04, + 0x36, 0x02, 0x00, 0x41, 0x8c, 0xc3, 0x04, 0x41, 0x84, 0xc3, 0x04, 0x36, + 0x02, 0x00, 0x41, 0x88, 0xc3, 0x04, 0x41, 0x84, 0xc3, 0x04, 0x36, 0x02, + 0x00, 0x41, 0x90, 0xc3, 0x04, 0x41, 0x80, 0xc3, 0x04, 0x28, 0x02, 0x00, + 0x36, 0x02, 0x00, 0x41, 0xe8, 0xc2, 0x04, 0x41, 0x80, 0x80, 0x04, 0x36, + 0x02, 0x00, 0x23, 0x00, 0x41, 0x10, 0x6b, 0x22, 0x00, 0x24, 0x00, 0x02, + 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x08, 0x6a, + 0x20, 0x00, 0x41, 0x0c, 0x6a, 0x10, 0x01, 0x41, 0xff, 0xff, 0x03, 0x71, + 0x45, 0x04, 0x40, 0x20, 0x00, 0x28, 0x02, 0x08, 0x41, 0x01, 0x6a, 0x22, + 0x01, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x28, 0x02, 0x0c, 0x10, 0x07, 0x22, + 0x02, 0x45, 0x0d, 0x02, 0x20, 0x01, 0x41, 0x04, 0x10, 0x09, 0x22, 0x01, + 0x45, 0x0d, 0x03, 0x20, 0x01, 0x20, 0x02, 0x10, 0x00, 0x41, 0xff, 0xff, + 0x03, 0x71, 0x0d, 0x04, 0x20, 0x00, 0x28, 0x02, 0x08, 0x00, 0x0b, 0x41, + 0xc7, 0x00, 0x10, 0x0b, 0x00, 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x0b, 0x00, + 0x0b, 0x41, 0xc6, 0x00, 0x10, 0x0b, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x08, + 0x41, 0xc6, 0x00, 0x10, 0x0b, 0x00, 0x0b, 0x20, 0x02, 0x10, 0x08, 0x20, + 0x01, 0x10, 0x08, 0x41, 0xc7, 0x00, 0x10, 0x0b, 0x00, 0x0b, 0x00, 0x0b, + 0x35, 0x01, 0x01, 0x7f, 0x41, 0xf4, 0xc2, 0x04, 0x20, 0x00, 0x36, 0x02, + 0x00, 0x41, 0xf0, 0xc2, 0x04, 0x20, 0x00, 0x36, 0x02, 0x00, 0x3f, 0x00, + 0x21, 0x00, 0x20, 0x01, 0x41, 0xfc, 0xc2, 0x04, 0x6a, 0x41, 0x00, 0x36, + 0x02, 0x00, 0x20, 0x01, 0x41, 0xf8, 0xc2, 0x04, 0x6a, 0x20, 0x00, 0x41, + 0x10, 0x74, 0x36, 0x02, 0x00, 0x0b, 0xde, 0x01, 0x01, 0x04, 0x7f, 0x02, + 0x40, 0x20, 0x00, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x41, 0xfc, 0xc2, 0x04, + 0x28, 0x02, 0x00, 0x22, 0x01, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x00, + 0x20, 0x01, 0x28, 0x02, 0x00, 0x4d, 0x04, 0x40, 0x20, 0x01, 0x21, 0x02, + 0x0c, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x01, 0x28, 0x02, 0x04, 0x22, 0x02, + 0x45, 0x0d, 0x02, 0x20, 0x01, 0x21, 0x03, 0x20, 0x02, 0x22, 0x01, 0x28, + 0x02, 0x00, 0x20, 0x00, 0x49, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x28, + 0x02, 0x04, 0x21, 0x00, 0x02, 0x40, 0x20, 0x03, 0x45, 0x04, 0x40, 0x41, + 0xfc, 0xc2, 0x04, 0x20, 0x00, 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, + 0x03, 0x20, 0x00, 0x36, 0x02, 0x04, 0x0b, 0x20, 0x02, 0x41, 0x08, 0x6a, + 0x0f, 0x0b, 0x41, 0xf4, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x22, 0x03, 0x41, + 0x08, 0x6a, 0x22, 0x01, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, 0x41, 0x7c, + 0x71, 0x22, 0x02, 0x41, 0xf8, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x4b, 0x04, + 0x40, 0x20, 0x02, 0x41, 0xf0, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x6b, 0x41, + 0x80, 0x80, 0x80, 0x02, 0x4a, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6b, + 0x41, 0x10, 0x76, 0x41, 0x01, 0x6a, 0x40, 0x00, 0x41, 0x7f, 0x46, 0x0d, + 0x01, 0x41, 0xf8, 0xc2, 0x04, 0x3f, 0x00, 0x41, 0x10, 0x74, 0x36, 0x02, + 0x00, 0x0b, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x00, 0x41, 0xf4, 0xc2, + 0x04, 0x20, 0x02, 0x36, 0x02, 0x00, 0x20, 0x01, 0x21, 0x04, 0x0b, 0x20, + 0x04, 0x0b, 0x41, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x04, 0x40, 0x41, 0xf4, + 0xc2, 0x04, 0x22, 0x01, 0x28, 0x02, 0x00, 0x20, 0x00, 0x41, 0x08, 0x6b, + 0x22, 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, 0x41, + 0x7c, 0x71, 0x47, 0x04, 0x40, 0x20, 0x00, 0x41, 0x04, 0x6b, 0x41, 0xfc, + 0xc2, 0x04, 0x22, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x0b, 0x20, + 0x01, 0x20, 0x02, 0x36, 0x02, 0x00, 0x0b, 0x0b, 0x1d, 0x00, 0x20, 0x00, + 0x20, 0x01, 0x6c, 0x22, 0x00, 0x10, 0x07, 0x21, 0x01, 0x20, 0x00, 0x04, + 0x40, 0x20, 0x01, 0x41, 0x00, 0x20, 0x00, 0xfc, 0x0b, 0x00, 0x0b, 0x20, + 0x01, 0x0b, 0x56, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20, 0x00, 0x45, 0x0d, + 0x00, 0x41, 0xf4, 0xc2, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x41, 0x08, + 0x6b, 0x22, 0x02, 0x28, 0x02, 0x00, 0x20, 0x00, 0x6a, 0x41, 0x03, 0x6a, + 0x41, 0x7c, 0x71, 0x46, 0x04, 0x40, 0x41, 0xf4, 0xc2, 0x04, 0x20, 0x02, + 0x36, 0x02, 0x00, 0x0c, 0x01, 0x0b, 0x20, 0x01, 0x10, 0x07, 0x21, 0x01, + 0x20, 0x02, 0x28, 0x02, 0x00, 0x22, 0x02, 0x04, 0x40, 0x20, 0x01, 0x20, + 0x00, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x0b, 0x20, 0x01, 0x0f, 0x0b, + 0x20, 0x01, 0x10, 0x07, 0x0b, 0x07, 0x00, 0x20, 0x00, 0x10, 0x02, 0x00, + 0x0b, 0xc5, 0x01, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, - 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x01, 0x41, - 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, - 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, - 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, - 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x0d, 0x01, 0x0b, 0x20, - 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x7b, 0x6a, 0x21, - 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x41, 0x80, - 0x82, 0x84, 0x08, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x28, 0x02, - 0x00, 0x22, 0x03, 0x6b, 0x20, 0x03, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, - 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x46, 0x0d, 0x00, 0x0b, - 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x2d, - 0x00, 0x00, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x21, 0x02, 0x20, - 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b, 0x0b, 0x3e, - 0x00, 0x02, 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, - 0x20, 0x00, 0x41, 0x08, 0x76, 0x2d, 0x00, 0x80, 0x80, 0x84, 0x80, 0x00, - 0x41, 0x05, 0x74, 0x20, 0x00, 0x41, 0x03, 0x76, 0x41, 0x1f, 0x71, 0x72, - 0x2d, 0x00, 0x80, 0x80, 0x84, 0x80, 0x00, 0x20, 0x00, 0x41, 0x07, 0x71, - 0x76, 0x41, 0x01, 0x71, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0xfe, 0xff, 0x0b, - 0x49, 0x0b, 0x49, 0x01, 0x03, 0x7f, 0x41, 0x00, 0x21, 0x03, 0x02, 0x40, - 0x20, 0x02, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x03, 0x40, 0x20, 0x00, 0x2d, - 0x00, 0x00, 0x22, 0x04, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x47, - 0x0d, 0x01, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, - 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, - 0x00, 0x0c, 0x02, 0x0b, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, - 0x0b, 0x20, 0x03, 0x0b, 0xf6, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, - 0x00, 0x47, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, - 0x20, 0x00, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, - 0x00, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, - 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, - 0x05, 0x0c, 0x03, 0x0b, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x05, 0x41, - 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x04, 0x41, - 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, - 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, - 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, - 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, - 0x01, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, - 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x7d, - 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, - 0x6a, 0x22, 0x04, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x05, 0x45, - 0x0d, 0x01, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, - 0x71, 0x46, 0x0d, 0x02, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, - 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x03, 0x0c, - 0x01, 0x0b, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x04, 0x0b, 0x20, - 0x03, 0x45, 0x0d, 0x01, 0x02, 0x40, 0x20, 0x04, 0x2d, 0x00, 0x00, 0x20, - 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x00, 0x20, 0x05, 0x41, 0x04, - 0x49, 0x0d, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x41, 0x81, 0x82, - 0x84, 0x08, 0x6c, 0x21, 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, - 0x20, 0x04, 0x28, 0x02, 0x00, 0x20, 0x00, 0x73, 0x22, 0x02, 0x6b, 0x20, - 0x02, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, - 0x82, 0x84, 0x78, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, - 0x04, 0x20, 0x05, 0x41, 0x7c, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, - 0x00, 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, - 0xff, 0x01, 0x71, 0x21, 0x02, 0x03, 0x40, 0x02, 0x40, 0x20, 0x04, 0x2d, - 0x00, 0x00, 0x20, 0x02, 0x47, 0x0d, 0x00, 0x20, 0x04, 0x0f, 0x0b, 0x20, - 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x7f, 0x6a, 0x22, - 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x41, 0x00, 0x0b, 0x67, 0x01, 0x02, 0x7f, - 0x20, 0x01, 0x2d, 0x00, 0x00, 0x21, 0x02, 0x02, 0x40, 0x20, 0x00, 0x2d, - 0x00, 0x00, 0x22, 0x03, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x02, 0x41, - 0xff, 0x01, 0x71, 0x47, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, - 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, - 0x2d, 0x00, 0x00, 0x21, 0x02, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x03, - 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x01, - 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x20, 0x02, 0x41, 0xff, 0x01, - 0x71, 0x46, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x03, 0x20, 0x02, 0x41, 0xff, - 0x01, 0x71, 0x6b, 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x10, 0x9a, - 0x80, 0x80, 0x80, 0x00, 0x0b, 0xa6, 0x02, 0x01, 0x07, 0x7f, 0x02, 0x40, - 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x20, 0x00, 0x20, - 0x00, 0x41, 0xff, 0x01, 0x71, 0x22, 0x02, 0x41, 0x03, 0x6e, 0x22, 0x03, - 0x41, 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71, 0x41, 0x02, 0x74, 0x28, - 0x02, 0xc0, 0x9e, 0x84, 0x80, 0x00, 0x20, 0x00, 0x41, 0x08, 0x76, 0x22, - 0x04, 0x2d, 0x00, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x41, 0xd6, 0x00, 0x6c, - 0x20, 0x03, 0x6a, 0x2d, 0x00, 0xa0, 0xa9, 0x84, 0x80, 0x00, 0x6c, 0x41, - 0x0b, 0x76, 0x41, 0x06, 0x70, 0x20, 0x04, 0x2d, 0x00, 0x90, 0xbe, 0x84, - 0x80, 0x00, 0x6a, 0x41, 0x02, 0x74, 0x28, 0x02, 0xd0, 0x9e, 0x84, 0x80, - 0x00, 0x22, 0x03, 0x41, 0x08, 0x75, 0x21, 0x04, 0x02, 0x40, 0x20, 0x03, - 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, - 0x04, 0x41, 0x00, 0x20, 0x03, 0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, 0x00, - 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x45, - 0x0d, 0x00, 0x20, 0x04, 0x41, 0x08, 0x76, 0x21, 0x04, 0x03, 0x40, 0x02, - 0x40, 0x20, 0x02, 0x20, 0x03, 0x41, 0x01, 0x76, 0x22, 0x05, 0x20, 0x04, - 0x6a, 0x22, 0x06, 0x41, 0x01, 0x74, 0x22, 0x07, 0x2d, 0x00, 0x90, 0xa6, - 0x84, 0x80, 0x00, 0x22, 0x08, 0x47, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x07, - 0x41, 0x90, 0xa6, 0x84, 0x80, 0x00, 0x6a, 0x2d, 0x00, 0x01, 0x41, 0x02, - 0x74, 0x28, 0x02, 0xd0, 0x9e, 0x84, 0x80, 0x00, 0x22, 0x03, 0x41, 0xff, - 0x01, 0x71, 0x22, 0x04, 0x41, 0x01, 0x4b, 0x0d, 0x00, 0x20, 0x03, 0x41, - 0x08, 0x75, 0x41, 0x00, 0x20, 0x04, 0x20, 0x01, 0x73, 0x6b, 0x71, 0x20, - 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, 0x01, 0x20, 0x01, 0x1b, 0x20, - 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x20, 0x02, 0x20, 0x08, - 0x49, 0x22, 0x08, 0x1b, 0x21, 0x04, 0x20, 0x05, 0x20, 0x03, 0x20, 0x05, - 0x6b, 0x20, 0x08, 0x1b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, - 0x0b, 0x0c, 0x00, 0x20, 0x00, 0x41, 0x01, 0x10, 0x9a, 0x80, 0x80, 0x80, - 0x00, 0x0b, 0x87, 0x01, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x0d, - 0x00, 0x41, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x2d, - 0x00, 0x00, 0x22, 0x03, 0x0d, 0x00, 0x41, 0x00, 0x21, 0x03, 0x0c, 0x01, - 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x7f, - 0x6a, 0x21, 0x02, 0x02, 0x40, 0x03, 0x40, 0x20, 0x03, 0x41, 0xff, 0x01, - 0x71, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x47, 0x0d, 0x01, 0x20, - 0x04, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x41, 0x00, 0x46, 0x0d, 0x01, 0x20, - 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, + 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x41, 0x01, + 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, + 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x01, + 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, + 0x0d, 0x01, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, + 0x45, 0x0d, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x45, 0x0d, 0x01, 0x20, + 0x00, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x41, 0x03, 0x71, 0x0d, 0x01, 0x0b, + 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x02, 0x20, 0x01, 0x41, 0x05, 0x6b, + 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x41, + 0x80, 0x82, 0x84, 0x08, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x22, 0x02, 0x28, + 0x02, 0x00, 0x22, 0x03, 0x6b, 0x20, 0x03, 0x72, 0x41, 0x80, 0x81, 0x82, + 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x46, 0x0d, 0x00, + 0x0b, 0x03, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, + 0x2d, 0x00, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x21, 0x02, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x01, 0x20, 0x00, 0x6b, 0x0b, 0x38, 0x00, 0x20, 0x00, + 0x41, 0xff, 0xff, 0x07, 0x4d, 0x04, 0x40, 0x20, 0x00, 0x41, 0x03, 0x76, + 0x41, 0x1f, 0x71, 0x20, 0x00, 0x41, 0x08, 0x76, 0x2d, 0x00, 0x80, 0x80, + 0x04, 0x41, 0x05, 0x74, 0x72, 0x2d, 0x00, 0x80, 0x80, 0x04, 0x20, 0x00, + 0x41, 0x07, 0x71, 0x76, 0x41, 0x01, 0x71, 0x0f, 0x0b, 0x20, 0x00, 0x41, + 0xfe, 0xff, 0x0b, 0x49, 0x0b, 0x43, 0x01, 0x03, 0x7f, 0x02, 0x40, 0x20, + 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, + 0x04, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x46, 0x04, 0x40, 0x20, + 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, + 0x00, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x01, 0x0c, 0x02, + 0x0b, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x6b, 0x21, 0x03, 0x0b, 0x20, 0x03, + 0x0b, 0xe9, 0x02, 0x01, 0x03, 0x7f, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, + 0x05, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, + 0x45, 0x20, 0x02, 0x45, 0x72, 0x45, 0x04, 0x40, 0x20, 0x00, 0x2d, 0x00, + 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x04, 0x40, 0x20, 0x00, + 0x21, 0x03, 0x20, 0x02, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x02, 0x41, + 0x01, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, 0x05, 0x20, 0x00, 0x41, + 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x04, 0x45, 0x72, + 0x0d, 0x01, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, + 0x71, 0x46, 0x0d, 0x02, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x04, 0x41, + 0x00, 0x47, 0x21, 0x05, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x22, 0x03, 0x41, + 0x03, 0x71, 0x45, 0x20, 0x04, 0x45, 0x72, 0x0d, 0x01, 0x20, 0x03, 0x2d, + 0x00, 0x00, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, + 0x02, 0x41, 0x03, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, 0x05, 0x20, + 0x00, 0x41, 0x03, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x04, + 0x45, 0x72, 0x0d, 0x01, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x20, 0x01, 0x41, + 0xff, 0x01, 0x71, 0x46, 0x0d, 0x02, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, + 0x03, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x22, 0x04, 0x41, 0x00, 0x47, 0x21, + 0x05, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x21, 0x04, 0x20, 0x00, 0x21, 0x03, + 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x01, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, + 0x22, 0x00, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x46, 0x20, 0x04, 0x41, 0x04, + 0x49, 0x72, 0x45, 0x04, 0x40, 0x20, 0x00, 0x41, 0x81, 0x82, 0x84, 0x08, + 0x6c, 0x21, 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, 0x20, 0x03, + 0x28, 0x02, 0x00, 0x20, 0x00, 0x73, 0x22, 0x02, 0x6b, 0x20, 0x02, 0x72, + 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, + 0x78, 0x47, 0x0d, 0x02, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, + 0x04, 0x41, 0x04, 0x6b, 0x22, 0x04, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, + 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x01, 0x0b, 0x20, 0x01, 0x41, 0xff, 0x01, + 0x71, 0x21, 0x00, 0x03, 0x40, 0x20, 0x00, 0x20, 0x03, 0x2d, 0x00, 0x00, + 0x46, 0x04, 0x40, 0x20, 0x03, 0x0f, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x6a, + 0x21, 0x03, 0x20, 0x04, 0x41, 0x01, 0x6b, 0x22, 0x04, 0x0d, 0x00, 0x0b, + 0x0b, 0x41, 0x00, 0x0b, 0x58, 0x01, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x00, + 0x2d, 0x00, 0x00, 0x22, 0x02, 0x45, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x22, 0x03, 0x47, 0x72, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, + 0x21, 0x00, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x03, 0x40, 0x20, + 0x01, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, + 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, + 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x20, 0x03, 0x46, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x20, 0x03, 0x6b, 0x0b, 0x08, 0x00, 0x20, + 0x00, 0x41, 0x00, 0x10, 0x12, 0x0b, 0x90, 0x02, 0x01, 0x07, 0x7f, 0x02, + 0x40, 0x20, 0x00, 0x41, 0xff, 0xff, 0x07, 0x4b, 0x0d, 0x00, 0x20, 0x00, + 0x20, 0x00, 0x41, 0xff, 0x01, 0x71, 0x22, 0x05, 0x41, 0x03, 0x6e, 0x22, + 0x02, 0x41, 0x03, 0x6c, 0x6b, 0x41, 0xff, 0x01, 0x71, 0x41, 0x02, 0x74, + 0x28, 0x02, 0xc0, 0x9e, 0x04, 0x20, 0x02, 0x20, 0x00, 0x41, 0x08, 0x76, + 0x22, 0x02, 0x2d, 0x00, 0xa0, 0xa9, 0x04, 0x41, 0xd6, 0x00, 0x6c, 0x6a, + 0x2d, 0x00, 0xa0, 0xa9, 0x04, 0x6c, 0x41, 0x0b, 0x76, 0x41, 0x06, 0x70, + 0x20, 0x02, 0x2d, 0x00, 0x90, 0xbe, 0x04, 0x6a, 0x41, 0x02, 0x74, 0x28, + 0x02, 0xd0, 0x9e, 0x04, 0x22, 0x03, 0x41, 0x08, 0x75, 0x21, 0x02, 0x20, + 0x03, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4d, 0x04, 0x40, + 0x20, 0x02, 0x41, 0x00, 0x20, 0x01, 0x20, 0x03, 0x73, 0x6b, 0x71, 0x20, + 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x02, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, + 0x45, 0x0d, 0x00, 0x20, 0x02, 0x41, 0x08, 0x76, 0x21, 0x02, 0x03, 0x40, + 0x20, 0x03, 0x41, 0x01, 0x76, 0x22, 0x06, 0x20, 0x02, 0x6a, 0x22, 0x04, + 0x41, 0x01, 0x74, 0x22, 0x07, 0x2d, 0x00, 0x90, 0xa6, 0x04, 0x22, 0x08, + 0x20, 0x05, 0x46, 0x04, 0x40, 0x20, 0x07, 0x41, 0x90, 0xa6, 0x04, 0x6a, + 0x2d, 0x00, 0x01, 0x41, 0x02, 0x74, 0x28, 0x02, 0xd0, 0x9e, 0x04, 0x22, + 0x02, 0x41, 0xff, 0x01, 0x71, 0x22, 0x03, 0x41, 0x01, 0x4d, 0x04, 0x40, + 0x41, 0x00, 0x20, 0x01, 0x20, 0x03, 0x73, 0x6b, 0x20, 0x02, 0x41, 0x08, + 0x75, 0x71, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x41, 0x7f, 0x41, 0x01, 0x20, + 0x01, 0x1b, 0x20, 0x00, 0x6a, 0x0f, 0x0b, 0x20, 0x02, 0x20, 0x04, 0x20, + 0x05, 0x20, 0x08, 0x49, 0x22, 0x04, 0x1b, 0x21, 0x02, 0x20, 0x06, 0x20, + 0x03, 0x20, 0x06, 0x6b, 0x20, 0x04, 0x1b, 0x22, 0x03, 0x0d, 0x00, 0x0b, + 0x0b, 0x20, 0x00, 0x0b, 0x08, 0x00, 0x20, 0x00, 0x41, 0x01, 0x10, 0x12, + 0x0b, 0x75, 0x01, 0x02, 0x7f, 0x20, 0x02, 0x45, 0x04, 0x40, 0x41, 0x00, + 0x0f, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x22, 0x03, 0x45, + 0x04, 0x40, 0x41, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x41, + 0x01, 0x6a, 0x21, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x21, 0x02, 0x02, + 0x40, 0x03, 0x40, 0x20, 0x02, 0x45, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x22, 0x04, 0x47, 0x20, 0x04, 0x45, 0x72, 0x72, 0x0d, 0x01, 0x20, + 0x02, 0x41, 0x01, 0x6b, 0x21, 0x02, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x00, 0x2d, 0x00, 0x00, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x00, 0x20, 0x03, 0x0d, 0x00, 0x0b, 0x41, 0x00, 0x21, 0x03, - 0x0b, 0x20, 0x03, 0x41, 0xff, 0x01, 0x71, 0x21, 0x03, 0x0b, 0x20, 0x03, - 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, - 0x99, 0x80, 0x80, 0x80, 0x00, 0x20, 0x00, 0x47, 0x0b, 0xb7, 0x0a, 0x01, - 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x21, 0x49, 0x0d, - 0x00, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, - 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x00, 0x20, 0x01, - 0x46, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x01, 0x20, 0x02, 0x20, 0x00, 0x6a, - 0x22, 0x03, 0x6b, 0x41, 0x00, 0x20, 0x02, 0x41, 0x01, 0x74, 0x6b, 0x4b, - 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, - 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x20, 0x01, 0x20, - 0x00, 0x73, 0x41, 0x03, 0x71, 0x21, 0x04, 0x02, 0x40, 0x02, 0x40, 0x02, - 0x40, 0x20, 0x00, 0x20, 0x01, 0x4f, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x04, - 0x45, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, - 0x03, 0x0b, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, - 0x02, 0x21, 0x05, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x20, 0x02, - 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, - 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, - 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, - 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, - 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x02, - 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x02, - 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, - 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x02, 0x41, - 0x7d, 0x6a, 0x21, 0x05, 0x02, 0x40, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x22, - 0x03, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x21, - 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, - 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x41, 0x04, 0x6a, - 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, - 0x7c, 0x6a, 0x21, 0x05, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x04, 0x0d, - 0x00, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, - 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, - 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, - 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, - 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, - 0x20, 0x00, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, - 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, - 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, - 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, - 0x41, 0x7d, 0x6a, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, - 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, - 0x03, 0x71, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, - 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, - 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x20, - 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x06, 0x41, 0x0c, 0x71, 0x41, 0x0c, 0x46, - 0x0d, 0x00, 0x20, 0x06, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x03, - 0x71, 0x21, 0x03, 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, - 0x41, 0x7c, 0x6a, 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, 0x20, 0x02, 0x6a, - 0x20, 0x04, 0x20, 0x02, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, - 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x02, 0x20, 0x03, 0x41, 0x7f, 0x6a, 0x22, - 0x03, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x06, 0x41, 0x0c, 0x49, 0x0d, 0x00, - 0x20, 0x01, 0x41, 0x70, 0x6a, 0x21, 0x05, 0x20, 0x00, 0x41, 0x70, 0x6a, - 0x21, 0x06, 0x03, 0x40, 0x20, 0x06, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, - 0x0c, 0x6a, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x22, 0x04, 0x41, 0x0c, 0x6a, - 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, - 0x04, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, - 0x41, 0x04, 0x6a, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, - 0x02, 0x00, 0x20, 0x03, 0x20, 0x04, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, - 0x20, 0x02, 0x41, 0x70, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, - 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x21, 0x03, 0x02, - 0x40, 0x20, 0x02, 0x41, 0x03, 0x71, 0x22, 0x04, 0x45, 0x0d, 0x00, 0x20, - 0x01, 0x41, 0x7f, 0x6a, 0x21, 0x05, 0x20, 0x00, 0x41, 0x7f, 0x6a, 0x21, - 0x06, 0x20, 0x02, 0x21, 0x03, 0x03, 0x40, 0x20, 0x06, 0x20, 0x03, 0x6a, - 0x20, 0x05, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, - 0x03, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x04, 0x41, 0x7f, 0x6a, 0x22, - 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x02, - 0x20, 0x01, 0x41, 0x7c, 0x6a, 0x21, 0x04, 0x20, 0x00, 0x41, 0x7c, 0x6a, - 0x21, 0x05, 0x03, 0x40, 0x20, 0x05, 0x20, 0x03, 0x6a, 0x22, 0x01, 0x41, - 0x03, 0x6a, 0x20, 0x04, 0x20, 0x03, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x6a, - 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x20, - 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, - 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, - 0x00, 0x00, 0x20, 0x01, 0x20, 0x02, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, - 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x22, 0x03, 0x0d, 0x00, 0x0c, 0x03, 0x0b, - 0x0b, 0x20, 0x05, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x05, - 0x41, 0x7c, 0x6a, 0x22, 0x04, 0x41, 0x1c, 0x71, 0x41, 0x1c, 0x46, 0x0d, - 0x00, 0x20, 0x05, 0x20, 0x04, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, - 0x07, 0x71, 0x22, 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x05, 0x03, 0x40, - 0x20, 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, - 0x41, 0x04, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, - 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x04, 0x41, 0x1c, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, - 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, - 0x01, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, - 0x41, 0x08, 0x6a, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, - 0x02, 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x01, 0x41, 0x0c, 0x6a, - 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x20, - 0x01, 0x41, 0x10, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, - 0x41, 0x14, 0x6a, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x36, - 0x02, 0x00, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, 0x01, 0x41, 0x18, 0x6a, - 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x1c, 0x6a, 0x20, - 0x01, 0x41, 0x1c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, - 0x41, 0x20, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, - 0x20, 0x05, 0x41, 0x60, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x4b, 0x0d, 0x00, - 0x0b, 0x0b, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, - 0x05, 0x41, 0x07, 0x71, 0x22, 0x02, 0x0d, 0x00, 0x20, 0x05, 0x21, 0x04, - 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x78, 0x71, 0x21, 0x04, 0x03, 0x40, - 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, - 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, - 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x05, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, - 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x20, - 0x01, 0x41, 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, - 0x41, 0x02, 0x6a, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, - 0x00, 0x00, 0x20, 0x03, 0x41, 0x03, 0x6a, 0x20, 0x01, 0x41, 0x03, 0x6a, - 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, - 0x01, 0x41, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, - 0x41, 0x05, 0x6a, 0x20, 0x01, 0x41, 0x05, 0x6a, 0x2d, 0x00, 0x00, 0x3a, - 0x00, 0x00, 0x20, 0x03, 0x41, 0x06, 0x6a, 0x20, 0x01, 0x41, 0x06, 0x6a, - 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x07, 0x6a, 0x20, - 0x01, 0x41, 0x07, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, - 0x41, 0x08, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, - 0x20, 0x04, 0x41, 0x78, 0x6a, 0x22, 0x04, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x00, 0x0b, 0x96, 0x03, 0x02, 0x03, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x02, - 0x40, 0x20, 0x02, 0x41, 0x21, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, - 0x01, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0b, 0x00, 0x20, 0x00, - 0x0f, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, - 0x00, 0x00, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x7f, 0x6a, - 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, - 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, - 0x00, 0x01, 0x20, 0x03, 0x41, 0x7d, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, - 0x20, 0x03, 0x41, 0x7e, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, - 0x41, 0x07, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, - 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, - 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, - 0x41, 0x03, 0x71, 0x22, 0x04, 0x6a, 0x22, 0x05, 0x20, 0x01, 0x41, 0xff, - 0x01, 0x71, 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x22, 0x03, 0x36, 0x02, - 0x00, 0x20, 0x05, 0x20, 0x02, 0x20, 0x04, 0x6b, 0x41, 0x3c, 0x71, 0x22, - 0x01, 0x6a, 0x22, 0x02, 0x41, 0x7c, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, - 0x20, 0x01, 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x05, 0x20, 0x03, 0x36, - 0x02, 0x08, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x04, 0x20, 0x02, 0x41, - 0x78, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x74, 0x6a, - 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x19, 0x49, 0x0d, 0x00, - 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x18, 0x20, 0x05, 0x20, 0x03, 0x36, - 0x02, 0x14, 0x20, 0x05, 0x20, 0x03, 0x36, 0x02, 0x10, 0x20, 0x05, 0x20, - 0x03, 0x36, 0x02, 0x0c, 0x20, 0x02, 0x41, 0x70, 0x6a, 0x20, 0x03, 0x36, - 0x02, 0x00, 0x20, 0x02, 0x41, 0x6c, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, - 0x20, 0x02, 0x41, 0x68, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, - 0x41, 0x64, 0x6a, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x20, 0x05, - 0x41, 0x04, 0x71, 0x41, 0x18, 0x72, 0x22, 0x02, 0x6b, 0x22, 0x01, 0x41, - 0x20, 0x49, 0x0d, 0x00, 0x20, 0x03, 0xad, 0x42, 0x81, 0x80, 0x80, 0x80, - 0x10, 0x7e, 0x21, 0x06, 0x20, 0x05, 0x20, 0x02, 0x6a, 0x21, 0x02, 0x03, - 0x40, 0x20, 0x02, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x18, - 0x6a, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x20, - 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x20, 0x06, 0x37, - 0x03, 0x00, 0x20, 0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, - 0x60, 0x6a, 0x22, 0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x10, 0x9b, 0x80, 0x80, 0x80, 0x00, - 0x20, 0x00, 0x47, 0x0b, 0x85, 0x08, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, - 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x20, 0x4b, 0x0d, 0x00, - 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x02, 0x45, 0x0d, - 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, - 0x02, 0x41, 0x7f, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, - 0x04, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, - 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, - 0x00, 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x21, 0x03, - 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x02, 0x6a, - 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, - 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, - 0x02, 0x41, 0x7d, 0x6a, 0x21, 0x03, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x21, - 0x04, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, - 0x0d, 0x02, 0x20, 0x03, 0x45, 0x0d, 0x02, 0x20, 0x00, 0x20, 0x01, 0x2d, - 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x21, 0x03, - 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x01, 0x41, 0x04, 0x6a, - 0x21, 0x05, 0x0c, 0x02, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x00, - 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, - 0x20, 0x02, 0x21, 0x03, 0x20, 0x00, 0x21, 0x04, 0x20, 0x01, 0x21, 0x05, - 0x0b, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x22, 0x02, 0x0d, 0x00, - 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x10, 0x4f, 0x0d, 0x00, 0x20, - 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x70, - 0x6a, 0x22, 0x02, 0x41, 0x10, 0x71, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x05, - 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, - 0x08, 0x37, 0x02, 0x08, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20, - 0x05, 0x41, 0x10, 0x6a, 0x21, 0x05, 0x20, 0x02, 0x21, 0x03, 0x0b, 0x20, - 0x02, 0x41, 0x10, 0x49, 0x0d, 0x00, 0x20, 0x03, 0x21, 0x02, 0x03, 0x40, - 0x20, 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, - 0x41, 0x08, 0x6a, 0x20, 0x05, 0x41, 0x08, 0x6a, 0x29, 0x02, 0x00, 0x37, - 0x02, 0x00, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x20, 0x05, 0x41, 0x10, 0x6a, - 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x41, 0x18, 0x6a, 0x20, - 0x05, 0x41, 0x18, 0x6a, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, - 0x41, 0x20, 0x6a, 0x21, 0x04, 0x20, 0x05, 0x41, 0x20, 0x6a, 0x21, 0x05, - 0x20, 0x02, 0x41, 0x60, 0x6a, 0x22, 0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, - 0x0b, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x41, 0x08, 0x49, 0x0d, 0x00, 0x20, - 0x04, 0x20, 0x05, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x05, 0x41, - 0x08, 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x21, 0x04, 0x0b, - 0x02, 0x40, 0x20, 0x02, 0x41, 0x04, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, - 0x20, 0x05, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x05, 0x41, 0x04, - 0x6a, 0x21, 0x05, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x0b, 0x02, - 0x40, 0x20, 0x02, 0x41, 0x02, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x04, 0x20, - 0x05, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, - 0x21, 0x04, 0x20, 0x05, 0x41, 0x02, 0x6a, 0x21, 0x05, 0x0b, 0x20, 0x02, - 0x41, 0x01, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, - 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, - 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, 0x20, 0x49, 0x0d, - 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x00, 0x22, 0x03, 0x3a, 0x00, - 0x00, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x0e, 0x03, - 0x03, 0x00, 0x01, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x08, 0x76, - 0x3a, 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x06, 0x6a, 0x29, 0x01, - 0x00, 0x37, 0x02, 0x06, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, - 0x10, 0x74, 0x20, 0x03, 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x02, 0x20, - 0x04, 0x41, 0x12, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x12, 0x6a, 0x21, - 0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0e, 0x6a, 0x28, 0x01, - 0x00, 0x21, 0x05, 0x41, 0x0e, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x04, - 0x20, 0x05, 0x41, 0x05, 0x6a, 0x29, 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, - 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, 0x18, 0x74, 0x20, 0x03, 0x41, - 0x08, 0x76, 0x72, 0x36, 0x02, 0x01, 0x20, 0x04, 0x41, 0x11, 0x6a, 0x21, - 0x02, 0x20, 0x05, 0x41, 0x11, 0x6a, 0x21, 0x01, 0x41, 0x0d, 0x21, 0x06, - 0x20, 0x05, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x05, 0x41, 0x0f, - 0x21, 0x03, 0x0c, 0x02, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x20, 0x03, 0x41, - 0x10, 0x4f, 0x0d, 0x00, 0x20, 0x04, 0x21, 0x02, 0x20, 0x05, 0x21, 0x01, - 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x3a, 0x00, - 0x00, 0x20, 0x04, 0x20, 0x05, 0x28, 0x00, 0x01, 0x36, 0x00, 0x01, 0x20, - 0x04, 0x20, 0x05, 0x29, 0x00, 0x05, 0x37, 0x00, 0x05, 0x20, 0x04, 0x20, - 0x05, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20, 0x04, 0x20, 0x05, 0x2d, - 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x02, - 0x20, 0x05, 0x41, 0x10, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x08, - 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x10, - 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x03, 0x41, 0x08, 0x76, 0x3a, - 0x00, 0x01, 0x20, 0x04, 0x20, 0x05, 0x41, 0x07, 0x6a, 0x29, 0x00, 0x00, - 0x37, 0x02, 0x07, 0x20, 0x04, 0x20, 0x05, 0x28, 0x02, 0x04, 0x41, 0x08, - 0x74, 0x20, 0x03, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x03, 0x20, 0x04, - 0x41, 0x13, 0x6a, 0x21, 0x02, 0x20, 0x05, 0x41, 0x13, 0x6a, 0x21, 0x01, - 0x41, 0x0f, 0x21, 0x06, 0x20, 0x05, 0x41, 0x0f, 0x6a, 0x28, 0x00, 0x00, - 0x21, 0x05, 0x41, 0x0d, 0x21, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x06, 0x6a, - 0x20, 0x05, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, - 0x00, 0x37, 0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, - 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, - 0x04, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, - 0x41, 0x04, 0x6a, 0x21, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x03, 0x41, 0x02, - 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, - 0x00, 0x00, 0x20, 0x02, 0x41, 0x02, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, - 0x02, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x03, 0x41, 0x01, 0x71, 0x45, 0x0d, - 0x00, 0x20, 0x02, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, - 0x20, 0x00, 0x0b, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x20, 0x46, 0x20, 0x00, - 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x10, 0xa2, 0x80, - 0x80, 0x80, 0x00, 0x0b, 0x0a, 0x00, 0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, - 0x0a, 0x49, 0x0b, 0x4d, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x20, 0x00, 0x10, - 0x94, 0x80, 0x80, 0x80, 0x00, 0x6a, 0x21, 0x03, 0x02, 0x40, 0x20, 0x02, - 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x04, - 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x03, - 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, - 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, - 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, 0xfa, 0x03, 0x01, - 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, - 0x20, 0x01, 0x20, 0x00, 0x73, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, - 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00, 0x47, 0x21, - 0x04, 0x02, 0x40, 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71, 0x0d, 0x00, - 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x02, 0x40, 0x20, 0x02, 0x0d, - 0x00, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x01, - 0x2d, 0x00, 0x00, 0x22, 0x03, 0x3a, 0x00, 0x00, 0x02, 0x40, 0x20, 0x03, - 0x0d, 0x00, 0x20, 0x00, 0x21, 0x03, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x05, - 0x0b, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7f, - 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, - 0x41, 0x01, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, - 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, - 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, 0x05, 0x20, 0x00, 0x41, - 0x02, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x7e, 0x6a, 0x22, 0x05, 0x41, - 0x00, 0x47, 0x21, 0x04, 0x02, 0x40, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x22, - 0x06, 0x41, 0x03, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, - 0x20, 0x03, 0x20, 0x06, 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, - 0x20, 0x04, 0x45, 0x0d, 0x06, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x21, 0x03, - 0x20, 0x02, 0x41, 0x7d, 0x6a, 0x22, 0x05, 0x41, 0x00, 0x47, 0x21, 0x04, - 0x02, 0x40, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x22, 0x06, 0x41, 0x03, 0x71, - 0x45, 0x0d, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x00, 0x20, 0x03, 0x20, 0x06, - 0x2d, 0x00, 0x00, 0x22, 0x04, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x45, 0x0d, - 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, - 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x00, - 0x47, 0x21, 0x04, 0x0c, 0x03, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, - 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, 0x21, - 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x06, 0x21, 0x01, 0x20, 0x05, 0x21, 0x02, - 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x02, 0x02, 0x40, 0x20, 0x01, 0x2d, 0x00, - 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x04, 0x0b, 0x20, 0x02, - 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x41, 0x80, 0x82, 0x84, 0x08, - 0x20, 0x01, 0x28, 0x02, 0x00, 0x22, 0x00, 0x6b, 0x20, 0x00, 0x72, 0x41, - 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, - 0x47, 0x0d, 0x02, 0x20, 0x03, 0x20, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, + 0x0b, 0x0b, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x6b, 0x0b, 0x09, + 0x00, 0x20, 0x00, 0x10, 0x11, 0x20, 0x00, 0x47, 0x0b, 0x93, 0x0a, 0x01, + 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x20, 0x02, 0x41, 0x21, 0x4f, 0x04, + 0x40, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x00, 0x20, + 0x01, 0x46, 0x0d, 0x00, 0x20, 0x01, 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, + 0x04, 0x6b, 0x41, 0x00, 0x20, 0x02, 0x41, 0x01, 0x74, 0x6b, 0x4d, 0x04, + 0x40, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x00, 0x20, + 0x01, 0x73, 0x41, 0x03, 0x71, 0x21, 0x03, 0x02, 0x40, 0x02, 0x40, 0x20, + 0x00, 0x20, 0x01, 0x49, 0x04, 0x40, 0x20, 0x03, 0x04, 0x40, 0x20, 0x02, + 0x21, 0x04, 0x20, 0x00, 0x21, 0x03, 0x0c, 0x03, 0x0b, 0x20, 0x00, 0x41, + 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x04, 0x20, 0x00, 0x21, + 0x03, 0x0c, 0x02, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, + 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x01, 0x6b, + 0x21, 0x04, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, + 0x45, 0x04, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x0c, 0x02, + 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, + 0x01, 0x3a, 0x00, 0x01, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x21, 0x04, 0x20, + 0x00, 0x41, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, + 0x20, 0x01, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x04, + 0x45, 0x0d, 0x03, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x02, 0x3a, 0x00, + 0x02, 0x20, 0x02, 0x41, 0x03, 0x6b, 0x21, 0x04, 0x20, 0x00, 0x41, 0x03, + 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x01, 0x41, + 0x03, 0x6a, 0x21, 0x01, 0x0c, 0x02, 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x03, + 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x01, - 0x20, 0x02, 0x41, 0x7c, 0x6a, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, - 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, 0x03, 0x40, 0x20, 0x03, - 0x20, 0x01, 0x2d, 0x00, 0x00, 0x22, 0x00, 0x3a, 0x00, 0x00, 0x02, 0x40, - 0x20, 0x00, 0x0d, 0x00, 0x20, 0x02, 0x21, 0x05, 0x0c, 0x03, 0x0b, 0x20, - 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, - 0x01, 0x20, 0x02, 0x41, 0x7f, 0x6a, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, - 0x41, 0x00, 0x21, 0x05, 0x0b, 0x02, 0x40, 0x20, 0x05, 0x45, 0x0d, 0x00, - 0x20, 0x03, 0x41, 0x00, 0x20, 0x05, 0xfc, 0x0b, 0x00, 0x0b, 0x20, 0x03, - 0x0b, 0x11, 0x00, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0x10, 0xa6, 0x80, - 0x80, 0x80, 0x00, 0x1a, 0x20, 0x00, 0x0b, 0x17, 0x00, 0x20, 0x00, 0x41, - 0x50, 0x6a, 0x41, 0x0a, 0x49, 0x20, 0x00, 0x41, 0x20, 0x72, 0x41, 0x9f, - 0x7f, 0x6a, 0x41, 0x06, 0x49, 0x72, 0x0b, 0x2a, 0x01, 0x03, 0x7f, 0x41, - 0x00, 0x21, 0x01, 0x03, 0x40, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x21, 0x02, - 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x03, 0x21, 0x01, 0x20, 0x02, 0x28, - 0x02, 0x00, 0x0d, 0x00, 0x0b, 0x20, 0x03, 0x41, 0x7c, 0x6a, 0x41, 0x02, - 0x75, 0x0b, 0x45, 0x01, 0x01, 0x7f, 0x02, 0x40, 0x20, 0x01, 0x45, 0x0d, - 0x00, 0x20, 0x00, 0x41, 0x7c, 0x6a, 0x21, 0x00, 0x02, 0x40, 0x03, 0x40, - 0x20, 0x00, 0x41, 0x04, 0x6a, 0x22, 0x00, 0x28, 0x02, 0x00, 0x22, 0x02, - 0x45, 0x0d, 0x01, 0x20, 0x02, 0x20, 0x01, 0x47, 0x0d, 0x00, 0x0b, 0x0b, - 0x20, 0x00, 0x41, 0x00, 0x20, 0x02, 0x1b, 0x0f, 0x0b, 0x20, 0x00, 0x20, - 0x00, 0x10, 0xa9, 0x80, 0x80, 0x80, 0x00, 0x41, 0x02, 0x74, 0x6a, 0x0b, - 0x1d, 0x00, 0x02, 0x40, 0x20, 0x00, 0x0d, 0x00, 0x41, 0x00, 0x0f, 0x0b, - 0x41, 0x90, 0xc2, 0x84, 0x80, 0x00, 0x20, 0x00, 0x10, 0xaa, 0x80, 0x80, - 0x80, 0x00, 0x41, 0x00, 0x47, 0x0b, 0x24, 0x01, 0x01, 0x7f, 0x41, 0x01, - 0x21, 0x01, 0x02, 0x40, 0x20, 0x00, 0x41, 0x50, 0x6a, 0x41, 0x0a, 0x49, - 0x0d, 0x00, 0x20, 0x00, 0x10, 0x95, 0x80, 0x80, 0x80, 0x00, 0x41, 0x00, - 0x47, 0x21, 0x01, 0x0b, 0x20, 0x01, 0x0b, 0x0b, 0xfc, 0x42, 0x02, 0x00, - 0x41, 0x80, 0x80, 0x04, 0x0b, 0xe8, 0x42, 0x12, 0x11, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, - 0x11, 0x22, 0x23, 0x24, 0x11, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x11, 0x2d, 0x2e, 0x2f, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x31, 0x32, 0x33, 0x10, 0x34, 0x35, 0x10, 0x10, 0x11, + 0x20, 0x02, 0x41, 0x04, 0x6b, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x02, 0x40, + 0x20, 0x03, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, + 0x0d, 0x00, 0x20, 0x02, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, + 0x01, 0x6b, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, + 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, + 0x04, 0x40, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, + 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x03, 0x6a, + 0x22, 0x04, 0x20, 0x01, 0x20, 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x04, 0x41, 0x03, 0x71, 0x45, 0x04, 0x40, 0x20, 0x03, 0x21, + 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, + 0x02, 0x41, 0x03, 0x6b, 0x22, 0x03, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x20, + 0x03, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x04, 0x41, 0x03, + 0x71, 0x45, 0x04, 0x40, 0x20, 0x03, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, + 0x03, 0x45, 0x0d, 0x04, 0x20, 0x00, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x22, + 0x02, 0x6a, 0x20, 0x01, 0x20, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x20, 0x02, 0x41, + 0x04, 0x6b, 0x22, 0x04, 0x41, 0x0c, 0x71, 0x41, 0x0c, 0x47, 0x04, 0x40, + 0x20, 0x04, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x03, 0x71, 0x21, + 0x03, 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x05, 0x20, 0x00, 0x41, 0x04, + 0x6b, 0x21, 0x06, 0x03, 0x40, 0x20, 0x02, 0x20, 0x06, 0x6a, 0x20, 0x02, + 0x20, 0x05, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, + 0x04, 0x6b, 0x21, 0x02, 0x20, 0x03, 0x41, 0x01, 0x6b, 0x22, 0x03, 0x0d, + 0x00, 0x0b, 0x0b, 0x20, 0x04, 0x41, 0x0c, 0x49, 0x0d, 0x00, 0x20, 0x01, + 0x41, 0x10, 0x6b, 0x21, 0x05, 0x20, 0x00, 0x41, 0x10, 0x6b, 0x21, 0x06, + 0x03, 0x40, 0x20, 0x02, 0x20, 0x06, 0x6a, 0x22, 0x03, 0x41, 0x0c, 0x6a, + 0x20, 0x02, 0x20, 0x05, 0x6a, 0x22, 0x04, 0x41, 0x0c, 0x6a, 0x28, 0x02, + 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x08, 0x6a, 0x20, 0x04, 0x41, + 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, + 0x6a, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, + 0x20, 0x03, 0x20, 0x04, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x02, + 0x41, 0x10, 0x6b, 0x22, 0x02, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, + 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, 0x02, 0x22, 0x03, 0x41, 0x03, 0x71, + 0x22, 0x05, 0x04, 0x40, 0x20, 0x01, 0x41, 0x01, 0x6b, 0x21, 0x04, 0x20, + 0x00, 0x41, 0x01, 0x6b, 0x21, 0x06, 0x03, 0x40, 0x20, 0x03, 0x20, 0x06, + 0x6a, 0x20, 0x03, 0x20, 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, + 0x20, 0x03, 0x41, 0x01, 0x6b, 0x21, 0x03, 0x20, 0x05, 0x41, 0x01, 0x6b, + 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, + 0x02, 0x20, 0x01, 0x41, 0x04, 0x6b, 0x21, 0x04, 0x20, 0x00, 0x41, 0x04, + 0x6b, 0x21, 0x05, 0x03, 0x40, 0x20, 0x03, 0x20, 0x05, 0x6a, 0x22, 0x01, + 0x41, 0x03, 0x6a, 0x20, 0x03, 0x20, 0x04, 0x6a, 0x22, 0x02, 0x41, 0x03, + 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x41, 0x02, 0x6a, + 0x20, 0x02, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, + 0x01, 0x41, 0x01, 0x6a, 0x20, 0x02, 0x41, 0x01, 0x6a, 0x2d, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x20, 0x01, 0x20, 0x02, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x03, 0x41, 0x04, 0x6b, 0x22, 0x03, 0x0d, 0x00, 0x0b, 0x0c, + 0x02, 0x0b, 0x20, 0x04, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x20, 0x04, 0x41, + 0x04, 0x6b, 0x22, 0x05, 0x41, 0x1c, 0x71, 0x41, 0x1c, 0x47, 0x04, 0x40, + 0x20, 0x04, 0x20, 0x05, 0x41, 0x02, 0x76, 0x41, 0x01, 0x6a, 0x41, 0x07, + 0x71, 0x22, 0x02, 0x41, 0x02, 0x74, 0x6b, 0x21, 0x04, 0x03, 0x40, 0x20, + 0x03, 0x20, 0x01, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, + 0x04, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, + 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x05, + 0x41, 0x1c, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x28, + 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x01, + 0x41, 0x04, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, + 0x08, 0x6a, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x41, 0x0c, 0x6a, 0x20, 0x01, 0x41, 0x0c, 0x6a, 0x28, + 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x20, 0x01, + 0x41, 0x10, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, + 0x14, 0x6a, 0x20, 0x01, 0x41, 0x14, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, + 0x00, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x20, 0x01, 0x41, 0x18, 0x6a, 0x28, + 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x03, 0x41, 0x1c, 0x6a, 0x20, 0x01, + 0x41, 0x1c, 0x6a, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, + 0x20, 0x6a, 0x21, 0x01, 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, 0x20, + 0x04, 0x41, 0x20, 0x6b, 0x22, 0x04, 0x41, 0x03, 0x4b, 0x0d, 0x00, 0x0b, + 0x0b, 0x20, 0x04, 0x45, 0x0d, 0x00, 0x02, 0x40, 0x20, 0x04, 0x41, 0x07, + 0x71, 0x22, 0x02, 0x45, 0x04, 0x40, 0x20, 0x04, 0x21, 0x05, 0x0c, 0x01, + 0x0b, 0x20, 0x04, 0x41, 0x78, 0x71, 0x21, 0x05, 0x03, 0x40, 0x20, 0x03, + 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, + 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, 0x6a, 0x21, 0x01, 0x20, 0x02, + 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x04, 0x41, + 0x08, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x03, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x20, 0x01, 0x41, + 0x01, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x02, + 0x6a, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, + 0x20, 0x03, 0x41, 0x03, 0x6a, 0x20, 0x01, 0x41, 0x03, 0x6a, 0x2d, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x20, 0x01, 0x41, + 0x04, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x05, + 0x6a, 0x20, 0x01, 0x41, 0x05, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, + 0x20, 0x03, 0x41, 0x06, 0x6a, 0x20, 0x01, 0x41, 0x06, 0x6a, 0x2d, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x07, 0x6a, 0x20, 0x01, 0x41, + 0x07, 0x6a, 0x2d, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x03, 0x41, 0x08, + 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x20, 0x05, + 0x41, 0x08, 0x6b, 0x22, 0x05, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0f, + 0x0b, 0x20, 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, + 0x00, 0x0b, 0x94, 0x03, 0x02, 0x03, 0x7f, 0x01, 0x7e, 0x02, 0x40, 0x20, + 0x02, 0x41, 0x21, 0x4f, 0x04, 0x40, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x20, + 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0b, 0x00, 0x20, 0x00, 0x0f, 0x0b, + 0x20, 0x02, 0x45, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x00, + 0x20, 0x00, 0x20, 0x02, 0x6a, 0x22, 0x03, 0x41, 0x01, 0x6b, 0x20, 0x01, + 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x03, 0x49, 0x0d, 0x00, 0x20, 0x00, + 0x20, 0x01, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x01, + 0x20, 0x03, 0x41, 0x03, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x03, + 0x41, 0x02, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x07, + 0x49, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x01, 0x3a, 0x00, 0x03, 0x20, 0x03, + 0x41, 0x04, 0x6b, 0x20, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x02, 0x41, 0x09, + 0x49, 0x0d, 0x00, 0x20, 0x00, 0x41, 0x00, 0x20, 0x00, 0x6b, 0x41, 0x03, + 0x71, 0x22, 0x05, 0x6a, 0x22, 0x04, 0x20, 0x01, 0x41, 0xff, 0x01, 0x71, + 0x41, 0x81, 0x82, 0x84, 0x08, 0x6c, 0x22, 0x03, 0x36, 0x02, 0x00, 0x20, + 0x04, 0x20, 0x02, 0x20, 0x05, 0x6b, 0x41, 0x3c, 0x71, 0x22, 0x02, 0x6a, + 0x22, 0x01, 0x41, 0x04, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, + 0x41, 0x09, 0x49, 0x0d, 0x00, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x08, + 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x04, 0x20, 0x01, 0x41, 0x08, 0x6b, + 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x0c, 0x6b, 0x20, 0x03, + 0x36, 0x02, 0x00, 0x20, 0x02, 0x41, 0x19, 0x49, 0x0d, 0x00, 0x20, 0x04, + 0x20, 0x03, 0x36, 0x02, 0x18, 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x14, + 0x20, 0x04, 0x20, 0x03, 0x36, 0x02, 0x10, 0x20, 0x04, 0x20, 0x03, 0x36, + 0x02, 0x0c, 0x20, 0x01, 0x41, 0x10, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, + 0x20, 0x01, 0x41, 0x14, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, + 0x41, 0x18, 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x01, 0x41, 0x1c, + 0x6b, 0x20, 0x03, 0x36, 0x02, 0x00, 0x20, 0x02, 0x20, 0x04, 0x41, 0x04, + 0x71, 0x41, 0x18, 0x72, 0x22, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x20, 0x49, + 0x0d, 0x00, 0x20, 0x03, 0xad, 0x42, 0x81, 0x80, 0x80, 0x80, 0x10, 0x7e, + 0x21, 0x06, 0x20, 0x02, 0x20, 0x04, 0x6a, 0x21, 0x02, 0x03, 0x40, 0x20, + 0x02, 0x20, 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x18, 0x6a, 0x20, + 0x06, 0x37, 0x03, 0x00, 0x20, 0x02, 0x41, 0x10, 0x6a, 0x20, 0x06, 0x37, + 0x03, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x20, 0x06, 0x37, 0x03, 0x00, + 0x20, 0x02, 0x41, 0x20, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x20, 0x6b, + 0x22, 0x01, 0x41, 0x1f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x00, 0x0b, + 0x09, 0x00, 0x20, 0x00, 0x10, 0x13, 0x20, 0x00, 0x47, 0x0b, 0xd5, 0x07, + 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x7f, 0x02, 0x40, 0x20, 0x02, 0x41, + 0x20, 0x4d, 0x04, 0x40, 0x20, 0x01, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, + 0x45, 0x72, 0x0d, 0x01, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x00, 0x3a, + 0x00, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x20, 0x01, 0x41, 0x01, 0x6a, + 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, + 0x05, 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, 0x20, 0x01, 0x2d, 0x00, + 0x01, 0x3a, 0x00, 0x01, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x20, 0x01, 0x41, + 0x02, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, 0x41, 0x02, + 0x6b, 0x22, 0x05, 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, 0x20, 0x01, + 0x2d, 0x00, 0x02, 0x3a, 0x00, 0x02, 0x20, 0x00, 0x41, 0x03, 0x6a, 0x20, + 0x01, 0x41, 0x03, 0x6a, 0x22, 0x03, 0x41, 0x03, 0x71, 0x45, 0x20, 0x02, + 0x41, 0x03, 0x6b, 0x22, 0x05, 0x45, 0x72, 0x0d, 0x02, 0x1a, 0x20, 0x00, + 0x20, 0x01, 0x2d, 0x00, 0x03, 0x3a, 0x00, 0x03, 0x20, 0x02, 0x41, 0x04, + 0x6b, 0x21, 0x05, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x00, + 0x41, 0x04, 0x6a, 0x0c, 0x02, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x02, 0x20, + 0x00, 0x20, 0x01, 0x20, 0x02, 0xfc, 0x0a, 0x00, 0x00, 0x20, 0x00, 0x0f, + 0x0b, 0x20, 0x02, 0x21, 0x05, 0x20, 0x01, 0x21, 0x03, 0x20, 0x00, 0x0b, + 0x22, 0x04, 0x41, 0x03, 0x71, 0x22, 0x02, 0x45, 0x04, 0x40, 0x02, 0x40, + 0x20, 0x05, 0x41, 0x10, 0x49, 0x04, 0x40, 0x20, 0x05, 0x21, 0x02, 0x0c, + 0x01, 0x0b, 0x20, 0x05, 0x41, 0x10, 0x6b, 0x22, 0x02, 0x41, 0x10, 0x71, + 0x45, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, 0x29, 0x02, 0x00, 0x37, 0x02, + 0x00, 0x20, 0x04, 0x20, 0x03, 0x29, 0x02, 0x08, 0x37, 0x02, 0x08, 0x20, + 0x04, 0x41, 0x10, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x21, + 0x03, 0x20, 0x02, 0x21, 0x05, 0x0b, 0x20, 0x02, 0x41, 0x10, 0x49, 0x0d, + 0x00, 0x20, 0x05, 0x21, 0x02, 0x03, 0x40, 0x20, 0x04, 0x20, 0x03, 0x29, + 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x20, 0x03, + 0x41, 0x08, 0x6a, 0x29, 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x41, + 0x10, 0x6a, 0x20, 0x03, 0x41, 0x10, 0x6a, 0x29, 0x02, 0x00, 0x37, 0x02, + 0x00, 0x20, 0x04, 0x41, 0x18, 0x6a, 0x20, 0x03, 0x41, 0x18, 0x6a, 0x29, + 0x02, 0x00, 0x37, 0x02, 0x00, 0x20, 0x04, 0x41, 0x20, 0x6a, 0x21, 0x04, + 0x20, 0x03, 0x41, 0x20, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x20, 0x6b, + 0x22, 0x02, 0x41, 0x0f, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x41, + 0x08, 0x4f, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, 0x29, 0x02, 0x00, 0x37, + 0x02, 0x00, 0x20, 0x04, 0x41, 0x08, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, + 0x08, 0x6a, 0x21, 0x03, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x71, 0x04, 0x40, + 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x00, 0x36, 0x02, 0x00, 0x20, 0x04, + 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, + 0x0b, 0x20, 0x02, 0x41, 0x02, 0x71, 0x04, 0x40, 0x20, 0x04, 0x20, 0x03, + 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x04, 0x41, 0x02, 0x6a, 0x21, + 0x04, 0x20, 0x03, 0x41, 0x02, 0x6a, 0x21, 0x03, 0x0b, 0x20, 0x02, 0x41, + 0x01, 0x71, 0x45, 0x0d, 0x01, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0f, 0x0b, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x7f, 0x02, 0x40, 0x20, 0x05, 0x41, 0x20, 0x4f, 0x04, 0x40, 0x20, 0x04, + 0x20, 0x03, 0x28, 0x02, 0x00, 0x22, 0x01, 0x3a, 0x00, 0x00, 0x02, 0x40, + 0x02, 0x40, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x0e, 0x02, 0x00, 0x01, 0x03, + 0x0b, 0x20, 0x04, 0x20, 0x01, 0x41, 0x08, 0x76, 0x3a, 0x00, 0x01, 0x20, + 0x04, 0x20, 0x03, 0x41, 0x06, 0x6a, 0x29, 0x01, 0x00, 0x37, 0x02, 0x06, + 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, 0x41, 0x10, 0x74, 0x20, 0x01, + 0x41, 0x10, 0x76, 0x72, 0x36, 0x02, 0x02, 0x20, 0x03, 0x41, 0x12, 0x6a, + 0x21, 0x01, 0x41, 0x0e, 0x21, 0x06, 0x20, 0x03, 0x41, 0x0e, 0x6a, 0x28, + 0x01, 0x00, 0x21, 0x03, 0x41, 0x0e, 0x21, 0x05, 0x20, 0x04, 0x41, 0x12, + 0x6a, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x41, 0x05, 0x6a, 0x29, + 0x00, 0x00, 0x37, 0x02, 0x05, 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, + 0x41, 0x18, 0x74, 0x20, 0x01, 0x41, 0x08, 0x76, 0x72, 0x36, 0x02, 0x01, + 0x20, 0x03, 0x41, 0x11, 0x6a, 0x21, 0x01, 0x41, 0x0d, 0x21, 0x06, 0x20, + 0x03, 0x41, 0x0d, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x03, 0x41, 0x0f, 0x21, + 0x05, 0x20, 0x04, 0x41, 0x11, 0x6a, 0x0c, 0x02, 0x0b, 0x02, 0x7f, 0x20, + 0x05, 0x41, 0x10, 0x49, 0x04, 0x40, 0x20, 0x04, 0x21, 0x02, 0x20, 0x03, + 0x0c, 0x01, 0x0b, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x3a, 0x00, + 0x00, 0x20, 0x04, 0x20, 0x03, 0x28, 0x00, 0x01, 0x36, 0x00, 0x01, 0x20, + 0x04, 0x20, 0x03, 0x29, 0x00, 0x05, 0x37, 0x00, 0x05, 0x20, 0x04, 0x20, + 0x03, 0x2f, 0x00, 0x0d, 0x3b, 0x00, 0x0d, 0x20, 0x04, 0x20, 0x03, 0x2d, + 0x00, 0x0f, 0x3a, 0x00, 0x0f, 0x20, 0x04, 0x41, 0x10, 0x6a, 0x21, 0x02, + 0x20, 0x03, 0x41, 0x10, 0x6a, 0x0b, 0x21, 0x01, 0x20, 0x05, 0x41, 0x08, + 0x71, 0x0d, 0x02, 0x0c, 0x03, 0x0b, 0x20, 0x04, 0x20, 0x01, 0x41, 0x10, + 0x76, 0x3a, 0x00, 0x02, 0x20, 0x04, 0x20, 0x01, 0x41, 0x08, 0x76, 0x3a, + 0x00, 0x01, 0x20, 0x04, 0x20, 0x03, 0x41, 0x07, 0x6a, 0x29, 0x00, 0x00, + 0x37, 0x02, 0x07, 0x20, 0x04, 0x20, 0x03, 0x28, 0x02, 0x04, 0x41, 0x08, + 0x74, 0x20, 0x01, 0x41, 0x18, 0x76, 0x72, 0x36, 0x02, 0x03, 0x20, 0x03, + 0x41, 0x13, 0x6a, 0x21, 0x01, 0x41, 0x0f, 0x21, 0x06, 0x20, 0x03, 0x41, + 0x0f, 0x6a, 0x28, 0x00, 0x00, 0x21, 0x03, 0x41, 0x0d, 0x21, 0x05, 0x20, + 0x04, 0x41, 0x13, 0x6a, 0x0b, 0x21, 0x02, 0x20, 0x04, 0x20, 0x06, 0x6a, + 0x20, 0x03, 0x36, 0x02, 0x00, 0x0b, 0x20, 0x02, 0x20, 0x01, 0x29, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x20, 0x02, 0x41, 0x08, 0x6a, 0x21, 0x02, 0x20, + 0x01, 0x41, 0x08, 0x6a, 0x21, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x04, 0x71, + 0x04, 0x40, 0x20, 0x02, 0x20, 0x01, 0x28, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x20, 0x02, 0x41, 0x04, 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x04, 0x6a, + 0x21, 0x01, 0x0b, 0x20, 0x05, 0x41, 0x02, 0x71, 0x04, 0x40, 0x20, 0x02, + 0x20, 0x01, 0x2f, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x20, 0x02, 0x41, 0x02, + 0x6a, 0x21, 0x02, 0x20, 0x01, 0x41, 0x02, 0x6a, 0x21, 0x01, 0x0b, 0x20, + 0x05, 0x41, 0x01, 0x71, 0x45, 0x0d, 0x00, 0x20, 0x02, 0x20, 0x01, 0x2d, + 0x00, 0x00, 0x3a, 0x00, 0x00, 0x0b, 0x20, 0x00, 0x0b, 0x0d, 0x00, 0x20, + 0x00, 0x41, 0x20, 0x46, 0x20, 0x00, 0x41, 0x09, 0x46, 0x72, 0x0b, 0x0a, + 0x00, 0x20, 0x00, 0x41, 0x30, 0x6b, 0x41, 0x0a, 0x49, 0x0b, 0x49, 0x01, + 0x02, 0x7f, 0x20, 0x00, 0x10, 0x0c, 0x20, 0x00, 0x6a, 0x21, 0x03, 0x02, + 0x40, 0x20, 0x02, 0x45, 0x0d, 0x00, 0x03, 0x40, 0x20, 0x01, 0x2d, 0x00, + 0x00, 0x22, 0x04, 0x45, 0x0d, 0x01, 0x20, 0x03, 0x20, 0x04, 0x3a, 0x00, + 0x00, 0x20, 0x03, 0x41, 0x01, 0x6a, 0x21, 0x03, 0x20, 0x01, 0x41, 0x01, + 0x6a, 0x21, 0x01, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, 0x00, + 0x0b, 0x0b, 0x20, 0x03, 0x41, 0x00, 0x3a, 0x00, 0x00, 0x20, 0x00, 0x0b, + 0xeb, 0x03, 0x01, 0x04, 0x7f, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, + 0x40, 0x20, 0x00, 0x20, 0x01, 0x22, 0x03, 0x73, 0x41, 0x03, 0x71, 0x04, + 0x40, 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x41, 0x00, + 0x47, 0x21, 0x06, 0x02, 0x40, 0x20, 0x03, 0x41, 0x03, 0x71, 0x45, 0x04, + 0x40, 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x02, 0x45, 0x04, + 0x40, 0x20, 0x00, 0x21, 0x04, 0x0c, 0x01, 0x0b, 0x20, 0x00, 0x20, 0x03, + 0x2d, 0x00, 0x00, 0x22, 0x01, 0x3a, 0x00, 0x00, 0x20, 0x01, 0x45, 0x04, + 0x40, 0x20, 0x00, 0x21, 0x04, 0x20, 0x02, 0x21, 0x01, 0x0c, 0x05, 0x0b, + 0x20, 0x00, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x01, 0x6b, + 0x22, 0x01, 0x41, 0x00, 0x47, 0x21, 0x06, 0x20, 0x03, 0x41, 0x01, 0x6a, + 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x20, 0x01, 0x45, 0x72, 0x45, 0x04, + 0x40, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x3a, 0x00, + 0x00, 0x20, 0x05, 0x45, 0x0d, 0x05, 0x20, 0x00, 0x41, 0x02, 0x6a, 0x21, + 0x04, 0x20, 0x02, 0x41, 0x02, 0x6b, 0x22, 0x01, 0x41, 0x00, 0x47, 0x21, + 0x06, 0x20, 0x03, 0x41, 0x02, 0x6a, 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, + 0x20, 0x01, 0x45, 0x72, 0x45, 0x04, 0x40, 0x20, 0x04, 0x20, 0x05, 0x2d, + 0x00, 0x00, 0x22, 0x05, 0x3a, 0x00, 0x00, 0x20, 0x05, 0x45, 0x0d, 0x06, + 0x20, 0x00, 0x41, 0x03, 0x6a, 0x21, 0x04, 0x20, 0x02, 0x41, 0x03, 0x6b, + 0x22, 0x01, 0x41, 0x00, 0x47, 0x21, 0x06, 0x20, 0x03, 0x41, 0x03, 0x6a, + 0x22, 0x05, 0x41, 0x03, 0x71, 0x45, 0x20, 0x01, 0x45, 0x72, 0x45, 0x04, + 0x40, 0x20, 0x04, 0x20, 0x05, 0x2d, 0x00, 0x00, 0x22, 0x05, 0x3a, 0x00, + 0x00, 0x20, 0x05, 0x45, 0x0d, 0x07, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, + 0x04, 0x20, 0x03, 0x41, 0x04, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x04, + 0x6b, 0x22, 0x02, 0x41, 0x00, 0x47, 0x21, 0x06, 0x0c, 0x03, 0x0b, 0x20, + 0x05, 0x21, 0x03, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x02, 0x0b, 0x20, 0x05, + 0x21, 0x03, 0x20, 0x01, 0x21, 0x02, 0x0c, 0x01, 0x0b, 0x20, 0x05, 0x21, + 0x03, 0x20, 0x01, 0x21, 0x02, 0x0b, 0x20, 0x06, 0x45, 0x0d, 0x02, 0x20, + 0x03, 0x2d, 0x00, 0x00, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x01, 0x0c, + 0x04, 0x0b, 0x20, 0x02, 0x41, 0x04, 0x49, 0x0d, 0x00, 0x03, 0x40, 0x41, + 0x80, 0x82, 0x84, 0x08, 0x20, 0x03, 0x28, 0x02, 0x00, 0x22, 0x01, 0x6b, + 0x20, 0x01, 0x72, 0x41, 0x80, 0x81, 0x82, 0x84, 0x78, 0x71, 0x41, 0x80, + 0x81, 0x82, 0x84, 0x78, 0x47, 0x0d, 0x02, 0x20, 0x04, 0x20, 0x01, 0x36, + 0x02, 0x00, 0x20, 0x04, 0x41, 0x04, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, + 0x04, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x04, 0x6b, 0x22, 0x02, 0x41, + 0x03, 0x4b, 0x0d, 0x00, 0x0b, 0x0b, 0x20, 0x02, 0x45, 0x0d, 0x01, 0x0b, + 0x03, 0x40, 0x20, 0x04, 0x20, 0x03, 0x2d, 0x00, 0x00, 0x22, 0x01, 0x3a, + 0x00, 0x00, 0x20, 0x01, 0x45, 0x04, 0x40, 0x20, 0x02, 0x21, 0x01, 0x0c, + 0x03, 0x0b, 0x20, 0x04, 0x41, 0x01, 0x6a, 0x21, 0x04, 0x20, 0x03, 0x41, + 0x01, 0x6a, 0x21, 0x03, 0x20, 0x02, 0x41, 0x01, 0x6b, 0x22, 0x02, 0x0d, + 0x00, 0x0b, 0x0b, 0x41, 0x00, 0x21, 0x01, 0x0b, 0x20, 0x01, 0x04, 0x40, + 0x20, 0x04, 0x41, 0x00, 0x20, 0x01, 0xfc, 0x0b, 0x00, 0x0b, 0x20, 0x00, + 0x0b, 0x17, 0x00, 0x20, 0x00, 0x41, 0x30, 0x6b, 0x41, 0x0a, 0x49, 0x20, + 0x00, 0x41, 0x20, 0x72, 0x41, 0xe1, 0x00, 0x6b, 0x41, 0x06, 0x49, 0x72, + 0x0b, 0x67, 0x01, 0x02, 0x7f, 0x20, 0x00, 0x45, 0x04, 0x40, 0x41, 0x00, + 0x0f, 0x0b, 0x02, 0x7f, 0x20, 0x00, 0x04, 0x40, 0x41, 0x8c, 0xc2, 0x04, + 0x21, 0x01, 0x03, 0x40, 0x20, 0x01, 0x41, 0x04, 0x6a, 0x22, 0x01, 0x28, + 0x02, 0x00, 0x22, 0x02, 0x41, 0x00, 0x20, 0x00, 0x20, 0x02, 0x47, 0x1b, + 0x0d, 0x00, 0x0b, 0x20, 0x01, 0x41, 0x00, 0x20, 0x02, 0x1b, 0x0c, 0x01, + 0x0b, 0x41, 0x00, 0x21, 0x00, 0x03, 0x40, 0x20, 0x00, 0x41, 0x90, 0xc2, + 0x04, 0x6a, 0x20, 0x00, 0x41, 0x04, 0x6a, 0x21, 0x00, 0x28, 0x02, 0x00, + 0x0d, 0x00, 0x0b, 0x20, 0x00, 0x41, 0x04, 0x6b, 0x41, 0x7c, 0x71, 0x41, + 0x90, 0xc2, 0x04, 0x6a, 0x0b, 0x41, 0x00, 0x47, 0x0b, 0x1d, 0x01, 0x01, + 0x7f, 0x41, 0x01, 0x21, 0x01, 0x20, 0x00, 0x41, 0x30, 0x6b, 0x41, 0x0a, + 0x4f, 0x04, 0x7f, 0x20, 0x00, 0x10, 0x0d, 0x41, 0x00, 0x47, 0x05, 0x20, + 0x01, 0x0b, 0x0b, 0x0b, 0xfc, 0x42, 0x02, 0x00, 0x41, 0x80, 0x80, 0x04, + 0x0b, 0xe8, 0x42, 0x12, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x11, 0x22, 0x23, 0x24, + 0x11, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x11, 0x2d, 0x2e, + 0x2f, 0x10, 0x10, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x31, + 0x32, 0x33, 0x10, 0x34, 0x35, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x36, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x37, 0x11, - 0x11, 0x11, 0x11, 0x38, 0x11, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x37, 0x11, 0x11, 0x11, 0x11, 0x38, + 0x11, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x3f, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x11, 0x11, 0x3f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x11, 0x40, 0x41, 0x11, 0x42, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x11, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x10, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, - 0x5c, 0x5d, 0x10, 0x5e, 0x5f, 0x60, 0x10, 0x11, 0x11, 0x11, 0x61, 0x62, - 0x63, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x64, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x65, 0x10, 0x10, + 0x11, 0x40, 0x41, 0x11, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x11, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x10, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x10, 0x5e, + 0x5f, 0x60, 0x10, 0x11, 0x11, 0x11, 0x61, 0x62, 0x63, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x64, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x11, 0x11, 0x65, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x66, 0x67, 0x10, - 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x10, 0x10, 0x10, 0x11, 0x11, 0x66, 0x67, 0x10, 0x10, 0x68, 0x69, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x11, 0x11, 0x6a, 0x11, 0x11, 0x6b, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x6a, 0x11, + 0x11, 0x6b, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x6c, 0x6d, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6e, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x11, 0x6c, 0x6d, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x6e, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x6f, 0x70, 0x71, 0x72, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x73, 0x74, 0x75, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x76, 0x77, 0x10, 0x10, 0x10, 0x10, 0x78, 0x10, 0x10, - 0x79, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0x6f, 0x70, 0x71, 0x72, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x73, 0x74, 0x75, 0x10, 0x10, 0x10, 0x10, 0x10, 0x76, + 0x77, 0x10, 0x10, 0x10, 0x10, 0x78, 0x10, 0x10, 0x79, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0xff, 0xff, 0x7f, 0xff, 0xff, - 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xc3, 0xff, 0x03, 0x00, 0x1f, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xdf, 0xbc, 0x40, 0xd7, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, - 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, - 0xff, 0x7f, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xbf, 0xb6, 0x00, 0xff, 0xff, 0xff, 0x87, 0x07, 0x00, 0x00, - 0x00, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, - 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xef, 0x1f, 0xfe, 0xe1, 0xff, 0x9f, 0x00, 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0x30, 0x04, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x1f, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x01, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xdf, 0x3f, 0x00, 0x00, 0xf0, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xdf, 0xe1, 0xff, 0xcf, - 0xff, 0xfe, 0xff, 0xef, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xc5, 0xe3, 0x9f, - 0x59, 0x80, 0xb0, 0xcf, 0xff, 0x03, 0x10, 0xee, 0x87, 0xf9, 0xff, 0xff, - 0xfd, 0x6d, 0xc3, 0x87, 0x19, 0x02, 0x5e, 0xc0, 0xff, 0x3f, 0x00, 0xee, - 0xbf, 0xfb, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0xbf, 0x1b, 0x01, 0x00, 0xcf, - 0xff, 0x00, 0x1e, 0xee, 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, - 0x19, 0xc0, 0xb0, 0xcf, 0xff, 0x02, 0x00, 0xec, 0xc7, 0x3d, 0xd6, 0x18, - 0xc7, 0xff, 0xc3, 0xc7, 0x1d, 0x81, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xef, - 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xff, 0xe3, 0xdf, 0x1d, 0x60, 0x07, 0xcf, - 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xef, 0xe3, 0xdf, - 0x1d, 0x60, 0x40, 0xcf, 0xff, 0x06, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0xdf, 0x5d, 0xf0, 0x80, 0xcf, 0xff, 0x00, 0xfc, 0xec, - 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xfb, 0x2f, 0x7f, 0x80, 0x5f, 0xff, 0xc0, - 0xff, 0x0c, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x07, 0x3f, - 0x20, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xf7, 0xff, 0xff, 0xaf, - 0xff, 0xff, 0x3b, 0x5f, 0x20, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xff, - 0x1f, 0xfe, 0xff, 0x03, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x7f, 0xf9, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x3d, 0x7f, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, - 0xff, 0x3d, 0x7f, 0x3d, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x20, 0x04, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, + 0xff, 0x03, 0x00, 0x1f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xbc, 0x40, + 0xd7, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x02, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xb6, + 0x00, 0xff, 0xff, 0xff, 0x87, 0x07, 0x00, 0x00, 0x00, 0xff, 0x07, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xc3, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x1f, 0xfe, + 0xe1, 0xff, 0x9f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x30, 0x04, 0xff, + 0xff, 0xff, 0xfc, 0xff, 0x1f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdf, 0x3f, 0x00, + 0x00, 0xf0, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xef, 0xff, 0xdf, 0xe1, 0xff, 0xcf, 0xff, 0xfe, 0xff, 0xef, + 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xc5, 0xe3, 0x9f, 0x59, 0x80, 0xb0, 0xcf, + 0xff, 0x03, 0x10, 0xee, 0x87, 0xf9, 0xff, 0xff, 0xfd, 0x6d, 0xc3, 0x87, + 0x19, 0x02, 0x5e, 0xc0, 0xff, 0x3f, 0x00, 0xee, 0xbf, 0xfb, 0xff, 0xff, + 0xfd, 0xed, 0xe3, 0xbf, 0x1b, 0x01, 0x00, 0xcf, 0xff, 0x00, 0x1e, 0xee, + 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19, 0xc0, 0xb0, 0xcf, + 0xff, 0x02, 0x00, 0xec, 0xc7, 0x3d, 0xd6, 0x18, 0xc7, 0xff, 0xc3, 0xc7, + 0x1d, 0x81, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, + 0xfd, 0xff, 0xe3, 0xdf, 0x1d, 0x60, 0x07, 0xcf, 0xff, 0x00, 0x00, 0xef, + 0xdf, 0xfd, 0xff, 0xff, 0xfd, 0xef, 0xe3, 0xdf, 0x1d, 0x60, 0x40, 0xcf, + 0xff, 0x06, 0x00, 0xef, 0xdf, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xdf, + 0x5d, 0xf0, 0x80, 0xcf, 0xff, 0x00, 0xfc, 0xec, 0xff, 0x7f, 0xfc, 0xff, + 0xff, 0xfb, 0x2f, 0x7f, 0x80, 0x5f, 0xff, 0xc0, 0xff, 0x0c, 0x00, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x07, 0x3f, 0x20, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0xd6, 0xf7, 0xff, 0xff, 0xaf, 0xff, 0xff, 0x3b, 0x5f, + 0x20, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, + 0x03, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0x03, + 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf9, 0xff, + 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, 0xff, 0xff, 0x3d, 0x7f, 0x3d, + 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x3f, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x07, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x01, 0xff, - 0xdf, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, - 0xdf, 0x0d, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, - 0x01, 0x80, 0x10, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x0f, 0xff, 0x01, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0f, 0xff, 0xff, 0xff, 0x03, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, - 0xff, 0x1f, 0x00, 0xff, 0x03, 0xff, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xef, 0xff, 0xef, 0x0f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, - 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, - 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x01, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x6f, 0x04, 0xff, + 0x9f, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x01, 0xff, 0xdf, 0x0f, 0x00, 0xff, + 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xdf, 0x0d, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0x01, 0x80, 0x10, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0x0f, 0xff, 0x01, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0x3f, 0x1f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, + 0x03, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0x00, 0xff, + 0x03, 0xff, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xef, + 0x0f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x03, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xe3, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0xff, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0x6f, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x3f, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xaa, 0xff, 0xff, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x5f, 0xdc, 0x1f, 0xcf, 0x0f, 0xff, - 0x1f, 0xdc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0xff, 0x1f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, - 0xfc, 0x2f, 0x3e, 0x50, 0xbd, 0xff, 0xf3, 0xe0, 0x43, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0x1f, 0x00, 0xff, 0xff, 0x3f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x3f, 0xff, 0xaa, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xdf, 0x5f, 0xdc, 0x1f, 0xcf, 0x0f, 0xff, 0x1f, 0xdc, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x80, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xfc, 0x2f, 0x3e, 0x50, + 0xbd, 0xff, 0xf3, 0xe0, 0x43, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x78, 0x0c, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xbf, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1f, 0x78, 0x0c, 0x00, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0xff, + 0xff, 0x7f, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x03, 0x3e, 0x1f, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xfe, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xe0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x1f, 0xff, 0xff, 0xff, - 0x0f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, 0x8f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xbf, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, - 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x80, 0xff, 0x03, 0xff, - 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, - 0x3f, 0xff, 0x03, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x7f, 0x05, 0x00, 0x00, 0x38, 0xff, 0xff, 0x3c, 0x00, 0x7e, - 0x7e, 0x7e, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x00, 0x00, 0x00, 0xfe, 0x03, 0x3e, 0x1f, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x7f, 0xf8, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf8, 0xe0, 0xff, 0xfd, 0x7f, 0x5f, 0xdb, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, - 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, - 0x00, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xc0, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, - 0xfc, 0xfc, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, 0xff, 0xff, 0x7f, - 0xff, 0xff, 0xb7, 0xff, 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, - 0xe0, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, - 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x3e, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, - 0x03, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x3f, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xf0, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2f, 0x00, 0xff, 0x03, 0x00, + 0x00, 0xfc, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, + 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xf7, 0xff, 0x00, 0x80, 0xff, 0x03, 0xff, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, 0x3f, 0xff, 0x03, 0xff, + 0xff, 0x7f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x05, + 0x00, 0x00, 0x38, 0xff, 0xff, 0x3c, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x7f, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0xff, 0xff, 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xf8, 0xe0, 0xff, + 0xfd, 0x7f, 0x5f, 0xdb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x03, 0xfe, + 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, 0xc0, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfc, 0xfc, 0xfc, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xef, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xb7, 0xff, + 0x3f, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x7f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x91, 0xff, - 0xff, 0x3f, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0x00, 0xff, - 0xff, 0x3f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xf0, 0xef, 0xfe, 0xff, - 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, - 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, - 0xff, 0x3f, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0xff, 0xff, + 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0xff, 0x0f, 0xff, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x03, 0xff, 0xff, 0xff, + 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0xff, + 0xff, 0x3f, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x91, 0xff, 0xff, 0x3f, 0x00, 0xff, + 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x37, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, + 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6f, 0xf0, 0xef, 0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0xff, 0xff, 0x3f, 0x00, 0xff, + 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x1f, 0x80, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xfc, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, + 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0x70, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x1e, 0x00, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xfb, 0xff, 0xff, 0xff, 0x9f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0xbd, 0xff, 0xbf, 0xff, 0x01, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xef, 0x9f, 0xf9, 0xff, 0xff, + 0xfd, 0xed, 0xe3, 0x9f, 0x19, 0x81, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbb, + 0x07, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xb3, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x7f, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x7f, 0x11, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x07, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1a, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0x7f, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, + 0xfd, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x01, 0x00, 0xff, 0x03, 0x00, + 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xfe, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfb, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0xb4, 0xcb, 0x00, 0xff, 0x03, 0xbf, 0xfd, 0xff, 0xff, 0xff, + 0x7f, 0x7b, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x00, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xc0, - 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, - 0x00, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xc7, 0xff, 0x70, 0x00, 0xff, 0xff, 0xff, 0xff, 0x47, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e, 0x00, 0xff, 0x17, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x9f, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xbd, 0xff, 0xbf, 0xff, - 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, 0x03, 0xef, - 0x9f, 0xf9, 0xff, 0xff, 0xfd, 0xed, 0xe3, 0x9f, 0x19, 0x81, 0xe0, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xbb, 0x07, 0xff, 0x83, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb3, 0x00, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x3f, 0x7f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x11, 0x00, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x01, 0xff, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0xff, - 0x07, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x80, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xfc, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xe7, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x01, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x01, - 0x00, 0xff, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, - 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, - 0xfb, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xb4, 0xcb, 0x00, 0xff, 0x03, 0xbf, - 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x7b, 0x01, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x7f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0x3f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, - 0x00, 0xff, 0x03, 0xf8, 0xff, 0xff, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0xff, + 0xff, 0xff, 0x7f, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x0f, 0x00, 0xff, 0x03, 0xf8, + 0xff, 0xff, 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xf0, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x07, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x07, 0xff, 0x1f, 0xff, 0x01, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xdf, 0x64, 0xde, 0xff, 0xeb, 0xef, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xbf, 0xe7, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0x7b, 0x5f, - 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0x1f, 0xff, + 0x01, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0x64, + 0xde, 0xff, 0xeb, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, + 0xe7, 0xdf, 0xdf, 0xff, 0xff, 0xff, 0x7b, 0x5f, 0xfc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xfd, - 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xdf, 0xff, 0xff, - 0xff, 0xdf, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, - 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xcf, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x1f, 0x80, 0x3f, 0xff, 0x43, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xf7, 0xff, + 0xff, 0xff, 0xf7, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, + 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, + 0xfd, 0xff, 0xff, 0xf7, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xf9, 0xdb, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x1f, 0x80, 0x3f, 0xff, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x08, 0xff, 0x03, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x8f, 0x08, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xff, 0x96, - 0xfe, 0xf7, 0x0a, 0x84, 0xea, 0x96, 0xaa, 0x96, 0xf7, 0xf7, 0x5e, 0xff, - 0xfb, 0xff, 0x0f, 0xee, 0xfb, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, - 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, - 0xe0, 0xff, 0xff, 0x00, 0xbf, 0x1d, 0x00, 0x00, 0xe7, 0x02, 0x00, 0x00, - 0x79, 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, - 0xfe, 0xff, 0xff, 0x01, 0x39, 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, 0x01, - 0x87, 0xff, 0xff, 0x00, 0xd4, 0xfe, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x01, - 0xd2, 0x00, 0x00, 0x01, 0xce, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x01, - 0x4f, 0x00, 0x00, 0x01, 0xca, 0x00, 0x00, 0x01, 0xcb, 0x00, 0x00, 0x01, - 0xcf, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x01, - 0xd1, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x01, 0xd5, 0x00, 0x00, 0x00, - 0x82, 0x00, 0x00, 0x01, 0xd6, 0x00, 0x00, 0x01, 0xda, 0x00, 0x00, 0x01, - 0xd9, 0x00, 0x00, 0x01, 0xdb, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0xb1, 0xff, 0xff, 0x01, 0x9f, 0xff, 0xff, 0x01, - 0xc8, 0xff, 0xff, 0x02, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x33, 0xff, 0xff, 0x00, - 0x26, 0xff, 0xff, 0x01, 0x7e, 0xff, 0xff, 0x01, 0x2b, 0x2a, 0x00, 0x01, - 0x5d, 0xff, 0xff, 0x01, 0x28, 0x2a, 0x00, 0x00, 0x3f, 0x2a, 0x00, 0x01, - 0x3d, 0xff, 0xff, 0x01, 0x45, 0x00, 0x00, 0x01, 0x47, 0x00, 0x00, 0x00, - 0x1f, 0x2a, 0x00, 0x00, 0x1c, 0x2a, 0x00, 0x00, 0x1e, 0x2a, 0x00, 0x00, - 0x2e, 0xff, 0xff, 0x00, 0x32, 0xff, 0xff, 0x00, 0x36, 0xff, 0xff, 0x00, - 0x35, 0xff, 0xff, 0x00, 0x4f, 0xa5, 0x00, 0x00, 0x4b, 0xa5, 0x00, 0x00, - 0x31, 0xff, 0xff, 0x00, 0x28, 0xa5, 0x00, 0x00, 0x44, 0xa5, 0x00, 0x00, - 0x2f, 0xff, 0xff, 0x00, 0x2d, 0xff, 0xff, 0x00, 0xf7, 0x29, 0x00, 0x00, - 0x41, 0xa5, 0x00, 0x00, 0xfd, 0x29, 0x00, 0x00, 0x2b, 0xff, 0xff, 0x00, - 0x2a, 0xff, 0xff, 0x00, 0xe7, 0x29, 0x00, 0x00, 0x43, 0xa5, 0x00, 0x00, - 0x2a, 0xa5, 0x00, 0x00, 0xbb, 0xff, 0xff, 0x00, 0x27, 0xff, 0xff, 0x00, - 0xb9, 0xff, 0xff, 0x00, 0x25, 0xff, 0xff, 0x00, 0x15, 0xa5, 0x00, 0x00, - 0x12, 0xa5, 0x00, 0x02, 0x24, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x00, 0x54, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, - 0x26, 0x00, 0x00, 0x01, 0x25, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, - 0x3f, 0x00, 0x00, 0x00, 0xda, 0xff, 0xff, 0x00, 0xdb, 0xff, 0xff, 0x00, - 0xe1, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc1, 0xff, 0xff, 0x01, - 0x08, 0x00, 0x00, 0x00, 0xc2, 0xff, 0xff, 0x00, 0xc7, 0xff, 0xff, 0x00, - 0xd1, 0xff, 0xff, 0x00, 0xca, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0x00, - 0xaa, 0xff, 0xff, 0x00, 0xb0, 0xff, 0xff, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x8c, 0xff, 0xff, 0x01, 0xc4, 0xff, 0xff, 0x00, 0xa0, 0xff, 0xff, 0x01, - 0xf9, 0xff, 0xff, 0x02, 0x1a, 0x70, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, - 0x50, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x01, - 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x0b, 0x00, 0x01, 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xd0, 0x97, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x02, - 0x05, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0xf4, 0xff, 0x00, - 0x9e, 0xe7, 0xff, 0x00, 0xc2, 0x89, 0x00, 0x00, 0xdb, 0xe7, 0xff, 0x00, - 0x92, 0xe7, 0xff, 0x00, 0x93, 0xe7, 0xff, 0x00, 0x9c, 0xe7, 0xff, 0x00, - 0x9d, 0xe7, 0xff, 0x00, 0xa4, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x8a, 0x00, 0x00, 0x04, 0x8a, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc5, 0xff, 0xff, 0x01, 0x41, 0xe2, 0xff, 0x02, 0x1d, 0x8f, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x01, 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x56, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x4a, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, - 0x7e, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x01, 0xb6, 0xff, 0xff, 0x01, - 0xf7, 0xff, 0xff, 0x00, 0xdb, 0xe3, 0xff, 0x01, 0x9c, 0xff, 0xff, 0x01, - 0x90, 0xff, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x82, 0xff, 0xff, 0x02, - 0x05, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, - 0xf0, 0xff, 0xff, 0x01, 0x1c, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, - 0xa3, 0xe2, 0xff, 0x01, 0x41, 0xdf, 0xff, 0x01, 0xba, 0xdf, 0xff, 0x00, - 0xe4, 0xff, 0xff, 0x02, 0x0b, 0xb1, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x01, 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x09, 0xd6, 0xff, 0x01, 0x1a, 0xf1, 0xff, 0x01, - 0x19, 0xd6, 0xff, 0x00, 0xd5, 0xd5, 0xff, 0x00, 0xd8, 0xd5, 0xff, 0x01, - 0xe4, 0xd5, 0xff, 0x01, 0x03, 0xd6, 0xff, 0x01, 0xe1, 0xd5, 0xff, 0x01, - 0xe2, 0xd5, 0xff, 0x01, 0xc1, 0xd5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa0, 0xe3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x02, 0x0c, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, 0xbc, 0x5a, 0xff, 0x01, - 0xa0, 0x03, 0x00, 0x01, 0xfc, 0x75, 0xff, 0x01, 0xd8, 0x5a, 0xff, 0x00, - 0x30, 0x00, 0x00, 0x01, 0xb1, 0x5a, 0xff, 0x01, 0xb5, 0x5a, 0xff, 0x01, - 0xbf, 0x5a, 0xff, 0x01, 0xee, 0x5a, 0xff, 0x01, 0xd6, 0x5a, 0xff, 0x01, - 0xeb, 0x5a, 0xff, 0x01, 0xd0, 0xff, 0xff, 0x01, 0xbd, 0x5a, 0xff, 0x01, - 0xc8, 0x75, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x68, 0xff, 0x00, - 0x60, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, - 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x28, 0x00, 0x00, 0x00, - 0xd8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, - 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, - 0xe0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, - 0xde, 0xff, 0xff, 0x30, 0x0c, 0x31, 0x0d, 0x78, 0x0e, 0x7f, 0x0f, 0x80, - 0x10, 0x81, 0x11, 0x86, 0x12, 0x89, 0x13, 0x8a, 0x13, 0x8e, 0x14, 0x8f, - 0x15, 0x90, 0x16, 0x93, 0x13, 0x94, 0x17, 0x95, 0x18, 0x96, 0x19, 0x97, - 0x1a, 0x9a, 0x1b, 0x9c, 0x19, 0x9d, 0x1c, 0x9e, 0x1d, 0x9f, 0x1e, 0xa6, - 0x1f, 0xa9, 0x1f, 0xae, 0x1f, 0xb1, 0x20, 0xb2, 0x20, 0xb7, 0x21, 0xbf, - 0x22, 0xc5, 0x23, 0xc8, 0x23, 0xcb, 0x23, 0xdd, 0x24, 0xf2, 0x23, 0xf6, - 0x25, 0xf7, 0x26, 0x20, 0x2d, 0x3a, 0x2e, 0x3d, 0x2f, 0x3e, 0x30, 0x3f, - 0x31, 0x40, 0x31, 0x43, 0x32, 0x44, 0x33, 0x45, 0x34, 0x50, 0x35, 0x51, - 0x36, 0x52, 0x37, 0x53, 0x38, 0x54, 0x39, 0x59, 0x3a, 0x5b, 0x3b, 0x5c, - 0x3c, 0x61, 0x3d, 0x63, 0x3e, 0x65, 0x3f, 0x66, 0x40, 0x68, 0x41, 0x69, - 0x42, 0x6a, 0x40, 0x6b, 0x43, 0x6c, 0x44, 0x6f, 0x42, 0x71, 0x45, 0x72, - 0x46, 0x75, 0x47, 0x7d, 0x48, 0x82, 0x49, 0x87, 0x4a, 0x89, 0x4b, 0x8a, - 0x4c, 0x8b, 0x4c, 0x8c, 0x4d, 0x92, 0x4e, 0x9d, 0x4f, 0x9e, 0x50, 0x45, - 0x57, 0x7b, 0x1d, 0x7c, 0x1d, 0x7d, 0x1d, 0x7f, 0x58, 0x86, 0x59, 0x88, - 0x5a, 0x89, 0x5a, 0x8a, 0x5a, 0x8c, 0x5b, 0x8e, 0x5c, 0x8f, 0x5c, 0xac, - 0x5d, 0xad, 0x5e, 0xae, 0x5e, 0xaf, 0x5e, 0xc2, 0x5f, 0xcc, 0x60, 0xcd, - 0x61, 0xce, 0x61, 0xcf, 0x62, 0xd0, 0x63, 0xd1, 0x64, 0xd5, 0x65, 0xd6, - 0x66, 0xd7, 0x67, 0xf0, 0x68, 0xf1, 0x69, 0xf2, 0x6a, 0xf3, 0x6b, 0xf4, - 0x6c, 0xf5, 0x6d, 0xf9, 0x6e, 0xfd, 0x2d, 0xfe, 0x2d, 0xff, 0x2d, 0x50, - 0x69, 0x51, 0x69, 0x52, 0x69, 0x53, 0x69, 0x54, 0x69, 0x55, 0x69, 0x56, - 0x69, 0x57, 0x69, 0x58, 0x69, 0x59, 0x69, 0x5a, 0x69, 0x5b, 0x69, 0x5c, - 0x69, 0x5d, 0x69, 0x5e, 0x69, 0x5f, 0x69, 0x82, 0x00, 0x83, 0x00, 0x84, - 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0xc0, - 0x75, 0xcf, 0x76, 0x80, 0x89, 0x81, 0x8a, 0x82, 0x8b, 0x85, 0x8c, 0x86, - 0x8d, 0x70, 0x9d, 0x71, 0x9d, 0x76, 0x9e, 0x77, 0x9e, 0x78, 0x9f, 0x79, - 0x9f, 0x7a, 0xa0, 0x7b, 0xa0, 0x7c, 0xa1, 0x7d, 0xa1, 0xb3, 0xa2, 0xba, - 0xa3, 0xbb, 0xa3, 0xbc, 0xa4, 0xbe, 0xa5, 0xc3, 0xa2, 0xcc, 0xa4, 0xda, - 0xa6, 0xdb, 0xa6, 0xe5, 0x6a, 0xea, 0xa7, 0xeb, 0xa7, 0xec, 0x6e, 0xf3, - 0xa2, 0xf8, 0xa8, 0xf9, 0xa8, 0xfa, 0xa9, 0xfb, 0xa9, 0xfc, 0xa4, 0x26, - 0xb0, 0x2a, 0xb1, 0x2b, 0xb2, 0x4e, 0xb3, 0x84, 0x08, 0x62, 0xba, 0x63, - 0xbb, 0x64, 0xbc, 0x65, 0xbd, 0x66, 0xbe, 0x6d, 0xbf, 0x6e, 0xc0, 0x6f, - 0xc1, 0x70, 0xc2, 0x7e, 0xc3, 0x7f, 0xc3, 0x7d, 0xcf, 0x8d, 0xd0, 0x94, - 0xd1, 0xab, 0xd2, 0xac, 0xd3, 0xad, 0xd4, 0xb0, 0xd5, 0xb1, 0xd6, 0xb2, - 0xd7, 0xc4, 0xd8, 0xc5, 0xd9, 0xc6, 0xda, 0x07, 0x08, 0x09, 0x0a, 0x0b, - 0x0c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0d, - 0x06, 0x06, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0f, - 0x10, 0x11, 0x12, 0x06, 0x13, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x14, 0x15, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x00, 0x00, 0x00, 0xef, 0xff, 0xff, 0xff, 0x96, 0xfe, 0xf7, 0x0a, 0x84, + 0xea, 0x96, 0xaa, 0x96, 0xf7, 0xf7, 0x5e, 0xff, 0xfb, 0xff, 0x0f, 0xee, + 0xfb, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, + 0x03, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x56, + 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, + 0xbf, 0x1d, 0x00, 0x00, 0xe7, 0x02, 0x00, 0x00, 0x79, 0x00, 0x00, 0x02, + 0x24, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, + 0x39, 0xff, 0xff, 0x00, 0x18, 0xff, 0xff, 0x01, 0x87, 0xff, 0xff, 0x00, + 0xd4, 0xfe, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x01, 0xd2, 0x00, 0x00, 0x01, + 0xce, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x01, 0x4f, 0x00, 0x00, 0x01, + 0xca, 0x00, 0x00, 0x01, 0xcb, 0x00, 0x00, 0x01, 0xcf, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x00, 0x01, 0xd3, 0x00, 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, + 0xa3, 0x00, 0x00, 0x01, 0xd5, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x01, + 0xd6, 0x00, 0x00, 0x01, 0xda, 0x00, 0x00, 0x01, 0xd9, 0x00, 0x00, 0x01, + 0xdb, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0xb1, 0xff, 0xff, 0x01, 0x9f, 0xff, 0xff, 0x01, 0xc8, 0xff, 0xff, 0x02, + 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x33, 0xff, 0xff, 0x00, 0x26, 0xff, 0xff, 0x01, + 0x7e, 0xff, 0xff, 0x01, 0x2b, 0x2a, 0x00, 0x01, 0x5d, 0xff, 0xff, 0x01, + 0x28, 0x2a, 0x00, 0x00, 0x3f, 0x2a, 0x00, 0x01, 0x3d, 0xff, 0xff, 0x01, + 0x45, 0x00, 0x00, 0x01, 0x47, 0x00, 0x00, 0x00, 0x1f, 0x2a, 0x00, 0x00, + 0x1c, 0x2a, 0x00, 0x00, 0x1e, 0x2a, 0x00, 0x00, 0x2e, 0xff, 0xff, 0x00, + 0x32, 0xff, 0xff, 0x00, 0x36, 0xff, 0xff, 0x00, 0x35, 0xff, 0xff, 0x00, + 0x4f, 0xa5, 0x00, 0x00, 0x4b, 0xa5, 0x00, 0x00, 0x31, 0xff, 0xff, 0x00, + 0x28, 0xa5, 0x00, 0x00, 0x44, 0xa5, 0x00, 0x00, 0x2f, 0xff, 0xff, 0x00, + 0x2d, 0xff, 0xff, 0x00, 0xf7, 0x29, 0x00, 0x00, 0x41, 0xa5, 0x00, 0x00, + 0xfd, 0x29, 0x00, 0x00, 0x2b, 0xff, 0xff, 0x00, 0x2a, 0xff, 0xff, 0x00, + 0xe7, 0x29, 0x00, 0x00, 0x43, 0xa5, 0x00, 0x00, 0x2a, 0xa5, 0x00, 0x00, + 0xbb, 0xff, 0xff, 0x00, 0x27, 0xff, 0xff, 0x00, 0xb9, 0xff, 0xff, 0x00, + 0x25, 0xff, 0xff, 0x00, 0x15, 0xa5, 0x00, 0x00, 0x12, 0xa5, 0x00, 0x02, + 0x24, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, + 0xe0, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, + 0x54, 0x00, 0x00, 0x01, 0x74, 0x00, 0x00, 0x01, 0x26, 0x00, 0x00, 0x01, + 0x25, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, 0x00, + 0xda, 0xff, 0xff, 0x00, 0xdb, 0xff, 0xff, 0x00, 0xe1, 0xff, 0xff, 0x00, + 0xc0, 0xff, 0xff, 0x00, 0xc1, 0xff, 0xff, 0x01, 0x08, 0x00, 0x00, 0x00, + 0xc2, 0xff, 0xff, 0x00, 0xc7, 0xff, 0xff, 0x00, 0xd1, 0xff, 0xff, 0x00, + 0xca, 0xff, 0xff, 0x00, 0xf8, 0xff, 0xff, 0x00, 0xaa, 0xff, 0xff, 0x00, + 0xb0, 0xff, 0xff, 0x00, 0x07, 0x00, 0x00, 0x00, 0x8c, 0xff, 0xff, 0x01, + 0xc4, 0xff, 0xff, 0x00, 0xa0, 0xff, 0xff, 0x01, 0xf9, 0xff, 0xff, 0x02, + 0x1a, 0x70, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, + 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x01, 0x50, 0x00, 0x00, 0x01, + 0x0f, 0x00, 0x00, 0x00, 0xf1, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x01, + 0x60, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xd0, 0x97, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0x02, 0x05, 0x8a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x40, 0xf4, 0xff, 0x00, 0x9e, 0xe7, 0xff, 0x00, + 0xc2, 0x89, 0x00, 0x00, 0xdb, 0xe7, 0xff, 0x00, 0x92, 0xe7, 0xff, 0x00, + 0x93, 0xe7, 0xff, 0x00, 0x9c, 0xe7, 0xff, 0x00, 0x9d, 0xe7, 0xff, 0x00, + 0xa4, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x8a, 0x00, 0x00, + 0x04, 0x8a, 0x00, 0x00, 0xe6, 0x0e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xff, 0xff, 0x01, + 0x41, 0xe2, 0xff, 0x02, 0x1d, 0x8f, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, + 0xf8, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x01, + 0xaa, 0xff, 0xff, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x01, 0xb6, 0xff, 0xff, 0x01, 0xf7, 0xff, 0xff, 0x00, + 0xdb, 0xe3, 0xff, 0x01, 0x9c, 0xff, 0xff, 0x01, 0x90, 0xff, 0xff, 0x01, + 0x80, 0xff, 0xff, 0x01, 0x82, 0xff, 0xff, 0x02, 0x05, 0xac, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x01, + 0x1c, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0xa3, 0xe2, 0xff, 0x01, + 0x41, 0xdf, 0xff, 0x01, 0xba, 0xdf, 0xff, 0x00, 0xe4, 0xff, 0xff, 0x02, + 0x0b, 0xb1, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x01, + 0x30, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x09, 0xd6, 0xff, 0x01, 0x1a, 0xf1, 0xff, 0x01, 0x19, 0xd6, 0xff, 0x00, + 0xd5, 0xd5, 0xff, 0x00, 0xd8, 0xd5, 0xff, 0x01, 0xe4, 0xd5, 0xff, 0x01, + 0x03, 0xd6, 0xff, 0x01, 0xe1, 0xd5, 0xff, 0x01, 0xe2, 0xd5, 0xff, 0x01, + 0xc1, 0xd5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xe3, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x02, + 0x0c, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x01, 0xbc, 0x5a, 0xff, 0x01, 0xa0, 0x03, 0x00, 0x01, + 0xfc, 0x75, 0xff, 0x01, 0xd8, 0x5a, 0xff, 0x00, 0x30, 0x00, 0x00, 0x01, + 0xb1, 0x5a, 0xff, 0x01, 0xb5, 0x5a, 0xff, 0x01, 0xbf, 0x5a, 0xff, 0x01, + 0xee, 0x5a, 0xff, 0x01, 0xd6, 0x5a, 0xff, 0x01, 0xeb, 0x5a, 0xff, 0x01, + 0xd0, 0xff, 0xff, 0x01, 0xbd, 0x5a, 0xff, 0x01, 0xc8, 0x75, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x68, 0xff, 0x00, 0x60, 0xfc, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x28, 0x00, 0x00, 0x00, 0xd8, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x22, 0x00, 0x00, 0x00, 0xde, 0xff, 0xff, 0x30, + 0x0c, 0x31, 0x0d, 0x78, 0x0e, 0x7f, 0x0f, 0x80, 0x10, 0x81, 0x11, 0x86, + 0x12, 0x89, 0x13, 0x8a, 0x13, 0x8e, 0x14, 0x8f, 0x15, 0x90, 0x16, 0x93, + 0x13, 0x94, 0x17, 0x95, 0x18, 0x96, 0x19, 0x97, 0x1a, 0x9a, 0x1b, 0x9c, + 0x19, 0x9d, 0x1c, 0x9e, 0x1d, 0x9f, 0x1e, 0xa6, 0x1f, 0xa9, 0x1f, 0xae, + 0x1f, 0xb1, 0x20, 0xb2, 0x20, 0xb7, 0x21, 0xbf, 0x22, 0xc5, 0x23, 0xc8, + 0x23, 0xcb, 0x23, 0xdd, 0x24, 0xf2, 0x23, 0xf6, 0x25, 0xf7, 0x26, 0x20, + 0x2d, 0x3a, 0x2e, 0x3d, 0x2f, 0x3e, 0x30, 0x3f, 0x31, 0x40, 0x31, 0x43, + 0x32, 0x44, 0x33, 0x45, 0x34, 0x50, 0x35, 0x51, 0x36, 0x52, 0x37, 0x53, + 0x38, 0x54, 0x39, 0x59, 0x3a, 0x5b, 0x3b, 0x5c, 0x3c, 0x61, 0x3d, 0x63, + 0x3e, 0x65, 0x3f, 0x66, 0x40, 0x68, 0x41, 0x69, 0x42, 0x6a, 0x40, 0x6b, + 0x43, 0x6c, 0x44, 0x6f, 0x42, 0x71, 0x45, 0x72, 0x46, 0x75, 0x47, 0x7d, + 0x48, 0x82, 0x49, 0x87, 0x4a, 0x89, 0x4b, 0x8a, 0x4c, 0x8b, 0x4c, 0x8c, + 0x4d, 0x92, 0x4e, 0x9d, 0x4f, 0x9e, 0x50, 0x45, 0x57, 0x7b, 0x1d, 0x7c, + 0x1d, 0x7d, 0x1d, 0x7f, 0x58, 0x86, 0x59, 0x88, 0x5a, 0x89, 0x5a, 0x8a, + 0x5a, 0x8c, 0x5b, 0x8e, 0x5c, 0x8f, 0x5c, 0xac, 0x5d, 0xad, 0x5e, 0xae, + 0x5e, 0xaf, 0x5e, 0xc2, 0x5f, 0xcc, 0x60, 0xcd, 0x61, 0xce, 0x61, 0xcf, + 0x62, 0xd0, 0x63, 0xd1, 0x64, 0xd5, 0x65, 0xd6, 0x66, 0xd7, 0x67, 0xf0, + 0x68, 0xf1, 0x69, 0xf2, 0x6a, 0xf3, 0x6b, 0xf4, 0x6c, 0xf5, 0x6d, 0xf9, + 0x6e, 0xfd, 0x2d, 0xfe, 0x2d, 0xff, 0x2d, 0x50, 0x69, 0x51, 0x69, 0x52, + 0x69, 0x53, 0x69, 0x54, 0x69, 0x55, 0x69, 0x56, 0x69, 0x57, 0x69, 0x58, + 0x69, 0x59, 0x69, 0x5a, 0x69, 0x5b, 0x69, 0x5c, 0x69, 0x5d, 0x69, 0x5e, + 0x69, 0x5f, 0x69, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, + 0x00, 0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0xc0, 0x75, 0xcf, 0x76, 0x80, + 0x89, 0x81, 0x8a, 0x82, 0x8b, 0x85, 0x8c, 0x86, 0x8d, 0x70, 0x9d, 0x71, + 0x9d, 0x76, 0x9e, 0x77, 0x9e, 0x78, 0x9f, 0x79, 0x9f, 0x7a, 0xa0, 0x7b, + 0xa0, 0x7c, 0xa1, 0x7d, 0xa1, 0xb3, 0xa2, 0xba, 0xa3, 0xbb, 0xa3, 0xbc, + 0xa4, 0xbe, 0xa5, 0xc3, 0xa2, 0xcc, 0xa4, 0xda, 0xa6, 0xdb, 0xa6, 0xe5, + 0x6a, 0xea, 0xa7, 0xeb, 0xa7, 0xec, 0x6e, 0xf3, 0xa2, 0xf8, 0xa8, 0xf9, + 0xa8, 0xfa, 0xa9, 0xfb, 0xa9, 0xfc, 0xa4, 0x26, 0xb0, 0x2a, 0xb1, 0x2b, + 0xb2, 0x4e, 0xb3, 0x84, 0x08, 0x62, 0xba, 0x63, 0xbb, 0x64, 0xbc, 0x65, + 0xbd, 0x66, 0xbe, 0x6d, 0xbf, 0x6e, 0xc0, 0x6f, 0xc1, 0x70, 0xc2, 0x7e, + 0xc3, 0x7f, 0xc3, 0x7d, 0xcf, 0x8d, 0xd0, 0x94, 0xd1, 0xab, 0xd2, 0xac, + 0xd3, 0xad, 0xd4, 0xb0, 0xd5, 0xb1, 0xd6, 0xb2, 0xd7, 0xc4, 0xd8, 0xc5, + 0xd9, 0xc6, 0xda, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x06, 0x06, 0x0e, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0f, 0x10, 0x11, 0x12, 0x06, + 0x13, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x14, + 0x15, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, @@ -1017,24 +946,23 @@ unsigned char STDLIB_WASM[] = { 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x16, 0x17, 0x06, 0x06, 0x06, 0x18, 0x06, + 0x06, 0x16, 0x17, 0x06, 0x06, 0x06, 0x18, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x19, 0x06, - 0x06, 0x06, 0x06, 0x1a, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1b, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1c, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x19, 0x06, 0x06, 0x06, 0x06, 0x1a, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1b, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1c, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1d, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, @@ -1044,9 +972,9 @@ unsigned char STDLIB_WASM[] = { 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, - 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1055,182 +983,182 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, - 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x2b, 0x5b, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x4a, 0x56, 0x56, 0x05, 0x31, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, + 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x2b, 0x5b, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x4a, 0x56, 0x56, 0x05, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x24, + 0x50, 0x79, 0x31, 0x50, 0x31, 0x50, 0x31, 0x38, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, + 0x31, 0x02, 0x4e, 0x0d, 0x0d, 0x4e, 0x03, 0x4e, 0x00, 0x24, 0x6e, 0x00, + 0x4e, 0x31, 0x26, 0x6e, 0x51, 0x4e, 0x24, 0x50, 0x4e, 0x39, 0x14, 0x81, + 0x1b, 0x1d, 0x1d, 0x53, 0x31, 0x50, 0x31, 0x50, 0x0d, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x1b, 0x53, 0x24, 0x50, 0x31, 0x02, 0x5c, 0x7b, 0x5c, + 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x14, 0x79, 0x5c, 0x7b, 0x5c, + 0x7b, 0x5c, 0x2d, 0x2b, 0x49, 0x03, 0x48, 0x03, 0x78, 0x5c, 0x7b, 0x14, + 0x00, 0x96, 0x0a, 0x01, 0x2b, 0x28, 0x06, 0x06, 0x00, 0x2a, 0x06, 0x2a, + 0x2a, 0x2b, 0x07, 0xbb, 0xb5, 0x2b, 0x1e, 0x00, 0x2b, 0x07, 0x2b, 0x2b, + 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0xcd, 0x46, 0xcd, 0x2b, 0x00, 0x25, 0x2b, 0x07, 0x01, 0x06, 0x01, 0x55, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x55, 0x56, 0x56, 0x02, 0x24, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x15, 0x81, 0x81, 0x81, 0x00, 0x00, 0x2b, 0x00, 0xb2, + 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0x00, 0x00, 0xcd, 0xcc, 0x01, + 0x00, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x83, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, + 0xac, 0xac, 0xac, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x24, 0x50, 0x79, 0x31, 0x50, 0x31, 0x50, 0x31, 0x38, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x4e, 0x31, 0x02, 0x4e, 0x0d, 0x0d, 0x4e, 0x03, 0x4e, - 0x00, 0x24, 0x6e, 0x00, 0x4e, 0x31, 0x26, 0x6e, 0x51, 0x4e, 0x24, 0x50, - 0x4e, 0x39, 0x14, 0x81, 0x1b, 0x1d, 0x1d, 0x53, 0x31, 0x50, 0x31, 0x50, - 0x0d, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x1b, 0x53, 0x24, 0x50, 0x31, - 0x02, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x14, - 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x49, 0x03, 0x48, 0x03, - 0x78, 0x5c, 0x7b, 0x14, 0x00, 0x96, 0x0a, 0x01, 0x2b, 0x28, 0x06, 0x06, - 0x00, 0x2a, 0x06, 0x2a, 0x2a, 0x2b, 0x07, 0xbb, 0xb5, 0x2b, 0x1e, 0x00, - 0x2b, 0x07, 0x2b, 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x50, 0x31, 0x02, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, + 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x54, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0c, + 0x00, 0x0c, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x6c, 0x81, 0x15, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0xcd, 0x46, 0xcd, 0x2b, 0x00, 0x25, 0x2b, 0x07, - 0x01, 0x06, 0x01, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x55, 0x56, 0x56, - 0x02, 0x24, 0x81, 0x81, 0x81, 0x81, 0x81, 0x15, 0x81, 0x81, 0x81, 0x00, - 0x00, 0x2b, 0x00, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0xb2, 0xd1, 0x00, - 0x00, 0xcd, 0xcc, 0x01, 0x00, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0x83, 0x81, - 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xac, 0xac, 0xac, - 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x02, 0x00, 0x00, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x4e, 0x31, 0x50, - 0x31, 0x50, 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x02, 0x87, 0xa6, 0x87, 0xa6, 0x87, - 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x87, 0xa6, 0x2a, + 0x2b, 0x2b, 0x2b, 0x07, 0x6c, 0x03, 0x41, 0x2b, 0x2b, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x2c, + 0x56, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x56, 0x7a, 0x9e, 0x26, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, + 0x25, 0x06, 0x01, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, + 0x56, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, + 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x81, 0x37, 0x75, 0x5b, 0x7b, 0x5c, 0x2b, + 0x2b, 0x4f, 0x56, 0x56, 0x02, 0xac, 0x04, 0x00, 0x00, 0x39, 0x2b, 0x2b, + 0x55, 0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x2b, 0x56, + 0x56, 0x32, 0x13, 0x81, 0x57, 0x00, 0x6f, 0x81, 0x7e, 0xc9, 0xd7, 0x7e, + 0x2d, 0x81, 0x81, 0x0e, 0x7e, 0x39, 0x7f, 0x6f, 0x57, 0x00, 0x81, 0x81, + 0x7e, 0x15, 0x00, 0x7e, 0x03, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x24, 0x2b, 0x97, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x80, 0x81, 0x81, 0x81, 0x81, 0x39, + 0xbb, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x00, 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xc9, 0xac, + 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, + 0xac, 0xac, 0xd0, 0x0d, 0x00, 0x4e, 0x31, 0x02, 0xb4, 0xc1, 0xc1, 0xd7, + 0xd7, 0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0xd7, + 0xd7, 0x53, 0xc1, 0x47, 0xd4, 0xd7, 0xd7, 0xd7, 0x05, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, + 0x50, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x54, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x0c, 0x00, 0x0c, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2a, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, + 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, + 0x7b, 0x5c, 0x2d, 0x2b, 0x2b, 0x79, 0x14, 0x5c, 0x7b, 0x5c, 0x2d, 0x79, + 0x2a, 0x5c, 0x27, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0xa4, 0x00, 0x0a, + 0xb4, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x03, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x07, 0x00, 0x48, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x6c, 0x81, 0x15, - 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x6c, 0x03, 0x41, 0x2b, - 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x2c, 0x56, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x56, 0x7a, 0x9e, 0x26, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, - 0x25, 0x06, 0x25, 0x06, 0x25, 0x06, 0x01, 0x2b, 0x2b, 0x4f, 0x56, 0x56, - 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, - 0x2b, 0x4f, 0x56, 0x56, 0x2c, 0x2b, 0x7f, 0x56, 0x56, 0x81, 0x37, 0x75, - 0x5b, 0x7b, 0x5c, 0x2b, 0x2b, 0x4f, 0x56, 0x56, 0x02, 0xac, 0x04, 0x00, - 0x00, 0x39, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x2b, 0x2b, 0x4f, 0x56, 0x56, - 0x2c, 0x2b, 0x2b, 0x56, 0x56, 0x32, 0x13, 0x81, 0x57, 0x00, 0x6f, 0x81, - 0x7e, 0xc9, 0xd7, 0x7e, 0x2d, 0x81, 0x81, 0x0e, 0x7e, 0x39, 0x7f, 0x6f, - 0x57, 0x00, 0x81, 0x81, 0x7e, 0x15, 0x00, 0x7e, 0x03, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x2b, 0x24, - 0x2b, 0x97, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2a, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x80, 0x81, - 0x81, 0x81, 0x81, 0x39, 0xbb, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x81, - 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, - 0x81, 0x81, 0xc9, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, - 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd0, 0x0d, 0x00, 0x4e, 0x31, 0x02, - 0xb4, 0xc1, 0xc1, 0xd7, 0xd7, 0x24, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0xd7, 0xd7, 0x53, 0xc1, 0x47, 0xd4, 0xd7, 0xd7, 0xd7, - 0x05, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4e, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x50, 0x31, - 0x50, 0x31, 0x50, 0x31, 0x50, 0x31, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x79, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x7b, 0x5c, - 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, - 0x7b, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, 0x2d, 0x2b, 0x2b, 0x79, 0x14, 0x5c, - 0x7b, 0x5c, 0x2d, 0x79, 0x2a, 0x5c, 0x27, 0x5c, 0x7b, 0x5c, 0x7b, 0x5c, - 0x7b, 0xa4, 0x00, 0x0a, 0xb4, 0x5c, 0x7b, 0x5c, 0x7b, 0x4f, 0x03, 0x2a, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x48, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x07, 0x00, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, + 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, - 0x56, 0x56, 0x56, 0x56, 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, + 0x2b, 0x2b, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, + 0x56, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x27, 0x51, 0x6f, 0x77, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7f, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x8e, 0x92, 0x97, 0x00, - 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, - 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x27, 0x51, 0x6f, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x83, 0x8e, 0x92, 0x97, 0x00, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1240,23 +1168,24 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xc6, 0xc9, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc9, 0x00, + 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, 0xe1, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1266,101 +1195,42 @@ unsigned char STDLIB_WASM[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, - 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x85, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, - 0x20, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x05, - 0x20, 0x00, 0x00, 0x06, 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x09, - 0x20, 0x00, 0x00, 0x0a, 0x20, 0x00, 0x00, 0x28, 0x20, 0x00, 0x00, 0x29, - 0x20, 0x00, 0x00, 0x5f, 0x20, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x41, 0xe8, 0xc2, 0x04, 0x0b, 0x04, 0x00, 0x00, - 0x02, 0x00, 0x00, 0xb7, 0x05, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x00, 0x0c, - 0x0b, 0x73, 0x74, 0x64, 0x6c, 0x69, 0x62, 0x2e, 0x77, 0x61, 0x73, 0x6d, - 0x01, 0xd9, 0x04, 0x2d, 0x00, 0x2a, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, - 0x72, 0x74, 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x31, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, 0x67, 0x65, 0x74, - 0x01, 0x30, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, - 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x31, 0x5f, - 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, - 0x65, 0x74, 0x02, 0x2b, 0x5f, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x73, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, - 0x31, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x03, - 0x11, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, - 0x5f, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x04, 0x13, 0x75, 0x6e, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x77, 0x65, 0x61, 0x6b, 0x3a, 0x6d, - 0x61, 0x69, 0x6e, 0x05, 0x12, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x6d, 0x5f, - 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x06, - 0x06, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x07, 0x0a, 0x72, 0x65, 0x73, - 0x65, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x70, 0x08, 0x06, 0x6d, 0x61, 0x6c, - 0x6c, 0x6f, 0x63, 0x09, 0x04, 0x66, 0x72, 0x65, 0x65, 0x0a, 0x06, 0x63, - 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x0b, 0x07, 0x72, 0x65, 0x61, 0x6c, 0x6c, - 0x6f, 0x63, 0x0c, 0x05, 0x5f, 0x45, 0x78, 0x69, 0x74, 0x0d, 0x0b, 0x5f, - 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x76, 0x6f, 0x69, 0x64, 0x0e, 0x0f, - 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x5f, - 0x67, 0x65, 0x74, 0x0f, 0x15, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, - 0x61, 0x72, 0x67, 0x73, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x67, - 0x65, 0x74, 0x10, 0x10, 0x5f, 0x5f, 0x77, 0x61, 0x73, 0x69, 0x5f, 0x70, - 0x72, 0x6f, 0x63, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x11, 0x0e, 0x5f, 0x5f, - 0x77, 0x61, 0x73, 0x69, 0x5f, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x74, 0x70, - 0x12, 0x05, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x13, 0x11, 0x5f, 0x5f, 0x77, - 0x61, 0x73, 0x6d, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x5f, 0x64, 0x74, 0x6f, - 0x72, 0x73, 0x14, 0x06, 0x73, 0x74, 0x72, 0x6c, 0x65, 0x6e, 0x15, 0x08, - 0x69, 0x73, 0x77, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x16, 0x06, 0x6d, 0x65, - 0x6d, 0x63, 0x6d, 0x70, 0x17, 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x68, 0x72, - 0x18, 0x06, 0x73, 0x74, 0x72, 0x63, 0x6d, 0x70, 0x19, 0x08, 0x74, 0x6f, - 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x1a, 0x07, 0x63, 0x61, 0x73, 0x65, - 0x6d, 0x61, 0x70, 0x1b, 0x08, 0x74, 0x6f, 0x77, 0x75, 0x70, 0x70, 0x65, - 0x72, 0x1c, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x6d, 0x70, 0x1d, 0x08, - 0x69, 0x73, 0x77, 0x75, 0x70, 0x70, 0x65, 0x72, 0x1e, 0x07, 0x6d, 0x65, - 0x6d, 0x6d, 0x6f, 0x76, 0x65, 0x1f, 0x06, 0x6d, 0x65, 0x6d, 0x73, 0x65, - 0x74, 0x20, 0x08, 0x69, 0x73, 0x77, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x21, - 0x06, 0x6d, 0x65, 0x6d, 0x63, 0x70, 0x79, 0x22, 0x07, 0x69, 0x73, 0x62, - 0x6c, 0x61, 0x6e, 0x6b, 0x23, 0x08, 0x69, 0x73, 0x77, 0x62, 0x6c, 0x61, - 0x6e, 0x6b, 0x24, 0x08, 0x69, 0x73, 0x77, 0x64, 0x69, 0x67, 0x69, 0x74, - 0x25, 0x07, 0x73, 0x74, 0x72, 0x6e, 0x63, 0x61, 0x74, 0x26, 0x09, 0x5f, - 0x5f, 0x73, 0x74, 0x70, 0x6e, 0x63, 0x70, 0x79, 0x27, 0x07, 0x73, 0x74, - 0x72, 0x6e, 0x63, 0x70, 0x79, 0x28, 0x09, 0x69, 0x73, 0x77, 0x78, 0x64, - 0x69, 0x67, 0x69, 0x74, 0x29, 0x06, 0x77, 0x63, 0x73, 0x6c, 0x65, 0x6e, - 0x2a, 0x06, 0x77, 0x63, 0x73, 0x63, 0x68, 0x72, 0x2b, 0x08, 0x69, 0x73, - 0x77, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x08, 0x69, 0x73, 0x77, 0x61, - 0x6c, 0x6e, 0x75, 0x6d, 0x07, 0x33, 0x02, 0x00, 0x0f, 0x5f, 0x5f, 0x73, - 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x01, 0x1f, 0x47, 0x4f, 0x54, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x5f, 0x5f, 0x6d, 0x65, - 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x09, 0x11, 0x02, - 0x00, 0x07, 0x2e, 0x72, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x01, 0x05, 0x2e, - 0x64, 0x61, 0x74, 0x61, 0x00, 0x8e, 0x01, 0x09, 0x70, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x65, 0x72, 0x73, 0x02, 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, - 0x61, 0x67, 0x65, 0x01, 0x03, 0x43, 0x31, 0x31, 0x00, 0x0c, 0x70, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, - 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x5f, 0x32, 0x31, 0x2e, 0x31, 0x2e, 0x34, - 0x2d, 0x77, 0x61, 0x73, 0x69, 0x2d, 0x73, 0x64, 0x6b, 0x20, 0x28, 0x68, - 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2f, 0x6c, - 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, - 0x32, 0x32, 0x32, 0x66, 0x63, 0x31, 0x31, 0x66, 0x32, 0x62, 0x38, 0x66, - 0x32, 0x35, 0x66, 0x36, 0x61, 0x30, 0x66, 0x34, 0x39, 0x37, 0x36, 0x32, - 0x37, 0x32, 0x65, 0x66, 0x31, 0x62, 0x62, 0x37, 0x62, 0x66, 0x34, 0x39, - 0x35, 0x32, 0x31, 0x64, 0x29, 0x00, 0xa4, 0x01, 0x0f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, - 0x09, 0x2b, 0x0b, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x2b, 0x0f, 0x62, 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x2d, 0x6f, 0x70, 0x74, 0x2b, 0x16, 0x63, 0x61, 0x6c, - 0x6c, 0x2d, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x2d, 0x6f, - 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x6e, 0x67, 0x2b, 0x0e, 0x65, 0x78, 0x74, - 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2b, - 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, - 0x0f, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x67, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x73, 0x2b, 0x13, 0x6e, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x2d, 0x66, 0x70, 0x74, 0x6f, 0x69, 0x6e, - 0x74, 0x2b, 0x0f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x2d, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2b, 0x08, 0x73, 0x69, 0x67, 0x6e, - 0x2d, 0x65, 0x78, 0x74 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x03, + 0x20, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x05, 0x20, 0x00, 0x00, 0x06, + 0x20, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x0a, + 0x20, 0x00, 0x00, 0x28, 0x20, 0x00, 0x00, 0x29, 0x20, 0x00, 0x00, 0x5f, + 0x20, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x41, 0xe8, 0xc2, 0x04, 0x0b, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x8e, + 0x01, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x73, 0x02, + 0x08, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x01, 0x03, 0x43, + 0x31, 0x31, 0x00, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, + 0x64, 0x2d, 0x62, 0x79, 0x01, 0x05, 0x63, 0x6c, 0x61, 0x6e, 0x67, 0x5f, + 0x32, 0x31, 0x2e, 0x31, 0x2e, 0x34, 0x2d, 0x77, 0x61, 0x73, 0x69, 0x2d, + 0x73, 0x64, 0x6b, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x6c, 0x6c, 0x76, 0x6d, 0x2f, 0x6c, 0x6c, 0x76, 0x6d, 0x2d, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x32, 0x32, 0x32, 0x66, 0x63, 0x31, + 0x31, 0x66, 0x32, 0x62, 0x38, 0x66, 0x32, 0x35, 0x66, 0x36, 0x61, 0x30, + 0x66, 0x34, 0x39, 0x37, 0x36, 0x32, 0x37, 0x32, 0x65, 0x66, 0x31, 0x62, + 0x62, 0x37, 0x62, 0x66, 0x34, 0x39, 0x35, 0x32, 0x31, 0x64, 0x29, 0x00, + 0xa4, 0x01, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x66, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x09, 0x2b, 0x0f, 0x6d, 0x75, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, + 0x2b, 0x13, 0x6e, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x70, 0x70, 0x69, 0x6e, + 0x67, 0x2d, 0x66, 0x70, 0x74, 0x6f, 0x69, 0x6e, 0x74, 0x2b, 0x0b, 0x62, + 0x75, 0x6c, 0x6b, 0x2d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2b, 0x08, + 0x73, 0x69, 0x67, 0x6e, 0x2d, 0x65, 0x78, 0x74, 0x2b, 0x0f, 0x72, 0x65, + 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2b, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x2b, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x2d, + 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x2b, 0x0f, 0x62, 0x75, 0x6c, 0x6b, 0x2d, + 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x2d, 0x6f, 0x70, 0x74, 0x2b, 0x16, + 0x63, 0x61, 0x6c, 0x6c, 0x2d, 0x69, 0x6e, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x6e, 0x67 }; -unsigned int STDLIB_WASM_LEN = 16348; +unsigned int STDLIB_WASM_LEN = 14794; From 9f9a0bc410c98c3ffaaf296242d896cd9acac1dd Mon Sep 17 00:00:00 2001 From: DanikVitek Date: Sat, 10 Jan 2026 23:01:55 +0200 Subject: [PATCH 133/140] fix: Renamed `TreeCursor<'cursor>` into `TreeCursor<'tree>`, to be consistant with the usages and reduse confusion --- lib/binding_rust/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index bf86cf74..583ff1b0 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -317,7 +317,7 @@ pub trait Decode { /// A stateful object for walking a syntax [`Tree`] efficiently. #[doc(alias = "TSTreeCursor")] -pub struct TreeCursor<'cursor>(ffi::TSTreeCursor, PhantomData<&'cursor ()>); +pub struct TreeCursor<'tree>(ffi::TSTreeCursor, PhantomData<&'tree ()>); /// A set of patterns that match nodes in a syntax tree. #[doc(alias = "TSQuery")] @@ -2082,11 +2082,11 @@ impl fmt::Display for Node<'_> { } } -impl<'cursor> TreeCursor<'cursor> { +impl<'tree> TreeCursor<'tree> { /// Get the tree cursor's current [`Node`]. #[doc(alias = "ts_tree_cursor_current_node")] #[must_use] - pub fn node(&self) -> Node<'cursor> { + pub fn node(&self) -> Node<'tree> { Node( unsafe { ffi::ts_tree_cursor_current_node(&self.0) }, PhantomData, @@ -2227,7 +2227,7 @@ impl<'cursor> TreeCursor<'cursor> { /// Re-initialize this tree cursor to start at the original node that the /// cursor was constructed with. #[doc(alias = "ts_tree_cursor_reset")] - pub fn reset(&mut self, node: Node<'cursor>) { + pub fn reset(&mut self, node: Node<'tree>) { unsafe { ffi::ts_tree_cursor_reset(&mut self.0, node.0) }; } From b12009a7466c31bb3342a10f1f460603456f0967 Mon Sep 17 00:00:00 2001 From: DanikVitek Date: Sat, 10 Jan 2026 23:01:55 +0200 Subject: [PATCH 134/140] fix: Clarify/fix lifetimes - One has to think about lifetimes if a type has one: - `<&'a Node<'tree>>::language` now returns `LanguageRef<'tree>` instead of `LanguageRef<'a>`, as it should; - Remove explicit "outlives" requirements from `QueryMatches`, `QueryCaptures`, and their impl blocks, because they're inferred - Removed unnecessary `&mut` from `cst_render_node`'s `cursor` parameter --- crates/cli/src/parse.rs | 2 +- crates/cli/src/tests/helpers/query_helpers.rs | 2 +- crates/generate/src/quickjs.rs | 20 ++++++++--------- crates/highlight/src/highlight.rs | 5 +++-- crates/loader/src/loader.rs | 16 ++++++++------ crates/tags/src/tags.rs | 1 + lib/binding_rust/lib.rs | 22 ++++++++----------- 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/crates/cli/src/parse.rs b/crates/cli/src/parse.rs index 1a1d9723..3551f556 100644 --- a/crates/cli/src/parse.rs +++ b/crates/cli/src/parse.rs @@ -953,7 +953,7 @@ fn render_node_range( fn cst_render_node( opts: &ParseFileOptions, - cursor: &mut TreeCursor, + cursor: &TreeCursor, source_code: &[u8], out: &mut impl Write, total_width: usize, diff --git a/crates/cli/src/tests/helpers/query_helpers.rs b/crates/cli/src/tests/helpers/query_helpers.rs index e648ac8e..e2c68f17 100644 --- a/crates/cli/src/tests/helpers/query_helpers.rs +++ b/crates/cli/src/tests/helpers/query_helpers.rs @@ -225,7 +225,7 @@ impl Pattern { } // Find every matching combination of child patterns and child nodes. - let mut finished_matches = Vec::::new(); + let mut finished_matches = Vec::>::new(); if cursor.goto_first_child() { let mut match_states = vec![(0, mat)]; loop { diff --git a/crates/generate/src/quickjs.rs b/crates/generate/src/quickjs.rs index 99e77397..d8c71cfe 100644 --- a/crates/generate/src/quickjs.rs +++ b/crates/generate/src/quickjs.rs @@ -215,11 +215,11 @@ fn try_resolve_path(path: &Path) -> rquickjs::Result { } #[allow(clippy::needless_pass_by_value)] -fn require_from_module<'a>( - ctx: Ctx<'a>, +fn require_from_module<'js>( + ctx: Ctx<'js>, module_path: String, from_module: &str, -) -> rquickjs::Result> { +) -> rquickjs::Result> { let current_module = PathBuf::from(from_module); let current_dir = if current_module.is_file() { current_module.parent().unwrap_or(Path::new(".")) @@ -234,13 +234,13 @@ fn require_from_module<'a>( load_module_from_content(&ctx, &resolved_path, &contents) } -fn load_module_from_content<'a>( - ctx: &Ctx<'a>, +fn load_module_from_content<'js>( + ctx: &Ctx<'js>, path: &Path, contents: &str, -) -> rquickjs::Result> { +) -> rquickjs::Result> { if path.extension().is_some_and(|ext| ext == "json") { - return ctx.eval::(format!("JSON.parse({contents:?})")); + return ctx.eval::, _>(format!("JSON.parse({contents:?})")); } let exports = Object::new(ctx.clone())?; @@ -256,7 +256,7 @@ fn load_module_from_content<'a>( let module_path = filename.clone(); let require = Function::new( ctx.clone(), - move |ctx_inner: Ctx<'a>, target_path: String| -> rquickjs::Result> { + move |ctx_inner: Ctx<'js>, target_path: String| -> rquickjs::Result> { require_from_module(ctx_inner, target_path, &module_path) }, )?; @@ -264,8 +264,8 @@ fn load_module_from_content<'a>( let wrapper = format!("(function(exports, require, module, __filename, __dirname) {{ {contents} }})"); - let module_func = ctx.eval::(wrapper)?; - module_func.call::<_, Value>((exports, require, module_obj.clone(), filename, dirname))?; + let module_func = ctx.eval::, _>(wrapper)?; + module_func.call::<_, Value<'js>>((exports, require, module_obj.clone(), filename, dirname))?; module_obj.get("exports") } diff --git a/crates/highlight/src/highlight.rs b/crates/highlight/src/highlight.rs index 9a78d1ac..d38351f6 100644 --- a/crates/highlight/src/highlight.rs +++ b/crates/highlight/src/highlight.rs @@ -189,7 +189,7 @@ struct HighlightIterLayer<'a> { depth: usize, } -pub struct _QueryCaptures<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> { +pub struct _QueryCaptures<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> { ptr: *mut ffi::TSQueryCursor, query: &'query Query, text_provider: T, @@ -225,7 +225,7 @@ impl<'tree> _QueryMatch<'_, 'tree> { } } -impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> Iterator +impl<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> Iterator for _QueryCaptures<'query, 'tree, T, I> { type Item = (QueryMatch<'query, 'tree>, usize); @@ -594,6 +594,7 @@ impl<'a> HighlightIterLayer<'a> { } } + // SAFETY: // The `captures` iterator borrows the `Tree` and the `QueryCursor`, which // prevents them from being moved. But both of these values are really just // pointers, so it's actually ok to move them. diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 11c8b673..451c6b82 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -765,7 +765,7 @@ impl Loader { } #[must_use] - pub fn get_all_language_configurations(&self) -> Vec<(&LanguageConfiguration, &Path)> { + pub fn get_all_language_configurations(&self) -> Vec<(&LanguageConfiguration<'static>, &Path)> { self.language_configurations .iter() .map(|c| (c, self.languages_by_id[c.language_id].0.as_ref())) @@ -775,7 +775,7 @@ impl Loader { pub fn language_configuration_for_scope( &self, scope: &str, - ) -> LoaderResult> { + ) -> LoaderResult)>> { for configuration in &self.language_configurations { if configuration.scope.as_ref().is_some_and(|s| s == scope) { let language = self.language_for_id(configuration.language_id)?; @@ -788,7 +788,7 @@ impl Loader { pub fn language_configuration_for_first_line_regex( &self, path: &Path, - ) -> LoaderResult> { + ) -> LoaderResult)>> { self.language_configuration_ids_by_first_line_regex .iter() .try_fold(None, |_, (regex, ids)| { @@ -817,7 +817,7 @@ impl Loader { pub fn language_configuration_for_file_name( &self, path: &Path, - ) -> LoaderResult> { + ) -> LoaderResult)>> { // Find all the language configurations that match this file name // or a suffix of the file name. let configuration_ids = path @@ -889,7 +889,7 @@ impl Loader { pub fn language_configuration_for_injection_string( &self, string: &str, - ) -> LoaderResult> { + ) -> LoaderResult)>> { let mut best_match_length = 0; let mut best_match_position = None; for (i, configuration) in self.language_configurations.iter().enumerate() { @@ -1534,7 +1534,9 @@ impl Loader { } #[must_use] - pub fn get_language_configuration_in_current_path(&self) -> Option<&LanguageConfiguration> { + pub fn get_language_configuration_in_current_path( + &self, + ) -> Option<&LanguageConfiguration<'static>> { self.language_configuration_in_current_path .map(|i| &self.language_configurations[i]) } @@ -1543,7 +1545,7 @@ impl Loader { &mut self, parser_path: &Path, set_current_path_config: bool, - ) -> LoaderResult<&[LanguageConfiguration]> { + ) -> LoaderResult<&[LanguageConfiguration<'static>]> { let initial_language_configuration_count = self.language_configurations.len(); match TreeSitterJSON::from_file(parser_path) { diff --git a/crates/tags/src/tags.rs b/crates/tags/src/tags.rs index 16270b0a..c6654876 100644 --- a/crates/tags/src/tags.rs +++ b/crates/tags/src/tags.rs @@ -313,6 +313,7 @@ impl TagsContext { ) .ok_or(Error::Cancelled)?; + // SAFETY: // The `matches` iterator borrows the `Tree`, which prevents it from being // moved. But the tree is really just a pointer, so it's actually ok to // move it. diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index 583ff1b0..51fd7f25 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -392,7 +392,7 @@ pub struct QueryMatch<'cursor, 'tree> { } /// A sequence of [`QueryMatch`]es associated with a given [`QueryCursor`]. -pub struct QueryMatches<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> { +pub struct QueryMatches<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> { ptr: *mut ffi::TSQueryCursor, query: &'query Query, text_provider: T, @@ -407,7 +407,7 @@ pub struct QueryMatches<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8] /// /// During iteration, each element contains a [`QueryMatch`] and index. The index can /// be used to access the new capture inside of the [`QueryMatch::captures`]'s [`captures`]. -pub struct QueryCaptures<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> { +pub struct QueryCaptures<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> { ptr: *mut ffi::TSQueryCursor, query: &'query Query, text_provider: T, @@ -1581,7 +1581,7 @@ impl<'tree> Node<'tree> { /// Get the [`Language`] that was used to parse this node's syntax tree. #[doc(alias = "ts_node_language")] #[must_use] - pub fn language(&self) -> LanguageRef { + pub fn language(&self) -> LanguageRef<'tree> { LanguageRef(unsafe { ffi::ts_node_language(self.0) }, PhantomData) } @@ -3404,7 +3404,7 @@ impl QueryProperty { /// Provide a `StreamingIterator` instead of the traditional `Iterator`, as the /// underlying object in the C library gets updated on each iteration. Copies would /// have their internal state overwritten, leading to Undefined Behavior -impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIterator +impl<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> StreamingIterator for QueryMatches<'query, 'tree, T, I> { type Item = QueryMatch<'query, 'tree>; @@ -3435,15 +3435,13 @@ impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIterato } } -impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIteratorMut - for QueryMatches<'query, 'tree, T, I> -{ +impl, I: AsRef<[u8]>> StreamingIteratorMut for QueryMatches<'_, '_, T, I> { fn get_mut(&mut self) -> Option<&mut Self::Item> { self.current_match.as_mut() } } -impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIterator +impl<'query, 'tree, T: TextProvider, I: AsRef<[u8]>> StreamingIterator for QueryCaptures<'query, 'tree, T, I> { type Item = (QueryMatch<'query, 'tree>, usize); @@ -3480,9 +3478,7 @@ impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIterato } } -impl<'query, 'tree: 'query, T: TextProvider, I: AsRef<[u8]>> StreamingIteratorMut - for QueryCaptures<'query, 'tree, T, I> -{ +impl, I: AsRef<[u8]>> StreamingIteratorMut for QueryCaptures<'_, '_, T, I> { fn get_mut(&mut self) -> Option<&mut Self::Item> { self.current_match.as_mut() } @@ -3622,8 +3618,8 @@ impl From for Range { } } -impl From<&'_ InputEdit> for ffi::TSInputEdit { - fn from(val: &'_ InputEdit) -> Self { +impl From<&InputEdit> for ffi::TSInputEdit { + fn from(val: &InputEdit) -> Self { Self { start_byte: val.start_byte as u32, old_end_byte: val.old_end_byte as u32, From cd603fa98178cb011f111c0472323d6dbcc1682c Mon Sep 17 00:00:00 2001 From: theanarkh <2923878201@qq.com> Date: Mon, 19 Jan 2026 06:39:52 +0800 Subject: [PATCH 135/140] feat: free memory automatically (#5225) --- lib/binding_web/src/finalization_registry.ts | 8 ++ lib/binding_web/src/lookahead_iterator.ts | 7 ++ lib/binding_web/src/parser.ts | 8 ++ lib/binding_web/src/query.ts | 7 ++ lib/binding_web/src/tree.ts | 7 ++ lib/binding_web/src/tree_cursor.ts | 7 ++ lib/binding_web/test/memory.test.ts | 74 +++++++++++++++++++ lib/binding_web/test/memory.ts | 20 +++++ .../test/memory_unsupported.test.ts | 25 +++++++ 9 files changed, 163 insertions(+) create mode 100644 lib/binding_web/src/finalization_registry.ts create mode 100644 lib/binding_web/test/memory.test.ts create mode 100644 lib/binding_web/test/memory.ts create mode 100644 lib/binding_web/test/memory_unsupported.test.ts diff --git a/lib/binding_web/src/finalization_registry.ts b/lib/binding_web/src/finalization_registry.ts new file mode 100644 index 00000000..5f9c45cc --- /dev/null +++ b/lib/binding_web/src/finalization_registry.ts @@ -0,0 +1,8 @@ +export function newFinalizer(handler: (value: T) => void): FinalizationRegistry | undefined { + try { + return new FinalizationRegistry(handler); + } catch(e) { + console.error('Unsupported FinalizationRegistry:', e); + return; + } +} diff --git a/lib/binding_web/src/lookahead_iterator.ts b/lib/binding_web/src/lookahead_iterator.ts index 92b4d28f..4dd6b296 100644 --- a/lib/binding_web/src/lookahead_iterator.ts +++ b/lib/binding_web/src/lookahead_iterator.ts @@ -1,5 +1,10 @@ import { C, Internal, assertInternal } from './constants'; import { Language } from './language'; +import { newFinalizer } from './finalization_registry'; + +const finalizer = newFinalizer((address: number) => { + C._ts_lookahead_iterator_delete(address); +}); export class LookaheadIterator implements Iterable { /** @internal */ @@ -13,6 +18,7 @@ export class LookaheadIterator implements Iterable { assertInternal(internal); this[0] = address; this.language = language; + finalizer?.register(this, address, this); } /** Get the current symbol of the lookahead iterator. */ @@ -27,6 +33,7 @@ export class LookaheadIterator implements Iterable { /** Delete the lookahead iterator, freeing its resources. */ delete(): void { + finalizer?.unregister(this); C._ts_lookahead_iterator_delete(this[0]); this[0] = 0; } diff --git a/lib/binding_web/src/parser.ts b/lib/binding_web/src/parser.ts index efcadf05..7e3c3b4a 100644 --- a/lib/binding_web/src/parser.ts +++ b/lib/binding_web/src/parser.ts @@ -3,6 +3,7 @@ import { Language } from './language'; import { marshalRange, unmarshalRange } from './marshal'; import { checkModule, initializeBinding } from './bindings'; import { Tree } from './tree'; +import { newFinalizer } from './finalization_registry'; /** * Options for parsing @@ -82,6 +83,11 @@ export let LANGUAGE_VERSION: number; */ export let MIN_COMPATIBLE_VERSION: number; +const finalizer = newFinalizer((addresses: number[]) => { + C._ts_parser_delete(addresses[0]); + C._free(addresses[1]); +}); + /** * A stateful object that is used to produce a {@link Tree} based on some * source code. @@ -117,6 +123,7 @@ export class Parser { */ constructor() { this.initialize(); + finalizer?.register(this, [this[0], this[1]], this); } /** @internal */ @@ -131,6 +138,7 @@ export class Parser { /** Delete the parser, freeing its resources. */ delete() { + finalizer?.unregister(this); C._ts_parser_delete(this[0]); C._free(this[1]); this[0] = 0; diff --git a/lib/binding_web/src/query.ts b/lib/binding_web/src/query.ts index b9cd1971..e2994b14 100644 --- a/lib/binding_web/src/query.ts +++ b/lib/binding_web/src/query.ts @@ -3,6 +3,7 @@ import { Node } from './node'; import { marshalNode, unmarshalCaptures } from './marshal'; import { TRANSFER_BUFFER } from './parser'; import { Language } from './language'; +import { newFinalizer } from './finalization_registry'; const PREDICATE_STEP_TYPE_CAPTURE = 1; @@ -506,6 +507,10 @@ function parsePattern( } } +const finalizer = newFinalizer((address: number) => { + C._ts_query_delete(address); +}); + export class Query { /** @internal */ private [0] = 0; // Internal handle for Wasm @@ -687,10 +692,12 @@ export class Query { this.assertedProperties = assertedProperties; this.refutedProperties = refutedProperties; this.exceededMatchLimit = false; + finalizer?.register(this, address, this); } /** Delete the query, freeing its resources. */ delete(): void { + finalizer?.unregister(this); C._ts_query_delete(this[0]); this[0] = 0; } diff --git a/lib/binding_web/src/tree.ts b/lib/binding_web/src/tree.ts index 7a251440..f6a7aaf3 100644 --- a/lib/binding_web/src/tree.ts +++ b/lib/binding_web/src/tree.ts @@ -5,6 +5,7 @@ import { TreeCursor } from './tree_cursor'; import { marshalEdit, marshalPoint, unmarshalNode, unmarshalRange } from './marshal'; import { TRANSFER_BUFFER } from './parser'; import { Edit } from './edit'; +import { newFinalizer } from './finalization_registry'; /** @internal */ export function getText(tree: Tree, startIndex: number, endIndex: number, startPosition: Point): string { @@ -28,6 +29,10 @@ export function getText(tree: Tree, startIndex: number, endIndex: number, startP return result ?? ''; } +const finalizer = newFinalizer((address: number) => { + C._ts_tree_delete(address); +}); + /** A tree that represents the syntactic structure of a source code file. */ export class Tree { /** @internal */ @@ -45,6 +50,7 @@ export class Tree { this[0] = address; this.language = language; this.textCallback = textCallback; + finalizer?.register(this, address, this); } /** Create a shallow copy of the syntax tree. This is very fast. */ @@ -55,6 +61,7 @@ export class Tree { /** Delete the syntax tree, freeing its resources. */ delete(): void { + finalizer?.unregister(this); C._ts_tree_delete(this[0]); this[0] = 0; } diff --git a/lib/binding_web/src/tree_cursor.ts b/lib/binding_web/src/tree_cursor.ts index 7562bb7f..978a86dc 100644 --- a/lib/binding_web/src/tree_cursor.ts +++ b/lib/binding_web/src/tree_cursor.ts @@ -3,6 +3,11 @@ import { marshalNode, marshalPoint, marshalTreeCursor, unmarshalNode, unmarshalP import { Node } from './node'; import { TRANSFER_BUFFER } from './parser'; import { getText, Tree } from './tree'; +import { newFinalizer } from './finalization_registry'; + +const finalizer = newFinalizer((address: number) => { + C._ts_tree_cursor_delete_wasm(address); +}); /** A stateful object for walking a syntax {@link Tree} efficiently. */ export class TreeCursor { @@ -30,6 +35,7 @@ export class TreeCursor { assertInternal(internal); this.tree = tree; unmarshalTreeCursor(this); + finalizer?.register(this, this.tree[0], this); } /** Creates a deep copy of the tree cursor. This allocates new memory. */ @@ -42,6 +48,7 @@ export class TreeCursor { /** Delete the tree cursor, freeing its resources. */ delete(): void { + finalizer?.unregister(this); marshalTreeCursor(this); C._ts_tree_cursor_delete_wasm(this.tree[0]); this[0] = this[1] = this[2] = 0; diff --git a/lib/binding_web/test/memory.test.ts b/lib/binding_web/test/memory.test.ts new file mode 100644 index 00000000..46238934 --- /dev/null +++ b/lib/binding_web/test/memory.test.ts @@ -0,0 +1,74 @@ +import { describe, expect, it } from 'vitest'; +import { gc, event, Finalizer } from './memory'; + +// hijack finalization registry before import web-tree-sitter +globalThis.FinalizationRegistry = Finalizer; + +describe('Memory Management', () => { + describe('call .delete()', () => { + it('test free memory manually', async () => { + const timer = setInterval(() => { + gc(); + }, 100); + let done = 0; + event.on('gc', () => { + done++; + }); + await (async () => { + const { JavaScript } = await (await import('./helper')).default; + const { Parser, Query } = await import('../src'); + const parser = new Parser(); + parser.setLanguage(JavaScript); + const tree = parser.parse('1+1')!; + const copyTree = tree.copy(); + const cursor = tree.walk(); + const copyCursor = cursor.copy(); + const lookaheadIterator = JavaScript.lookaheadIterator(cursor.currentNode.nextParseState)!; + const query = new Query(JavaScript, '(identifier) @element'); + parser.delete(); + tree.delete(); + copyTree.delete(); + cursor.delete(); + copyCursor.delete(); + lookaheadIterator.delete(); + query.delete(); + })(); + // wait for gc + await new Promise((resolve) => setTimeout(resolve, 1000)); + clearInterval(timer); + // expect no gc event fired + expect(done).toBe(0); + }); + }); + + describe('do not call .delete()', () => { + it('test free memory automatically', async () => { + const timer = setInterval(() => { + gc(); + }, 100); + let done = 0; + const promise = new Promise((resolve) => { + event.on('gc', () => { + if (++done === 7) { + resolve(undefined); + clearInterval(timer); + } + console.log('free memory times: ', done); + }); + }); + await (async () => { + const { JavaScript } = await (await import('./helper')).default; + const { Parser, Query } = await import('../src'); + const parser = new Parser(); // 1 + parser.setLanguage(JavaScript); + const tree = parser.parse('1+1')!; // 2 + tree.copy(); // 3 + const cursor = tree.walk(); // 4 + cursor.copy(); // 5 + JavaScript.lookaheadIterator(cursor.currentNode.nextParseState)!; // 6 + new Query(JavaScript, '(identifier) @element'); // 7 + })(); + await promise; + }); + }); +}); diff --git a/lib/binding_web/test/memory.ts b/lib/binding_web/test/memory.ts new file mode 100644 index 00000000..62cb8b7d --- /dev/null +++ b/lib/binding_web/test/memory.ts @@ -0,0 +1,20 @@ +import { EventEmitter } from 'events'; +import { Session } from 'inspector'; + +const session = new Session(); +session.connect(); + +export function gc() { + session.post('HeapProfiler.collectGarbage'); +} + +export const event = new EventEmitter(); + +export class Finalizer extends FinalizationRegistry { + constructor(handler: (value: T) => void) { + super((value) => { + handler(value); + event.emit('gc'); + }); + } +} diff --git a/lib/binding_web/test/memory_unsupported.test.ts b/lib/binding_web/test/memory_unsupported.test.ts new file mode 100644 index 00000000..cc1f69bf --- /dev/null +++ b/lib/binding_web/test/memory_unsupported.test.ts @@ -0,0 +1,25 @@ +import { describe, it } from 'vitest'; + +describe('FinalizationRegistry is unsupported', () => { + it('test FinalizationRegistry is unsupported', async () => { + // @ts-expect-error: test FinalizationRegistry is not supported + globalThis.FinalizationRegistry = undefined; + const { JavaScript } = await (await import('./helper')).default; + const { Parser, Query } = await import('../src'); + const parser = new Parser(); + parser.setLanguage(JavaScript); + const tree = parser.parse('1+1')!; + const copyTree = tree.copy(); + const cursor = tree.walk(); + const copyCursor = cursor.copy(); + const lookaheadIterator = JavaScript.lookaheadIterator(cursor.currentNode.nextParseState)!; + const query = new Query(JavaScript, '(identifier) @element'); + parser.delete(); + tree.delete(); + copyTree.delete(); + cursor.delete(); + copyCursor.delete(); + lookaheadIterator.delete(); + query.delete(); + }); +}); From 0cdb6bef7b6fc912e3db0a928ddb5c2993bbe6a6 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Sun, 18 Jan 2026 02:25:25 -0500 Subject: [PATCH 136/140] fix(cli): warn user when `nm` can't be run to verify the symbols inside the parser being built --- crates/loader/src/loader.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/loader/src/loader.rs b/crates/loader/src/loader.rs index 451c6b82..e7584378 100644 --- a/crates/loader/src/loader.rs +++ b/crates/loader/src/loader.rs @@ -1305,6 +1305,11 @@ impl Loader { })); } } + } else { + warn!( + "Failed to run `nm` to verify symbols in {}", + library_path.display() + ); } Ok(()) From 470ecf89966cfe7450e30b473f2bec0c370e2e20 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Tue, 13 Jan 2026 00:47:46 -0500 Subject: [PATCH 137/140] feat(ci): ensure `wasm-stdlib.h` is regenerated when wasm stdlib source files are modified. --- .github/scripts/wasm_stdlib.js | 25 +++++++++++++++++++++++++ .github/workflows/ci.yml | 3 +++ .github/workflows/wasm_stdlib.yml | 19 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 .github/scripts/wasm_stdlib.js create mode 100644 .github/workflows/wasm_stdlib.yml diff --git a/.github/scripts/wasm_stdlib.js b/.github/scripts/wasm_stdlib.js new file mode 100644 index 00000000..e1350094 --- /dev/null +++ b/.github/scripts/wasm_stdlib.js @@ -0,0 +1,25 @@ +module.exports = async ({ github, context, core }) => { + if (context.eventName !== 'pull_request') return; + + const prNumber = context.payload.pull_request.number; + const owner = context.repo.owner; + const repo = context.repo.repo; + + const { data: files } = await github.rest.pulls.listFiles({ + owner, + repo, + pull_number: prNumber + }); + + const changedFiles = files.map(file => file.filename); + + const wasmStdLibSrc = 'crates/language/wasm/'; + const dirChanged = changedFiles.some(file => file.startsWith(wasmStdLibSrc)); + + if (!dirChanged) return; + + const wasmStdLibHeader = 'lib/src/wasm/wasm-stdlib.h'; + const requiredChanged = changedFiles.includes(wasmStdLibHeader); + + if (!requiredChanged) core.setFailed(`Changes detected in ${wasmStdLibSrc} but ${wasmStdLibHeader} was not modified.`); +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 97a7e378..a60c93f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,3 +44,6 @@ jobs: build: uses: ./.github/workflows/build.yml + + check-wasm-stdlib: + uses: ./.github/workflows/wasm_stdlib.yml diff --git a/.github/workflows/wasm_stdlib.yml b/.github/workflows/wasm_stdlib.yml new file mode 100644 index 00000000..3e7ee0cc --- /dev/null +++ b/.github/workflows/wasm_stdlib.yml @@ -0,0 +1,19 @@ +name: Check Wasm Stdlib build + +on: + workflow_call: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Check directory changes + uses: actions/github-script@v7 + with: + script: | + const scriptPath = `${process.env.GITHUB_WORKSPACE}/.github/scripts/wasm_stdlib.js`; + const script = require(scriptPath); + return script({ github, context, core }); From ae8184b8b925afa97c0216541a12bd443e1285e1 Mon Sep 17 00:00:00 2001 From: Tam1SH Date: Tue, 6 Jan 2026 05:18:06 +0300 Subject: [PATCH 138/140] docs(playground): highlight full row for highlighted nodes --- crates/cli/src/playground.html | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/crates/cli/src/playground.html b/crates/cli/src/playground.html index 6f90e030..147516ac 100644 --- a/crates/cli/src/playground.html +++ b/crates/cli/src/playground.html @@ -19,7 +19,8 @@ --light-scrollbar-track: #f1f1f1; --light-scrollbar-thumb: #c1c1c1; --light-scrollbar-thumb-hover: #a8a8a8; - + --light-tree-row-bg: #e3f2fd; + --dark-bg: #1d1f21; --dark-border: #2d2d2d; --dark-text: #c5c8c6; @@ -28,6 +29,7 @@ --dark-scrollbar-track: #25282c; --dark-scrollbar-thumb: #4a4d51; --dark-scrollbar-thumb-hover: #5a5d61; + --dark-tree-row-bg: #373737; --primary-color: #0550ae; --primary-color-alpha: rgba(5, 80, 174, 0.1); @@ -42,6 +44,7 @@ --text-color: var(--dark-text); --panel-bg: var(--dark-panel-bg); --code-bg: var(--dark-code-bg); + --tree-row-bg: var(--dark-tree-row-bg); } [data-theme="light"] { @@ -50,6 +53,7 @@ --text-color: var(--light-text); --panel-bg: white; --code-bg: white; + --tree-row-bg: var(--light-tree-row-bg); } /* Base Styles */ @@ -275,7 +279,7 @@ } #output-container a.highlighted { - background-color: #d9d9d9; + background-color: #cae2ff; color: red; border-radius: 3px; text-decoration: underline; @@ -346,7 +350,7 @@ } & #output-container a.highlighted { - background-color: #373b41; + background-color: #656669; color: red; } @@ -373,6 +377,9 @@ color: var(--dark-text); } } + .tree-row:has(.highlighted) { + background-color: var(--tree-row-bg); + } From d251226a3cd0074fbadb2b6afe62061fb35bffed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:34:23 +0000 Subject: [PATCH 139/140] ci: bump actions/github-script from 7 to 8 in the actions group Bumps the actions group with 1 update: [actions/github-script](https://github.com/actions/github-script). Updates `actions/github-script` from 7 to 8 - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/wasm_stdlib.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wasm_stdlib.yml b/.github/workflows/wasm_stdlib.yml index 3e7ee0cc..adec8411 100644 --- a/.github/workflows/wasm_stdlib.yml +++ b/.github/workflows/wasm_stdlib.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v6 - name: Check directory changes - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: | const scriptPath = `${process.env.GITHUB_WORKSPACE}/.github/scripts/wasm_stdlib.js`; From 6739742fb61b7234122472b3da26ca5990809c1d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jan 2026 22:33:52 +0000 Subject: [PATCH 140/140] build(deps): bump cc from 1.2.52 to 1.2.53 in the cargo group Bumps the cargo group with 1 update: [cc](https://github.com/rust-lang/cc-rs). Updates `cc` from 1.2.52 to 1.2.53 - [Release notes](https://github.com/rust-lang/cc-rs/releases) - [Changelog](https://github.com/rust-lang/cc-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.52...cc-v1.2.53) --- updated-dependencies: - dependency-name: cc dependency-version: 1.2.53 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bb4214f..ae7803c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,9 +187,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.52" +version = "1.2.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" dependencies = [ "find-msvc-tools", "shlex", @@ -664,9 +664,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" [[package]] name = "fnv" diff --git a/Cargo.toml b/Cargo.toml index 5730ddf2..ca0d644a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -106,7 +106,7 @@ ansi_colours = "1.2.3" anstyle = "1.0.13" anyhow = "1.0.100" bstr = "1.12.0" -cc = "1.2.52" +cc = "1.2.53" clap = { version = "4.5.54", features = [ "cargo", "derive",