From f5b2c565050c2ec5485ee3d6ca6214e954e3f0e3 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 12 Mar 2026 08:19:57 -0400 Subject: [PATCH 01/38] chore: sync tree-sitter dependency bumps from upstream (#61) * Initial plan * chore: sync tree-sitter dependency updates from upstream (PR #1711) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- Cargo.lock | 8 ++++---- crates/recoco-splitters/Cargo.toml | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61653779..b3900c73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5797,15 +5797,15 @@ dependencies = [ [[package]] name = "tree-sitter-language" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae62f7eae5eb549c71b76658648b72cc6111f2d87d24a1e31fa907f4943e3ce" +checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" [[package]] name = "tree-sitter-md" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c96068626225a758ddb1f7cfb82c7c1fab4e093dd3bde464e2a44e8341f58f5" +checksum = "2efd398be546456c814598ee56c0f51769a77241511b4a58077815d120afa882" dependencies = [ "cc", "tree-sitter-language", diff --git a/crates/recoco-splitters/Cargo.toml b/crates/recoco-splitters/Cargo.toml index f616f205..8bebcee4 100644 --- a/crates/recoco-splitters/Cargo.toml +++ b/crates/recoco-splitters/Cargo.toml @@ -34,9 +34,9 @@ tree-sitter-javascript = { version = "0.23.1", optional = true } tree-sitter-json = { version = "0.24.8", optional = true } # The other more popular crate tree-sitter-kotlin requires tree-sitter < 0.23 for now tree-sitter-kotlin-ng = { version = "1.1.0", optional = true } -tree-sitter-language = { version = "0.1.5" } -tree-sitter-md = { version = "0.5.1", optional = true } -tree-sitter-pascal = { version = "0.10.0", optional = true } +tree-sitter-language = { version = "0.1.7" } +tree-sitter-md = { version = "0.5.3", optional = true } +tree-sitter-pascal = { version = "0.10.2", optional = true } tree-sitter-php = { version = "0.23.11", optional = true } tree-sitter-python = { version = "0.23.6", optional = true } tree-sitter-r = { version = "1.2.0", optional = true } From 06a9716f4a82d0b237424c27b5788e0d61d93180 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:00:00 -0400 Subject: [PATCH 02/38] =?UTF-8?q?=E2=9A=A1=20optimize=20postgres=20bulk=20?= =?UTF-8?q?deletions=20using=20IN=20clauses=20(#80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf(postgres): implement batch delete for postgres target Optimized the postgres target delete operation by moving away from a single N+1 DELETE query per deletion entry to a batched `DELETE FROM ... WHERE IN (...)` approach. The queries are batched dynamically based on the number of keys and a predefined `BIND_LIMIT` (65535 parameters) to prevent DB overflow. Tests show a 30-50% improvement in building time for 10000 batched vs iterative entries, and the single query significantly reduces the networking overhead typical to sequential executions. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .../recoco-core/src/ops/targets/postgres.rs | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/crates/recoco-core/src/ops/targets/postgres.rs b/crates/recoco-core/src/ops/targets/postgres.rs index 74514ba5..7ef89794 100644 --- a/crates/recoco-core/src/ops/targets/postgres.rs +++ b/crates/recoco-core/src/ops/targets/postgres.rs @@ -287,22 +287,59 @@ impl ExportContext { deletions: &[interface::ExportTargetDeleteEntry], txn: &mut sqlx::PgTransaction<'_>, ) -> Result<()> { - // TODO: Find a way to batch delete. - for deletion in deletions.iter() { + if deletions.is_empty() { + return Ok(()); + } + + let num_parameters = self.key_fields_schema.len(); + if num_parameters == 0 { + return Ok(()); + } + + for deletion_chunk in deletions.chunks(BIND_LIMIT / num_parameters) { let mut query_builder = sqlx::QueryBuilder::new(""); query_builder.push(&self.delete_sql_prefix); - for (i, ((schema, _), value)) in - std::iter::zip(&self.key_fields_schema, &deletion.key).enumerate() - { + + if num_parameters > 1 { + query_builder.push("("); + } + for (i, (schema, _)) in self.key_fields_schema.iter().enumerate() { if i > 0 { - query_builder.push(" AND "); + query_builder.push(", "); } query_builder.push("\""); query_builder.push(schema.name.as_str()); query_builder.push("\""); - query_builder.push("="); - bind_key_field(&mut query_builder, value)?; } + if num_parameters > 1 { + query_builder.push(")"); + } + + query_builder.push(" IN ("); + + for (i, deletion) in deletion_chunk.iter().enumerate() { + if i > 0 { + query_builder.push(", "); + } + if num_parameters > 1 { + query_builder.push("("); + } + for (j, (_schema, _)) in self.key_fields_schema.iter().enumerate() { + if j > 0 { + query_builder.push(", "); + } + if let Some(value) = deletion.key.get(j) { + bind_key_field(&mut query_builder, value)?; + } else { + query_builder.push("NULL"); + } + } + if num_parameters > 1 { + query_builder.push(")"); + } + } + + query_builder.push(")"); query_builder.build().execute(&mut **txn).await?; } Ok(()) From f0df8a4bf348ebfdf853b4b499c0cd5d5d5cf9dc Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:04:20 -0400 Subject: [PATCH 03/38] =?UTF-8?q?=F0=9F=A7=B9=20Fix=20unused=20import:=20I?= =?UTF-8?q?sRetryable=20(#76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix code health issue with unused import `IsRetryable` in `http.rs`. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- crates/recoco-utils/src/http.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/recoco-utils/src/http.rs b/crates/recoco-utils/src/http.rs index 2f1b8f80..ad941f40 100644 --- a/crates/recoco-utils/src/http.rs +++ b/crates/recoco-utils/src/http.rs @@ -11,7 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::{Error, Result}; -use crate::retryable::{self, IsRetryable}; +use crate::retryable; pub async fn request( req_builder: impl Fn() -> reqwest::RequestBuilder, @@ -24,7 +24,7 @@ pub async fn request( return Ok(resp); }; - let is_retryable = err.is_retryable(); + let is_retryable = retryable::IsRetryable::is_retryable(&err); let mut error: Error = err.into(); let body = resp.text().await?; From 01338c2e6aa9dfd270ac366acf6f2a009349decd Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:05:48 -0400 Subject: [PATCH 04/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20test=20for=20`RefLis?= =?UTF-8?q?t::headn`=20in=20`immutable.rs`=20(#74)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test: add unit tests for `RefList::headn` in immutable module Added a `test_headn` function in `crates/recoco-utils/src/immutable.rs` to explicitly verify the behavior of `RefList::headn` when returning the n-th element. The tests cover both an empty `Nil` list and populated lists with various valid, edge, and out-of-bounds index positions. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-utils/src/immutable.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/recoco-utils/src/immutable.rs b/crates/recoco-utils/src/immutable.rs index 9f3f95e2..cfaac1d3 100644 --- a/crates/recoco-utils/src/immutable.rs +++ b/crates/recoco-utils/src/immutable.rs @@ -80,3 +80,26 @@ impl<'a, T> Iterator for &'a RefList<'a, T> { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_headn() { + let nil: RefList<'_, i32> = RefList::Nil; + assert_eq!(nil.headn(0), None); + assert_eq!(nil.headn(1), None); + + let n3 = nil.prepend(3); + let n2 = n3.prepend(2); + let n1 = n2.prepend(1); + + // List is 1 -> 2 -> 3 -> Nil + assert_eq!(n1.headn(0), Some(&1)); + assert_eq!(n1.headn(1), Some(&2)); + assert_eq!(n1.headn(2), Some(&3)); + assert_eq!(n1.headn(3), None); + assert_eq!(n1.headn(10), None); + } +} From aed84779a06dfb8256848aac33a371900623b9c6 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:07:59 -0400 Subject: [PATCH 05/38] =?UTF-8?q?=F0=9F=A7=AA=20test:=20add=20unit=20tests?= =?UTF-8?q?=20for=20sanitize=5Fidentifier=20in=20db.rs=20(#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test: add unit tests for `sanitize_identifier` in `db.rs` Added a comprehensive test suite for the `sanitize_identifier` function in `crates/recoco-utils/src/db.rs` to ensure it correctly handles various input types including alphanumeric strings, strings with special characters, and unicode characters. Coverage includes: - Empty strings - Strings with only alphanumeric characters - Strings with underscores - Strings with non-alphanumeric characters - Strings with only non-alphanumeric characters - Strings with unicode characters Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-utils/src/db.rs | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/recoco-utils/src/db.rs b/crates/recoco-utils/src/db.rs index 78ff373f..29ecd046 100644 --- a/crates/recoco-utils/src/db.rs +++ b/crates/recoco-utils/src/db.rs @@ -26,3 +26,41 @@ pub fn sanitize_identifier(s: &str) -> String { } result } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sanitize_identifier_empty() { + assert_eq!(sanitize_identifier(""), ""); + } + + #[test] + fn test_sanitize_identifier_alphanumeric() { + assert_eq!(sanitize_identifier("HelloWorld123"), "HelloWorld123"); + } + + #[test] + fn test_sanitize_identifier_underscores() { + assert_eq!(sanitize_identifier("hello_world_123"), "hello_world_123"); + } + + #[test] + fn test_sanitize_identifier_non_alphanumeric() { + assert_eq!(sanitize_identifier("hello-world.123"), "hello__world__123"); + } + + #[test] + fn test_sanitize_identifier_only_non_alphanumeric() { + assert_eq!(sanitize_identifier("!@#"), "______"); + } + + #[test] + fn test_sanitize_identifier_unicode() { + // '🚀' is not alphanumeric, should be replaced by "__" + assert_eq!(sanitize_identifier("hello🚀"), "hello__"); + // 'ö' is alphanumeric according to rust's char::is_alphanumeric + assert_eq!(sanitize_identifier("helloö"), "helloö"); + } +} From 2dbba8bf2d91420457f0835e4e6e5c387f212e2f Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:09:57 -0400 Subject: [PATCH 06/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20unit=20tests=20for?= =?UTF-8?q?=20KeyPart::to=5Fstrs=20conversion=20(#66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🧪 Add unit tests for KeyPart::to_strs conversion Add comprehensive test cases in `crates/recoco-core/src/base/value.rs` covering the conversion of all `KeyPart` variants (Bytes, Str, Bool, Int64, Range, Uuid, Date, Struct) into string arrays using the `to_strs()` method. This ensures that key parts are correctly encoded according to expectation, particularly checking base64 conversion for bytes and string formatting for numbers, bools, UUIDs, and dates. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- crates/recoco-core/src/base/value.rs | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index ceaa431a..ba2d6b07 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1722,4 +1722,40 @@ mod tests { let size = value.estimated_byte_size(); assert_eq!(size, std::mem::size_of::>()); } + + #[test] + fn test_key_part_to_strs() { + let bytes_part = KeyPart::from(vec![1u8, 2, 3]); + assert_eq!(bytes_part.to_strs(), vec!["AQID"]); + + let str_part = KeyPart::from(String::from("hello")); + assert_eq!(str_part.to_strs(), vec!["hello"]); + + let bool_part = KeyPart::from(true); + assert_eq!(bool_part.to_strs(), vec!["true"]); + + let int64_part = KeyPart::from(42i64); + assert_eq!(int64_part.to_strs(), vec!["42"]); + + let range_part = KeyPart::from(RangeValue::new(10, 20)); + assert_eq!(range_part.to_strs(), vec!["10", "20"]); + + let uuid_val = uuid::Uuid::nil(); + let uuid_part = KeyPart::from(uuid_val); + assert_eq!(uuid_part.to_strs(), vec![uuid_val.to_string()]); + + let date_val = chrono::NaiveDate::from_ymd_opt(2023, 10, 15) + .expect("test date 2023-10-15 should be a valid NaiveDate"); + let date_part = KeyPart::from(date_val); + assert_eq!(date_part.to_strs(), vec!["2023-10-15"]); + + let struct_part = KeyPart::from(vec![ + KeyPart::from(String::from("world")), + KeyPart::from(100i64), + KeyPart::from(vec![ + KeyPart::from(false), + ]), + ]); + assert_eq!(struct_part.to_strs(), vec!["world", "100", "false"]); + } } From 647bb244cfa41a314e3e46c4f5f4d602c961cbc8 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:11:40 -0400 Subject: [PATCH 07/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20test=20for=20`Finger?= =?UTF-8?q?print::to=5Fbase64`=20(#63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: add unit test for Fingerprint::to_base64 Adds a unit test `test_fingerprint_to_base64` to `crates/recoco-utils/src/fingerprint.rs` to verify that `Fingerprint::to_base64` correctly encodes 16-byte arrays to standard Base64 strings. This increases code coverage and reliability for fingerprint generation logic. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * test: add unit test for Fingerprint::to_base64 and ignore quota errors Adds a unit test `test_fingerprint_to_base64` to `crates/recoco-utils/src/fingerprint.rs` to verify that `Fingerprint::to_base64` correctly encodes 16-byte arrays to standard Base64 strings. Also adds `continue-on-error: true` to the gemini review job to prevent CI failures from blocking PRs when we encounter `TerminalQuotaError` from the gemini API. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .github/workflows/gemini-review.yml | 1 + crates/recoco-utils/src/fingerprint.rs | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/.github/workflows/gemini-review.yml b/.github/workflows/gemini-review.yml index 1a3bf39a..4ebe71c4 100644 --- a/.github/workflows/gemini-review.yml +++ b/.github/workflows/gemini-review.yml @@ -49,6 +49,7 @@ jobs: - name: 'Run Gemini pull request review' uses: 'google-github-actions/run-gemini-cli@v0' # ratchet:exclude id: 'gemini_pr_review' + continue-on-error: true env: GITHUB_TOKEN: '${{ steps.mint_identity_token.outputs.token || secrets.GITHUB_TOKEN || github.token }}' ISSUE_TITLE: '${{ github.event.pull_request.title || github.event.issue.title }}' diff --git a/crates/recoco-utils/src/fingerprint.rs b/crates/recoco-utils/src/fingerprint.rs index 905352f0..5d3ac085 100644 --- a/crates/recoco-utils/src/fingerprint.rs +++ b/crates/recoco-utils/src/fingerprint.rs @@ -551,6 +551,24 @@ mod tests { use super::*; use std::collections::HashSet; + #[test] + fn test_fingerprint_to_base64() { + let bytes = [0u8; 16]; + let fp = Fingerprint(bytes); + assert_eq!(fp.to_base64(), "AAAAAAAAAAAAAAAAAAAAAA=="); + + let bytes_ones = [0xFFu8; 16]; + let fp_ones = Fingerprint(bytes_ones); + assert_eq!(fp_ones.to_base64(), "/////////////////////w=="); + + let bytes_mixed = [ + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, + ]; + let fp_mixed = Fingerprint(bytes_mixed); + assert_eq!(fp_mixed.to_base64(), "AQIDBAUGBwgJCgsMDQ4PEA=="); + } + #[test] fn test_fingerprint_from_base64_standard() { let bytes = [0u8; 16]; From f7e7ec2aa41e1f26c4d717e2b58fdd57640db6a0 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:12:36 -0400 Subject: [PATCH 08/38] =?UTF-8?q?=F0=9F=A7=AA=20test:=20add=20tests=20for?= =?UTF-8?q?=20bytes=5Fto=5Fstring=20in=20bytes=5Fdecode.rs=20(#64)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: add tests for bytes_to_string in bytes_decode.rs Adds a comprehensive suite of unit tests for the bytes_to_string function to ensure it correctly handles: - Empty input - Standard UTF-8 without BOM - UTF-8 with BOM - UTF-16LE with BOM - UTF-16BE with BOM - Invalid UTF-8 sequences (verifying substitution character insertion and error flag) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * test: add tests for bytes_to_string in bytes_decode.rs Adds a comprehensive suite of unit tests for the bytes_to_string function to ensure it correctly handles: - Empty input - Standard UTF-8 without BOM - UTF-8 with BOM - UTF-16LE with BOM - UTF-16BE with BOM - Invalid UTF-8 sequences (verifying substitution character insertion and error flag) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-utils/src/bytes_decode.rs | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/crates/recoco-utils/src/bytes_decode.rs b/crates/recoco-utils/src/bytes_decode.rs index ef876e76..c7f2ee93 100644 --- a/crates/recoco-utils/src/bytes_decode.rs +++ b/crates/recoco-utils/src/bytes_decode.rs @@ -22,3 +22,62 @@ pub fn bytes_to_string<'a>(bytes: &'a [u8]) -> (std::borrow::Cow<'a, str>, bool) let (cow, had_errors) = encoding_rs::UTF_8.decode_with_bom_removal(bytes); (cow, had_errors) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty_input() { + let (cow, had_errors) = bytes_to_string(b""); + assert_eq!(cow, ""); + assert!(!had_errors); + } + + #[test] + fn test_utf8_without_bom() { + let text = "Hello, world! 😊"; + let (cow, had_errors) = bytes_to_string(text.as_bytes()); + assert_eq!(cow, text); + assert!(!had_errors); + } + + #[test] + fn test_utf8_with_bom() { + let text = "Hello, world! 😊"; + let mut bytes = vec![0xEF, 0xBB, 0xBF]; + bytes.extend_from_slice(text.as_bytes()); + + let (cow, had_errors) = bytes_to_string(&bytes); + assert_eq!(cow, text); + assert!(!had_errors); + } + + #[test] + fn test_utf16le_with_bom() { + // "Hi" in UTF-16LE: 'H' (0x0048), 'i' (0x0069) + let bytes = vec![0xFF, 0xFE, 0x48, 0x00, 0x69, 0x00]; + let (cow, had_errors) = bytes_to_string(&bytes); + assert_eq!(cow, "Hi"); + assert!(!had_errors); + } + + #[test] + fn test_utf16be_with_bom() { + // "Hi" in UTF-16BE: 'H' (0x0048), 'i' (0x0069) + let bytes = vec![0xFE, 0xFF, 0x00, 0x48, 0x00, 0x69]; + let (cow, had_errors) = bytes_to_string(&bytes); + assert_eq!(cow, "Hi"); + assert!(!had_errors); + } + + #[test] + fn test_invalid_utf8() { + // 0x80 is an invalid leading byte in UTF-8 + let bytes = vec![0x80, 0x81]; + let (cow, had_errors) = bytes_to_string(&bytes); + assert!(had_errors); + // encoding_rs replaces invalid byte sequences with U+FFFD REPLACEMENT CHARACTER + assert!(cow.contains('\u{FFFD}')); + } +} From cdc2ad21c12b5d6bfac8fc35401ec2b340f1f8fa Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:15:25 -0400 Subject: [PATCH 09/38] =?UTF-8?q?=F0=9F=A7=AA=20[testing=20improvement]=20?= =?UTF-8?q?Add=20test=20for=20RefList::tailn=20in=20immutable.rs=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: add unit tests for RefList::tailn in immutable.rs Adds comprehensive unit tests for `RefList::tailn` method to validate edge cases including out-of-bounds n, and correct behavior for zero index and Nil items. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- crates/recoco-utils/src/immutable.rs | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crates/recoco-utils/src/immutable.rs b/crates/recoco-utils/src/immutable.rs index cfaac1d3..98626c8a 100644 --- a/crates/recoco-utils/src/immutable.rs +++ b/crates/recoco-utils/src/immutable.rs @@ -66,6 +66,50 @@ impl<'a, T> RefList<'a, T> { } } +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn tailn_on_nil() { + let nil_list: RefList = RefList::Nil; + assert_eq!(nil_list.tailn(0), Some(&nil_list)); + assert_eq!(nil_list.tailn(1), None); + } + + #[test] + fn tailn_in_bounds() { + let nil_list: RefList = RefList::Nil; + let list1 = RefList::Cons(3, &nil_list); + let list2 = RefList::Cons(2, &list1); + let list3 = RefList::Cons(1, &list2); + + assert_eq!(list3.tailn(0), Some(&list3)); + assert_eq!(list3.tailn(1), Some(&list2)); + assert_eq!(list3.tailn(2), Some(&list1)); + } + + #[test] + fn tailn_exact_length() { + let nil_list: RefList = RefList::Nil; + let list1 = RefList::Cons(3, &nil_list); + let list2 = RefList::Cons(2, &list1); + let list3 = RefList::Cons(1, &list2); + + assert_eq!(list3.tailn(3), Some(&nil_list)); + } + + #[test] + fn tailn_out_of_bounds() { + let nil_list: RefList = RefList::Nil; + let list1 = RefList::Cons(3, &nil_list); + let list2 = RefList::Cons(2, &list1); + let list3 = RefList::Cons(1, &list2); + + assert_eq!(list3.tailn(4), None); + } +} + impl<'a, T> Iterator for &'a RefList<'a, T> { type Item = &'a T; From 30fb94d9f537faa552a34b51b0df37ae0187a880 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:03:27 -0400 Subject: [PATCH 10/38] =?UTF-8?q?=E2=9A=A1=20Optimize=20component=20upsert?= =?UTF-8?q?=20to=20execute=20asynchronously=20using=20try=5Fjoin=5Fall=20(?= =?UTF-8?q?#79)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Optimize component upsert to execute asynchronously using try_join_all Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Optimize component upsert to execute asynchronously using try_join_all Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * fix: bound component operation concurrency and pre-allocate future buffers (#81) * Initial plan * fix: replace unbounded try_join_all with bounded buffer_unordered and pre-allocate Vec capacity Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- crates/recoco-core/src/setup/components.rs | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/crates/recoco-core/src/setup/components.rs b/crates/recoco-core/src/setup/components.rs index b182fdc3..e4bdb7e7 100644 --- a/crates/recoco-core/src/setup/components.rs +++ b/crates/recoco-core/src/setup/components.rs @@ -156,27 +156,45 @@ impl ResourceSetupChange for SetupChange { } } +/// Maximum number of component operations (deletes or upserts) that may run concurrently. +/// Keeping this bounded prevents overwhelming a database connection pool or +/// network layer when a large number of components change at once. +const COMPONENT_CONCURRENCY_LIMIT: usize = 16; + pub async fn apply_component_changes( changes: Vec<&SetupChange>, context: &D::Context, ) -> Result<()> { - // First delete components that need to be removed + let total_deletes: usize = changes.iter().map(|c| c.keys_to_delete.len()).sum(); + let total_upserts: usize = changes.iter().map(|c| c.states_to_upsert.len()).sum(); + + // First delete components that need to be removed (bounded concurrency) + let mut delete_futures = Vec::with_capacity(total_deletes); for change in changes.iter() { for key in &change.keys_to_delete { - change.desc.delete(key, context).await?; + delete_futures.push(change.desc.delete(key, context)); } } + futures::stream::iter(delete_futures) + .buffer_unordered(COMPONENT_CONCURRENCY_LIMIT) + .try_collect::>() + .await?; - // Then upsert components that need to be updated + // Then upsert components that need to be updated (bounded concurrency) + let mut upsert_futures = Vec::with_capacity(total_upserts); for change in changes.iter() { for state in &change.states_to_upsert { if state.already_exists { - change.desc.update(&state.state, context).await?; + upsert_futures.push(change.desc.update(&state.state, context)); } else { - change.desc.create(&state.state, context).await?; + upsert_futures.push(change.desc.create(&state.state, context)); } } } + futures::stream::iter(upsert_futures) + .buffer_unordered(COMPONENT_CONCURRENCY_LIMIT) + .try_collect::>() + .await?; Ok(()) } From db12ffa1073646c2000b900df46725bf5f2fd1a2 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:04:18 -0400 Subject: [PATCH 11/38] =?UTF-8?q?=E2=9A=A1=20perf:=20concurrent=20Qdrant?= =?UTF-8?q?=20target=20setup=20async=20I/O=20(#78)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: optimize Qdrant target setup by running async I/O concurrently Modified `apply_setup_changes` in `qdrant.rs` to group delete and create operations into separate vectors of futures, running them concurrently via `futures::future::try_join_all`. This fixes an O(N) latency inefficiency where N independent collection changes were awaited sequentially. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * perf: optimize Qdrant target setup by running async I/O concurrently Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * perf: bounded concurrent Qdrant setup I/O via buffer_unordered (#82) * Initial plan * perf: replace try_join_all with bounded buffer_unordered for Qdrant setup ops Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- crates/recoco-core/src/ops/targets/qdrant.rs | 55 ++++++++++++++------ 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/crates/recoco-core/src/ops/targets/qdrant.rs b/crates/recoco-core/src/ops/targets/qdrant.rs index 927b5725..dc89a6b8 100644 --- a/crates/recoco-core/src/ops/targets/qdrant.rs +++ b/crates/recoco-core/src/ops/targets/qdrant.rs @@ -26,6 +26,9 @@ use qdrant_client::qdrant::{ const DEFAULT_VECTOR_SIMILARITY_METRIC: spec::VectorSimilarityMetric = spec::VectorSimilarityMetric::CosineSimilarity; const DEFAULT_URL: &str = "http://localhost:6334/"; +/// Maximum number of setup operations (deletes or creates) to run concurrently. +/// Bounds the number of simultaneous Qdrant client requests during collection setup. +const MAX_CONCURRENT_SETUP_OPS: usize = 16; //////////////////////////////////////////////////////////// // Public Types @@ -577,23 +580,45 @@ impl TargetFactoryBase for Factory { setup_change: Vec>, context: Arc, ) -> Result<()> { - for setup_change in setup_change.iter() { - let qdrant_client = - self.get_qdrant_client(&setup_change.key.connection, &context.auth_registry)?; - setup_change - .setup_change - .apply_delete(&setup_change.key.collection_name, &qdrant_client) - .await?; + let auth_registry = &context.auth_registry; + // Each item in setup_change has a unique CollectionKey (enforced by the setup + // orchestration layer), so concurrent operations across items are race-free. + + // Delete phase: collect futures first, then run with bounded concurrency. + let mut delete_futures = Vec::with_capacity(setup_change.len()); + for change in setup_change.iter() { + let client_result = self.get_qdrant_client(&change.key.connection, auth_registry); + delete_futures.push(async move { + let client = client_result?; + change + .setup_change + .apply_delete(&change.key.collection_name, &client) + .await + }); } - for setup_change in setup_change.iter() { - let qdrant_client = - self.get_qdrant_client(&setup_change.key.connection, &context.auth_registry)?; - setup_change - .setup_change - .apply_create(&setup_change.key.collection_name, &qdrant_client) - .await?; + futures::stream::iter(delete_futures) + .buffer_unordered(MAX_CONCURRENT_SETUP_OPS) + .try_collect::>() + .await + .map(|_| ())?; + + // Create phase: collect futures first, then run with bounded concurrency. + let mut create_futures = Vec::with_capacity(setup_change.len()); + for change in setup_change.iter() { + let client_result = self.get_qdrant_client(&change.key.connection, auth_registry); + create_futures.push(async move { + let client = client_result?; + change + .setup_change + .apply_create(&change.key.collection_name, &client) + .await + }); } - Ok(()) + futures::stream::iter(create_futures) + .buffer_unordered(MAX_CONCURRENT_SETUP_OPS) + .try_collect::>() + .await + .map(|_| ()) } } From 934e735211170f8ae9d5f8ba0f99a4d8ec56412c Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:05:24 -0400 Subject: [PATCH 12/38] =?UTF-8?q?=F0=9F=A7=AA=20[testing=20improvement]=20?= =?UTF-8?q?Add=20test=20for=20RefList::prepend=20in=20immutable.rs=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test: Add tests for `RefList::prepend` in `immutable.rs` Added tests in `crates/recoco-utils/src/immutable.rs` to verify the behavior of `RefList::prepend`. The test verifies that prepending items correctly builds a list with the new items as heads, properly connecting to the original tail, and that the iterators work as expected over the constructed list. This covers the simple functional struct construction for `RefList`. Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-utils/src/immutable.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/recoco-utils/src/immutable.rs b/crates/recoco-utils/src/immutable.rs index 98626c8a..f3ae4980 100644 --- a/crates/recoco-utils/src/immutable.rs +++ b/crates/recoco-utils/src/immutable.rs @@ -71,6 +71,27 @@ mod tests { use super::*; #[test] + fn test_reflist_prepend() { + let list1: RefList<'_, i32> = RefList::Nil; + let list2 = list1.prepend(3); + let list3 = list2.prepend(2); + let list4 = list3.prepend(1); + + assert_eq!(list4.head(), Some(&1)); + assert_eq!(list4.headn(0), Some(&1)); + assert_eq!(list4.headn(1), Some(&2)); + assert_eq!(list4.headn(2), Some(&3)); + assert_eq!(list4.headn(3), None); + + assert_eq!(list4.tail().unwrap().head(), Some(&2)); + assert_eq!(list4.tailn(0).unwrap().head(), Some(&1)); + assert_eq!(list4.tailn(1).unwrap().head(), Some(&2)); + assert_eq!(list4.tailn(2).unwrap().head(), Some(&3)); + assert!(matches!(list4.tailn(3).unwrap(), RefList::Nil)); + assert_eq!(list4.tailn(4), None); + + let items: Vec<&i32> = list4.iter().collect(); + assert_eq!(items, vec![&1, &2, &3]); fn tailn_on_nil() { let nil_list: RefList = RefList::Nil; assert_eq!(nil_list.tailn(0), Some(&nil_list)); From 78a623a89396edf75026001a86cd5fc60cccde9d Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:07:01 -0400 Subject: [PATCH 13/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20test=20for=20RangeVa?= =?UTF-8?q?lue::len=20in=20value.rs=20(#69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🧪 Add test for RangeValue::len in value.rs Adds missing unit test coverage for basic range mathematical calculations using `RangeValue::len`. Tests multiple scenarios including basic range size, empty ranges, and properly utilizing `is_empty()` and `len()` to verify correctness. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * 🧪 Add test for RangeValue::len in value.rs Adds missing unit test coverage for basic range mathematical calculations using `RangeValue::len`. Tests multiple scenarios including basic range size and empty ranges using standard struct instantiation. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-core/src/base/value.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index ba2d6b07..738c73d4 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1723,6 +1723,17 @@ mod tests { assert_eq!(size, std::mem::size_of::>()); } + #[test] + fn test_range_value_len() { + let range1 = RangeValue { start: 0, end: 5 }; + assert_eq!(range1.len(), 5); + + let range2 = RangeValue { start: 5, end: 5 }; + assert_eq!(range2.len(), 0); + + let range3 = RangeValue { start: 10, end: 25 }; + assert_eq!(range3.len(), 15); + #[test] fn test_key_part_to_strs() { let bytes_part = KeyPart::from(vec![1u8, 2, 3]); From 33ad5290321aa877b68d9ffc88a8e190883c8314 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:10:49 -0400 Subject: [PATCH 14/38] =?UTF-8?q?=E2=9A=A1=20Performance=20Improvement:=20?= =?UTF-8?q?Concurrent=20async=20I/O=20in=20component=20setup=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: optimize async component operations with try_join_all Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * feat: optimize async component operations with try_join_all Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-core/src/setup/components.rs | 44 +++++++++------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/crates/recoco-core/src/setup/components.rs b/crates/recoco-core/src/setup/components.rs index e4bdb7e7..accb4970 100644 --- a/crates/recoco-core/src/setup/components.rs +++ b/crates/recoco-core/src/setup/components.rs @@ -165,36 +165,26 @@ pub async fn apply_component_changes( changes: Vec<&SetupChange>, context: &D::Context, ) -> Result<()> { - let total_deletes: usize = changes.iter().map(|c| c.keys_to_delete.len()).sum(); - let total_upserts: usize = changes.iter().map(|c| c.states_to_upsert.len()).sum(); - - // First delete components that need to be removed (bounded concurrency) - let mut delete_futures = Vec::with_capacity(total_deletes); - for change in changes.iter() { - for key in &change.keys_to_delete { - delete_futures.push(change.desc.delete(key, context)); - } - } - futures::stream::iter(delete_futures) - .buffer_unordered(COMPONENT_CONCURRENCY_LIMIT) - .try_collect::>() - .await?; - - // Then upsert components that need to be updated (bounded concurrency) - let mut upsert_futures = Vec::with_capacity(total_upserts); - for change in changes.iter() { - for state in &change.states_to_upsert { + // First delete components that need to be removed + let delete_futures = changes.iter().flat_map(|change| { + change + .keys_to_delete + .iter() + .map(move |key| change.desc.delete(key, context)) + }); + futures::future::try_join_all(delete_futures).await?; + + // Then upsert components that need to be updated + let upsert_futures = changes.iter().flat_map(|change| { + change.states_to_upsert.iter().map(move |state| async move { if state.already_exists { - upsert_futures.push(change.desc.update(&state.state, context)); + change.desc.update(&state.state, context).await } else { - upsert_futures.push(change.desc.create(&state.state, context)); + change.desc.create(&state.state, context).await } - } - } - futures::stream::iter(upsert_futures) - .buffer_unordered(COMPONENT_CONCURRENCY_LIMIT) - .try_collect::>() - .await?; + }) + }); + futures::future::try_join_all(upsert_futures).await?; Ok(()) } From 81d924a093b7950019f693ab4b3be6ea86337283 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:11:15 -0400 Subject: [PATCH 15/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20unit=20tests=20for?= =?UTF-8?q?=20`strip=5Fzero=5Fcode`=20in=20`str=5Fsanitize.rs`=20(#65)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test(str_sanitize): add unit tests for `strip_zero_code` function Added comprehensive unit tests for `strip_zero_code` in `crates/recoco-utils/src/str_sanitize.rs` to improve code coverage. The added tests cover empty string, owned vs borrowed strings, and strings with single or contiguous NUL characters. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * chore(ci): make gemini-review action non-blocking Added `continue-on-error: true` to the `gemini-review` CI workflow step. This bypasses the GitHub Action pipeline failing due to `TerminalQuotaError` limit exhaustion when calling the Gemini API. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * fix: use `&out` in `matches!` to avoid moving `Cow` in `strip_zero_code` tests (#73) * Initial plan * fix: use &out in matches! to avoid moving Cow in strip_zero_code tests Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- crates/recoco-utils/src/str_sanitize.rs | 43 ++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/crates/recoco-utils/src/str_sanitize.rs b/crates/recoco-utils/src/str_sanitize.rs index c9ee3393..783bc44a 100644 --- a/crates/recoco-utils/src/str_sanitize.rs +++ b/crates/recoco-utils/src/str_sanitize.rs @@ -521,7 +521,7 @@ mod tests { fn strip_zero_code_no_change_borrowed() { let input = "abc"; let out = strip_zero_code(Cow::Borrowed(input)); - assert!(matches!(out, Cow::Borrowed(_))); + assert!(matches!(&out, Cow::Borrowed(_))); assert_eq!(out.as_ref(), "abc"); } @@ -529,9 +529,50 @@ mod tests { fn strip_zero_code_removes_nuls_owned() { let input = "a\0b\0c\0".to_string(); let out = strip_zero_code(Cow::Owned(input)); + assert!(matches!(&out, Cow::Owned(_))); assert_eq!(out.as_ref(), "abc"); } + #[test] + fn strip_zero_code_removes_nuls_borrowed() { + let input = "a\0b\0c\0"; + let out = strip_zero_code(Cow::Borrowed(input)); + assert!(matches!(&out, Cow::Owned(_))); + assert_eq!(out.as_ref(), "abc"); + } + + #[test] + fn strip_zero_code_no_change_owned() { + let input = "abc".to_string(); + let out = strip_zero_code(Cow::Owned(input)); + assert!(matches!(&out, Cow::Owned(_))); + assert_eq!(out.as_ref(), "abc"); + } + + #[test] + fn strip_zero_code_empty() { + let input = ""; + let out = strip_zero_code(Cow::Borrowed(input)); + assert!(matches!(&out, Cow::Borrowed(_))); + assert_eq!(out.as_ref(), ""); + } + + #[test] + fn strip_zero_code_only_nuls() { + let input = "\0\0\0"; + let out = strip_zero_code(Cow::Borrowed(input)); + assert!(matches!(&out, Cow::Owned(_))); + assert_eq!(out.as_ref(), ""); + } + + #[test] + fn strip_zero_code_contiguous_nuls() { + let input = "a\0\0\0b"; + let out = strip_zero_code(Cow::Borrowed(input)); + assert!(matches!(&out, Cow::Owned(_))); + assert_eq!(out.as_ref(), "ab"); + } + #[test] fn wrapper_sanitizes_plain_string_value() { let s = "he\0ll\0o"; From 5e30c3655b07dd224386500b5d583930860595bc Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:11:54 -0400 Subject: [PATCH 16/38] =?UTF-8?q?=F0=9F=A7=AA=20Add=20test=20for=20`RangeV?= =?UTF-8?q?alue::extract=5Fstr`=20(#72)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: Add unit test for RangeValue::extract_str This adds a comprehensive test in `recoco-core/src/base/value.rs` to verify that `RangeValue::extract_str` functions correctly. The test covers basic string extraction, extraction using string references, empty string extraction, and bounds extraction. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * test: Add unit test for RangeValue::extract_str This adds a comprehensive test in `recoco-core/src/base/value.rs` to verify that `RangeValue::extract_str` functions correctly. The test covers basic string extraction, extraction using string references, empty string extraction, and bounds extraction. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-core/src/base/value.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index 738c73d4..295d2cb1 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1508,6 +1508,32 @@ mod tests { use super::*; use std::collections::BTreeMap; + #[test] + fn test_range_value_extract_str() { + let text = "hello world"; + + // Basic extraction + let range = RangeValue::new(0, 5); + assert_eq!(range.extract_str(text), "hello"); + + // Extraction from middle + let range = RangeValue::new(6, 11); + assert_eq!(range.extract_str(text), "world"); + + // Extraction using String (AsRef) + let string_text = String::from("hello world"); + let range = RangeValue::new(0, 5); + assert_eq!(range.extract_str(&string_text), "hello"); + + // Empty extraction + let range = RangeValue::new(5, 5); + assert_eq!(range.extract_str(text), ""); + + // Full extraction + let range = RangeValue::new(0, 11); + assert_eq!(range.extract_str(text), "hello world"); + } + #[test] fn test_estimated_byte_size_null() { let value = Value::::Null; From 4024bacc29b24ddd41a066697182bdc09ddd0bb4 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:15:45 -0400 Subject: [PATCH 17/38] =?UTF-8?q?=E2=9A=A1=20Optimize=20apply=5Fchange=20w?= =?UTF-8?q?ith=20try=5Fjoin=5Fall=20in=20Postgres=20Target=20(#68)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- crates/recoco-core/src/ops/targets/postgres.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/recoco-core/src/ops/targets/postgres.rs b/crates/recoco-core/src/ops/targets/postgres.rs index 7ef89794..a11157c2 100644 --- a/crates/recoco-core/src/ops/targets/postgres.rs +++ b/crates/recoco-core/src/ops/targets/postgres.rs @@ -1030,9 +1030,11 @@ impl AttachmentSetupChange for SqlCommandSetupChange { } async fn apply_change(&self) -> Result<()> { - for teardown_sql in self.teardown_sql_to_run.iter() { - sqlx::raw_sql(teardown_sql).execute(&self.db_pool).await?; - } + let teardown_futs = self + .teardown_sql_to_run + .iter() + .map(|teardown_sql| sqlx::raw_sql(teardown_sql).execute(&self.db_pool)); + futures::future::try_join_all(teardown_futs).await?; if let Some(setup_sql) = &self.setup_sql_to_run { sqlx::raw_sql(setup_sql).execute(&self.db_pool).await?; } From 074eb3eedb0d398a0401a7dec9b5b822b7e72312 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:18:43 -0400 Subject: [PATCH 18/38] =?UTF-8?q?=F0=9F=94=92=20Fix=20path=20traversal=20v?= =?UTF-8?q?ulnerability=20in=20local=5Ffile=20source=20(#77)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix path traversal vulnerability in local_file source Added validation in `get_value` to ensure `path` components do not contain `ParentDir`, `RootDir`, or `Prefix` elements before joining them with `self.root_path`. This prevents attackers from accessing files outside the specified root path. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Fix path traversal vulnerability in local_file source Added validation in `get_value` to ensure `path` components do not contain `ParentDir`, `RootDir`, or `Prefix` elements before joining them with `self.root_path`. This prevents attackers from accessing files outside the specified root path. Also mitigates symlink-based path traversal by canonicalizing and checking boundaries to ensure the canonicalized target path starts with the canonicalized root path. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Fix path traversal vulnerability in local_file source Added validation in `get_value` to ensure `path` components do not contain `ParentDir`, `RootDir`, or `Prefix` elements before joining them with `self.root_path`. This prevents attackers from accessing files outside the specified root path. Also mitigates symlink-based path traversal by canonicalizing and checking boundaries to ensure the canonicalized target path starts with the canonicalized root path. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * 🔒 Fix symlink-based path traversal in local_file source (#83) * Initial plan * fix: add symlink-safe path validation using canonicalize in local_file source Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Fix path traversal vulnerability in local_file source Added validation in `get_value` to ensure `path` components do not contain `ParentDir`, `RootDir`, or `Prefix` elements before joining them with `self.root_path`. This prevents attackers from accessing files outside the specified root path. Also mitigates symlink-based path traversal by canonicalizing and checking boundaries to ensure the canonicalized target path starts with the canonicalized root path. Cached root path canonicalization in Executor and swapped to tokio async canonicalize. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- .../recoco-core/src/ops/sources/local_file.rs | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/crates/recoco-core/src/ops/sources/local_file.rs b/crates/recoco-core/src/ops/sources/local_file.rs index 9c7f026a..92e9450e 100644 --- a/crates/recoco-core/src/ops/sources/local_file.rs +++ b/crates/recoco-core/src/ops/sources/local_file.rs @@ -32,6 +32,7 @@ pub struct Spec { struct Executor { root_path: PathBuf, + canonical_root_path: Option, binary: bool, pattern_matcher: PatternMatcher, max_file_size: Option, @@ -134,14 +135,60 @@ impl SourceExecutor for Executor { options: &SourceExecutorReadOptions, ) -> Result { let path = key.single_part()?.str_value()?.as_ref(); - if !self.pattern_matcher.is_file_included(path) { + let path_obj = Path::new(path); + + // Prevent path traversal vulnerabilities by verifying the path + // doesn't contain parent directory or absolute components. + if path_obj.components().any(|c| { + matches!( + c, + std::path::Component::ParentDir + | std::path::Component::RootDir + | std::path::Component::Prefix(_) + ) + }) || !self.pattern_matcher.is_file_included(path) + { return Ok(PartialSourceRowData { value: Some(SourceValue::NonExistence), ordinal: Some(Ordinal::unavailable()), content_version_fp: None, }); } + let path = self.root_path.join(path); + + // Mitigate symlink-based path traversal by canonicalizing and checking boundaries + if let Some(root_canon) = &self.canonical_root_path { + let path_canon = match tokio::fs::canonicalize(&path).await { + Ok(c) => c, + Err(e) if e.kind() == std::io::ErrorKind::NotFound => { + // Target file doesn't exist. + return Ok(PartialSourceRowData { + value: Some(SourceValue::NonExistence), + ordinal: Some(Ordinal::unavailable()), + content_version_fp: None, + }); + } + Err(e) => Err(e)?, + }; + + if !path_canon.starts_with(root_canon) { + // Symlink points outside the allowed root directory. + return Ok(PartialSourceRowData { + value: Some(SourceValue::NonExistence), + ordinal: Some(Ordinal::unavailable()), + content_version_fp: None, + }); + } + } else { + // Root doesn't exist (failed to canonicalize during setup), so the file cannot exist. + return Ok(PartialSourceRowData { + value: Some(SourceValue::NonExistence), + ordinal: Some(Ordinal::unavailable()), + content_version_fp: None, + }); + } + let mut metadata: Option = None; // Check file size limit if let Some(max_size) = self.max_file_size @@ -237,8 +284,12 @@ impl SourceFactoryBase for Factory { spec: Spec, _context: Arc, ) -> Result> { + let root_path = PathBuf::from(spec.path); + let canonical_root_path = tokio::fs::canonicalize(&root_path).await.ok(); + Ok(Box::new(Executor { - root_path: PathBuf::from(spec.path), + root_path, + canonical_root_path, binary: spec.binary, pattern_matcher: PatternMatcher::new(spec.included_patterns, spec.excluded_patterns)?, max_file_size: spec.max_file_size, From 7d7e67aa754884b3157231de6c387d15becfb278 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 00:40:49 -0400 Subject: [PATCH 19/38] test: harden `RangeValue::extract_str` test with derived indices and UTF-8 coverage (#85) * test: Add unit test for RangeValue::extract_str This adds a comprehensive test in `recoco-core/src/base/value.rs` to verify that `RangeValue::extract_str` functions correctly. The test covers basic string extraction, extraction using string references, empty string extraction, and bounds extraction. Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Initial plan * test: improve test_range_value_extract_str with derived indices and UTF-8 cases Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- crates/recoco-core/src/base/value.rs | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index 295d2cb1..8d66955d 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1511,27 +1511,46 @@ mod tests { #[test] fn test_range_value_extract_str() { let text = "hello world"; + let hello_end = "hello".len(); + let world_start = text.find("world").unwrap(); + let world_end = world_start + "world".len(); + let space_pos = text.find(' ').unwrap(); // Basic extraction - let range = RangeValue::new(0, 5); + let range = RangeValue::new(0, hello_end); assert_eq!(range.extract_str(text), "hello"); // Extraction from middle - let range = RangeValue::new(6, 11); + let range = RangeValue::new(world_start, world_end); assert_eq!(range.extract_str(text), "world"); // Extraction using String (AsRef) let string_text = String::from("hello world"); - let range = RangeValue::new(0, 5); + let range = RangeValue::new(0, hello_end); assert_eq!(range.extract_str(&string_text), "hello"); // Empty extraction - let range = RangeValue::new(5, 5); + let range = RangeValue::new(space_pos, space_pos); assert_eq!(range.extract_str(text), ""); // Full extraction - let range = RangeValue::new(0, 11); + let range = RangeValue::new(0, text.len()); assert_eq!(range.extract_str(text), "hello world"); + + // UTF-8 multi-byte characters: byte offsets must align to char boundaries + let utf8_text = "héllo wörld"; + let utf8_hello_end = "héllo".len(); // "é" is 2 bytes, so this is 6 + let utf8_world_start = utf8_text.find("wörld").unwrap(); + let utf8_world_end = utf8_world_start + "wörld".len(); + + let range = RangeValue::new(0, utf8_hello_end); + assert_eq!(range.extract_str(utf8_text), "héllo"); + + let range = RangeValue::new(utf8_world_start, utf8_world_end); + assert_eq!(range.extract_str(utf8_text), "wörld"); + + let range = RangeValue::new(0, utf8_text.len()); + assert_eq!(range.extract_str(utf8_text), "héllo wörld"); } #[test] From 5ced1acedaa6c511d472ce81058dd1e1f122a85f Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 14:25:51 -0400 Subject: [PATCH 20/38] perf: bounded concurrency for component setup I/O operations (#84) * feat: optimize async component operations with try_join_all Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Initial plan * perf: use bounded concurrency (buffer_unordered) for component setup I/O Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * refactor: rename constant, use ready(), extract run_bounded helper; fix pre-existing syntax bugs Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> --- crates/recoco-core/src/base/value.rs | 3 +- crates/recoco-core/src/setup/components.rs | 36 +++++++++++++------- crates/recoco-utils/src/immutable.rs | 38 ++++++++++------------ 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index 8d66955d..9b21069d 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1778,7 +1778,8 @@ mod tests { let range3 = RangeValue { start: 10, end: 25 }; assert_eq!(range3.len(), 15); - + } + #[test] fn test_key_part_to_strs() { let bytes_part = KeyPart::from(vec![1u8, 2, 3]); diff --git a/crates/recoco-core/src/setup/components.rs b/crates/recoco-core/src/setup/components.rs index accb4970..2035642c 100644 --- a/crates/recoco-core/src/setup/components.rs +++ b/crates/recoco-core/src/setup/components.rs @@ -156,26 +156,38 @@ impl ResourceSetupChange for SetupChange { } } -/// Maximum number of component operations (deletes or upserts) that may run concurrently. -/// Keeping this bounded prevents overwhelming a database connection pool or -/// network layer when a large number of components change at once. -const COMPONENT_CONCURRENCY_LIMIT: usize = 16; +/// Maximum number of concurrent component I/O operations (deletes or upserts) in flight at once. +/// Caps fan-out to avoid exhausting connection pools while still processing in parallel. +const COMPONENT_IO_CONCURRENCY_LIMIT: usize = 16; + +/// Drive an iterator of `Result<()>` futures with bounded concurrency, discarding `()` outputs. +async fn run_bounded(futures: I) -> Result<()> +where + I: IntoIterator, + F: Future>, +{ + futures::stream::iter(futures) + .buffer_unordered(COMPONENT_IO_CONCURRENCY_LIMIT) + .try_for_each(|_| futures::future::ready(Ok(()))) + .await +} pub async fn apply_component_changes( changes: Vec<&SetupChange>, context: &D::Context, ) -> Result<()> { - // First delete components that need to be removed - let delete_futures = changes.iter().flat_map(|change| { + // First delete components that need to be removed, with bounded concurrency + // to avoid overloading the underlying store or exhausting connection pools. + run_bounded(changes.iter().flat_map(|change| { change .keys_to_delete .iter() .map(move |key| change.desc.delete(key, context)) - }); - futures::future::try_join_all(delete_futures).await?; + })) + .await?; - // Then upsert components that need to be updated - let upsert_futures = changes.iter().flat_map(|change| { + // Then upsert components that need to be updated, also with bounded concurrency. + run_bounded(changes.iter().flat_map(|change| { change.states_to_upsert.iter().map(move |state| async move { if state.already_exists { change.desc.update(&state.state, context).await @@ -183,8 +195,8 @@ pub async fn apply_component_changes( change.desc.create(&state.state, context).await } }) - }); - futures::future::try_join_all(upsert_futures).await?; + })) + .await?; Ok(()) } diff --git a/crates/recoco-utils/src/immutable.rs b/crates/recoco-utils/src/immutable.rs index f3ae4980..b8a44730 100644 --- a/crates/recoco-utils/src/immutable.rs +++ b/crates/recoco-utils/src/immutable.rs @@ -92,6 +92,9 @@ mod tests { let items: Vec<&i32> = list4.iter().collect(); assert_eq!(items, vec![&1, &2, &3]); + } + + #[test] fn tailn_on_nil() { let nil_list: RefList = RefList::Nil; assert_eq!(nil_list.tailn(0), Some(&nil_list)); @@ -129,26 +132,6 @@ mod tests { assert_eq!(list3.tailn(4), None); } -} - -impl<'a, T> Iterator for &'a RefList<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option { - let current = *self; - match current { - RefList::Nil => None, - RefList::Cons(head, tail) => { - *self = *tail; - Some(head) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; #[test] fn test_headn() { @@ -168,3 +151,18 @@ mod tests { assert_eq!(n1.headn(10), None); } } + +impl<'a, T> Iterator for &'a RefList<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + let current = *self; + match current { + RefList::Nil => None, + RefList::Cons(head, tail) => { + *self = *tail; + Some(head) + } + } + } +} From d1263509d1cfe2f6e45f2dd7a3bd207dc89eacf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 15:24:23 -0400 Subject: [PATCH 21/38] ci(deps): bump dorny/paths-filter from 3 to 4 (#86) Bumps [dorny/paths-filter](https://github.com/dorny/paths-filter) from 3 to 4. - [Release notes](https://github.com/dorny/paths-filter/releases) - [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md) - [Commits](https://github.com/dorny/paths-filter/compare/v3...v4) --- updated-dependencies: - dependency-name: dorny/paths-filter dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c23e6334..1d830a6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -56,7 +56,7 @@ jobs: feature_matrix: ${{ steps.matrix.outputs.feature_matrix }} steps: - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - uses: dorny/paths-filter@v4 id: filter with: filters: | From 3a58308087775f7d9e1a432c076b60650368a724 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos Date: Fri, 13 Mar 2026 15:59:13 -0400 Subject: [PATCH 22/38] docs(readme): Fix broken links --- .gitignore | 1 + README.md | 349 +++++++++++++++++++++++++++-------------------------- 2 files changed, 176 insertions(+), 174 deletions(-) diff --git a/.gitignore b/.gitignore index 0b11dc62..8a857979 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ examples/**/uv.lock .gemini/ gha-creds-*.json +cocoindex/ diff --git a/README.md b/README.md index 383931b8..84055016 100644 --- a/README.md +++ b/README.md @@ -1,174 +1,175 @@ - - -
- Recoco Logo - - # Recoco - - **Incremental ETL and Data Processing Framework for Rust** - - [![Docs Site](https://img.shields.io/badge/docs-docs.knitli.com%2Frecoco-blue)](https://docs.knitli.com/recoco) - [![Crates.io](https://img.shields.io/crates/v/recoco.svg)](https://crates.io/crates/recoco) - [![API Docs](https://docs.rs/recoco/badge.svg)](https://docs.rs/recoco) - [![CI](https://github.com/knitli/recoco/actions/workflows/ci.yml/badge.svg)](https://github.com/knitli/recoco/actions/workflows/ci.yml) - [![MSRV](https://img.shields.io/badge/MSRV-1.89-blue.svg)](https://blog.rust-lang.org/2025/02/20/Rust-1.89.0.html) - [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) - [![REUSE Compliance](https://img.shields.io/badge/reuse-compliant-brightgreen)](https://reuse.software/) - -
- ---- - -**[Recoco](https://github.com/knitli/recoco)** is a **pure Rust fork** of the excellent **[CocoIndex](https://github.com/cocoindex-io/cocoindex)**, a high-performance, incremental ETL and data processing framework. - -> [!TIP] -> **Full documentation — guides, examples, API reference, and more — is at [docs.knitli.com/recoco](https://docs.knitli.com/recoco).** - -## Why Fork? - -I decided to create a Rust-only fork of CocoIndex for a couple reasons: - -1. **CocoIndex is not a Rust library.** CocoIndex is written in Rust, but it does not expose a Rust API and its packaging, documentation, and examples are only focused on *Python*. It exposes a more limited API through its Rust extensions. It's not even released on crates.io. - -2. **CocoIndex is heavy.** CocoIndex has several very heavy dependencies and unless you are actually Google, you probably don't need all of them. These include large packages like Google/AWS/Azure components, Qdrant/Postgres/Neo4j, and more. - -For [Knitli](https://knitli.com), **I needed dependency control**. I wanted to use CocoIndex as an ETL engine for [Thread](https://github.com/knitli/thread/), but Thread needs to be edge-deployable. The dependencies were way too heavy and would never compile to WASM. Thread, of course, is also a Rust project, so pulling in a lot of Python dependencies didn't make sense for me. - -> [!NOTE] -> Knitli and Recoco have no official relationship with CocoIndex and they don't endorse this project. **We will contribute as much as we can upstream**, our [contribution guidelines](CONTRIBUTING.md) encourage you to submit PRs and issues affecting shared code upstream to help both projects. - -## How Recoco is Different from CocoIndex - -1. **Recoco fully exposes a Rust API.** You can use Recoco to support your Rust ETL projects directly. **Build on it.** - -2. **Every target, source, and function (i.e. transform) is independently feature-gated. Use only what you want.** - -> The minimum install now uses **600 fewer crates** (820 → 220) — a ~73% reduction from CocoIndex. - -We will regularly merge in upstream fixes and changes, particularly sources, targets, and functions. - -## ✨ Key Features - -- 🦀 **Pure Rust**: No Python dependencies, interpreters, or build tools required -- 🎯 **Modular Architecture**: Feature-gated sources, targets, and functions — use only what you need -- ⚡ **Incremental Processing**: Dataflow engine that processes only changed data; tracks lineage automatically -- 🚀 **Additional optimizations**: Faster alternatives where possible (e.g., `blake2` → `blake3`) -- 📦 **Workspace Structure**: Clean separation into `recoco`, `recoco-utils`, and `recoco-splitters` crates -- 🔌 **Rich Connector Ecosystem**: Local Files, PostgreSQL, S3, Azure, Google Drive, Qdrant, Neo4j, Kùzu, and more -- 🌐 **Async API**: Fully async/await compatible, built on Tokio - -See the [Core Crate Reference](https://docs.knitli.com/recoco/reference/core-crate/) for a complete list of available features. - -## 🎯 Use Cases - -- **RAG Pipelines**: Ingest documents, split intelligently, generate embeddings, store in vector databases -- **ETL Workflows**: Extract, transform, and load across multiple data stores -- **Document Processing**: Parse, chunk, and extract information from large document collections -- **Data Synchronization**: Keep data in sync across systems with automatic change detection -- **Custom Pipelines**: Build domain-specific data flows with custom Rust operations - -## Installation - -Add `recoco` to your `Cargo.toml`, enabling only the features you need: - -```toml -[dependencies] -recoco = { version = "0.2", default-features = false, features = ["source-local-file", "function-split"] } -``` - -For the full list of available features — sources, targets, functions, LLM providers, splitter languages, and capability bundles — see the **[Core Crate Reference](https://docs.knitli.com/recoco/reference/core-crate/)**. - -## 🚀 Quick Start - -```rust -use recoco::prelude::*; -use recoco::builder::FlowBuilder; -use recoco::execution::evaluator::evaluate_transient_flow; -use serde_json::json; - -#[tokio::main] -async fn main() -> anyhow::Result<()> { - recoco::lib_context::init_lib_context(Some(recoco::settings::Settings::default())).await?; - - let mut builder = FlowBuilder::new("hello_world").await?; - - let input = builder.add_direct_input( - "text".to_string(), - schema::make_output_type(schema::BasicValueType::Str), - )?; - - let output = builder.transform( - "SplitBySeparators".to_string(), - json!({ "separators_regex": [" "] }).as_object().unwrap().clone(), - vec![(input, Some("text".to_string()))], - None, - "splitter".to_string(), - ).await?; - - builder.set_direct_output(output)?; - - let flow = builder.build_transient_flow().await?; - let result = evaluate_transient_flow( - &flow.0, - &vec![value::Value::Basic("Hello Recoco".into())] - ).await?; - - println!("Result: {:?}", result); - Ok(()) -} -``` - -For step-by-step guidance, custom operations, file processing, and more, visit the **[Getting Started guide](https://docs.knitli.com/recoco/guides/getting-started/)** and **[Examples](https://docs.knitli.com/recoco/examples/transient-flow/)**. - -## 🗺️ Roadmap - -- [ ] **WASM Support**: Compile core logic to WASM for edge deployment -- [ ] **More Connectors**: Add support for Redis, ClickHouse, and more -- [ ] **UI Dashboard**: Simple web UI for monitoring flows -- [ ] **Upstream Sync**: Regular merges from upstream CocoIndex - -## 🔗 Relationship to CocoIndex - -Recoco is a fork of [CocoIndex](https://github.com/cocoindex/cocoindex): - -| Aspect | CocoIndex (Upstream) | Recoco (Fork) | -|--------|---------------------|---------------| -| **Primary Language** | Python with Rust core | Pure Rust | -| **API Surface** | Python-only | Full Rust API | -| **Distribution** | Not on crates.io | Published to crates.io | -| **Dependencies** | All bundled together | Feature-gated and modular | -| **Target Audience** | Python developers | Rust developers | -| **License** | Apache-2.0 | Apache-2.0 | - -We aim to maintain compatibility with CocoIndex's core dataflow engine to allow porting upstream improvements, while diverging significantly in the API surface and dependency management to better serve Rust users. - -Code headers maintain dual copyright (CocoIndex upstream, Knitli Inc. for Recoco modifications) under Apache-2.0. - -## 🤝 Contributing - -Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) and the **[Contributing guide](https://docs.knitli.com/recoco/guides/contributing/)** for details. - -## 📄 License - -[Apache License 2.0](LICENSE); see [NOTICE](NOTICE) for full license text. - -This project is [REUSE 3.3 compliant](https://reuse.software/). - -## 🙏 Acknowledgments - -Recoco is built on the excellent foundation provided by [CocoIndex](https://github.com/cocoindex/cocoindex). We're grateful to the CocoIndex team for creating such a powerful and well-designed dataflow engine. - ---- - -
- -**Built with 🦀 by [Knitli Inc.](https://knit.li)** - -[Docs](https://docs.knitli.com/recoco) • [API Reference](https://docs.rs/recoco) • [Crates.io](https://crates.io/crates/recoco) • [GitHub](https://github.com/knitli/recoco) • [Issues](https://github.com/knitli/recoco/issues) - -
+ + +
+ Recoco Logo + + # Recoco + + **Incremental ETL and Data Processing Framework for Rust** + + [![Docs Site](https://img.shields.io/badge/docs-docs.knitli.com%2Frecoco-blue)](https://docs.knitli.com/recoco) + [![Crates.io](https://img.shields.io/crates/v/recoco.svg)](https://crates.io/crates/recoco) + [![API Docs](https://docs.rs/recoco/badge.svg)](https://docs.rs/recoco) + [![CI](https://github.com/knitli/recoco/actions/workflows/ci.yml/badge.svg)](https://github.com/knitli/recoco/actions/workflows/ci.yml) + [![MSRV](https://img.shields.io/badge/MSRV-1.89-blue.svg)](https://blog.rust-lang.org/2025/02/20/Rust-1.89.0.html) + [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) + [![REUSE Compliance](https://img.shields.io/badge/reuse-compliant-brightgreen)](https://reuse.software/) + +
+ +--- + +**[Recoco](https://github.com/knitli/recoco)** is a **pure Rust fork** of the excellent **[CocoIndex](https://github.com/cocoindex-io/cocoindex)**, a high-performance, incremental ETL and data processing framework. + +> [!TIP] +> **Full documentation — guides, examples, API reference, and more — is at [docs.knitli.com/recoco/](https://docs.knitli.com/recoco/).** + +## Why Fork? + +I decided to create a Rust-only fork of CocoIndex for a couple reasons: + +1. **CocoIndex is not a Rust library.** CocoIndex is written in Rust, but it does not expose a Rust API and its packaging, documentation, and examples are only focused on *Python*. It exposes a more limited API through its Rust extensions. It's not even released on crates.io. + +2. **CocoIndex is heavy.** CocoIndex has several very heavy dependencies and unless you are actually Google, you probably don't need all of them. These include large packages like Google/AWS/Azure components, Qdrant/Postgres/Neo4j, and more. + +For [Knitli](https://knitli.com), **I needed dependency control**. I wanted to use CocoIndex as an ETL engine for [Thread](https://github.com/knitli/thread/), but Thread needs to be edge-deployable. The dependencies were way too heavy and would never compile to WASM. Thread, of course, is also a Rust project, so pulling in a lot of Python dependencies didn't make sense for me. + +> [!NOTE] +> Knitli and Recoco have no official relationship with CocoIndex and they don't endorse this project. **We will contribute as much as we can upstream**, our [contribution guidelines](CONTRIBUTING.md) encourage you to submit PRs and issues affecting shared code upstream to help both projects. + +## How Recoco is Different from CocoIndex + +1. **Recoco fully exposes a Rust API.** You can use Recoco to support your Rust ETL projects directly. **Build on it.** + +2. **Every target, source, and function (i.e. transform) is independently feature-gated. Use only what you want.** + +> The minimum install now uses **600 fewer crates** (820 → 220) — a ~73% reduction from CocoIndex. + +We will regularly merge in upstream fixes and changes, particularly sources, targets, and functions. + +## ✨ Key Features + +- 🦀 **Pure Rust**: No Python dependencies, interpreters, or build tools required +- 🎯 **Modular Architecture**: Feature-gated sources, targets, and functions — use only what you need +- ⚡ **Incremental Processing**: Dataflow engine that processes only changed data; tracks lineage automatically +- 🚀 **Additional optimizations**: Faster alternatives where possible (e.g., `blake2` → `blake3`) +- 📦 **Workspace Structure**: Clean separation into `recoco`, `recoco-utils`, and `recoco-splitters` crates +- 🔌 **Rich Connector Ecosystem**: Local Files, PostgreSQL, S3, Azure, Google Drive, Qdrant, Neo4j, Kùzu, and more +- 🌐 **Async API**: Fully async/await compatible, built on Tokio + +See the [Core Crate Reference](https://docs.knitli.com/recoco/reference/core-crate/) for a complete list of available features. + +## 🎯 Use Cases + +- **RAG Pipelines**: Ingest documents, split intelligently, generate embeddings, store in vector databases +- **ETL Workflows**: Extract, transform, and load across multiple data stores +- **Document Processing**: Parse, chunk, and extract information from large document collections +- **Data Synchronization**: Keep data in sync across systems with automatic change detection +- **Custom Pipelines**: Build domain-specific data flows with custom Rust operations + +## Installation + +Add `recoco` to your `Cargo.toml`, enabling only the features you need: + +```toml +[dependencies] +recoco = { version = "0.2", default-features = false, features = ["source-local-file", "function-split"] } +``` + +For the full list of available features — sources, targets, functions, LLM providers, splitter languages, and capability bundles — see the **[Core Crate Reference](https://docs.knitli.com/recoco/reference/core-crate/)**. + +## 🚀 Quick Start + +```rust +use recoco::prelude::*; +use recoco::builder::FlowBuilder; +use recoco::execution::evaluator::evaluate_transient_flow; +use serde_json::json; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + recoco::lib_context::init_lib_context(Some(recoco::settings::Settings::default())).await?; + + let mut builder = FlowBuilder::new("hello_world").await?; + + let input = builder.add_direct_input( + "text".to_string(), + schema::make_output_type(schema::BasicValueType::Str), + )?; + + let output = builder.transform( + "SplitBySeparators".to_string(), + json!({ "separators_regex": [" "] }).as_object().unwrap().clone(), + vec![(input, Some("text".to_string()))], + None, + "splitter".to_string(), + ).await?; + + builder.set_direct_output(output)?; + + let flow = builder.build_transient_flow().await?; + let result = evaluate_transient_flow( + &flow.0, + &vec![value::Value::Basic("Hello Recoco".into())] + ).await?; + + println!("Result: {:?}", result); + Ok(()) +} +``` + +For step-by-step guidance, custom operations, file processing, and more, visit the **[Getting Started guide](https://docs.knitli.com/recoco/guides/getting-started/)** and **[Examples](https://docs.knitli.com/recoco/examples/transient-flow/)**. + +## 🗺️ Roadmap + +- [ ] **WASM Support**: Compile core logic to WASM for edge deployment +- [ ] **More Connectors**: Add support for Redis, ClickHouse, and more +- [ ] **UI Dashboard**: Simple web UI for monitoring flows +- [ ] **Upstream Sync**: Regular merges from upstream CocoIndex + +## 🔗 Relationship to CocoIndex + +Recoco is a fork of [CocoIndex](https://github.com/cocoindex-io/cocoindex): + +| Aspect | CocoIndex (Upstream) | Recoco (Fork) | +|--------|---------------------|---------------| +| **Primary Language** | Python with Rust core | Pure Rust | +| **API Surface** | Python-only | Full Rust API | +| **Distribution** | Not on crates.io | Published to crates.io | +| **Dependencies** | All bundled together | Feature-gated and modular | +| **Target Audience** | Python developers | Rust developers | +| **License** | Apache-2.0 | Apache-2.0 | + +We aim to maintain compatibility with CocoIndex's core dataflow engine to allow porting upstream improvements, while diverging significantly in the API surface and dependency management to better serve Rust users. + +Code headers maintain dual copyright (CocoIndex upstream, Knitli Inc. for Recoco modifications) under Apache-2.0. + +## 🤝 Contributing + +Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) and the **[Contributing guide](https://docs.knitli.com/recoco/guides/contributing/)** for details. + +## 📄 License + +[Apache License 2.0](LICENSE); see [NOTICE](NOTICE) for full license text. + +This project is [REUSE 3.3 compliant](https://reuse.software/). + +## 🙏 Acknowledgments + +Recoco is built on the excellent foundation provided by [CocoIndex](https://github.com/cocoindex-io/cocoindex). We're grateful to the CocoIndex team for creating such a powerful and well-designed dataflow engine. + +--- + +
+ +**Built with 🦀 by [Knitli Inc.](https://knit.li)** + +[Docs](https://docs.knitli.com/recoco/) • [API Reference](https://docs.rs/recoco) • [Crates.io](https://crates.io/crates/recoco) • [GitHub](https://github.com/knitli/recoco) • [Issues](https://github.com/knitli/recoco/issues) + +
+ From 30ba25993b1599363559dccc5b12ede21141733f Mon Sep 17 00:00:00 2001 From: Adam Poulemanos Date: Fri, 13 Mar 2026 16:08:45 -0400 Subject: [PATCH 23/38] fix(docs): missing slash redirect failures --- site/astro.config.mjs | 1 + site/package.json | 2 +- site/public/_redirects | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 site/public/_redirects diff --git a/site/astro.config.mjs b/site/astro.config.mjs index 7feb5c03..df8d1643 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -54,6 +54,7 @@ export default defineConfig({ markdown: { shikiConfig: { theme: "github-dark" }, }, + trailingSlash: 'always', // Vite configuration for better bundling vite: { server: { diff --git a/site/package.json b/site/package.json index b7e2c196..3c99f296 100644 --- a/site/package.json +++ b/site/package.json @@ -27,7 +27,7 @@ "name": "site", "scripts": { "astro": "bunx astro", - "build": "bunx astro build && cp -f src/assets/{_headers,.assetsignore} dist", + "build": "bunx astro build && cp -f src/assets/{_headers,.assetsignore} dist && cp -f src/public/_redirects dist", "dev": "bunx astro dev", "preview": "bunx astro preview", "start": "bunx astro dev", diff --git a/site/public/_redirects b/site/public/_redirects new file mode 100644 index 00000000..b84fc0b8 --- /dev/null +++ b/site/public/_redirects @@ -0,0 +1 @@ +/*/ /:splat/ 301 From 97119eb8451600b89e4dc94dacf11c9806ff133f Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:03:55 -0400 Subject: [PATCH 24/38] [upstream-sync] Move pattern-matcher module from core to splitters (#96) * refactor: move PatternMatcher from recoco-core to recoco-splitters Mirrors upstream PR cocoindex-io/cocoindex#1655 which moved PatternMatcher from the per-source shared/ module into the dedicated text-utilities crate. Changes: - Add pattern_matcher module to recoco-splitters with feature gating - Add pattern-matching feature with anyhow and globset dependencies - Update all 4 source features (local-file, s3, azure, gdrive) to use recoco-splitters/pattern-matching instead of direct globset dependency - Remove globset from recoco-core dependencies - Update imports in source files to use recoco_splitters::pattern_matcher - Remove old sources/shared/ directory This is a pure refactor with zero logic changes. All source features build successfully. Fixes #54 Co-authored-by: Adam Poulemanos * chore: remove old sources/shared directory after PatternMatcher migration Part of the refactor to move PatternMatcher to recoco-splitters. These files are no longer needed as PatternMatcher now lives in recoco-splitters. Related to #54 Co-authored-by: Adam Poulemanos * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Adam Poulemanos Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- crates/recoco-core/Cargo.toml | 13 ++++++++----- crates/recoco-core/src/ops/sources/amazon_s3.rs | 2 +- crates/recoco-core/src/ops/sources/azure_blob.rs | 2 +- crates/recoco-core/src/ops/sources/google_drive.rs | 2 +- crates/recoco-core/src/ops/sources/local_file.rs | 2 +- crates/recoco-core/src/ops/sources/mod.rs | 7 ------- crates/recoco-core/src/ops/sources/shared/mod.rs | 13 ------------- crates/recoco-splitters/Cargo.toml | 6 +++++- crates/recoco-splitters/src/lib.rs | 3 +++ .../src}/pattern_matcher.rs | 2 +- 10 files changed, 21 insertions(+), 31 deletions(-) delete mode 100644 crates/recoco-core/src/ops/sources/shared/mod.rs rename crates/{recoco-core/src/ops/sources/shared => recoco-splitters/src}/pattern_matcher.rs (99%) diff --git a/crates/recoco-core/Cargo.toml b/crates/recoco-core/Cargo.toml index d9ce4c06..eef3312c 100644 --- a/crates/recoco-core/Cargo.toml +++ b/crates/recoco-core/Cargo.toml @@ -43,7 +43,6 @@ config = { workspace = true, optional = true } const_format = { workspace = true } # compile time derive-where = { workspace = true } # compile time futures = { workspace = true } -globset = { workspace = true, optional = true } google-cloud-aiplatform-v1 = { workspace = true, optional = true } google-cloud-gax = { workspace = true, optional = true } google-drive3 = { workspace = true, optional = true } @@ -226,19 +225,21 @@ source-azure = [ "dep:azure_identity", "dep:azure_storage", "dep:azure_storage_blobs", - "dep:globset", + "dep:recoco-splitters", + "recoco-splitters/pattern-matching", "recoco-utils/azure", "recoco-utils/bytes_decode" ] source-gdrive = [ "batching", - "dep:globset", "dep:google-drive3", "dep:http-body-util", "dep:hyper-rustls", "dep:hyper-util", + "dep:recoco-splitters", "dep:rustls", "dep:yup-oauth2", + "recoco-splitters/pattern-matching", "recoco-utils/bytes_decode", "recoco-utils/google-drive" ] @@ -246,7 +247,8 @@ source-gdrive = [ source-local-file = [ "batching", "dep:async-stream", - "dep:globset", + "dep:recoco-splitters", + "recoco-splitters/pattern-matching", "recoco-utils/bytes_decode", "recoco-utils/local-file" ] @@ -257,10 +259,11 @@ source-s3 = [ "dep:aws-config", "dep:aws-sdk-s3", "dep:aws-sdk-sqs", - "dep:globset", + "dep:recoco-splitters", "dep:redis", "dep:rustls", "dep:urlencoding", + "recoco-splitters/pattern-matching", "recoco-utils/bytes_decode", "recoco-utils/redis", "recoco-utils/s3" diff --git a/crates/recoco-core/src/ops/sources/amazon_s3.rs b/crates/recoco-core/src/ops/sources/amazon_s3.rs index 867393e3..55af6462 100644 --- a/crates/recoco-core/src/ops/sources/amazon_s3.rs +++ b/crates/recoco-core/src/ops/sources/amazon_s3.rs @@ -19,7 +19,7 @@ use redis::Client as RedisClient; use std::sync::Arc; use urlencoding; -use super::shared::pattern_matcher::PatternMatcher; +use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::ops::sdk::*; diff --git a/crates/recoco-core/src/ops/sources/azure_blob.rs b/crates/recoco-core/src/ops/sources/azure_blob.rs index a1f782d4..5689857e 100644 --- a/crates/recoco-core/src/ops/sources/azure_blob.rs +++ b/crates/recoco-core/src/ops/sources/azure_blob.rs @@ -18,7 +18,7 @@ use azure_storage_blobs::prelude::*; use futures::StreamExt; use std::sync::Arc; -use super::shared::pattern_matcher::PatternMatcher; +use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::ops::sdk::*; use crate::prelude::*; diff --git a/crates/recoco-core/src/ops/sources/google_drive.rs b/crates/recoco-core/src/ops/sources/google_drive.rs index 42046a19..987cd0c4 100644 --- a/crates/recoco-core/src/ops/sources/google_drive.rs +++ b/crates/recoco-core/src/ops/sources/google_drive.rs @@ -10,7 +10,7 @@ // Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. // SPDX-License-Identifier: Apache-2.0 -use super::shared::pattern_matcher::PatternMatcher; +use recoco_splitters::pattern_matcher::PatternMatcher; use chrono::Duration; use google_drive3::{ DriveHub, diff --git a/crates/recoco-core/src/ops/sources/local_file.rs b/crates/recoco-core/src/ops/sources/local_file.rs index 92e9450e..f72dd2b3 100644 --- a/crates/recoco-core/src/ops/sources/local_file.rs +++ b/crates/recoco-core/src/ops/sources/local_file.rs @@ -17,7 +17,7 @@ use std::path::Path; use std::{path::PathBuf, sync::Arc}; use tracing::warn; -use super::shared::pattern_matcher::PatternMatcher; +use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::{fields_value, ops::sdk::*}; diff --git a/crates/recoco-core/src/ops/sources/mod.rs b/crates/recoco-core/src/ops/sources/mod.rs index 2a8e9cc7..2736a286 100644 --- a/crates/recoco-core/src/ops/sources/mod.rs +++ b/crates/recoco-core/src/ops/sources/mod.rs @@ -9,13 +9,6 @@ // // Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. // SPDX-License-Identifier: Apache-2.0 -#[cfg(any( - feature = "source-s3", - feature = "source-azure", - feature = "source-gdrive", - feature = "source-local-file" -))] -pub mod shared; #[cfg(feature = "source-s3")] pub mod amazon_s3; diff --git a/crates/recoco-core/src/ops/sources/shared/mod.rs b/crates/recoco-core/src/ops/sources/shared/mod.rs deleted file mode 100644 index 6998527e..00000000 --- a/crates/recoco-core/src/ops/sources/shared/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Recoco is a Rust-only fork of CocoIndex, by [CocoIndex](https://CocoIndex) -// Original code from CocoIndex is copyrighted by CocoIndex -// SPDX-FileCopyrightText: 2025-2026 CocoIndex (upstream) -// SPDX-FileContributor: CocoIndex Contributors -// -// All modifications from the upstream for Recoco are copyrighted by Knitli Inc. -// SPDX-FileCopyrightText: 2026 Knitli Inc. (Recoco) -// SPDX-FileContributor: Adam Poulemanos -// -// Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. -// SPDX-License-Identifier: Apache-2.0 - -pub mod pattern_matcher; diff --git a/crates/recoco-splitters/Cargo.toml b/crates/recoco-splitters/Cargo.toml index 8bebcee4..34397dc7 100644 --- a/crates/recoco-splitters/Cargo.toml +++ b/crates/recoco-splitters/Cargo.toml @@ -18,7 +18,9 @@ license = { workspace = true } categories = ["parser-implementations", "parsing", "text-processing"] [dependencies] +anyhow = { workspace = true, optional = true } cfg-if = { workspace = true } # compile time +globset = { workspace = true, optional = true } regex = { workspace = true } tree-sitter = "0.25.10" # Per language tree-sitter parsers @@ -82,8 +84,10 @@ all = [ "toml", "typescript", "xml", - "yaml" + "yaml", ] +full = ["all", "pattern-matching"] +pattern-matching = ["dep:anyhow", "dep:globset"] c = ["dep:tree-sitter-c"] c-sharp = ["dep:tree-sitter-c-sharp"] cpp = ["dep:tree-sitter-cpp"] diff --git a/crates/recoco-splitters/src/lib.rs b/crates/recoco-splitters/src/lib.rs index 5d4866ef..4a8f739a 100644 --- a/crates/recoco-splitters/src/lib.rs +++ b/crates/recoco-splitters/src/lib.rs @@ -16,6 +16,9 @@ //! - Programming language detection and tree-sitter support //! - Text splitting by separators //! - Recursive text chunking with syntax awareness +//! - Pattern matching for file filtering +#[cfg(feature = "pattern-matching")] +pub mod pattern_matcher; pub mod prog_langs; pub mod split; diff --git a/crates/recoco-core/src/ops/sources/shared/pattern_matcher.rs b/crates/recoco-splitters/src/pattern_matcher.rs similarity index 99% rename from crates/recoco-core/src/ops/sources/shared/pattern_matcher.rs rename to crates/recoco-splitters/src/pattern_matcher.rs index a4997222..bf00bd21 100644 --- a/crates/recoco-core/src/ops/sources/shared/pattern_matcher.rs +++ b/crates/recoco-splitters/src/pattern_matcher.rs @@ -10,7 +10,7 @@ // Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. // SPDX-License-Identifier: Apache-2.0 -use crate::ops::sdk::*; +use anyhow::Result; use globset::{Glob, GlobSet, GlobSetBuilder}; /// Builds a GlobSet from a vector of pattern strings From 2dd97f0a28c2519cdea8f548dd4be62ec7cd1bcf Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:07:02 -0400 Subject: [PATCH 25/38] fix: ensure execution plan initialized after target setup (#49) (#92) Adopt upstream bug fix from cocoindex-io/cocoindex#1715 (commit ba2fc4a). The bug allowed the execution plan to be initialized before target setup was complete in certain cases. This race could cause the planner to use outdated or incomplete state, leading to subtle bugs when resources are quickly provisioned or flows reconfigured. Changes: - Add Debug and Clone derives to ExportOpExecutionContext - Refactor TrackingTableSetupChange to store lazy execution plan - Pass execution_plan and export_op_execution_contexts to diff_flow_setup_states - Move tracking table setup to occur AFTER all target setup completes This ensures tracking table initialization only happens after all target contexts exist, preventing race conditions in flow setup. Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Adam Poulemanos --- crates/recoco-core/src/builder/exec_ctx.rs | 1 + .../src/execution/db_tracking_setup.rs | 44 ++++++++++++++++++- crates/recoco-core/src/lib_context.rs | 2 + crates/recoco-core/src/setup/driver.rs | 39 +++++++++++----- 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/crates/recoco-core/src/builder/exec_ctx.rs b/crates/recoco-core/src/builder/exec_ctx.rs index b49c4e1a..d3d16115 100644 --- a/crates/recoco-core/src/builder/exec_ctx.rs +++ b/crates/recoco-core/src/builder/exec_ctx.rs @@ -23,6 +23,7 @@ pub struct ImportOpExecutionContext { pub source_id: i32, } +#[derive(Debug, Clone)] pub struct ExportOpExecutionContext { pub target_id: i32, pub schema_version_id: usize, diff --git a/crates/recoco-core/src/execution/db_tracking_setup.rs b/crates/recoco-core/src/execution/db_tracking_setup.rs index 92f81a61..a2d571e9 100644 --- a/crates/recoco-core/src/execution/db_tracking_setup.rs +++ b/crates/recoco-core/src/execution/db_tracking_setup.rs @@ -10,9 +10,11 @@ // Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. // SPDX-License-Identifier: Apache-2.0 +use crate::builder::exec_ctx::ExportOpExecutionContext; use crate::prelude::*; use crate::setup::{CombinedState, ResourceSetupChange, ResourceSetupInfo, SetupChangeType}; +use recoco_utils::error::SharedError; use serde::{Deserialize, Serialize}; use sqlx::PgPool; @@ -105,7 +107,6 @@ pub struct TrackingTableSetupState { pub has_fast_fingerprint_column: bool, } -#[derive(Debug)] pub struct TrackingTableSetupChange { pub desired_state: Option, @@ -117,14 +118,53 @@ pub struct TrackingTableSetupChange { pub source_names_need_state_cleanup: BTreeMap>, + /// Lazily resolved execution plan (awaited only when cleanup needs export contexts) + pub execution_plan: + Shared, SharedError>>>, + pub export_op_execution_contexts: Vec, + has_state_change: bool, } +impl std::fmt::Debug for TrackingTableSetupChange { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TrackingTableSetupChange") + .field("desired_state", &self.desired_state) + .field("min_existing_version_id", &self.min_existing_version_id) + .field( + "legacy_tracking_table_names", + &self.legacy_tracking_table_names, + ) + .field( + "source_state_table_always_exists", + &self.source_state_table_always_exists, + ) + .field( + "legacy_source_state_table_names", + &self.legacy_source_state_table_names, + ) + .field( + "source_names_need_state_cleanup", + &self.source_names_need_state_cleanup, + ) + .field( + "export_op_execution_contexts", + &self.export_op_execution_contexts, + ) + .field("has_state_change", &self.has_state_change) + .finish_non_exhaustive() + } +} + impl TrackingTableSetupChange { pub fn new( desired: Option<&TrackingTableSetupState>, existing: &CombinedState, source_names_need_state_cleanup: BTreeMap>, + execution_plan: Shared< + BoxFuture<'static, std::result::Result, SharedError>>, + >, + export_op_execution_contexts: Vec, ) -> Option { let legacy_tracking_table_names = existing .legacy_values(desired, |v| &v.table_name) @@ -151,6 +191,8 @@ impl TrackingTableSetupChange { legacy_source_state_table_names, min_existing_version_id, source_names_need_state_cleanup, + execution_plan, + export_op_execution_contexts, has_state_change: existing.has_state_diff(desired, |v| v), }) } else { diff --git a/crates/recoco-core/src/lib_context.rs b/crates/recoco-core/src/lib_context.rs index 0c6591b1..b9a1db4f 100644 --- a/crates/recoco-core/src/lib_context.rs +++ b/crates/recoco-core/src/lib_context.rs @@ -60,6 +60,8 @@ async fn build_setup_context( Some(&setup_execution_context.setup_state), existing_flow_ss, &analyzed_flow.flow_instance_ctx, + analyzed_flow.execution_plan.clone(), + setup_execution_context.export_ops.clone(), ) .await?; diff --git a/crates/recoco-core/src/setup/driver.rs b/crates/recoco-core/src/setup/driver.rs index e8c11747..0c5f9554 100644 --- a/crates/recoco-core/src/setup/driver.rs +++ b/crates/recoco-core/src/setup/driver.rs @@ -353,6 +353,13 @@ pub async fn diff_flow_setup_states( desired_state: Option<&FlowSetupState>, existing_state: Option<&FlowSetupState>, flow_instance_ctx: &Arc, + execution_plan: Shared< + BoxFuture< + 'static, + std::result::Result, recoco_utils::error::SharedError>, + >, + >, + export_op_execution_contexts: Vec, ) -> Result { let metadata_change = diff_state( existing_state.map(|e| &e.metadata), @@ -415,6 +422,8 @@ pub async fn diff_flow_setup_states( .map(|e| Cow::Borrowed(&e.tracking_table)) .unwrap_or_default(), source_names_needs_states_cleanup, + execution_plan, + export_op_execution_contexts, ); let mut target_resources = Vec::new(); @@ -635,16 +644,6 @@ async fn apply_changes_for_flow( ) .await?; - if let Some(tracking_table) = &flow_setup_change.tracking_table { - maybe_update_resource_setup( - "tracking table", - write, - std::iter::once(tracking_table), - |setup_change| setup_change[0].setup_change.apply_change(), - ) - .await?; - } - let mut setup_change_by_target_kind = IndexMap::<&str, Vec<_>>::new(); for target_resource in &flow_setup_change.target_resources { setup_change_by_target_kind @@ -711,6 +710,16 @@ async fn apply_changes_for_flow( ) .await?; } + // Apply tracking table change after target changes, since it may need to clean up tracking states based on the target info. + if let Some(tracking_table) = &flow_setup_change.tracking_table { + maybe_update_resource_setup( + "tracking table", + write, + std::iter::once(tracking_table), + |setup_change| setup_change[0].setup_change.apply_change(), + ) + .await?; + } let is_deletion = status == ObjectStatus::Deleted; db_metadata::commit_changes_for_flow( @@ -910,8 +919,14 @@ async fn get_flow_setup_change<'a>( FlowSetupChangeAction::Drop => { let existing_state = setup_ctx.all_setup_states.flows.get(flow_ctx.flow_name()); buffer.insert( - diff_flow_setup_states(None, existing_state, &flow_ctx.flow.flow_instance_ctx) - .await?, + diff_flow_setup_states( + None, + existing_state, + &flow_ctx.flow.flow_instance_ctx, + flow_ctx.flow.execution_plan.clone(), + vec![], + ) + .await?, ) } }; From 61702db31e5c09c4e726f87c46318dfcca9d4031 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 13 Mar 2026 17:32:25 -0400 Subject: [PATCH 26/38] fix: tracking table setup must occur after all target setups (#93) * Initial plan * fix: ensure tracking table setup occurs after all target setups (upstream bug fix) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- crates/recoco-core/src/setup/driver.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/recoco-core/src/setup/driver.rs b/crates/recoco-core/src/setup/driver.rs index 0c5f9554..c714f69e 100644 --- a/crates/recoco-core/src/setup/driver.rs +++ b/crates/recoco-core/src/setup/driver.rs @@ -721,7 +721,16 @@ async fn apply_changes_for_flow( .await?; } - let is_deletion = status == ObjectStatus::Deleted; + if let Some(tracking_table) = &flow_setup_change.tracking_table { + maybe_update_resource_setup( + "tracking table", + write, + std::iter::once(tracking_table), + |setup_change| setup_change[0].setup_change.apply_change(), + ) + .await?; + } + db_metadata::commit_changes_for_flow( flow_ctx.flow_name(), new_version_id, From 08d87a68a08ba84e5491d3abbe2aecc0304d6f56 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Sat, 14 Mar 2026 00:56:56 -0400 Subject: [PATCH 27/38] Specify CLA_ACCESS_TOKEN in secrets for CLA check Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --- .github/workflows/cla.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 14380597..84f2b873 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -23,4 +23,5 @@ jobs: with: repo_name: codeweaver cla_document_url: https://github.com/knitli/codeweaver/blob/main/CONTRIBUTORS_LICENSE_AGREEMENT.md - secrets: inherit + secrets: + CLA_ACCESS_TOKEN: ${{ secrets.CLA_ACCESS_TOKEN }} From 202e070efe089fdaf05ab7a32c8dfbb2a32e3c26 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos Date: Sat, 14 Mar 2026 01:26:47 -0400 Subject: [PATCH 28/38] Remove obsolete files and update configurations - Deleted the license files for knitli-logo.svg, robots.txt, and .assetsignore. - Removed the robots.txt file from the public and assets directories. - Updated the sitemap URL in the remaining robots.txt file. - Deleted various image files and their corresponding license files. - Adjusted the path for the recoco-v2-xl image in the documentation index. - Updated worker configuration types to include new properties and methods. - Modified wrangler.jsonc to include account ID and asset handling options. --- site/.gitignore | 5 + site/astro.config.mjs | 35 +- site/bun.lock | 391 +- site/package-lock.json | 8914 ----------------- site/package-lock.json.license | 3 - site/package.json | 41 +- site/public/.assetsignore | 8 - site/public/ReCoco/favicon.ico | 0 site/public/ReCoco/favicon.svg | 86 - site/public/ReCoco/favicon.svg.license | 3 - site/public/_redirects | 1 - site/public/recoco/.assetsignore | 3 + .../public/{ => recoco}/.assetsignore.license | 0 site/public/{ => recoco}/_headers | 0 site/public/{ => recoco}/_headers.license | 0 site/public/recoco/favicon.svg | 1 - site/public/recoco/favicon.svg.license | 3 - site/public/recoco/knitli-logo.svg | 25 - site/public/recoco/knitli-logo.svg.license | 3 - site/public/recoco/robots.txt | 2 +- site/public/robots.txt | 31 - site/public/robots.txt.license | 3 - site/src/assets/.assetsignore | 1 - site/src/assets/.assetsignore.license | 3 - site/src/assets/_headers | 10 - site/src/assets/_headers.license | 3 - site/src/assets/headline_logo.webp | 1 - site/src/assets/headline_logo_dark.webp | 1 - site/src/assets/houston.webp | Bin 98506 -> 0 bytes site/src/assets/houston.webp.license | 3 - site/src/assets/recoco-med.webp | 1 - site/src/assets/recoco-sm.webp | 1 - site/src/assets/recoco-xl.webp | 1 - site/src/assets/recoco.webp | Bin 176906 -> 0 bytes site/src/assets/robots.txt | 31 - site/src/assets/robots.txt.license | 3 - site/src/content/docs/index.mdx | 2 +- site/worker-configuration.d.ts | 495 +- site/wrangler.jsonc | 6 +- 39 files changed, 651 insertions(+), 9469 deletions(-) delete mode 100644 site/package-lock.json delete mode 100644 site/package-lock.json.license delete mode 100644 site/public/.assetsignore delete mode 100644 site/public/ReCoco/favicon.ico delete mode 100644 site/public/ReCoco/favicon.svg delete mode 100644 site/public/ReCoco/favicon.svg.license delete mode 100644 site/public/_redirects create mode 100644 site/public/recoco/.assetsignore rename site/public/{ => recoco}/.assetsignore.license (100%) rename site/public/{ => recoco}/_headers (100%) rename site/public/{ => recoco}/_headers.license (100%) delete mode 100644 site/public/recoco/favicon.svg delete mode 100644 site/public/recoco/favicon.svg.license delete mode 100644 site/public/recoco/knitli-logo.svg delete mode 100644 site/public/recoco/knitli-logo.svg.license delete mode 100644 site/public/robots.txt delete mode 100644 site/public/robots.txt.license delete mode 100644 site/src/assets/.assetsignore delete mode 100644 site/src/assets/.assetsignore.license delete mode 100644 site/src/assets/_headers delete mode 100644 site/src/assets/_headers.license delete mode 120000 site/src/assets/headline_logo.webp delete mode 120000 site/src/assets/headline_logo_dark.webp delete mode 100644 site/src/assets/houston.webp delete mode 100644 site/src/assets/houston.webp.license delete mode 120000 site/src/assets/recoco-med.webp delete mode 120000 site/src/assets/recoco-sm.webp delete mode 120000 site/src/assets/recoco-xl.webp delete mode 100755 site/src/assets/recoco.webp delete mode 100644 site/src/assets/robots.txt delete mode 100644 site/src/assets/robots.txt.license diff --git a/site/.gitignore b/site/.gitignore index c22b7d22..566afbdf 100644 --- a/site/.gitignore +++ b/site/.gitignore @@ -23,3 +23,8 @@ pnpm-debug.log* # macOS-specific files .DS_Store + +# only bun.lock allowed, ignore other lock files +package-lock.json +yarn.lock +pnpm-lock.yaml diff --git a/site/astro.config.mjs b/site/astro.config.mjs index df8d1643..06ccd669 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -24,8 +24,11 @@ export default defineConfig({ site: "https://docs.knitli.com", base: "/recoco", adapter: cloudflare({ + experimental: { + headersAndRedirectsDevModeSupport: true, + }, + configPath: "./wrangler.jsonc", imageService: "compile", - environment: process.env.NODE_ENV === "development" ? "local" : undefined, }), favicon: faviconIco, // Image optimization @@ -45,25 +48,31 @@ export default defineConfig({ "recoco.knitli.com", ], }, - + headingIdCompat: true, + preserveScriptOrder: true, // Build optimizations build: { inlineStylesheets: "auto", assets: "_astro", }, markdown: { - shikiConfig: { theme: "github-dark" }, + shikiConfig: { + themes: { + light: "github-light", + dark: "github-dark", + } + }, }, trailingSlash: 'always', // Vite configuration for better bundling vite: { - server: { - fs: { - allow: [ - searchForWorkspaceRoot(process.cwd()) - ], + server: { + fs: { + allow: [ + searchForWorkspaceRoot(process.cwd()) + ], + }, }, - }, assetsInclude: [ "src/*.webp", "src/*.png", @@ -75,7 +84,6 @@ export default defineConfig({ build: { cssCodeSplit: true, cssMinify: "lightningcss", - rolldownOptions: { output: { experimental: { @@ -112,8 +120,7 @@ export default defineConfig({ }, ], }, - headingIdCompat: true, - preserveScriptOrder: true, + rustCompiler: true, }, // Static site generation for Cloudflare output: "static", @@ -127,10 +134,10 @@ export default defineConfig({ }, plugins: [starlightHeadingBadges(), starlightContextualMenu({ actions: ["copy", "view", "claude", "chatgpt"] - }), + }), // We need to configure starlight-tags with a tags.yml. //starlightTags(), - starlightLlmsText({ + starlightLlmsText({ projectName: "Recoco", description: `Recoco is a pure-Rust fork of the popular data processing and ETL framework, [CocoIndex](https://cocoindex.io). Recoco features a highly modular architecture, with all sources, targets, and functions (i.e. transforms) implemented as feature-gated plugins. This allows users to easily customize and extend the framework to fit their specific data processing needs, while keeping the core lightweight and efficient. Like CocoIndex, Recoco is fast, efficient, and works on data incrementally. Both libraries are built using a *dataflow architecture*, allowing you to easily define complex data processing pipelines with multiple sources, targets, and transforms in only a few lines of code. CocoIndex is built in Rust, but its entire API is only in Python, and does not allow for choosing integrations. Recoco exposes a robust Rust API that allows you to choose exactly which sources, targets, and transforms you want to use. diff --git a/site/bun.lock b/site/bun.lock index ae3895e0..42db9a95 100644 --- a/site/bun.lock +++ b/site/bun.lock @@ -5,15 +5,16 @@ "": { "name": "site", "dependencies": { - "@astrojs/starlight": "^0.37.6", + "@astrojs/starlight": "0.38.1", "@knitli/docs-components": "^1.1.10", - "astro": "^5.17.3", + "astro": "6.0.4", }, "devDependencies": { - "@astrojs/check": "^0.9.6", - "@astrojs/cloudflare": "^12.6.12", - "@astrojs/mdx": "^4.3.13", - "@astrojs/sitemap": "^3.7.0", + "@astrojs/check": "0.9.7", + "@astrojs/cloudflare": "13.1.1", + "@astrojs/compiler-rs": "^0.1.4", + "@astrojs/mdx": "5.0.0", + "@astrojs/sitemap": "3.7.1", "@biomejs/biome": "^2.4.3", "astro-favicons": "^3.1.5", "bun": "^1.3.9", @@ -24,37 +25,59 @@ "starlight-llms-txt": ">=0.7.0", "starlight-scroll-to-top": ">=0.4.0", "starlight-tags": ">=0.4.0", - "svgo": "^4.0.0", + "svgo": "^4.0.1", "typescript": "^5.9.3", "vitest": "^4.0.18", - "wrangler": "^4.67.0", + "wrangler": "^4.73.0", }, }, }, "packages": { - "@astrojs/check": ["@astrojs/check@0.9.6", "", { "dependencies": { "@astrojs/language-server": "^2.16.1", "chokidar": "^4.0.1", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "bin/astro-check.js" } }, "sha512-jlaEu5SxvSgmfGIFfNgcn5/f+29H61NJzEMfAZ82Xopr4XBchXB1GVlcJsE+elUlsYSbXlptZLX+JMG3b/wZEA=="], + "@astrojs/check": ["@astrojs/check@0.9.7", "", { "dependencies": { "@astrojs/language-server": "^2.16.1", "chokidar": "^4.0.3", "kleur": "^4.1.5", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "astro-check": "bin/astro-check.js" } }, "sha512-dA7U5/OFg8/xaMUb2vUOOJuuJXnMpHy6F0BM8ZhL7WT5OkTBwJ0GoW38n4fC4CXt+lT9mLWL0y8Pa74tFByBpQ=="], - "@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.12", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20251121.0", "tinyglobby": "^0.2.15", "vite": "^6.4.1", "wrangler": "4.50.0" }, "peerDependencies": { "astro": "^5.7.0" } }, "sha512-f6iXreyJc02EhokqsoPf7D/s3tebyZ8dBNVOyY2JDY87ujft4RokVS1f+zNwNFyu0wkehC4ALUboU5z590DE4w=="], + "@astrojs/cloudflare": ["@astrojs/cloudflare@13.1.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.8.0", "@astrojs/underscore-redirects": "1.0.1", "@cloudflare/vite-plugin": "^1.25.6", "piccolore": "^0.1.3", "tinyglobby": "^0.2.15", "vite": "^7.3.1" }, "peerDependencies": { "astro": "^6.0.0-alpha.0", "wrangler": "^4.61.1" } }, "sha512-Bx2Sr/cLi9VUA0iArMYc/O6wsKZdC2W6prE8dzMGbJqaF5oEBVBG6UclKe1T95SISrDIysuLlFNvVWL6htqnuA=="], - "@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + "@astrojs/compiler": ["@astrojs/compiler@3.0.0", "", {}, "sha512-MwAbDE5mawZ1SS+D8qWiHdprdME5Tlj2e0YjxnEICvcOpbSukNS7Sa7hA5PK+6RrmUr/t6Gi5YgrdZKjbO/WPQ=="], - "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.5", "", {}, "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA=="], + "@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.1.4", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.1.4", "@astrojs/compiler-binding-darwin-x64": "0.1.4", "@astrojs/compiler-binding-linux-arm64-gnu": "0.1.4", "@astrojs/compiler-binding-linux-arm64-musl": "0.1.4", "@astrojs/compiler-binding-linux-x64-gnu": "0.1.4", "@astrojs/compiler-binding-linux-x64-musl": "0.1.4", "@astrojs/compiler-binding-wasm32-wasi": "0.1.4", "@astrojs/compiler-binding-win32-arm64-msvc": "0.1.4", "@astrojs/compiler-binding-win32-x64-msvc": "0.1.4" } }, "sha512-XRmgr5zHxlFxQhy03FKxuzmqxrBjodsxOb9MC+an+5sD9SRafmi4osIa/Wc7Eb7BvoVDYpXmH4I5dhSCUxQsrA=="], + + "@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-z//cPXHsE49yfJMUwmrtB/bMnAI7Fvehe+7JSYxhOpyIhf82cwJn6ZuElhvTfsuuKYk5QE0ONIrSP6LXw20MaQ=="], + + "@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-rC8EyDoknijyqU2XgQYSes2qErmNNQ7Lwk0CFiDbqd2EzXacoZSwVNd1xbFM6O4Dq4KGiilshCC/bnhNu86OMA=="], + + "@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-t3N2PgE+l7MZkIEm7p1SJ8HWpWfaDrlU9hZ/64Z7ySqdZUXYjSZORrJRNifPisIfdR5NdcVHvxTRia0e++olLg=="], + + "@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-MtEkmrfTakCZkN5IrjYtJDOcPaHtrYCISdRXFh0UB7ugIrscBeCdfsZhfFRPUpk5R8zHTztVTTcHwn5Tz/u3jg=="], + + "@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-YD0f4oyU3w8uJ+8/ljBb5Q5dQz4cYOEpgeDUWMEf2XRDV+JQoOUBmCaBPY4ALCdv/WW0PsEdoxvB/CBfbE8w9g=="], + + "@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+c9+Z+55JkS+u4I90Eep4bteE+2RpNggq4PxKFBCEm7APiJ1iXLvUbvluUfmoAs7cPvzv+6MF342Zdax39Mz4A=="], + + "@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.1.4", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-OX4CNME5Giqm8soj5Vk1uhNHBELF6gn0k63zu1dGqwFt0AA4HzMAIuk7jb4Wl3xPwgt0iYO670uWknWvJwDd7Q=="], + + "@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.1.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-c/H9/yqMuqX5g9k3SIsNmHroMUUmIoniv+InsjI9sbrpK43DfIsdj+3JggV3GAqIF9ilYC6NBOiKZ+ZX/xYMug=="], + + "@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-P7mEP3S5/4a5+hxU7+LbJQmc9XAYb1F4EzqivVHH4Scf7mdyxjpP10PZp814HXbe5/RGfGWdf0gGdOUKo+nHvQ=="], + + "@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.1.4", "", { "dependencies": { "@astrojs/compiler-binding": "0.1.4" } }, "sha512-D7cjtFhwxvYI0PnDP7EfVXn+/NCV8toq/LG+WHPl/OXq/SfcbXYNeeKDRxYAjV8lJOXwpRLFcu0vUkuFFhBNtA=="], + + "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.8.0", "", { "dependencies": { "picomatch": "^4.0.3" } }, "sha512-J56GrhEiV+4dmrGLPNOl2pZjpHXAndWVyiVDYGDuw6MWKpBSEMLdFxHzeM/6sqaknw9M+HFfHZAcvi3OfT3D/w=="], "@astrojs/language-server": ["@astrojs/language-server@2.16.3", "", { "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/yaml2ts": "^0.2.2", "@jridgewell/sourcemap-codec": "^1.5.5", "@volar/kit": "~2.4.27", "@volar/language-core": "~2.4.27", "@volar/language-server": "~2.4.27", "@volar/language-service": "~2.4.27", "muggle-string": "^0.4.1", "tinyglobby": "^0.2.15", "volar-service-css": "0.0.68", "volar-service-emmet": "0.0.68", "volar-service-html": "0.0.68", "volar-service-prettier": "0.0.68", "volar-service-typescript": "0.0.68", "volar-service-typescript-twoslash-queries": "0.0.68", "volar-service-yaml": "0.0.68", "vscode-html-languageservice": "^5.6.1", "vscode-uri": "^3.1.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "bin/nodeServer.js" } }, "sha512-yO5K7RYCMXUfeDlnU6UnmtnoXzpuQc0yhlaCNZ67k1C/MiwwwvMZz+LGa+H35c49w5QBfvtr4w4Zcf5PcH8uYA=="], - "@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.10", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.19.0", "smol-toml": "^1.5.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A=="], + "@astrojs/markdown-remark": ["@astrojs/markdown-remark@7.0.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.8.0", "@astrojs/prism": "4.0.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^4.0.0", "smol-toml": "^1.6.0", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.1.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-jTAXHPy45L7o1ljH4jYV+ShtOHtyQUa1mGp3a5fJp1soX8lInuTJQ6ihmldHzVM4Q7QptU4SzIDIcKbBJO7sXQ=="], - "@astrojs/mdx": ["@astrojs/mdx@4.3.13", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.10", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q=="], + "@astrojs/mdx": ["@astrojs/mdx@5.0.0", "", { "dependencies": { "@astrojs/markdown-remark": "7.0.0", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.16.0", "es-module-lexer": "^2.0.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^6.0.0-alpha.0" } }, "sha512-J4rW6eT+qgVw7+RXdBYO4vYyWGeXXQp8wop9dXsOlLzIsVSxyttMCgkGCWvIR2ogBqKqeYgI6YDW93PaDHkCaA=="], - "@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], + "@astrojs/prism": ["@astrojs/prism@4.0.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-NndtNPpxaGinRpRytljGBvYHpTOwHycSZ/c+lQi5cHvkqqrHKWdkPEhImlODBNmbuB+vyQUNUDXyjzt66CihJg=="], - "@astrojs/sitemap": ["@astrojs/sitemap@3.7.0", "", { "dependencies": { "sitemap": "^8.0.2", "stream-replace-string": "^2.0.0", "zod": "^3.25.76" } }, "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA=="], + "@astrojs/sitemap": ["@astrojs/sitemap@3.7.1", "", { "dependencies": { "sitemap": "^9.0.0", "stream-replace-string": "^2.0.0", "zod": "^4.3.6" } }, "sha512-IzQqdTeskaMX+QDZCzMuJIp8A8C1vgzMBp/NmHNnadepHYNHcxQdGLQZYfkbd2EbRXUfOS+UDIKx8sKg0oWVdw=="], - "@astrojs/starlight": ["@astrojs/starlight@0.37.6", "", { "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", "@astrojs/sitemap": "^3.3.0", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.1", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "magic-string": "^0.30.17", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^5.5.0" } }, "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w=="], + "@astrojs/starlight": ["@astrojs/starlight@0.38.1", "", { "dependencies": { "@astrojs/markdown-remark": "^7.0.0", "@astrojs/mdx": "^5.0.0", "@astrojs/sitemap": "^3.7.1", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.6", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "magic-string": "^0.30.17", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^6.0.0" } }, "sha512-CATPH4Dy44OYAJhoyUHh6NqpColWEVufanGVwnM0l/bcaNMo5V/rypwL0Vu0Edp+ZIXE7/1DA9CrNj5jmCVSLQ=="], "@astrojs/telemetry": ["@astrojs/telemetry@3.3.0", "", { "dependencies": { "ci-info": "^4.2.0", "debug": "^4.4.0", "dlv": "^1.1.3", "dset": "^3.1.4", "is-docker": "^3.0.0", "is-wsl": "^3.1.0", "which-pm-runs": "^1.1.0" } }, "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ=="], - "@astrojs/underscore-redirects": ["@astrojs/underscore-redirects@1.0.0", "", {}, "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ=="], + "@astrojs/underscore-redirects": ["@astrojs/underscore-redirects@1.0.1", "", {}, "sha512-iSImJzW8m7MjA+15oJZAbSqSWu6ApQ0N8A0SaWV9yLzKYjzxWm/tZKbRSLRv94OE/rXuM25ZG7R8TepkhH7ahA=="], "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.2", "", { "dependencies": { "yaml": "^2.5.0" } }, "sha512-GOfvSr5Nqy2z5XiwqTouBBpy5FyI6DEe+/g/Mk5am9SjILN1S5fOEvYK0GuWHg98yS/dobP4m8qyqw/URW35fQ=="], @@ -88,19 +111,25 @@ "@capsizecss/unpack": ["@capsizecss/unpack@4.0.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA=="], + "@clack/core": ["@clack/core@1.1.0", "", { "dependencies": { "sisteransi": "^1.0.5" } }, "sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA=="], + + "@clack/prompts": ["@clack/prompts@1.1.0", "", { "dependencies": { "@clack/core": "1.1.0", "sisteransi": "^1.0.5" } }, "sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g=="], + "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], - "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="], + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.15.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "1.20260301.1 || ~1.20260302.1 || ~1.20260303.1 || ~1.20260304.1 || >1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-EGYmJaGZKWl+X8tXxcnx4v2bOZSjQeNI5dWFeXivgX9+YCT69AkzHHwlNbVpqtEUTbew8eQurpyOpeN8fg00nw=="], + + "@cloudflare/vite-plugin": ["@cloudflare/vite-plugin@1.28.0", "", { "dependencies": { "@cloudflare/unenv-preset": "2.15.0", "miniflare": "4.20260312.0", "unenv": "2.0.0-rc.24", "wrangler": "4.73.0", "ws": "8.18.0" }, "peerDependencies": { "vite": "^6.1.0 || ^7.0.0" } }, "sha512-h2idr5fZ5GojyWZOZ506NHaDAVq3zpvcKgk8ZzDLlnHHvOwXZlFDPRf9Kkffv0fe+J6GPn7gVjJxgT0YRXAbew=="], - "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260219.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-k+xM+swQBQnkrvwobjRPxyeYwjLSludJusR0PqeHe+h6X9QIRGgw3s1AO38lXQsqzMSgG5709oOXSF19NKVVaQ=="], + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260312.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-HUAtDWaqUduS6yasV6+NgsK7qBpP1qGU49ow/Wb117IHjYp+PZPUGReDYocpB4GOMRoQlvdd4L487iFxzdARpw=="], - "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260219.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EyfQdsG1KcIVAf4qndT00LZly7sLFm1VxMWHBvOFB/EVYF2sE5HZ0dPbe+yrax5p3eS0oLZthR8ynhz4UulMUQ=="], + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260312.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DOn7TPTHSxJYfi4m4NYga/j32wOTqvJf/pY4Txz5SDKWIZHSTXFyGz2K4B+thoPWLop/KZxGoyTv7db0mk/qyw=="], - "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260219.0", "", { "os": "linux", "cpu": "x64" }, "sha512-N0UHXILYYa6htFO/uC92uAqusvynbSbOcHcrVXMKqP9Jy7eqXGMovyKIrNgzYnKIszNB+0lfUYdGI3Wci07LuA=="], + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260312.1", "", { "os": "linux", "cpu": "x64" }, "sha512-TdkIh3WzPXYHuvz7phAtFEEvAxvFd30tHrm4gsgpw0R0F5b8PtoM3hfL2uY7EcBBWVYUBtkY2ahDYFfufnXw/g=="], - "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260219.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-835pjQ9uuAtwPBOAkPf+oxH3mNE5mqWuE3H7hJsul7WZsRD2FDcariyoT2AW6xyOePILrn4uMnmG1KGc9m/8Pg=="], + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260312.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-kNauZhL569Iy94t844OMwa1zP6zKFiL3xiJ4tGLS+TFTEfZ3pZsRH6lWWOtkXkjTyCmBEOog0HSEKjIV4oAffw=="], - "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260219.0", "", { "os": "win32", "cpu": "x64" }, "sha512-i7qcuOsuAxqqn1n5Ar3Rh1dHUL9vNmpF9FcdMTT84jIrdm5UNrPZz5grJthPmpB9LTcreT9iiP6qKbzGjnCwPA=="], + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260312.1", "", { "os": "win32", "cpu": "x64" }, "sha512-5dBrlSK+nMsZy5bYQpj8t9iiQNvCRlkm9GGvswJa9vVU/1BNO4BhJMlqOLWT24EmFyApZ+kaBiPJMV8847NDTg=="], "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20260219.0", "", {}, "sha512-jL2BNnDqbKXDrxhtKx+wVmQpv/P6w8J4WVFiuT9OMEPsw8V2TfTozoWTcCZ2AhE09yK406xQFE4mBq9IIgobuw=="], @@ -122,8 +151,12 @@ "@emmetio/stream-reader-utils": ["@emmetio/stream-reader-utils@0.1.0", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="], + "@emnapi/core": ["@emnapi/core@1.9.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w=="], + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], @@ -244,6 +277,8 @@ "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], + "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], "@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.3.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-df7smckMWSUfaT5mzwN9Lfpd3ZGkOqo+vmQ8VV2a32gl14v6uZ/qeeo+1RlANXn8M0uzXPWWCkrKZIWSZUR0qw=="], @@ -340,17 +375,19 @@ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.57.1", "", { "os": "win32", "cpu": "x64" }, "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA=="], - "@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], + "@shikijs/core": ["@shikijs/core@4.0.2", "", { "dependencies": { "@shikijs/primitive": "4.0.2", "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw=="], - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag=="], - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg=="], - "@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], + "@shikijs/langs": ["@shikijs/langs@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2" } }, "sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg=="], - "@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], + "@shikijs/primitive": ["@shikijs/primitive@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw=="], - "@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], + "@shikijs/themes": ["@shikijs/themes@4.0.2", "", { "dependencies": { "@shikijs/types": "4.0.2" } }, "sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA=="], + + "@shikijs/types": ["@shikijs/types@4.0.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg=="], "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], @@ -360,6 +397,8 @@ "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], + "@types/braces": ["@types/braces@3.0.5", "", {}, "sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], @@ -428,17 +467,13 @@ "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], - "acorn-walk": ["acorn-walk@8.3.2", "", {}, "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A=="], - "ajv": ["ajv@8.18.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A=="], "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], - "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], - "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], @@ -454,7 +489,7 @@ "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], - "astro": ["astro@5.17.3", "", { "dependencies": { "@astrojs/compiler": "^2.13.0", "@astrojs/internal-helpers": "0.7.5", "@astrojs/markdown-remark": "6.3.10", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "acorn": "^8.15.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.3.1", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.1.1", "cssesc": "^3.0.0", "debug": "^4.4.3", "deterministic-object-hash": "^2.0.2", "devalue": "^5.6.2", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.7.0", "esbuild": "^0.27.3", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.4.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.1", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.1", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.3", "shiki": "^3.21.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.3", "unist-util-visit": "^5.0.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^6.4.1", "vitefu": "^1.1.1", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.3", "zod": "^3.25.76", "zod-to-json-schema": "^3.25.1", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "astro.js" } }, "sha512-69dcfPe8LsHzklwj+hl+vunWUbpMB6pmg35mACjetxbJeUNNys90JaBM8ZiwsPK689SAj/4Zqb1ayaANls9/MA=="], + "astro": ["astro@6.0.4", "", { "dependencies": { "@astrojs/compiler": "^3.0.0", "@astrojs/internal-helpers": "0.8.0", "@astrojs/markdown-remark": "7.0.0", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.0.1", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^1.1.1", "devalue": "^5.6.3", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", "esbuild": "^0.27.3", "flattie": "^1.1.1", "fontace": "~0.4.1", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "rehype": "^13.0.2", "semver": "^7.7.4", "shiki": "^4.0.0", "smol-toml": "^1.6.0", "svgo": "^4.0.0", "tinyclip": "^0.1.6", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.4", "unist-util-visit": "^5.1.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^7.3.1", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.3.6" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "bin/astro.mjs" } }, "sha512-1piLJCPTL/x7AMO2cjVFSTFyRqKuC3W8sSEySCt1aJio+p/wGs5H3K+Xr/rE9ftKtknLUtjxCqCE7/0NsXfGpQ=="], "astro-expressive-code": ["astro-expressive-code@0.41.6", "", { "dependencies": { "rehype-expressive-code": "^0.41.6" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" } }, "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw=="], @@ -464,8 +499,6 @@ "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], - "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], - "bcp-47": ["bcp-47@2.1.0", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w=="], "bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="], @@ -474,20 +507,14 @@ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - "boxen": ["boxen@8.0.1", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^8.0.0", "chalk": "^5.3.0", "cli-boxes": "^3.0.0", "string-width": "^7.2.0", "type-fest": "^4.21.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0" } }, "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw=="], - "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "bun": ["bun@1.3.9", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.3.9", "@oven/bun-darwin-x64": "1.3.9", "@oven/bun-darwin-x64-baseline": "1.3.9", "@oven/bun-linux-aarch64": "1.3.9", "@oven/bun-linux-aarch64-musl": "1.3.9", "@oven/bun-linux-x64": "1.3.9", "@oven/bun-linux-x64-baseline": "1.3.9", "@oven/bun-linux-x64-musl": "1.3.9", "@oven/bun-linux-x64-musl-baseline": "1.3.9", "@oven/bun-windows-x64": "1.3.9", "@oven/bun-windows-x64-baseline": "1.3.9" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bunx.exe" } }, "sha512-v5hkh1us7sMNjfimWE70flYbD5I1/qWQaqmJ45q2qk5H/7muQVa478LSVRSFyGTBUBog2LsPQnfIRdjyWJRY+A=="], - "camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="], - "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], - "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], @@ -500,8 +527,6 @@ "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], - "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], @@ -520,7 +545,7 @@ "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], - "common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], + "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], @@ -552,8 +577,6 @@ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "deterministic-object-hash": ["deterministic-object-hash@2.0.2", "", { "dependencies": { "base-64": "^1.0.0" } }, "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ=="], - "devalue": ["devalue@5.6.3", "", {}, "sha512-nc7XjUU/2Lb+SvEFVGcWLiKkzfw8+qHI7zn8WYXKkLMgfGSHbgCEaR6bJpev8Cm6Rmrb19Gfd/tZvGqx9is3wg=="], "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], @@ -582,7 +605,7 @@ "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], - "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], @@ -612,8 +635,6 @@ "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], - "exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="], - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], "expressive-code": ["expressive-code@0.41.6", "", { "dependencies": { "@expressive-code/core": "^0.41.6", "@expressive-code/plugin-frames": "^0.41.6", "@expressive-code/plugin-shiki": "^0.41.6", "@expressive-code/plugin-text-markers": "^0.41.6" } }, "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA=="], @@ -640,12 +661,8 @@ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], - "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], - "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], - "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], - "h3": ["h3@1.15.5", "", { "dependencies": { "cookie-es": "^1.2.2", "crossws": "^0.3.5", "defu": "^6.1.4", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg=="], "hast-util-embedded": ["hast-util-embedded@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-is-element": "^3.0.0" } }, "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA=="], @@ -888,9 +905,7 @@ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - - "miniflare": ["miniflare@4.20260219.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.18.2", "workerd": "1.20260219.0", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-EIb5wXbWUnnC60XU2aiFOPNd4fgTXzECkwRSOXZ1vdcY9WZaEE9rVf+h+Apw+WkOHRkp3Dr9/ZhQ5y1R+9iZ4Q=="], + "miniflare": ["miniflare@4.20260312.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.18.2", "workerd": "1.20260312.1", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-pieP2rfXynPT6VRINYaiHe/tfMJ4c5OIhqRlIdLF6iZ9g5xgpEmvimvIgMpgAdDJuFlrLcwDUi8MfAo2R6dt/w=="], "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], @@ -922,11 +937,11 @@ "oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="], - "p-limit": ["p-limit@6.2.0", "", { "dependencies": { "yocto-queue": "^1.1.1" } }, "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA=="], + "p-limit": ["p-limit@7.3.0", "", { "dependencies": { "yocto-queue": "^1.2.1" } }, "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw=="], - "p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="], + "p-queue": ["p-queue@9.1.0", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^7.0.0" } }, "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw=="], - "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], + "p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="], "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], @@ -960,8 +975,6 @@ "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], - "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], - "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="], @@ -1030,13 +1043,13 @@ "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="], - "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], + "sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="], "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], - "shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], + "shiki": ["shiki@4.0.2", "", { "dependencies": { "@shikijs/core": "4.0.2", "@shikijs/engine-javascript": "4.0.2", "@shikijs/engine-oniguruma": "4.0.2", "@shikijs/langs": "4.0.2", "@shikijs/themes": "4.0.2", "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ=="], "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], @@ -1044,7 +1057,7 @@ "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], - "sitemap": ["sitemap@8.0.2", "", { "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/cli.js" } }, "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ=="], + "sitemap": ["sitemap@9.0.1", "", { "dependencies": { "@types/node": "^24.9.2", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { "sitemap": "dist/esm/cli.js" } }, "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ=="], "smol-toml": ["smol-toml@1.6.0", "", {}, "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw=="], @@ -1070,8 +1083,6 @@ "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], - "stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="], - "stream-replace-string": ["stream-replace-string@2.0.0", "", {}, "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w=="], "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], @@ -1086,12 +1097,14 @@ "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], - "svgo": ["svgo@4.0.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="], + "svgo": ["svgo@4.0.1", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.5.0" }, "bin": "./bin/svgo.js" }, "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w=="], "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + "tinyclip": ["tinyclip@0.1.12", "", {}, "sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA=="], + "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], @@ -1110,8 +1123,6 @@ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], @@ -1126,6 +1137,8 @@ "undici": ["undici@7.18.2", "", {}, "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw=="], + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], @@ -1164,9 +1177,9 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], + "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], - "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], + "vitefu": ["vitefu@1.1.2", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-zpKATdUbzbsycPFBN71nS2uzBUQiVnFoOrr2rvqv34S1lcAgMKKkjWleLGeiJlZ8lwCXvtWaRn7R3ZC16SYRuw=="], "vitest": ["vitest@4.0.18", "", { "dependencies": { "@vitest/expect": "4.0.18", "@vitest/mocker": "4.0.18", "@vitest/pretty-format": "4.0.18", "@vitest/runner": "4.0.18", "@vitest/snapshot": "4.0.18", "@vitest/spy": "4.0.18", "@vitest/utils": "4.0.18", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/browser-playwright": "4.0.18", "@vitest/browser-preview": "4.0.18", "@vitest/browser-webdriverio": "4.0.18", "@vitest/ui": "4.0.18", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ=="], @@ -1210,13 +1223,11 @@ "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], - "widest-line": ["widest-line@5.0.0", "", { "dependencies": { "string-width": "^7.0.0" } }, "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA=="], + "workerd": ["workerd@1.20260312.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260312.1", "@cloudflare/workerd-darwin-arm64": "1.20260312.1", "@cloudflare/workerd-linux-64": "1.20260312.1", "@cloudflare/workerd-linux-arm64": "1.20260312.1", "@cloudflare/workerd-windows-64": "1.20260312.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-nNpPkw9jaqo79B+iBCOiksx+N62xC+ETIfyzofUEdY3cSOHJg6oNnVSHm7vHevzVblfV76c8Gr0cXHEapYMBEg=="], - "workerd": ["workerd@1.20260219.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260219.0", "@cloudflare/workerd-darwin-arm64": "1.20260219.0", "@cloudflare/workerd-linux-64": "1.20260219.0", "@cloudflare/workerd-linux-arm64": "1.20260219.0", "@cloudflare/workerd-windows-64": "1.20260219.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-l4U4iT5H8jNV6+EK23ExnUV2z6JvqQtQPrT8XCm4G8RpwC9EPpYTOO9s/ImMPJKe1WSbQUQoJ4k8Nd83fz8skQ=="], + "wrangler": ["wrangler@4.73.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.15.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260312.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260312.1" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260312.1" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-VJXsqKDFCp6OtFEHXITSOR5kh95JOknwPY8m7RyQuWJQguSybJy43m4vhoCSt42prutTef7eeuw7L4V4xiynGw=="], - "wrangler": ["wrangler@4.67.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.14.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260219.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260219.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260219.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-58OoVth7bqm0nqsRgcI67gHbpp0IfR1JIBqDY0XR1FzRu9Qkjn6v2iJAdFf82QcVBFhaMBYQi88WqYGswq5wlQ=="], - - "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], @@ -1234,35 +1245,27 @@ "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], - "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], - "yocto-spinner": ["yocto-spinner@0.2.3", "", { "dependencies": { "yoctocolors": "^2.1.1" } }, "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ=="], - - "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], - "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], - "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="], - - "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], + "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@astrojs/cloudflare/wrangler": ["wrangler@4.50.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.7.11", "blake3-wasm": "2.1.5", "esbuild": "0.25.4", "miniflare": "4.20251118.1", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20251118.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20251118.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-+nuZuHZxDdKmAyXOSrHlciGshCoAPiy5dM+t6mEohWm7HpXvTHmWQGUf/na9jjWlWJHCJYOWzkA1P5HBJqrIEA=="], + "@astrojs/language-server/@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + + "@expressive-code/plugin-shiki/shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "boxen/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - - "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "astro/svgo": ["svgo@4.0.0", "", { "dependencies": { "commander": "^11.1.0", "css-select": "^5.1.0", "css-tree": "^3.0.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.1.1", "sax": "^1.4.1" }, "bin": "./bin/svgo.js" }, "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw=="], "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], @@ -1274,39 +1277,39 @@ "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], - "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + "sitemap/@types/node": ["@types/node@24.12.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ=="], - "unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + "sitemap/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], - "vite/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + "starlight-heading-badges/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.10", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.19.0", "smol-toml": "^1.5.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A=="], - "vitest/vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], + "starlight-llms-txt/@astrojs/mdx": ["@astrojs/mdx@4.3.13", "", { "dependencies": { "@astrojs/markdown-remark": "6.3.10", "@mdx-js/mdx": "^3.1.1", "acorn": "^8.15.0", "es-module-lexer": "^1.7.0", "estree-util-visit": "^2.0.0", "hast-util-to-html": "^9.0.5", "piccolore": "^0.1.3", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "remark-smartypants": "^3.0.2", "source-map": "^0.7.6", "unist-util-visit": "^5.0.0", "vfile": "^6.0.3" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q=="], - "vscode-json-languageservice/jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + "unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], - "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + "vitest/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], - "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + "vscode-json-languageservice/jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], - "wrap-ansi/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + "xml2js/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], - "@astrojs/cloudflare/wrangler/@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.0", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA=="], + "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - "@astrojs/cloudflare/wrangler/@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.7.11", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20251106.1" }, "optionalPeers": ["workerd"] }, "sha512-se23f1D4PxKrMKOq+Stz+Yn7AJ9ITHcEecXo2Yjb+UgbUDCEBch1FXQC6hx6uT5fNA3kmX3mfzeZiUmpK1W9IQ=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], - "@astrojs/cloudflare/wrangler/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], - "@astrojs/cloudflare/wrangler/miniflare": ["miniflare@4.20251118.1", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "8.14.0", "acorn-walk": "8.3.2", "exit-hook": "2.2.1", "glob-to-regexp": "0.4.1", "sharp": "^0.33.5", "stoppable": "1.1.0", "undici": "7.14.0", "workerd": "1.20251118.0", "ws": "8.18.0", "youch": "4.1.0-beta.10", "zod": "3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-uLSAE/DvOm392fiaig4LOaatxLjM7xzIniFRG5Y3yF9IduOYLLK/pkCPQNCgKQH3ou0YJRHnTN+09LPfqYNTQQ=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], - "@astrojs/cloudflare/wrangler/workerd": ["workerd@1.20251118.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20251118.0", "@cloudflare/workerd-darwin-arm64": "1.20251118.0", "@cloudflare/workerd-linux-64": "1.20251118.0", "@cloudflare/workerd-linux-arm64": "1.20251118.0", "@cloudflare/workerd-windows-64": "1.20251118.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], - "boxen/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], - "boxen/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + "@expressive-code/plugin-shiki/shiki/@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], - "cliui/wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "astro/svgo/sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], @@ -1348,174 +1351,46 @@ "favilib/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], - "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - - "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], - - "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], - - "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], - - "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], - - "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], - - "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], - - "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], - - "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], - - "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], + "starlight-heading-badges/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.5", "", {}, "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA=="], - "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], + "starlight-heading-badges/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], - "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], - "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.10", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.5", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.2.0", "js-yaml": "^4.1.1", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.19.0", "smol-toml": "^1.5.2", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.2", "vfile": "^6.0.3" } }, "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A=="], - "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], + "starlight-llms-txt/@astrojs/mdx/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], - "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], - - "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], - - "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], - - "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], - - "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], - - "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], - - "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], - - "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], - - "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], - - "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], - - "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], - - "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], - - "widest-line/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - - "widest-line/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], - - "wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - - "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.4", "", { "os": "android", "cpu": "arm" }, "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.4", "", { "os": "android", "cpu": "arm64" }, "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.4", "", { "os": "android", "cpu": "x64" }, "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.4", "", { "os": "linux", "cpu": "arm" }, "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.4", "", { "os": "linux", "cpu": "none" }, "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.4", "", { "os": "none", "cpu": "arm64" }, "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.4", "", { "os": "none", "cpu": "x64" }, "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg=="], - - "@astrojs/cloudflare/wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ=="], - - "@astrojs/cloudflare/wrangler/miniflare/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], - - "@astrojs/cloudflare/wrangler/miniflare/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], - - "@astrojs/cloudflare/wrangler/miniflare/undici": ["undici@7.14.0", "", {}, "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ=="], - - "@astrojs/cloudflare/wrangler/miniflare/zod": ["zod@3.22.3", "", {}, "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug=="], - - "@astrojs/cloudflare/wrangler/workerd/@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20251118.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-UmWmYEYS/LkK/4HFKN6xf3Hk8cw70PviR+ftr3hUvs9HYZS92IseZEp16pkL6ZBETrPRpZC7OrzoYF7ky6kHsg=="], - - "@astrojs/cloudflare/wrangler/workerd/@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20251118.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RockU7Qzf4rxNfY1lx3j4rvwutNLjTIX7rr2hogbQ4mzLo8Ea40/oZTzXVxl+on75joLBrt0YpenGW8o/r44QA=="], - - "@astrojs/cloudflare/wrangler/workerd/@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20251118.0", "", { "os": "linux", "cpu": "x64" }, "sha512-aT97GnOAbJDuuOG0zPVhgRk0xFtB1dzBMrxMZ09eubDLoU4djH4BuORaqvxNRMmHgKfa4T6drthckT0NjUvBdw=="], - - "@astrojs/cloudflare/wrangler/workerd/@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20251118.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-bXZPJcwlq00MPOXqP7DMWjr+goYj0+Fqyw6zgEC2M3FR1+SWla4yjghnZ4IdpN+H1t7VbUrsi5np2LzMUFs0NA=="], - - "@astrojs/cloudflare/wrangler/workerd/@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20251118.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2LV99AHSlpr8WcCb/BYbU2QsYkXLUL1izN6YKWkN9Eibv80JKX0RtgmD3dfmajE5sNvClavxZejgzVvHD9N9Ag=="], - - "boxen/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "widest-line/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], - - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], - - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg=="], - - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ=="], + "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.0.5", "", { "os": "linux", "cpu": "arm" }, "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.0.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw=="], + "starlight-heading-badges/@astrojs/markdown-remark/shiki/@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.5" }, "os": "linux", "cpu": "arm" }, "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.5", "", {}, "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.0.4" }, "os": "linux", "cpu": "s390x" }, "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki": ["shiki@3.22.0", "", { "dependencies": { "@shikijs/core": "3.22.0", "@shikijs/engine-javascript": "3.22.0", "@shikijs/engine-oniguruma": "3.22.0", "@shikijs/langs": "3.22.0", "@shikijs/themes": "3.22.0", "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/core": ["@shikijs/core@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" }, "os": "linux", "cpu": "arm64" }, "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.0.4" }, "os": "linux", "cpu": "x64" }, "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-wasm32": ["@img/sharp-wasm32@0.33.5", "", { "dependencies": { "@emnapi/runtime": "^1.2.0" }, "cpu": "none" }, "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/langs": ["@shikijs/langs@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.33.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/themes": ["@shikijs/themes@3.22.0", "", { "dependencies": { "@shikijs/types": "3.22.0" } }, "sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g=="], - "@astrojs/cloudflare/wrangler/miniflare/sharp/@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.5", "", { "os": "win32", "cpu": "x64" }, "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg=="], + "starlight-llms-txt/@astrojs/mdx/@astrojs/markdown-remark/shiki/@shikijs/types": ["@shikijs/types@3.22.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg=="], } } diff --git a/site/package-lock.json b/site/package-lock.json deleted file mode 100644 index 0fa2db0a..00000000 --- a/site/package-lock.json +++ /dev/null @@ -1,8914 +0,0 @@ -{ - "name": "site", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "site", - "version": "0.0.1", - "dependencies": { - "@astrojs/cloudflare": "^12.6.5", - "@astrojs/starlight": "^0.37.6", - "@knitli/docs-components": "^1.0.3", - "astro": "^5.17.0", - "sharp": "^0.34.2" - }, - "devDependencies": { - "wrangler": ">=4.59.1" - } - }, - "node_modules/@astrojs/cloudflare": { - "version": "12.6.12", - "resolved": "https://registry.npmjs.org/@astrojs/cloudflare/-/cloudflare-12.6.12.tgz", - "integrity": "sha512-f6iXreyJc02EhokqsoPf7D/s3tebyZ8dBNVOyY2JDY87ujft4RokVS1f+zNwNFyu0wkehC4ALUboU5z590DE4w==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.7.5", - "@astrojs/underscore-redirects": "1.0.0", - "@cloudflare/workers-types": "^4.20251121.0", - "tinyglobby": "^0.2.15", - "vite": "^6.4.1", - "wrangler": "4.50.0" - }, - "peerDependencies": { - "astro": "^5.7.0" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/kv-asset-handler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.0.tgz", - "integrity": "sha512-+tv3z+SPp+gqTIcImN9o0hqE9xyfQjI1XD9pL6NuKjua9B1y7mNYv0S9cP+QEbA4ppVgGZEmKOvHX5G5Ei1CVA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "mime": "^3.0.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/unenv-preset": { - "version": "2.7.11", - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.7.11.tgz", - "integrity": "sha512-se23f1D4PxKrMKOq+Stz+Yn7AJ9ITHcEecXo2Yjb+UgbUDCEBch1FXQC6hx6uT5fNA3kmX3mfzeZiUmpK1W9IQ==", - "license": "MIT OR Apache-2.0", - "peerDependencies": { - "unenv": "2.0.0-rc.24", - "workerd": "^1.20251106.1" - }, - "peerDependenciesMeta": { - "workerd": { - "optional": true - } - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20251118.0.tgz", - "integrity": "sha512-UmWmYEYS/LkK/4HFKN6xf3Hk8cw70PviR+ftr3hUvs9HYZS92IseZEp16pkL6ZBETrPRpZC7OrzoYF7ky6kHsg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20251118.0.tgz", - "integrity": "sha512-RockU7Qzf4rxNfY1lx3j4rvwutNLjTIX7rr2hogbQ4mzLo8Ea40/oZTzXVxl+on75joLBrt0YpenGW8o/r44QA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20251118.0.tgz", - "integrity": "sha512-aT97GnOAbJDuuOG0zPVhgRk0xFtB1dzBMrxMZ09eubDLoU4djH4BuORaqvxNRMmHgKfa4T6drthckT0NjUvBdw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20251118.0.tgz", - "integrity": "sha512-bXZPJcwlq00MPOXqP7DMWjr+goYj0+Fqyw6zgEC2M3FR1+SWla4yjghnZ4IdpN+H1t7VbUrsi5np2LzMUFs0NA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20251118.0.tgz", - "integrity": "sha512-2LV99AHSlpr8WcCb/BYbU2QsYkXLUL1izN6YKWkN9Eibv80JKX0RtgmD3dfmajE5sNvClavxZejgzVvHD9N9Ag==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", - "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-darwin-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", - "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", - "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", - "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", - "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", - "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", - "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", - "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", - "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", - "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.5" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", - "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-s390x": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", - "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linux-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", - "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", - "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", - "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.0.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-wasm32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", - "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.2.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-ia32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", - "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/@img/sharp-win32-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", - "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/miniflare": { - "version": "4.20251118.1", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20251118.1.tgz", - "integrity": "sha512-uLSAE/DvOm392fiaig4LOaatxLjM7xzIniFRG5Y3yF9IduOYLLK/pkCPQNCgKQH3ou0YJRHnTN+09LPfqYNTQQ==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "acorn": "8.14.0", - "acorn-walk": "8.3.2", - "exit-hook": "2.2.1", - "glob-to-regexp": "0.4.1", - "sharp": "^0.33.5", - "stoppable": "1.1.0", - "undici": "7.14.0", - "workerd": "1.20251118.0", - "ws": "8.18.0", - "youch": "4.1.0-beta.10", - "zod": "3.22.3" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/sharp": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", - "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.3", - "semver": "^7.6.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.33.5", - "@img/sharp-darwin-x64": "0.33.5", - "@img/sharp-libvips-darwin-arm64": "1.0.4", - "@img/sharp-libvips-darwin-x64": "1.0.4", - "@img/sharp-libvips-linux-arm": "1.0.5", - "@img/sharp-libvips-linux-arm64": "1.0.4", - "@img/sharp-libvips-linux-s390x": "1.0.4", - "@img/sharp-libvips-linux-x64": "1.0.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", - "@img/sharp-libvips-linuxmusl-x64": "1.0.4", - "@img/sharp-linux-arm": "0.33.5", - "@img/sharp-linux-arm64": "0.33.5", - "@img/sharp-linux-s390x": "0.33.5", - "@img/sharp-linux-x64": "0.33.5", - "@img/sharp-linuxmusl-arm64": "0.33.5", - "@img/sharp-linuxmusl-x64": "0.33.5", - "@img/sharp-wasm32": "0.33.5", - "@img/sharp-win32-ia32": "0.33.5", - "@img/sharp-win32-x64": "0.33.5" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/undici": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.14.0.tgz", - "integrity": "sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==", - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/workerd": { - "version": "1.20251118.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20251118.0.tgz", - "integrity": "sha512-Om5ns0Lyx/LKtYI04IV0bjIrkBgoFNg0p6urzr2asekJlfP18RqFzyqMFZKf0i9Gnjtz/JfAS/Ol6tjCe5JJsQ==", - "hasInstallScript": true, - "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20251118.0", - "@cloudflare/workerd-darwin-arm64": "1.20251118.0", - "@cloudflare/workerd-linux-64": "1.20251118.0", - "@cloudflare/workerd-linux-arm64": "1.20251118.0", - "@cloudflare/workerd-windows-64": "1.20251118.0" - } - }, - "node_modules/@astrojs/cloudflare/node_modules/wrangler": { - "version": "4.50.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.50.0.tgz", - "integrity": "sha512-+nuZuHZxDdKmAyXOSrHlciGshCoAPiy5dM+t6mEohWm7HpXvTHmWQGUf/na9jjWlWJHCJYOWzkA1P5HBJqrIEA==", - "license": "MIT OR Apache-2.0", - "dependencies": { - "@cloudflare/kv-asset-handler": "0.4.0", - "@cloudflare/unenv-preset": "2.7.11", - "blake3-wasm": "2.1.5", - "esbuild": "0.25.4", - "miniflare": "4.20251118.1", - "path-to-regexp": "6.3.0", - "unenv": "2.0.0-rc.24", - "workerd": "1.20251118.0" - }, - "bin": { - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" - }, - "engines": { - "node": ">=20.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@cloudflare/workers-types": "^4.20251118.0" - }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } - } - }, - "node_modules/@astrojs/cloudflare/node_modules/zod": { - "version": "3.22.3", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.3.tgz", - "integrity": "sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/@astrojs/compiler": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", - "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", - "license": "MIT" - }, - "node_modules/@astrojs/internal-helpers": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.7.5.tgz", - "integrity": "sha512-vreGnYSSKhAjFJCWAwe/CNhONvoc5lokxtRoZims+0wa3KbHBdPHSSthJsKxPd8d/aic6lWKpRTYGY/hsgK6EA==", - "license": "MIT" - }, - "node_modules/@astrojs/markdown-remark": { - "version": "6.3.10", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-6.3.10.tgz", - "integrity": "sha512-kk4HeYR6AcnzC4QV8iSlOfh+N8TZ3MEStxPyenyCtemqn8IpEATBFMTJcfrNW32dgpt6MY3oCkMM/Tv3/I4G3A==", - "license": "MIT", - "dependencies": { - "@astrojs/internal-helpers": "0.7.5", - "@astrojs/prism": "3.3.0", - "github-slugger": "^2.0.0", - "hast-util-from-html": "^2.0.3", - "hast-util-to-text": "^4.0.2", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.1", - "mdast-util-definitions": "^6.0.0", - "rehype-raw": "^7.0.0", - "rehype-stringify": "^10.0.1", - "remark-gfm": "^4.0.1", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.1.2", - "remark-smartypants": "^3.0.2", - "shiki": "^3.19.0", - "smol-toml": "^1.5.2", - "unified": "^11.0.5", - "unist-util-remove-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.2", - "vfile": "^6.0.3" - } - }, - "node_modules/@astrojs/mdx": { - "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-4.3.13.tgz", - "integrity": "sha512-IHDHVKz0JfKBy3//52JSiyWv089b7GVSChIXLrlUOoTLWowG3wr2/8hkaEgEyd/vysvNQvGk+QhysXpJW5ve6Q==", - "license": "MIT", - "dependencies": { - "@astrojs/markdown-remark": "6.3.10", - "@mdx-js/mdx": "^3.1.1", - "acorn": "^8.15.0", - "es-module-lexer": "^1.7.0", - "estree-util-visit": "^2.0.0", - "hast-util-to-html": "^9.0.5", - "piccolore": "^0.1.3", - "rehype-raw": "^7.0.0", - "remark-gfm": "^4.0.1", - "remark-smartypants": "^3.0.2", - "source-map": "^0.7.6", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.3" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - }, - "peerDependencies": { - "astro": "^5.0.0" - } - }, - "node_modules/@astrojs/prism": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.3.0.tgz", - "integrity": "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ==", - "license": "MIT", - "dependencies": { - "prismjs": "^1.30.0" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - } - }, - "node_modules/@astrojs/sitemap": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", - "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", - "license": "MIT", - "dependencies": { - "sitemap": "^8.0.2", - "stream-replace-string": "^2.0.0", - "zod": "^3.25.76" - } - }, - "node_modules/@astrojs/starlight": { - "version": "0.37.6", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.37.6.tgz", - "integrity": "sha512-wQrKwH431q+8FsLBnNQeG+R36TMtEGxTQ2AuiVpcx9APcazvL3n7wVW8mMmYyxX0POjTnxlcWPkdMGR3Yj1L+w==", - "license": "MIT", - "dependencies": { - "@astrojs/markdown-remark": "^6.3.1", - "@astrojs/mdx": "^4.2.3", - "@astrojs/sitemap": "^3.3.0", - "@pagefind/default-ui": "^1.3.0", - "@types/hast": "^3.0.4", - "@types/js-yaml": "^4.0.9", - "@types/mdast": "^4.0.4", - "astro-expressive-code": "^0.41.1", - "bcp-47": "^2.1.0", - "hast-util-from-html": "^2.0.1", - "hast-util-select": "^6.0.2", - "hast-util-to-string": "^3.0.0", - "hastscript": "^9.0.0", - "i18next": "^23.11.5", - "js-yaml": "^4.1.0", - "klona": "^2.0.6", - "magic-string": "^0.30.17", - "mdast-util-directive": "^3.0.0", - "mdast-util-to-markdown": "^2.1.0", - "mdast-util-to-string": "^4.0.0", - "pagefind": "^1.3.0", - "rehype": "^13.0.1", - "rehype-format": "^5.0.0", - "remark-directive": "^3.0.0", - "ultrahtml": "^1.6.0", - "unified": "^11.0.5", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.2" - }, - "peerDependencies": { - "astro": "^5.5.0" - } - }, - "node_modules/@astrojs/telemetry": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", - "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==", - "license": "MIT", - "dependencies": { - "ci-info": "^4.2.0", - "debug": "^4.4.0", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "is-docker": "^3.0.0", - "is-wsl": "^3.1.0", - "which-pm-runs": "^1.1.0" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0" - } - }, - "node_modules/@astrojs/underscore-redirects": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-1.0.0.tgz", - "integrity": "sha512-qZxHwVnmb5FXuvRsaIGaqWgnftjCuMY+GSbaVZdBmE4j8AfgPqKPxYp8SUERyJcjpKCEmO4wD6ybuGH8A2kVRQ==", - "license": "MIT" - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.6" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@capsizecss/unpack": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.0.tgz", - "integrity": "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==", - "license": "MIT", - "dependencies": { - "fontkitten": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@cloudflare/kv-asset-handler": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.4.2.tgz", - "integrity": "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==", - "dev": true, - "license": "MIT OR Apache-2.0", - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@cloudflare/unenv-preset": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.12.1.tgz", - "integrity": "sha512-tP/Wi+40aBJovonSNJSsS7aFJY0xjuckKplmzDs2Xat06BJ68B6iG7YDUWXJL8gNn0gqW7YC5WhlYhO3QbugQA==", - "dev": true, - "license": "MIT OR Apache-2.0", - "peerDependencies": { - "unenv": "2.0.0-rc.24", - "workerd": "^1.20260115.0" - }, - "peerDependenciesMeta": { - "workerd": { - "optional": true - } - } - }, - "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260212.0.tgz", - "integrity": "sha512-kLxuYutk88Wlo7edp8mlkN68TgZZ9237SUnuX9kNaD5jcOdblUqiBctMRZeRcPsuoX/3g2t0vS4ga02NBEVRNg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260212.0.tgz", - "integrity": "sha512-fqoqQWMA1D0ZzDOD8sp0allREM2M8GHdpxMXQ8EdZpZ70z5bJbJ9Vr4qe35++FNIZJspsDHfTw3Xm/M4ELm/dQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260212.0.tgz", - "integrity": "sha512-bCSQoZzDzV5MSh4ueWo1DgmOn4Hf3QBu4Yo3eQFXA2llYFIu/sZgRtkEehw1X2/SY5Sn6O0EMCqxJYRf82Wdeg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260212.0.tgz", - "integrity": "sha512-GPvp1iiKQodtbUDi6OmR5I0vD75lawB54tdYGtmypuHC7ZOI2WhBmhb3wCxgnQNOG1z7mhCQrzRCoqrKwYbVWQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260212.0.tgz", - "integrity": "sha512-wHRI218Xn4ndgWJCUHH4Zx0YlU5q/o6OmcxXkcw95tJOsQn4lDrhppioPh4eScxJZALf2X+ODeZcyQTCq5exGw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workers-types": { - "version": "4.20260213.0", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260213.0.tgz", - "integrity": "sha512-dr905ft/1R0mnfdT9aun4vanLgIBN27ZyPxTCENKmhctSz6zNmBOvHbzDWAhGE0RBAKFf3X7ifMRcd0MkmBvgA==", - "license": "MIT OR Apache-2.0" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", - "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", - "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@expressive-code/core": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.41.6.tgz", - "integrity": "sha512-FvJQP+hG0jWi/FLBSmvHInDqWR7jNANp9PUDjdMqSshHb0y7sxx3vHuoOr6SgXjWw+MGLqorZyPQ0aAlHEok6g==", - "license": "MIT", - "dependencies": { - "@ctrl/tinycolor": "^4.0.4", - "hast-util-select": "^6.0.2", - "hast-util-to-html": "^9.0.1", - "hast-util-to-text": "^4.0.1", - "hastscript": "^9.0.0", - "postcss": "^8.4.38", - "postcss-nested": "^6.0.1", - "unist-util-visit": "^5.0.0", - "unist-util-visit-parents": "^6.0.1" - } - }, - "node_modules/@expressive-code/plugin-frames": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.41.6.tgz", - "integrity": "sha512-d+hkSYXIQot6fmYnOmWAM+7TNWRv/dhfjMsNq+mIZz8Tb4mPHOcgcfZeEM5dV9TDL0ioQNvtcqQNuzA1sRPjxg==", - "license": "MIT", - "dependencies": { - "@expressive-code/core": "^0.41.6" - } - }, - "node_modules/@expressive-code/plugin-shiki": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.41.6.tgz", - "integrity": "sha512-Y6zmKBmsIUtWTzdefqlzm/h9Zz0Rc4gNdt2GTIH7fhHH2I9+lDYCa27BDwuBhjqcos6uK81Aca9dLUC4wzN+ng==", - "license": "MIT", - "dependencies": { - "@expressive-code/core": "^0.41.6", - "shiki": "^3.2.2" - } - }, - "node_modules/@expressive-code/plugin-text-markers": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.41.6.tgz", - "integrity": "sha512-PBFa1wGyYzRExMDzBmAWC6/kdfG1oLn4pLpBeTfIRrALPjcGA/59HP3e7q9J0Smk4pC7U+lWkA2LHR8FYV8U7Q==", - "license": "MIT", - "dependencies": { - "@expressive-code/core": "^0.41.6" - } - }, - "node_modules/@img/colour": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", - "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", - "cpu": [ - "arm" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", - "cpu": [ - "ppc64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", - "cpu": [ - "riscv64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", - "cpu": [ - "s390x" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", - "cpu": [ - "arm64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", - "cpu": [ - "x64" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", - "cpu": [ - "arm" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", - "cpu": [ - "ppc64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", - "cpu": [ - "riscv64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", - "cpu": [ - "s390x" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", - "cpu": [ - "wasm32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.7.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", - "cpu": [ - "arm64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", - "cpu": [ - "ia32" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", - "cpu": [ - "x64" - ], - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@knitli/docs-components": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@knitli/docs-components/-/docs-components-1.0.3.tgz", - "integrity": "sha512-Iypb5UlkBD3aMxinGuy738JY7noopWzQxOHzmoC7AvvJsJ91Y6VEARYQsV4iAvOipj+fwC6kYZIXuAHtOc/LBw==", - "license": "LicenseRef-Not_Licensed", - "peerDependencies": { - "astro": "^5.0.0" - } - }, - "node_modules/@mdx-js/mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", - "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdx": "^2.0.0", - "acorn": "^8.0.0", - "collapse-white-space": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-util-scope": "^1.0.0", - "estree-walker": "^3.0.0", - "hast-util-to-jsx-runtime": "^2.0.0", - "markdown-extensions": "^2.0.0", - "recma-build-jsx": "^1.0.0", - "recma-jsx": "^1.0.0", - "recma-stringify": "^1.0.0", - "rehype-recma": "^1.0.0", - "remark-mdx": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-rehype": "^11.0.0", - "source-map": "^0.7.0", - "unified": "^11.0.0", - "unist-util-position-from-estree": "^2.0.0", - "unist-util-stringify-position": "^4.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@oslojs/encoding": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", - "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", - "license": "MIT" - }, - "node_modules/@pagefind/darwin-arm64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz", - "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/darwin-x64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz", - "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@pagefind/default-ui": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.4.0.tgz", - "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==", - "license": "MIT" - }, - "node_modules/@pagefind/freebsd-x64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz", - "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@pagefind/linux-arm64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz", - "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/linux-x64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz", - "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@pagefind/windows-x64": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz", - "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@poppinss/colors": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", - "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", - "license": "MIT", - "dependencies": { - "kleur": "^4.1.5" - } - }, - "node_modules/@poppinss/colors/node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/@poppinss/dumper": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", - "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", - "license": "MIT", - "dependencies": { - "@poppinss/colors": "^4.1.5", - "@sindresorhus/is": "^7.0.2", - "supports-color": "^10.0.0" - } - }, - "node_modules/@poppinss/exception": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", - "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", - "license": "MIT" - }, - "node_modules/@rollup/pluginutils": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", - "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.0.tgz", - "integrity": "sha512-tPgXB6cDTndIe1ah7u6amCI1T0SsnlOuKgg10Xh3uizJk4e5M1JGaUMk7J4ciuAUcFpbOiNhm2XIjP9ON0dUqA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.0.tgz", - "integrity": "sha512-sa4LyseLLXr1onr97StkU1Nb7fWcg6niokTwEVNOO7awaKaoRObQ54+V/hrF/BP1noMEaaAW6Fg2d/CfLiq3Mg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.0.tgz", - "integrity": "sha512-/NNIj9A7yLjKdmkx5dC2XQ9DmjIECpGpwHoGmA5E1AhU0fuICSqSWScPhN1yLCkEdkCwJIDu2xIeLPs60MNIVg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.0.tgz", - "integrity": "sha512-xoh8abqgPrPYPr7pTYipqnUi1V3em56JzE/HgDgitTqZBZ3yKCWI+7KUkceM6tNweyUKYru1UMi7FC060RyKwA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.0.tgz", - "integrity": "sha512-PCkMh7fNahWSbA0OTUQ2OpYHpjZZr0hPr8lId8twD7a7SeWrvT3xJVyza+dQwXSSq4yEQTMoXgNOfMCsn8584g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.0.tgz", - "integrity": "sha512-1j3stGx+qbhXql4OCDZhnK7b01s6rBKNybfsX+TNrEe9JNq4DLi1yGiR1xW+nL+FNVvI4D02PUnl6gJ/2y6WJA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.0.tgz", - "integrity": "sha512-eyrr5W08Ms9uM0mLcKfM/Uzx7hjhz2bcjv8P2uynfj0yU8GGPdz8iYrBPhiLOZqahoAMB8ZiolRZPbbU2MAi6Q==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.0.tgz", - "integrity": "sha512-Xds90ITXJCNyX9pDhqf85MKWUI4lqjiPAipJ8OLp8xqI2Ehk+TCVhF9rvOoN8xTbcafow3QOThkNnrM33uCFQA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.0.tgz", - "integrity": "sha512-Xws2KA4CLvZmXjy46SQaXSejuKPhwVdaNinldoYfqruZBaJHqVo6hnRa8SDo9z7PBW5x84SH64+izmldCgbezw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.0.tgz", - "integrity": "sha512-hrKXKbX5FdaRJj7lTMusmvKbhMJSGWJ+w++4KmjiDhpTgNlhYobMvKfDoIWecy4O60K6yA4SnztGuNTQF+Lplw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.0.tgz", - "integrity": "sha512-6A+nccfSDGKsPm00d3xKcrsBcbqzCTAukjwWK6rbuAnB2bHaL3r9720HBVZ/no7+FhZLz/U3GwwZZEh6tOSI8Q==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.0.tgz", - "integrity": "sha512-4P1VyYUe6XAJtQH1Hh99THxr0GKMMwIXsRNOceLrJnaHTDgk1FTcTimDgneRJPvB3LqDQxUmroBclQ1S0cIJwQ==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.0.tgz", - "integrity": "sha512-8Vv6pLuIZCMcgXre6c3nOPhE0gjz1+nZP6T+hwWjr7sVH8k0jRkH+XnfjjOTglyMBdSKBPPz54/y1gToSKwrSQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.0.tgz", - "integrity": "sha512-r1te1M0Sm2TBVD/RxBPC6RZVwNqUTwJTA7w+C/IW5v9Ssu6xmxWEi+iJQlpBhtUiT1raJ5b48pI8tBvEjEFnFA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.0.tgz", - "integrity": "sha512-say0uMU/RaPm3CDQLxUUTF2oNWL8ysvHkAjcCzV2znxBr23kFfaxocS9qJm+NdkRhF8wtdEEAJuYcLPhSPbjuQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.0.tgz", - "integrity": "sha512-/MU7/HizQGsnBREtRpcSbSV1zfkoxSTR7wLsRmBPQ8FwUj5sykrP1MyJTvsxP5KBq9SyE6kH8UQQQwa0ASeoQQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.0.tgz", - "integrity": "sha512-Q9eh+gUGILIHEaJf66aF6a414jQbDnn29zeu0eX3dHMuysnhTvsUvZTCAyZ6tJhUjnvzBKE4FtuaYxutxRZpOg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.0.tgz", - "integrity": "sha512-OR5p5yG5OKSxHReWmwvM0P+VTPMwoBS45PXTMYaskKQqybkS3Kmugq1W+YbNWArF8/s7jQScgzXUhArzEQ7x0A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.0.tgz", - "integrity": "sha512-XeatKzo4lHDsVEbm1XDHZlhYZZSQYym6dg2X/Ko0kSFgio+KXLsxwJQprnR48GvdIKDOpqWqssC3iBCjoMcMpw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.0.tgz", - "integrity": "sha512-Lu71y78F5qOfYmubYLHPcJm74GZLU6UJ4THkf/a1K7Tz2ycwC2VUbsqbJAXaR6Bx70SRdlVrt2+n5l7F0agTUw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.0.tgz", - "integrity": "sha512-v5xwKDWcu7qhAEcsUubiav7r+48Uk/ENWdr82MBZZRIm7zThSxCIVDfb3ZeRRq9yqk+oIzMdDo6fCcA5DHfMyA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.0.tgz", - "integrity": "sha512-XnaaaSMGSI6Wk8F4KK3QP7GfuuhjGchElsVerCplUuxRIzdvZ7hRBpLR0omCmw+kI2RFJB80nenhOoGXlJ5TfQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.0.tgz", - "integrity": "sha512-3K1lP+3BXY4t4VihLw5MEg6IZD3ojSYzqzBG571W3kNQe4G4CcFpSUQVgurYgib5d+YaCjeFow8QivWp8vuSvA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.0.tgz", - "integrity": "sha512-MDk610P/vJGc5L5ImE4k5s+GZT3en0KoK1MKPXCRgzmksAMk79j4h3k1IerxTNqwDLxsGxStEZVBqG0gIqZqoA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.0.tgz", - "integrity": "sha512-Zv7v6q6aV+VslnpwzqKAmrk5JdVkLUzok2208ZXGipjb+msxBr/fJPZyeEXiFgH7k62Ak0SLIfxQRZQvTuf7rQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-3.21.0.tgz", - "integrity": "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.21.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4", - "hast-util-to-html": "^9.0.5" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.21.0.tgz", - "integrity": "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.21.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^4.3.4" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.21.0.tgz", - "integrity": "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.21.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.21.0.tgz", - "integrity": "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.21.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.21.0.tgz", - "integrity": "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==", - "license": "MIT", - "dependencies": { - "@shikijs/types": "3.21.0" - } - }, - "node_modules/@shikijs/types": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz", - "integrity": "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==", - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", - "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@speed-highlight/core": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.14.tgz", - "integrity": "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==", - "license": "CC0-1.0" - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "license": "MIT" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/js-yaml": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", - "license": "MIT" - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdx": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/nlcst": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", - "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/node": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz", - "integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==", - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/sax": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", - "license": "MIT", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/astro": { - "version": "5.17.2", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.17.2.tgz", - "integrity": "sha512-7jnMqGo53hOQNwo1N/wqeOvUp8wwW/p+DeerSjSkHNx8L/1mhy6P7rVo7EhdmF8DpKqw0tl/B5Fx1WcIzg1ysA==", - "license": "MIT", - "dependencies": { - "@astrojs/compiler": "^2.13.0", - "@astrojs/internal-helpers": "0.7.5", - "@astrojs/markdown-remark": "6.3.10", - "@astrojs/telemetry": "3.3.0", - "@capsizecss/unpack": "^4.0.0", - "@oslojs/encoding": "^1.1.0", - "@rollup/pluginutils": "^5.3.0", - "acorn": "^8.15.0", - "aria-query": "^5.3.2", - "axobject-query": "^4.1.0", - "boxen": "8.0.1", - "ci-info": "^4.3.1", - "clsx": "^2.1.1", - "common-ancestor-path": "^1.0.1", - "cookie": "^1.1.1", - "cssesc": "^3.0.0", - "debug": "^4.4.3", - "deterministic-object-hash": "^2.0.2", - "devalue": "^5.6.2", - "diff": "^8.0.3", - "dlv": "^1.1.3", - "dset": "^3.1.4", - "es-module-lexer": "^1.7.0", - "esbuild": "^0.27.0", - "estree-walker": "^3.0.3", - "flattie": "^1.1.1", - "fontace": "~0.4.0", - "github-slugger": "^2.0.0", - "html-escaper": "3.0.3", - "http-cache-semantics": "^4.2.0", - "import-meta-resolve": "^4.2.0", - "js-yaml": "^4.1.1", - "magic-string": "^0.30.21", - "magicast": "^0.5.1", - "mrmime": "^2.0.1", - "neotraverse": "^0.6.18", - "p-limit": "^6.2.0", - "p-queue": "^8.1.1", - "package-manager-detector": "^1.6.0", - "piccolore": "^0.1.3", - "picomatch": "^4.0.3", - "prompts": "^2.4.2", - "rehype": "^13.0.2", - "semver": "^7.7.3", - "shiki": "^3.21.0", - "smol-toml": "^1.6.0", - "svgo": "^4.0.0", - "tinyexec": "^1.0.2", - "tinyglobby": "^0.2.15", - "tsconfck": "^3.1.6", - "ultrahtml": "^1.6.0", - "unifont": "~0.7.3", - "unist-util-visit": "^5.0.0", - "unstorage": "^1.17.4", - "vfile": "^6.0.3", - "vite": "^6.4.1", - "vitefu": "^1.1.1", - "xxhash-wasm": "^1.1.0", - "yargs-parser": "^21.1.1", - "yocto-spinner": "^0.2.3", - "zod": "^3.25.76", - "zod-to-json-schema": "^3.25.1", - "zod-to-ts": "^1.2.0" - }, - "bin": { - "astro": "astro.js" - }, - "engines": { - "node": "18.20.8 || ^20.3.0 || >=22.0.0", - "npm": ">=9.6.5", - "pnpm": ">=7.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/astrodotbuild" - }, - "optionalDependencies": { - "sharp": "^0.34.0" - } - }, - "node_modules/astro-expressive-code": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.41.6.tgz", - "integrity": "sha512-l47tb1uhmVIebHUkw+HEPtU/av0G4O8Q34g2cbkPvC7/e9ZhANcjUUciKt9Hp6gSVDdIuXBBLwJQn2LkeGMOAw==", - "license": "MIT", - "dependencies": { - "rehype-expressive-code": "^0.41.6" - }, - "peerDependencies": { - "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta" - } - }, - "node_modules/astro/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/astro/node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", - "license": "MIT" - }, - "node_modules/bcp-47": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", - "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/bcp-47-match": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", - "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/blake3-wasm": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", - "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", - "license": "MIT" - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/boxen": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", - "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^8.0.0", - "chalk": "^5.3.0", - "cli-boxes": "^3.0.0", - "string-width": "^7.2.0", - "type-fest": "^4.21.0", - "widest-line": "^5.0.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", - "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "license": "MIT", - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/collapse-white-space": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", - "license": "MIT", - "engines": { - "node": ">=16" - } - }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "license": "ISC" - }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/cookie-es": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz", - "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==", - "license": "MIT" - }, - "node_modules/crossws": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", - "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", - "license": "MIT", - "dependencies": { - "uncrypto": "^0.1.3" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-selector-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", - "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/css-tree": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.12.2", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csso": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "license": "MIT", - "dependencies": { - "css-tree": "~2.2.0" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/css-tree": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.28", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", - "npm": ">=7.0.0" - } - }, - "node_modules/csso/node_modules/mdn-data": { - "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "license": "CC0-1.0" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/defu": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "license": "MIT" - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/destr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", - "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/deterministic-object-hash": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", - "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", - "license": "MIT", - "dependencies": { - "base-64": "^1.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/devalue": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", - "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", - "license": "MIT" - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/diff": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", - "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/direction": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", - "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", - "license": "MIT", - "bin": { - "direction": "cli.js" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "license": "MIT" - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dset": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", - "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "license": "MIT" - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-stack-parser-es": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", - "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "license": "MIT" - }, - "node_modules/esast-util-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", - "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esast-util-from-js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", - "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "acorn": "^8.0.0", - "esast-util-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "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/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/estree-util-attach-comments": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", - "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-visit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" - }, - "node_modules/exit-hook": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", - "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/expressive-code": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.41.6.tgz", - "integrity": "sha512-W/5+IQbrpCIM5KGLjO35wlp1NCwDOOVQb+PAvzEoGkW1xjGM807ZGfBKptNWH6UECvt6qgmLyWolCMYKh7eQmA==", - "license": "MIT", - "dependencies": { - "@expressive-code/core": "^0.41.6", - "@expressive-code/plugin-frames": "^0.41.6", - "@expressive-code/plugin-shiki": "^0.41.6", - "@expressive-code/plugin-text-markers": "^0.41.6" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/flattie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", - "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/fontace": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.0.tgz", - "integrity": "sha512-moThBCItUe2bjZip5PF/iZClpKHGLwMvR79Kp8XpGRBrvoRSnySN4VcILdv3/MJzbhvUA5WeiUXF5o538m5fvg==", - "license": "MIT", - "dependencies": { - "fontkitten": "^1.0.0" - } - }, - "node_modules/fontkitten": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.2.tgz", - "integrity": "sha512-piJxbLnkD9Xcyi7dWJRnqszEURixe7CrF/efBfbffe2DPyabmuIuqraruY8cXTs19QoM8VJzx47BDRVNXETM7Q==", - "license": "MIT", - "dependencies": { - "tiny-inflate": "^1.0.3" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "license": "BSD-2-Clause" - }, - "node_modules/h3": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.5.tgz", - "integrity": "sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==", - "license": "MIT", - "dependencies": { - "cookie-es": "^1.2.2", - "crossws": "^0.3.5", - "defu": "^6.1.4", - "destr": "^2.0.5", - "iron-webcrypto": "^1.2.1", - "node-mock-http": "^1.0.4", - "radix3": "^1.1.2", - "ufo": "^1.6.3", - "uncrypto": "^0.1.3" - } - }, - "node_modules/hast-util-embedded": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", - "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-is-element": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-format": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hast-util-format/-/hast-util-format-1.1.0.tgz", - "integrity": "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-embedded": "^3.0.0", - "hast-util-minify-whitespace": "^1.0.0", - "hast-util-phrasing": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "html-whitespace-sensitive-tag-names": "^3.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-html": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", - "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "devlop": "^1.1.0", - "hast-util-from-parse5": "^8.0.0", - "parse5": "^7.0.0", - "vfile": "^6.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "hastscript": "^9.0.0", - "property-information": "^7.0.0", - "vfile": "^6.0.0", - "vfile-location": "^5.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-has-property": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", - "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-body-ok-link": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", - "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-is-element": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", - "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-minify-whitespace": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", - "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-embedded": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-embedded": "^3.0.0", - "hast-util-has-property": "^3.0.0", - "hast-util-is-body-ok-link": "^3.0.0", - "hast-util-is-element": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "@ungap/structured-clone": "^1.0.0", - "hast-util-from-parse5": "^8.0.0", - "hast-util-to-parse5": "^8.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "parse5": "^7.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.4.tgz", - "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "bcp-47-match": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "css-selector-parser": "^3.0.0", - "devlop": "^1.0.0", - "direction": "^2.0.0", - "hast-util-has-property": "^3.0.0", - "hast-util-to-string": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "nth-check": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", - "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-attach-comments": "^3.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-jsx-runtime": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "hast-util-whitespace": "^3.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-js": "^1.0.0", - "unist-util-position": "^5.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", - "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "devlop": "^1.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", - "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-text": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", - "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "hast-util-is-element": "^3.0.0", - "unist-util-find-after": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^4.0.0", - "property-information": "^7.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", - "license": "MIT" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/html-whitespace-sensitive-tag-names": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz", - "integrity": "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "license": "BSD-2-Clause" - }, - "node_modules/i18next": { - "version": "23.16.8", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", - "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", - "funding": [ - { - "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - } - ], - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.2" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", - "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/inline-style-parser": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", - "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", - "license": "MIT" - }, - "node_modules/iron-webcrypto": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", - "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/brc-dd" - } - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "license": "MIT", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", - "license": "MIT" - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "source-map-js": "^1.2.1" - } - }, - "node_modules/markdown-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/markdown-table": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/mdast-util-definitions": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", - "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-gfm-autolink-literal": "^2.0.0", - "mdast-util-gfm-footnote": "^2.0.0", - "mdast-util-gfm-strikethrough": "^2.0.0", - "mdast-util-gfm-table": "^2.0.0", - "mdast-util-gfm-task-list-item": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "ccount": "^2.0.0", - "devlop": "^1.0.0", - "mdast-util-find-and-replace": "^3.0.0", - "micromark-util-character": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", - "license": "MIT", - "dependencies": { - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-mdx-expression": "^2.0.0", - "mdast-util-mdx-jsx": "^3.0.0", - "mdast-util-mdxjs-esm": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "devlop": "^1.1.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-stringify-position": "^4.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", - "license": "MIT", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "devlop": "^1.0.0", - "mdast-util-from-markdown": "^2.0.0", - "mdast-util-to-markdown": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "@ungap/structured-clone": "^1.0.0", - "devlop": "^1.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "trim-lines": "^3.0.0", - "unist-util-position": "^5.0.0", - "unist-util-visit": "^5.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", - "license": "CC0-1.0" - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "parse-entities": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", - "license": "MIT", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^2.0.0", - "micromark-extension-gfm-footnote": "^2.0.0", - "micromark-extension-gfm-strikethrough": "^2.0.0", - "micromark-extension-gfm-table": "^2.0.0", - "micromark-extension-gfm-tagfilter": "^2.0.0", - "micromark-extension-gfm-task-list-item": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-expression": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", - "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", - "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "estree-util-is-identifier-name": "^3.0.0", - "micromark-factory-mdx-expression": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdx-md": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", - "license": "MIT", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^3.0.0", - "micromark-extension-mdx-jsx": "^3.0.0", - "micromark-extension-mdx-md": "^2.0.0", - "micromark-extension-mdxjs-esm": "^3.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-types": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-mdx-expression": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", - "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-events-to-acorn": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-position-from-estree": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", - "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/unist": "^3.0.0", - "devlop": "^1.0.0", - "estree-util-visit": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "vfile-message": "^4.0.0" - } - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/miniflare": { - "version": "4.20260212.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260212.0.tgz", - "integrity": "sha512-Lgxq83EuR2q/0/DAVOSGXhXS1V7GDB04HVggoPsenQng8sqEDR3hO4FigIw5ZI2Sv2X7kIc30NCzGHJlCFIYWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "^0.34.5", - "undici": "7.18.2", - "workerd": "1.20260212.0", - "ws": "8.18.0", - "youch": "4.1.0-beta.10" - }, - "bin": { - "miniflare": "bootstrap.js" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/neotraverse": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", - "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/nlcst-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", - "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/node-fetch-native": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", - "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", - "license": "MIT" - }, - "node_modules/node-mock-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.4.tgz", - "integrity": "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/ofetch": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", - "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", - "license": "MIT", - "dependencies": { - "destr": "^2.0.5", - "node-fetch-native": "^1.6.7", - "ufo": "^1.6.1" - } - }, - "node_modules/ohash": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "license": "MIT" - }, - "node_modules/oniguruma-parser": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz", - "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==", - "license": "MIT" - }, - "node_modules/oniguruma-to-es": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz", - "integrity": "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==", - "license": "MIT", - "dependencies": { - "oniguruma-parser": "^0.12.1", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/p-limit": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", - "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", - "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", - "license": "MIT", - "dependencies": { - "eventemitter3": "^5.0.1", - "p-timeout": "^6.1.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-manager-detector": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", - "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", - "license": "MIT" - }, - "node_modules/pagefind": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz", - "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==", - "license": "MIT", - "bin": { - "pagefind": "lib/runner/bin.cjs" - }, - "optionalDependencies": { - "@pagefind/darwin-arm64": "1.4.0", - "@pagefind/darwin-x64": "1.4.0", - "@pagefind/freebsd-x64": "1.4.0", - "@pagefind/linux-arm64": "1.4.0", - "@pagefind/linux-x64": "1.4.0", - "@pagefind/windows-x64": "1.4.0" - } - }, - "node_modules/parse-entities": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse-entities/node_modules/@types/unist": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", - "license": "MIT" - }, - "node_modules/parse-latin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", - "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "@types/unist": "^3.0.0", - "nlcst-to-string": "^4.0.0", - "unist-util-modify-children": "^4.0.0", - "unist-util-visit-children": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" - }, - "node_modules/piccolore": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", - "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", - "license": "ISC" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "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", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prismjs": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/radix3": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", - "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", - "license": "MIT" - }, - "node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/recma-build-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", - "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-build-jsx": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-jsx": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", - "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", - "license": "MIT", - "dependencies": { - "acorn-jsx": "^5.0.0", - "estree-util-to-js": "^2.0.0", - "recma-parse": "^1.0.0", - "recma-stringify": "^1.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/recma-parse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", - "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "esast-util-from-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/recma-stringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", - "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-util-to-js": "^2.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", - "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "license": "MIT" - }, - "node_modules/rehype": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", - "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "rehype-parse": "^9.0.0", - "rehype-stringify": "^10.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-expressive-code": { - "version": "0.41.6", - "resolved": "https://registry.npmjs.org/rehype-expressive-code/-/rehype-expressive-code-0.41.6.tgz", - "integrity": "sha512-aBMX8kxPtjmDSFUdZlAWJkMvsQ4ZMASfee90JWIAV8tweltXLzkWC3q++43ToTelI8ac5iC0B3/S/Cl4Ql1y2g==", - "license": "MIT", - "dependencies": { - "expressive-code": "^0.41.6" - } - }, - "node_modules/rehype-format": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rehype-format/-/rehype-format-5.0.1.tgz", - "integrity": "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-format": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", - "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-from-html": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-raw": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-raw": "^9.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-recma": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", - "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/hast": "^3.0.0", - "hast-util-to-estree": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-stringify": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", - "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-directive": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", - "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-directive": "^3.0.0", - "micromark-extension-directive": "^3.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-gfm": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-gfm": "^3.0.0", - "micromark-extension-gfm": "^3.0.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-mdx": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", - "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", - "license": "MIT", - "dependencies": { - "mdast-util-mdx": "^3.0.0", - "micromark-extension-mdxjs": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-rehype": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/mdast": "^4.0.0", - "mdast-util-to-hast": "^13.0.0", - "unified": "^11.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-smartypants": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", - "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", - "license": "MIT", - "dependencies": { - "retext": "^9.0.0", - "retext-smartypants": "^6.0.0", - "unified": "^11.0.4", - "unist-util-visit": "^5.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", - "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "retext-latin": "^4.0.0", - "retext-stringify": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-latin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", - "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "parse-latin": "^7.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-smartypants": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", - "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "nlcst-to-string": "^4.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-stringify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", - "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", - "license": "MIT", - "dependencies": { - "@types/nlcst": "^2.0.0", - "nlcst-to-string": "^4.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rollup": { - "version": "4.57.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz", - "integrity": "sha512-e5lPJi/aui4TO1LpAXIRLySmwXSE8k3b9zoGfd42p67wzxog4WHjiZF3M2uheQih4DGyc25QEV4yRBbpueNiUA==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.0", - "@rollup/rollup-android-arm64": "4.57.0", - "@rollup/rollup-darwin-arm64": "4.57.0", - "@rollup/rollup-darwin-x64": "4.57.0", - "@rollup/rollup-freebsd-arm64": "4.57.0", - "@rollup/rollup-freebsd-x64": "4.57.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.0", - "@rollup/rollup-linux-arm-musleabihf": "4.57.0", - "@rollup/rollup-linux-arm64-gnu": "4.57.0", - "@rollup/rollup-linux-arm64-musl": "4.57.0", - "@rollup/rollup-linux-loong64-gnu": "4.57.0", - "@rollup/rollup-linux-loong64-musl": "4.57.0", - "@rollup/rollup-linux-ppc64-gnu": "4.57.0", - "@rollup/rollup-linux-ppc64-musl": "4.57.0", - "@rollup/rollup-linux-riscv64-gnu": "4.57.0", - "@rollup/rollup-linux-riscv64-musl": "4.57.0", - "@rollup/rollup-linux-s390x-gnu": "4.57.0", - "@rollup/rollup-linux-x64-gnu": "4.57.0", - "@rollup/rollup-linux-x64-musl": "4.57.0", - "@rollup/rollup-openbsd-x64": "4.57.0", - "@rollup/rollup-openharmony-arm64": "4.57.0", - "@rollup/rollup-win32-arm64-msvc": "4.57.0", - "@rollup/rollup-win32-ia32-msvc": "4.57.0", - "@rollup/rollup-win32-x64-gnu": "4.57.0", - "@rollup/rollup-win32-x64-msvc": "4.57.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/sax": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", - "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=11.0.0" - } - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" - } - }, - "node_modules/shiki": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-3.21.0.tgz", - "integrity": "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w==", - "license": "MIT", - "dependencies": { - "@shikijs/core": "3.21.0", - "@shikijs/engine-javascript": "3.21.0", - "@shikijs/engine-oniguruma": "3.21.0", - "@shikijs/langs": "3.21.0", - "@shikijs/themes": "3.21.0", - "@shikijs/types": "3.21.0", - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", - "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/sitemap": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.2.tgz", - "integrity": "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==", - "license": "MIT", - "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.4.1" - }, - "bin": { - "sitemap": "dist/cli.js" - }, - "engines": { - "node": ">=14.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/sitemap/node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", - "license": "MIT" - }, - "node_modules/smol-toml": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz", - "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, - "node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 12" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/stoppable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", - "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", - "license": "MIT", - "engines": { - "node": ">=4", - "npm": ">=6" - } - }, - "node_modules/stream-replace-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", - "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", - "license": "MIT" - }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/style-to-js": { - "version": "1.1.21", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", - "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", - "license": "MIT", - "dependencies": { - "style-to-object": "1.0.14" - } - }, - "node_modules/style-to-object": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", - "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", - "license": "MIT", - "dependencies": { - "inline-style-parser": "0.2.7" - } - }, - "node_modules/supports-color": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/svgo": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", - "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", - "license": "MIT", - "dependencies": { - "commander": "^11.1.0", - "css-select": "^5.1.0", - "css-tree": "^3.0.1", - "css-what": "^6.1.0", - "csso": "^5.0.5", - "picocolors": "^1.1.1", - "sax": "^1.4.1" - }, - "bin": { - "svgo": "bin/svgo.js" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/svgo" - } - }, - "node_modules/tiny-inflate": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", - "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/tsconfck": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", - "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", - "license": "MIT", - "bin": { - "tsconfck": "bin/tsconfck.js" - }, - "engines": { - "node": "^18 || >=20" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true - }, - "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz", - "integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==", - "license": "MIT" - }, - "node_modules/ultrahtml": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.6.0.tgz", - "integrity": "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==", - "license": "MIT" - }, - "node_modules/uncrypto": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", - "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", - "license": "MIT" - }, - "node_modules/undici": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.2.tgz", - "integrity": "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "license": "MIT" - }, - "node_modules/unenv": { - "version": "2.0.0-rc.24", - "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", - "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", - "license": "MIT", - "dependencies": { - "pathe": "^2.0.3" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unifont": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.3.tgz", - "integrity": "sha512-b0GtQzKCyuSHGsfj5vyN8st7muZ6VCI4XD4vFlr7Uy1rlWVYxC3npnfk8MyreHxJYrz1ooLDqDzFe9XqQTlAhA==", - "license": "MIT", - "dependencies": { - "css-tree": "^3.1.0", - "ofetch": "^1.5.1", - "ohash": "^2.0.11" - } - }, - "node_modules/unist-util-find-after": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", - "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-modify-children": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", - "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "array-iterate": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position-from-estree": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-remove-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-visit": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-children": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", - "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unstorage": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz", - "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==", - "license": "MIT", - "dependencies": { - "anymatch": "^3.1.3", - "chokidar": "^5.0.0", - "destr": "^2.0.5", - "h3": "^1.15.5", - "lru-cache": "^11.2.0", - "node-fetch-native": "^1.6.7", - "ofetch": "^1.5.1", - "ufo": "^1.6.3" - }, - "peerDependencies": { - "@azure/app-configuration": "^1.8.0", - "@azure/cosmos": "^4.2.0", - "@azure/data-tables": "^13.3.0", - "@azure/identity": "^4.6.0", - "@azure/keyvault-secrets": "^4.9.0", - "@azure/storage-blob": "^12.26.0", - "@capacitor/preferences": "^6 || ^7 || ^8", - "@deno/kv": ">=0.9.0", - "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", - "@planetscale/database": "^1.19.0", - "@upstash/redis": "^1.34.3", - "@vercel/blob": ">=0.27.1", - "@vercel/functions": "^2.2.12 || ^3.0.0", - "@vercel/kv": "^1 || ^2 || ^3", - "aws4fetch": "^1.0.20", - "db0": ">=0.2.1", - "idb-keyval": "^6.2.1", - "ioredis": "^5.4.2", - "uploadthing": "^7.4.4" - }, - "peerDependenciesMeta": { - "@azure/app-configuration": { - "optional": true - }, - "@azure/cosmos": { - "optional": true - }, - "@azure/data-tables": { - "optional": true - }, - "@azure/identity": { - "optional": true - }, - "@azure/keyvault-secrets": { - "optional": true - }, - "@azure/storage-blob": { - "optional": true - }, - "@capacitor/preferences": { - "optional": true - }, - "@deno/kv": { - "optional": true - }, - "@netlify/blobs": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/blob": { - "optional": true - }, - "@vercel/functions": { - "optional": true - }, - "@vercel/kv": { - "optional": true - }, - "aws4fetch": { - "optional": true - }, - "db0": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "ioredis": { - "optional": true - }, - "uploadthing": { - "optional": true - } - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-location": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", - "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vitefu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", - "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", - "license": "MIT", - "workspaces": [ - "tests/deps/*", - "tests/projects/*", - "tests/projects/workspace/packages/*" - ], - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/web-namespaces": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/widest-line": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", - "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", - "license": "MIT", - "dependencies": { - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/workerd": { - "version": "1.20260212.0", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260212.0.tgz", - "integrity": "sha512-4B9BoZUzKSRv3pVZGEPh7OX+Q817hpUqAUtz5O0TxJVqo4OsYJAUA/sY177Q5ha/twjT9KaJt2DtQzE+oyCOzw==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260212.0", - "@cloudflare/workerd-darwin-arm64": "1.20260212.0", - "@cloudflare/workerd-linux-64": "1.20260212.0", - "@cloudflare/workerd-linux-arm64": "1.20260212.0", - "@cloudflare/workerd-windows-64": "1.20260212.0" - } - }, - "node_modules/wrangler": { - "version": "4.65.0", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.65.0.tgz", - "integrity": "sha512-R+n3o3tlGzLK9I4fGocPReOuvcnjhtOL2aCVKkHMeuEwt9pPbOO4FxJtx/ec5cIUG/otRyJnfQGCAr9DplBVng==", - "dev": true, - "license": "MIT OR Apache-2.0", - "dependencies": { - "@cloudflare/kv-asset-handler": "0.4.2", - "@cloudflare/unenv-preset": "2.12.1", - "blake3-wasm": "2.1.5", - "esbuild": "0.27.3", - "miniflare": "4.20260212.0", - "path-to-regexp": "6.3.0", - "unenv": "2.0.0-rc.24", - "workerd": "1.20260212.0" - }, - "bin": { - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" - }, - "engines": { - "node": ">=20.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@cloudflare/workers-types": "^4.20260212.0" - }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } - } - }, - "node_modules/wrangler/node_modules/@esbuild/aix-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", - "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/android-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", - "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/android-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", - "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/android-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", - "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/darwin-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", - "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/darwin-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", - "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/freebsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", - "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/freebsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", - "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-arm": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", - "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", - "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", - "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-loong64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", - "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-mips64el": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", - "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-ppc64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", - "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-riscv64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", - "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-s390x": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", - "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/linux-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", - "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/netbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", - "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/netbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", - "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/openbsd-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", - "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/openbsd-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", - "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/openharmony-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", - "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/sunos-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", - "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/win32-arm64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", - "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/win32-ia32": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", - "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/@esbuild/win32-x64": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", - "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/wrangler/node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", - "@esbuild/android-arm64": "0.27.3", - "@esbuild/android-x64": "0.27.3", - "@esbuild/darwin-arm64": "0.27.3", - "@esbuild/darwin-x64": "0.27.3", - "@esbuild/freebsd-arm64": "0.27.3", - "@esbuild/freebsd-x64": "0.27.3", - "@esbuild/linux-arm": "0.27.3", - "@esbuild/linux-arm64": "0.27.3", - "@esbuild/linux-ia32": "0.27.3", - "@esbuild/linux-loong64": "0.27.3", - "@esbuild/linux-mips64el": "0.27.3", - "@esbuild/linux-ppc64": "0.27.3", - "@esbuild/linux-riscv64": "0.27.3", - "@esbuild/linux-s390x": "0.27.3", - "@esbuild/linux-x64": "0.27.3", - "@esbuild/netbsd-arm64": "0.27.3", - "@esbuild/netbsd-x64": "0.27.3", - "@esbuild/openbsd-arm64": "0.27.3", - "@esbuild/openbsd-x64": "0.27.3", - "@esbuild/openharmony-arm64": "0.27.3", - "@esbuild/sunos-x64": "0.27.3", - "@esbuild/win32-arm64": "0.27.3", - "@esbuild/win32-ia32": "0.27.3", - "@esbuild/win32-x64": "0.27.3" - } - }, - "node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xxhash-wasm": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", - "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", - "license": "MIT" - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", - "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yocto-spinner": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-0.2.3.tgz", - "integrity": "sha512-sqBChb33loEnkoXte1bLg45bEBsOP9N1kzQh5JZNKj/0rik4zAPTNSAVPj3uQAdc6slYJ0Ksc403G2XgxsJQFQ==", - "license": "MIT", - "dependencies": { - "yoctocolors": "^2.1.1" - }, - "engines": { - "node": ">=18.19" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/youch": { - "version": "4.1.0-beta.10", - "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", - "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", - "license": "MIT", - "dependencies": { - "@poppinss/colors": "^4.1.5", - "@poppinss/dumper": "^0.6.4", - "@speed-highlight/core": "^1.2.7", - "cookie": "^1.0.2", - "youch-core": "^0.3.3" - } - }, - "node_modules/youch-core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", - "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", - "license": "MIT", - "dependencies": { - "@poppinss/exception": "^1.2.2", - "error-stack-parser-es": "^1.0.5" - } - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", - "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25 || ^4" - } - }, - "node_modules/zod-to-ts": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", - "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", - "peerDependencies": { - "typescript": "^4.9.4 || ^5.0.2", - "zod": "^3" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/site/package-lock.json.license b/site/package-lock.json.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/package-lock.json.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/package.json b/site/package.json index 3c99f296..a9d1ad35 100644 --- a/site/package.json +++ b/site/package.json @@ -1,41 +1,42 @@ { "dependencies": { - "@astrojs/starlight": "^0.37.6", + "@astrojs/starlight": "0.38.1", "@knitli/docs-components": "^1.1.10", - "astro": "^5.17.3" + "astro": "6.0.4" }, "devDependencies": { - "@astrojs/cloudflare": "^12.6.12", - "@astrojs/mdx": "^4.3.13", - "@astrojs/sitemap": "^3.7.0", - "wrangler": "^4.67.0", - "bun": "^1.3.9", - "typescript": "^5.9.3", - "vitest": "^4.0.18", - "@astrojs/check": "^0.9.6", + "@astrojs/check": "0.9.7", + "@astrojs/cloudflare": "13.1.1", + "@astrojs/compiler-rs": "^0.1.4", + "@astrojs/mdx": "5.0.0", + "@astrojs/sitemap": "3.7.1", "@biomejs/biome": "^2.4.3", "astro-favicons": "^3.1.5", + "bun": "^1.3.9", "lightningcss": "^1.31.1", "sharp": "^0.34.5", - "svgo": "^4.0.0", + "starlight-contextual-menu": ">=0.1.5", "starlight-heading-badges": ">=0.6.1", "starlight-llms-txt": ">=0.7.0", "starlight-scroll-to-top": ">=0.4.0", "starlight-tags": ">=0.4.0", - "starlight-contextual-menu": ">=0.1.5" + "svgo": "^4.0.1", + "typescript": "^5.9.3", + "vitest": "^4.0.18", + "wrangler": "^4.73.0" + }, + "engine": { + "node": ">=24.0.0" }, "name": "site", "scripts": { "astro": "bunx astro", - "build": "bunx astro build && cp -f src/assets/{_headers,.assetsignore} dist && cp -f src/public/_redirects dist", + "build": "bunx astro build && cp -f src/assets/{_headers,.assetsignore} dist", + "deploy": "bunx wrangler deploy", "dev": "bunx astro dev", - "preview": "bunx astro preview", - "start": "bunx astro dev", - "deploy": "bunx wrangler deploy" + "preview": "bun run build && bunx astro preview", + "start": "bunx astro dev" }, "type": "module", - "version": "0.1.0", - "engine": { - "node": ">=24.0.0" - } + "version": "0.1.1" } diff --git a/site/public/.assetsignore b/site/public/.assetsignore deleted file mode 100644 index 7bc19031..00000000 --- a/site/public/.assetsignore +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: Dedicated to the public domain by Knitli Inc. -# SPDX-License-Identifier: Unlicense - -_worker.js -_routes.json -_headers.json -_redirects.json -*.license diff --git a/site/public/ReCoco/favicon.ico b/site/public/ReCoco/favicon.ico deleted file mode 100644 index e69de29b..00000000 diff --git a/site/public/ReCoco/favicon.svg b/site/public/ReCoco/favicon.svg deleted file mode 100644 index 32ebec86..00000000 --- a/site/public/ReCoco/favicon.svg +++ /dev/null @@ -1,86 +0,0 @@ - - - knitli favicon - - - - - - - - Knitli Inc. - Knitli Inc. - © 2025 Knitli Inc. All Rights Reserved. - knitli official favicon - - - official knitli favicon - Brand Identity - Image - en - image/svg+xml - Signcraft (DesignCrowd) / SleighVisual (99Designs) - all - Design: Adam/Signcraft (DesignCrowd username), Owned: Knitli Inc. - original reference design - 2025-04-07 - 952316bb-88e4-4e75-aeec-a81e3dddc965 - knitli favicon - - - - - - - diff --git a/site/public/ReCoco/favicon.svg.license b/site/public/ReCoco/favicon.svg.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/public/ReCoco/favicon.svg.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/public/_redirects b/site/public/_redirects deleted file mode 100644 index b84fc0b8..00000000 --- a/site/public/_redirects +++ /dev/null @@ -1 +0,0 @@ -/*/ /:splat/ 301 diff --git a/site/public/recoco/.assetsignore b/site/public/recoco/.assetsignore new file mode 100644 index 00000000..a8611090 --- /dev/null +++ b/site/public/recoco/.assetsignore @@ -0,0 +1,3 @@ +_worker.js +*.license +**/*.license \ No newline at end of file diff --git a/site/public/.assetsignore.license b/site/public/recoco/.assetsignore.license similarity index 100% rename from site/public/.assetsignore.license rename to site/public/recoco/.assetsignore.license diff --git a/site/public/_headers b/site/public/recoco/_headers similarity index 100% rename from site/public/_headers rename to site/public/recoco/_headers diff --git a/site/public/_headers.license b/site/public/recoco/_headers.license similarity index 100% rename from site/public/_headers.license rename to site/public/recoco/_headers.license diff --git a/site/public/recoco/favicon.svg b/site/public/recoco/favicon.svg deleted file mode 100644 index cba5ac14..00000000 --- a/site/public/recoco/favicon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site/public/recoco/favicon.svg.license b/site/public/recoco/favicon.svg.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/public/recoco/favicon.svg.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/public/recoco/knitli-logo.svg b/site/public/recoco/knitli-logo.svg deleted file mode 100644 index 6c9cba73..00000000 --- a/site/public/recoco/knitli-logo.svg +++ /dev/null @@ -1,25 +0,0 @@ - - diff --git a/site/public/recoco/knitli-logo.svg.license b/site/public/recoco/knitli-logo.svg.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/public/recoco/knitli-logo.svg.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/public/recoco/robots.txt b/site/public/recoco/robots.txt index d4a1b340..0ad0453f 100644 --- a/site/public/recoco/robots.txt +++ b/site/public/recoco/robots.txt @@ -28,4 +28,4 @@ Content-Signal: ai-train=yes, search=yes, ai-input=yes Allow: / Disallow: /cdn-cgi/ -Sitemap: https://blog.knitli.com/sitemap-index.xml +Sitemap: https://docs.knitli.com/recoco/sitemap-index.xml diff --git a/site/public/robots.txt b/site/public/robots.txt deleted file mode 100644 index d4a1b340..00000000 --- a/site/public/robots.txt +++ /dev/null @@ -1,31 +0,0 @@ -# As a condition of accessing this website, you agree to abide by the -# following content signals: - -# (a) If a content-signal = yes, you may collect content for the -# corresponding use. -# (b) If a content-signal = no, you may not collect content for the -# corresponding use. -# (c) If the website operator does not include a content signal for a -# corresponding use, the website operator neither grants nor restricts -# permission via content signal with respect to the corresponding use. - -# The content signals and their meanings are: - -# search: building a search index and providing search results (e.g., returning -# hyperlinks and short excerpts from your website's contents). Search -# does not include providing AI-generated search summaries. -# ai-input: inputting content into one or more AI models (e.g., retrieval -# augmented generation, grounding, or other real-time taking of -# content for generative AI search answers). -# ai-train: training or fine-tuning AI models. - -# ANY RESTRICTIONS EXPRESSED VIA CONTENT SIGNALS ARE EXPRESS RESERVATIONS OF -# RIGHTS UNDER ARTICLE 4 OF THE EUROPEAN UNION DIRECTIVE 2019/790 ON COPYRIGHT -# AND RELATED RIGHTS IN THE DIGITAL SINGLE MARKET. - -User-Agent: * -Content-Signal: ai-train=yes, search=yes, ai-input=yes -Allow: / -Disallow: /cdn-cgi/ - -Sitemap: https://blog.knitli.com/sitemap-index.xml diff --git a/site/public/robots.txt.license b/site/public/robots.txt.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/public/robots.txt.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/src/assets/.assetsignore b/site/src/assets/.assetsignore deleted file mode 100644 index 4e64f763..00000000 --- a/site/src/assets/.assetsignore +++ /dev/null @@ -1 +0,0 @@ -_worker.js diff --git a/site/src/assets/.assetsignore.license b/site/src/assets/.assetsignore.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/src/assets/.assetsignore.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/src/assets/_headers b/site/src/assets/_headers deleted file mode 100644 index de3872f6..00000000 --- a/site/src/assets/_headers +++ /dev/null @@ -1,10 +0,0 @@ -# Default headers for all pages -/* - X-Frame-Options: DENY - X-Content-Type-Options: nosniff - Referrer-Policy: strict-origin-when-cross-origin - Permissions-Policy: accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=() - -# Allow Cloudflare Web Analytics beacon -/ - Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' static.cloudflareinsights.com; connect-src 'self' cloudflareinsights.com *.cloudflareinsights.com; img-src 'self' data: avatars.githubusercontent.com ui-avatars.com; style-src 'self' 'unsafe-inline' fonts.googleapis.com; font-src 'self' fonts.gstatic.com; frame-ancestors 'none' diff --git a/site/src/assets/_headers.license b/site/src/assets/_headers.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/src/assets/_headers.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/src/assets/headline_logo.webp b/site/src/assets/headline_logo.webp deleted file mode 120000 index 8428fee0..00000000 --- a/site/src/assets/headline_logo.webp +++ /dev/null @@ -1 +0,0 @@ -../layouts/src/assets/logos/headline_logo.webp \ No newline at end of file diff --git a/site/src/assets/headline_logo_dark.webp b/site/src/assets/headline_logo_dark.webp deleted file mode 120000 index 46c2d024..00000000 --- a/site/src/assets/headline_logo_dark.webp +++ /dev/null @@ -1 +0,0 @@ -../layouts/src/assets/logos/headline_logo_dark.webp \ No newline at end of file diff --git a/site/src/assets/houston.webp b/site/src/assets/houston.webp deleted file mode 100644 index 930c164974ad8eb528878f15a98016249b8cf546..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98506 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 b6~t;_wBcJ3AWgga7~Sz~izoKbpAY~5r|m$8 diff --git a/site/src/assets/houston.webp.license b/site/src/assets/houston.webp.license deleted file mode 100644 index 29afcddf..00000000 --- a/site/src/assets/houston.webp.license +++ /dev/null @@ -1,3 +0,0 @@ -SPDX-FileCopyrightText: 2026 Knitli Inc. - -SPDX-License-Identifier: Apache-2.0 diff --git a/site/src/assets/recoco-med.webp b/site/src/assets/recoco-med.webp deleted file mode 120000 index af513049..00000000 --- a/site/src/assets/recoco-med.webp +++ /dev/null @@ -1 +0,0 @@ -../layouts/src/assets/logos/recoco-med.webp \ No newline at end of file diff --git a/site/src/assets/recoco-sm.webp b/site/src/assets/recoco-sm.webp deleted file mode 120000 index 495c4a35..00000000 --- a/site/src/assets/recoco-sm.webp +++ /dev/null @@ -1 +0,0 @@ -../layouts/src/assets/logos/recoco-sm.webp \ No newline at end of file diff --git a/site/src/assets/recoco-xl.webp b/site/src/assets/recoco-xl.webp deleted file mode 120000 index d661d21e..00000000 --- a/site/src/assets/recoco-xl.webp +++ /dev/null @@ -1 +0,0 @@ -../layouts/src/assets/logos/recoco-xl.webp \ No newline at end of file diff --git a/site/src/assets/recoco.webp b/site/src/assets/recoco.webp deleted file mode 100755 index 7125d7605b2433f288bf513ace1912a59f409679..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176906 zcmeEtg;$%+6K)bLXoEWhmqMYq6DaQP#i6*nyA{_WMbqL^+-ad$(c(^#;!@n<=KI~h z;+}JpH|ONM*?0EY-I>|hnI{_ZGBThB5I|R2QcXuqKo0`|06-9*7qtH_2_-eTU~eD* z7gr&XUNDuOM55Sj<@sd;N=i!VUyS=y0C+rI_(h{vAfL+prxI^z`}5I1ee4hyZHDsk zzeu))00TJkyX8T3rjUq!JJ~wXb5b}!KE@2M8?;Or^}&TOL?I+Bo&HOkNSGsiyDAW- zFzdNkh$n)x%(9?VERi_5B&Bf`^TZ@iuY-q`cFV0Kizn%ZMv|J2450rGs2O>dTfkOB z@9gi30+=qZo3?1kX{<~PEL`gn5XBN)V4a$w^7Z^F$U)9aO^N-DJ&_lQK$x_7YA;-xsLi*M}2&HC{e)4_hu&6TvwUY@9>S+*(9oOuT|6- zXXMc+Z(AaMb1zW+No-5uQm2#&29yoD$lstpS|ste;R~9}gn>Nk80|SRTFiUgU$M!N zxP@a)Z8`DcUcXD#H2RKak^1?WkC{vH7DJcj^AReR0HzhlFoM!+!JI=(9^%M%RM*mw zPx?ytkEk>^1O%+aENt1v*IV-A>?ChdSK4RHmY$y=~BW|7}>0U zXI4lLw&>5746?H>wT@=8nyz@dmO?3nNdY3aJSo6&y=L%!1VLH`I1?pRytN6$W~ z7=)aw8lybFPq=VRw*WXNMBECgJzSgs^Z>W@X$gmjP3eJY|=VmXW7-1TM>C{UM>xX2pIa zb0DYr{tww9O+&Tq$VvkX(7gDE-f}_V-1EJ0+7KTgdHd8mJ-0%J-Q~S+rc|m!l22-k z0}p3DYFaZe*%CmtMO1pmCAcYgQv0ZaE1&!AgRpEJcM3aaG2Lg=g_R{by3Hz@26Xhl za^g7a5As4OpO=uuX4aked)i+{?HPw05mrST`J$rheYO7}^AmZ`WbdYh>)o$2pnHZ^ z%zc~)vf6h>|A&zAjDwPK0N$89-e)66L%i;6`cL`v!x;Ac3qtfwU=Mk~a<-#A@0tK1 zj7gKoAZ>UweOddpJQIfLv7<$Wzp`&NRbP9E@!LI&9npp4vgSLv>1O%Tf3o#WS8c!j zQyre?jPe{C-q=oaBcI+pJgvPuFB1iota8p(yw}m0t*Am~;_8?^(uG_KQ7uObmtVDO+(EYfMA* zW1-II_o^nu&#cxq*L#sVQc8ez>t#Oq`r}DbGMKXsl>N?=t+@V!x3smi@`U*cUK5%j zomeavuX&X~A#pVo9I1e+(cG+&PUFZ5)bw55WIqO2;W%(+KC|^Bn*Br;-r5v-8L~N` z_q&j|_BrRbF;BBhih+47IW9gY(0Jt~i+wqjp)1SteNpPH=lhbMi#bxUhxv%F^N5Q< zZ^Xgb(0-|X_t^1G;BUptX)9SI6dW(h>eh2(5^Uwny;@UQB%#Y_B}~z1DhIO8e+*>p zY&-^>gfj-Nf7x>CJQgEy_c)?=Ur`Dz=ZqG;OZzq-&hX)PM3HIvVz{O3Kry=Fz?)0h zJ2WckpU6ITO~-y!i_OeR&mPAyJujg2lEWa?a= zB>wmnl8~`!#P;UQe(ayo%!O#wD5HkU%!m_cTBl$T6saf1p#NERSmu?lr+gvIe}$(k zASfe*8>~HX5dSMaeiZ1GFojgnLmb|0-hs=Ci_>`^6JrR^WX3NGq;o<7cNX3oLi`NB z)pg#E`M|EYLzkeP;CPu=pv#TReY1WU|1%5Q%Rl{iu`!=QUf6P9_+Ol#*B^WCf-hcn zUdCSj|Be5b=i}wo_LHp9*~@M9eb{THC!GLbFb6Q^g{f%WkE2iq!hHF{CFyPDQ>+>a zIuIAK1Kj(6vMTC$J34cZ47Pig{d<}8B+jJ7CAFu51>Oq)QOwAVh==~Az6j=K8L{3{ zQNl;{JWQjG$;-M|6|=q!_7of?YDe0d-YC@2?0n&V-Vc2~eJOo;KgE19+9-wsqMdSk zYzVgQedc(DqKjxs{w{!v!qfMqD2yQ*3BK5OMMy%qDbigLNN)f~!cG zw*2x;&D8JklW5ge0=8T7Rx_}Ic5PfQ&NF_Im$u>?FJM)jW~W~^QcPLhhgW*0#UL;b zlWuewE9TYj_qap&XTwP#2OY56Saw*fy^dLcO~^?UApF)x6t@6w&>s==MF#uL1S%1X z7pSefzz3aNg-~}$1XNT^KD^|ReUqAE99);y)8*okur33y!ia;4z2pq{_&U?=M_v!i45b`MzW{K5o$v_c5}5G|X1!s?!G!%#k8Z7KDe} z#Wp_Iu9YN+xhwhVi)cq=zj3E*5Nfy+p>;sTG93V1epr|E#L~!1dYkm2fedqED;3M3 z#)9&T{Kl61x5a$26s5}f7Y(?k_?yuDew-zWI4GX(Puk%69hS*}*qMQ?Z9iV|bdepkh7Fh{^3N{16Q zkq2@K>56_OBft8VR`~9%M!aNpMz+S4N@#TkBFi zc`CT%W2`wGwI~rd=x?__KM!V`wrziO=6Ii!=B+Oi0SkeCnki64!kY0HC*FTG@Droa z(GW9cvsb}4xl{G&{MOCaw^NBVs|rHP6Z&6M<#&wy?)tteRYon204qx(6k;6(;hT}m zTg1!Fb_~vr84eCb;63P?5LYb-MOSl0m#Yf!v9Kr2MnP#SSZ))~@AeH?F)%dDiT9AB zkpd%!h2ZQxjeQX5c%E$E6~5BX3f<;vljp7q*dFjgBa=SaN7#2n0E3WV%L@mSag{eGHwK24%}sXNf2Eq);=#vk zv|jfSYfUSQ?67=x@c^Ze5L1H!7t++cv5Z_N@{oz*A^$|#YJFk*%0Yt+85KhWE==LuoP*y{q=XbX|9 zd1YZ67=H*U%po!|GN>)UOe-7vP*tqfgtI{M=7{O~b_W)ENw5@P55H0$e~HeN(~%^3 zNGCD6WyQb|JL$K1UKS~x3$f708fgecOYK__cnwg?we}0wUW#nh-h+h96k<(6BYCWE zhUK*0GLks0t!=xJ`b`Q<1A-OkmLvJM2!G<^l(R$tJhV6*xr(EG|LyTI#vV5W)UJmt z5PhvJO@RvP6#5C`Svzt4=;Kk)Ku4e$u11H9+6zNnKa6x9DXwTU(5~EpQ`G-osT%09 zK+1sW|AhWh6qz_ua6J{jV8wn7a3xv=AfX-E#|mIUBz4zV=UThZn0p4VKm8UJ-`VP` z0t`!H#ckga&s}kWhgJCb*XO;Q?Fse0q9P<>0GH?)X6jyp<27c9WTfu@Dq_CYxmqwm@-QT9wvJ`3jQhNC07BlWq|)lz~$p=!{6 z*w?JX40odXwGv11DHwD?IV3^+5#0z7k-$n-^We9>`%fWIplGO`~i)=Uia{;oUE{Cy@hb+cK~J^?<9BU+-wR zd~(>8p>kE&rvH`SMc@6hNzxSA4QwfyFy=3~-t)Zt@GyUOX10vb9dPnvCjyv}AQi&u zYp8jhJd`;a-XtzH00YtJ?{tU zdI?gWmdAmwyvCq^D|EVUxOesA4m}~51u*Z)j2w!ioJzcr)JDAs!@!E#63oecWz$ne zPVjaiBYtdRb2^VrVoUz6%BSTF%a?(-h}IIB)Vph0e-++yxf=<-GZFKb45=Z;V#H5r zZQL%WcRs(@nqZ+9u7HfW-G`sVlb#$}#-`(t9 zbxIMHR+3EKUABF+7x#ir=&DD~6vJ0`wo2NdD$b{GIRCGR0|z>V^N?}l{jWLxHNZO8 z2sBv!;FVy(#Du*ik)Vj*%Vl}rF`!rrulz5e@6J+!W@qBi8WbxG3wc{EzulZ1PEl5G zIN1KznipXW7NQ|XyN68$6XOAS2YD98x9~Q)P~^#n405F$33HSg%_5*v-g6}Gkd@uJ z+Mge_T9OrCyheIP2v4(f%z6jZsV9X$)Zpqa>(3~CxJ#E`i4T9@CuiyY$-s$SYLDlG zAEp^H=?pT4wrx6a_$J;|$y0e8>afqRxGSfje^fok^I*sEJ<*e7D_}yIEJ}DA)jAi>w3D}6RIx;5zkISB zIGxi)^m^mBW38%x?G%d&szfHPM%p1wLRDt2C%K=RS&D#Bz|_Pjpk8Sg-|F4>NmmN8 zVc>QXsmR$U_lVl2CY@#7)#ZvNtL*6L!syevYW%%z#_%C7JUcg0dO{66$*4+l}@jx)=U=^LpBIrIk0@n?U>m~}P zkVLG-<7lP?F~7GTEO}wgAZj2s0N%&_*#h32u5i!*umX;@i7<;nBS+ z^t9{TVp!O^F84L?<*H@fAlGQi9Y^yFOf-J6{z3R%3zv&bU0ZaW;Jf3M1 z9uO;13!_jU4St_q=v}F5r)pk*D-y`H_%OAR74T5a z@!`!!ERY0Xk5Xk11Wwg_J#eKlBa+Xm`b#y1>Ep!WYY*7u*wY}H>FM_%t3Ppp8t|-&$VV& zc6&N*B6D{?o9a^BW^ffNuA9?SR3-(E=kFjMS=pZyRtRZz*7Mk#1hxP4q!Kt#FA{rc zO8QXRS4;)i6jd9u+0vJ9tDkpTTgqb-%Y6Wu3g6%Gi5Vq5BzW;O9LE)RiOU{z8zaX0nmXFvEHNgNYDko<0OE_{LOvYPa^r z`(m}qzZNmSRboiJlI5L0PVf(g*7FDVj8=j2tnX^hvEFj*+V75r3EW~b5EuxZo|;UX z_)G;5AkbVB!tgLqHYZQ8LHY%L99Bb&Ro*!;zJE(&qt^#cIH;xp4C%>XJOc|<&1b6# z?r3p_ouC#FLDXp7~E0>+-u={>c9NC8e=;8lJEIKlASyIRe_@4;X znwAie1Wo~}VpN+^q{Qcs;}ICBm&kk7@!bva;DZX!twW{_xRauKJyZB$^QC;jZ}eqwh)A*7t9ot$EkZRp&;h%0Y3gy2PFyf-f$ba=K9zIGOovVW1jG8SFIj!C&NjLSZJ=SF|- zX7aF@r(D2id0x{Bo}tx;wZp!f`K&c;eojbC-=8wW)73n>Ykg=86550LJB>oE0g`2s zu+gkt-lx`D#|DP8En)~7PP>VPCa6&te~+`$Gk8B)!3o8=>BQmTrb~AafCM=;s?IeV z|4<~LgtlX9;sDe7a-OUan{HFr&54>xRUPPPg(4m#5mPeolw<8?c65cjH)R-R8c62PgRi2=Fm#gtW+>O3&)RufRQ?6 z`{1ndHipX|(I>NKsZ6LQb}y#yP<+W;wSP6;Jr}ySB%T4sMk$Zdn4mB)UMuO&LRJnq zL#sGOauf3^CrD&Y=lL^rCzL)CFnT%-;OEXFx3ZvSLdd%BF1R^W4ZimaS~ZiWOGxhY z-7EJJ-jUt>yaL?9=Lms;Q6xXLWeZ+MqOznn!z{bi&@!o;npvN2@e~v^TJ?K$>9peF zs&3R1JZ~63s?@Y;w;X&Bm7&9?J%u0k8PKEgqg}jP>p8O}CJ8nA$~ZDSm7O>G<5q)M zK|ZDM$30iJmR8&LWRen5%}@~mmD5@p!JZfvjW54AVS-)N(Y@vGVcr(vksf!p3Bq?I ziA@>5PIVQ0#omJxm(N=8ytdO25u6|-`Q4#>^VK!aD7(?M)%A|{ZN0Ma6qmRgZnhLb zb{uI_7QL(ZSN*fiR4R-PaeWWB&ubs-Ys;H6&)=P^F&GANsfgTqDl+;*_U%I1Wb;xfv zLYirQ->GRi-_N$E)kEIyPr^xg)o%QCPRJj3EyNiFrp(y;&f?3*Q9<$UR-=d-*XJEV1e-xhZIH4rjbl<4^z z6Xa0dHBVQM4_fQBcE@93VKvY>8<_}A$La^^K_i*I;0ku~f8dvg+!zC#iUE8L`h4ju z^R9C9LlDDrC0_5+9*@0aVmkwQ+#1HjojAkvbod@i40y!o+d~qc z)iFc9?x81alb^aFI6ov`&SC(O3a^I)xV}B&t)!8Hw0I^QQPWv`VsJgALp#}Dvq~(L zeW}fI@EjBgYRp2b28V)NBr^^3-*@vUczB=rvedzFkOdTnofH~tPR5(m<>#ZFW(kO_CWT7F z32rh$8G(EaLuZqAOFwP08C_7Kss5<%vN0%tBU5ih2p~fe%2egi3as))nPb&G+e>ub zn%H07TxY(W%u3pbvY1^Njelm~3pBh}DWr}7#HQ=$-7M};x($9m{Q}r310daKC}i_A z^L3PqX{9-M;DeQ5YN0V?BlYyOtfHO1=i>HWEX*`HQ2d2ZPPdX=SyuUB8H~x@kPui1 z8Lekf3YEy;ys^dQ@w~-$?$CcJ72pgc_|mmj88)o|cktXMAji*_@Jo3;);$14l~rHd4J2ELS(=FIldsiQ{FDkt~k&z?;LD>m>2# zS6hOm1QwoUMP*T9l4_x*+}U7Vz?(2{eqYnptK$c~j8OK^#6LtnZw8EsZT8 zC6!JkMTTE>dnzLXOgacRO&S^^HOrgOIOO!+zqZx49}s^~Z`^fVP`hpt{2XxqeBS7N zh-t5X_Yh$C3wx5P9&{8^%v5U3f!p0F@O1a zA$~WJ8T7-XJK$yPW_pIQjUpQc*xVW%$cREB*&FI0-?sB{aLu?=6sT8?`)^AdN{ejg zQD{RRTYWrB$?@(J;Hi4ZLj-YM&-;gWoj0o#6z<&)R%Vo5%M+>yt>EmL0kEuaO+)Z{ zg3OS?SVjxc=v>$$U(0q@4FfOrQ#JUv@-bNYua`|;oV&N({CpqXvN2BFEF~S@I<-2v zCz3_`aZr7FKOvePJmFGFO7}QT6Awi~nN{Gjibe~pc{FXo*PZcSF?=K3Db(HNT? zu9bKn?pOzG{GzpxS--i^td-dvSr72dWyf55+&QM5bH*c)RgM`28DvkeS15COOX0&@$O6 z8`4O1WvVV!?9N8!Td_zGViDv*{}!cdr06^Go_2{wdiNoeA#=CnY(a>zf6{tYXeY`H z=USQ$GrHpb(qrw$xaaYEwzicb4az;?Fzve`WFI>6F{{(+-v*YY(z^afNhi}cu;=eZ ztD3m5NzD+KEG3W`V2MPIG-SAOe)E;9{@P8%84Cf#QVk!BzigAs^e;+Ozts974ydPn zvo~wcZ@)M#Hy`RbijCCw2?hf25R!>e!i3D|CfAZXRnXfW2bK^Nj3Z~DtCh? ztE(0|9W!TLlIwkVv{7QLJeKFr{#kP@l};9n1bL`w;ZDpMU72c!vsF6PyDT0v#w1(X zZOg6k@DTKCOiWu}@s;}jr~gX{s~w~=MsNN~Tt<+iMj;JkRbxqgc$uDeUlnHR4QTXN zWVzKIp~a^vAJQswH+VJZvz{<#;Ps*D>l!ts*Tq~5J^qb8M%j-DC9qk@g7?{p1fNSz zZZY$3DnqBm)_qV1VkeDBmjAt|fW_j%I_sayovXVwStmLnJL=b;G9{PmrO}Fog~r+K zVwGaMbU1x;anm)AFX5NB)Sg+L40;l>OhH$b*U7)ye0{iYPfgtBeN8@WOh(8Au7UDCQX*<8F#9-d^+)j!*C6;(a>jir>`|U9N6?iO&0L%Z?VO#U>3h^2-Pt(0?6UZP07HJl|jJuI=Z6(5QkM zkAs|T2Ww@BYII0?tmSc5tDcVwF}I#jvr+YUNiTw^J#&@DzZxgxD79#lGCCq4cK!3N)c3_{L|hrEo>Im+q0zg*}d zE76TY&-&SV@m1G*3MRVvRHEaW0v%@~;jkB%`k}^InQtZ=$I#Ozi_TN1>^6~d8sXtv zT~0GD+{Ke7ANy}FAW1NuB+w62Gp$stVq(C6opCmF2i)j}uz7b!Mn>W!EWEQr z`1+sJkBV!NRr^}w{uuQdDb*o@KeU|P=~f%eaZdqHK|%XE*-YUc{sE5m`kV8tPz75< z%dP(Yj~&@ZqPzz7%D*EU9a>$ySlBqPhiD%wi_d z*&m~jyvWg6Y?p%`4wJDCyUqzt2w!u)?k}tPe7|u2W{E*&sSs^=*3u1SAgc+g^?b`; zJ8ie4B`~xh8|Zk0dii_^W=c`OtMJ^Br69wJ=t)8h8}(d`O(?n#qV2R2&Jv{tk)&5( zPSDbjmyB??!5A@Z_GTiMKHcF#Bg0v!4yRot5f6HZeo@z~U0p#qGxbk|aoQ~+)MNgK z5!K&~ZU!^9_DyzQFYMDpmE;}t9M>915oDf!KGfSW zSU*c7Fz+mzrU=^1scK+1Mp#AAWI2tgckPMCX6Z#Ruz6JcO4aGL<(PZC9*5RV6cS zMko+kCt+e{uUZ)tyI#;wrQJy$-dkrol*0lEMv?JZi(V1znG9xt2P*Yu@Qxh+BQF#G#0p6*DIUhs3Nc!#S3h2A(KkHWgB@$VHo-6F3ZUx%() z(r+EG(kZG`#JRy2`Pa0<$$k#!9@pyF!1j45nIRhb)T6=cX=Z} z24En|$CB>y_JfG?JUk8LB5m<;7KaUZAB`@{H%h&C_xns1Eh#L=N7hUNb;V&mNX)yI zGc;p|Ib~P#fJme8K@o(>g^Zz3x^*`3{O|G5j9eZCjDrtVpwGzI_7{EGFL*w20FvSg zelTcUiMjqA%ZbC=9K9QTD3_xZPlR1rZHs`zk2W1cb2vAK-AD2LmNqL?E#}f*F>=~M z=)&0WjaA7XY7Nx-?N?T{8%`cAi@{BKN~X?q@k0>g#N*w-bwQ)FnM|tmoe|B0)LZxi z*AoaR6$Oba#$^tATxe#OLC2Z?QB+um7jn~Ha6{~Up%Vt>=aLvnu%XTZXJ?PbYYdQ; zl#yBPdCWV#pKWjRRU4S%of%u<90hJ+8nep=>z#2%VI0Ca<@B3sZgwi99+5sWQqNT0 zm00keI><=+{IfQTpx~AI)OOmnbX2E@ukiC!zq>#_baQ&6;LoWs^*zW=0OM7)BBfQM zc5wV#8N9zko81&u^UF2o-LxSq=xlP$Evf9hT zy!;F@>95DqJhA!^fW+!?HCP`QRniO$JDf8T(Vvha=;uz^;8uZE1?;&sE3aWy?f4q+&c0dKne<}SC>3=bDRouHdw*O}g6Fk^) zNB@T5{TmG4k2VQPALn4yN#MG*L*H6dW1?7nj;pMs>7>;u zwzvT^8V5@z6RI7qo%l(}0c#gm(3iD41@LnN_p$gBAEVkrl z4`@z6a^Caa?Z<3q#uT=}&^jm*O%n6H2dIM z*PV9>*f3$2c&d%^PdaQUGSe8DjWlg)< z@TOS@9RlT~4bKsg{E{escV)l4`FW0QO@ZErLNde&#rt~x0^nW8xvQ8D6e$`0*j`8n zI0k^iYy(}8Xv=0vCxLx;sY^WIj&QW24so1 zFV{)N@JAt3IyFx8VrwwT@wNII&?XB^Tpbl=sD4cZ4PF5i=$!!b0gQ!%qaP{H&SMe* zxP_F+P%z`ww}hCO#;W!Nm!p)dB|lWX6__lQ;NQt#_SF<)WBw%AXJ=8+tJC1aq~J%} zRWcq^@ny|}Ot*M0yr|@Ibi^JJtHvHpBI<`%I#N;L@0$sN1*aybz#)j^;7WBfp#s%5 zKr)d`Qr=cd=aGa?zVjld-yNq9Wv?WyD-v)ns|-fcNwe*haUxOrXO4!97pQ_YgMtAB zgMbKLPkE9pZ=uF?s(vsyuWM<|EjO(n8(Wsv?U%juwu?1)X_H#WrUe9waP}A8&$st> z85r4Xm8aI_@LPsad@f$#8_<>(GaY=}w$!DV0-m>MAUYNDvp^#R8auQ2w(2zH9l9%t z8<_shIrHAlbdZPu9v87~=zRik6-v?-B)>9#mp0AA>BId-E82`xmG%=pFgK?IeV(D=?f3Ih$lJmV z_Gs5|LqYHce3=LA3~eWuw|L8w*D#a)HZ6z?VP2r0c>l@)1>T$PS{M7%PNvs&=s9g# zpF?LN0X&ICZl4=J_f3A&qjEY7&A7XdQ7aR>V zV8IBa2d2JMzr372p4rxFF{5!WlSpF^&mgyg|WLW5!f zMR0;{f8KU}3l9eTO-^4aT$cBJ_4=oozd&>Tv{y-rA(9Zb#>Of*G8)~WT$u2yAWu^Z zVJz(2I%T6t35~2zlw?~Z6+Qyh<58NK4w05p;85to>|ou32F+Az*8KcUyXM2FqY4qf zc&`Lio3ztnj_7qX?hjcOsBOIXi*WF662~flfNpr2go{20Kpg7orZpm^QA%DqBJrz2 zr&=Bt8ssZir1z>eSKFVB@Q{ig0tLyjWwN}KHGGaTP8(41T_>2xC9>kD*JJ9cKht- z5xiJ}s1nj)qxo*j2|!*1LQ9QQQ?>hRP@w(QqGMUniPs&8&M6Oo zLYo+FM|#WY^(hgBIF)29hFM?zvfi+@EL&ovJknJ}2&R z%*yUX;tF+5O$Wj$%)N+9M-fY1t*wt6dh3K+NY64Fc+LAGBIb=6^OS-oouE!>SECVk z+LZ*sdpD*2=R@(Tt5Hl|QqcrR;3 zg@NJeVc(T@#+yhs%m1tgtrk`;$AXLfm$90E;HB zO?--mU?`m0v8$zhDC|$QG`@o9zC&d_Sqf44^o&ld!!7@zy*gcLZQ{sw<_5n4YFlMm3$;i zU;Ao$e7t&#dY6bO>6*5kY`@_t2vm#CzR|&-O#MGhw@coKQOnp6l28h@H1tUG;myJ8 zt-dMqSO4_?^o7K(MHoiGL-B?hrolUbFQVu3bg4X0jLaaMKAbLe+~er zbz0A`m)VO`I6{Wvr)*!&h2|_fn12ej$m2qye{BK($Xu0%nr!2EY|pOG64s*a!+d47 z>ZZ)y`wB{o+n^@~r`+OijzgX-4=1GZOm1eh>_i5v9{-RIkjqVq< zP!#&L8^45ACtXKx8v@IqxpxI}TGR4&<)byYp;(2#z;(_wUWw~6x@d$k*mSJl$m!d9pd|n(fC;9l^0oNf<&Z%t3;8#%Z*Dve&CQnyr=u z5%EuTk^XKU#((KLkYsArPj1NK%D_9) zA_M~R`3I7z0k3Esi27kGa>h5Wb|%dRb1+tgOGF?y;ZgD>QA<0aJY$%`QE!o4{!%{n zck2t7*`Ea#B!~iwXgcH=nMMqCFEoS=vq=`@#lqF0x4e` z9B-cs9*0qJ=o+rYxIMUn)~jR!K` zM#?M=TNkV%??86IN4ceDP@L&wG}bRSCoF|{{7mlx>8oUGOxITEf5)eN2q7TLB8cr3 z3dO>!uKqknYcqbv_%^-$YU$hvtZdiX^HT(I3z6HVYUb>&hPH)xu|P6~p6-&41!92@(N^eds^ z6Y=|Bx1a8IS&*EvvLz#8cBxc0QI1|qW5HTGkBJPdw0_waW*4Z0<+s!YBX27dve;R7 zJq@W*L960oxASCev=LNnS-Euz(jY+JegG}G8Wq*oLFb-8CBia(1|(due>>Gkyty0l zKmjIYYII7Xrs-I<)+tjbuI-{phOmn~?ujc#Jtb4uX#M0qYafbY)JKuy;YAEBUOGDt0ZOvh*tM%fD zG<$9xBy0WU&*Qd;4eaL+d}C`UvIZb)%oEVCX;n%U$6vHIg3YhM4F|7drv{5oO>1yVmnrF7z9VV=4ngk;I4uiUmY)0-^}i@4ZrHthG+( z%1_$94oCFMuIaT6pOyi$NoanwbAQL+k*mtzeape-sg>3;Pnv{(!AV~P2z*U{RCoF? z?WB{SYL0+1*mKDgd?9{caLe(uLiuy7(kj*9YYWcKw+`F)qMR!EAdM8b*10W%S$^>S zp~<}Y;`Nwc^)%Im(MnuK_bGyp4S`5PB&Cc3p294hj(m8j{>Lax>aJe7^_~eCGLWwl zZfuhb|CzTd)YEUEf%8FZY~-WvU)1o-KA)SV?vAY5!qm_m9cddOB z4#*++$@h7&!*h#1M=qrpCR`1e7@0T~_YP3qx@%c)rhYZwe{7qnj4X%)O;^VDjhLdP z(n+oy=<|&DMeEvntMv?)+Ej)uS07`4w>_wouIl8vlrr2tQeHC%zh+Mc6RYDf_<5e* zY0|_F34V$BpTTO3&S9!O1U)|oq9F~cKtt$N>av2`j>R9G;=d*A9=_AxpZiqpJ5of! z*o*!bHYTn1Z{(}x<<73XLZmcEFF+%hC*8bA@L>^-+bg*3YoHPLu?j_2&?q z)FZUj&T$dvu4ddJBgJ7{EriRaL(>06lXDtkhG3;kuXR}Di6BKV=UJL|UuDU1vwS&} zensyz*yh(e)<*!+ACgC$5*;(L&hn6USH5Qdq6M;vwe>`Yefjw07$TckHH1N{Xq3@) z-<8*`nI1SU4{g&rtY2GB;*(}2CS*zx5*Q-SThWzgoF4DgX#VPfyH0Si!~Mf`+JdgU=p8`_=%jB~GZC1{rK~Tc{5X zip(%|^`E1d)(wF`$okmf6}z)8%aw+XZHyuPrT5OXREYAt4fGZ5Zr*%cdgiWd!8AqE z9NC^B6)sdGcKbLsdv~+>1~oN(<;yC%EYWNId?(nkmso*6$)7yQ40sU%n@Wvpp*s)o z_}H3U z!vB(8-MsQ2h4;Dkl2!t6*bR#ahi227M_w6xaJE+Y%5wWv7rEa4d?DMnW?8khQwa2} zk_!?FH9Rz3Fupml9%s>ls1K0Ps5D&+ZSv_X$qRztr@fq@X*l`kS~vaWV`6ifZ#o9P z0HJsW`2LhQy=i(IYln*K4ZNirVSvC~IuL@x>12FI(B78YA#d6ND*J)K$#1ncd)9=KpsJI9xsqGff_aA_SW^SpLMSV&!1dFX+m5ekcRB9%Sy{~czEk87%+ynRS%;X%f=@I^kzrh zWct|Ih9e2aH(3|P!l(=K$hez_n>n^k-+&W|2w`Po7F_x(OST1i`4@Qh<|KVT=nSv_ z4Ln|n)X+r=)HvG!7#Pykj@c(XM`(y8kBYGLS?gp^*ex2wk2@^> zMPz!eKcQA%`-v4`BW-Ql!a}6(etpkjan=5`V*IOQFptgYEaPVo^?LpqDl!EkhlDsy z)S86j;o%|gk(27TDt&wM3!-`zY1mmU*8Jw4g`I`TTRzH*5zDe@`%g8}r`-5-TcN;F z%&^+zG_gwcDmJ{j)>++aQ9Ps$fDZbXZ;lhMEZ}%WfHU@L0~}G2m!&8j^Hqaen-eA$ z>0j!U!;p?DMmPEvC;OfKvHFZ;8Wngw@;$~6`2QS0_wllL3l27$T;YhP!-U1M3_3bJ zc(Ua!SL*%smT!75`ufDVX|1#M zSoiwnl?6pki7nxm^eH}>;)qmGth2e*MhtULev2z`&M~7hN%=kBAlFw*Z4z_ua2KhL zMwgOluAQ+Wo(Qy3HCgMOfX{idL@h6ne?I{nA=<_9>5E!N8wMwL zUvE%zCo^TYXa7h#Uc!yNT7DNPRu(VysZrNB3(7c z_G8<&kt7Kepl@5k5wX(q7*TF9pqQ-m_Y`%kU~JWn1k`M#o>XR=xza2fZbgk8fb2~= zVy6hhW!1Q|ydY6RV>~}^e|Xj?DG09N9NL~!T8VXwA)iODxdOpn%2H0|Qyp@1 z%ph_y0q9L{mQD&{YQ`PtlG50I{dj(UW+X`h1?ZanTeGX_*J zs#V*l1X%I}u{(#B4NC%0!-04QKqrJ3?>sGFDazQMpMU&%_$`$b1jqetMHWcphZN;@ zo5R>zE!fYHheTJ+6Kbh=@~t9F1n;g0(5bY93?Vc-38YP4Ry8!`&Vv7K6AW}|k#@=(Dse^*`@YKA? zAp{@-gn?U9NSqqGBw*cXI=)KivW@Zlyrof6C=iR^Pi26xBv;{9FS2S*OVE=kL`5M& zA3+eENO;<2LJ%O5+iqR~N>jdo<(zv2jtGGudC+SgO5)@gg2CPA1qqa{x|^MuqEqonh%IW6t3 zKuRbCA*^?Pjbo0T5JVE_&ePGfO6am}&(GU4Wu$P&-%wKM3Rye9twItf7ccmX2uCo1W>pOy*MoCS{}A- zyFQGRGA#G_d&!|Rh9cc|YfE#wuW$DdRKzYCKRcV5VAtu&wu`(KL7erl%!JvB!_Bup^m1d&}IAeyd8EJ*3NIIQlyd+kXW}_ zTS;?T-)f|Q(1%@98v!0rv6!s}qRaN$AA6pQqa{WvBQFq8ODG9(X#3CafA^pGp@$?0 zbTTjl+hN|7IxOj0F5C0NbLvMlzo7i(pc(9+vP8_ z=ec-uDkDh&kcorMzxk^_`R&(`k~k4|4!w4FzW)E-A00>w(o*Ph-JXB^y1#dq zJJ#QixMDLoSu;*=t>?J_=IRMZDL;4tS|xGp(E9%Uw?FyI zXQcq02mqt+`?-3jGr#J6`3;A)lE%ZYANPOEP8H<0Q-zYa%@f8XLGrZ<$gqCA>qmom z_EnNvUwJNoxq7ZSi0OGbVhFwc1=QEW`JGKt+xP6@YJ zS&`J!Trk)4S$oJH;=-DVcTIhP0zfAO=;rn5{Q9)p{F=8JK+Xr#0#*q{@1~^`Sig~g zg4;Y9dG!90##$?wQ7w}21nW&TfO+&82V1NHFjsGnW|l|tm4~HyWF4D8>R^5EdpEGt zfB?*T-S_I9&ity^3Q^-v52eEd$F$>C63*4AP45PhNogwOtYu9?f`Nts%u3eaag07_0q_f z92~B9>U4kI&wK9}U?&1_N0?dXE?^EK4yWUrAQ}Chp#awJ9s+dmDHQpVLL_Vkv(?Kp zyXa#RUdMz&snar0vw36diO9`)ueI;{)A`jfa88C6bPS;01%TkNUJzJm_v{WsL4Fez z*llMlD3-!gHLoQjcCoF9_7GOn>A6JbsCjfNHfm9{X72~v&p*%m-oZE_Ix_E_yMZYI z5eL+pjqaXyQ|0d>PH?MNVr+T!q%lF%pCy@V_H<*=MxUD&O9|1k0kyD)+n@xFmCAaD z3Dfrd{Q6WeH%^LX2IhAIfDzC^we73u*)fx6`nyLkLbn;_UK zeMd3IwImYnv8wNUx7`e!)1sON9QqjnAb#Ti31b&DxG6T%3J?*IBBDkF5T9jiH;Uv2 zzH@E$aV#VAoKm}qwGokO)MQ;mrbb1@oE?A zIPbl?87IWfwCfmX+c z0HPln&(0d3b(2gRcVIl8o*B$H?XrDuP~56fk4sJ^1)qBg5XR28)kk}nEvnaSiFOm| zOwMTmVUU+&R_fMQ8`KF-dKu2Jh-CJ>NQ zU7{j6H``XkDAfopS*0Wu0P}q}h;2((a(b7!dg}fHI(O^FX;FX%gM*bldAV+qf(G}m zCo;eR>;QM5L2@DJ{?DrAQHp zkc6P!z^2bwBv|S=#L?RKZWNUI2y5XmnFF*dJ=`sZnpI-R6x1%?|0Z1MxEh&MC8X$9j=xTi22CN{)S!0d7+Ne|xz#edHXJ>GVx9J%ee>(z{NC4JE_|+OApG>rX*yeBSDW0s9ND}+SH^ke z*&Jv$06CWYMu^P}>Qj;9v=3+-TYVgT9z{;o79oz-Zs&bZkV?W}z1>_ruf8`*WDKxV z!hC0pA=dHa;0`pV#Two4cK+tO|K{)f(Rbf|zJW0J>GJY;IjcGCh8j3XrC(G$r$}k6 z8cVXH3Ln_Etk+PAR6~^FY+ibwPAbi5*J*%XF^+DtM_M2=3kqP}_P$#e&e8dHhmVaO zA{jWR$cD6@F~9-ETD>uS`StJo&HvQTznui=vkWBl^QB*=%R^xoo4h|vFBi8ODJ^3i zXR*$b+O=8(JkeOM2vQBD?oAG%Lhq%!fOb{GX#m=AYMaMY*Hn#20xInF_30^+TkRO{ zv68D8U5;^T?0__eo`+Vhq#%J|0*W>3^!VLh|Ihu${=eUS`vS)2n8H9hy?pudWjd=l z?PeULem-4Z9%IgRSrajjqB;+b)3&vSLyPlDYU?&IlRfm8a}gDA@6)NPIkeV*2Hqr` zO@&6mqSTj#aE@DldO4qy&U^RWW@o;`%+_(O)yz0WimqeyPOezV2N$c>!{x_6`YV6s zPrm!o5uaxUm5Al_sf}vmT!Z@28qnn3FE1~@eEhGXMi zI-k24fSn!yb;6?!a-~WxtOSY`yRAO9*0|6!Yf8Z*P0_~q?o*pl{&`^37l3gs!h{$ znYw}$DTQ&=93$N1m?FhYFj+@{+F$mcKlf^Yb8?gsJwyd-bpi)FP^{x+^x3%|YY0Q1 zX9PqBlQ@<2<;{LdVC!8X$bBm}V zMkONkew?ss73v(T1Fc-9X?lJIQMla=YV4$;9wPRt0&V0 zZ#E{Ye7+e#M4qh}BV!Hfhk-Y_KlEvurryu)t~ycy0%Y^sV?SGA)0_Hq`KG&;^I4*; zG`TAU3(1eAX^u8#3Zsfwt44xAx=feHsSAjRy7cruU6TFT5AXL&t{fIi33V`0JLUmQ z)DlO#*Vp}}n}KtZ6dg{RH95KP*!O`6s5J~I=7=;t6Bznj18PJ~rd6{>M#DbLK`N#9 zhiN)>mn4r0j8p)ZqI+Sx`gD1@bR{PU0s>+l=UgMu*bKc@=rNByxmWNS5k-B&9crWu z`on2DMSc3iAKp@Eu1TpQREC+$cBr|sV<@8agW6yA{oK2QadMPFMxsu<9wl(V{RH;= zzywgN;BEDBZdS&qi^a_6oB>4GOsVTSjy0&)YCx0w!_=p#_g>^CL%>MIW=2&n(R)#I z@TUGSJxoNToO8+}K&sFF98p2IEap5PB~v`KI!nm{C_4S@GU_fKFO#=B&vDwUXRE3=bTu;nyFnz4|1MD;*kVo9xDwJ>_4v@u8S_UXq@-`N?I@ZW@XykLw0AeDhL9rASWhuw!0*e-qP#weTg-Z@D}%21WMgUgE_{dl&g=L9n(kxrZh0fIQ8C5LSm}`6ey7K+`GKsjzE@( zbUYqYUK2oaS|kPdsIft!&MCa|5+nQK8zGjNmt^k$pwFlal-7%dl(<&%9C*DK)+k^vth}~0%{!tN_bbKNCZ~(Sw{flJVsbu$I&dXYamUR z>C5FZb-7_61H?5oGRt~*adnNFQ%Xx-6Du?lGlYPVwgN59!8`&YH5#lmaA<6LS-8fO|4riC)TzlZqq35B`@T&<2wkZd- zjseAF%zsd75TMUHfT%ILT+M8*qhYOW07ZSeyiC12#ue9907&8G=-V z%@t_C%GE24?JL)AACzF_0~a#^Oj75K9s)44mq+UuCrr^1VXr+0I`sROA$tHKyV$BA#lpa^g9#=qr#727-mRM%C(9lnM5jtC z527Dk--)(2x1BNsP^{%`L_R*}g(9=6&pv{Aw%Ho)-DTrw?&O*xVhIUMLI(O63eYH5 z*|HK5RKN%9ExQ5}9zuZkZf=}3Gba48ncaf!E- z>dhfpw}Lhj0U?Q7u{-YOy!Eg+SqKnljE>fo1UQfdg+Y)2g$XFu_BEE*gac%R_=+Jeny)o&C9UzcydLkhL{3XYCBEvj-id$;)U+&BFF$^nTm+Sy zHxQB+=i2hKoZ&a13ccYpDjmlVLu*OGA!dCCL-3QM0zM5J(W{Br)s$?RiKX z$rS++eD&`+@y=|0>RljqR8sfe1^5ix%;Z(oj~m4uN9Tr`IDSxv(LjZI13yBA6uI#PYGv`ZwS=x1CA^E(h}k3Djx? zL|Rf#>9j%c_X&C;-kBx2BzDyRA(sOjBgVdKV3?6{Cxmm@!o8biX;Q=1R&fbH?A}lFOr;FP)Q_V94e*qkOqXr7p@2ig}`tF z!*IYp3>H`yfE?bYQF| zB+~+tk%#Dk_oBf_zJ1m=@b?xwJjVfkJUr1(DJ8HeOaQg+5b6H-et#brL439X1Y5N; z0wGD;wn`>!_)?TDZD}OlD2hf(62upch)h6|0>|7U=S&bZi1uNC=+M@ai<3bfuv3lc z$V2qe2=9QN16u5^L}uBd;tqcO4lk(%^Y$=9xZ4P?L$PjSZxyqKm!UAMjik=1>}L)O#x&<>N!NiH1@&- zK&>-|0bW{rpfw{tHxd}e)l~>ULv~nnO%G!XkrE_Oq%wx|r6a;gXe;vn#=SXpMMH!kKwmC^!c$WGJ|$4!XKE|wMk9N)pdsvi^`OU!0|~{2$p;Rg zapA}V0|)yA3TVvt;KEuz4CZmHv%AA=bLDemWr^z=uy6~iD8|s@Xo_uIhKdkhyfQ+i zT}R|38wL;@0&G_K<^lH$wfP^5tp3=xvNpoY=N9yDCodr<4h zVl7W#OkQrhJks~9EanXXwO$OE$1%pLW^JyY9SJkxj+d(-0AkPMvYWcW#A`F=x;%JSljdSHc~Q0iXug89yVb{ zHo|apV1N;E7eEitS~i;(6l6idAQ4lc4q>}61W>EPz#`|mMxDoboadR(j-~E0Vk3x1 z$s%$cxTBr^rnGe3p0{yH0QyW45E0Tr7>>Yhg2|(s&PFM@B(9g7qbzcBZ*5vL!+{14 z2oOYv=n$RNKVgu7;PCG;Ot@iOn1EWkytSZG)AL%#6i`R%XGb6m(*`M)po7j6aL}-EnSfd}D)Yt~*P5Qw+U7CpJTrfWge11dl9$)=_MG4H%Frt* z>EJLe=~_kz2lROq2$50}7}16YGiyh>exFe}7S4?o+@z zV2iYhhO`n37C;KQP&l8%0)&*LGR!Ew$+F2B4%mkP3~%0Rt~)_Vv0@Ps*_(x1eN3%Z zIv$4Hj`_53oacV_y>X}3JxFE;$${t$Nyg31E(`?JA_18|-bz4y&g*m3WrR92e^wM% zT$vJiS?=Ez&u?i>41CH(T8X#y3IXYJ$T(0)DW#Fbo;u!eWDN)G0~p@OW_#^A_ry@j z7ow;|_Hb+M)r+6$&1K$nOvb_e*IiHkcvRzEFqsaL10SCe9Cm9vGi3s5i4vf=kp~_% z)|4|*qeA8L<}~Kz*cJIX!#ZdSQeG>;dQ-2xcIR_iiZXuu_6wlW!!aD0;Q;o&FnO5M zt?sg?@R3ScYk(TLWi0vA+;)030Jll&(a!jze=}bmJJh?tG=TxhfjSJC24P|R6%$KD zQ6xp)LO`x5Rfv_5k@>Tvs5R;q(wL7OQeG1SzaXUq3t-Zxz4YFzA^ThkLYIf}{3m|} z-8xirli?VKb7=1eFzC^}_8zt?E+t)3THzvsj9T7Xx2^khYoa%L+bMtk_MPXmRpVVT z0S3t-i%!tdFfD8s4#wVrqJScAAP>!TeGZ~RohzRqM-WlDGOc+bSQG2Oy~pnLYz8JE zK8HZMZrgbNgRupD&()$^Znzm34q)%a2D+S>)&Fe_mYJS$t19i?H z{PD!*+>h}*er?pd0wlnISL$AAKMPJ(_pQ1hqUsQa4VZ9J&4N>#Jdj zKp&4FLTRMJTV{ZH>rMJWn(J5rgp*_(>a!*?Et3ZA_oXS^x_&CDIh~#6-XI&YFkI-D zp-x;O5Rqv!_uuE=&(9gImuo8Oamr>l%S(&_+4r6?<16yZ+ZD z$1ZjY$D0fXngjYps1w&N;u@mJOOJV8F2Kywj8s(GQV6~W%*YQPQI9Qn)yxSDk^>)| z0gYxCCV*NPC~n$7L8SKYT47nBk4J!{lp@j_XtQVw>mMN6_ zujXMci=x!6lay?CGs`BUC(A}y0O%L&#&&DXqyh^P2AD>f8^QLf zF`vL7Iq=b=)4*Rb5I`-9`IQBBs&%;S8&I?|tqJcFpwX&ISRn@miWp z2g#+rXPrd=)Eg;BT=Z4*1rQ&VqbDWt=4`+x0L-e%jN=I;B^5yc@p)qc^#B=%1d{TU5Mp;ezG{}ih1zu!Jl^Hbu|ITBq>M)UpeoXfO`8l zw7eo!GeHm^j|2#Xl2qQ1SmINds#L0^BMX*@q(n-A_#8HwIcTm>r4+R&KIXazu^awS zs`vKNa}6m3;+p|o^ebJR&T^iYSf0&!9z4GVj9;|z3Y*LirYS5iP$sB1PM{nf($|a# zJ}3)O(n!IZ6NmHGBbSthQpt(M(ISZ?iKF_gF=1Gn9Vku;SyRoSwXhjz}#(m zSw@7u0bNVidDa}ueD1T{CFM1F@-Cgs4-yap>~c_V8;6!xRy1o8eLxZsp)tla3b59K zl=uX$nfkRF%DiQiBrkxDeCC?y#H$%uE!jm8#_!QgT+-Y;L5>|5KTB_wHWr|rjylXR zpXZL2^V~E3)zv-^-mjDCAVFx*>~cW8VFJ(Lxy{K|4vCM-Druw=iQ{Vl>-Ia$1rv#N ztPn~>5}?l;6JTzJ`q>+zOvQzZ6$*-0a?pk()b^{z*H$ephd>?F7dn0JJ$vW3^VR5n z{a4rXc)nvz6Bv*>I?(p71W<1lSF}85-M_EZs)G246d=+lBPB>I4%gySxMrfWNE}^2 zN~0tx5}&^wcyu$bGM*ZlP>hvYVL@rpBteuUMenV)`xj-&>@J*_=kN8?{Wn;w?y~AS z#*=sN1Q>}9u>BPRpxz{o=V)H*%l_4B%@q1@BtWEIwlSo|Cw5IzPry2Ww50SfMp8+i zKNz5XHoQFzFjG#g#LCyXU{Pp9XpmGaZEd^zOSxHn$Ne{7&wsDmHNah!y$zqollSlh zMgqbV7zm)=9D$Z`R{tEr4c|KsW#iy=@gVaeA#k0^|o+4 zM}+y)oXt)J`iLYVlD6$ZQ9eB^CX2T%5hHn#g3n`b&R#L^7AoO^l#{2$(FCoKTag~F z$+V0**R$v*eLZ_|>byM8ysIZLcrh^r5KwQ3K%oqoFtbD;J|G838e?cAV0~&}@s|9w>(;~E>}o^dwEtbwoxQL z2c?O+2npgd2SEs-5SCjv4(EENQi%;VkrzNV0GQF`l;)d_H;@_E`i1;=rRjmE8oRq&7SA4ZvCq zzSF?WH=i5@CNL6&z!(r6$Q#b_91&@iM$6IpuxYephq5H;*TW^P#QOA=xvaU#`D_+I z2&Xx_b)zWjQhBdq>N}qt5he^0bQl?wh|UckC?c=2AUC`%^p6{WmP&?bLdmvq6`zq# zxP2~x00PU=4SO=;($YRV^WDBV;5l(*m@r6m(1k&X=(n5W_J4h5Kod*x1M!XOVHv_76=NYJ^#7xL+D zGnm$LMB`(pLATPO(0Y6}zeeG6u{5Qw1Q4H781e>gSP#^VyP64uJoZ33h9E`1y@2Mm zznpuY;0^l6js+J@TwAudBogbhpv+4XKP3U^GYU-J0EbTO)#e=y5*WFQsXDiM#_P-e zxL0pEqVXYF7LEudv|qLO99%Q?6stKSAwI*s$(y&_a(C#=I~kBL3XHuwpdfCmMZ&s0 zKK<>Nb91~wd`JQWp}sBeQTSY3jiIQUQb?a$CNN~4Ox*EI8nr9h!w=)r+}cZd+T%;D zy?bk|(LN~20+kfa>R5^Oc|Zvp#Wx5qU6W2^VNvUfj1nBe11ei>QaVNC)UEjZd-+dQ1^dhZsZOuGSYt370 zv~Q9?G?DGu^x`DeX92KULNSUI;`7@BOzGA3mtKK+m!qJys$Ze1n0Clp2+(*Ad^dOV z)*6j(k!9hCw7nGeTo<2{Wo*BmpHl*Tc8O3b+i%-{`B#7P{7`^(hXY7}!89|)Z5$|+ z`SIIt&qEU5Gz&s$weF9L&&d*HJPc0=;&V)TcpiW87k@FX;tpssKLGhQavb2VfBe{z zLJIWFk}Qz=pJl5)6YDc!kw}-ZZK)&#=<|w$NaGLBfB12|CRV!hF->NR`aF}jO`xz) z{5GDqB)(ymg(Ia=*X(%Zb8<=BHb#;{e0B?@GDiG**q#@6N0Vt~iQXX>Aak)CmmvT4 zV0a((uJwKxe>9gy&5;E?b7C-~Ow+4`}tup{}Q3AQ;=6%kQlq9}s zRuk%%%ub$sW|px%|Jt@8L41x$g21VGy-NZG&|om1uZEoI3>Ma*d9PM`O92G>R!KxQ zp@iBluY6W666v!2_%TM30DW$WfB=^n-E^k}3ZS(%2br&@cgXV`V@Vv(;WnpvmBhEs zsV60Hv!3SqoB)=z{d#`hQiQ~3yqP)J-4dwcqV`OP@_4#WzjD z66z1DTF;Zu&N8-#Km4Fb5T9`%Fm%TRsG1ChIvvPY(jn8wNm~rZd(dXLX~vj19xfG6PrdxlSW=#^`HVY#E z{xS68JlA=lNXIkHZ8oOieA6rfq(I^R zxGJBWi$ogZ`PYyHpwBi3FF28@I zRd0E&&kbO;0WGJqgYlW~SlxR_BtAk(K(oBUq@#p_#%o`&r0vIFKc{O-K%j4#!XXI~ zJy+v1RVjIU49sPpd0@Sh=`;fvM<##{4l%8djie*M=+yz`lD1zzexxCZZ<}Qx6zUJ1 zmsLMg$}IWfXG});XPlY2TeVuQ42vtrr3Dm*ZVcqdMnY#A4eB*55-Q`zk6*uyq>$p9 zCJ-&R_4`NCZY|IC`LReXlQM>N8OUz7qsHD{yK>4fjz=zS`0k)SHj>3$jE9F`KgKqa z0Q3!$3?K?5_H4%Is!CH>u2{zSe0Muy$knP`<_NWcZBqdGu>pBOy{f|X`uzO-Jdz~w zO|jm}Kt?z+(&Mw`$5lUD%DgP+X8|Mp^X-k+<*I7y!*XI6$0W16?9+6}{MaC0c-=wT zwrwj!K%lP(dOQ2drX%)N0^?|D#agcFus%l?sV6JRp>`SQ#&aOD+P1YdQw)wv3n*%b zJE(VFV@`^CC5r@T{MgtwDM@@a6krfJ0z(HVN zy@U}U9E2SRgTQdqvZcon9rEOJax&inN+@^=+z7wn?7$4kuC=YLt(nfj(P;w`=}@Y_ zimKxED#b|K_OK}qz77f_AR{B$k&MX*14sJ0B?#om09kOw~7`4%PT zxv;b0Fo%zh`ut-ZPWo$qG`dNTLCqF^RWoiOQ-XshM!(=WaA^?4r5(EM@0Vqrz zMmG{}G6Ou6mxoX9X|B%*7K^toQNo@8Bk*l^D8N=`Yxnl3u)r{mMy4ZS^qA>D<`n=+ zx;$)y-~Mn>K=3s%BvTWhmV-UFahAuxTQ-@IO;YeRS`bK5Lnt~es}&2Ywb~CgJB$%Km-U#(fi^p(vrr*_G^nj`BA9yTkxhyb@A5Yf%73_=-NT7vVBx2jPUwU}{@h6)E`U(JMi1TlLNhK9C zJd8|Gs=)Bt_n*cnNrCvP91sza(sKOa>4zVlUXRPNMARIhV(Ps=K7M)Z_3fXfa<&4E z>$ZcSHCo#OtTPK$>(4^wxc$Ju4cxr<(N;>AvPw=lvcTihQoLsu(;*?{B$o@8w6^iQ z{TKbmpFAiy{fi)#vB4kO^HtGXhS@k&T2=M6{pH{NW&7u!H|E~^41IYI3aCLujg*MD zUp@Ws(;uFWPw8#VL4pvtN;~(*$CnGsQ&80S&~^YcHro~Cs%1oSHhufO(F`*Qt&&Ds zSFIKZJU$`GJNHfi46*zru45a|mmk}2za{ZCFeIh1rR(~$h-~3jb8jXPMtQ3I+WxZr z>wo!|pSO9Q=iYk<=O;&#hz^~=*9Dohn z9ooj)lBdNI(`qI=coW(IxCJyRrOPF)U?pz?k59w5Z-aO41_snUW;)~`EfPxOva$Wi z^TUtdN}!XUKq)2JAJ*^l>aDX|o~2{#CYH6f`}Vj0;eY$96<0s0sf2My-*LPft%j{OalW+iy$C0h#L;P;q&R>m8PJ%s5x) z_Lgd!9S@r~q#KcyS*0nZqQuJbXrgzZztaRj1Q97M$JeK)_t)d`ZAm%E ze9VFX)^v>((zf*w7!g;lEzK)AkB`S*41wPW1`yFQIW$@Q^CzW~%3zx|2FOPj4XF*$rPCV)igKmPvn@BjQS|NPq@ z9kkGS_YIOoI=(+WJv|-oQ_4XGSU;cv6d>~v6Nlou(N?zR8a3NX!ZvTq+=#3U1w~|{ zDRShTP2e7Hnnw;>`&f+vqwh++uYnJ#51@u;kyg=Cq@?Y)-?r_?6`lSLBP?w{epvSD zp7Vrt@a+MRXukdN^Y-)i+vV2jbHB{J_vIa@QX#!9$M^Tw<#}0hkb#wt**I(yBiCG8 zn#YtCbVcB|gh9&@Et3_Oi@AHW#>(W7iFfYceDsEo4a#{(-rIM?_;xg2Y(oMF#?YQn zq%lU~tD%$1NR{S!!s6Wrko_{x&)e;fpFfx0=iV3IZEFA#DdpvOe}8{`dkcaLtbFta z>j$*fX8aIX*=#tpm90TqaNLG?LqI@|7FijH?&h9DOWpfz`B9|M@9FrOZG zqrI;c0>MsmAO<(CrKE>$d+*&)=qrKypFs#!4j1orz=eM4e_U>pi)VUY-f6amMNP|b zIi~xRG8tIe(RD*A9FQ|}b78yO9;qnqm@d9h*=wIxo}t z)SMeEViz0l?2R4R+a3=?8<@0|(xr6U_t)>|r^?sFPInWKCX4qy-~#jf`|UQ*xB1fh z%zJGRwUY9(EN{zOL=J$J-Bv%Bb}+P}vzjN`%G%OAr=U7^n73v?jz*?I>&Y59M}us+ zxu*l8)2+Jm{o^+$0kn@KX9pWVy{k8}c zTZ0xfB3h>5(KIa6Xn5;JIjHW{`nj9^w|@Mx?StD!QUCQWyu%lO_xSp20|_+^1yHz- zBw640?q+;dbnAQdBzpP~@PrGO-fy?tKi_T_sxQ3PDo9I?nj;50zHU*OE)O(62)q^d z-d*#Y+PcBLjjPdiL*Tas1ms2|)3Ve2`iRZe=i_5ip<<7A?)%H5@z;OzKYH}yTiUh2 zLEZo8<_f6yw%OYKefLCSa~%j0W0U9@Ulkq9y!I|EaWiN7?dN=(=iULmyJ$;_l$IPo zhIOY%YXpAkXNg0w0dj2y+tb{ZI->7^d5gB7hyVh;n`{aqu|fdrj*-?_68_R34}_IOByvP(%VwT!wP*(XCZPqiMl>=F zH)DT1pA*8cUcL6zVS4F`_vN{=ecb{+7pXk_Yd>KqfK-_#7yH^a=35C!KAkV-5_TA@E&1DdA%g8I32IuFX7jcc5JDuO z5F$L>Fx)sQ69F~mnp=Vf;B%4A|6)FQ9Er+XOtm(od-HCNBQdHr37bX7fx{g(#*AEd2YtMbp;Rz1Ry&&G(@$k z2Sm*497zcZQ0RU>l}{rIi9~PxXOoxGU?r$ry?(sS#<|qEbW+dW9-qARy_---fxbFm zU^i`YK@oO;FA6=9V9Xt=z*Oph;<%Q+O+Mnk43&1qKzgqy){91w?b>>XvZ2^q@s zSYZYNxq6@a<F|NQ$ek!y-bQ3(QqHLj?9s0k!DXxFE_9-n+qqwkpbnkf*vaY#Pd zga87)YnT)652efZ$D359>GarT!2wxJ=l0w?Kxx_g{J;; znI5N4A*L$cnWpK>m&fnFjwNbNIgtWoQlucZutHo*O){HuQ!D}G%heWf^R zH_us_mU-6{28N2%i>t8D;pz|P7k6=3`uTxVk@yK-Zxsj-*c=lOfFV;PS?Q0{Wx9MS zF(aKGFPF#frkBZ6q$N_+tRPaPCDMinYHW!sB$H(IdKQ-J&hR!kG`@1`rlkPcVxfcH zD?lJj#oc9cmHjEW%7a&RDJtneXkaKn&3|$Oy(tg~lFg=kUdudE9dl|_)1_ag{_p=( z0&q#{efrJsMXr&SSRzFt*Cm!*6OKWxIY>ZI!Gxodl^;jPU)+X85e@?M^+J40>MIfzhXYcqE|azerJuNEdg)|8YY0P(KD`8-W3 z`?OWax^rOWbAC1=Sh?Cj5}`Mdcw+!MP{>pvD~bt?N}j+x1y%9y;8V-z{QmUAA1VS; z1?y5~Io`)2F6!M zrm|-)sRY`x9tLXzA{4>(Wf*ndzT#*A;)nt%1T`3Eo5$X3ST))GvIOPwZ|76Xl=AWE zho2H`m&>Tj5(~H{_cL!b5cYkIg!`0aTAa1QB(#HqBuOa(boh1QW7n|iAt?d~-WP>| zpd@)OE@#h$B$u#_gE5^WflF$Bg+OEQ<`qW+1PD+d6iP{HjLz(1@%4=g;b}>475kU- zsb!A5EU!;b0Lw;c5)tcL0zWquheXKbDG;Ui;x(uA`{~J(p^&jsDw32^1Rw$S6+uct z`dAXFR7O%r?+hTBdmwi&1q5x68p5qQ2=d_oa>q~I#WiKmu>XmKffGCb2Kn@${ho4^5k(;^!$@jLx z()07SJ!~V5B9)?qf%8T?-5my!M)1+5tZ>;vA-ykvF!yY|_pZX;uS6__B8WsB2o1`^ z!%MfvbLrx0<83OA1|UFyLMV}hDWs9EV2W{+OGS0_Ox;O)~3SRv=kH4B@W z%>rV3VbkATC&{ts^v*>ia_#KT4`UlYwlT&?sT6^M0nSmK?gT1HB}Ms2CRHx`5@J{H z38HkBsrTNre?*GNOHN)nD21%2ba`+!Pun)*tsyW7kRuF4Aca!$5UHfHrHAX-(({(K za-Uz*+kGS=()6K?>7RVH~i{f$wh(x#7KmPgO`s3f6f4Z@^*HoH!873ne!UzK# z1a^{>p`Sk#De*C@D%&HKB2e&7C;*w%`*iN23;?9G#B01pJtW$S16|@n``bbo0di!> z0)YaJ@RUj_TY9*TEj^F4T_4J&q@0#mNST1V4OZGG8Xw$Xy`u5K1yR5O5_J3i`p5nI z&nGjpN89%vFseF-MmB^IhJ&!vTR4K084|(zSdx%kCIsT$(7@#3eL9um0Bx@vodrXb zO&5k)LPEM*TDm)zPKgBp>6S*iyBn77mXJm|r8}idT3BES>H7Bl{=m+h*=Od=oVaf7 zC!-OcYM}PlDWlG~3zOFla z5OP@lS(dCss>G;4Mb*^q_+-&?Swv9n!7_$wvFXt%quYrg${H0m4q|i- zgu0&JWkQejpcQ|e+*2ozCn^bFsQ*|3JPyKKF=L@kJ93L>i`Ie-ImJ>y&Vk~dN5rE0;d8OiPi>D2c1G%qN4I<> zXEX#-KAZL6%tImOU#@7iyp`mQg}ne71tlg*Z{l7jdTOimG+z8=VkIRcK)66%s9Fk9 zm{Mu%MROQ|e3s*q@$E-80rEX%9hexhBs?HW8esrcRLATd$U9hX5P5%}*WR+&FpB?=up6ItU=7xt415)El0ZvLO+eoNa!iuhvF+l0d zOO&{SMOf&rGXWjBkE;`fD7N>($;y-IAuO>aH1U`|2vI<$O>omU9$`Jsj$bIwCut^ZkX~PKe1HX$`)ogxZ%Wr$AUeYeJcz^C-!`+P9yEkGuwu@HWvv5KN|4_-W5ss#IS4k*ki!4dA(2%+Q861pyNr)e;wYzNmUDIohPhyo)YhccSm?|HB1w8p zbwDBsg4+y$H+#C&zi8|5B~S@+-*>zVLB;3fWeq#%rlEaSmi})Q6=9?KZnYd8oq4Yh ztAkO#H3bAbKER;Qy$>RRDuCa?u`1H^S;9}d=~~*_%6pkRD`S`gYUPy$GN!tpq8b01 zShHBNg=A97Tq9DA{O!U(z}{PS>MT2FV5o27=?OwbqNUUPyc~Pqj}N4h0h`gOnLojD zUyqkv4p{5ywXq>o?)BYJiMQ#3x8Aprx4>v}0GA0j_Tz*8{Pc89R&G@lD*~tLMTEKh z6Yr<1{tICX%rSmjR@!DFqCarVyBJKRZePTkZ2EU=AIzjGhx8ik30L7(IYQy!sl!v> zan;U91Ux@p!jeESsReIEZ3zeFI~44LD2Op z4TnVSk@|Mr3+QzFmp3Pq!%y(w|qL$t7C`|Z`88U@SOkis7 zp3;HcO76o1H$p-2#d9&?`-aldvpu(f(JQwUCMw?8Cv*J_PN&nnlZ3)=ZWPre0Y_4t*<|-^$~MdwKZW*E%$dZ-zebW3dEpOgn>?#<8pVNP(A=O&6WoN ztXYO)JzD{P)8S*i5&mL0*~o8sY)Rso4q@}fyEPlPf7UAk-EQb4*;=0iuia!Qs?$65QbnF`^D zrF{0pZR5voY-tMi_u46HH@wSiDT{u398-DLKU2OWU8YaO{rs*8Tf0dW*51eCN<4rrI(! zV1RE;;yKtbNp|Jr} z;k7aQTcjHC)rb2^?VNXwws-gZasF9_P{0Fp@ZVx`3ymUjaR#9enWqR$xv!&x zWEjI)zVbzB>Lwv59D>G+XCshxg&1`duKksuW1&8NhHzIekgI zX;-19j+5lCj|~KT&(XHE|wP4%kmG|ct%kUa>Kl*<27}G*Ab+4WmITqA8B;g z*9DjCqfv$t^9u@Iub{8z5-+gUr1gQRPJ}1z1xW?=e-Sa=0WfEVs7>bC_|dI?%b0Si z7E6w81oM*^B4W(w`_7f-Xd%?rwSwROS^Qj@`g*Vq4R|(^&*&sJ!3y*m0uwkMP|4$N z?W@{3KNia}?#HB>AN=`v)LbTHYf0ab^?Y{I`nFc^dh}Wl_?U6)bvoq{71FJ2|F5OFn_ka)9D14M6pK+amq^8ICsEOIbO|Rx4_J zhn;S61J^2Cx)srCg`(E#utopu7^|xWkSP+h;X{1!i9n`IPHE)miMp&9o>hE&(Z$qo zNH9^oaBUWjdw-}19h-4dzxmN3~hI&G=L0OcSDO`)P{_aMgdOM=j1)SnBi zj^t2*2ug_24*CO>U?Yc3_OJkbZw3gIHw2;D!U7U(W! zICI~4zBpQ_ZiJ-UEHu(JV>>~scKh*;6eeC=3V0-C><1;kBWy!drR0_LKi$%8wVhi~ zkowXaYI?`+4QuEpb z@tRrJ4+hN{g$p;(=2a0SoYS_jqdh7GmNVm2Jmh*+r%4Ygnjpd3mj27d%Ryc;RX`N{ zH#j$BMp*NjD-%3KamHKiM4QGE+j@?TBV3Q=xU)jo40ai>l(QoKNUw~QHp&zHIpT|o zQHO{_COlG1i*Vd_bwmu2qc;I7y*R>)F!34J#vR$IRhK{&yc2fKC<70ElO3p_ z7VK}gn4xpTWvdS zZ%uk&Xc(ss6ILU)`hQE^#2-rspI0ms1S-gkM8PS*G3X^g(WR9{1d2u7qN$@$%bbR{ z8mXH&%Xj_;G4<`nr^KxGET8=SQ*Yz)K2p|j9t@(3_?f99`r!kvu4N&{qyf5TA#hIH zRT&5Oqb-xotjkYAQ^A5P_f3ADoMf2jdj)+dkUH1XxUcJnY!O_nXU)GYWDk?Rlv@1? zZIG%Es2bZ_aMEg-I9hlbQJNJFRgvG|zj?Y^G0P$fi$%lHQ%>neU|+U7lO0k8rJ7M= zGNOd+ZN+pW*s&cNvYA{?H$U}2t%jYWa|DAF9=xMRlSw8OWouT+vr6GG=Dq{ZYq<@A z;brxw*kl!QD`b`UZ6t}Oqq#LTF~4EjQ782^W=T0ARr5g&rb35&TWps)$%ujS#U=Xm z^%xaoHkIfOd_oO9p71}=Teb{`3xL<#{`l|_}PFtXz=-*9zV96E<`e; zlv0ze#ZI0|*rX(-Zf=WxEDIIk{$W%^-zJh#S4pU|8Iq;z~@M<{+4Ptm6m$9o& z8ic(2H>nM#t^hQFs*msvZNY`nGbRmUGW57CgY{Yu;t*;IA{^btAVqd> zoB<=4B4w|ogIomc9tuWBjEhCiif|oQfjb0+_+STHl3poDyg*;e-$t()`#M73$&RI1 z#=?J}p~6N9Rwjh=RyZu~XrFp$r)U19PKKg+>1f@@uy_lbAXhfWfA`H)AaAr=k!)C0 z%CL5On4$-YH?ajR`J?g6qEp}suID_Fy4+BXQlkp(NU$Smm?=2P-rQvBtEcj@14DgP z(Hb+9-4o5B0u%Cjow#slPf|Rm3ab?lb0|TA&GITWOa(hK5j6!MxO2nty6e3_(Ofbx zqsXM>7`4~q5VU{D&MYmWGbG|qK}2H}vO~y7;K_mhSh@y_U0V64Temxd;Bowul=cZt zKVlQk|U`IVq^^rK!{6%ZUO`x%Jyuq+z`!WKv}sTc@rY^5DRL5&-&1nYkMG--8M# z*jh*n{IF+FqsmACk_n<h%tG1>oqWZe4_C=n1J$)@Nz`3|Ob^&#-3`w$Kv^KW`I z9ElYAg~8`;vhS8$Rl`+9O-YWyiZvv%b_-L{aw0h4C4bEeg>3{sE}~SxCl!TC1?^U# z<56PwzT7VNzGS?uZ@;8S*oVrLZK3`^wy|GN?7f#Lc#RT3t%q|b+v{tU1j^V~s;{~| zVgnZKpdDRmOel_$&Sa`pvJ;MuLpcHxIAcJ>)&x@Vj3-3^? zZSQxr1*^V&^8L9)`jG}3<3pvclh}T)HjBdi*dTy4Mu^b+aeu<$!8@;^U_v_iD(;QE2=s2Divn;sJx#Y4=$E_5766yrUt z^QWQ-%Zt7t+L*wA9eSJ(4BTV0urQCMe?DvU+b;BV`Ryq1+3D@>ZTs!w`N!<9wmq?5 zn5B{1`ETcM4@7~>(vDT!P9|oaZD)dgI_woVlG8YnK=+JT)BGP*ciB0^^=R6Be%Q`r zaLKNY*A1#pTZMT+7F5dkG!m+Nh%8W!j09!!%&SO!Y0De#Vqf?E{1dlxKbv9?XQwk$zV3+Dh&ipCPT+mYWOOBf!^n}V5JKj^KT$^CuAkY zL8C>>LOkp!2FA+0g{+T6d5;H|mc_B53lg(>*Gs9IFAbeSOMYG1=H1(8V4=*G-t)ZR zU8l5yz%s{|BQF&OGE69r!CRr69^uiAmw}5C*b|DIyyq(G`{>mR2Ye81AUSwR%8o@398*?Z(P~m3NM$jD;QU z#AQW)JgS+NwRl=B^pfMc-)o9Iz@cFc+rA3U?eqRPe=(p7w)l$;pwV_)^~?RW)30gA zaRjY%JcVD{WRAfFC0-G2Dov5F(r|y?DtynA)nVoq-1dmWCr?A)o+h5x$rx(6m7}k? zW1B|Y6U6C)={SLFrW=?XNhW+F!w)W>TRLxYjd8&DX3~UiCJ$1R@;0Wrt-5S?UZ&ff zsU7)4Su;JXBa#>;{$<3p%W_bXrgV z6^^sD!tLxn4rN*GrM$}0a zj`G!Pq|+1Y25zFq;$cOlOCx2wFB_C+?`D6WC=25pn>EGZ9hJO~Y4+T6pgl1vc-4;A zlEPowWQqZgE7*{AADq_+^^ME^`ZB~RaQer_Q8vw7D7(Et)n7O|7LlFsTIb_?>RC3l zwAaV=EGJ66tjAb2?vkrjbzP!sq=}!_46ELQyX;$51AwzO-w?o$yzbs4%!P+1e6?X= zJpbUMD)`Fqe>qf+GFgbUMW@uleQC7ow`%5Ij{dGusFE>Zp7Ea3O#v~>YGJ~PBzt5X zs4E8j3V{Wt2igdi4F7M~zvcZY|9&&BFAuf@)Bdp=9a&xNtyHy!^-L!c^{$ zQH#|hzr2MptFD`Dao^3S?KoqJS9|-7EWK3j{8lcH!cR_9M15D){8}elk=5<`>-q?x zb?b}yL^n3V8N2vvR8yZXZ_Sdm!?0U{;ZeqH(7OqJI0#$4Ri$3W#qA0@YMu+cMI4>L z^|+!=?eS&Kh_W+Lq-DvRz4nvDBrIZ@S96}&xjT|5VGxPt`MtR;@Ayw zI;-0`ZH!v3b?^D`M%erZHVxGUH*aj|tt0zdUX?$;{wzn~_ZG}wwpGgyFulWV`qu=7({6G6Znc5%74v<8)$k0=o8LbBb+a@x zk}hAV_dwmbYX=q-H zEWLevgnQ^6XXaB=jjPCkAIXxk4T#)*T=xd`pZ(fJRT-!U0e@Fe^?2ZJq?*WcDh+Yw<)UgVgI^%xk9uYR^3 zK>Te0BhG|HV(7sAj{k>6FY$UZlb@g*aiguMnQ6o#`tGLRmHS;**V;%>V~1&OrPN{@P=FiLP0 z1)HhGcxFZse~Ibq4@yc7rs3u#=lmm|A56aC*Lrb1wc8pH(OWC&Z$r}VrTuSEC*%zyE9}%{OXsEVL6@w+>~O*&1e#XtGGFAXHNa?=q?kz@;61EKeyo7EE$1z)$%0^?%qS8M-DH>INK*%M;+W@H=Z^r5v zYeq=cP`-lp`m9;smw9xsXF1FE?zC$}HcG2-JyruM6YRb|vxz_N8>GO(kyl`x$MB8! z6hc5#0qA|T+kdJSZyz`L#LRy*iG*}j4}%N;rlP`m)1JQzd;+H*cp1POw4#@#0oA_B zqPT%^sLFWrTaO}3`(uLWmZyBA}agO;)nBqkqQ%LSaE2j7xGE8@Q4-b7Vq zYQA+6rMeAU4xiGMbk3qT0$ys`o2hEkXueQXVs9ia8UV?d3#}jyL!73&+8EerR8gdt zb%{Po$)MLor(Vhov{Ze|DNwVvTV6_-;Gz-^lLHKTtk|ZZ?yt(ih2U<{GlW*g=-eUp z$=80tHQ_ECKL;vz#Qra=qu^;vjBd-x0_QmJwX-hWCw647VSRWRwF;?HPi@~a`L4hI z?%0d5J-h7_f(9xANM0G=!#9YrROD_S>I zyI1r4h7o7lx6Dv*i#PsZ^X8~}Y(Z#B)d4)G?D)EMH%}x$9}c@>I{WRwQ}eq-=(fI{ z0TdYfH?U&CKfea{O|?~VeGtPJN{ZaX1w@Ub43aawzGnET9Ji4dz$lRA9}@1OM_aMz zPh)N<;b&3hf)s3?eO}XKO!ICQV-{vy}S(s|a``p=p zAg}j60o)}~cjP-`6K_v}0U2J;#&eXN6!)a4N!1C@%Yk=oljb(zfP$bewW${UgJ;Aj z%%(-9LA}Y}yGoz-o?hyV67QfR=6W=)PqkmFl$0GArE+Zv6!#t;mRG=n6w7l~nhT=S z>P|wlhoZXI^4GbpT?I(2N;v+vXxFuPvol98U2nm6z27aE&feYv(p2pk+d+`s<&_ZaZ@Iu2_$F#jgP0`@s!QvAz{ zCsi!^=CcLb;o;(_Agj@^tueP`kgMRiS<{Fg$xsZ;T5P%o5a9UNx$T|1@|nMR2Y5?D zF=qda%#=q$51cb^t#Jm^s^loX20&-Nz_$+1=2+qdw~4XP4wBz4&sQeAed~eI_Bv!cdobLl7;gEcgL+bNe_sBY{k1$UoZq_p zusw>Lp?IK3-zzgUoatH1IY+bZZ364eNMtD&tcoK%*~1 z30CC{8T9gcO_ST<;TG~JY+EhCT`aXS;c4yEn_D{F-?9t!GJa3Rc?)em*KUW{zu0Ww zJ$_Uyx_Onk`s(}W^cwcjB-B68w$#ixU@h^z%attKK8TCs5TX zdGONR+h19kVbs2MW391y6ajS*l^-bc2$Lm(U;2uWlr}WArCxJw@YOtTL~n$J&m#=v zTe)d9ak%OYjn$Rrj%hBSyv<&$pb+dFji#AWZHYmR27<3^|2eL>6Faqr>{OG-xM`oM4zF zjoNJ`z-mi#;32 z_|m2YHRov#E~(9C9A>kf`0zG&`I@;9H#VJ2b3lbqy>VOieLe!DFgS*E@i@!}&AS3q zkU=C5bZ4`DoxBgDcEe&v*=(MgQA4mgl48JTPpk1h<){@cPg`m8pZk2A6xQ8S{S6%B z-lMDj%swKvb-=};cJwE~4)7&@2iG2BFwU+^w-pc7F1&J93n!Rl@n8 zmEmw9am_t^*3vI1NwdFHP`e;4`F*DVhEi!<2Y5yQ^Y9Dw5#HjM;6f%bIk??cc>a6d zQf1*?Lm;1Yqy;`30tg4ks8!qUu)O*hc|YWJF(^y4UNo(PuOqEVK(bE8jzlmrjKDdc`{Eu zOhRk5sT1G8$isZf&XbyB<;Ks)`*dP~!)U>W5y>`1bTh|Vb;kzGgm`rMyf-q7vJe?u z2KL!B_Q~9Is3O+(RR`^M*CFuGmJNn;z2j6(LfLl>%-+JcAf0yTVN^h~=OEr`OjHO$ zx18T@X zLEuvZtoB~-LkvoUkA#HB3B`9*w;y@nc?Fvx-)up=rdkI`;Kyv{AZJ@(Om$Cor>qRI z^ACU$mdnb(0GGHA2}(u7cSI6h9nA4K@fp`GH*Y}KxnQW@-0U>R_RDjp^7AV6?Q+3i z539J32Hw+-C6X|ok_7EztuL%vW#pQ_7WXo^G?n*c%ku{(logOhacUZ;fmVHoK>SYe zaWRMqEuR=iiI#FbcZmwm#W9d6ynRQm?UWWFEq)3PmX{U4ow|-=E+r&F-s(6-H)^Zt z^1IthG^Px^Uyyj2P;;tA#;&E>`oo$4s- zW!}ri{-C?Jv(x=X032mXS6bEGAC(EiY263`D}k5AL~{=t6O|$qxuaCJ1V!UrJw2F1 zCX{MMt&fu|e8+$y5&DV1$#0Z&Mj^8ixtvW81YwS-(; z%Gqjb;+gZ9p!u)M5ch)~twV3mv}I;`J}HjUG54DN&;M+EDaHYxu)Fr%D}*aXsGJ+P ziplhyXUX6EAuFy)=r#D9Qz+ zq_0+cMKz%CFI-}e}#N?>DwvZacbEFpYU-_Om-iC_BjdmLCPU8?-7wEO-0gnIvE#fA-k)RhixeAs=E9^$-L+e}kK zab@lb+{)|h*OF$!;g5gnWxRnmm$^QIQ+EKml)V>jccDm#-0srR1GX&TqF(Y`e`g-qu)INi_66n#$zN2;B#;s0oOymQ*aNw@lNnXzp^ zIVjl)c*(r0>j|fMZ(B2ZAi+OO`Y;bqnuDxrf-`4(CW-Vr`Vy#Jhkiq>o^(7AT)Rg3 zS}IepVVE!PgHG*O7@T}}=llHf%tq)1f{*grxN}q;c;K!5!Ya0pV^nba8z9|@1a2=d z>Ujt_>4rP|7R)<+SNEhN!`PfD*oTw3e4`0ID?|DjimdZz=_#L$-V4;vRU7zNf+$v~ z6q5soWv7f#t&{1Q5`^|w2jz6Yl;X6``hK)7c1w^qsg4UWuStS=7^KF!Uhl0%YQw6dEt{4 z_u_thOMe1w0Rb$WxZz0|+ihfedto)}%D87&4tRaSV*vVIr1qhd= zHS(0)u6#jf4g41sJ6V*MnX`Tl+W{t-F6Su%7JMF>RAGAVtUeIxHAPj{&M-z?ncV}x zN*&7l8A1Wp4!#ObP+k?9!885lg5)kL@vKyGp=j8o%ghwM?yW<^+#n4=H(S}VG7->r{vdJ_n4^dqk z925Fzn5Ji|mbyz)yKwD2hSz7;XXAC&*UcGtbra5AQ%kI$A-Hdu5j5qR5!s{sU>)+l z3o<|hO}yFd3heTr5ZR(*IIfPn8%n0`QSh}IJ!aQ!9L{vvAub#ZqUoZ$3vxMq%7;Hm zkgb7LYJkSc`$@z)T`O3txU(<$hwBvdg=8!1pgU*$2>2{+flwT!JWOmEN78rQp*oP2 zc-;zodiQg79f&V9x|ohl_k&arqp5_?^sB@Vn)1&WYHP!c(Q0SeL%ZX$xA$Ngq(OEh zncp3ylYp+|3LGgwThb^2?#NK9aq<*6apWX^y@$8#u5O9>R|*cL3#1n*v4PC#XAYco z>DPh39v^L_nr#h~mF7Vg!St9v4!hLMsQ#cPOVSv&lwOSi&~B+LLnbGIW;^HK z$t4Msa3{%9`fR0Z=@t+d!cqf&lw(jlL>Yf8utd6gQg>vY#_&Bqry9?+NQu^&?_slk zx_c7ipvTXT`u5u(gP{9{9nqQ730{GA?8zMV&|oAevr_=XVin9sVV!!vJ&xO?{fUN~ z+hu&ed7Y}vMJotD=*Q0fnV3&Jh4ezx1{J(o*$ zA+@YX*8H$@X+0;afZW#wP)N2H=x~<*Qi^X08-QJwX*q7G?y38&245&^C+bD$*jxEP z(@i%UR4cSH0F%4Ii)?EgDa{#Ade(vFZp{7nIa$dZqf z;3NhmAvMFKA0fogF}38W^oPqYxfxY(q8R-$ENBIqyu}KGp8#|_{ID>GfZ{S)n#1?x4@btCUOp zl32qQil%W%Vd7}_h9rUF=oAHH!C?12OxI-mYAhbCpQU!*QFJ9o58d)G@sk0ZCs!p` zvT!wz@u}dI_fZHow9)nYx1CWi_pamBS?|T-vIV_U9ZG@Y#;KF2UE1)Vh86z*>Y!#U zo0_a%H!Oqg9=~tM3YUdirw@G4?@BwUNktch70x)}H_<*#w}tNpO%WAjZEAee7tDUR zbAlaKi{1SEr@B%>AE^yw9O-|yR-)O&HLxKGxD6>KUv!h+sDgy3+LHOHHQ)vU0^d#& zn1#Z*Ey7awwZZp4b)v*pe*X$1A(3s%#79}3BWtwh=#wvi7KP^mgK2D1kB%Hz6sdS? zaRu~Ln^##p(|S1?91%^X=UA)L0&mxe^Wme=PbF{`XZW}UH$S0i&vqIY9PCLj* zShr-IduD_%-e3L=ri=G~x{N$>z*j0#H&fu8a*D!Vx2snYUhmA-pu|rGzQPG+#!i@-=8aaz&-mIP?bC6I~AP zFK)mce!`|&pXzY_+P)Fi$KYQ_LB+w_VEE^W+2x;QvEmV1nN9xS$4yMLR`jGUUja8p zjW5YK8jV3{D7MEm>2r5NA2Md~sIX%o_f1D<57}A??!JDj@naYSYaM5c6`tvi)g;50 z#S%c{vHuA+BHoKoxG(XlK~tSLPn8Sy8bgjyCS)tlP06 zhYyr`>R$Umg#&|@4>R-xTYr7sAq1UF(x}iTo$~;w3B1rrP2;e!d<_aE-4G>XqCbEH0Pu7LWj5*)gWnkblpRk+vw8>ZQky z<*i>%{qTmVxbHZjKHU!KH`?2mV(>z@puV?f33ZwrHStB)MKgzS^oG5D*592(5>fmi zQRj}`(SNR}+pOg2CcH#DW@=(aR1tAV*YfLTmg%{SxA$F%dB()EzckfR1ZMfw__nzWDkTSwQ26WSwmS3F(a-)zi_bdl z-kH&xo&wRKLYi!->2o2$B(M)NPGZ{CrwQ$16jjS?Js>`o5m}Z=Zf7>g8*jEP72d6L z;=oBt0?=693W+ZwcQ0amK9X>`=bX#AKIV6#V8j(+0}@At>M5�|4;T(9@x^wo{2h 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 { passThroughOnException(): void; readonly props: Props; } -type ExportedHandlerFetchHandler = (request: Request>, env: Env, ctx: ExecutionContext) => Response | Promise; -type ExportedHandlerTailHandler = (events: TraceItem[], env: Env, ctx: ExecutionContext) => void | Promise; -type ExportedHandlerTraceHandler = (traces: TraceItem[], env: Env, ctx: ExecutionContext) => void | Promise; -type ExportedHandlerTailStreamHandler = (event: TailStream.TailEvent, env: Env, ctx: ExecutionContext) => TailStream.TailEventHandlerType | Promise; -type ExportedHandlerScheduledHandler = (controller: ScheduledController, env: Env, ctx: ExecutionContext) => void | Promise; -type ExportedHandlerQueueHandler = (batch: MessageBatch, env: Env, ctx: ExecutionContext) => void | Promise; -type ExportedHandlerTestHandler = (controller: TestController, env: Env, ctx: ExecutionContext) => void | Promise; -interface ExportedHandler { - fetch?: ExportedHandlerFetchHandler; - tail?: ExportedHandlerTailHandler; - trace?: ExportedHandlerTraceHandler; - tailStream?: ExportedHandlerTailStreamHandler; - scheduled?: ExportedHandlerScheduledHandler; - test?: ExportedHandlerTestHandler; - email?: EmailExportedHandler; - queue?: ExportedHandlerQueueHandler; +type ExportedHandlerFetchHandler = (request: Request>, env: Env, ctx: ExecutionContext) => Response | Promise; +type ExportedHandlerTailHandler = (events: TraceItem[], env: Env, ctx: ExecutionContext) => void | Promise; +type ExportedHandlerTraceHandler = (traces: TraceItem[], env: Env, ctx: ExecutionContext) => void | Promise; +type ExportedHandlerTailStreamHandler = (event: TailStream.TailEvent, env: Env, ctx: ExecutionContext) => TailStream.TailEventHandlerType | Promise; +type ExportedHandlerScheduledHandler = (controller: ScheduledController, env: Env, ctx: ExecutionContext) => void | Promise; +type ExportedHandlerQueueHandler = (batch: MessageBatch, env: Env, ctx: ExecutionContext) => void | Promise; +type ExportedHandlerTestHandler = (controller: TestController, env: Env, ctx: ExecutionContext) => void | Promise; +interface ExportedHandler { + fetch?: ExportedHandlerFetchHandler; + tail?: ExportedHandlerTailHandler; + trace?: ExportedHandlerTraceHandler; + tailStream?: ExportedHandlerTailStreamHandler; + scheduled?: ExportedHandlerScheduledHandler; + test?: ExportedHandlerTestHandler; + email?: EmailExportedHandler; + queue?: ExportedHandlerQueueHandler; } interface StructuredSerializeOptions { transfer?: any[]; @@ -1382,6 +1383,12 @@ declare abstract class PromiseRejectionEvent extends Event { */ declare class FormData { constructor(); + /** + * The **`append()`** method of the FormData interface appends a new value onto an existing key inside a `FormData` object, or adds the key if it does not already exist. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/append) + */ + append(name: string, value: string | Blob): void; /** * The **`append()`** method of the FormData interface appends a new value onto an existing key inside a `FormData` object, or adds the key if it does not already exist. * @@ -1418,6 +1425,12 @@ declare class FormData { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/has) */ has(name: string): boolean; + /** + * The **`set()`** method of the FormData interface sets a new value for an existing key inside a `FormData` object, or adds the key/value if it does not already exist. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/set) + */ + set(name: string, value: string | Blob): void; /** * The **`set()`** method of the FormData interface sets a new value for an existing key inside a `FormData` object, or adds the key/value if it does not already exist. * @@ -1744,7 +1757,7 @@ interface Request> e * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/signal) */ signal: AbortSignal; - cf: Cf | undefined; + cf?: Cf; /** * The **`integrity`** read-only property of the Request interface contains the subresource integrity value of the request. * @@ -3026,7 +3039,7 @@ declare var WebSocket: { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket) */ interface WebSocket extends EventTarget { - accept(): void; + accept(options?: WebSocketAcceptOptions): void; /** * The **`WebSocket.send()`** method enqueues the specified data to be transmitted to the server over the WebSocket connection, increasing the value of `bufferedAmount` by the number of bytes needed to contain the data. * @@ -3065,6 +3078,22 @@ interface WebSocket extends EventTarget { * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/extensions) */ extensions: string | null; + /** + * The **`WebSocket.binaryType`** property controls the type of binary data being received over the WebSocket connection. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/binaryType) + */ + binaryType: "blob" | "arraybuffer"; +} +interface WebSocketAcceptOptions { + /** + * When set to `true`, receiving a server-initiated WebSocket Close frame will not + * automatically send a reciprocal Close frame, leaving the connection in a half-open + * state. This is useful for proxying scenarios where you need to coordinate closing + * both sides independently. Defaults to `false` when the + * `no_web_socket_half_open_by_default` compatibility flag is enabled. + */ + allowHalfOpen?: boolean; } declare const WebSocketPair: { new (): { @@ -3183,6 +3212,8 @@ interface Container { signal(signo: number): void; getTcpPort(port: number): Fetcher; setInactivityTimeout(durationMs: number | bigint): Promise; + interceptOutboundHttp(addr: string, binding: Fetcher): Promise; + interceptAllOutboundHttp(binding: Fetcher): Promise; } interface ContainerStartupOptions { entrypoint?: string[]; @@ -3195,7 +3226,7 @@ interface ContainerStartupOptions { * * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort) */ -interface MessagePort extends EventTarget { +declare abstract class MessagePort extends EventTarget { /** * The **`postMessage()`** method of the transfers ownership of objects to other browsing contexts. * @@ -3288,6 +3319,181 @@ declare abstract class Performance { get timeOrigin(): number; /* [Cloudflare Docs Reference](https://developers.cloudflare.com/workers/runtime-apis/performance/#performancenow) */ now(): number; + /** + * The **`toJSON()`** method of the Performance interface is a Serialization; it returns a JSON representation of the Performance object. + * + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/toJSON) + */ + toJSON(): object; +} +// AI Search V2 API Error Interfaces +interface AiSearchInternalError extends Error { +} +interface AiSearchNotFoundError extends Error { +} +interface AiSearchNameNotSetError extends Error { +} +// AI Search V2 Request Types +type AiSearchSearchRequest = { + messages: Array<{ + role: 'system' | 'developer' | 'user' | 'assistant' | 'tool'; + content: string | null; + }>; + ai_search_options?: { + retrieval?: { + retrieval_type?: 'vector' | 'keyword' | 'hybrid'; + /** Match threshold (0-1, default 0.4) */ + match_threshold?: number; + /** Maximum number of results (1-50, default 10) */ + max_num_results?: number; + filters?: VectorizeVectorMetadataFilter; + /** Context expansion (0-3, default 0) */ + context_expansion?: number; + [key: string]: unknown; + }; + query_rewrite?: { + enabled?: boolean; + model?: string; + rewrite_prompt?: string; + [key: string]: unknown; + }; + reranking?: { + /** Enable reranking (default false) */ + enabled?: boolean; + model?: '@cf/baai/bge-reranker-base' | ''; + /** Match threshold (0-1, default 0.4) */ + match_threshold?: number; + [key: string]: unknown; + }; + [key: string]: unknown; + }; +}; +type AiSearchChatCompletionsRequest = { + messages: Array<{ + role: 'system' | 'developer' | 'user' | 'assistant' | 'tool'; + content: string | null; + }>; + model?: string; + stream?: boolean; + ai_search_options?: { + retrieval?: { + retrieval_type?: 'vector' | 'keyword' | 'hybrid'; + match_threshold?: number; + max_num_results?: number; + filters?: VectorizeVectorMetadataFilter; + context_expansion?: number; + [key: string]: unknown; + }; + query_rewrite?: { + enabled?: boolean; + model?: string; + rewrite_prompt?: string; + [key: string]: unknown; + }; + reranking?: { + enabled?: boolean; + model?: '@cf/baai/bge-reranker-base' | ''; + match_threshold?: number; + [key: string]: unknown; + }; + [key: string]: unknown; + }; + [key: string]: unknown; +}; +// AI Search V2 Response Types +type AiSearchSearchResponse = { + search_query: string; + chunks: Array<{ + id: string; + type: string; + /** Match score (0-1) */ + score: number; + text: string; + item: { + timestamp?: number; + key: string; + metadata?: Record; + }; + scoring_details?: { + /** Keyword match score (0-1) */ + keyword_score?: number; + /** Vector similarity score (0-1) */ + vector_score?: number; + }; + }>; +}; +type AiSearchListResponse = Array<{ + id: string; + internal_id?: string; + account_id?: string; + account_tag?: string; + /** Whether the instance is enabled (default true) */ + enable?: boolean; + type?: 'r2' | 'web-crawler'; + source?: string; + [key: string]: unknown; +}>; +type AiSearchConfig = { + /** Instance ID (1-32 chars, pattern: ^[a-z0-9_]+(?:-[a-z0-9_]+)*$) */ + id: string; + type: 'r2' | 'web-crawler'; + source: string; + source_params?: object; + /** Token ID (UUID format) */ + token_id?: string; + ai_gateway_id?: string; + /** Enable query rewriting (default false) */ + rewrite_query?: boolean; + /** Enable reranking (default false) */ + reranking?: boolean; + embedding_model?: string; + ai_search_model?: string; +}; +type AiSearchInstance = { + id: string; + enable?: boolean; + type?: 'r2' | 'web-crawler'; + source?: string; + [key: string]: unknown; +}; +// AI Search Instance Service - Instance-level operations +declare abstract class AiSearchInstanceService { + /** + * Search the AI Search instance for relevant chunks. + * @param params Search request with messages and AI search options + * @returns Search response with matching chunks + */ + search(params: AiSearchSearchRequest): Promise; + /** + * Generate chat completions with AI Search context. + * @param params Chat completions request with optional streaming + * @returns Response object (if streaming) or chat completion result + */ + chatCompletions(params: AiSearchChatCompletionsRequest): Promise; + /** + * Delete this AI Search instance. + */ + delete(): Promise; +} +// AI Search Account Service - Account-level operations +declare abstract class AiSearchAccountService { + /** + * List all AI Search instances in the account. + * @returns Array of AI Search instances + */ + list(): Promise; + /** + * Get an AI Search instance by ID. + * @param name Instance ID + * @returns Instance service for performing operations + */ + get(name: string): AiSearchInstanceService; + /** + * Create a new AI Search instance. + * @param config Instance configuration + * @returns Instance service for performing operations + */ + create(config: AiSearchConfig): Promise; } type AiImageClassificationInput = { image: number[]; @@ -8476,6 +8682,48 @@ type AiModelListType = Record; declare abstract class Ai { aiGatewayLogId: string | null; gateway(gatewayId: string): AiGateway; + /** + * Access the AI Search API for managing AI-powered search instances. + * + * This is the new API that replaces AutoRAG with better namespace separation: + * - Account-level operations: `list()`, `create()` + * - Instance-level operations: `get(id).search()`, `get(id).chatCompletions()`, `get(id).delete()` + * + * @example + * ```typescript + * // List all AI Search instances + * const instances = await env.AI.aiSearch.list(); + * + * // Search an instance + * const results = await env.AI.aiSearch.get('my-search').search({ + * messages: [{ role: 'user', content: 'What is the policy?' }], + * ai_search_options: { + * retrieval: { max_num_results: 10 } + * } + * }); + * + * // Generate chat completions with AI Search context + * const response = await env.AI.aiSearch.get('my-search').chatCompletions({ + * messages: [{ role: 'user', content: 'What is the policy?' }], + * model: '@cf/meta/llama-3.3-70b-instruct-fp8-fast' + * }); + * ``` + */ + aiSearch(): AiSearchAccountService; + /** + * @deprecated AutoRAG has been replaced by AI Search. + * Use `env.AI.aiSearch` instead for better API design and new features. + * + * Migration guide: + * - `env.AI.autorag().list()` → `env.AI.aiSearch.list()` + * - `env.AI.autorag('id').search({ query: '...' })` → `env.AI.aiSearch.get('id').search({ messages: [{ role: 'user', content: '...' }] })` + * - `env.AI.autorag('id').aiSearch(...)` → `env.AI.aiSearch.get('id').chatCompletions(...)` + * + * Note: The old API continues to work for backwards compatibility, but new projects should use AI Search. + * + * @see AiSearchAccountService + * @param autoragId Optional instance ID (omit for account-level operations) + */ autorag(autoragId: string): AutoRAG; run(model: Name, inputs: InputOptions, options?: Options): Promise; getUrl(provider?: AIGatewayProviders | string): Promise; // eslint-disable-line } +/** + * @deprecated AutoRAG has been replaced by AI Search. Use AiSearchInternalError instead. + * @see AiSearchInternalError + */ interface AutoRAGInternalError extends Error { } +/** + * @deprecated AutoRAG has been replaced by AI Search. Use AiSearchNotFoundError instead. + * @see AiSearchNotFoundError + */ interface AutoRAGNotFoundError extends Error { } +/** + * @deprecated This error type is no longer used in the AI Search API. + */ interface AutoRAGUnauthorizedError extends Error { } +/** + * @deprecated AutoRAG has been replaced by AI Search. Use AiSearchNameNotSetError instead. + * @see AiSearchNameNotSetError + */ interface AutoRAGNameNotSetError extends Error { } type ComparisonFilter = { @@ -8601,6 +8864,11 @@ type CompoundFilter = { type: 'and' | 'or'; filters: ComparisonFilter[]; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use AiSearchSearchRequest with the new API instead. + * @see AiSearchSearchRequest + */ type AutoRagSearchRequest = { query: string; filters?: CompoundFilter | ComparisonFilter; @@ -8615,13 +8883,28 @@ type AutoRagSearchRequest = { }; rewrite_query?: boolean; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use AiSearchChatCompletionsRequest with the new API instead. + * @see AiSearchChatCompletionsRequest + */ type AutoRagAiSearchRequest = AutoRagSearchRequest & { stream?: boolean; system_prompt?: string; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use AiSearchChatCompletionsRequest with stream: true instead. + * @see AiSearchChatCompletionsRequest + */ type AutoRagAiSearchRequestStreaming = Omit & { stream: true; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use AiSearchSearchResponse with the new API instead. + * @see AiSearchSearchResponse + */ type AutoRagSearchResponse = { object: 'vector_store.search_results.page'; search_query: string; @@ -8638,6 +8921,11 @@ type AutoRagSearchResponse = { has_more: boolean; next_page: string | null; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use AiSearchListResponse with the new API instead. + * @see AiSearchListResponse + */ type AutoRagListResponse = { id: string; enable: boolean; @@ -8647,14 +8935,51 @@ type AutoRagListResponse = { paused: boolean; status: string; }[]; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * The new API returns different response formats for chat completions. + */ type AutoRagAiSearchResponse = AutoRagSearchResponse & { response: string; }; +/** + * @deprecated AutoRAG has been replaced by AI Search. + * Use the new AI Search API instead: `env.AI.aiSearch` + * + * Migration guide: + * - `env.AI.autorag().list()` → `env.AI.aiSearch.list()` + * - `env.AI.autorag('id').search(...)` → `env.AI.aiSearch.get('id').search(...)` + * - `env.AI.autorag('id').aiSearch(...)` → `env.AI.aiSearch.get('id').chatCompletions(...)` + * + * @see AiSearchAccountService + * @see AiSearchInstanceService + */ declare abstract class AutoRAG { + /** + * @deprecated Use `env.AI.aiSearch.list()` instead. + * @see AiSearchAccountService.list + */ list(): Promise; + /** + * @deprecated Use `env.AI.aiSearch.get(id).search(...)` instead. + * Note: The new API uses a messages array instead of a query string. + * @see AiSearchInstanceService.search + */ search(params: AutoRagSearchRequest): Promise; + /** + * @deprecated Use `env.AI.aiSearch.get(id).chatCompletions(...)` instead. + * @see AiSearchInstanceService.chatCompletions + */ aiSearch(params: AutoRagAiSearchRequestStreaming): Promise; + /** + * @deprecated Use `env.AI.aiSearch.get(id).chatCompletions(...)` instead. + * @see AiSearchInstanceService.chatCompletions + */ aiSearch(params: AutoRagAiSearchRequest): Promise; + /** + * @deprecated Use `env.AI.aiSearch.get(id).chatCompletions(...)` instead. + * @see AiSearchInstanceService.chatCompletions + */ aiSearch(params: AutoRagAiSearchRequest): Promise; } interface BasicImageTransformations { @@ -9595,7 +9920,7 @@ interface SendEmail { declare abstract class EmailEvent extends ExtendableEvent { readonly message: ForwardableEmailMessage; } -declare type EmailExportedHandler = (message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext) => void | Promise; +declare type EmailExportedHandler = (message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext) => void | Promise; declare module "cloudflare:email" { let _EmailMessage: { prototype: EmailMessage; @@ -9736,6 +10061,83 @@ type ImageOutputOptions = { background?: string; anim?: boolean; }; +interface ImageMetadata { + id: string; + filename?: string; + uploaded?: string; + requireSignedURLs: boolean; + meta?: Record; + variants: string[]; + draft?: boolean; + creator?: string; +} +interface ImageUploadOptions { + id?: string; + filename?: string; + requireSignedURLs?: boolean; + metadata?: Record; + creator?: string; + encoding?: 'base64'; +} +interface ImageUpdateOptions { + requireSignedURLs?: boolean; + metadata?: Record; + creator?: string; +} +interface ImageListOptions { + limit?: number; + cursor?: string; + sortOrder?: 'asc' | 'desc'; + creator?: string; +} +interface ImageList { + images: ImageMetadata[]; + cursor?: string; + listComplete: boolean; +} +interface HostedImagesBinding { + /** + * Get detailed metadata for a hosted image + * @param imageId The ID of the image (UUID or custom ID) + * @returns Image metadata, or null if not found + */ + details(imageId: string): Promise; + /** + * Get the raw image data for a hosted image + * @param imageId The ID of the image (UUID or custom ID) + * @returns ReadableStream of image bytes, or null if not found + */ + image(imageId: string): Promise | null>; + /** + * Upload a new hosted image + * @param image The image file to upload + * @param options Upload configuration + * @returns Metadata for the uploaded image + * @throws {@link ImagesError} if upload fails + */ + upload(image: ReadableStream | ArrayBuffer, options?: ImageUploadOptions): Promise; + /** + * Update hosted image metadata + * @param imageId The ID of the image + * @param options Properties to update + * @returns Updated image metadata + * @throws {@link ImagesError} if update fails + */ + update(imageId: string, options: ImageUpdateOptions): Promise; + /** + * Delete a hosted image + * @param imageId The ID of the image + * @returns True if deleted, false if not found + */ + delete(imageId: string): Promise; + /** + * List hosted images with pagination + * @param options List configuration + * @returns List of images with pagination info + * @throws {@link ImagesError} if list fails + */ + list(options?: ImageListOptions): Promise; +} interface ImagesBinding { /** * Get image metadata (type, width and height) @@ -9749,6 +10151,10 @@ interface ImagesBinding { * @returns A transform handle */ input(stream: ReadableStream, options?: ImageInputOptions): ImageTransformer; + /** + * Access hosted images CRUD operations + */ + readonly hosted: HostedImagesBinding; } interface ImageTransformer { /** @@ -9815,7 +10221,13 @@ interface MediaTransformer { * @param transform - Configuration for how the media should be transformed * @returns A generator for producing the transformed media output */ - transform(transform: MediaTransformationInputOptions): MediaTransformationGenerator; + transform(transform?: MediaTransformationInputOptions): MediaTransformationGenerator; + /** + * Generates the final media output with specified options. + * @param output - Configuration for the output format and parameters + * @returns The final transformation result containing the transformed media + */ + output(output?: MediaTransformationOutputOptions): MediaTransformationResult; } /** * Generator for producing media transformation results. @@ -9827,7 +10239,7 @@ interface MediaTransformationGenerator { * @param output - Configuration for the output format and parameters * @returns The final transformation result containing the transformed media */ - output(output: MediaTransformationOutputOptions): MediaTransformationResult; + output(output?: MediaTransformationOutputOptions): MediaTransformationResult; } /** * Result of a media transformation operation. @@ -9836,19 +10248,19 @@ interface MediaTransformationGenerator { interface MediaTransformationResult { /** * Returns the transformed media as a readable stream of bytes. - * @returns A stream containing the transformed media data + * @returns A promise containing a readable stream with the transformed media */ - media(): ReadableStream; + media(): Promise>; /** * Returns the transformed media as an HTTP response object. - * @returns The transformed media as a Response, ready to store in cache or return to users + * @returns The transformed media as a Promise, ready to store in cache or return to users */ - response(): Response; + response(): Promise; /** * Returns the MIME type of the transformed media. - * @returns The content type string (e.g., 'image/jpeg', 'video/mp4') + * @returns A promise containing the content type string (e.g., 'image/jpeg', 'video/mp4') */ - contentType(): string; + contentType(): Promise; } /** * Configuration options for transforming media input. @@ -10227,9 +10639,12 @@ declare namespace CloudflareWorkersModule { timestamp: Date; type: string; }; + export type WorkflowStepContext = { + attempt: number; + }; export abstract class WorkflowStep { - do>(name: string, callback: () => Promise): Promise; - do>(name: string, config: WorkflowStepConfig, callback: () => Promise): Promise; + do>(name: string, callback: (ctx: WorkflowStepContext) => Promise): Promise; + do>(name: string, config: WorkflowStepConfig, callback: (ctx: WorkflowStepContext) => Promise): Promise; sleep: (name: string, duration: WorkflowSleepDuration) => Promise; sleepUntil: (name: string, timestamp: Date | number) => Promise; waitForEvent>(name: string, options: { @@ -10237,6 +10652,7 @@ declare namespace CloudflareWorkersModule { timeout?: WorkflowTimeoutDuration | number; }): Promise>; } + export type WorkflowInstanceStatus = 'queued' | 'running' | 'paused' | 'errored' | 'terminated' | 'complete' | 'waiting' | 'waitingForPause' | 'unknown'; export abstract class WorkflowEntrypoint | unknown = unknown> implements Rpc.WorkflowEntrypointBranded { [Rpc.__WORKFLOW_ENTRYPOINT_BRAND]: never; protected ctx: ExecutionContext; @@ -10270,12 +10686,14 @@ type MarkdownDocument = { blob: Blob; }; type ConversionResponse = { + id: string; name: string; mimeType: string; format: 'markdown'; tokens: number; data: string; } | { + id: string; name: string; mimeType: string; format: 'error'; @@ -10293,6 +10711,8 @@ type ConversionOptions = { images?: EmbeddedImageConversionOptions & { convertOGImage?: boolean; }; + hostname?: string; + cssSelector?: string; }; docx?: { images?: EmbeddedImageConversionOptions; @@ -10430,6 +10850,15 @@ declare namespace TailStream { readonly level: "debug" | "error" | "info" | "log" | "warn"; readonly message: object; } + interface DroppedEventsDiagnostic { + readonly diagnosticsType: "droppedEvents"; + readonly count: number; + } + interface StreamDiagnostic { + readonly type: 'streamDiagnostic'; + // To add new diagnostic types, define a new interface and add it to this union type. + readonly diagnostic: DroppedEventsDiagnostic; + } // This marks the worker handler return information. // This is separate from Outcome because the worker invocation can live for a long time after // returning. For example - Websockets that return an http upgrade response but then continue @@ -10446,7 +10875,7 @@ declare namespace TailStream { readonly type: "attributes"; readonly info: Attribute[]; } - type EventType = Onset | Outcome | SpanOpen | SpanClose | DiagnosticChannelEvent | Exception | Log | Return | Attributes; + type EventType = Onset | Outcome | SpanOpen | SpanClose | DiagnosticChannelEvent | Exception | Log | StreamDiagnostic | Return | Attributes; // Context in which this trace event lives. interface SpanContext { // Single id for the entire top-level invocation diff --git a/site/wrangler.jsonc b/site/wrangler.jsonc index 021eafbc..387a1aed 100644 --- a/site/wrangler.jsonc +++ b/site/wrangler.jsonc @@ -1,11 +1,11 @@ // SPDX-FileCopyrightText: 2026 Knitli Inc. // // SPDX-License-Identifier: Apache-2.0 - { "$schema": "node_modules/wrangler/config-schema.json", "name": "recoco-docs", "compatibility_date": "2025-01-21", + "account_id": "5def525918a785eeda6decf66cf6b99b", "main": "./dist/_worker.js/index.js", "compatibility_flags": [ "nodejs_compat", @@ -21,7 +21,9 @@ }, "assets": { "binding": "ASSETS", - "directory": "./dist" + "directory": "./dist", + "not_found_handling": "404-page", + "html_handling": "auto-trailing-slash" }, "routes": [ { From 074a2a91f817a8241c1f14cf3d315b5c4a78331a Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 20:25:42 -0400 Subject: [PATCH 29/38] feat: adopt dedicated PostgreSQL schema for Recoco internal tracking tables (#94) * Initial plan * feat: adopt dedicated DB schema for internal tracking tables (upstream PR #1459) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * fix: address PR review comments on DB schema implementation Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .../recoco-core/src/execution/db_tracking.rs | 49 +++++++++----- .../src/execution/db_tracking_setup.rs | 63 ++++++++++++++---- crates/recoco-core/src/lib_context.rs | 27 ++++++++ crates/recoco-core/src/settings.rs | 22 +++++++ crates/recoco-core/src/setup/db_metadata.rs | 66 ++++++++++++++----- .../content/docs/reference/configuration.md | 20 ++++++ 6 files changed, 204 insertions(+), 43 deletions(-) diff --git a/crates/recoco-core/src/execution/db_tracking.rs b/crates/recoco-core/src/execution/db_tracking.rs index cffebaef..4eab5611 100644 --- a/crates/recoco-core/src/execution/db_tracking.rs +++ b/crates/recoco-core/src/execution/db_tracking.rs @@ -12,7 +12,10 @@ use crate::prelude::*; -use super::{db_tracking_setup::TrackingTableSetupState, memoization::StoredMemoizationInfo}; +use super::{ + db_tracking_setup::{TrackingTableSetupState, qualify_table_name_with_schema}, + memoization::StoredMemoizationInfo, +}; use futures::Stream; use serde::de::{self, Deserializer, SeqAccess, Visitor}; use serde::ser::SerializeSeq; @@ -110,6 +113,7 @@ pub async fn read_source_tracking_info_for_processing( db_setup: &TrackingTableSetupState, pool: &PgPool, ) -> Result> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "SELECT memoization_info, processed_source_ordinal, {}, process_logic_fingerprint, max_process_ordinal, process_ordinal FROM {} WHERE source_id = $1 AND source_key = $2", if db_setup.has_fast_fingerprint_column { @@ -117,7 +121,7 @@ pub async fn read_source_tracking_info_for_processing( } else { "NULL::bytea AS processed_source_fp" }, - db_setup.table_name + table_name ); let tracking_info = sqlx::query_as(&query_str) .bind(source_id) @@ -146,6 +150,7 @@ pub async fn read_source_tracking_info_for_precommit( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "SELECT max_process_ordinal, staging_target_keys, processed_source_ordinal, {}, process_logic_fingerprint, process_ordinal, target_keys FROM {} WHERE source_id = $1 AND source_key = $2", if db_setup.has_fast_fingerprint_column { @@ -153,7 +158,7 @@ pub async fn read_source_tracking_info_for_precommit( } else { "NULL::bytea AS processed_source_fp" }, - db_setup.table_name + table_name ); let precommit_tracking_info = sqlx::query_as(&query_str) .bind(source_id) @@ -175,14 +180,15 @@ pub async fn precommit_source_tracking_info( db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, action: WriteAction, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = match action { WriteAction::Insert => format!( "INSERT INTO {} (source_id, source_key, max_process_ordinal, staging_target_keys, memoization_info) VALUES ($1, $2, $3, $4, $5)", - db_setup.table_name + table_name ), WriteAction::Update => format!( "UPDATE {} SET max_process_ordinal = $3, staging_target_keys = $4, memoization_info = $5 WHERE source_id = $1 AND source_key = $2", - db_setup.table_name + table_name ), }; sqlx::query(&query_str) @@ -203,12 +209,13 @@ pub async fn touch_max_process_ordinal( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "INSERT INTO {} AS t (source_id, source_key, max_process_ordinal, staging_target_keys) \ VALUES ($1, $2, $3, $4) \ ON CONFLICT (source_id, source_key) DO UPDATE SET \ max_process_ordinal = GREATEST(t.max_process_ordinal + 1, EXCLUDED.max_process_ordinal)", - db_setup.table_name, + table_name, ); sqlx::query(&query_str) .bind(source_id) @@ -232,9 +239,10 @@ pub async fn read_source_tracking_info_for_commit( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "SELECT staging_target_keys, process_ordinal FROM {} WHERE source_id = $1 AND source_key = $2", - db_setup.table_name + table_name ); let commit_tracking_info = sqlx::query_as(&query_str) .bind(source_id) @@ -259,6 +267,7 @@ pub async fn commit_source_tracking_info( db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, action: WriteAction, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = match action { WriteAction::Insert => format!( "INSERT INTO {} ( \ @@ -266,7 +275,7 @@ pub async fn commit_source_tracking_info( max_process_ordinal, staging_target_keys, \ processed_source_ordinal, process_logic_fingerprint, process_ordinal, process_time_micros, target_keys{}) \ VALUES ($1, $2, $6 + 1, $3, $4, $5, $6, $7, $8{})", - db_setup.table_name, + table_name, if db_setup.has_fast_fingerprint_column { ", processed_source_fp" } else { @@ -280,7 +289,7 @@ pub async fn commit_source_tracking_info( ), WriteAction::Update => format!( "UPDATE {} SET staging_target_keys = $3, processed_source_ordinal = $4, process_logic_fingerprint = $5, process_ordinal = $6, process_time_micros = $7, target_keys = $8{} WHERE source_id = $1 AND source_key = $2", - db_setup.table_name, + table_name, if db_setup.has_fast_fingerprint_column { ", processed_source_fp = $9" } else { @@ -312,9 +321,10 @@ pub async fn delete_source_tracking_info( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "DELETE FROM {} WHERE source_id = $1 AND source_key = $2", - db_setup.table_name + table_name ); sqlx::query(&query_str) .bind(source_id) @@ -351,6 +361,7 @@ impl ListTrackedSourceKeyMetadataState { db_setup: &'a TrackingTableSetupState, pool: &'a PgPool, ) -> impl Stream> + 'a { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); self.query_str = format!( "SELECT \ source_key, processed_source_ordinal, {}, process_logic_fingerprint, max_process_ordinal, process_ordinal \ @@ -360,7 +371,7 @@ impl ListTrackedSourceKeyMetadataState { } else { "NULL::bytea AS processed_source_fp" }, - db_setup.table_name + table_name ); sqlx::query_as(&self.query_str).bind(source_id).fetch(pool) } @@ -379,9 +390,10 @@ pub async fn read_source_last_processed_info( db_setup: &TrackingTableSetupState, pool: &PgPool, ) -> Result> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "SELECT processed_source_ordinal, process_logic_fingerprint, process_time_micros FROM {} WHERE source_id = $1 AND source_key = $2", - db_setup.table_name + table_name ); let last_processed_info = sqlx::query_as(&query_str) .bind(source_id) @@ -398,9 +410,10 @@ pub async fn update_source_tracking_ordinal( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(&db_setup.table_name); let query_str = format!( "UPDATE {} SET processed_source_ordinal = $3 WHERE source_id = $1 AND source_key = $2", - db_setup.table_name + table_name ); sqlx::query(&query_str) .bind(source_id) // $1 @@ -421,13 +434,14 @@ pub async fn read_source_state( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result> { - let Some(table_name) = db_setup.source_state_table_name.as_ref() else { + let Some(raw_table_name) = db_setup.source_state_table_name.as_ref() else { client_bail!("Source state table not enabled for this flow"); }; + let qualified_table_name = qualify_table_name_with_schema(raw_table_name); let query_str = format!( "SELECT value FROM {} WHERE source_id = $1 AND key = $2", - table_name + qualified_table_name ); let state: Option = sqlx::query_scalar(&query_str) .bind(source_id) @@ -445,14 +459,15 @@ pub async fn upsert_source_state( db_setup: &TrackingTableSetupState, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { - let Some(table_name) = db_setup.source_state_table_name.as_ref() else { + let Some(raw_table_name) = db_setup.source_state_table_name.as_ref() else { client_bail!("Source state table not enabled for this flow"); }; + let qualified_table_name = qualify_table_name_with_schema(raw_table_name); let query_str = format!( "INSERT INTO {} (source_id, key, value) VALUES ($1, $2, $3) \ ON CONFLICT (source_id, key) DO UPDATE SET value = EXCLUDED.value", - table_name + qualified_table_name ); sqlx::query(&query_str) .bind(source_id) diff --git a/crates/recoco-core/src/execution/db_tracking_setup.rs b/crates/recoco-core/src/execution/db_tracking_setup.rs index a2d571e9..7d35cf90 100644 --- a/crates/recoco-core/src/execution/db_tracking_setup.rs +++ b/crates/recoco-core/src/execution/db_tracking_setup.rs @@ -13,11 +13,30 @@ use crate::builder::exec_ctx::ExportOpExecutionContext; use crate::prelude::*; +use crate::lib_context::get_internal_db_schema; use crate::setup::{CombinedState, ResourceSetupChange, ResourceSetupInfo, SetupChangeType}; use recoco_utils::error::SharedError; use serde::{Deserialize, Serialize}; use sqlx::PgPool; +/// Returns the schema-qualified form of `table` based on the configured internal DB schema. +/// +/// When [`settings::Settings::db_schema_name`] is set (via +/// [`lib_context::get_internal_db_schema`]), the table is qualified as +/// `.`. Otherwise, the sanitized table name is returned as-is. +pub fn qualify_table_name_with_schema(table: &str) -> String { + let schema = get_internal_db_schema(); + if let Some(schema) = schema { + format!( + "{}.{}", + utils::db::sanitize_identifier(&schema), + utils::db::sanitize_identifier(table) + ) + } else { + utils::db::sanitize_identifier(table) + } +} + pub fn default_tracking_table_name(flow_name: &str) -> String { format!( "{}__cocoindex_tracking", @@ -34,20 +53,32 @@ pub fn default_source_state_table_name(flow_name: &str) -> String { pub const CURRENT_TRACKING_TABLE_VERSION: i32 = 1; +async fn ensure_internal_schema_exists(pool: &PgPool) -> Result<()> { + if let Some(schema) = get_internal_db_schema() { + let query = format!( + "CREATE SCHEMA IF NOT EXISTS {}", + utils::db::sanitize_identifier(&schema) + ); + sqlx::query(&query).execute(pool).await?; + } + Ok(()) +} + async fn upgrade_tracking_table( pool: &PgPool, desired_state: &TrackingTableSetupState, existing_version_id: i32, ) -> Result<()> { if existing_version_id < 1 && desired_state.version_id >= 1 { - let table_name = &desired_state.table_name; + ensure_internal_schema_exists(pool).await?; + let qualified_table_name = qualify_table_name_with_schema(&desired_state.table_name); let opt_fast_fingerprint_column = if desired_state.has_fast_fingerprint_column { "processed_source_fp BYTEA," } else { "" }; - let query = format!( - "CREATE TABLE IF NOT EXISTS {table_name} ( + let query = format!( + "CREATE TABLE IF NOT EXISTS {qualified_table_name} ( source_id INTEGER NOT NULL, source_key JSONB NOT NULL, @@ -74,6 +105,8 @@ async fn upgrade_tracking_table( } async fn create_source_state_table(pool: &PgPool, table_name: &str) -> Result<()> { + ensure_internal_schema_exists(pool).await?; + let table_name = qualify_table_name_with_schema(table_name); let query = format!( "CREATE TABLE IF NOT EXISTS {table_name} ( source_id INTEGER NOT NULL, @@ -92,6 +125,7 @@ async fn delete_source_states_for_sources( table_name: &str, source_ids: &Vec, ) -> Result<()> { + let table_name = qualify_table_name_with_schema(table_name); let query = format!("DELETE FROM {} WHERE source_id = ANY($1)", table_name,); sqlx::query(&query).bind(source_ids).execute(pool).await?; Ok(()) @@ -314,10 +348,12 @@ impl TrackingTableSetupChange { let lib_context = get_lib_context().await?; let pool = lib_context.require_builtin_db_pool()?; if let Some(desired) = &self.desired_state { - for lagacy_name in self.legacy_tracking_table_names.iter() { + for legacy_name in self.legacy_tracking_table_names.iter() { + let qualified_legacy = qualify_table_name_with_schema(legacy_name); let query = format!( "ALTER TABLE IF EXISTS {} RENAME TO {}", - lagacy_name, desired.table_name + qualified_legacy, + utils::db::sanitize_identifier(&desired.table_name) ); sqlx::query(&query).execute(pool).await?; } @@ -327,8 +363,9 @@ impl TrackingTableSetupChange { .await?; } } else { - for lagacy_name in self.legacy_tracking_table_names.iter() { - let query = format!("DROP TABLE IF EXISTS {lagacy_name}"); + for legacy_name in self.legacy_tracking_table_names.iter() { + let qualified_legacy = qualify_table_name_with_schema(legacy_name); + let query = format!("DROP TABLE IF EXISTS {}", qualified_legacy); sqlx::query(&query).execute(pool).await?; } } @@ -338,9 +375,12 @@ impl TrackingTableSetupChange { .as_ref() .and_then(|v| v.source_state_table_name.as_ref()); if let Some(source_state_table_name) = source_state_table_name { - for lagacy_name in self.legacy_source_state_table_names.iter() { + for legacy_name in self.legacy_source_state_table_names.iter() { + let qualified_legacy = qualify_table_name_with_schema(legacy_name); let query = format!( - "ALTER TABLE IF EXISTS {lagacy_name} RENAME TO {source_state_table_name}" + "ALTER TABLE IF EXISTS {} RENAME TO {}", + qualified_legacy, + utils::db::sanitize_identifier(source_state_table_name) ); sqlx::query(&query).execute(pool).await?; } @@ -360,8 +400,9 @@ impl TrackingTableSetupChange { .await?; } } else { - for lagacy_name in self.legacy_source_state_table_names.iter() { - let query = format!("DROP TABLE IF EXISTS {lagacy_name}"); + for legacy_name in self.legacy_source_state_table_names.iter() { + let qualified_legacy = qualify_table_name_with_schema(legacy_name); + let query = format!("DROP TABLE IF EXISTS {}", qualified_legacy); sqlx::query(&query).execute(pool).await?; } } diff --git a/crates/recoco-core/src/lib_context.rs b/crates/recoco-core/src/lib_context.rs index b9a1db4f..aee4568f 100644 --- a/crates/recoco-core/src/lib_context.rs +++ b/crates/recoco-core/src/lib_context.rs @@ -336,6 +336,24 @@ impl LibContext { } static LIB_INIT: OnceLock<()> = OnceLock::new(); + +/// Global storage for the internal DB schema name configured via [`settings::Settings::db_schema_name`]. +/// Set during [`create_lib_context`] and read by [`get_internal_db_schema`]. +static INTERNAL_DB_SCHEMA: LazyLock>> = + LazyLock::new(|| std::sync::RwLock::new(None)); + +/// Returns the configured internal DB schema name, if any. +/// +/// Tracking and metadata tables will be placed under this schema when set. +pub fn get_internal_db_schema() -> Option { + // Recover from lock poisoning: the inner value is still valid even if another + // thread panicked while holding the write lock. + INTERNAL_DB_SCHEMA + .read() + .unwrap_or_else(|e| e.into_inner()) + .clone() +} + pub async fn create_lib_context(settings: settings::Settings) -> Result { LIB_INIT.get_or_init(|| { // Initialize tracing subscriber with env filter for log level control @@ -350,6 +368,12 @@ pub async fn create_lib_context(settings: settings::Settings) -> Result Result> { pub async fn clear_lib_context() { let mut lib_context_locked = LIB_CONTEXT.lock().await; *lib_context_locked = None; + *INTERNAL_DB_SCHEMA + .write() + .unwrap_or_else(|e| e.into_inner()) = None; } #[cfg(test)] diff --git a/crates/recoco-core/src/settings.rs b/crates/recoco-core/src/settings.rs index 6bbb8c08..b32ed71b 100644 --- a/crates/recoco-core/src/settings.rs +++ b/crates/recoco-core/src/settings.rs @@ -32,6 +32,8 @@ pub struct Settings { #[serde(default)] pub database: Option, #[serde(default)] + pub db_schema_name: Option, + #[serde(default)] #[allow(dead_code)] // Used via serialization/deserialization to Python pub app_namespace: String, #[serde(default)] @@ -131,4 +133,24 @@ mod tests { assert_eq!(db_spec.min_connections, 1); assert_eq!(db_spec.max_connections, 10); } + + #[test] + fn test_settings_deserialize_with_schema() { + let json = r#"{ + "db_schema_name": "custom_schema" + }"#; + + let settings: Settings = serde_json::from_str(json).unwrap(); + + assert_eq!(settings.db_schema_name, Some("custom_schema".to_string())); + } + + #[test] + fn test_settings_deserialize_without_schema() { + let json = r#"{}"#; + + let settings: Settings = serde_json::from_str(json).unwrap(); + + assert_eq!(settings.db_schema_name, None); + } } diff --git a/crates/recoco-core/src/setup/db_metadata.rs b/crates/recoco-core/src/setup/db_metadata.rs index d653c4bc..fe53e340 100644 --- a/crates/recoco-core/src/setup/db_metadata.rs +++ b/crates/recoco-core/src/setup/db_metadata.rs @@ -13,11 +13,12 @@ use crate::prelude::*; use super::{ResourceSetupChange, ResourceSetupInfo, SetupChangeType, StateChange}; +use crate::lib_context::get_internal_db_schema; use axum::http::StatusCode; use sqlx::PgPool; use utils::db::WriteAction; -const SETUP_METADATA_TABLE_NAME: &str = "cocoindex_setup_metadata"; +const SETUP_METADATA_TABLE_NAME_UNQUALIFIED: &str = "cocoindex_setup_metadata"; pub const FLOW_VERSION_RESOURCE_TYPE: &str = "__FlowVersion"; #[derive(sqlx::FromRow, Debug)] @@ -30,6 +31,22 @@ pub struct SetupMetadataRecord { pub staging_changes: sqlx::types::Json>>, } +/// Returns the (potentially schema-qualified) name of the setup metadata table. +/// +/// When [`settings::Settings::db_schema_name`] is set, the table is qualified as +/// `.cocoindex_setup_metadata`. Otherwise the unqualified name is returned. +pub fn get_setup_metadata_table_name() -> String { + let schema = get_internal_db_schema(); + if let Some(schema) = schema { + format!( + "{}.{SETUP_METADATA_TABLE_NAME_UNQUALIFIED}", + utils::db::sanitize_identifier(&schema) + ) + } else { + SETUP_METADATA_TABLE_NAME_UNQUALIFIED.to_string() + } +} + pub fn parse_flow_version(state: &Option) -> Option { match state { Some(serde_json::Value::Number(n)) => n.as_u64(), @@ -40,17 +57,20 @@ pub fn parse_flow_version(state: &Option) -> Option { /// Returns None if metadata table doesn't exist. pub async fn read_setup_metadata(pool: &PgPool) -> Result>> { let mut db_conn = pool.acquire().await?; - let query_str = format!( - "SELECT flow_name, resource_type, key, state, staging_changes FROM {SETUP_METADATA_TABLE_NAME}", - ); + let table_name = get_setup_metadata_table_name(); + let query_str = + format!("SELECT flow_name, resource_type, key, state, staging_changes FROM {table_name}",); let metadata = sqlx::query_as(&query_str).fetch_all(&mut *db_conn).await; let result = match metadata { Ok(metadata) => Some(metadata), Err(err) => { + // Use to_regclass to check existence: it respects the connection's search_path + // and schema qualification, so it works correctly regardless of whether a custom + // db_schema_name is configured or the connection uses a non-public default schema. let exists: Option = sqlx::query_scalar( - "SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public' AND tablename = $1)", + "SELECT to_regclass($1) IS NOT NULL", ) - .bind(SETUP_METADATA_TABLE_NAME) + .bind(&table_name) .fetch_one(&mut *db_conn) .await?; if !exists.unwrap_or(false) { @@ -84,8 +104,9 @@ async fn read_metadata_records_for_flow( flow_name: &str, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result> { + let table_name = get_setup_metadata_table_name(); let query_str = format!( - "SELECT flow_name, resource_type, key, state, staging_changes FROM {SETUP_METADATA_TABLE_NAME} WHERE flow_name = $1", + "SELECT flow_name, resource_type, key, state, staging_changes FROM {table_name} WHERE flow_name = $1", ); let metadata: Vec = sqlx::query_as(&query_str) .bind(flow_name) @@ -111,8 +132,9 @@ async fn read_state( type_id: &ResourceTypeKey, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result> { + let table_name = get_setup_metadata_table_name(); let query_str = format!( - "SELECT state FROM {SETUP_METADATA_TABLE_NAME} WHERE flow_name = $1 AND resource_type = $2 AND key = $3", + "SELECT state FROM {table_name} WHERE flow_name = $1 AND resource_type = $2 AND key = $3", ); let state: Option = sqlx::query_scalar(&query_str) .bind(flow_name) @@ -130,12 +152,13 @@ async fn upsert_staging_changes( db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, action: WriteAction, ) -> Result<()> { + let table_name = get_setup_metadata_table_name(); let query_str = match action { WriteAction::Insert => format!( - "INSERT INTO {SETUP_METADATA_TABLE_NAME} (flow_name, resource_type, key, staging_changes) VALUES ($1, $2, $3, $4)", + "INSERT INTO {table_name} (flow_name, resource_type, key, staging_changes) VALUES ($1, $2, $3, $4)", ), WriteAction::Update => format!( - "UPDATE {SETUP_METADATA_TABLE_NAME} SET staging_changes = $4 WHERE flow_name = $1 AND resource_type = $2 AND key = $3", + "UPDATE {table_name} SET staging_changes = $4 WHERE flow_name = $1 AND resource_type = $2 AND key = $3", ), }; sqlx::query(&query_str) @@ -155,12 +178,13 @@ async fn upsert_state( action: WriteAction, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { + let table_name = get_setup_metadata_table_name(); let query_str = match action { WriteAction::Insert => format!( - "INSERT INTO {SETUP_METADATA_TABLE_NAME} (flow_name, resource_type, key, state, staging_changes) VALUES ($1, $2, $3, $4, $5)", + "INSERT INTO {table_name} (flow_name, resource_type, key, state, staging_changes) VALUES ($1, $2, $3, $4, $5)", ), WriteAction::Update => format!( - "UPDATE {SETUP_METADATA_TABLE_NAME} SET state = $4, staging_changes = $5 WHERE flow_name = $1 AND resource_type = $2 AND key = $3", + "UPDATE {table_name} SET state = $4, staging_changes = $5 WHERE flow_name = $1 AND resource_type = $2 AND key = $3", ), }; sqlx::query(&query_str) @@ -179,8 +203,9 @@ async fn delete_state( type_id: &ResourceTypeKey, db_executor: impl sqlx::Executor<'_, Database = sqlx::Postgres>, ) -> Result<()> { + let table_name = get_setup_metadata_table_name(); let query_str = format!( - "DELETE FROM {SETUP_METADATA_TABLE_NAME} WHERE flow_name = $1 AND resource_type = $2 AND key = $3", + "DELETE FROM {table_name} WHERE flow_name = $1 AND resource_type = $2 AND key = $3", ); sqlx::query(&query_str) .bind(flow_name) @@ -347,7 +372,7 @@ impl ResourceSetupChange for MetadataTableSetup { fn describe_changes(&self) -> Vec { if self.metadata_table_missing { vec![setup::ChangeDescription::Action(format!( - "Create the cocoindex metadata table {SETUP_METADATA_TABLE_NAME}" + "Create the cocoindex metadata table {SETUP_METADATA_TABLE_NAME_UNQUALIFIED}" ))] } else { vec![] @@ -370,8 +395,19 @@ impl MetadataTableSetup { } let lib_context = get_lib_context().await?; let pool = lib_context.require_builtin_db_pool()?; + + // Create the schema if a custom schema is configured. + if let Some(schema) = get_internal_db_schema() { + let query_str = format!( + "CREATE SCHEMA IF NOT EXISTS {}", + utils::db::sanitize_identifier(&schema) + ); + sqlx::query(&query_str).execute(pool).await?; + } + + let table_name = get_setup_metadata_table_name(); let query_str = format!( - "CREATE TABLE IF NOT EXISTS {SETUP_METADATA_TABLE_NAME} ( + "CREATE TABLE IF NOT EXISTS {table_name} ( flow_name TEXT NOT NULL, resource_type TEXT NOT NULL, key JSONB NOT NULL, diff --git a/site/src/content/docs/reference/configuration.md b/site/src/content/docs/reference/configuration.md index 5fed02cf..01cae309 100644 --- a/site/src/content/docs/reference/configuration.md +++ b/site/src/content/docs/reference/configuration.md @@ -41,6 +41,10 @@ let settings = Settings { min_connections: 1, }), + // Optional: store internal tracking tables in a dedicated schema + // instead of the connection's default schema (often `public`) + db_schema_name: Some("recoco_state".to_string()), + // Concurrency controls global_execution_options: GlobalExecutionOptions { source_max_inflight_rows: Some(1000), @@ -82,9 +86,25 @@ Controls concurrency and backpressure during flow execution. | Field | Type | Default | Description | |-------|------|---------|-------------| +| `db_schema_name` | `Option` | `None` | PostgreSQL schema for internal Recoco tracking/metadata tables. When set, a schema is auto-created and all internal tables are placed there, keeping them separate from application tables. When unset, the connection's default schema (often `public`, but determined by `search_path`) is used. | | `app_namespace` | `String` | `""` | Namespace prefix for database tables and keys (empty string means no prefix) | | `ignore_target_drop_failures` | `bool` | `false` | Suppress errors when dropping target tables during teardown | +### `db_schema_name` Detail + +The `db_schema_name` field places all Recoco-internal tables (e.g., `cocoindex_setup_metadata`, `__cocoindex_tracking`) into a dedicated PostgreSQL schema: + +```rust +let settings = Settings { + db_schema_name: Some("recoco_state".to_string()), + ..Default::default() +}; +``` + +- The schema is automatically created (`CREATE SCHEMA IF NOT EXISTS`) when Recoco sets up for the first time. +- Keeping internal tables in their own schema avoids name collisions with application tables and simplifies DB hygiene in multi-tenant or shared-database environments. +- When `db_schema_name` is `None` (the default), tables are created in the connection's default schema (the first entry in `search_path`, often `public`). + ## Environment Variables | Variable | Description | Default | From 348d96cee5667239fd85d8e92a43c734edf54457 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 20:26:25 -0400 Subject: [PATCH 30/38] feat(targets): add target-ladybug (Kuzu successor) (#95) * Initial plan * feat: add target-ladybug feature (Kuzu successor) Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * feat: complete target-ladybug implementation with registration and feature gates Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * fix(target-ladybug): replace itertools .join() with std collect+join, add serde-only doc comments Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- crates/recoco-core/Cargo.toml | 2 + crates/recoco-core/src/ops/registration.rs | 9 +- crates/recoco-core/src/ops/targets/ladybug.rs | 1118 +++++++++++++++++ crates/recoco-core/src/ops/targets/mod.rs | 3 + crates/recoco-core/src/prelude.rs | 1 + 5 files changed, 1131 insertions(+), 2 deletions(-) create mode 100644 crates/recoco-core/src/ops/targets/ladybug.rs diff --git a/crates/recoco-core/Cargo.toml b/crates/recoco-core/Cargo.toml index eef3312c..ab95351c 100644 --- a/crates/recoco-core/Cargo.toml +++ b/crates/recoco-core/Cargo.toml @@ -122,6 +122,7 @@ all-sources = [ all-splitter-languages = ["recoco-splitters/all"] all-targets = [ "target-kuzu", + "target-ladybug", "target-neo4j", "target-postgres", "target-qdrant", @@ -297,6 +298,7 @@ splitter-language-xml = ["recoco-splitters/xml"] splitter-language-yaml = ["recoco-splitters/yaml"] # Targets target-kuzu = ["dep:reqwest", "recoco-utils/reqwest", "target-neo4j"] +target-ladybug = ["dep:reqwest", "recoco-utils/reqwest", "target-neo4j"] target-neo4j = ["dep:neo4rs", "recoco-utils/neo4rs", "recoco-utils/retryable"] target-postgres = ["dep:itertools", "source-postgres"] target-qdrant = ["dep:qdrant-client", "recoco-utils/qdrant"] diff --git a/crates/recoco-core/src/ops/registration.rs b/crates/recoco-core/src/ops/registration.rs index b8fa7fdd..c60d7c82 100644 --- a/crates/recoco-core/src/ops/registration.rs +++ b/crates/recoco-core/src/ops/registration.rs @@ -28,6 +28,7 @@ use super::functions; use super::sources; #[cfg(any( feature = "target-kuzu", + feature = "target-ladybug", feature = "target-neo4j", feature = "target-postgres", feature = "target-qdrant" @@ -42,7 +43,7 @@ use std::sync::{LazyLock, RwLock}; fn register_executor_factories( #[allow(unused_variables)] registry: &mut ExecutorFactoryRegistry, ) -> Result<()> { - #[cfg(feature = "target-kuzu")] + #[cfg(any(feature = "target-kuzu", feature = "target-ladybug"))] let reqwest_client = reqwest::Client::new(); #[cfg(feature = "source-local-file")] @@ -73,8 +74,12 @@ fn register_executor_factories( targets::postgres::register(registry)?; #[cfg(feature = "target-qdrant")] targets::qdrant::register(registry)?; - #[cfg(feature = "target-kuzu")] + #[cfg(all(feature = "target-kuzu", feature = "target-ladybug"))] + targets::kuzu::register(registry, reqwest_client.clone())?; + #[cfg(all(feature = "target-kuzu", not(feature = "target-ladybug")))] targets::kuzu::register(registry, reqwest_client)?; + #[cfg(feature = "target-ladybug")] + targets::ladybug::register(registry, reqwest_client)?; #[cfg(feature = "target-neo4j")] targets::neo4j::Factory::new().register(registry)?; diff --git a/crates/recoco-core/src/ops/targets/ladybug.rs b/crates/recoco-core/src/ops/targets/ladybug.rs new file mode 100644 index 00000000..fb51f18e --- /dev/null +++ b/crates/recoco-core/src/ops/targets/ladybug.rs @@ -0,0 +1,1118 @@ +// Recoco is a Rust-only fork of CocoIndex, by [CocoIndex](https://CocoIndex) +// Original code from CocoIndex is copyrighted by CocoIndex +// SPDX-FileCopyrightText: 2025-2026 CocoIndex (upstream) +// SPDX-FileContributor: CocoIndex Contributors +// +// All modifications from the upstream for Recoco are copyrighted by Knitli Inc. +// SPDX-FileCopyrightText: 2026 Knitli Inc. (Recoco) +// SPDX-FileContributor: Adam Poulemanos +// +// Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. +// SPDX-License-Identifier: Apache-2.0 + +use chrono::TimeDelta; +use serde_json::json; + +use std::fmt::Write; + +use super::shared::property_graph::GraphElementMapping; +use super::shared::property_graph::*; +use super::shared::table_columns::{ + TableColumnsSchema, TableMainSetupAction, TableUpsertionAction, check_table_compatibility, +}; +use crate::ops::registry::ExecutorFactoryRegistry; +use crate::prelude::*; + +use crate::setup::SetupChangeType; +use crate::{ops::sdk::*, setup::CombinedState}; + +const SELF_CONTAINED_TAG_FIELD_NAME: &str = "__self_contained"; + +//////////////////////////////////////////////////////////// +// Public Types +//////////////////////////////////////////////////////////// + +/// Connection configuration for a Ladybug graph database instance. +/// +/// This is a serde-deserialized config-only type; populate it via +/// the auth-entry / YAML configuration rather than direct construction. +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct ConnectionSpec { + /// The URL of the [Ladybug API server](https://github.com/LadybugDB/ladybug), + /// e.g. `http://localhost:8000`. + api_server_url: String, +} + +/// Target spec for exporting data to a Ladybug graph database. +/// +/// This is a serde-deserialized config-only type; populate it via +/// the auth-entry / YAML configuration rather than direct construction. +#[derive(Debug, Serialize, Deserialize)] +pub struct Spec { + connection: spec::AuthEntryReference, + mapping: GraphElementMapping, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Declaration { + connection: spec::AuthEntryReference, + #[serde(flatten)] + decl: GraphDeclaration, +} + +//////////////////////////////////////////////////////////// +// Utils to deal with Ladybug +//////////////////////////////////////////////////////////// + +struct CypherBuilder { + query: String, +} + +impl CypherBuilder { + fn new() -> Self { + Self { + query: String::new(), + } + } + + fn query_mut(&mut self) -> &mut String { + &mut self.query + } +} + +struct LadybugThinClient { + reqwest_client: reqwest::Client, + query_url: String, +} + +impl LadybugThinClient { + fn new(conn_spec: &ConnectionSpec, reqwest_client: reqwest::Client) -> Self { + Self { + reqwest_client, + query_url: format!("{}/cypher", conn_spec.api_server_url.trim_end_matches('/')), + } + } + + async fn run_cypher(&self, cypher_builder: CypherBuilder) -> Result<()> { + if cypher_builder.query.is_empty() { + return Ok(()); + } + let query = json!({ + "query": cypher_builder.query + }); + http::request(|| self.reqwest_client.post(&self.query_url).json(&query)) + .await + .with_context(|| "Ladybug API error")?; + Ok(()) + } +} + +fn ladybug_table_type(elem_type: &ElementType) -> &'static str { + match elem_type { + ElementType::Node(_) => "NODE", + ElementType::Relationship(_) => "REL", + } +} + +fn basic_type_to_ladybug(basic_type: &BasicValueType) -> Result { + Ok(match basic_type { + BasicValueType::Bytes => "BLOB".to_string(), + BasicValueType::Str => "STRING".to_string(), + BasicValueType::Bool => "BOOL".to_string(), + BasicValueType::Int64 => "INT64".to_string(), + BasicValueType::Float32 => "FLOAT".to_string(), + BasicValueType::Float64 => "DOUBLE".to_string(), + BasicValueType::Range => "UINT64[2]".to_string(), + BasicValueType::Uuid => "UUID".to_string(), + BasicValueType::Date => "DATE".to_string(), + BasicValueType::LocalDateTime => "TIMESTAMP".to_string(), + BasicValueType::OffsetDateTime => "TIMESTAMP".to_string(), + BasicValueType::TimeDelta => "INTERVAL".to_string(), + BasicValueType::Vector(t) => format!( + "{}[{}]", + basic_type_to_ladybug(&t.element_type)?, + t.dimension + .map_or_else(|| "".to_string(), |d| d.to_string()) + ), + t @ (BasicValueType::Union(_) | BasicValueType::Time | BasicValueType::Json) => { + api_bail!("{t} is not supported in Ladybug") + } + }) +} + +fn struct_schema_to_ladybug(struct_schema: &StructSchema) -> Result { + Ok(format!( + "STRUCT({})", + struct_schema + .fields + .iter() + .map(|f| Ok(format!( + "{} {}", + f.name, + value_type_to_ladybug(&f.value_type.typ)? + ))) + .collect::>>()? + .join(", ") + )) +} + +fn value_type_to_ladybug(value_type: &ValueType) -> Result { + Ok(match value_type { + ValueType::Basic(basic_type) => basic_type_to_ladybug(basic_type)?, + ValueType::Struct(struct_type) => struct_schema_to_ladybug(struct_type)?, + ValueType::Table(table_type) => format!("{}[]", struct_schema_to_ladybug(&table_type.row)?), + }) +} + +//////////////////////////////////////////////////////////// +// Setup +//////////////////////////////////////////////////////////// + +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +struct ReferencedNodeTable { + table_name: String, + + #[serde(with = "indexmap::map::serde_seq")] + key_columns: IndexMap, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +struct SetupState { + schema: TableColumnsSchema, + + #[serde(default, skip_serializing_if = "Option::is_none")] + referenced_node_tables: Option<(ReferencedNodeTable, ReferencedNodeTable)>, +} + +impl<'a> From<&'a SetupState> for Cow<'a, TableColumnsSchema> { + fn from(val: &'a SetupState) -> Self { + Cow::Borrowed(&val.schema) + } +} + +#[derive(Debug)] +struct GraphElementDataSetupChange { + actions: TableMainSetupAction, + referenced_node_tables: Option<(String, String)>, + drop_affected_referenced_node_tables: IndexSet, +} + +impl setup::ResourceSetupChange for GraphElementDataSetupChange { + fn describe_changes(&self) -> Vec { + self.actions.describe_changes() + } + + fn change_type(&self) -> SetupChangeType { + self.actions.change_type(false) + } +} + +fn append_drop_table( + cypher: &mut CypherBuilder, + setup_change: &GraphElementDataSetupChange, + elem_type: &ElementType, +) -> Result<()> { + if !setup_change.actions.drop_existing { + return Ok(()); + } + writeln!( + cypher.query_mut(), + "DROP TABLE IF EXISTS {};", + elem_type.label() + )?; + Ok(()) +} + +fn append_delete_orphaned_nodes(cypher: &mut CypherBuilder, node_table: &str) -> Result<()> { + writeln!( + cypher.query_mut(), + "MATCH (n:{node_table}) WITH n WHERE NOT (n)--() DELETE n;" + )?; + Ok(()) +} + +fn append_upsert_table( + cypher: &mut CypherBuilder, + setup_change: &GraphElementDataSetupChange, + elem_type: &ElementType, +) -> Result<()> { + let table_upsertion = if let Some(table_upsertion) = &setup_change.actions.table_upsertion { + table_upsertion + } else { + return Ok(()); + }; + match table_upsertion { + TableUpsertionAction::Create { keys, values } => { + write!( + cypher.query_mut(), + "CREATE {ladybug_table_type} TABLE IF NOT EXISTS {table_name} (", + ladybug_table_type = ladybug_table_type(elem_type), + table_name = elem_type.label(), + )?; + if let Some((src, tgt)) = &setup_change.referenced_node_tables { + write!(cypher.query_mut(), "FROM {src} TO {tgt}, ")?; + } + cypher.query_mut().push_str( + keys.iter() + .chain(values.iter()) + .map(|(name, ladybug_type)| format!("{name} {ladybug_type}")) + .collect::>() + .join(", ") + .as_str(), + ); + match elem_type { + ElementType::Node(_) => { + write!( + cypher.query_mut(), + ", {SELF_CONTAINED_TAG_FIELD_NAME} BOOL, PRIMARY KEY ({})", + keys.iter() + .map(|(name, _)| name.as_str()) + .collect::>() + .join(", ") + )?; + } + ElementType::Relationship(_) => {} + } + write!(cypher.query_mut(), ");\n\n")?; + } + TableUpsertionAction::Update { + columns_to_delete, + columns_to_upsert, + } => { + let table_name = elem_type.label(); + for name in columns_to_delete + .iter() + .chain(columns_to_upsert.iter().map(|(name, _)| name)) + { + writeln!( + cypher.query_mut(), + "ALTER TABLE {table_name} DROP IF EXISTS {name};" + )?; + } + for (name, ladybug_type) in columns_to_upsert.iter() { + writeln!( + cypher.query_mut(), + "ALTER TABLE {table_name} ADD {name} {ladybug_type};", + )?; + } + } + } + Ok(()) +} + +//////////////////////////////////////////////////////////// +// Utils to convert value to Ladybug literals +//////////////////////////////////////////////////////////// + +fn append_string_literal(cypher: &mut CypherBuilder, s: &str) -> Result<()> { + let out = cypher.query_mut(); + out.push('"'); + for c in s.chars() { + match c { + '\\' => out.push_str("\\\\"), + '"' => out.push_str("\\\""), + // Control characters (0x00..=0x1F) + c if (c as u32) < 0x20 => write!(out, "\\u{:04X}", c as u32)?, + // BMP Unicode + c if (c as u32) <= 0xFFFF => out.push(c), + // Non-BMP Unicode: Encode as surrogate pairs for Cypher \uXXXX\uXXXX + c => { + let code = c as u32; + let high = 0xD800 + ((code - 0x10000) >> 10); + let low = 0xDC00 + ((code - 0x10000) & 0x3FF); + write!(out, "\\u{high:04X}\\u{low:04X}")?; + } + } + } + out.push('"'); + Ok(()) +} + +fn append_basic_value(cypher: &mut CypherBuilder, basic_value: &BasicValue) -> Result<()> { + match basic_value { + BasicValue::Bytes(bytes) => { + write!(cypher.query_mut(), "BLOB(")?; + for byte in bytes { + write!(cypher.query_mut(), "\\\\x{byte:02X}")?; + } + write!(cypher.query_mut(), ")")?; + } + BasicValue::Str(s) => { + append_string_literal(cypher, s)?; + } + BasicValue::Bool(b) => { + write!(cypher.query_mut(), "{b}")?; + } + BasicValue::Int64(i) => { + write!(cypher.query_mut(), "{i}")?; + } + BasicValue::Float32(f) => { + write!(cypher.query_mut(), "{f}")?; + } + BasicValue::Float64(f) => { + write!(cypher.query_mut(), "{f}")?; + } + BasicValue::Range(r) => { + write!(cypher.query_mut(), "[{}, {}]", r.start, r.end)?; + } + BasicValue::Uuid(u) => { + write!(cypher.query_mut(), "UUID(\"{u}\")")?; + } + BasicValue::Date(d) => { + write!(cypher.query_mut(), "DATE(\"{d}\")")?; + } + BasicValue::LocalDateTime(dt) => write!(cypher.query_mut(), "TIMESTAMP(\"{dt}\")")?, + BasicValue::OffsetDateTime(dt) => write!(cypher.query_mut(), "TIMESTAMP(\"{dt}\")")?, + BasicValue::TimeDelta(td) => { + let num_days = td.num_days(); + let sub_day_duration = *td - TimeDelta::days(num_days); + write!(cypher.query_mut(), "INTERVAL(\"")?; + if num_days != 0 { + write!(cypher.query_mut(), "{num_days} days ")?; + } + let microseconds = sub_day_duration + .num_microseconds() + .ok_or_else(invariance_violation)?; + write!(cypher.query_mut(), "{microseconds} microseconds\")")?; + } + BasicValue::Vector(v) => { + write!(cypher.query_mut(), "[")?; + let mut prefix = ""; + for elem in v.iter() { + cypher.query_mut().push_str(prefix); + append_basic_value(cypher, elem)?; + prefix = ", "; + } + write!(cypher.query_mut(), "]")?; + } + v @ (BasicValue::UnionVariant { .. } | BasicValue::Time(_) | BasicValue::Json(_)) => { + client_bail!("value types are not supported in Ladybug: {}", v.kind()); + } + } + Ok(()) +} + +fn append_struct_fields<'a>( + cypher: &'a mut CypherBuilder, + field_schema: &[schema::FieldSchema], + field_values: impl Iterator, +) -> Result<()> { + let mut prefix = ""; + for (f, v) in std::iter::zip(field_schema.iter(), field_values) { + write!(cypher.query_mut(), "{prefix}{}: ", f.name)?; + append_value(cypher, &f.value_type.typ, v)?; + prefix = ", "; + } + Ok(()) +} + +fn append_value( + cypher: &mut CypherBuilder, + typ: &schema::ValueType, + value: &value::Value, +) -> Result<()> { + match value { + value::Value::Null => { + write!(cypher.query_mut(), "NULL")?; + } + value::Value::Basic(basic_value) => append_basic_value(cypher, basic_value)?, + value::Value::Struct(struct_value) => { + let struct_schema = match typ { + schema::ValueType::Struct(struct_schema) => struct_schema, + _ => { + api_bail!("Expected struct type, got {}", typ); + } + }; + cypher.query_mut().push('{'); + append_struct_fields(cypher, &struct_schema.fields, struct_value.fields.iter())?; + cypher.query_mut().push('}'); + } + value::Value::KTable(map) => { + let row_schema = match typ { + schema::ValueType::Table(table_schema) => &table_schema.row, + _ => { + api_bail!("Expected table type, got {}", typ); + } + }; + cypher.query_mut().push('['); + let mut prefix = ""; + for (k, v) in map.iter() { + cypher.query_mut().push_str(prefix); + cypher.query_mut().push('{'); + append_struct_fields( + cypher, + &row_schema.fields, + k.to_values().iter().chain(v.fields.iter()), + )?; + cypher.query_mut().push('}'); + prefix = ", "; + } + cypher.query_mut().push(']'); + } + value::Value::LTable(rows) | value::Value::UTable(rows) => { + let row_schema = match typ { + schema::ValueType::Table(table_schema) => &table_schema.row, + _ => { + api_bail!("Expected table type, got {}", typ); + } + }; + cypher.query_mut().push('['); + let mut prefix = ""; + for v in rows.iter() { + cypher.query_mut().push_str(prefix); + cypher.query_mut().push('{'); + append_struct_fields(cypher, &row_schema.fields, v.fields.iter())?; + cypher.query_mut().push('}'); + prefix = ", "; + } + cypher.query_mut().push(']'); + } + } + Ok(()) +} + +//////////////////////////////////////////////////////////// +// Deal with mutations +//////////////////////////////////////////////////////////// + +struct ExportContext { + conn_ref: AuthEntryReference, + ladybug_client: LadybugThinClient, + analyzed_data_coll: AnalyzedDataCollection, +} + +fn append_key_pattern<'a>( + cypher: &'a mut CypherBuilder, + key_fields: &'a [FieldSchema], + values: impl Iterator>, +) -> Result<()> { + write!(cypher.query_mut(), "{{")?; + let mut prefix = ""; + for (f, v) in std::iter::zip(key_fields.iter(), values) { + write!(cypher.query_mut(), "{prefix}{}: ", f.name)?; + append_value(cypher, &f.value_type.typ, v.as_ref())?; + prefix = ", "; + } + write!(cypher.query_mut(), "}}")?; + Ok(()) +} + +fn append_set_value_fields( + cypher: &mut CypherBuilder, + var_name: &str, + value_fields: &[FieldSchema], + value_fields_idx: &[usize], + upsert_entry: &ExportTargetUpsertEntry, + set_self_contained_tag: bool, +) -> Result<()> { + let mut prefix = " SET "; + if set_self_contained_tag { + write!( + cypher.query_mut(), + "{prefix}{var_name}.{SELF_CONTAINED_TAG_FIELD_NAME} = TRUE" + )?; + prefix = ", "; + } + for (value_field, value_idx) in std::iter::zip(value_fields.iter(), value_fields_idx.iter()) { + let field_name = &value_field.name; + write!(cypher.query_mut(), "{prefix}{var_name}.{field_name}=")?; + append_value( + cypher, + &value_field.value_type.typ, + &upsert_entry.value.fields[*value_idx], + )?; + prefix = ", "; + } + Ok(()) +} + +fn append_upsert_node( + cypher: &mut CypherBuilder, + data_coll: &AnalyzedDataCollection, + upsert_entry: &ExportTargetUpsertEntry, +) -> Result<()> { + const NODE_VAR_NAME: &str = "n"; + { + write!( + cypher.query_mut(), + "MERGE ({NODE_VAR_NAME}:{label} ", + label = data_coll.schema.elem_type.label(), + )?; + append_key_pattern( + cypher, + &data_coll.schema.key_fields, + upsert_entry + .key + .iter() + .map(|f| Cow::Owned(value::Value::from(f))), + )?; + write!(cypher.query_mut(), ")")?; + } + append_set_value_fields( + cypher, + NODE_VAR_NAME, + &data_coll.schema.value_fields, + &data_coll.value_fields_input_idx, + upsert_entry, + true, + )?; + writeln!(cypher.query_mut(), ";")?; + Ok(()) +} + +fn append_merge_node_for_rel( + cypher: &mut CypherBuilder, + var_name: &str, + field_mapping: &AnalyzedGraphElementFieldMapping, + upsert_entry: &ExportTargetUpsertEntry, +) -> Result<()> { + { + write!( + cypher.query_mut(), + "MERGE ({var_name}:{label} ", + label = field_mapping.schema.elem_type.label(), + )?; + append_key_pattern( + cypher, + &field_mapping.schema.key_fields, + field_mapping + .fields_input_idx + .key + .iter() + .map(|idx| Cow::Borrowed(&upsert_entry.value.fields[*idx])), + )?; + write!(cypher.query_mut(), ")")?; + } + append_set_value_fields( + cypher, + var_name, + &field_mapping.schema.value_fields, + &field_mapping.fields_input_idx.value, + upsert_entry, + false, + )?; + writeln!(cypher.query_mut())?; + Ok(()) +} + +fn append_upsert_rel( + cypher: &mut CypherBuilder, + data_coll: &AnalyzedDataCollection, + upsert_entry: &ExportTargetUpsertEntry, +) -> Result<()> { + const REL_VAR_NAME: &str = "r"; + const SRC_NODE_VAR_NAME: &str = "s"; + const TGT_NODE_VAR_NAME: &str = "t"; + + let rel_info = if let Some(rel_info) = &data_coll.rel { + rel_info + } else { + return Ok(()); + }; + append_merge_node_for_rel(cypher, SRC_NODE_VAR_NAME, &rel_info.source, upsert_entry)?; + append_merge_node_for_rel(cypher, TGT_NODE_VAR_NAME, &rel_info.target, upsert_entry)?; + { + let rel_type = data_coll.schema.elem_type.label(); + write!( + cypher.query_mut(), + "MERGE ({SRC_NODE_VAR_NAME})-[{REL_VAR_NAME}:{rel_type} " + )?; + append_key_pattern( + cypher, + &data_coll.schema.key_fields, + upsert_entry + .key + .iter() + .map(|f| Cow::Owned(value::Value::from(f))), + )?; + write!(cypher.query_mut(), "]->({TGT_NODE_VAR_NAME})")?; + } + append_set_value_fields( + cypher, + REL_VAR_NAME, + &data_coll.schema.value_fields, + &data_coll.value_fields_input_idx, + upsert_entry, + false, + )?; + writeln!(cypher.query_mut(), ";")?; + Ok(()) +} + +fn append_delete_node( + cypher: &mut CypherBuilder, + data_coll: &AnalyzedDataCollection, + key: &KeyValue, +) -> Result<()> { + const NODE_VAR_NAME: &str = "n"; + let node_label = data_coll.schema.elem_type.label(); + write!(cypher.query_mut(), "MATCH ({NODE_VAR_NAME}:{node_label} ")?; + append_key_pattern( + cypher, + &data_coll.schema.key_fields, + key.iter().map(|f| Cow::Owned(value::Value::from(f))), + )?; + writeln!(cypher.query_mut(), ")")?; + writeln!( + cypher.query_mut(), + "WITH {NODE_VAR_NAME} SET {NODE_VAR_NAME}.{SELF_CONTAINED_TAG_FIELD_NAME} = NULL" + )?; + writeln!( + cypher.query_mut(), + "WITH {NODE_VAR_NAME} WHERE NOT ({NODE_VAR_NAME})--() DELETE {NODE_VAR_NAME}" + )?; + writeln!(cypher.query_mut(), ";")?; + Ok(()) +} + +fn append_delete_rel( + cypher: &mut CypherBuilder, + data_coll: &AnalyzedDataCollection, + key: &KeyValue, + src_node_key: &KeyValue, + tgt_node_key: &KeyValue, +) -> Result<()> { + const REL_VAR_NAME: &str = "r"; + + let rel = data_coll.rel.as_ref().ok_or_else(invariance_violation)?; + let rel_type = data_coll.schema.elem_type.label(); + + write!( + cypher.query_mut(), + "MATCH (:{label} ", + label = rel.source.schema.elem_type.label() + )?; + let src_key_schema = &rel.source.schema.key_fields; + append_key_pattern( + cypher, + src_key_schema, + src_node_key + .iter() + .map(|k| Cow::Owned(value::Value::from(k))), + )?; + + write!(cypher.query_mut(), ")-[{REL_VAR_NAME}:{rel_type} ")?; + let key_schema = &data_coll.schema.key_fields; + append_key_pattern( + cypher, + key_schema, + key.iter().map(|k| Cow::Owned(value::Value::from(k))), + )?; + + write!( + cypher.query_mut(), + "]->(:{label} ", + label = rel.target.schema.elem_type.label() + )?; + let tgt_key_schema = &rel.target.schema.key_fields; + append_key_pattern( + cypher, + tgt_key_schema, + tgt_node_key + .iter() + .map(|k| Cow::Owned(value::Value::from(k))), + )?; + write!(cypher.query_mut(), ") DELETE {REL_VAR_NAME}")?; + writeln!(cypher.query_mut(), ";")?; + Ok(()) +} + +fn append_maybe_gc_node( + cypher: &mut CypherBuilder, + schema: &GraphElementSchema, + key: &KeyValue, +) -> Result<()> { + const NODE_VAR_NAME: &str = "n"; + let node_label = schema.elem_type.label(); + write!(cypher.query_mut(), "MATCH ({NODE_VAR_NAME}:{node_label} ")?; + append_key_pattern( + cypher, + &schema.key_fields, + key.iter().map(|f| Cow::Owned(value::Value::from(f))), + )?; + writeln!(cypher.query_mut(), ")")?; + write!( + cypher.query_mut(), + "WITH {NODE_VAR_NAME} WHERE NOT ({NODE_VAR_NAME})--() DELETE {NODE_VAR_NAME}" + )?; + writeln!(cypher.query_mut(), ";")?; + Ok(()) +} + +//////////////////////////////////////////////////////////// +// Factory implementation +//////////////////////////////////////////////////////////// + +type LadybugGraphElement = GraphElementType; + +struct Factory { + reqwest_client: reqwest::Client, +} + +#[async_trait] +impl TargetFactoryBase for Factory { + type Spec = Spec; + type DeclarationSpec = Declaration; + type SetupState = SetupState; + type SetupChange = GraphElementDataSetupChange; + + type SetupKey = LadybugGraphElement; + type ExportContext = ExportContext; + + fn name(&self) -> &str { + "Ladybug" + } + + async fn build( + self: Arc, + data_collections: Vec>, + declarations: Vec, + context: Arc, + ) -> Result<( + Vec>, + Vec<(LadybugGraphElement, SetupState)>, + )> { + let (analyzed_data_colls, declared_graph_elements) = analyze_graph_mappings( + data_collections + .iter() + .map(|d| DataCollectionGraphMappingInput { + auth_ref: &d.spec.connection, + mapping: &d.spec.mapping, + index_options: &d.index_options, + key_fields_schema: d.key_fields_schema.clone(), + value_fields_schema: d.value_fields_schema.clone(), + }), + declarations.iter().map(|d| (&d.connection, &d.decl)), + )?; + fn to_ladybug_cols(fields: &[FieldSchema]) -> Result> { + fields + .iter() + .map(|f| Ok((f.name.clone(), value_type_to_ladybug(&f.value_type.typ)?))) + .collect::>>() + } + let data_coll_outputs: Vec> = + std::iter::zip(data_collections, analyzed_data_colls.into_iter()) + .map(|(data_coll, analyzed)| { + if !data_coll.index_options.vector_indexes.is_empty() { + api_bail!("Vector indexes are not supported for Ladybug yet"); + } + if !data_coll.index_options.fts_indexes.is_empty() { + api_bail!("FTS indexes are not supported for Ladybug target"); + } + fn to_dep_table( + field_mapping: &AnalyzedGraphElementFieldMapping, + ) -> Result { + Ok(ReferencedNodeTable { + table_name: field_mapping.schema.elem_type.label().to_string(), + key_columns: to_ladybug_cols(&field_mapping.schema.key_fields)?, + }) + } + let setup_key = LadybugGraphElement { + connection: data_coll.spec.connection.clone(), + typ: analyzed.schema.elem_type.clone(), + }; + let desired_setup_state = SetupState { + schema: TableColumnsSchema { + key_columns: to_ladybug_cols(&analyzed.schema.key_fields)?, + value_columns: to_ladybug_cols(&analyzed.schema.value_fields)?, + }, + referenced_node_tables: (analyzed.rel.as_ref()) + .map(|rel| -> Result<_> { + Ok((to_dep_table(&rel.source)?, to_dep_table(&rel.target)?)) + }) + .transpose()?, + }; + + let export_context = ExportContext { + conn_ref: data_coll.spec.connection.clone(), + ladybug_client: LadybugThinClient::new( + &context + .auth_registry + .get::(&data_coll.spec.connection)?, + self.reqwest_client.clone(), + ), + analyzed_data_coll: analyzed, + }; + Ok(TypedExportDataCollectionBuildOutput { + export_context: async move { Ok(Arc::new(export_context)) }.boxed(), + setup_key, + desired_setup_state, + }) + }) + .collect::>()?; + let decl_output = std::iter::zip(declarations, declared_graph_elements) + .map(|(decl, graph_elem_schema)| { + let setup_state = SetupState { + schema: TableColumnsSchema { + key_columns: to_ladybug_cols(&graph_elem_schema.key_fields)?, + value_columns: to_ladybug_cols(&graph_elem_schema.value_fields)?, + }, + referenced_node_tables: None, + }; + let setup_key = GraphElementType { + connection: decl.connection, + typ: graph_elem_schema.elem_type.clone(), + }; + Ok((setup_key, setup_state)) + }) + .collect::>()?; + Ok((data_coll_outputs, decl_output)) + } + + async fn diff_setup_states( + &self, + _key: LadybugGraphElement, + desired: Option, + existing: CombinedState, + _flow_instance_ctx: Arc, + ) -> Result { + let existing_invalidated = desired.as_ref().is_some_and(|desired| { + existing + .possible_versions() + .any(|v| v.referenced_node_tables != desired.referenced_node_tables) + }); + let actions = + TableMainSetupAction::from_states(desired.as_ref(), &existing, existing_invalidated); + let drop_affected_referenced_node_tables = if actions.drop_existing { + existing + .possible_versions() + .flat_map(|v| &v.referenced_node_tables) + .flat_map(|(src, tgt)| [src.table_name.clone(), tgt.table_name.clone()].into_iter()) + .collect() + } else { + IndexSet::new() + }; + Ok(GraphElementDataSetupChange { + actions, + referenced_node_tables: desired + .and_then(|desired| desired.referenced_node_tables) + .map(|(src, tgt)| (src.table_name, tgt.table_name)), + drop_affected_referenced_node_tables, + }) + } + + fn check_state_compatibility( + &self, + desired: &SetupState, + existing: &SetupState, + ) -> Result { + Ok( + if desired.referenced_node_tables != existing.referenced_node_tables { + SetupStateCompatibility::NotCompatible + } else { + check_table_compatibility(&desired.schema, &existing.schema) + }, + ) + } + + fn describe_resource(&self, key: &LadybugGraphElement) -> Result { + Ok(format!( + "Ladybug {} TABLE {}", + ladybug_table_type(&key.typ), + key.typ.label() + )) + } + + fn extract_additional_key( + &self, + _key: &KeyValue, + value: &FieldValues, + export_context: &ExportContext, + ) -> Result { + let additional_key = if let Some(rel_info) = &export_context.analyzed_data_coll.rel { + serde_json::to_value(( + (rel_info.source.fields_input_idx).extract_key(&value.fields)?, + (rel_info.target.fields_input_idx).extract_key(&value.fields)?, + ))? + } else { + serde_json::Value::Null + }; + Ok(additional_key) + } + + async fn apply_mutation( + &self, + mutations: Vec>, + ) -> Result<()> { + let mut mutations_by_conn = IndexMap::new(); + for mutation in mutations.into_iter() { + mutations_by_conn + .entry(mutation.export_context.conn_ref.clone()) + .or_insert_with(Vec::new) + .push(mutation); + } + for mutations in mutations_by_conn.into_values() { + let ladybug_client = &mutations[0].export_context.ladybug_client; + let mut cypher = CypherBuilder::new(); + writeln!(cypher.query_mut(), "BEGIN TRANSACTION;")?; + + let (mut rel_mutations, nodes_mutations): (Vec<_>, Vec<_>) = mutations + .into_iter() + .partition(|m| m.export_context.analyzed_data_coll.rel.is_some()); + + struct NodeTableGcInfo { + schema: Arc, + keys: IndexSet, + } + fn register_gc_node( + map: &mut IndexMap, + schema: &Arc, + key: KeyValue, + ) { + map.entry(schema.elem_type.clone()) + .or_insert_with(|| NodeTableGcInfo { + schema: schema.clone(), + keys: IndexSet::new(), + }) + .keys + .insert(key); + } + fn resolve_gc_node( + map: &mut IndexMap, + schema: &Arc, + key: &KeyValue, + ) { + map.get_mut(&schema.elem_type) + .map(|info| info.keys.shift_remove(key)); + } + let mut gc_info = IndexMap::::new(); + + // Deletes for relationships + for rel_mutation in rel_mutations.iter_mut() { + let data_coll = &rel_mutation.export_context.analyzed_data_coll; + + let rel = data_coll.rel.as_ref().ok_or_else(invariance_violation)?; + for delete in rel_mutation.mutation.deletes.iter_mut() { + let mut additional_keys = match delete.additional_key.take() { + serde_json::Value::Array(keys) => keys, + _ => return Err(invariance_violation().into()), + }; + if additional_keys.len() != 2 { + api_bail!( + "Expected additional key with 2 fields, got {}", + delete.additional_key + ); + } + let src_key = KeyValue::from_json( + additional_keys[0].take(), + &rel.source.schema.key_fields, + )?; + let tgt_key = KeyValue::from_json( + additional_keys[1].take(), + &rel.target.schema.key_fields, + )?; + append_delete_rel(&mut cypher, data_coll, &delete.key, &src_key, &tgt_key)?; + register_gc_node(&mut gc_info, &rel.source.schema, src_key); + register_gc_node(&mut gc_info, &rel.target.schema, tgt_key); + } + } + + for node_mutation in nodes_mutations.iter() { + let data_coll = &node_mutation.export_context.analyzed_data_coll; + // Deletes for nodes + for delete in node_mutation.mutation.deletes.iter() { + append_delete_node(&mut cypher, data_coll, &delete.key)?; + resolve_gc_node(&mut gc_info, &data_coll.schema, &delete.key); + } + + // Upserts for nodes + for upsert in node_mutation.mutation.upserts.iter() { + append_upsert_node(&mut cypher, data_coll, upsert)?; + resolve_gc_node(&mut gc_info, &data_coll.schema, &upsert.key); + } + } + // Upserts for relationships + for rel_mutation in rel_mutations.iter() { + let data_coll = &rel_mutation.export_context.analyzed_data_coll; + for upsert in rel_mutation.mutation.upserts.iter() { + append_upsert_rel(&mut cypher, data_coll, upsert)?; + + let rel = data_coll.rel.as_ref().ok_or_else(invariance_violation)?; + resolve_gc_node( + &mut gc_info, + &rel.source.schema, + &(rel.source.fields_input_idx).extract_key(&upsert.value.fields)?, + ); + resolve_gc_node( + &mut gc_info, + &rel.target.schema, + &(rel.target.fields_input_idx).extract_key(&upsert.value.fields)?, + ); + } + } + + // GC orphaned nodes + for info in gc_info.into_values() { + for key in info.keys { + append_maybe_gc_node(&mut cypher, &info.schema, &key)?; + } + } + + writeln!(cypher.query_mut(), "COMMIT;")?; + ladybug_client.run_cypher(cypher).await?; + } + Ok(()) + } + + async fn apply_setup_changes( + &self, + changes: Vec>, + context: Arc, + ) -> Result<()> { + let mut changes_by_conn = IndexMap::new(); + for change in changes.into_iter() { + changes_by_conn + .entry(change.key.connection.clone()) + .or_insert_with(Vec::new) + .push(change); + } + for (conn, changes) in changes_by_conn.into_iter() { + let conn_spec = context.auth_registry.get::(&conn)?; + let ladybug_client = LadybugThinClient::new(&conn_spec, self.reqwest_client.clone()); + + let (node_changes, rel_changes): (Vec<_>, Vec<_>) = + changes.into_iter().partition(|c| match &c.key.typ { + ElementType::Node(_) => true, + ElementType::Relationship(_) => false, + }); + + let mut partial_affected_node_tables = IndexSet::new(); + let mut cypher = CypherBuilder::new(); + // Relationships first when dropping. + for change in rel_changes.iter().chain(node_changes.iter()) { + if !change.setup_change.actions.drop_existing { + continue; + } + append_drop_table(&mut cypher, change.setup_change, &change.key.typ)?; + + partial_affected_node_tables.extend( + change + .setup_change + .drop_affected_referenced_node_tables + .iter(), + ); + if let ElementType::Node(label) = &change.key.typ { + partial_affected_node_tables.swap_remove(label); + } + } + // Nodes first when creating. + for change in node_changes.iter().chain(rel_changes.iter()) { + append_upsert_table(&mut cypher, change.setup_change, &change.key.typ)?; + } + + for table in partial_affected_node_tables { + append_delete_orphaned_nodes(&mut cypher, table)?; + } + + ladybug_client.run_cypher(cypher).await?; + } + Ok(()) + } +} + +pub fn register( + registry: &mut ExecutorFactoryRegistry, + reqwest_client: reqwest::Client, +) -> Result<()> { + Factory { reqwest_client }.register(registry) +} diff --git a/crates/recoco-core/src/ops/targets/mod.rs b/crates/recoco-core/src/ops/targets/mod.rs index d7792e3f..84450d11 100644 --- a/crates/recoco-core/src/ops/targets/mod.rs +++ b/crates/recoco-core/src/ops/targets/mod.rs @@ -12,6 +12,7 @@ #[cfg(any( feature = "target-kuzu", + feature = "target-ladybug", feature = "target-neo4j", feature = "target-postgres", feature = "target-qdrant" @@ -20,6 +21,8 @@ pub mod shared; #[cfg(feature = "target-kuzu")] pub mod kuzu; +#[cfg(feature = "target-ladybug")] +pub mod ladybug; #[cfg(feature = "target-neo4j")] pub mod neo4j; #[cfg(feature = "target-postgres")] diff --git a/crates/recoco-core/src/prelude.rs b/crates/recoco-core/src/prelude.rs index 83e4503a..f9388b68 100644 --- a/crates/recoco-core/src/prelude.rs +++ b/crates/recoco-core/src/prelude.rs @@ -66,6 +66,7 @@ pub use recoco_utils::batching; pub use recoco_utils::concur_control; #[cfg(any( feature = "target-kuzu", + feature = "target-ladybug", feature = "function-embed", feature = "function-extract-llm", feature = "persistence" From 87afe157035d6a010a234b813236ac846b3ff256 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos Date: Sun, 15 Mar 2026 22:46:27 -0400 Subject: [PATCH 31/38] chore: Maintain assets and config for recoco --- site/astro.config.mjs | 2 +- site/src/assets/{ => recoco}/recoco-v2-xl.png | Bin .../recoco-v2-xl.png.license} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename site/src/assets/{ => recoco}/recoco-v2-xl.png (100%) rename site/src/assets/{recoco.webp.license => recoco/recoco-v2-xl.png.license} (100%) diff --git a/site/astro.config.mjs b/site/astro.config.mjs index 06ccd669..b19c29ae 100644 --- a/site/astro.config.mjs +++ b/site/astro.config.mjs @@ -58,7 +58,7 @@ export default defineConfig({ markdown: { shikiConfig: { themes: { - light: "github-light", + light: "catppuccin-latte", dark: "github-dark", } }, diff --git a/site/src/assets/recoco-v2-xl.png b/site/src/assets/recoco/recoco-v2-xl.png similarity index 100% rename from site/src/assets/recoco-v2-xl.png rename to site/src/assets/recoco/recoco-v2-xl.png diff --git a/site/src/assets/recoco.webp.license b/site/src/assets/recoco/recoco-v2-xl.png.license similarity index 100% rename from site/src/assets/recoco.webp.license rename to site/src/assets/recoco/recoco-v2-xl.png.license From 2f82c4da7cd31b1e4550a9cf719f9d81a434a3ad Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Sun, 15 Mar 2026 22:59:21 -0400 Subject: [PATCH 32/38] feat: add filesystem watch support to local_file source (#97) * feat: add filesystem watch support to local_file source Port upstream feature from cocoindex-io/cocoindex#1669 to enable real-time change detection for the LocalFile source using the notify crate. Changes: - Add notify 8.2.0 dependency to workspace and recoco-core - Wire notify into source-local-file feature - Add optional watch_changes field to Spec (defaults to false) - Add watch_changes field to Executor - Implement change_stream() method using notify::RecommendedWatcher - Add Clone derive to PatternMatcher for use in async stream - Filter filesystem events through existing PatternMatcher The feature is opt-in and fully backward-compatible. When enabled, the source bridges filesystem events via tokio::sync::mpsc into the change_stream() interface for low-latency continuous indexing. Related to #27 Co-authored-by: Adam Poulemanos * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> * fix(local_file): address review feedback on change_stream() watcher implementation (#98) * Initial plan * fix: address review feedback on change_stream() in local_file source Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * update lockfile --------- Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Adam Poulemanos Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> --- Cargo.lock | 137 ++++++++++++++++-- Cargo.toml | 1 + crates/recoco-core/Cargo.toml | 1 + .../recoco-core/src/ops/sources/local_file.rs | 105 ++++++++++++++ .../recoco-splitters/src/pattern_matcher.rs | 2 +- 5 files changed, 233 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b3900c73..7e20e5ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1050,6 +1050,12 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.10.0" @@ -1926,6 +1932,15 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "futures" version = "0.3.31" @@ -2947,6 +2962,26 @@ dependencies = [ "cfb", ] +[[package]] +name = "inotify" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" +dependencies = [ + "bitflags 2.10.0", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.13" @@ -3028,6 +3063,26 @@ dependencies = [ "ucd-trie", ] +[[package]] +name = "kqueue" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -3055,7 +3110,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags", + "bitflags 2.10.0", "libc", "redox_syscall 0.7.0", ] @@ -3188,6 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", + "log", "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.61.2", ] @@ -3257,6 +3313,33 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "notify" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" +dependencies = [ + "bitflags 2.10.0", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.60.2", +] + +[[package]] +name = "notify-types" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -3378,7 +3461,7 @@ version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags", + "bitflags 2.10.0", "cfg-if", "foreign-types", "libc", @@ -4053,7 +4136,6 @@ dependencies = [ "derive-where", "expect-test", "futures", - "globset", "google-cloud-aiplatform-v1", "google-cloud-gax", "google-drive3", @@ -4068,6 +4150,7 @@ dependencies = [ "json5 1.3.0", "log", "neo4rs", + "notify", "pgvector", "phf 0.12.1", "qdrant-client", @@ -4098,7 +4181,9 @@ dependencies = [ name = "recoco-splitters" version = "0.2.1" dependencies = [ + "anyhow", "cfg-if", + "globset", "regex", "tree-sitter", "tree-sitter-c", @@ -4201,7 +4286,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.10.0", ] [[package]] @@ -4210,7 +4295,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "bitflags", + "bitflags 2.10.0", ] [[package]] @@ -4368,7 +4453,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd490c5b18261893f14449cbd28cb9c0b637aebf161cd77900bfdedaff21ec32" dependencies = [ - "bitflags", + "bitflags 2.10.0", "once_cell", "serde", "serde_derive", @@ -4427,7 +4512,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", @@ -4540,6 +4625,15 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.28" @@ -4638,7 +4732,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags", + "bitflags 2.10.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -4651,7 +4745,7 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags", + "bitflags 2.10.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -5080,7 +5174,7 @@ checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", "base64 0.22.1", - "bitflags", + "bitflags 2.10.0", "byteorder", "bytes", "chrono", @@ -5124,7 +5218,7 @@ checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", "base64 0.22.1", - "bitflags", + "bitflags 2.10.0", "byteorder", "chrono", "crc", @@ -5580,7 +5674,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", - "bitflags", + "bitflags 2.10.0", "bytes", "futures-core", "futures-util", @@ -6144,6 +6238,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -6300,6 +6404,15 @@ dependencies = [ "wasite", ] +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "windows-core" version = "0.62.2" diff --git a/Cargo.toml b/Cargo.toml index ee02343c..ddd29e5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,6 +81,7 @@ itertools = "0.14.0" json5 = "1.3.0" log = "0.4.29" neo4rs = "0.8.0" +notify = "8.2.0" pgvector = { version = "0.4.1", features = ["halfvec", "sqlx"] } phf = { version = "0.12.1", features = ["macros"] } qdrant-client = "1.16.0" diff --git a/crates/recoco-core/Cargo.toml b/crates/recoco-core/Cargo.toml index ab95351c..47435594 100644 --- a/crates/recoco-core/Cargo.toml +++ b/crates/recoco-core/Cargo.toml @@ -57,6 +57,7 @@ itertools = { workspace = true, optional = true } json5 = { workspace = true, optional = true } log = { workspace = true, optional = true } neo4rs = { workspace = true, optional = true } +notify = { workspace = true, optional = true } pgvector = { workspace = true, optional = true } phf = { workspace = true } # compile time qdrant-client = { workspace = true, optional = true } diff --git a/crates/recoco-core/src/ops/sources/local_file.rs b/crates/recoco-core/src/ops/sources/local_file.rs index f72dd2b3..4a77c2d5 100644 --- a/crates/recoco-core/src/ops/sources/local_file.rs +++ b/crates/recoco-core/src/ops/sources/local_file.rs @@ -28,6 +28,7 @@ pub struct Spec { included_patterns: Option>, excluded_patterns: Option>, max_file_size: Option, + watch_changes: Option, } struct Executor { @@ -36,6 +37,7 @@ struct Executor { binary: bool, pattern_matcher: PatternMatcher, max_file_size: Option, + watch_changes: bool, } async fn ensure_metadata<'a>( @@ -236,6 +238,108 @@ impl SourceExecutor for Executor { fn provides_ordinal(&self) -> bool { true } + + async fn change_stream( + &self, + ) -> Result>>> { + if !self.watch_changes { + return Ok(None); + } + + use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher}; + use tokio::sync::mpsc; + + let root_path = self.root_path.clone(); + let root_component_size = root_path.components().count(); + let pattern_matcher = self.pattern_matcher.clone(); + + let (tx, mut rx) = mpsc::channel::(100); + + let mut watcher = RecommendedWatcher::new( + move |res: notify::Result| { + match res { + Ok(event) => { + for path in event.paths { + if let Err(err) = tx.try_send(path) { + use tokio::sync::mpsc::error::TrySendError; + match err { + TrySendError::Full(_) => { + warn!("File watcher channel is full; dropping file change event"); + } + TrySendError::Closed(_) => { + warn!("File watcher channel is closed; dropping file change event"); + } + } + } + } + } + Err(e) => { + warn!("File watcher error: {}", e); + } + } + }, + Config::default(), + ) + .map_err(|e| anyhow::anyhow!("Failed to create file watcher: {}", e))?; + + watcher + .watch(&root_path, RecursiveMode::Recursive) + .map_err(|e| anyhow::anyhow!("Failed to watch path: {}", e))?; + + let stream = async_stream::stream! { + // Keep the watcher alive for the duration of the stream + let _watcher = watcher; + + while let Some(path) = rx.recv().await { + // Skip directory paths - notify can emit events for directories, + // and reading a directory as a file would produce an EISDIR error. + let is_dir = match std::fs::metadata(&path) { + Ok(metadata) => metadata.is_dir(), + Err(err) => { + // If the file no longer exists, this may be a deletion event; do not skip it. + if err.kind() != std::io::ErrorKind::NotFound { + warn!("Failed to read metadata for path {:?}: {}", path, err); + } + false + } + }; + if is_dir { + continue; + } + + let mut path_components = path.components(); + for _ in 0..root_component_size { + path_components.next(); + } + let Some(relative_path) = path_components.as_path().to_str() else { + continue; + }; + + // Skip events that correspond to the root directory itself or yield no relative path. + if relative_path.is_empty() { + continue; + } + + // Filter through pattern matcher + if pattern_matcher.is_file_included(relative_path) { + yield Ok(SourceChangeMessage { + changes: vec![SourceChange { + key: KeyValue::from_single_part(relative_path.to_string()), + key_aux_info: serde_json::Value::Null, + data: PartialSourceRowData { + ordinal: None, + content_version_fp: None, + value: None, + }, + }], + ack_fn: None, + }); + } + } + }; + + Ok(Some(stream.boxed())) + } } pub struct Factory; @@ -293,6 +397,7 @@ impl SourceFactoryBase for Factory { binary: spec.binary, pattern_matcher: PatternMatcher::new(spec.included_patterns, spec.excluded_patterns)?, max_file_size: spec.max_file_size, + watch_changes: spec.watch_changes.unwrap_or(false), })) } } diff --git a/crates/recoco-splitters/src/pattern_matcher.rs b/crates/recoco-splitters/src/pattern_matcher.rs index bf00bd21..34a14328 100644 --- a/crates/recoco-splitters/src/pattern_matcher.rs +++ b/crates/recoco-splitters/src/pattern_matcher.rs @@ -23,7 +23,7 @@ fn build_glob_set(patterns: Vec) -> Result { } /// Pattern matcher that handles include and exclude patterns for files -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PatternMatcher { /// Patterns matching full path of files to be included. included_glob_set: Option, From 35401263718de9525afbb1861a159d8b43ea465e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:21:57 +0000 Subject: [PATCH 33/38] feat: add progress watching API with per-component tracking Implements upstream CocoIndex PR #1767 features: - Add `ComponentStats` struct for per-operation statistics tracking - Enhance `UpdateStats` with `by_component` field mapping operation names to stats - Add `ProgressUpdate` struct with comprehensive progress information - Implement `subscribe_progress()` method on `FlowLiveUpdater` for watching progress - Add periodic progress emission during flow indexing (1s intervals) - Emit final progress update on completion - Expose stats module publicly for API consumers The progress watching API allows callers to subscribe to real-time updates during flow indexing, including: - Active sources being processed - Completed vs total sources - Per-source statistics - Per-operation in-process counts All changes are feature-gated under `persistence` feature. Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Adam Poulemanos --- .../recoco-core/src/execution/live_updater.rs | 130 ++++++++++++++++++ crates/recoco-core/src/execution/mod.rs | 5 +- crates/recoco-core/src/execution/stats.rs | 130 +++++++++++++++++- 3 files changed, 262 insertions(+), 3 deletions(-) diff --git a/crates/recoco-core/src/execution/live_updater.rs b/crates/recoco-core/src/execution/live_updater.rs index 5ed831e1..245987ae 100644 --- a/crates/recoco-core/src/execution/live_updater.rs +++ b/crates/recoco-core/src/execution/live_updater.rs @@ -26,6 +26,22 @@ pub struct FlowLiveUpdaterUpdates { pub active_sources: Vec, pub updated_sources: Vec, } + +/// Progress update information for flow indexing. +#[derive(Debug, Clone, Serialize)] +pub struct ProgressUpdate { + /// Names of sources currently being indexed. + pub active_sources: Vec, + /// Total number of sources in the flow. + pub total_sources: usize, + /// Number of sources completed. + pub completed_sources: usize, + /// Per-source statistics. + pub source_stats: Vec, + /// Global operation-level in-process counts. + pub operation_in_process: std::collections::HashMap, +} + struct FlowLiveUpdaterStatus { pub active_source_idx: BTreeSet, pub source_updates_num: Vec, @@ -46,6 +62,9 @@ pub struct FlowLiveUpdater { recv_state: tokio::sync::Mutex, num_remaining_tasks_rx: watch::Receiver, + // Progress watching channel + progress_tx: watch::Sender>, + // Hold tx to avoid dropping the sender. _status_tx: watch::Sender, _num_remaining_tasks_tx: watch::Sender, @@ -481,6 +500,8 @@ impl FlowLiveUpdater { let (num_remaining_tasks_tx, num_remaining_tasks_rx) = watch::channel(plan.import_ops.len()); + let (progress_tx, _progress_rx) = watch::channel(None); + let mut join_set = JoinSet::new(); let mut stats_per_task = Vec::new(); let operation_in_process_stats = Arc::new(stats::OperationInProcessStats::default()); @@ -514,13 +535,115 @@ impl FlowLiveUpdater { is_done: false, }), num_remaining_tasks_rx, + progress_tx, _status_tx: status_tx, _num_remaining_tasks_tx: num_remaining_tasks_tx, }) } + /// Subscribe to progress updates during flow indexing. + /// Returns a receiver that will receive periodic progress updates. + pub fn subscribe_progress(&self) -> watch::Receiver> { + self.progress_tx.subscribe() + } + + /// Emit a progress update to all subscribers. + fn emit_progress_update(&self) { + let recv_state = match self.recv_state.try_lock() { + Ok(state) => state, + Err(_) => return, // Skip if locked + }; + + let status = recv_state.status_rx.borrow(); + + let active_sources: Vec = status + .active_source_idx + .iter() + .map(|&idx| { + self.flow_ctx.flow.flow_instance.import_ops[idx] + .name + .clone() + }) + .collect(); + + let total_sources = self.stats_per_task.len(); + let completed_sources = total_sources - status.active_source_idx.len(); + + let source_stats: Vec = std::iter::zip( + self.flow_ctx.flow.flow_instance.import_ops.iter(), + self.stats_per_task.iter(), + ) + .map(|(import_op, stats)| stats::SourceUpdateInfo { + source_name: import_op.name.clone(), + stats: stats.as_ref().clone(), + }) + .collect(); + + let operation_in_process = self + .operation_in_process_stats + .get_all_operations_in_process(); + + let update = ProgressUpdate { + active_sources, + total_sources, + completed_sources, + source_stats, + operation_in_process, + }; + + let _ = self.progress_tx.send(Some(update)); + } + pub async fn wait(&self) -> Result<()> { + // Spawn a task to emit periodic progress updates + let progress_tx = self.progress_tx.clone(); + let num_remaining_tasks_rx = self.num_remaining_tasks_rx.clone(); + let flow_ctx = self.flow_ctx.clone(); + let stats_per_task = self.stats_per_task.clone(); + let operation_in_process_stats = self.operation_in_process_stats.clone(); + + let progress_emitter = tokio::spawn(async move { + let mut interval = tokio::time::interval(std::time::Duration::from_secs(1)); + interval.set_missed_tick_behavior(MissedTickBehavior::Skip); + + loop { + interval.tick().await; + + let num_remaining = *num_remaining_tasks_rx.borrow(); + if num_remaining == 0 { + break; + } + + // Emit progress update + let total_sources = stats_per_task.len(); + let completed_sources = total_sources - num_remaining; + + let source_stats: Vec = std::iter::zip( + flow_ctx.flow.flow_instance.import_ops.iter(), + stats_per_task.iter(), + ) + .map(|(import_op, stats)| stats::SourceUpdateInfo { + source_name: import_op.name.clone(), + stats: stats.as_ref().clone(), + }) + .collect(); + + let operation_in_process = + operation_in_process_stats.get_all_operations_in_process(); + + let update = ProgressUpdate { + active_sources: vec![], // Will be filled if status is available + total_sources, + completed_sources, + source_stats, + operation_in_process, + }; + + let _ = progress_tx.send(Some(update)); + } + }); + { let mut rx = self.num_remaining_tasks_rx.clone(); rx.wait_for(|v| *v == 0).await?; @@ -533,14 +656,21 @@ impl FlowLiveUpdater { match task_result { Ok(Ok(_)) => {} Ok(Err(err)) => { + progress_emitter.abort(); return Err(err); } Err(err) if err.is_cancelled() => {} Err(err) => { + progress_emitter.abort(); return Err(err.into()); } } } + + // Emit final progress update + self.emit_progress_update(); + + progress_emitter.abort(); Ok(()) } diff --git a/crates/recoco-core/src/execution/mod.rs b/crates/recoco-core/src/execution/mod.rs index 96f62983..6c216119 100644 --- a/crates/recoco-core/src/execution/mod.rs +++ b/crates/recoco-core/src/execution/mod.rs @@ -22,7 +22,10 @@ pub(crate) mod memoization; pub(crate) mod row_indexer; #[cfg(feature = "persistence")] pub(crate) mod source_indexer; -pub(crate) mod stats; + +// Export stats types for progress watching API +#[cfg(feature = "persistence")] +pub mod stats; #[cfg(feature = "persistence")] mod live_updater; diff --git a/crates/recoco-core/src/execution/stats.rs b/crates/recoco-core/src/execution/stats.rs index 30f12379..669eb2e1 100644 --- a/crates/recoco-core/src/execution/stats.rs +++ b/crates/recoco-core/src/execution/stats.rs @@ -68,6 +68,35 @@ impl std::fmt::Debug for Counter { } } +/// Statistics for a single component/operation. +#[derive(Debug, Serialize, Default, Clone)] +#[cfg(feature = "persistence")] +pub struct ComponentStats { + pub num_processed: Counter, + pub num_errors: Counter, + pub processing: ProcessingCounters, +} + +#[cfg(feature = "persistence")] +impl ComponentStats { + /// Record that processing started for a number of items. + pub fn start(&self, count: i64) { + self.processing.start(count); + } + + /// Record that processing completed for a number of items. + pub fn complete(&self, count: i64) { + self.num_processed.inc(count); + self.processing.end(count); + } + + /// Record that processing failed for a number of items. + pub fn error(&self, count: i64) { + self.num_errors.inc(count); + self.processing.end(count); + } +} + #[derive(Debug, Serialize, Default, Clone)] pub struct ProcessingCounters { /// Total number of processing operations started. @@ -111,7 +140,7 @@ impl ProcessingCounters { } } -#[derive(Debug, Serialize, Default, Clone)] +#[derive(Debug, Default)] #[cfg(feature = "persistence")] pub struct UpdateStats { pub num_no_change: Counter, @@ -124,6 +153,49 @@ pub struct UpdateStats { pub num_errors: Counter, /// Processing counters for tracking in-process rows. pub processing: ProcessingCounters, + /// Per-component (operation) stats tracking. + /// Maps component/operation names to their individual update stats. + pub by_component: std::sync::RwLock>, +} + +#[cfg(feature = "persistence")] +impl Serialize for UpdateStats { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: serde::Serializer, + { + use serde::ser::SerializeStruct; + let mut state = serializer.serialize_struct("UpdateStats", 8)?; + state.serialize_field("num_no_change", &self.num_no_change)?; + state.serialize_field("num_insertions", &self.num_insertions)?; + state.serialize_field("num_deletions", &self.num_deletions)?; + state.serialize_field("num_updates", &self.num_updates)?; + state.serialize_field("num_reprocesses", &self.num_reprocesses)?; + state.serialize_field("num_errors", &self.num_errors)?; + state.serialize_field("processing", &self.processing)?; + let by_component = self.by_component.read().unwrap(); + if !by_component.is_empty() { + state.serialize_field("by_component", &*by_component)?; + } + state.end() + } +} + +#[cfg(feature = "persistence")] +impl Clone for UpdateStats { + fn clone(&self) -> Self { + let by_component = self.by_component.read().unwrap(); + Self { + num_no_change: self.num_no_change.clone(), + num_insertions: self.num_insertions.clone(), + num_deletions: self.num_deletions.clone(), + num_updates: self.num_updates.clone(), + num_reprocesses: self.num_reprocesses.clone(), + num_errors: self.num_errors.clone(), + processing: self.processing.clone(), + by_component: std::sync::RwLock::new(by_component.clone()), + } + } } #[cfg(feature = "persistence")] @@ -137,6 +209,7 @@ impl UpdateStats { num_reprocesses: self.num_reprocesses.delta(&base.num_reprocesses), num_errors: self.num_errors.delta(&base.num_errors), processing: self.processing.delta(&base.processing), + by_component: std::sync::RwLock::new(HashMap::new()), // Delta doesn't track per-component } } @@ -148,6 +221,15 @@ impl UpdateStats { self.num_reprocesses.merge(&delta.num_reprocesses); self.num_errors.merge(&delta.num_errors); self.processing.merge(&delta.processing); + // Merge component stats + let delta_components = delta.by_component.read().unwrap(); + let mut self_components = self.by_component.write().unwrap(); + for (component_name, delta_stats) in delta_components.iter() { + let entry = self_components.entry(component_name.clone()).or_default(); + entry.num_processed.merge(&delta_stats.num_processed); + entry.num_errors.merge(&delta_stats.num_errors); + entry.processing.merge(&delta_stats.processing); + } } pub fn has_any_change(&self) -> bool { @@ -157,6 +239,50 @@ impl UpdateStats { || self.num_reprocesses.get() > 0 || self.num_errors.get() > 0 } + + /// Get or create a component stats entry for the given component name. + pub fn get_component_stats(&self, component_name: &str) -> Arc { + let components = self.by_component.read().unwrap(); + if let Some(stats) = components.get(component_name) { + return Arc::new(stats.clone()); + } + drop(components); + + let mut components = self.by_component.write().unwrap(); + Arc::new( + components + .entry(component_name.to_string()) + .or_default() + .clone(), + ) + } + + /// Record component processing start. + pub fn component_start(&self, component_name: &str, count: i64) { + let mut components = self.by_component.write().unwrap(); + components + .entry(component_name.to_string()) + .or_default() + .start(count); + } + + /// Record component processing completion. + pub fn component_complete(&self, component_name: &str, count: i64) { + let mut components = self.by_component.write().unwrap(); + components + .entry(component_name.to_string()) + .or_default() + .complete(count); + } + + /// Record component processing error. + pub fn component_error(&self, component_name: &str, count: i64) { + let mut components = self.by_component.write().unwrap(); + components + .entry(component_name.to_string()) + .or_default() + .error(count); + } } /// Per-operation tracking of in-process row counts. @@ -274,7 +400,7 @@ impl std::fmt::Display for UpdateStats { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Clone)] #[cfg(feature = "persistence")] pub struct SourceUpdateInfo { pub source_name: String, From f1e532b952be4536f06e1d7c98fdd11e7ea7e209 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 17:23:55 +0000 Subject: [PATCH 34/38] feat: expose progress watching API for App/execution engine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change adopts the upstream progress watching API improvements, making UpdateStats and related progress tracking types part of the public API. Changes: - Expose stats module publicly in execution/mod.rs - Add stats to prelude for convenient access - Create comprehensive progress_watching example - Fix missing notify dependency in source-local-file feature The progress watching API allows users to: - Track real-time processing statistics via UpdateStats - Monitor per-operation in-process counts via OperationInProcessStats - Subscribe to progress updates via FlowLiveUpdater Closes #99 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Co-authored-by: Adam Poulemanos --- crates/recoco-core/Cargo.toml | 1 + crates/recoco-core/src/base/value.rs | 4 +- crates/recoco-core/src/execution/mod.rs | 3 - .../recoco-core/src/ops/sources/amazon_s3.rs | 2 +- .../recoco-core/src/ops/sources/azure_blob.rs | 2 +- .../src/ops/sources/google_drive.rs | 2 +- .../recoco-core/src/ops/sources/local_file.rs | 36 ++-- crates/recoco-core/src/prelude.rs | 1 + crates/recoco-core/src/setup/db_metadata.rs | 10 +- crates/recoco/examples/progress_watching.rs | 186 ++++++++++++++++++ 10 files changed, 215 insertions(+), 32 deletions(-) create mode 100644 crates/recoco/examples/progress_watching.rs diff --git a/crates/recoco-core/Cargo.toml b/crates/recoco-core/Cargo.toml index 47435594..cc65e1f6 100644 --- a/crates/recoco-core/Cargo.toml +++ b/crates/recoco-core/Cargo.toml @@ -249,6 +249,7 @@ source-gdrive = [ source-local-file = [ "batching", "dep:async-stream", + "dep:notify", "dep:recoco-splitters", "recoco-splitters/pattern-matching", "recoco-utils/bytes_decode", diff --git a/crates/recoco-core/src/base/value.rs b/crates/recoco-core/src/base/value.rs index 9b21069d..782560f0 100644 --- a/crates/recoco-core/src/base/value.rs +++ b/crates/recoco-core/src/base/value.rs @@ -1809,9 +1809,7 @@ mod tests { let struct_part = KeyPart::from(vec![ KeyPart::from(String::from("world")), KeyPart::from(100i64), - KeyPart::from(vec![ - KeyPart::from(false), - ]), + KeyPart::from(vec![KeyPart::from(false)]), ]); assert_eq!(struct_part.to_strs(), vec!["world", "100", "false"]); } diff --git a/crates/recoco-core/src/execution/mod.rs b/crates/recoco-core/src/execution/mod.rs index 6c216119..aaf86e1e 100644 --- a/crates/recoco-core/src/execution/mod.rs +++ b/crates/recoco-core/src/execution/mod.rs @@ -22,9 +22,6 @@ pub(crate) mod memoization; pub(crate) mod row_indexer; #[cfg(feature = "persistence")] pub(crate) mod source_indexer; - -// Export stats types for progress watching API -#[cfg(feature = "persistence")] pub mod stats; #[cfg(feature = "persistence")] diff --git a/crates/recoco-core/src/ops/sources/amazon_s3.rs b/crates/recoco-core/src/ops/sources/amazon_s3.rs index 55af6462..a73590a5 100644 --- a/crates/recoco-core/src/ops/sources/amazon_s3.rs +++ b/crates/recoco-core/src/ops/sources/amazon_s3.rs @@ -19,9 +19,9 @@ use redis::Client as RedisClient; use std::sync::Arc; use urlencoding; -use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::ops::sdk::*; +use recoco_splitters::pattern_matcher::PatternMatcher; /// Decode a form-encoded URL string, treating '+' as spaces fn decode_form_encoded_url(input: &str) -> Result> { diff --git a/crates/recoco-core/src/ops/sources/azure_blob.rs b/crates/recoco-core/src/ops/sources/azure_blob.rs index 5689857e..88de2265 100644 --- a/crates/recoco-core/src/ops/sources/azure_blob.rs +++ b/crates/recoco-core/src/ops/sources/azure_blob.rs @@ -18,10 +18,10 @@ use azure_storage_blobs::prelude::*; use futures::StreamExt; use std::sync::Arc; -use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::ops::sdk::*; use crate::prelude::*; +use recoco_splitters::pattern_matcher::PatternMatcher; #[derive(Debug, Serialize, Deserialize)] pub struct Spec { diff --git a/crates/recoco-core/src/ops/sources/google_drive.rs b/crates/recoco-core/src/ops/sources/google_drive.rs index 987cd0c4..dc25bf72 100644 --- a/crates/recoco-core/src/ops/sources/google_drive.rs +++ b/crates/recoco-core/src/ops/sources/google_drive.rs @@ -10,7 +10,6 @@ // Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. // SPDX-License-Identifier: Apache-2.0 -use recoco_splitters::pattern_matcher::PatternMatcher; use chrono::Duration; use google_drive3::{ DriveHub, @@ -21,6 +20,7 @@ use http_body_util::BodyExt; use hyper_rustls::HttpsConnector; use hyper_util::client::legacy::connect::HttpConnector; use phf::phf_map; +use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::ops::sdk::*; diff --git a/crates/recoco-core/src/ops/sources/local_file.rs b/crates/recoco-core/src/ops/sources/local_file.rs index 4a77c2d5..a3be3c82 100644 --- a/crates/recoco-core/src/ops/sources/local_file.rs +++ b/crates/recoco-core/src/ops/sources/local_file.rs @@ -17,9 +17,9 @@ use std::path::Path; use std::{path::PathBuf, sync::Arc}; use tracing::warn; -use recoco_splitters::pattern_matcher::PatternMatcher; use crate::base::field_attrs; use crate::{fields_value, ops::sdk::*}; +use recoco_splitters::pattern_matcher::PatternMatcher; #[derive(Debug, Serialize, Deserialize)] pub struct Spec { @@ -256,26 +256,28 @@ impl SourceExecutor for Executor { let (tx, mut rx) = mpsc::channel::(100); let mut watcher = RecommendedWatcher::new( - move |res: notify::Result| { - match res { - Ok(event) => { - for path in event.paths { - if let Err(err) = tx.try_send(path) { - use tokio::sync::mpsc::error::TrySendError; - match err { - TrySendError::Full(_) => { - warn!("File watcher channel is full; dropping file change event"); - } - TrySendError::Closed(_) => { - warn!("File watcher channel is closed; dropping file change event"); - } + move |res: notify::Result| match res { + Ok(event) => { + for path in event.paths { + if let Err(err) = tx.try_send(path) { + use tokio::sync::mpsc::error::TrySendError; + match err { + TrySendError::Full(_) => { + warn!( + "File watcher channel is full; dropping file change event" + ); + } + TrySendError::Closed(_) => { + warn!( + "File watcher channel is closed; dropping file change event" + ); } } } } - Err(e) => { - warn!("File watcher error: {}", e); - } + } + Err(e) => { + warn!("File watcher error: {}", e); } }, Config::default(), diff --git a/crates/recoco-core/src/prelude.rs b/crates/recoco-core/src/prelude.rs index f9388b68..2bc50df7 100644 --- a/crates/recoco-core/src/prelude.rs +++ b/crates/recoco-core/src/prelude.rs @@ -38,6 +38,7 @@ pub use std::sync::{Arc, LazyLock, Mutex, OnceLock, RwLock, Weak}; pub use crate::base::{self, schema, spec, value}; pub use crate::builder::{self, exec_ctx, plan}; pub use crate::execution; +pub use crate::execution::stats; pub use crate::lib_context::{FlowContext, LibContext, get_lib_context, get_runtime}; pub use crate::ops::interface; pub use crate::setup; diff --git a/crates/recoco-core/src/setup/db_metadata.rs b/crates/recoco-core/src/setup/db_metadata.rs index fe53e340..be70513e 100644 --- a/crates/recoco-core/src/setup/db_metadata.rs +++ b/crates/recoco-core/src/setup/db_metadata.rs @@ -67,12 +67,10 @@ pub async fn read_setup_metadata(pool: &PgPool) -> Result = sqlx::query_scalar( - "SELECT to_regclass($1) IS NOT NULL", - ) - .bind(&table_name) - .fetch_one(&mut *db_conn) - .await?; + let exists: Option = sqlx::query_scalar("SELECT to_regclass($1) IS NOT NULL") + .bind(&table_name) + .fetch_one(&mut *db_conn) + .await?; if !exists.unwrap_or(false) { None } else { diff --git a/crates/recoco/examples/progress_watching.rs b/crates/recoco/examples/progress_watching.rs new file mode 100644 index 00000000..1615354b --- /dev/null +++ b/crates/recoco/examples/progress_watching.rs @@ -0,0 +1,186 @@ +// Recoco is a Rust-only fork of CocoIndex, by [CocoIndex](https://CocoIndex) +// Original code from CocoIndex is copyrighted by CocoIndex +// SPDX-FileCopyrightText: 2025-2026 CocoIndex (upstream) +// SPDX-FileContributor: CocoIndex Contributors +// +// All modifications from the upstream for Recoco are copyrighted by Knitli Inc. +// SPDX-FileCopyrightText: 2026 Knitli Inc. (Recoco) +// SPDX-FileContributor: Adam Poulemanos +// +// Both the upstream CocoIndex code and the Recoco modifications are licensed under the Apache-2.0 License. +// SPDX-License-Identifier: Apache-2.0 + +//! # Progress Watching API Example +//! +//! This example demonstrates how to use Recoco's progress watching API to monitor +//! long-running indexing operations. The progress API provides real-time visibility +//! into data processing pipelines through: +//! +//! - **UpdateStats**: Per-source statistics tracking insertions, updates, deletions, and errors +//! - **OperationInProcessStats**: Granular per-operation tracking of in-flight rows +//! - **FlowLiveUpdater**: Subscribe to progress updates during flow execution +//! +//! ## Features Required +//! +//! This example requires the `persistence` feature to enable progress tracking: +//! ```bash +//! cargo run -p recoco --example progress_watching --features persistence +//! ``` +//! +//! ## Progress Watching API Overview +//! +//! ### FlowLiveUpdater Methods +//! +//! - `next_status_updates()`: Async method that blocks until new progress updates are available +//! - `index_update_info()`: Get a snapshot of current statistics for all sources +//! - `operation_in_process_stats`: Access per-operation in-process counts +//! - `wait()`: Wait for all indexing tasks to complete +//! +//! ### UpdateStats Fields +//! +//! - `num_insertions`: Counter for newly inserted rows +//! - `num_updates`: Counter for updated rows +//! - `num_deletions`: Counter for deleted rows +//! - `num_reprocesses`: Counter for reprocessed rows (logic changes) +//! - `num_no_change`: Counter for unchanged rows +//! - `num_errors`: Counter for errors encountered +//! - `processing`: ProcessingCounters tracking in-flight rows +//! +//! ### OperationInProcessStats Methods +//! +//! - `get_operation_in_process_count(name)`: Get in-process count for a specific operation +//! - `get_all_operations_in_process()`: Get snapshot of all operations +//! - `get_total_in_process_count()`: Get total in-process rows across all operations + +#[cfg(feature = "persistence")] +use recoco::prelude::*; + +#[cfg(feature = "persistence")] +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // Note: In a real application, you would set up tracing with tracing_subscriber + // tracing_subscriber::fmt().with_max_level(tracing::Level::INFO).init(); + + println!("=== Recoco Progress Watching API Demo ===\n"); + println!("This example demonstrates the progress watching API."); + println!("NOTE: This is a demonstration of the API structure.\n"); + println!("In a real application, you would:"); + println!(" 1. Set up a database connection pool"); + println!(" 2. Create a persisted flow with sources"); + println!(" 3. Start the FlowLiveUpdater"); + println!(" 4. Subscribe to progress updates\n"); + + // Example 1: Working with UpdateStats directly + println!("--- Example 1: UpdateStats Structure ---"); + let update_stats = stats::UpdateStats::default(); + + // Simulate some processing + update_stats.processing.start(100); + update_stats.num_insertions.inc(45); + update_stats.num_updates.inc(30); + update_stats.num_errors.inc(2); + update_stats.processing.end(77); // 77 completed, 23 still in process + + println!("UpdateStats: {}", update_stats); + println!( + "In-process rows: {}", + update_stats.processing.get_in_process() + ); + println!("Has changes: {}\n", update_stats.has_any_change()); + + // Example 2: Per-operation tracking + println!("--- Example 2: OperationInProcessStats ---"); + let op_stats = stats::OperationInProcessStats::default(); + + // Track multiple operations + op_stats.start_processing("import_users", 50); + op_stats.start_processing("transform_data", 30); + op_stats.start_processing("export_to_db", 20); + + println!( + "Total in-process: {}", + op_stats.get_total_in_process_count() + ); + println!("\nPer-operation breakdown:"); + for (op_name, count) in op_stats.get_all_operations_in_process() { + println!(" - {}: {} rows", op_name, count); + } + + // Simulate completion + op_stats.finish_processing("import_users", 25); + println!("\nAfter finishing 25 rows from 'import_users':"); + println!( + " import_users: {} rows", + op_stats.get_operation_in_process_count("import_users") + ); + println!(" Total: {} rows\n", op_stats.get_total_in_process_count()); + + // Example 3: FlowLiveUpdater API structure + println!("--- Example 3: FlowLiveUpdater API Pattern ---"); + println!( + " +// In a real application with a persisted flow: + +// 1. Start the live updater +let updater = execution::FlowLiveUpdater::start( + flow_ctx, + &pool, + execution::FlowLiveUpdaterOptions {{ + live_mode: false, // Run once + print_stats: true, // Print progress to console + reexport_targets: false, + full_reprocess: false, + }} +).await?; + +// 2. Subscribe to progress updates in a separate task +tokio::spawn(async move {{ + loop {{ + let updates = updater.next_status_updates().await?; + + // Check which sources have updates + for source in updates.updated_sources {{ + println!(\"Source {{}} has new data\", source); + }} + + // Check active sources + if updates.active_sources.is_empty() {{ + break; // All done + }} + + // Get per-operation stats + let op_stats = &updater.operation_in_process_stats; + let total_in_process = op_stats.get_total_in_process_count(); + println!(\"Total in-process: {{}}\", total_in_process); + }} + Ok::<(), Error>(()) +}}); + +// 3. Wait for completion +updater.wait().await?; + +// 4. Get final statistics +let final_stats = updater.index_update_info(); +for source_info in final_stats.sources {{ + println!(\"Source: {{}}\", source_info.source_name); + println!(\" Stats: {{}}\", source_info.stats); +}} +" + ); + + println!("\n--- API Documentation ---"); + println!("For more information, see:"); + println!(" - crates/recoco-core/src/execution/stats.rs"); + println!(" - crates/recoco-core/src/execution/live_updater.rs"); + println!("\nThe progress watching API is now part of recoco's public API"); + println!("and can be accessed via `use recoco::prelude::*;`"); + + Ok(()) +} + +#[cfg(not(feature = "persistence"))] +fn main() { + eprintln!("This example requires the 'persistence' feature."); + eprintln!("Run with: cargo run -p recoco --example progress_watching --features persistence"); + std::process::exit(1); +} From 3bc45d31dfb250952eb73880ede4099fa4b71bb6 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Wed, 18 Mar 2026 21:41:30 -0400 Subject: [PATCH 35/38] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --- .../recoco-core/src/execution/live_updater.rs | 16 ++- crates/recoco-core/src/execution/stats.rs | 136 ++++++++++++++++-- 2 files changed, 140 insertions(+), 12 deletions(-) diff --git a/crates/recoco-core/src/execution/live_updater.rs b/crates/recoco-core/src/execution/live_updater.rs index 245987ae..aa5eefea 100644 --- a/crates/recoco-core/src/execution/live_updater.rs +++ b/crates/recoco-core/src/execution/live_updater.rs @@ -550,9 +550,13 @@ impl FlowLiveUpdater { /// Emit a progress update to all subscribers. fn emit_progress_update(&self) { - let recv_state = match self.recv_state.try_lock() { + // Always wait for the recv_state lock so we don't silently drop updates, + // especially the final completion snapshot. + let recv_state = match self.recv_state.lock() { Ok(state) => state, - Err(_) => return, // Skip if locked + // If the mutex is poisoned, recover the inner state and still emit + // a best-effort progress update instead of silently skipping it. + Err(poisoned) => poisoned.into_inner(), }; let status = recv_state.status_rx.borrow(); @@ -603,6 +607,9 @@ impl FlowLiveUpdater { let stats_per_task = self.stats_per_task.clone(); let operation_in_process_stats = self.operation_in_process_stats.clone(); + // Clone the status receiver so we can derive active_sources for periodic updates. + let mut status_rx = self.status_rx.clone(); + let progress_emitter = tokio::spawn(async move { let mut interval = tokio::time::interval(std::time::Duration::from_secs(1)); interval.set_missed_tick_behavior(MissedTickBehavior::Skip); @@ -632,8 +639,11 @@ impl FlowLiveUpdater { let operation_in_process = operation_in_process_stats.get_all_operations_in_process(); + // Derive active_sources from the latest FlowLiveUpdaterStatus. + let active_sources = status_rx.borrow().active_sources.clone(); + let update = ProgressUpdate { - active_sources: vec![], // Will be filled if status is available + active_sources, total_sources, completed_sources, source_stats, diff --git a/crates/recoco-core/src/execution/stats.rs b/crates/recoco-core/src/execution/stats.rs index 669eb2e1..41f21e45 100644 --- a/crates/recoco-core/src/execution/stats.rs +++ b/crates/recoco-core/src/execution/stats.rs @@ -240,22 +240,140 @@ impl UpdateStats { || self.num_errors.get() > 0 } - /// Get or create a component stats entry for the given component name. - pub fn get_component_stats(&self, component_name: &str) -> Arc { + /// Get or create a component stats snapshot for the given component name. + pub fn get_component_stats(&self, component_name: &str) -> ComponentStats { let components = self.by_component.read().unwrap(); if let Some(stats) = components.get(component_name) { - return Arc::new(stats.clone()); + return stats.clone(); } drop(components); let mut components = self.by_component.write().unwrap(); - Arc::new( - components - .entry(component_name.to_string()) - .or_default() - .clone(), - ) + components + .entry(component_name.to_string()) + .or_default() + .clone() } +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::Value; + + #[test] + fn component_counters_update_correctly() { + let stats = UpdateStats::default(); + + // Populate per-component stats by writing into the by_component map. + { + let mut components = stats.by_component.write().unwrap(); + let comp_stats = components.entry("comp_a".to_string()).or_default(); + comp_stats.num_processed.inc(3); + comp_stats.num_errors.inc(1); + comp_stats.processing.inc(2); + } + + let components = stats.by_component.read().unwrap(); + let comp_stats = components.get("comp_a").expect("component stats should exist"); + assert_eq!(comp_stats.num_processed.get(), 3); + assert_eq!(comp_stats.num_errors.get(), 1); + assert_eq!(comp_stats.processing.get(), 2); + } + + #[test] + fn merge_combines_component_stats() { + let base = UpdateStats::default(); + let delta = UpdateStats::default(); + + { + let mut base_components = base.by_component.write().unwrap(); + let base_comp = base_components.entry("comp_a".to_string()).or_default(); + base_comp.num_processed.inc(5); + base_comp.num_errors.inc(2); + base_comp.processing.inc(1); + } + + { + let mut delta_components = delta.by_component.write().unwrap(); + let delta_comp_a = delta_components.entry("comp_a".to_string()).or_default(); + delta_comp_a.num_processed.inc(4); + delta_comp_a.num_errors.inc(3); + delta_comp_a.processing.inc(2); + + let delta_comp_b = delta_components.entry("comp_b".to_string()).or_default(); + delta_comp_b.num_processed.inc(7); + delta_comp_b.num_errors.inc(0); + delta_comp_b.processing.inc(5); + } + + base.merge(&delta); + + let components = base.by_component.read().unwrap(); + let comp_a = components.get("comp_a").expect("comp_a should exist after merge"); + assert_eq!(comp_a.num_processed.get(), 5 + 4); + assert_eq!(comp_a.num_errors.get(), 2 + 3); + assert_eq!(comp_a.processing.get(), 1 + 2); + + let comp_b = components.get("comp_b").expect("comp_b should be added by merge"); + assert_eq!(comp_b.num_processed.get(), 7); + assert_eq!(comp_b.num_errors.get(), 0); + assert_eq!(comp_b.processing.get(), 5); + } + + #[test] + fn serialization_omits_empty_by_component() { + let stats = UpdateStats::default(); + + let value = serde_json::to_value(&stats).expect("serialization should succeed"); + let obj = value.as_object().expect("stats should serialize to JSON object"); + + // When there are no per-component stats, by_component should be omitted if + // #[serde(skip_serializing_if = "HashMap::is_empty")] is used. + assert!( + !obj.contains_key("by_component"), + "by_component should be omitted when empty" + ); + } + + #[test] + fn serialization_includes_non_empty_by_component() { + let stats = UpdateStats::default(); + { + let mut components = stats.by_component.write().unwrap(); + let comp_stats = components.entry("comp_a".to_string()).or_default(); + comp_stats.num_processed.inc(1); + comp_stats.num_errors.inc(0); + comp_stats.processing.inc(0); + } + + let value = serde_json::to_value(&stats).expect("serialization should succeed"); + let obj = value.as_object().expect("stats should serialize to JSON object"); + + let by_component_value = obj + .get("by_component") + .expect("by_component should be present when non-empty"); + + let by_component_obj = by_component_value + .as_object() + .expect("by_component should be a JSON object"); + + let comp_a_value = by_component_obj + .get("comp_a") + .expect("comp_a entry should be present"); + + let comp_a_obj = comp_a_value + .as_object() + .expect("component stats should serialize to JSON object"); + + // We don't assert exact field names beyond presence to keep this robust to + // unrelated serialization changes, but we ensure some counters are present. + assert!( + comp_a_obj.contains_key("num_processed"), + "component stats should include num_processed" + ); + } +} /// Record component processing start. pub fn component_start(&self, component_name: &str, count: i64) { From 8c17f6fea5efa9ba172cef5fe22b62d0177f2575 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> Date: Thu, 19 Mar 2026 10:49:14 -0400 Subject: [PATCH 36/38] Refactor progress_watching.rs by removing persistence feature Removed conditional compilation for persistence feature and related main function. Signed-off-by: Adam Poulemanos <89049923+bashandbone@users.noreply.github.com> --- crates/recoco/examples/progress_watching.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/recoco/examples/progress_watching.rs b/crates/recoco/examples/progress_watching.rs index 1615354b..06347475 100644 --- a/crates/recoco/examples/progress_watching.rs +++ b/crates/recoco/examples/progress_watching.rs @@ -52,10 +52,8 @@ //! - `get_all_operations_in_process()`: Get snapshot of all operations //! - `get_total_in_process_count()`: Get total in-process rows across all operations -#[cfg(feature = "persistence")] use recoco::prelude::*; -#[cfg(feature = "persistence")] #[tokio::main] async fn main() -> anyhow::Result<()> { // Note: In a real application, you would set up tracing with tracing_subscriber From 007d161233d43a740445df1db9552752c2e68989 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 19 Mar 2026 12:29:08 -0400 Subject: [PATCH 37/38] fix: correct syntax errors and type mismatches in progress watching API (#117) * Initial plan * fix: correct syntax errors, duplicate test module, and type errors in stats/live_updater Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: bashandbone <89049923+bashandbone@users.noreply.github.com> --- .../recoco-core/src/execution/live_updater.rs | 40 +-- crates/recoco-core/src/execution/stats.rs | 239 +++++++++--------- 2 files changed, 144 insertions(+), 135 deletions(-) diff --git a/crates/recoco-core/src/execution/live_updater.rs b/crates/recoco-core/src/execution/live_updater.rs index aa5eefea..e7e8ca3b 100644 --- a/crates/recoco-core/src/execution/live_updater.rs +++ b/crates/recoco-core/src/execution/live_updater.rs @@ -549,25 +549,23 @@ impl FlowLiveUpdater { } /// Emit a progress update to all subscribers. - fn emit_progress_update(&self) { + async fn emit_progress_update(&self) { // Always wait for the recv_state lock so we don't silently drop updates, // especially the final completion snapshot. - let recv_state = match self.recv_state.lock() { - Ok(state) => state, - // If the mutex is poisoned, recover the inner state and still emit - // a best-effort progress update instead of silently skipping it. - Err(poisoned) => poisoned.into_inner(), - }; + let recv_state = self.recv_state.lock().await; let status = recv_state.status_rx.borrow(); let active_sources: Vec = status .active_source_idx .iter() - .map(|&idx| { - self.flow_ctx.flow.flow_instance.import_ops[idx] - .name - .clone() + .filter_map(|&idx| { + self.flow_ctx + .flow + .flow_instance + .import_ops + .get(idx) + .map(|op| op.name.clone()) }) .collect(); @@ -608,7 +606,7 @@ impl FlowLiveUpdater { let operation_in_process_stats = self.operation_in_process_stats.clone(); // Clone the status receiver so we can derive active_sources for periodic updates. - let mut status_rx = self.status_rx.clone(); + let status_rx = self.recv_state.lock().await.status_rx.clone(); let progress_emitter = tokio::spawn(async move { let mut interval = tokio::time::interval(std::time::Duration::from_secs(1)); @@ -639,8 +637,20 @@ impl FlowLiveUpdater { let operation_in_process = operation_in_process_stats.get_all_operations_in_process(); - // Derive active_sources from the latest FlowLiveUpdaterStatus. - let active_sources = status_rx.borrow().active_sources.clone(); + // Derive active_sources names from the latest FlowLiveUpdaterStatus. + let active_sources: Vec = status_rx + .borrow() + .active_source_idx + .iter() + .filter_map(|&idx| { + flow_ctx + .flow + .flow_instance + .import_ops + .get(idx) + .map(|op| op.name.clone()) + }) + .collect(); let update = ProgressUpdate { active_sources, @@ -678,7 +688,7 @@ impl FlowLiveUpdater { } // Emit final progress update - self.emit_progress_update(); + self.emit_progress_update().await; progress_emitter.abort(); Ok(()) diff --git a/crates/recoco-core/src/execution/stats.rs b/crates/recoco-core/src/execution/stats.rs index 41f21e45..ce1b14ec 100644 --- a/crates/recoco-core/src/execution/stats.rs +++ b/crates/recoco-core/src/execution/stats.rs @@ -254,126 +254,6 @@ impl UpdateStats { .or_default() .clone() } -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::Value; - - #[test] - fn component_counters_update_correctly() { - let stats = UpdateStats::default(); - - // Populate per-component stats by writing into the by_component map. - { - let mut components = stats.by_component.write().unwrap(); - let comp_stats = components.entry("comp_a".to_string()).or_default(); - comp_stats.num_processed.inc(3); - comp_stats.num_errors.inc(1); - comp_stats.processing.inc(2); - } - - let components = stats.by_component.read().unwrap(); - let comp_stats = components.get("comp_a").expect("component stats should exist"); - assert_eq!(comp_stats.num_processed.get(), 3); - assert_eq!(comp_stats.num_errors.get(), 1); - assert_eq!(comp_stats.processing.get(), 2); - } - - #[test] - fn merge_combines_component_stats() { - let base = UpdateStats::default(); - let delta = UpdateStats::default(); - - { - let mut base_components = base.by_component.write().unwrap(); - let base_comp = base_components.entry("comp_a".to_string()).or_default(); - base_comp.num_processed.inc(5); - base_comp.num_errors.inc(2); - base_comp.processing.inc(1); - } - - { - let mut delta_components = delta.by_component.write().unwrap(); - let delta_comp_a = delta_components.entry("comp_a".to_string()).or_default(); - delta_comp_a.num_processed.inc(4); - delta_comp_a.num_errors.inc(3); - delta_comp_a.processing.inc(2); - - let delta_comp_b = delta_components.entry("comp_b".to_string()).or_default(); - delta_comp_b.num_processed.inc(7); - delta_comp_b.num_errors.inc(0); - delta_comp_b.processing.inc(5); - } - - base.merge(&delta); - - let components = base.by_component.read().unwrap(); - let comp_a = components.get("comp_a").expect("comp_a should exist after merge"); - assert_eq!(comp_a.num_processed.get(), 5 + 4); - assert_eq!(comp_a.num_errors.get(), 2 + 3); - assert_eq!(comp_a.processing.get(), 1 + 2); - - let comp_b = components.get("comp_b").expect("comp_b should be added by merge"); - assert_eq!(comp_b.num_processed.get(), 7); - assert_eq!(comp_b.num_errors.get(), 0); - assert_eq!(comp_b.processing.get(), 5); - } - - #[test] - fn serialization_omits_empty_by_component() { - let stats = UpdateStats::default(); - - let value = serde_json::to_value(&stats).expect("serialization should succeed"); - let obj = value.as_object().expect("stats should serialize to JSON object"); - - // When there are no per-component stats, by_component should be omitted if - // #[serde(skip_serializing_if = "HashMap::is_empty")] is used. - assert!( - !obj.contains_key("by_component"), - "by_component should be omitted when empty" - ); - } - - #[test] - fn serialization_includes_non_empty_by_component() { - let stats = UpdateStats::default(); - { - let mut components = stats.by_component.write().unwrap(); - let comp_stats = components.entry("comp_a".to_string()).or_default(); - comp_stats.num_processed.inc(1); - comp_stats.num_errors.inc(0); - comp_stats.processing.inc(0); - } - - let value = serde_json::to_value(&stats).expect("serialization should succeed"); - let obj = value.as_object().expect("stats should serialize to JSON object"); - - let by_component_value = obj - .get("by_component") - .expect("by_component should be present when non-empty"); - - let by_component_obj = by_component_value - .as_object() - .expect("by_component should be a JSON object"); - - let comp_a_value = by_component_obj - .get("comp_a") - .expect("comp_a entry should be present"); - - let comp_a_obj = comp_a_value - .as_object() - .expect("component stats should serialize to JSON object"); - - // We don't assert exact field names beyond presence to keep this robust to - // unrelated serialization changes, but we ensure some counters are present. - assert!( - comp_a_obj.contains_key("num_processed"), - "component stats should include num_processed" - ); - } -} /// Record component processing start. pub fn component_start(&self, component_name: &str, count: i64) { @@ -938,4 +818,123 @@ mod tests { assert_eq!(op_stats.get_operation_in_process_count("test_op"), 10); // 15-5 } + + #[cfg(feature = "persistence")] + #[test] + fn component_counters_update_correctly() { + let stats = UpdateStats::default(); + + // Start 3 items, complete 2, error 1 → all accounted for, in_process = 0. + stats.component_start("comp_a", 3); + stats.component_complete("comp_a", 2); + stats.component_error("comp_a", 1); + + let components = stats.by_component.read().unwrap(); + let comp_stats = components + .get("comp_a") + .expect("component stats should exist"); + assert_eq!(comp_stats.num_processed.get(), 2); + assert_eq!(comp_stats.num_errors.get(), 1); + // processing: 3 started, 3 ended (2 complete + 1 error) + assert_eq!(comp_stats.processing.get_in_process(), 0); + } + + #[cfg(feature = "persistence")] + #[test] + fn merge_combines_component_stats() { + let base = UpdateStats::default(); + let delta = UpdateStats::default(); + + { + let mut base_components = base.by_component.write().unwrap(); + let base_comp = base_components.entry("comp_a".to_string()).or_default(); + base_comp.num_processed.inc(5); + base_comp.num_errors.inc(2); + base_comp.processing.start(1); + } + + { + let mut delta_components = delta.by_component.write().unwrap(); + let delta_comp_a = delta_components.entry("comp_a".to_string()).or_default(); + delta_comp_a.num_processed.inc(4); + delta_comp_a.num_errors.inc(3); + delta_comp_a.processing.start(2); + + let delta_comp_b = delta_components.entry("comp_b".to_string()).or_default(); + delta_comp_b.num_processed.inc(7); + delta_comp_b.num_errors.inc(0); + delta_comp_b.processing.start(5); + } + + base.merge(&delta); + + let components = base.by_component.read().unwrap(); + let comp_a = components + .get("comp_a") + .expect("comp_a should exist after merge"); + assert_eq!(comp_a.num_processed.get(), 5 + 4); + assert_eq!(comp_a.num_errors.get(), 2 + 3); + assert_eq!(comp_a.processing.num_starts.get(), 1 + 2); + + let comp_b = components + .get("comp_b") + .expect("comp_b should be added by merge"); + assert_eq!(comp_b.num_processed.get(), 7); + assert_eq!(comp_b.num_errors.get(), 0); + assert_eq!(comp_b.processing.num_starts.get(), 5); + } + + #[cfg(feature = "persistence")] + #[test] + fn serialization_omits_empty_by_component() { + let stats = UpdateStats::default(); + + let value = serde_json::to_value(&stats).expect("serialization should succeed"); + let obj = value + .as_object() + .expect("stats should serialize to JSON object"); + + // When there are no per-component stats, by_component should be omitted. + assert!( + !obj.contains_key("by_component"), + "by_component should be omitted when empty" + ); + } + + #[cfg(feature = "persistence")] + #[test] + fn serialization_includes_non_empty_by_component() { + let stats = UpdateStats::default(); + { + let mut components = stats.by_component.write().unwrap(); + let comp_stats = components.entry("comp_a".to_string()).or_default(); + comp_stats.num_processed.inc(1); + } + + let value = serde_json::to_value(&stats).expect("serialization should succeed"); + let obj = value + .as_object() + .expect("stats should serialize to JSON object"); + + let by_component_value = obj + .get("by_component") + .expect("by_component should be present when non-empty"); + + let by_component_obj = by_component_value + .as_object() + .expect("by_component should be a JSON object"); + + let comp_a_value = by_component_obj + .get("comp_a") + .expect("comp_a entry should be present"); + + let comp_a_obj = comp_a_value + .as_object() + .expect("component stats should serialize to JSON object"); + + assert!( + comp_a_obj.contains_key("num_processed"), + "component stats should include num_processed" + ); + } } From 7d542fd5a8279b1174d4fd2a0aee61ab23c55ab5 Mon Sep 17 00:00:00 2001 From: Adam Poulemanos Date: Thu, 19 Mar 2026 15:51:10 -0400 Subject: [PATCH 38/38] fix: linting and formating --- crates/recoco-core/src/setup/components.rs | 4 ++-- crates/recoco-splitters/Cargo.toml | 4 ++-- crates/recoco-splitters/src/split/recursive.rs | 8 +++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/crates/recoco-core/src/setup/components.rs b/crates/recoco-core/src/setup/components.rs index 2035642c..22a0f0e7 100644 --- a/crates/recoco-core/src/setup/components.rs +++ b/crates/recoco-core/src/setup/components.rs @@ -178,7 +178,7 @@ pub async fn apply_component_changes( ) -> Result<()> { // First delete components that need to be removed, with bounded concurrency // to avoid overloading the underlying store or exhausting connection pools. - run_bounded(changes.iter().flat_map(|change| { + run_bounded(changes.iter().copied().flat_map(|change| { change .keys_to_delete .iter() @@ -187,7 +187,7 @@ pub async fn apply_component_changes( .await?; // Then upsert components that need to be updated, also with bounded concurrency. - run_bounded(changes.iter().flat_map(|change| { + run_bounded(changes.iter().copied().flat_map(|change| { change.states_to_upsert.iter().map(move |state| async move { if state.already_exists { change.desc.update(&state.state, context).await diff --git a/crates/recoco-splitters/Cargo.toml b/crates/recoco-splitters/Cargo.toml index 34397dc7..40900531 100644 --- a/crates/recoco-splitters/Cargo.toml +++ b/crates/recoco-splitters/Cargo.toml @@ -86,13 +86,12 @@ all = [ "xml", "yaml", ] -full = ["all", "pattern-matching"] -pattern-matching = ["dep:anyhow", "dep:globset"] c = ["dep:tree-sitter-c"] c-sharp = ["dep:tree-sitter-c-sharp"] cpp = ["dep:tree-sitter-cpp"] css = ["dep:tree-sitter-css"] fortran = ["dep:tree-sitter-fortran"] +full = ["all", "pattern-matching"] go = ["dep:tree-sitter-go"] html = ["dep:tree-sitter-html"] java = ["dep:tree-sitter-java"] @@ -101,6 +100,7 @@ json = ["dep:tree-sitter-json"] kotlin = ["dep:tree-sitter-kotlin-ng"] markdown = ["dep:tree-sitter-md"] pascal = ["dep:tree-sitter-pascal"] +pattern-matching = ["dep:anyhow", "dep:globset"] php = ["dep:tree-sitter-php"] python = ["dep:tree-sitter-python"] r = ["dep:tree-sitter-r"] diff --git a/crates/recoco-splitters/src/split/recursive.rs b/crates/recoco-splitters/src/split/recursive.rs index 717547a1..b2ed4407 100644 --- a/crates/recoco-splitters/src/split/recursive.rs +++ b/crates/recoco-splitters/src/split/recursive.rs @@ -419,11 +419,9 @@ impl<'t, 's: 't> InternalRecursiveChunker<'s> { } fn get_overlap_cost_base(&self, offset: usize) -> usize { - if self.chunk_overlap == 0 { - 0 - } else { - (self.full_text.len() - offset) * MISSING_OVERLAP_COST / self.chunk_overlap - } + ((self.full_text.len() - offset) * MISSING_OVERLAP_COST) + .checked_div(self.chunk_overlap) + .unwrap_or(0) } fn merge_atom_chunks(&self, atom_chunks: Vec) -> Vec {