diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 305c9cf9eed7..7af071b226a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,7 +125,7 @@ jobs: test: name: Test Suite if: ${{ needs.pre_job.outputs.should_skip != 'true' || github.event_name != 'pull_request' }} - timeout-minutes: 35 + timeout-minutes: 50 needs: pre_job runs-on: ${{ matrix.os }} strategy: @@ -199,7 +199,7 @@ jobs: source .venv/bin/activate pip install maturin maturin develop - + - name: Build CLI (Windows) if: ${{ matrix.os == 'windows-latest' }} run: | diff --git a/.idea/hydroflow.iml b/.idea/hydroflow.iml index fc353ac331a9..8871ceafeb5a 100644 --- a/.idea/hydroflow.iml +++ b/.idea/hydroflow.iml @@ -36,6 +36,10 @@ + + + + diff --git a/.vscode/settings.json b/.vscode/settings.json index 80aead1799ae..d650a5fd0e7c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,15 @@ } } ], + "editor.semanticTokenColorCustomizations": { + "enabled": true, + "rules": { + "*.unsafe:rust": { + "foreground": "#ea1708", + "fontStyle": "bold" + } + } + }, "files.watcherExclude": { "**/target": true }, diff --git a/Cargo.lock b/Cargo.lock index 425c3ecc420a..396a800a5c20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,15 +83,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anstream" version = "0.6.15" @@ -143,9 +134,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" dependencies = [ "backtrace", ] @@ -156,12 +147,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "ascii" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" - [[package]] name = "async-channel" version = "2.3.1" @@ -321,6 +306,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "benches" version = "0.0.0" @@ -357,6 +348,9 @@ name = "bitflags" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -488,9 +482,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.14" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" dependencies = [ "shlex", ] @@ -532,12 +526,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "chunked_transfer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" - [[package]] name = "ciborium" version = "0.2.2" @@ -649,6 +637,26 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "config" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7328b20597b53c2454f0b1919720c25c7339051c02b72b7e05409e00b14132be" +dependencies = [ + "async-trait", + "convert_case", + "json5", + "lazy_static", + "nom 7.1.3", + "pathdiff", + "ron", + "rust-ini", + "serde", + "serde_json", + "toml", + "yaml-rust", +] + [[package]] name = "console" version = "0.15.8" @@ -672,6 +680,35 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -795,25 +832,15 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "ctrlc" -version = "3.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" -dependencies = [ - "nix", - "windows-sys 0.59.0", -] - [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core 0.9.10", @@ -844,12 +871,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - [[package]] name = "differential-dataflow-master" version = "0.13.0-dev.1" @@ -874,24 +895,12 @@ dependencies = [ ] [[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" +name = "dlv-list" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", + "const-random", ] [[package]] @@ -918,6 +927,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "env_filter" version = "0.1.2" @@ -1011,16 +1029,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e180ac76c23b45e767bd7ae9579bc0bb458618c4bc71835926e098e61d15f8" -dependencies = [ - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "futures" version = "0.3.30" @@ -1038,9 +1046,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1048,9 +1056,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" @@ -1065,9 +1073,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -1084,9 +1092,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1095,21 +1103,27 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1167,6 +1181,70 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gossip_kv" +version = "0.1.0" +dependencies = [ + "clap", + "config", + "governor", + "hostname", + "hydroflow", + "lattices", + "lazy_static", + "notify", + "prometheus", + "rand", + "serde", + "serde_json", + "shlex", + "tokio", + "tracing", + "tracing-subscriber", + "uuid", + "warp", +] + +[[package]] +name = "governor" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0746aa765db78b521451ef74221663b57ba595bf83f75d0ce23cc09447c8139f" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.3", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.1" @@ -1177,6 +1255,12 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + [[package]] name = "hashbrown" version = "0.14.5" @@ -1187,6 +1271,36 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http 0.2.12", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.12", +] + [[package]] name = "heck" version = "0.4.1" @@ -1211,12 +1325,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "home" version = "0.5.9" @@ -1227,12 +1335,14 @@ dependencies = [ ] [[package]] -name = "html-escape" -version = "0.2.13" +name = "hostname" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ - "utf8-width", + "cfg-if", + "libc", + "windows", ] [[package]] @@ -1246,6 +1356,28 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.9.4" @@ -1266,7 +1398,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hydro_cli" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "async-ssh2-lite", @@ -1292,12 +1424,12 @@ dependencies = [ "serde", "serde_json", "tokio", - "tokio-tungstenite", + "tokio-tungstenite 0.20.1", ] [[package]] name = "hydro_deploy" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "async-process", @@ -1329,7 +1461,7 @@ dependencies = [ [[package]] name = "hydroflow" -version = "0.9.0" +version = "0.10.0" dependencies = [ "bincode", "byteorder", @@ -1354,8 +1486,8 @@ dependencies = [ "rand_distr", "ref-cast", "regex", - "rustc-hash", - "sealed", + "rustc-hash 1.1.0", + "sealed 0.5.0", "serde", "serde_json", "slotmap", @@ -1376,7 +1508,7 @@ dependencies = [ [[package]] name = "hydroflow_datalog" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hydroflow_datalog_core", "proc-macro-crate", @@ -1387,7 +1519,7 @@ dependencies = [ [[package]] name = "hydroflow_datalog_core" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hydroflow_lang", "insta", @@ -1403,7 +1535,7 @@ dependencies = [ [[package]] name = "hydroflow_deploy_integration" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-recursion", "async-trait", @@ -1419,7 +1551,7 @@ dependencies = [ [[package]] name = "hydroflow_lang" -version = "0.9.0" +version = "0.10.0" dependencies = [ "auto_impl", "clap", @@ -1437,7 +1569,7 @@ dependencies = [ [[package]] name = "hydroflow_macro" -version = "0.9.0" +version = "0.10.0" dependencies = [ "hydroflow_lang", "itertools", @@ -1449,7 +1581,7 @@ dependencies = [ [[package]] name = "hydroflow_plus" -version = "0.9.0" +version = "0.10.0" dependencies = [ "async-ssh2-lite", "bincode", @@ -1463,6 +1595,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", + "sealed 0.6.0", "serde", "sha2", "stageleft", @@ -1470,6 +1603,7 @@ dependencies = [ "syn 2.0.75", "tokio", "toml", + "trybuild", "trybuild-internals-api", ] @@ -1513,6 +1647,30 @@ dependencies = [ "stageleft_tool", ] +[[package]] +name = "hyper" +version = "0.14.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1548,12 +1706,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.0", ] [[package]] @@ -1598,6 +1756,26 @@ dependencies = [ "str_stack", ] +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "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 = "insta" version = "1.39.0" @@ -1682,20 +1860,54 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +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 = "lattices" -version = "0.5.7" +version = "0.5.8" dependencies = [ "cc-traits", "lattices_macro", - "sealed", + "ref-cast", + "sealed 0.5.0", "serde", "trybuild", + "variadics", + "variadics_macro", ] [[package]] name = "lattices_macro" -version = "0.5.6" +version = "0.5.7" dependencies = [ "insta", "prettyplease", @@ -1717,16 +1929,6 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - [[package]] name = "libm" version = "0.2.8" @@ -1828,6 +2030,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minicov" version = "0.3.5" @@ -1838,6 +2056,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.4" @@ -1847,6 +2071,18 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "mio" version = "1.0.2" @@ -1859,9 +2095,27 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 0.2.12", + "httparse", + "log", + "memchr", + "mime", + "spin", + "version_check", +] + [[package]] name = "multiplatform_test" -version = "0.2.0" +version = "0.3.0" dependencies = [ "env_logger", "log", @@ -1905,12 +2159,51 @@ dependencies = [ "libc", ] +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + [[package]] name = "nom" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf51a729ecf40266a2368ad335a5fdde43471f545a967109cd62146ecf8b66ff" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.6.0", + "filetime", + "inotify", + "kqueue", + "libc", + "log", + "mio 0.8.11", + "walkdir", + "windows-sys 0.48.0", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2031,10 +2324,14 @@ dependencies = [ ] [[package]] -name = "option-ext" -version = "0.2.0" +name = "ordered-multimap" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +checksum = "4ed8acf08e98e744e5384c8bc63ceb0364e68a6854187221c18df61c4797690e" +dependencies = [ + "dlv-list", + "hashbrown 0.13.2", +] [[package]] name = "overload" @@ -2102,12 +2399,63 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.75", +] + +[[package]] +name = "pest_meta" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + [[package]] name = "pin-project" version = "1.1.5" @@ -2243,9 +2591,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -2258,13 +2606,34 @@ checksum = "6ab1427f3d2635891f842892dda177883dca0639e05fe66796a62c9d2f23b49c" dependencies = [ "byteorder", "libc", - "nom", + "nom 2.2.1", "rustc_version", ] +[[package]] +name = "prometheus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot 0.12.3", + "protobuf", + "thiserror", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + [[package]] name = "pusherator" -version = "0.0.8" +version = "0.0.9" dependencies = [ "either", "variadics", @@ -2368,6 +2737,21 @@ dependencies = [ "serde", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quick-xml" version = "0.26.0" @@ -2426,6 +2810,15 @@ dependencies = [ "rand", ] +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "rayon" version = "1.10.0" @@ -2464,17 +2857,6 @@ dependencies = [ "bitflags 2.6.0", ] -[[package]] -name = "redox_users" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" -dependencies = [ - "getrandom", - "libredox", - "thiserror", -] - [[package]] name = "ref-cast" version = "1.0.23" @@ -2561,11 +2943,33 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.6.0", + "serde", + "serde_derive", +] + +[[package]] +name = "rust-ini" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e2a3bcec1f113553ef1c88aae6c020a369d03d55b58de9869a0908930385091" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + [[package]] name = "rust-sitter" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f69b9a5d53b74db5166799a0024c2849e144c652dd6253c5bf58dfe086798cbc" +checksum = "890cd29b9cd344678003f03f22d8b171a4d4b333f1ba88e2804b1ef7dd39b1d5" dependencies = [ "rust-sitter-macro", "tree-sitter-c2rust", @@ -2573,41 +2977,41 @@ dependencies = [ [[package]] name = "rust-sitter-common" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b559ebfd4114d398a36dfe25d7221bf84839fc3ef1309a6b7f4d1eece78dc690" +checksum = "3d8e1c8d26b8d5fb23415a5123588669e776ad934abbfbe6d8677ed322694216" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.75", ] [[package]] name = "rust-sitter-macro" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8238447de92f7104ddbda8b5fd38a9be055229373283ef42b774b340d8117def" +checksum = "07defe73314513d2b671b4c81603a236193eabe8ec7afd480dd3ed769dd75fb6" dependencies = [ "proc-macro2", "quote", "rust-sitter-common", - "syn 1.0.109", + "syn 2.0.75", ] [[package]] name = "rust-sitter-tool" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b840052f42d08fb67d13f68b72f1c41f99865d83239f4edff8fa1c6fd6fa0a12" +checksum = "9e666bbe8cf47a6ba0c88da4f2b98ebadb98bc1b5b9723aa5784137ae93f9436" dependencies = [ "cc", "rust-sitter-common", "serde", "serde_json", - "syn 1.0.109", - "syn-inline-mod 0.5.0", + "syn 2.0.75", + "syn-inline-mod", "tempfile", "tree-sitter", - "tree-sitter-cli", + "tree-sitter-generate", ] [[package]] @@ -2622,6 +3026,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2683,6 +3093,17 @@ dependencies = [ "syn 2.0.75", ] +[[package]] +name = "sealed" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] + [[package]] name = "semver" version = "0.9.0" @@ -2715,9 +3136,9 @@ checksum = "5a9f47faea3cad316faa914d013d24f471cd90bfca1a0c70f05a3f42c6441e99" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -2735,9 +3156,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -2746,9 +3167,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "indexmap", "itoa", @@ -2766,6 +3187,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -2788,19 +3221,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha256" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" -dependencies = [ - "async-trait", - "bytes", - "hex", - "sha2", - "tokio", -] - [[package]] name = "sharded-slab" version = "0.1.7" @@ -2878,6 +3298,21 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "ssh2" version = "0.9.4" @@ -2892,7 +3327,7 @@ dependencies = [ [[package]] name = "stageleft" -version = "0.4.0" +version = "0.5.0" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2903,14 +3338,14 @@ dependencies = [ [[package]] name = "stageleft_macro" -version = "0.3.0" +version = "0.4.0" dependencies = [ "insta", "prettyplease", "proc-macro-crate", "proc-macro2", "quote", - "sha256", + "sha2", "syn 2.0.75", ] @@ -2933,13 +3368,13 @@ dependencies = [ [[package]] name = "stageleft_tool" -version = "0.3.0" +version = "0.4.0" dependencies = [ "proc-macro2", "quote", - "sha256", + "sha2", "syn 2.0.75", - "syn-inline-mod 0.6.0", + "syn-inline-mod", ] [[package]] @@ -2964,6 +3399,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + [[package]] name = "strsim" version = "0.11.1" @@ -2992,16 +3433,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn-inline-mod" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b670f535364c67358ecffb60b9f2579f9b45d3c71e8cca6d45d22ee0fadaa7eb" -dependencies = [ - "proc-macro2", - "syn 1.0.109", -] - [[package]] name = "syn-inline-mod" version = "0.6.0" @@ -3159,15 +3590,12 @@ dependencies = [ ] [[package]] -name = "tiny_http" -version = "0.12.0" +name = "tiny-keccak" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" dependencies = [ - "ascii", - "chunked_transfer", - "httpdate", - "log", + "crunchy", ] [[package]] @@ -3204,7 +3632,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio", + "mio 1.0.2", "parking_lot 0.12.3", "pin-project-lite", "signal-hook-registry", @@ -3245,7 +3673,19 @@ dependencies = [ "futures-util", "log", "tokio", - "tungstenite", + "tungstenite 0.20.1", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.21.0", ] [[package]] @@ -3321,12 +3761,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3384,123 +3831,65 @@ dependencies = [ [[package]] name = "tree-sitter" -version = "0.22.6" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7cc499ceadd4dcdf7ec6d4cbc34ece92c3fa07821e287aedecd4416c516dca" +checksum = "f9871f16d6cf5c4757dcf30d5d2172a2df6987c510c017bbb7abfb7f9aa24d06" dependencies = [ "cc", "regex", + "regex-syntax 0.8.4", + "streaming-iterator", + "tree-sitter-language", ] [[package]] name = "tree-sitter-c2rust" -version = "0.22.6" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cd4f1075a82f3c4ae5e93dc39d4e0765d132a6d2773b3d86214fcc54e6d1e9" +checksum = "a5f97c8ed19295f92e02af90c915c72d0836e08132f155709bc45b66acdfde35" dependencies = [ "c2rust-bitfields", "once_cell", "regex", + "regex-syntax 0.8.4", + "streaming-iterator", + "tree-sitter-language", ] [[package]] -name = "tree-sitter-cli" -version = "0.22.6" +name = "tree-sitter-generate" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7437ac48e37e5014007527ed9281c00c333c9ad0731e1c8489c0eff667b99d5" +checksum = "169563a4e3713ad23a2a755446ed1e3af7db5cfc3b8beb0986b7e96f3619aec3" dependencies = [ - "ansi_term", - "anstyle", "anyhow", - "clap", - "ctrlc", - "difference", - "dirs", - "filetime", - "glob", "heck 0.5.0", - "html-escape", "indexmap", "indoc", "lazy_static", "log", - "memchr", "regex", "regex-syntax 0.8.4", - "rustc-hash", + "rustc-hash 2.0.0", "semver 1.0.23", "serde", - "serde_derive", "serde_json", "smallbitvec", - "tiny_http", "tree-sitter", - "tree-sitter-config", - "tree-sitter-highlight", - "tree-sitter-loader", - "tree-sitter-tags", - "walkdir", - "wasmparser", - "webbrowser", -] - -[[package]] -name = "tree-sitter-config" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64b4608a1d822f56e3afcecabfa4915a768ea92bc44abad1ae32cd4c607ebd" -dependencies = [ - "anyhow", - "dirs", - "serde", - "serde_json", + "url", ] [[package]] -name = "tree-sitter-highlight" -version = "0.22.6" +name = "tree-sitter-language" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaca0fe34fa96eec6aaa8e63308dbe1bafe65a6317487c287f93938959b21907" -dependencies = [ - "lazy_static", - "regex", - "thiserror", - "tree-sitter", -] +checksum = "e8ddffe35a0e5eeeadf13ff7350af564c6e73993a24db62caee1822b185c2600" [[package]] -name = "tree-sitter-loader" -version = "0.22.6" +name = "try-lock" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9b13749644fbe22ec25c79861dc1e637ef4ab9e469fd820fcb30b10091293" -dependencies = [ - "anyhow", - "cc", - "dirs", - "fs4", - "indoc", - "libloading", - "once_cell", - "regex", - "serde", - "serde_json", - "tempfile", - "tree-sitter", - "tree-sitter-highlight", - "tree-sitter-tags", -] - -[[package]] -name = "tree-sitter-tags" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34380416097ab36d1b4cd83f887d9e150ea4feaeb6ee9a5ecfe53d26839acc69" -dependencies = [ - "memchr", - "regex", - "thiserror", - "tree-sitter", -] +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "try_match" @@ -3559,7 +3948,26 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", + "httparse", + "log", + "rand", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", "httparse", "log", "rand", @@ -3575,6 +3983,21 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -3596,6 +4019,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + [[package]] name = "unicode-width" version = "0.1.13" @@ -3623,6 +4052,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -3631,18 +4061,21 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom", +] + [[package]] name = "valuable" version = "0.1.0" @@ -3651,13 +4084,26 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "variadics" -version = "0.0.6" +version = "0.0.7" dependencies = [ - "hashbrown", - "sealed", + "hashbrown 0.14.5", + "sealed 0.5.0", "trybuild", ] +[[package]] +name = "variadics_macro" +version = "0.5.5" +dependencies = [ + "insta", + "prettyplease", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.75", + "variadics", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -3680,6 +4126,44 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378d202ff965b011c64817db11d5829506d3404edeadb61f190d111da3f231c" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "headers", + "http 0.2.12", + "hyper", + "log", + "mime", + "mime_guess", + "multer", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-tungstenite 0.21.0", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3779,19 +4263,6 @@ dependencies = [ "syn 2.0.75", ] -[[package]] -name = "wasmparser" -version = "0.206.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39192edb55d55b41963db40fd49b0b542156f04447b5b512744a91d38567bdbc" -dependencies = [ - "ahash", - "bitflags 2.6.0", - "hashbrown", - "indexmap", - "semver 1.0.23", -] - [[package]] name = "web-sys" version = "0.3.70" @@ -3882,6 +4353,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -4123,6 +4604,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index 668519191c00..224bad277975 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ # See "Adding new crates" and "Moving crates" addendum sections in `RELEASING.md` members = [ "benches", + "datastores/gossip_kv", "hydro_deploy/core", "hydro_deploy/hydro_cli", "hydro_deploy/hydro_cli_examples", @@ -28,6 +29,7 @@ members = [ "stageleft_tool", "topolotree", "variadics", + "variadics_macro", "website_playground", ] @@ -55,6 +57,7 @@ opt-level = "s" [workspace.lints.rust] unused_qualifications = "warn" +unsafe_op_in_unsafe_fn = "warn" [workspace.lints.clippy] allow_attributes = "warn" diff --git a/README.md b/README.md index da04f8a3587f..34d0e833e1c2 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,58 @@

- "hf" - Hydroflow
+ "hf"

Crates.io Docs.rs

-Hydroflow is a low-latency dataflow runtime written in Rust. The goal of the [Hydro Project](https://hydro.run) -is to empower developers to harness the full potential of the cloud by making distributed programs easy to specify and automatic to scale. Hydroflow is the lowest level in the [Hydro stack](https://hydro.run/docs/hydroflow/ecosystem/), -serving as a single-node low-latency runtime with explicit networking. This allows us to support -not just data processing pipelines, but distributed protocols (e.g. Paxos) and real-world -long-running applications as well. +Hydro is a novel distributed programming library for standard Rust. Hydro allows developers to build distributed systems that are efficient, scalable, and correct. -Take a look at the [Hydroflow Book](https://hydro.run/docs/hydroflow/). +Hydro integrates naturally into standard Rust constructs and IDEs, providing types and programming constructs for ensuring distributed correctness. Under the covers it provides a metaprogrammed compiler that optimizes for cross-node issues of scaling and data movement while leveraging Rust and LLVM for per-node performance. -## The Hydroflow Surface Syntax +We often describe Hydro via a metaphor: *LLVM for the cloud*. Like LLVM, Hydro is a layered compilation framework with a low-level Internal Representation language. In contrast to LLVM, Hydro focuses on distributed aspects of modern software. + +
+ Image description +
-Hydroflow comes with a custom "surface syntax"—a domain-specific language which serves as a very -simple, readable IR for specifying single-node Hydroflow programs. These programs are intended to be stitched together -by the Hydro stack to create larger autoscaling distributed systems. -Here's a simple example of the surface syntax. Check out the [Hydroflow Playground](https://hydro.run/playground) -for an interactive demo. -```rust -source_iter(0..10) - -> map(|n| n * n) - -> filter(|n| *n > 10) - -> foo; +## The Language (and the Low-Level IR) +Hydro provides a high-level language for the majority of developers called [Hydroflow+](https://hydro.run/docs/hydroflow_plus). Hydroflow+ allows you to program an entire fleet of processes from a single program, and then launch your fleet locally or in the cloud via [Hydro Deploy](https://hydro.run/docs/deploy). Get started with Hydroflow+ via the Hydroflow+ [documentation](https://hydro.run/docs/hydroflow_plus) and [examples](https://github.com/hydro-project/hydroflow/tree/main/hydroflow_plus_test/examples). -foo = map(|n| (n..=n+1)) - -> flatten() - -> for_each(|n| println!("Howdy {}", n)); -``` +> Internally, the Hydro stack compiles Hydroflow+ programs into a low-level Internal Representation (IR) language called [Hydroflow](https://hydro.run/docs/hydroflow); each process corresponds to a separate Hydroflow program. In rare cases you may want to compose one or more processes in Hydroflow by hand; see the Hydroflow [documentation](https://hydro.run/docs/hydroflow) or [examples](https://github.com/hydro-project/hydroflow/tree/main/hydroflow/examples) for details. -For more, check out the [surface syntax section of the Hydroflow book](https://hydro.run/docs/hydroflow/syntax/). +## Development Setup -## Start with a Template Program -We provide a `cargo-generate` template for you to get started from a simple working example. +See the [quickstart section of the Hydroflow+ book](https://hydro.run/docs/hydroflow_plus/quickstart/) for instructions on installing Rust and getting started with the Hydroflow+ template. -To install `cargo-generate`, run the following: -```bash,ignore -cargo install cargo-generate -``` +# A New Approach to Distributed Programming +There have been many frameworks and platforms for distributed programming over the years, with significant tradeoffs. These include: -Then run: -```bash,ignore -cargo generate gh:hydro-project/hydroflow template/hydroflow -``` +**Higher level frameworks** have been designed to serve specialized distributed use cases. These including *Client-Server (Monolith)* frameworks (e.g. Ruby on Rails + DBMS), parallel *Bulk Dataflow* frameworks (e.g. Spark, Flink, etc.), and step-wise *Workflows / Pipelines / Serverless / μservice Orchestration* frameworks (e.g. Kafka, Airflow). All of these frameworks offer limited expressibility and are inefficient outside their sweet spot. Each one ties developers' hands in different ways. -`cd` into the generated folder, ensure the correct nightly version of rust is installed, and test the generated project: -```bash -#shell-command-next-line -cd -#shell-command-next-line -rustup update -#shell-command-next-line -cargo test -``` +**Lower level asynchronous APIs** provide general-purpose distributed interfaces for sequential programming, including + *RPCs*, *Async/Await* frameworks and *Actor* frameworks (e.g. Akka, Ray, Unison, Orleans, gRPC). These interfaces allow developers to build distributed systems *one async sequential process* at a time. While they offer low-level control of individual processes, they provide minimal help for global correctness of the fleet. -And you will get a well-formed Hydroflow/Rust project to use as a starting point. It provides a simple Echo Server and Client, and advice -for adapting it to other uses. +## Towards a more comprehensive approach +What's wanted, we believe, is a proper language stack addressing distributed concerns: -### Enable IDE Support for Ligatures -Since flow edges `->` appear frequently in flows described using the Hydroflow surface syntax, enabling ligature support -in your IDE may improve your code reading experience. This has no impact on code functionality or performance. +- **Broad Expressivity**: The stack should support a spectrum of performance regimes from lightweight, low-latency async event handling to high-throughput dataflow. It should also support a full range of architectural configurations, from SIMD to more heterogeneous architectures. +- **Familiarity**: The distributed aspects of the language should be integrated into a familiar mature programming language and environment, including libraries, IDEs and other tooling. A mature compiler should optimize local code to be fast and lean. (Hydro embraces Rust and LLVM for these attributes.) +- **Performance control**: The ability to program a fleet of machines "globally" should not prevent software engineers from optimizing the code that executes locally at each node. +- **Distributed Typechecking**: The type system of the language should enforce distributed correctness in the compiler, in ways that are visible in an IDE at time of authoring. For example, the types of data items should include their abstract locations, so that two items materialized at different nodes cannot be referenced together without an intervening construct for (async) communication. +- **Distributed Optimizations**: The compiler should be able to correctly optimize (transform) programs for distributed concerns: removing bottlenecks by flexibly assigning compute and data to different processes or clusters, while preserving program semantics. +- **Modularity**: The standard modularity of traditional programming—e.g. function calling abstractions—should work for distriuted logic. For example, it should be possible to wrap a common cross-node construct like "heartbeats and timeouts", and invoke it as simply as one invokes a sequential function. +- **Native Testing Tools** for correctness. In today's standard practice, formal specification languages for testing (e.g. TLA+) are separate from languages of implementation. We believe it should be possible to perform many kinds of formal testing (e.g. model checking) on the same code that is used in deployment. -Instructions to enable this for the `Fira Code` font: -- [VSCode](https://github.com/tonsky/FiraCode/wiki/VS-Code-Instructions) -- [IntelliJ](https://github.com/tonsky/FiraCode/wiki/IntelliJ-products-instructions) +[Hydro](https://hydro.run) is a Rust library for distributed programming that is designed to address these goals. -More font options are available [here](https://github.com/tonsky/FiraCode?tab=readme-ov-file#alternatives). +# Learning More +The Hydro project's main website is at [https://hydro.run](https://hydro.run). -## Dev Setup +- **Docs**: There are docs for the [high-level Hydroflow+ language](https://hydro.run/docs/hydroflow_plus/) and the [low-level Hydroflow IR](https://hydro.run/docs/hydroflow), as well as the [HydroDeploy](https://hydro.run/docs/deploy) framework for launching Hydroflow+ programs. -See the [setup section of the book](https://hydro.run/docs/hydroflow/quickstart/setup). - -### The Examples Container - -The `hydroflow/examples` subdirectory of this repository includes a number of examples. -To make running these examples in the cloud easier, we've created a Docker image that contains compiled versions of those examples. The image is defined in the `Dockerfile` in the same directory as this README. - -If you want to build the examples container locally, you can run -``` -docker build -t hydroflow-examples . -``` - -This will build an image suitable for your architecture. - -The `scripts/multiplatform-docker-build.sh ` script will build both `arm64` and `amd64` versions of the image and push them to the image name specified. By default, this will push the image to DockerHub; if you want to push the image to another repository, you can pass an image URL as the argument to `multiplatform-docker-build.sh` instead. - -Example binaries are located in `/usr/src/myapp`. +- **Research Papers**: Our [research publications](https://hydro.run/research) are available on the project website. Some notable selections: + - The original Hydro vision paper from CIDR 2021: [New Directions in Cloud Programming](https://hydro.run/papers/new-directions.pdf) + - The first paper on optimizations from SIGMOD 2024: [Optimizing Distributed Protocols with Query Rewrites](https://hydro.run/papers/david-sigmod-2024.pdf) + - The first paper on Hydro's formal semantics to appear in POPL 2025: [Flo: a Semantic Foundation for Progressive Stream Processing](https://arxiv.org/abs/2411.08274) diff --git a/RELEASING.md b/RELEASING.md index 8b96d3e48e79..fc7c5a87593d 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -5,15 +5,15 @@ This is a guide on how to create releases for Hydroflow and all the other crates We use the [`cargo-smart-release` crate](https://github.com/Byron/cargo-smart-release) for our release workflow. Originally, cargo-smart-release [was part of gitoxide](https://github.com/Byron/gitoxide/pull/998) but it has since been separated into its own crate. We have our own [GitHub Action release workflow](https://github.com/hydro-project/hydroflow/actions/workflows/release.yml) -([action specification here](.github/workflows/release.yml)) which is our intended way to create +([action YAML here](.github/workflows/release.yml)) which is our intended way to create releases. -Calling `cargo smart-release` is supposed to _just work_, but has a few rough edges that require a -bit of manual attention before just calling the release workflow. It is supposed to generate +Calling `cargo smart-release` is supposed to _just work_, but it has a few rough edges that can +prevent the release workflow from completing successfully. Mainly, it is supposed to generate changelogs automatically from our [conventional commit](https://www.conventionalcommits.org/) -messages, but requires manually intervention to do so in some situations. +messages, but sometimes requires manual intervention in some situations. -## Installing `cargo-smart-release` locally +## Optional: Installing and running `cargo-smart-release` locally ```sh cargo install cargo-smart-release @@ -21,6 +21,21 @@ cargo install cargo-smart-release Re-run this command before each release to update the tool before testing locally, as the CI will always use the latest version. +Re-run this command before each release to update the tool before testing locally, as the CI will always use the latest version. + +To (dry) run the command locally to spot-check for errors and warnings: +```bash +cargo smart-release --update-crates-index \ + --no-changelog-preview --allow-fully-generated-changelogs \ + --bump-dependencies auto --bump minor \ # or `patch`, `major`, `keep`, `auto` + hydroflow hydroflow_lang hydroflow_macro hydroflow_plus \ + hydroflow_datalog hydroflow_datalog_core \ + hydro_deploy hydro_cli hydroflow_cli_integration \ + hydroflow_plus_cli_integration \ + stageleft stageleft_macro stageleft_tool \ + multiplatform_test +``` + ## Dry run to ensure changelogs can be generated `cargo smart-release` tries to generate changelogs from commit messages. However if a particular @@ -65,6 +80,8 @@ showing that all the changelogs can be modified. Make sure the version bumps loo [INFO ] WOULD modify existing changelog for 'hydro_cli'. ``` +### Check log for this! + If the job does not succeed or succeeds but fails to generate changelogs for certain packages, then you will need to do a bit of manual work. That looks like this in the log (check for this!): ```log @@ -74,6 +91,8 @@ In this case, you will need to create a commit to each package's `CHANGELOG.md` unchanged (or minimally changed). For example, [hydro_datalog 0.4](https://github.com/hydro-project/hydroflow/commit/5faee64ab82eeb7a24f62a1b55c46d72d8eb5320) or [hydro_cli 0.3](https://github.com/hydro-project/hydroflow/commit/4c2cf81411835529b5d7daa35717834e46e28b9b). +Once all changelogs are ok to autogenerate, we can move on to the real-deal run. + ## Real-deal run Again, go to the [Release action](https://github.com/hydro-project/hydroflow/actions/workflows/release.yml) @@ -165,6 +184,14 @@ Commit those changes, then continue as normal. (There may be other issues with the `git tag`s `cargo-smart-release` uses to track versions if you are renaming a crate _back to an old name_). +## Addendum: `[build-dependencies]` + +Due to bug [cargo-smart-release#16](https://github.com/Byron/cargo-smart-release/issues/16), `cargo-smart-release` +does not properly handle `[build-dependencies]` in `Cargo.toml`. If one workspace crate has another +workspace crate as a build dependency `cargo-smart-release` will fail to find this dependency and +may fail due to versioning issues. The workspace dependency should also be added to the `[depedencies]` +section in order to work around this issue. + ## Addendum: The GitHub App account So... `cargo smart-release` wants to push to `hydro-project/hydroflow`'s `main` branch. However, diff --git a/build_docs.bash b/build_docs.bash index 00c5768d5130..478f93614b07 100644 --- a/build_docs.bash +++ b/build_docs.bash @@ -14,7 +14,13 @@ cd website_playground CARGO_CFG_HYDROFLOW_GENERATE_DOCS="1" RUSTFLAGS="--cfg procmacro2_semver_exempt --cfg super_unstable" CC="$PWD/../clang+llvm-13.0.0-$PLATFORM/bin/clang" wasm-pack build -cd ../docs +cd .. + +RUSTDOCFLAGS="-Dwarnings" cargo doc --no-deps + +cp -r target/doc docs/static/rustdoc + +cd docs npm ci diff --git a/datastores/gossip_kv/Cargo.toml b/datastores/gossip_kv/Cargo.toml new file mode 100644 index 000000000000..c2b7e8dc243b --- /dev/null +++ b/datastores/gossip_kv/Cargo.toml @@ -0,0 +1,45 @@ +[package] +description = "Gossip KV Library" +name = "gossip_kv" +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" +publish = false + +[dependencies] +clap = { version = "4.5.4", features = ["derive", "env"] } +config = "0.14.0" +governor = "0.7.0" +hostname = "0.4.0" +hydroflow = { path="../../hydroflow" } +lattices = { path = '../../lattices'} +lazy_static = "1.5.0" +# The specific set of features for Notify are picked to disable the default cross-beam channels (cause problems with +# tokio) and use std channels. See docs for more information: https://docs.rs/notify/6.1.1/notify/ +notify = { version = "6.1.1", default-features = false, features = ["macos_kqueue"] } +prometheus = "0.13.4" +rand = "0.8.5" +serde = "1.0.203" +serde_json = "1.0.117" +shlex = "1.3.0" +tokio = { version = "1.0.0", features = ["rt", "rt-multi-thread", "macros"] } +tracing = "0.1.40" +tracing-subscriber = {version = "0.3.18", features = ["env-filter"]} +uuid = { version = "1.9.1", features = ["v4"] } +warp = "0.3.7" + +[[bin]] +name = "gossip_server" +path = "server/main.rs" + +[[bin]] +name = "load_test_server" +path = "load_test_server/server.rs" + +[[bin]] +name = "gossip_cli" +path = "cli/main.rs" + +[lib] +name = "gossip_kv" +path = "kv/lib.rs" diff --git a/datastores/gossip_kv/README.md b/datastores/gossip_kv/README.md new file mode 100644 index 000000000000..76a1108da080 --- /dev/null +++ b/datastores/gossip_kv/README.md @@ -0,0 +1,87 @@ +# Gossip Key-Value Store + +# Architecture +The Gossip Key-Value Store is a distributed key-value store that uses a gossip protocol to replicate data across all +members of the cluster. The key-value store is eventually consistent and is designed to be used in scenarios where +strict consistency is not a hard requirement. + +## Data Model +Data stored in the key-value store is modelled as three level hierarchy `Namespace > Table > Rows`. + +``` +┌──────────────┐ +│ Namespace │ +└─┬────────────┘ + │ ┌──────────────┐ + └────┤ Table │ + └─┬────────────┘ + │ ┌──────────────┐ + └────┤ Row │ + └──────────────┘ +``` + +Represented as JSON, the data model looks like this: + +```json +{ + "sys": { + "members": { + "member_id": { + "protocols": [ + { + "name": "gossip", + "endpoint": "..." + }, + { + "name": "...", + "endpoint": "..." + } + ] + } + } + }, + "usr": { + "table_A": { + "key_1": "value_1", + "key_2": "value_2" + }, + "table_B": { + "key_1": "value_1", + "key_2": "value_2" + } + } +} +``` +Note that JSON is used here for illustrative purposes only - it isn't the actual data format used by the key-value +store. + +### Namespace +A namespace is a group of tables. There are only two namespaces in the key-value store: `sys` and `usr`. The `sys` +namespace is reserved for system data and is used by the key-value store itself. The `usr` namespace is used for user +data. + +### `sys` Data + +### Members +The members table contains information about all the members in the cluster. Each member is identified by a unique +`member_id`. + +#### Protocols +Each member exposes a set of protocols and endpoint that can be used to communicate with it. For example, every member +exposes the `gossip` protocol which is used by the key-value store to replicate data across the cluster. + +### `usr` Data +The `usr` namespace is used to store user data. The data is stored in tables and rows. Each table is a collection of rows +where each row is a key-value pair. Values are stored as strings and are not interpreted by the key-value store. + +# Unit Testing +A deterministic unit test suite is provided for the key-value store and the replication protocols. See the unit tests +on [server.rs](./kv/server.rs) for more. + +# Deployment +## Local (Minikube) Deployment +For local development and testing, the key-value store can be deployed on Minikube. See [Minikube Deployment](./deployment/local/README.md) +for more information. + +## AWS Deployment +See [AWS Deployment](./deployment/aws/README.md) for more information. \ No newline at end of file diff --git a/datastores/gossip_kv/cli/Dockerfile b/datastores/gossip_kv/cli/Dockerfile new file mode 100644 index 000000000000..208948c50766 --- /dev/null +++ b/datastores/gossip_kv/cli/Dockerfile @@ -0,0 +1,12 @@ +FROM "hydroflow-gossip-kv-base-image:latest" AS builder +WORKDIR /usr/src/gossip-kv-server +COPY . . +RUN find . +RUN cargo build --release --workspace -p gossip_kv + +FROM rustlang/rust:nightly-slim +COPY --from=builder /usr/src/gossip-kv-server/target/release/gossip_cli /usr/local/bin/gossip_cli + +RUN apt-get update && apt-get install -y \ + dnsutils \ + && rm -rf /var/lib/apt/lists/* diff --git a/datastores/gossip_kv/cli/main.rs b/datastores/gossip_kv/cli/main.rs new file mode 100644 index 000000000000..8834da9ce459 --- /dev/null +++ b/datastores/gossip_kv/cli/main.rs @@ -0,0 +1,119 @@ +use std::net::SocketAddr; + +use clap::{CommandFactory, Parser, Subcommand}; +use gossip_kv::{ClientRequest, ClientResponse, Key}; +use hydroflow::util::{bind_udp_bytes, ipv4_resolve}; +use hydroflow::{hydroflow_syntax, tokio, DemuxEnum}; +use tracing::error; + +/// CLI program to interact with Layer 0 gossip store. +#[derive(Debug, Parser)] +struct Opts { + #[clap(short, long, help = "Server address to connect to.")] + server_address: Option, +} + +/// Dummy app for using clap to process commands for interactive CLI. +#[derive(Debug, Parser)] +#[command(multicall = true)] +struct InteractiveApp { + #[clap(subcommand)] + commands: InteractiveCommands, +} + +#[derive(Debug, Subcommand, DemuxEnum)] +enum InteractiveCommands { + /// Get a value from the store. + Get { + #[arg(value_parser = parse_key, required = true, help = "Key to get")] + key: Key, + }, + /// Upsert a value in the store. + Set { + #[arg(value_parser = parse_key, required = true, help = "Key to set")] + key: Key, + value: String, + }, + /// Delete a value from the store. + Delete { + #[arg(value_parser = parse_key, required = true, help = "Key to delete")] + key: Key, + }, + /// Exit the application. + Exit, +} + +/// Allows clap to parse Keys from user input. +fn parse_key(s: &str) -> Result { + s.parse::().map_err(|e| e.to_string()) +} + +/// Parse a command from a line of input. +fn parse_command(line: String) -> Option { + // Override how help is handled. + if line.trim() == "help" { + InteractiveApp::command() + .help_template("\nAvailable Commands: \n{subcommands}") + .print_help() + .unwrap(); + return None; + } + + // Split quoted string into parts. + let line_parts = shlex::split(&line); + + if line_parts.is_none() { + error!("\nUnable to parse command."); + return None; + } + + // Provide split parts to clap to process. + let maybe_parsed = InteractiveApp::try_parse_from(line_parts.unwrap()); + + match maybe_parsed { + Err(e) => { + // Problem with the parsed result. This displays some help. + error!("\n{}", e); + None + } + Ok(cli) => Some(cli.commands), + } +} + +#[hydroflow::main] +async fn main() { + tracing_subscriber::fmt::init(); + + let opts = Opts::parse(); + + // Bind to OS-assigned port on localhost. + let address = ipv4_resolve("0.0.0.0:0").unwrap(); + + // Default to localhost:3000 if not provided. + let server_address = opts.server_address.map_or_else( + || ipv4_resolve("localhost:3001").unwrap(), + |s| ipv4_resolve(&s).unwrap(), + ); + + // Setup UDP sockets for communication. + let (outbound, inbound, _) = bind_udp_bytes(address).await; + + let mut cli = hydroflow_syntax! { + inbound_messages = source_stream_serde(inbound) -> map(Result::unwrap) -> for_each(|(response, _addr): (ClientResponse, SocketAddr)| println!("{:?}", response)); + + outbound_messages = union() -> dest_sink_serde(outbound); + + // Parse commands from stdin. + commands = source_stdin() + -> filter_map(|line| parse_command(line.unwrap())) + -> demux_enum::(); + + commands[Get] -> map(|(key,)| (ClientRequest::Get {key}, server_address)) -> outbound_messages; + commands[Set] -> map(|(key, value)| (ClientRequest::Set {key, value}, server_address)) -> outbound_messages; + commands[Delete] -> map(|(key,)| (ClientRequest::Delete {key}, server_address)) -> outbound_messages; + commands[Exit] -> for_each(|()| std::process::exit(0)); // TODO: Graceful shutdown https://github.com/hydro-project/hydroflow/issues/1253 + + }; + + cli.run_async().await; +} diff --git a/datastores/gossip_kv/deployment/aws/Makefile b/datastores/gossip_kv/deployment/aws/Makefile new file mode 100644 index 000000000000..1ac35ba5c8f8 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/Makefile @@ -0,0 +1,76 @@ +INFRA_PATH=./terraform/infra +APPLICATION_PATH=./terraform/application + +BASE_IMAGE_VERSION:=latest +SERVER_IMAGE_VERSION:=latest +CLI_IMAGE_VERSION:=latest +LOAD_TEST_IMAGE_VERSION:=latest + +# Docker Image Tags +BASE_IMAGE_TAG:=hydroflow-gossip-kv-base-image:$(BASE_IMAGE_VERSION) +SERVER_IMAGE_TAG:=hydroflow-gossip-kv-server:$(SERVER_IMAGE_VERSION) +CLI_IMAGE_TAG:=hydroflow-gossip-kv-cli:$(CLI_IMAGE_VERSION) +LOAD_TEST_IMAGE_TAG:=hydroflow-gossip-kv-load-test:$(LOAD_TEST_IMAGE_VERSION) + +.PHONY : init infra docker_images base_image server_image cli_image upload_docker_images application config clean + +init: + terraform -chdir="$(INFRA_PATH)" init + terraform -chdir="$(APPLICATION_PATH)" init + +infra: + terraform -chdir="$(INFRA_PATH)" apply -auto-approve + +kubectl_setup: + @echo "Setting up kubectl to work with AWS EKS Cluster" + aws eks update-kubeconfig --region $$(terraform -chdir=$(INFRA_PATH) output -raw region) --name $$(terraform -chdir=$(INFRA_PATH) output -raw cluster_name) + +docker_images: base_image server_image cli_image + +base_image: + docker build -t "$(BASE_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/server/baseimage.Dockerfile ../../../.. + +server_image: + docker build -t "$(SERVER_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/server/Dockerfile ../../../.. + +cli_image: + docker build -t "$(CLI_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/cli/Dockerfile ../../../.. + +upload_docker_images: docker_images + $(eval SERVER_REPO_URL := $(shell terraform -chdir=$(INFRA_PATH) output -json repository_urls | jq -r '.["gossip_kv_server"]')) + $(eval CLI_REPO_URL := $(shell terraform -chdir=$(INFRA_PATH) output -json repository_urls | jq -r '.["gossip_kv_cli"]')) + $(eval LOAD_TEST_REPO_URL := $(shell terraform -chdir=$(INFRA_PATH) output -json repository_urls | jq -r '.["gossip_kv_load_test"]')) + $(eval REGION := $(shell terraform -chdir=$(INFRA_PATH) output -raw region)) + echo $(SERVER_REPO_URL) + docker tag $(SERVER_IMAGE_TAG) $(SERVER_REPO_URL):$(SERVER_IMAGE_VERSION) + docker tag $(CLI_IMAGE_TAG) $(CLI_REPO_URL):$(CLI_IMAGE_VERSION) + docker tag $(LOAD_TEST_IMAGE_TAG) $(LOAD_TEST_REPO_URL):$(LOAD_TEST_IMAGE_VERSION) + aws ecr get-login-password --region $(REGION) | docker login --username AWS --password-stdin $(SERVER_REPO_URL) + docker push $(SERVER_REPO_URL):$(SERVER_IMAGE_VERSION) + aws ecr get-login-password --region $(REGION) | docker login --username AWS --password-stdin $(CLI_REPO_URL) + docker push $(CLI_REPO_URL):$(CLI_IMAGE_VERSION) + aws ecr get-login-password --region $(REGION) | docker login --username AWS --password-stdin $(LOAD_TEST_REPO_URL) + docker push $(LOAD_TEST_REPO_URL):$(LOAD_TEST_IMAGE_VERSION) + +application: + terraform -chdir="$(APPLICATION_PATH)" apply -auto-approve + +tunnel_grafana: + $(eval GRAFANA_PORT := $(shell terraform -chdir=$(APPLICATION_PATH) output -raw grafana_port)) + @echo "Grafana will be accessible at http://localhost:$(GRAFANA_PORT)" + kubectl port-forward svc/grafana $(GRAFANA_PORT):$(GRAFANA_PORT) + +tunnel_prometheus: + $(eval PROMETHEUS_PORT := $(shell terraform -chdir=$(APPLICATION_PATH) output -raw prometheus_port)) + @echo "Prometheus will be accessible at http://localhost:$(PROMETHEUS_PORT)" + kubectl port-forward svc/prometheus $(PROMETHEUS_PORT):$(PROMETHEUS_PORT) + + +config: + kubectl apply -f seed_node_config.yaml + +clean: + terraform -chdir="$(APPLICATION_PATH)" destroy -auto-approve + terraform -chdir="$(INFRA_PATH)" destroy -auto-approve + rm -rf $(INFRA_PATH)/.terraform $(INFRA_PATH)/terraform.tfstate $(INFRA_PATH)/terraform.tfstate.backup + rm -rf $(APPLICATION_PATH)/.terraform $(APPLICATION_PATH)/terraform.tfstate $(APPLICATION_PATH)/terraform.tfstate.backup diff --git a/datastores/gossip_kv/deployment/aws/README.md b/datastores/gossip_kv/deployment/aws/README.md new file mode 100644 index 000000000000..7c821f0003a7 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/README.md @@ -0,0 +1,89 @@ +# AWS Deployment + +## Pre-requisites +- [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) +- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) +- [Docker](https://docs.docker.com/get-docker/) +- [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) +- [Make](https://www.gnu.org/software/make/) +- [k9s](https://k9scli.io/) + +### Mac Setup Using Homebrew +```shell +brew install terraform +brew install awscli +brew install docker +brew install kubernetes-cli +brew install k9s +``` + +## Initialize Setup +Initializes terraform providers required for local deployment. +```shell +make init +``` + +## Configure AWS Credentials +Make sure you have the AWS credentials configured. Subsequent terraform commands will use these credentials to create +the infrastructure. +```shell +aws configure +``` + +## Create Infrastructure +Creates a local kubernetes cluster using minikube. + +```shell +make infra +``` + +## Kubectl +To enable kubectl usage with the newly created AWS EKS cluster, use the following command. + +```shell +make kubectl_setup +``` + +## K9s +To monitor the cluster using k9s, use the following command. + +```shell +k9s +``` + +## Build & Upload Docker Image +Build and upload the docker image for the application, into ECR. +```shell +make upload_docker_images +``` + +## Create Application +```shell +make application +``` + +## Check if the application is running +```shell +kubectl get pods # All gossip-kv-* pods should show status as "Running" +```` + +## Access Grafana Dashboards +```shell +make tunnel_grafana +``` + +## Access Prometheus +```shell +make tunnel_prometheus +``` + +## Update seed node configuration +```shell +make config +``` + +## Clean +Destroys the AWS resources and cleans up terraform state. +```shell +make clean +``` \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/seed_node_config.yaml b/datastores/gossip_kv/deployment/aws/seed_node_config.yaml new file mode 100644 index 000000000000..bebeda8cb5e4 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/seed_node_config.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gossip-kv-dynamic-config +data: + dynamic.toml: | + [[seed_nodes]] + id = "gossip-kv-seed-nodes-0" + address = "gossip-kv-seed-nodes-0.gossip-kv-seed-nodes.default.svc.cluster.local:3000" + + [[seed_nodes]] + id = "gossip-kv-seed-nodes-1" + address = "gossip-kv-seed-nodes-1.gossip-kv-seed-nodes.default.svc.cluster.local:3000" + + [[seed_nodes]] + id = "gossip-kv-seed-nodes-2" + address = "gossip-kv-seed-nodes-2.gossip-kv-seed-nodes.default.svc.cluster.local:3000" \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/.gitignore b/datastores/gossip_kv/deployment/aws/terraform/.gitignore new file mode 100644 index 000000000000..e63962a88795 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/.gitignore @@ -0,0 +1,30 @@ +### TERRAFORM IGNORES ### +# Terraform Plugin and module directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +*.tfvars +*.tfvars.json + +# Ignore local override files +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Terraform CLI configuration files +.terraformrc +terraform.rc + +# Backup files created by Terraform during state edits +*.backup + +# Terraform plan files (these are generated and can be large) +*.tfplan diff --git a/datastores/gossip_kv/deployment/aws/terraform/application/.terraform.lock.hcl b/datastores/gossip_kv/deployment/aws/terraform/application/.terraform.lock.hcl new file mode 100644 index 000000000000..d3440c12f8c2 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/application/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.33.0" + constraints = ">= 2.32.0" + hashes = [ + "h1:HDyytvOlqNw5fJ0SB/nzgqCWniK4LAZNx23LaPavQq8=", + "zh:255b35790b706d405e987750190658dcaefb663741b96803a9529ba5d7435329", + "zh:362feba1aa820a8e02869ec71d1a08e87243dbce43671dc0995fa6c5a2fafa1d", + "zh:39332abcf75b5dd9c78c79c7c0c094f7d4ca908d1b76bbd2aae67e8e3516710c", + "zh:3e8e7f758bb09a9b5b613c8866e77541f8f00b521070cc86bc095ce61f010baf", + "zh:427883b889b9c36630c3eec4d5c07bc4ae12cc0d358fc17ea42a8049bf8d5275", + "zh:69bfc4ed067a5e4844db1a1809343652ff239aa0a8da089b1671524c44e8740a", + "zh:6b9f731062b945c5020e0930ed9a1b1b50afd2caf751f0e70a282d165c970979", + "zh:6faf9ec006af7ee7014a9c3251d65b701792abb823f149b0b7e4ac4433848201", + "zh:b706f76d695104a47682ee6ab842870f9c70a680f979fa9e7efe34278c0831bc", + "zh:b9bca48de2c92f57389ed58dd2fac564deaccd79a92cafd08edeed3ba6b91d4d", + "zh:bbd3336dbee5aed9880f98e36fb8340e0c6d8f0399a05787521af599ccb3dac4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/datastores/gossip_kv/deployment/aws/terraform/application/main.tf b/datastores/gossip_kv/deployment/aws/terraform/application/main.tf new file mode 100644 index 000000000000..b707edaa89c4 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/application/main.tf @@ -0,0 +1,447 @@ +terraform { + backend "local" { + path = "../state/application.tfstate" + } + + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.32.0" + } + } +} + +data "terraform_remote_state" "infra" { + backend = "local" + config = { + path = "../state/infra.tfstate" + } +} + + +provider "kubernetes" { + host = data.terraform_remote_state.infra.outputs.cluster_endpoint + cluster_ca_certificate = base64decode(data.terraform_remote_state.infra.outputs.cluster_certificate_authority_data) + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + args = [ + "eks", + "get-token", + "--cluster-name", + data.terraform_remote_state.infra.outputs.cluster_name, + ] + } +} + +resource "kubernetes_stateful_set" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + service_name = "gossip-kv-seed-nodes" + replicas = 1 + + selector { + match_labels = { + app = "gossip-kv-seed-nodes" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-seed-nodes" + } + annotations = { + "prometheus.io/scrape" : "true" + "prometheus.io/port" : var.pod_monitoring_port + } + } + + spec { + termination_grace_period_seconds = 5 + + container { + name = "gossip-kv-server" + image = "${data.terraform_remote_state.infra.outputs.repository_urls.gossip_kv_server}:latest" + image_pull_policy = "Always" + + env { + name = "RUST_LOG" + value = "trace" + } + + env { + name = "RUST_BACKTRACE" + value = "full" + } + + port { + container_port = 3001 + protocol = "UDP" + } + + port { + container_port = var.pod_monitoring_port + protocol = "TCP" + } + + volume_mount { + name = "gossip-kv-dynamic-config" + mount_path = "/config/dynamic" + } + } + + volume { + name = "gossip-kv-dynamic-config" + + config_map { + name = "gossip-kv-dynamic-config" + } + } + } + } + } +} + +resource "kubernetes_deployment" "gossip_kv_cli" { + metadata { + name = "gossip-kv-cli" + labels = { + app = "gossip-kv-cli" + } + } + + spec { + replicas = 1 + + selector { + match_labels = { + app = "gossip-kv-cli" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-cli" + } + } + + spec { + termination_grace_period_seconds = 5 + + container { + name = "gossip-kv-cli" + image = "${data.terraform_remote_state.infra.outputs.repository_urls.gossip_kv_cli}:latest" + image_pull_policy = "Always" + command = ["/bin/sh"] + args = ["-c", "while true; do sleep 3600; done"] + tty = true + + env { + name = "RUST_LOG" + value = "info" + } + } + } + } + } +} + +resource "kubernetes_service" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + cluster_ip = "None" + selector = { + app = "gossip-kv-seed-nodes" + } + + port { + port = 3001 + target_port = 3001 + protocol = "UDP" + } + } +} + +resource "kubernetes_config_map" "gossip_kv_dynamic_config" { + metadata { + name = "gossip-kv-dynamic-config" + } + + data = { + "dynamic.toml" = < repo} + repository_name = each.value + + repository_read_write_access_arns = [data.aws_caller_identity.current.arn] + repository_lifecycle_policy = jsonencode({ + rules = [ + { + rulePriority = 1, + description = "Keep last 30 images", + selection = { + tagStatus = "tagged", + tagPrefixList = ["v"], + countType = "imageCountMoreThan", + countNumber = 30 + }, + action = { + type = "expire" + } + } + ] + }) + + repository_image_tag_mutability = "MUTABLE" + tags = { + Terraform = "true" + Environment = "dev" + } +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/infra/outputs.tf b/datastores/gossip_kv/deployment/aws/terraform/infra/outputs.tf new file mode 100644 index 000000000000..f965d56a2157 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/infra/outputs.tf @@ -0,0 +1,28 @@ +output "cluster_endpoint" { + description = "Endpoint for EKS control plane" + value = module.eks_cluster.cluster_endpoint +} + +output "cluster_name" { + description = "Kubernetes Cluster Name" + value = module.eks_cluster.cluster_name +} + +output "vpc_id" { + value = module.vpc.vpc_id +} + +output "region" { + description = "AWS region" + value = var.region +} + +output "repository_urls" { + description = "URLs of all ECR repositories created" + value = { for repo, details in module.ecr : repo => details.repository_url } +} + +output "cluster_certificate_authority_data" { + description = "Base64 encoded PEM certificate data for the cluster" + value = module.eks_cluster.cluster_certificate_authority_data +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/infra/variables.tf b/datastores/gossip_kv/deployment/aws/terraform/infra/variables.tf new file mode 100644 index 000000000000..7522b20fcc27 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/infra/variables.tf @@ -0,0 +1,17 @@ +variable "region" { + description = "AWS region" + type = string + default = "us-east-2" +} + +variable "instance_type" { + description = "Instance type for the EKS nodes" + type = string + default = "t3.small" +} + +variable "ecr_repositories" { + description = "List of ECR repository names" + type = list(string) + default = ["gossip_kv_server", "gossip_kv_cli", "gossip_kv_load_test"] +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/main.tf b/datastores/gossip_kv/deployment/aws/terraform/main.tf new file mode 100644 index 000000000000..47799f259c45 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/main.tf @@ -0,0 +1,561 @@ +provider "aws" { + region = var.region +} + +# Filter out local zones, which are not currently supported +# with managed node groups +data "aws_availability_zones" "available" { + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +data "aws_caller_identity" "current" {} + +locals { + cluster_name = "anna-load-test-${random_string.suffix.result}" + account_id = data.aws_caller_identity.current.account_id +} + +resource "random_string" "suffix" { + length = 8 + special = false +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "5.8.1" + + name = "anna-load-test-vpc" + + cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + map_public_ip_on_launch = true + public_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + + enable_dns_hostnames = true + + public_subnet_tags = { + "kubernetes.io/role/elb" = 1 + } +} + +module "eks_cluster" { + source = "terraform-aws-modules/eks/aws" + version = "20.24.3" + + cluster_name = local.cluster_name + cluster_version = "1.31" + + cluster_endpoint_public_access = true + enable_cluster_creator_admin_permissions = true + + cluster_addons = { + aws-ebs-csi-driver = { + service_account_role_arn = module.irsa-ebs-csi.iam_role_arn + } + } + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.public_subnets + + eks_managed_node_group_defaults = { + ami_type = "AL2_x86_64" + } + + eks_managed_node_groups = { + one = { + name = "servers" + + instance_types = [var.instance_type] + + min_size = 1 + max_size = 3 + desired_size = 2 + } + } +} + +# https://aws.amazon.com/blogs/containers/amazon-ebs-csi-driver-is-now-generally-available-in-amazon-eks-add-ons/ +data "aws_iam_policy" "ebs_csi_policy" { + arn = "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy" +} + +module "irsa-ebs-csi" { + source = "terraform-aws-modules/iam/aws//modules/iam-assumable-role-with-oidc" + version = "5.39.0" + + create_role = true + role_name = "AmazonEKSTFEBSCSIRole-${module.eks_cluster.cluster_name}" + provider_url = module.eks_cluster.oidc_provider + role_policy_arns = [data.aws_iam_policy.ebs_csi_policy.arn] + oidc_fully_qualified_subjects = ["system:serviceaccount:kube-system:ebs-csi-controller-sa"] +} + +variable "ecr_repositories" { + description = "List of ECR repository names" + type = list(string) + default = ["gossip_kv_server", "gossip_kv_cli", "gossip_kv_load_test"] +} + +module "ecr" { + source = "terraform-aws-modules/ecr/aws" + version = "2.3.0" + + for_each = {for repo in var.ecr_repositories : repo => repo} + repository_name = each.value + + repository_read_write_access_arns = [data.aws_caller_identity.current.arn] + repository_lifecycle_policy = jsonencode({ + rules = [ + { + rulePriority = 1, + description = "Keep last 30 images", + selection = { + tagStatus = "tagged", + tagPrefixList = ["v"], + countType = "imageCountMoreThan", + countNumber = 30 + }, + action = { + type = "expire" + } + } + ] + }) + + repository_image_tag_mutability = "MUTABLE" + tags = { + Terraform = "true" + Environment = "dev" + } +} + +provider "kubernetes" { + host = module.eks_cluster.cluster_endpoint + cluster_ca_certificate = base64decode(module.eks_cluster.cluster_certificate_authority_data) + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + args = [ + "eks", + "get-token", + "--cluster-name", + module.eks_cluster.cluster_name, + ] + } +} + +resource "kubernetes_stateful_set" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + service_name = "gossip-kv-seed-nodes" + replicas = 1 + + selector { + match_labels = { + app = "gossip-kv-seed-nodes" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-seed-nodes" + } + annotations = { + "prometheus.io/scrape" : "true" + "prometheus.io/port" : var.pod_monitoring_port + } + } + + spec { + termination_grace_period_seconds = 5 + + container { + name = "gossip-kv-server" + image = "${module.ecr.gossip_kv_load_test.repository_url}:latest" + image_pull_policy = "Always" + + env { + name = "RUST_LOG" + value = "trace" + } + + env { + name = "RUST_BACKTRACE" + value = "full" + } + + port { + container_port = 3001 + protocol = "UDP" + } + + port { + container_port = var.pod_monitoring_port + protocol = "TCP" + } + + volume_mount { + name = "gossip-kv-dynamic-config" + mount_path = "/config/dynamic" + } + } + + volume { + name = "gossip-kv-dynamic-config" + + config_map { + name = "gossip-kv-dynamic-config" + } + } + } + } + } +} + +resource "kubernetes_deployment" "gossip_kv_cli" { + metadata { + name = "gossip-kv-cli" + labels = { + app = "gossip-kv-cli" + } + } + + spec { + replicas = 1 + + selector { + match_labels = { + app = "gossip-kv-cli" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-cli" + } + } + + spec { + termination_grace_period_seconds = 5 + + container { + name = "gossip-kv-cli" + image = "${module.ecr.gossip_kv_cli.repository_url}:latest" + image_pull_policy = "Always" + command = ["/bin/sh"] + args = ["-c", "while true; do sleep 3600; done"] + tty = true + + env { + name = "RUST_LOG" + value = "info" + } + } + } + } + } +} + +resource "kubernetes_service" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + cluster_ip = "None" + selector = { + app = "gossip-kv-seed-nodes" + } + + port { + port = 3001 + target_port = 3001 + protocol = "UDP" + } + } +} + +resource "kubernetes_config_map" "gossip_kv_dynamic_config" { + metadata { + name = "gossip-kv-dynamic-config" + } + + data = { + "dynamic.toml" = < details.repository_url } +} + +output "grafana_port" { + description = "Port for Grafana UI" + value = var.grafana_port +} + +output "prometheus_port" { + description = "Port for Prometheus UI" + value = var.prometheus_port +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/terraform.tf b/datastores/gossip_kv/deployment/aws/terraform/terraform.tf new file mode 100644 index 000000000000..6b54c550a221 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/terraform.tf @@ -0,0 +1,30 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.70.0" + } + + random = { + source = "hashicorp/random" + version = "~> 3.6.1" + } + + tls = { + source = "hashicorp/tls" + version = "~> 4.0.5" + } + + cloudinit = { + source = "hashicorp/cloudinit" + version = "~> 2.3.4" + } + + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.32.0" + } + } + + required_version = "~> 1.3" +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/aws/terraform/variables.tf b/datastores/gossip_kv/deployment/aws/terraform/variables.tf new file mode 100644 index 000000000000..fb8ff7995be5 --- /dev/null +++ b/datastores/gossip_kv/deployment/aws/terraform/variables.tf @@ -0,0 +1,29 @@ +variable "region" { + description = "AWS region where the resources will be created" + type = string + default = "us-east-2" +} + +variable "instance_type" { + description = "Instance type for the EC2 instances" + type = string + default = "t3.small" +} + +variable "grafana_port" { + description = "Port for Grafana UI" + type = number + default = 4001 +} + +variable "prometheus_port" { + description = "Port for Prometheus UI" + type = number + default = 4002 +} + +variable "pod_monitoring_port" { + description = "Port for monitoring pods using prometheus. Every pod runs a prometheus exporter on this port." + type = number + default = 4003 +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/local/Makefile b/datastores/gossip_kv/deployment/local/Makefile new file mode 100644 index 000000000000..ee030a22207a --- /dev/null +++ b/datastores/gossip_kv/deployment/local/Makefile @@ -0,0 +1,46 @@ + +INFRA_PATH=./terraform/infra +APPLICATION_PATH=./terraform/application + +BASE_IMAGE_VERSION:=latest +SERVER_IMAGE_VERSION:=latest +CLI_IMAGE_VERSION:=latest +LOAD_TEST_IMAGE_VERSION:=latest + +# Docker Image Tags +BASE_IMAGE_TAG:=hydroflow-gossip-kv-base-image:$(BASE_IMAGE_VERSION) +SERVER_IMAGE_TAG:=hydroflow-gossip-kv-server:$(SERVER_IMAGE_VERSION) +CLI_IMAGE_TAG:=hydroflow-gossip-kv-cli:$(CLI_IMAGE_VERSION) +LOAD_TEST_IMAGE_TAG:=hydroflow-gossip-kv-load-test:$(LOAD_TEST_IMAGE_VERSION) + +.PHONY : init infra docker_images base_image server_image cli_image application config clean + +init: + terraform -chdir="$(INFRA_PATH)" init + terraform -chdir="$(APPLICATION_PATH)" init + +infra: + terraform -chdir="$(INFRA_PATH)" apply -auto-approve + +docker_images: base_image server_image cli_image + +base_image: + docker build -t "$(BASE_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/server/baseimage.Dockerfile ../../../.. + +server_image: + docker build -t "$(SERVER_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/server/Dockerfile ../../../.. + +cli_image: + docker build -t "$(CLI_IMAGE_TAG)" -f ../../../../datastores/gossip_kv/cli/Dockerfile ../../../.. + +application: + terraform -chdir="$(APPLICATION_PATH)" apply -auto-approve + +config: + kubectl apply -f seed_node_config.yaml + +clean: + terraform -chdir="$(APPLICATION_PATH)" destroy -auto-approve + terraform -chdir="$(INFRA_PATH)" destroy -auto-approve + rm -rf $(INFRA_PATH)/.terraform $(INFRA_PATH)/terraform.tfstate $(INFRA_PATH)/terraform.tfstate.backup + rm -rf $(APPLICATION_PATH)/.terraform $(APPLICATION_PATH)/terraform.tfstate $(APPLICATION_PATH)/terraform.tfstate.backup diff --git a/datastores/gossip_kv/deployment/local/README.md b/datastores/gossip_kv/deployment/local/README.md new file mode 100644 index 000000000000..e45c622f9280 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/README.md @@ -0,0 +1,109 @@ +# Local (Minikube) Deployment + +## Pre-requisites +- [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli) +- [Minikube](https://minikube.sigs.k8s.io/docs/start/) +- [Docker](https://docs.docker.com/get-docker/) +- [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) +- [Make](https://www.gnu.org/software/make/) +- [k9s](https://k9scli.io/) + +### Mac Setup Using Homebrew +```shell +brew install terraform +brew install minikube +brew install docker +brew install kubernetes-cli +brew install k9s +``` + +## Initialize Setup +Initializes terraform providers required for local deployment. +```shell +make init +``` + +## Create Infrastructure +Creates a local kubernetes cluster using minikube. + +```shell +make infra +``` +### List Minikube Profiles +The `make infra` command creates minikube profile 'terraform-provider-minikube'. The details of the profile can be +listed using the following command. +```shell +minikube profile list +``` +Other minikube commands can be specified using the profile name as shown below. +```shell +minikube --profile=terraform-provider-minikube +``` + +### Kubectl +The kubectl context is set to the minikube profile 'terraform-provider-minikube' by default. + +To switch back to the 'terraform-provider-minikube' context at anytime, use the following command. +```shell +kubectl config use-context terraform-provider-minikube +``` + +### K9s +To monitor the cluster using k9s, use the following command. + +```shell +k9s +``` + +If the current context is not set to `terraform-provider-minikube`, use the following command. +```shell +k9s --context terraform-provider-minikube +``` + +### Build Docker Image +Setup the docker environment to use the minikube docker registry. +```shell +eval $(minikube -p terraform-provider-minikube docker-env) +``` + +Build the docker image for the application, into the local minikube docker registry. +```shell +make docker_images +``` +You can view the docker images in the minikube registry using the following command. +```shell +docker images +``` + +If docker isn't pointing to the minikube registry, use the following command. +```shell +minikube -p terraform-provider-minikube ssh docker images +``` + +## Create Application +```shell +make application +``` + +### Check if the application is running +```shell +kubectl get pods # All gossip-kv-* pods should show status as "Running" +```` + +### Update seed node configuration +```shell +make config +``` + +## Clean + +Destroys the mini-kube cluster and removes the terraform state files. + +```shell +make clean +``` + +If terraform is an inconsistent state, use the following command to blow away the minikube cluster and start fresh. +```shell +minikube delete -p terraform-provider-minikube +``` \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/local/seed_node_config.yaml b/datastores/gossip_kv/deployment/local/seed_node_config.yaml new file mode 100644 index 000000000000..bebeda8cb5e4 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/seed_node_config.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: gossip-kv-dynamic-config +data: + dynamic.toml: | + [[seed_nodes]] + id = "gossip-kv-seed-nodes-0" + address = "gossip-kv-seed-nodes-0.gossip-kv-seed-nodes.default.svc.cluster.local:3000" + + [[seed_nodes]] + id = "gossip-kv-seed-nodes-1" + address = "gossip-kv-seed-nodes-1.gossip-kv-seed-nodes.default.svc.cluster.local:3000" + + [[seed_nodes]] + id = "gossip-kv-seed-nodes-2" + address = "gossip-kv-seed-nodes-2.gossip-kv-seed-nodes.default.svc.cluster.local:3000" \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/local/terraform/.gitignore b/datastores/gossip_kv/deployment/local/terraform/.gitignore new file mode 100644 index 000000000000..e63962a88795 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/.gitignore @@ -0,0 +1,30 @@ +### TERRAFORM IGNORES ### +# Terraform Plugin and module directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +*.tfvars +*.tfvars.json + +# Ignore local override files +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Terraform CLI configuration files +.terraformrc +terraform.rc + +# Backup files created by Terraform during state edits +*.backup + +# Terraform plan files (these are generated and can be large) +*.tfplan diff --git a/datastores/gossip_kv/deployment/local/terraform/application/.terraform.lock.hcl b/datastores/gossip_kv/deployment/local/terraform/application/.terraform.lock.hcl new file mode 100644 index 000000000000..0bc31d25bae2 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/application/.terraform.lock.hcl @@ -0,0 +1,21 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.33.0" + hashes = [ + "h1:HDyytvOlqNw5fJ0SB/nzgqCWniK4LAZNx23LaPavQq8=", + "zh:255b35790b706d405e987750190658dcaefb663741b96803a9529ba5d7435329", + "zh:362feba1aa820a8e02869ec71d1a08e87243dbce43671dc0995fa6c5a2fafa1d", + "zh:39332abcf75b5dd9c78c79c7c0c094f7d4ca908d1b76bbd2aae67e8e3516710c", + "zh:3e8e7f758bb09a9b5b613c8866e77541f8f00b521070cc86bc095ce61f010baf", + "zh:427883b889b9c36630c3eec4d5c07bc4ae12cc0d358fc17ea42a8049bf8d5275", + "zh:69bfc4ed067a5e4844db1a1809343652ff239aa0a8da089b1671524c44e8740a", + "zh:6b9f731062b945c5020e0930ed9a1b1b50afd2caf751f0e70a282d165c970979", + "zh:6faf9ec006af7ee7014a9c3251d65b701792abb823f149b0b7e4ac4433848201", + "zh:b706f76d695104a47682ee6ab842870f9c70a680f979fa9e7efe34278c0831bc", + "zh:b9bca48de2c92f57389ed58dd2fac564deaccd79a92cafd08edeed3ba6b91d4d", + "zh:bbd3336dbee5aed9880f98e36fb8340e0c6d8f0399a05787521af599ccb3dac4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/datastores/gossip_kv/deployment/local/terraform/application/main.tf b/datastores/gossip_kv/deployment/local/terraform/application/main.tf new file mode 100644 index 000000000000..c9e439b31ea0 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/application/main.tf @@ -0,0 +1,153 @@ +terraform { + backend "local" { + path = "../state/application.tfstate" + } +} + +data "terraform_remote_state" "infra" { + backend = "local" + config = { + path = "../state/infra.tfstate" + } +} + +provider "kubernetes" { + host = data.terraform_remote_state.infra.outputs.kubernetes_host + client_certificate = data.terraform_remote_state.infra.outputs.kubernetes_client_certificate + client_key = data.terraform_remote_state.infra.outputs.kubernetes_client_key + cluster_ca_certificate = data.terraform_remote_state.infra.outputs.kubernetes_cluster_ca_certificate +} + +resource "kubernetes_stateful_set" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + replicas = 3 + service_name = "gossip-kv-seed-nodes" + + selector { + match_labels = { + app = "gossip-kv-seed-nodes" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-seed-nodes" + } + } + spec { + termination_grace_period_seconds = 5 # Allows for quick restarts. Not recommended for production. + + container { + name = "gossip-kv-server" + image = "docker.io/hydroflow-gossip-kv-server:latest" + image_pull_policy = "IfNotPresent" + env { + name = "RUST_LOG" + value = "trace" + } + env { + name = "RUST_BACKTRACE" + value = "full" + } + port { + container_port = 3001 + protocol = "UDP" + } + volume_mount { + name = "gossip-kv-dynamic-config" + mount_path = "/config/dynamic" + } + } + + volume { + name = "gossip-kv-dynamic-config" + config_map { + name = "gossip-kv-dynamic-config" + } + } + } + } + } +} + +resource "kubernetes_deployment" "gossip_kv_cli" { + metadata { + name = "gossip-kv-cli" + labels = { + app = "gossip-kv-cli" + } + } + + spec { + replicas = 1 + + selector { + match_labels = { + app = "gossip-kv-cli" + } + } + + template { + metadata { + labels = { + app = "gossip-kv-cli" + } + } + spec { + termination_grace_period_seconds = 5 + container { + name = "gossip-kv-cli" + image = "docker.io/hydroflow-gossip-kv-cli:latest" + image_pull_policy = "IfNotPresent" + command = ["/bin/sh"] + args = ["-c", "while true; do sleep 3600; done"] + tty = true + env { + name = "RUST_LOG" + value = "info" + } + } + } + } + } +} + +resource "kubernetes_service" "gossip_kv_seed_nodes" { + metadata { + name = "gossip-kv-seed-nodes" + labels = { + app = "gossip-kv-seed-nodes" + } + } + + spec { + port { + port = 3001 + target_port = 3001 + protocol = "UDP" + } + cluster_ip = "None" + selector = { + app = "gossip-kv-seed-nodes" + } + } +} + + +resource "kubernetes_config_map" "gossip_kv_dynamic_config" { + metadata { + name = "gossip-kv-dynamic-config" + } + + data = { + "dynamic.toml" = "" + } +} \ No newline at end of file diff --git a/datastores/gossip_kv/deployment/local/terraform/infra/.terraform.lock.hcl b/datastores/gossip_kv/deployment/local/terraform/infra/.terraform.lock.hcl new file mode 100644 index 000000000000..fc26421f157d --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/infra/.terraform.lock.hcl @@ -0,0 +1,40 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.33.0" + hashes = [ + "h1:HDyytvOlqNw5fJ0SB/nzgqCWniK4LAZNx23LaPavQq8=", + "zh:255b35790b706d405e987750190658dcaefb663741b96803a9529ba5d7435329", + "zh:362feba1aa820a8e02869ec71d1a08e87243dbce43671dc0995fa6c5a2fafa1d", + "zh:39332abcf75b5dd9c78c79c7c0c094f7d4ca908d1b76bbd2aae67e8e3516710c", + "zh:3e8e7f758bb09a9b5b613c8866e77541f8f00b521070cc86bc095ce61f010baf", + "zh:427883b889b9c36630c3eec4d5c07bc4ae12cc0d358fc17ea42a8049bf8d5275", + "zh:69bfc4ed067a5e4844db1a1809343652ff239aa0a8da089b1671524c44e8740a", + "zh:6b9f731062b945c5020e0930ed9a1b1b50afd2caf751f0e70a282d165c970979", + "zh:6faf9ec006af7ee7014a9c3251d65b701792abb823f149b0b7e4ac4433848201", + "zh:b706f76d695104a47682ee6ab842870f9c70a680f979fa9e7efe34278c0831bc", + "zh:b9bca48de2c92f57389ed58dd2fac564deaccd79a92cafd08edeed3ba6b91d4d", + "zh:bbd3336dbee5aed9880f98e36fb8340e0c6d8f0399a05787521af599ccb3dac4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/scott-the-programmer/minikube" { + version = "0.4.2" + constraints = "0.4.2" + hashes = [ + "h1:kUXMe9QKg/SS9WI36FRVK31z3gj59DaljIJKO0cHH68=", + "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", + "zh:74f33b5a5ca42defdf44a2e6c4e08336a353c514f6c37f2ff41b5471324f5b03", + "zh:7f2fa2bcc6bde40098647fb171c0fd952a4d9146ab3df113f16b50565359b4fb", + "zh:88e01b8a9615d2c9ee8b0b34398ed5b00617ba4581edb2ca50a18608a9642072", + "zh:89384deab32270c985f8d0f0e762b483ec37339900ef600156b89ea10f45c77b", + "zh:9164e86a0200cf2189ed939a554d1156a1acff67c3f79dfc296d1b9226d1e814", + "zh:ab0cb857884de38dcce31b66b112f5a886ef5a85abbaa6e96af3c23f312947af", + "zh:bd4fd61701bbc4b6ede08612c7e944813e0948887d666fa0ff64186e97e93c22", + "zh:cf48a09a4c92d77f373ea359415087891788ed11a2537000c79600c05524bd26", + "zh:fedc68ccc3f1b1447f9ed97e486f30ed526f9e098854dc18f9fc9b26f2f5ec43", + "zh:ff97171d251fb6658c729676c62b2315bcc3b056115992dbb19737e6ba550f0d", + ] +} diff --git a/datastores/gossip_kv/deployment/local/terraform/infra/main.tf b/datastores/gossip_kv/deployment/local/terraform/infra/main.tf new file mode 100644 index 000000000000..5262f27c06f7 --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/infra/main.tf @@ -0,0 +1,26 @@ +terraform { + backend "local" { + path = "../state/infra.tfstate" + } + + required_providers { + minikube = { + source = "scott-the-programmer/minikube" + version = "0.4.2" + } + } +} + +resource "minikube_cluster" "gossip_kv" { + driver = "docker" + cpus = 16 + memory = 32768 + disk_size = "100g" +} + +provider "kubernetes" { + host = minikube_cluster.gossip_kv.host + client_certificate = minikube_cluster.gossip_kv.client_certificate + client_key = minikube_cluster.gossip_kv.client_key + cluster_ca_certificate = minikube_cluster.gossip_kv.cluster_ca_certificate +} diff --git a/datastores/gossip_kv/deployment/local/terraform/infra/outputs.tf b/datastores/gossip_kv/deployment/local/terraform/infra/outputs.tf new file mode 100644 index 000000000000..07550ca955eb --- /dev/null +++ b/datastores/gossip_kv/deployment/local/terraform/infra/outputs.tf @@ -0,0 +1,18 @@ +output "kubernetes_host" { + value = minikube_cluster.gossip_kv.host +} + +output "kubernetes_client_certificate" { + value = minikube_cluster.gossip_kv.client_certificate + sensitive = true +} + +output "kubernetes_client_key" { + value = minikube_cluster.gossip_kv.client_key + sensitive = true +} + +output "kubernetes_cluster_ca_certificate" { + value = minikube_cluster.gossip_kv.cluster_ca_certificate + sensitive = true +} \ No newline at end of file diff --git a/datastores/gossip_kv/kv/lattices/mod.rs b/datastores/gossip_kv/kv/lattices/mod.rs new file mode 100644 index 000000000000..1aa5883b4bda --- /dev/null +++ b/datastores/gossip_kv/kv/lattices/mod.rs @@ -0,0 +1,248 @@ +use std::cmp::Ordering; +use std::collections::HashSet; +use std::hash::Hash; + +use hydroflow::lattices::{IsBot, IsTop, LatticeFrom, LatticeOrd, Merge}; +use serde::{Deserialize, Serialize}; + +/// A bounded set union lattice with a fixed size N. +/// +/// Once the set reaches size N, it becomes top. The items in the set are no longer tracked to +/// reclaim associated memory. +#[derive(Debug, Clone, Eq, Serialize, Deserialize)] + +pub struct BoundedSetLattice +where + T: Eq + Hash, +{ + // The set of items in the lattice with invariant: + // is_top => items.is_empty() ... i.e. the items are dropped when the lattice reaches top. + items: HashSet, + is_top: bool, +} + +impl LatticeFrom> for BoundedSetLattice +where + T: Eq + Hash, +{ + fn lattice_from(other: BoundedSetLattice) -> Self { + other + } +} + +impl Default for BoundedSetLattice +where + T: Eq + Hash, +{ + fn default() -> Self { + Self { + items: HashSet::new(), + is_top: N == 0, // This lattice is effectively a unit lattice `()`, if N == 0 + } + } +} + +impl From<()> for BoundedSetLattice +where + T: Eq + Hash, +{ + fn from(_: ()) -> Self { + Default::default() + } +} + +impl From> for () +where + T: Eq + Hash, +{ + fn from(_: BoundedSetLattice) -> Self {} +} + +impl BoundedSetLattice +where + T: Eq + Hash, +{ + pub fn new() -> Self { + Default::default() + } + + pub fn new_from(items: U) -> Self + where + U: IntoIterator, + { + let mut lattice = Self::new(); + lattice.merge(items); + lattice + } +} + +impl IsBot for BoundedSetLattice +where + T: Eq + Hash, +{ + fn is_bot(&self) -> bool { + match N { + 0 => true, + _ => self.items.is_empty() && !self.is_top, + } + } +} + +impl IsTop for BoundedSetLattice +where + T: Eq + Hash, +{ + fn is_top(&self) -> bool { + self.is_top + } +} + +impl Merge for BoundedSetLattice +where + U: IntoIterator, + T: Eq + Hash, +{ + fn merge(&mut self, other: U) -> bool { + if self.is_top { + return false; + } + + let old_len = self.items.len(); + self.items.extend(other); + let new_len = self.items.len(); + + if new_len >= N { + self.is_top = true; + self.items.clear(); + } + + new_len != old_len + } +} + +impl PartialOrd for BoundedSetLattice +where + T: Eq + Hash, +{ + fn partial_cmp(&self, other: &Self) -> Option { + match (self.is_top, other.is_top) { + (true, true) => Some(Ordering::Equal), + (true, false) => Some(Ordering::Greater), + (false, true) => Some(Ordering::Less), + (false, false) => match self.items.len().cmp(&other.items.len()) { + Ordering::Greater => { + if other.items.iter().all(|key| self.items.contains(key)) { + Some(Ordering::Greater) + } else { + None + } + } + Ordering::Less => { + if self.items.iter().all(|key| other.items.contains(key)) { + Some(Ordering::Less) + } else { + None + } + } + Ordering::Equal => { + if self.items.iter().all(|key| other.items.contains(key)) { + Some(Ordering::Equal) + } else { + None + } + } + }, + } + } +} + +impl PartialEq for BoundedSetLattice +where + T: Eq + Hash, +{ + fn eq(&self, other: &Self) -> bool { + match (self.is_top, other.is_top) { + (true, true) => true, + (true, false) => false, + (false, true) => false, + (false, false) => self.items == other.items, + } + } +} + +impl LatticeOrd for BoundedSetLattice where T: Eq + Hash {} + +impl Merge> for BoundedSetLattice +where + T: Eq + Hash, +{ + fn merge(&mut self, other: BoundedSetLattice) -> bool { + match (self.is_top, other.is_top) { + (true, _) => false, + (false, true) => { + self.is_top = true; + self.items.clear(); + true + } + (false, false) => self.merge(other.items), + } + } +} + +#[cfg(test)] +mod tests { + use hydroflow::lattices::test::check_all; + + use super::*; + + #[test] + fn test_0_bounded_set_lattice() { + let mut lat: BoundedSetLattice = ().into(); + assert!(lat.is_bot() && lat.is_top()); + + // Merges should always return false. + assert!(!lat.merge([1])); + + // No changes to top/bot status. + assert!(lat.is_bot() && lat.is_top()); + } + + #[test] + fn test_1_bounded_set_lattice() { + // The bounded lattice with N = 1 is effectively a WithBottom lattice. + let mut lat = BoundedSetLattice::::new(); + assert!(lat.is_bot() && !lat.is_top()); + assert!(lat.items.is_empty()); + + assert!(lat.merge([1])); + assert!(!lat.is_bot() && lat.is_top()); + assert!(lat.items.is_empty()); // Check that the items were dropped. + + assert!(!lat.merge([2])); + } + + #[test] + fn test_2_bounded_set_lattice() { + let mut a = BoundedSetLattice::::new(); + let b: BoundedSetLattice = BoundedSetLattice::new_from([1, 2]); + + assert!(a.is_bot() && !a.is_top()); + assert!(!b.is_bot() && b.is_top()); + + assert!(a.merge(b)); + assert!(!a.is_bot() && a.is_top()); + + assert!(!a.merge([3])); + } + + #[test] + fn test_lattice_properties() { + check_all(&[ + Default::default(), + BoundedSetLattice::::new_from([1]), + BoundedSetLattice::::new_from([1, 2]), + BoundedSetLattice::::new_from([1, 2, 3]), + BoundedSetLattice::::new_from([1, 2, 3, 4]), + ]); + } +} diff --git a/datastores/gossip_kv/kv/lib.rs b/datastores/gossip_kv/kv/lib.rs new file mode 100644 index 000000000000..15badc703be3 --- /dev/null +++ b/datastores/gossip_kv/kv/lib.rs @@ -0,0 +1,273 @@ +pub mod membership; +pub mod model; + +pub mod server; + +pub mod lattices; + +pub mod util; + +use std::collections::HashSet; +use std::fmt::Display; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; + +use crate::model::{Clock, Namespaces}; +use crate::KeyParseError::InvalidNamespace; + +/// The namespace of the key of an entry in the key-value store. +#[derive(Debug, Eq, PartialEq, Clone, Copy, Serialize, Deserialize, Hash)] +pub enum Namespace { + /// User namespace is for use by the user of the key-value store. + User, + + /// System namespace is reserved for use by the key-value store itself. + System, +} + +/// Error that can occur when parsing a key from a string. +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +pub enum KeyParseError { + /// The namespace in the key is invalid. Namespaces must be either `usr` or `sys`. + InvalidNamespace, + + /// The key is in an invalid format. Keys must be of the form `/namespace/table/row`. + InvalidFormat, +} + +impl Display for KeyParseError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + InvalidNamespace => write!(f, "Invalid namespace"), + KeyParseError::InvalidFormat => write!(f, "Invalid key format"), + } + } +} + +impl FromStr for Namespace { + type Err = KeyParseError; + fn from_str(s: &str) -> Result { + match s { + "usr" => Ok(Namespace::User), + "sys" => Ok(Namespace::System), + _ => Err(InvalidNamespace), + } + } +} + +/// The name of a table in the key-value store. +pub type TableName = String; + +/// The key of a row in a table in the key-value store. +pub type RowKey = String; + +/// A key of an entry in the key-value store. +/// +/// Data in the key-value store is organized into namespaces, tables, and rows. Namespaces are +/// either `usr` for user data or `sys` for system data. Namespaces contain tables, which contain +/// rows. Each row has a row key and a row value. +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Hash)] +pub struct Key { + /// The namespace of the key. + pub namespace: Namespace, + /// The name of the table in the key. + pub table: TableName, + /// The key of the row in the table. + pub row_key: RowKey, +} + +impl FromStr for Key { + type Err = KeyParseError; + fn from_str(s: &str) -> Result { + let mut parts: Vec = vec![]; + let mut current_part = String::new(); + let mut escaping = false; + + for c in s.chars() { + match (escaping, c) { + (true, '\\') | (true, '/') => { + current_part.push(c); + escaping = false; + } + (true, _) => return Err(KeyParseError::InvalidFormat), + (false, '\\') => { + escaping = true; + } + (false, '/') => { + parts.push(current_part); + current_part = String::new(); + } + (false, _) => { + current_part.push(c); + } + } + } + + if escaping { + return Err(KeyParseError::InvalidFormat); + } + + if !current_part.is_empty() { + parts.push(current_part); + } + + if parts.len() != 4 { + return Err(KeyParseError::InvalidFormat); + } + + if !parts[0].is_empty() { + return Err(KeyParseError::InvalidFormat); + } + + if parts[2].is_empty() || parts[3].is_empty() { + return Err(KeyParseError::InvalidFormat); + } + + let namespace = parts[1].parse()?; + Ok(Key { + namespace, + table: parts[2].to_string(), + row_key: parts[3].to_string(), + }) + } +} + +/// A request from a client to the key-value store. +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub enum ClientRequest { + /// A request to get the value of a key. + Get { key: Key }, + /// A request to set the value of a key. + Set { key: Key, value: String }, + /// A request to delete the value of a key. + Delete { key: Key }, +} + +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub enum ClientResponse { + /// A response for a get request. The key is echoed back along with the value, if it exists. + /// Multiple values are returned if there were concurrent writes to the key. + Get { key: Key, value: HashSet }, + /// A response for a set request. The success field is true if the set was successful. + Set { success: bool }, + /// A response for a delete request. The success field is true if delete was successful. + Delete { success: bool }, +} + +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub enum GossipMessage { + /// An "infecting message" to share updates with a peer. + Gossip { + message_id: String, + member_id: String, + writes: Namespaces, + }, + /// An acknowledgement message sent by a peer in response to a Gossip message, to indicate + /// that it hasn't seen some of the writes in the Gossip message before. + Ack { + message_id: String, + member_id: String, + }, + /// A negative acknowledgement sent by a peer in response to a Gossip message, to indicate + /// that it has seen all of the writes in the Gossip message before. + Nack { + message_id: String, + member_id: String, + }, +} + +#[cfg(test)] +mod tests { + use super::{Key, Namespace}; + + #[test] + fn test_key_parsing_sys_namespace() { + // Sys namespace + let first = "/sys/sys_table/sys_row".parse::().unwrap(); + assert_eq!(first.namespace, Namespace::System); + assert_eq!(first.table, "sys_table"); + assert_eq!(first.row_key, "sys_row"); + } + #[test] + fn test_key_parsing_user_namespace() { + // User namespace + let second = "/usr/usr_table/usr_row".parse::().unwrap(); + assert_eq!(second.namespace, Namespace::User); + assert_eq!(second.table, "usr_table"); + assert_eq!(second.row_key, "usr_row"); + } + + #[test] + fn test_key_empty_table() { + // Empty table + let empty_table = "/usr//usr_row".parse::(); + assert!(empty_table.is_err()); + assert_eq!( + empty_table.unwrap_err(), + super::KeyParseError::InvalidFormat + ); + } + + #[test] + fn test_key_empty_row() { + // Empty row + let empty_row = "/usr/usr_table/".parse::(); + assert!(empty_row.is_err()); + assert_eq!(empty_row.unwrap_err(), super::KeyParseError::InvalidFormat); + } + + #[test] + fn test_key_parsing_invalid_namespace() { + // Invalid namespace + let non_existent_namespace = "/ne_namespace/ne_table/ne_row".parse::(); + assert!(non_existent_namespace.is_err()); + assert_eq!( + non_existent_namespace.unwrap_err(), + super::KeyParseError::InvalidNamespace + ); + } + + #[test] + fn test_key_parsing_invalid_format() { + // Invalid format + let invalid_format = "/not_even_a_key".parse::(); + assert!(invalid_format.is_err()); + assert_eq!( + invalid_format.unwrap_err(), + super::KeyParseError::InvalidFormat + ); + + let invalid_format = "abcd/sys/sys_table/sys_row".parse::(); + assert!(invalid_format.is_err()); + assert_eq!( + invalid_format.unwrap_err(), + super::KeyParseError::InvalidFormat + ); + } + + #[test] + fn test_key_parsing_escaping() { + // Escape \ + let key = r"/usr/usr\/table/usr\/row".parse::().unwrap(); + assert_eq!(key.namespace, Namespace::User); + assert_eq!(key.table, r"usr/table"); + assert_eq!(key.row_key, r"usr/row"); + + // Escaping / + let key = r"/usr/usr\\table/usr\\row".parse::().unwrap(); + assert_eq!(key.namespace, Namespace::User); + assert_eq!(key.table, r"usr\table"); + assert_eq!(key.row_key, r"usr\row"); + + // Escaping any character + let key = r"/usr/usr\table/usr\row".parse::(); + assert!(key.is_err()); + assert_eq!(key.unwrap_err(), super::KeyParseError::InvalidFormat); + + // Dangling escape + let key = r"/usr/usr_table/usr_row\".parse::(); + assert!(key.is_err()); + assert_eq!(key.unwrap_err(), super::KeyParseError::InvalidFormat); + } +} diff --git a/datastores/gossip_kv/kv/membership.rs b/datastores/gossip_kv/kv/membership.rs new file mode 100644 index 000000000000..3657c87d3cd2 --- /dev/null +++ b/datastores/gossip_kv/kv/membership.rs @@ -0,0 +1,85 @@ +use std::fmt::Debug; +use std::hash::Hash; + +use serde::{Deserialize, Serialize}; + +pub type MemberId = String; + +/// Information about a member in the cluster. +/// +/// A member is a transducer that is part of the cluster. Leaving or failing is a terminal +/// state for a member. When a transducer restarts and rejoins the cluster, it is considered a +/// new member. +/// +/// # Generic Parameters +/// -- `A`: The transport of the endpoint on which the protocol is running. In production, this will +/// likely be a `SocketAddr`. +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub struct MemberData +where + A: Debug + Clone + Eq + Hash + Serialize, +{ + /// The name of the member. Usually, this is a randomly generated identifier, based on the + /// hostname on which the member is running. + pub id: MemberId, + + /// The protocols that the member supports. + pub protocols: Vec>, +} + +/// A builder for `MemberData`. +pub struct MemberDataBuilder +where + A: Debug + Clone + Eq + Hash + Serialize, +{ + id: MemberId, + protocols: Vec>, +} + +impl MemberDataBuilder +where + A: Debug + Clone + Eq + Hash + Serialize, +{ + /// Creates a new `MemberDataBuilder`. + pub fn new(id: MemberId) -> Self { + MemberDataBuilder { + id, + protocols: Vec::new(), + } + } + + /// Adds a protocol to the member. + pub fn add_protocol(mut self, protocol: Protocol) -> Self { + self.protocols.push(protocol); + self + } + + /// Builds the `MemberData`. + pub fn build(self) -> MemberData { + MemberData { + id: self.id, + protocols: self.protocols, + } + } +} + +/// A protocol supported by a member. +/// +/// # Generic Parameters +/// -- `A`: The transport of the endpoint on which the protocol is running. In production, this will +/// likely be a `SocketAddr`. +#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)] +pub struct Protocol { + /// The name of the protocol. + pub name: String, + + /// The endpoint on which the protocol is running. + pub endpoint: A, +} + +impl Protocol { + /// Creates a new `Protocol`. + pub fn new(name: String, endpoint: A) -> Self { + Protocol { name, endpoint } + } +} diff --git a/datastores/gossip_kv/kv/model.rs b/datastores/gossip_kv/kv/model.rs new file mode 100644 index 000000000000..3d17d78d3b68 --- /dev/null +++ b/datastores/gossip_kv/kv/model.rs @@ -0,0 +1,166 @@ +use hydroflow::lattices::map_union::MapUnionHashMap; +use hydroflow::lattices::set_union::SetUnionHashSet; +use hydroflow::lattices::{DomPair, Max}; + +use crate::Namespace; + +/// Primary key for entries in a table. +pub type RowKey = String; + +/// Value stored in a table. Modelled as a timestamped set of strings. +/// +/// Each value is timestamped with the time at which it was last updated. Concurrent updates at +/// the same timestamp are stored as a set. +pub type RowValue = DomPair>; + +/// A map from row keys to values in a table. +pub type Table = MapUnionHashMap; + +/// Name of a table in the data store. +pub type TableName = String; + +/// A map from table names to tables. +pub type TableMap = MapUnionHashMap>; + +pub type NamespaceMap = MapUnionHashMap>; + +pub type Namespaces = NamespaceMap>; + +/// Timestamps used in the model. +// TODO: This will be updated to use a more sophisticated clock type with https://github.com/hydro-project/hydroflow/issues/1207. +pub type Clock = Max; + +/// TableMap element to upsert a row in an existing TableMap. +/// +/// Merge this into an existing TableMap to upsert a row in a table. If the table does not exist, +/// it gets created. There's no explicit "create table" operation. +/// +/// Parameters: +/// - `row_ts`: New timestamp of the row being upserted. +/// - `table_name`: Name of the table. +/// - `key`: Primary key of the row. +/// - `val`: Row value. +pub fn upsert_row( + row_ts: C, + ns: Namespace, + table_name: TableName, + key: RowKey, + val: String, +) -> Namespaces { + let value: RowValue = RowValue::new_from(row_ts, SetUnionHashSet::new_from([val])); + let row: Table> = Table::new_from([(key, value)]); + let table: TableMap> = TableMap::new_from([(table_name, row)]); + Namespaces::new_from([(ns, table)]) +} + +/// TableMap element to delete a row from an existing TableMap. +/// +/// Merge this into an existing TableMap to delete a row from a table. +/// +/// Parameters: +/// - `row_ts`: New timestamp of the row being deleted. +/// - `table_name`: Name of the table. +/// - `key`: Primary key of the row. +pub fn delete_row( + row_ts: C, + ns: Namespace, + table_name: TableName, + key: RowKey, +) -> Namespaces { + let value: RowValue = RowValue::new_from(row_ts, SetUnionHashSet::new_from([])); + let row: Table> = Table::new_from([(key, value)]); + let table = TableMap::new_from([(table_name, row)]); + Namespaces::new_from([(ns, table)]) +} + +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + use hydroflow::lattices::Merge; + + use crate::model::{delete_row, upsert_row, Clock, Namespaces, RowKey, TableName}; + use crate::Namespace::System; + + #[test] + fn test_table_map() { + let mut namespaces: Namespaces = Namespaces::default(); + + let first_tick: Clock = Clock::new(0); + let second_tick: Clock = Clock::new(1); + + let members_table = TableName::from("members"); + let key_1 = RowKey::from("key1"); + let value_1: String = "value1".to_string(); + + // Table starts out empty. + assert_eq!( + namespaces.as_reveal_ref().len(), + 0, + "Expected no namespaces." + ); + + let insert = upsert_row( + first_tick, + System, + members_table.clone(), + key_1.clone(), + value_1.clone(), + ); + Merge::merge(&mut namespaces, insert); + { + let table = namespaces + .as_reveal_ref() + .get(&System) + .unwrap() + .as_reveal_ref() + .get(&members_table) + .unwrap(); + + let row = table.as_reveal_ref().get(&key_1); + assert!(row.is_some(), "Row should exist"); + assert_eq!( + *row.unwrap().as_reveal_ref().0, + first_tick, + "Unexpected row timestamp" + ); + + let value = row.unwrap().as_reveal_ref().1.as_reveal_ref(); + assert_eq!( + value, + &HashSet::from([value_1.to_string()]), + "Unexpected row value" + ); + } + + let delete_row = delete_row( + second_tick, + System, + members_table.clone(), + key_1.to_string(), + ); + Merge::merge(&mut namespaces, delete_row); + { + let table = namespaces + .as_reveal_ref() + .get(&System) + .unwrap() + .as_reveal_ref() + .get(&members_table) + .unwrap(); + + // Deletion in this case leaves a "tombstone" + let row = table.as_reveal_ref().get(&key_1); + + assert!(row.is_some(), "Row should exist"); + assert_eq!( + *row.unwrap().as_reveal_ref().0, + second_tick, + "Unexpected row timestamp" + ); + + let value = row.unwrap().as_reveal_ref().1.as_reveal_ref(); + assert_eq!(value, &HashSet::from([]), "Row should be empty"); + } + } +} diff --git a/datastores/gossip_kv/kv/server.rs b/datastores/gossip_kv/kv/server.rs new file mode 100644 index 000000000000..a36d89013c40 --- /dev/null +++ b/datastores/gossip_kv/kv/server.rs @@ -0,0 +1,763 @@ +use std::collections::{HashMap, HashSet}; +use std::fmt::Debug; +use std::hash::Hash; + +use hydroflow::futures::{Sink, Stream}; +use hydroflow::hydroflow_syntax; +use hydroflow::itertools::Itertools; +use hydroflow::lattices::map_union::{KeyedBimorphism, MapUnionHashMap, MapUnionSingletonMap}; +use hydroflow::lattices::set_union::SetUnionHashSet; +use hydroflow::lattices::{Lattice, PairBimorphism}; +use hydroflow::scheduled::graph::Hydroflow; +use lattices::set_union::SetUnion; +use lattices::{IsTop, Max, Pair}; +use lazy_static::lazy_static; +use prometheus::{register_int_counter, IntCounter}; +use rand::seq::IteratorRandom; +use rand::thread_rng; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; +use tracing::{info, trace}; + +use crate::lattices::BoundedSetLattice; +use crate::membership::{MemberData, MemberId}; +use crate::model::{ + delete_row, upsert_row, Clock, NamespaceMap, Namespaces, RowKey, RowValue, TableMap, TableName, +}; +use crate::util::{ClientRequestWithAddress, GossipRequestWithAddress}; +use crate::GossipMessage::{Ack, Nack}; +use crate::{ClientRequest, ClientResponse, GossipMessage, Key, Namespace}; + +/// A trait that represents an abstract network address. In production, this will typically be +/// SocketAddr. +pub trait Address: Hash + Debug + Clone + Eq + Serialize {} +impl Address for A where A: Hash + Debug + Clone + Eq + Serialize {} + +#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)] +pub struct SeedNode +where + A: Address, +{ + pub id: MemberId, + pub address: A, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Lattice)] +pub struct InfectingWrite { + write: Namespaces, + members: BoundedSetLattice, +} + +pub type MessageId = String; + +lazy_static! { + pub static ref SETS_COUNTER: IntCounter = + register_int_counter!("sets", "Counts the number of SET requests processed.").unwrap(); +} + +/// Creates a L0 key-value store server using Hydroflow. +/// +/// # Arguments +/// -- `client_inputs`: The input stream of client requests for the client protocol. +/// -- `client_outputs`: The output sink of client responses for the client protocol. +/// -- `member_info`: The membership information of the server. +/// -- `seed_nodes`: A list of seed nodes that can be used to bootstrap the gossip cluster. +#[expect(clippy::too_many_arguments)] +pub fn server< + ClientInput, + ClientOutput, + ClientOutputError, + GossipInput, + GossipOutput, + GossipOutputError, + GossipTrigger, + SeedNodeStream, + Addr, +>( + client_inputs: ClientInput, + client_outputs: ClientOutput, + gossip_inputs: GossipInput, + gossip_outputs: GossipOutput, + gossip_trigger: GossipTrigger, + member_info: MemberData, + seed_nodes: Vec>, + seed_node_stream: SeedNodeStream, +) -> Hydroflow<'static> +where + ClientInput: Stream + Unpin + 'static, + ClientOutput: Sink<(ClientResponse, Addr), Error = ClientOutputError> + Unpin + 'static, + GossipInput: Stream + Unpin + 'static, + GossipOutput: Sink<(GossipMessage, Addr), Error = GossipOutputError> + Unpin + 'static, + GossipTrigger: Stream + Unpin + 'static, + SeedNodeStream: Stream>> + Unpin + 'static, + Addr: Address + DeserializeOwned + 'static, + ClientOutputError: Debug + 'static, + GossipOutputError: Debug + 'static, +{ + let my_member_id = member_info.id.clone(); + // TODO: This is ugly, but the only way this works at the moment. + let member_id_2 = my_member_id.clone(); + let member_id_3 = my_member_id.clone(); + let member_id_4 = my_member_id.clone(); + let member_id_5 = my_member_id.clone(); + let member_id_6 = my_member_id.clone(); + + hydroflow_syntax! { + + on_start = initialize() -> tee(); + on_start -> for_each(|_| info!("{:?}: Transducer {} started.", context.current_tick(), member_id_6)); + + seed_nodes = source_stream(seed_node_stream) + -> fold::<'static>(|| Box::new(seed_nodes), |last_seed_nodes, new_seed_nodes: Vec>| { + **last_seed_nodes = new_seed_nodes; + info!("Updated seed nodes: {:?}", **last_seed_nodes); + }); + + // Setup member metadata for this process. + on_start -> map(|_| upsert_row(Clock::new(0), Namespace::System, "members".to_string(), my_member_id.clone(), serde_json::to_string(&member_info).unwrap())) + -> writes; + + client_out = + inspect(|(resp, addr)| trace!("{:?}: Sending response: {:?} to {:?}.", context.current_tick(), resp, addr)) + -> dest_sink(client_outputs); + + client_in = source_stream(client_inputs) + -> map(|(msg, addr)| ClientRequestWithAddress::from_request_and_address(msg, addr)) + -> demux_enum::>(); + + client_in[Get] + -> inspect(|req| trace!("{:?}: Received Get request: {:?}.", context.current_tick(), req)) + -> map(|(key, addr) : (Key, Addr)| { + let row = MapUnionHashMap::new_from([ + ( + key.row_key, + SetUnionHashSet::new_from([addr /* to respond with the result later*/]) + ), + ]); + let table = MapUnionHashMap::new_from([(key.table, row)]); + MapUnionHashMap::new_from([(key.namespace, table)]) + }) + -> reads; + + client_in[Set] + -> inspect(|request| trace!("{:?}: Received Set request: {:?}.", context.current_tick(), request)) + -> map(|(key, value, _addr) : (Key, String, Addr)| upsert_row(Clock::new(context.current_tick().0), key.namespace, key.table, key.row_key, value)) + -> inspect(|_| { + SETS_COUNTER.inc(); // Bump SET metrics + }) + -> writes; + + client_in[Delete] + -> inspect(|req| trace!("{:?}: Received Delete request: {:?}.", context.current_tick(), req)) + -> map(|(key, _addr) : (Key, Addr)| delete_row(Clock::new(context.current_tick().0), key.namespace, key.table, key.row_key)) + -> writes; + + gossip_in = source_stream(gossip_inputs) + -> map(|(msg, addr)| GossipRequestWithAddress::from_request_and_address(msg, addr)) + -> demux_enum::>(); + + incoming_gossip_messages = gossip_in[Gossip] + -> inspect(|request| trace!("{:?}: Received gossip request: {:?}.", context.current_tick(), request)) + -> tee(); + + gossip_in[Ack] + -> inspect(|request| trace!("{:?}: Received gossip ack: {:?}.", context.current_tick(), request)) + -> null(); + + gossip_in[Nack] + -> inspect(|request| trace!("{:?}: Received gossip nack: {:?}.", context.current_tick(), request)) + -> map( |(message_id, member_id, _addr)| { + MapUnionSingletonMap::new_from((message_id, InfectingWrite { write: Default::default(), members: BoundedSetLattice::new_from([member_id]) })) + }) + -> infecting_writes; + + gossip_out = union() -> dest_sink(gossip_outputs); + + incoming_gossip_messages + -> map(|(_msg_id, _member_id, writes, _addr)| writes ) + -> writes; + + gossip_processing_pipeline = incoming_gossip_messages + -> map(|(msg_id, _member_id, writes, sender_address) : (String, MemberId, Namespaces>, Addr)| { + let namespaces = &#namespaces; + let all_data: &HashMap>> = namespaces.as_reveal_ref(); + let possible_new_data: &HashMap>>>= writes.as_reveal_ref(); + + // Check if any of the data is new + /* TODO: This logic is duplicated in MapUnion::Merge and ideally should be accessed + from the pass-through streaming output from `state`. See + https://www.notion.so/hydro-project/Proposal-for-State-API-10a2a586262f8080b981d1a2948a69ac + for more. */ + let gossip_has_new_data = possible_new_data.iter() + .flat_map(|(namespace, tables)| { + tables.as_reveal_ref().iter().flat_map(move |(table, rows)|{ + rows.as_reveal_ref().iter().map(move |(row_key, row_value)| (namespace, table, row_key, row_value.as_reveal_ref().0.as_reveal_ref())) + }) + }) + .any(|(ns,table, row_key, new_ts)| { + let existing_tables = all_data.get(ns); + let existing_rows = existing_tables.and_then(|tables| tables.as_reveal_ref().get(table)); + let existing_row = existing_rows.and_then(|rows| rows.as_reveal_ref().get(row_key)); + let existing_ts = existing_row.map(|row| row.as_reveal_ref().0.as_reveal_ref()); + + if let Some(existing_ts) = existing_ts { + trace!("Comparing timestamps: {:?} vs {:?}", new_ts, existing_ts); + new_ts > existing_ts + } else { + true + } + }); + + if gossip_has_new_data { + (Ack { message_id: msg_id, member_id: member_id_2.clone()}, sender_address, Some(writes)) + } else { + (Nack { message_id: msg_id, member_id: member_id_3.clone()}, sender_address, None) + } + }) + -> tee(); + + gossip_processing_pipeline + -> map(|(response, address, _writes)| (response, address)) + -> inspect( |(msg, addr)| trace!("{:?}: Sending gossip response: {:?} to {:?}.", context.current_tick(), msg, addr)) + -> gossip_out; + + gossip_processing_pipeline + -> filter(|(_, _, writes)| writes.is_some()) + -> map(|(_, _, writes)| writes.unwrap()) + -> writes; + + writes = union(); + + writes -> namespaces; + + namespaces = state::<'static, Namespaces::>(); + new_writes = namespaces -> tee(); // TODO: Use the output from here to generate NACKs / ACKs + + reads = state::<'tick, MapUnionHashMap>>>>(); + + new_writes -> [0]process_system_table_reads; + reads -> [1]process_system_table_reads; + + process_system_table_reads = lattice_bimorphism(KeyedBimorphism::, _>::new(KeyedBimorphism::, _>::new(KeyedBimorphism::, _>::new(PairBimorphism))), #namespaces, #reads) + -> lattice_reduce::<'tick>() // TODO: This can be removed if we fix https://github.com/hydro-project/hydroflow/issues/1401. Otherwise the result can be returned twice if get & gossip arrive in the same tick. + -> flat_map(|result: NamespaceMap, SetUnion>>>| { + + let mut response: Vec<(ClientResponse, Addr)> = vec![]; + + let result = result.as_reveal_ref(); + + for (namespace, tables) in result.iter() { + for (table_name, table) in tables.as_reveal_ref().iter() { + for (row_key, join_results) in table.as_reveal_ref().iter() { + let key = Key { + namespace: *namespace, + table: table_name.clone(), + row_key: row_key.clone(), + }; + + let timestamped_values = join_results.as_reveal_ref().0; + let all_values = timestamped_values.as_reveal_ref().1.as_reveal_ref(); + + let all_addresses = join_results.as_reveal_ref().1.as_reveal_ref(); + let socket_addr = all_addresses.iter().find_or_first(|_| true).unwrap(); + + response.push(( + ClientResponse::Get {key, value: all_values.clone()}, + socket_addr.clone(), + )); + } + } + } + response + }) -> client_out; + + new_writes -> for_each(|x| trace!("NEW WRITE: {:?}", x)); + + // Step 1: Put the new writes in a map, with the write as the key and a SetBoundedLattice as the value. + infecting_writes = union() -> state::<'static, MapUnionHashMap>(); + + new_writes -> map(|write| { + // Ideally, the write itself is the key, but writes are a hashmap and hashmaps don't + // have a hash implementation. So we just generate a GUID identifier for the write + // for now. + let id = uuid::Uuid::new_v4().to_string(); + MapUnionSingletonMap::new_from((id, InfectingWrite { write, members: BoundedSetLattice::new() })) + }) -> infecting_writes; + + gossip_trigger = source_stream(gossip_trigger); + + gossip_messages = gossip_trigger + -> flat_map( |_| + { + let infecting_writes = #infecting_writes.as_reveal_ref().clone(); + trace!("{:?}: Currently gossipping {} infecting writes.", context.current_tick(), infecting_writes.iter().filter(|(_, write)| !write.members.is_top()).count()); + infecting_writes + } + ) + -> filter(|(_id, infecting_write)| !infecting_write.members.is_top()) + -> map(|(id, infecting_write)| { + trace!("{:?}: Choosing a peer to gossip to. {:?}:{:?}", context.current_tick(), id, infecting_write); + let peers = #namespaces.as_reveal_ref().get(&Namespace::System).unwrap().as_reveal_ref().get("members").unwrap().as_reveal_ref().clone(); + + let mut peer_names = HashSet::new(); + peers.iter().for_each(|(row_key, _)| { + peer_names.insert(row_key.clone()); + }); + + let seed_nodes = &#seed_nodes; + seed_nodes.iter().for_each(|seed_node| { + peer_names.insert(seed_node.id.clone()); + }); + + // Exclude self from the list of peers. + peer_names.remove(&member_id_5); + + trace!("{:?}: Peers: {:?}", context.current_tick(), peer_names); + + let chosen_peer_name = peer_names.iter().choose(&mut thread_rng()); + + if chosen_peer_name.is_none() { + trace!("{:?}: No peers to gossip to.", context.current_tick()); + return None; + } + + let chosen_peer_name = chosen_peer_name.unwrap(); + let gossip_address = if peers.contains_key(chosen_peer_name) { + let peer_info_value = peers.get(chosen_peer_name).unwrap().as_reveal_ref().1.as_reveal_ref().iter().next().unwrap().clone(); + let peer_info_deserialized = serde_json::from_str::>(&peer_info_value).unwrap(); + peer_info_deserialized.protocols.iter().find(|protocol| protocol.name == "gossip").unwrap().clone().endpoint + } else { + seed_nodes.iter().find(|seed_node| seed_node.id == *chosen_peer_name).unwrap().address.clone() + }; + + trace!("Chosen peer: {:?}:{:?}", chosen_peer_name, gossip_address); + Some((id, infecting_write, gossip_address)) + }) + -> flatten() + -> inspect(|(message_id, infecting_write, peer_gossip_address)| trace!("{:?}: Sending write:\nMessageId:{:?}\nWrite:{:?}\nPeer Address:{:?}", context.current_tick(), message_id, infecting_write, peer_gossip_address)) + -> map(|(message_id, infecting_write, peer_gossip_address): (String, InfectingWrite, Addr)| { + let gossip_request = GossipMessage::Gossip { + message_id: message_id.clone(), + member_id: member_id_4.clone(), + writes: infecting_write.write.clone(), + }; + (gossip_request, peer_gossip_address) + }) + -> gossip_out; + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + use hydroflow::tokio_stream::empty; + use hydroflow::util::simulation::{Address, Fleet, Hostname}; + + use super::*; + use crate::membership::{MemberDataBuilder, Protocol}; + + #[hydroflow::test] + async fn test_member_init() { + let mut fleet = Fleet::new(); + + let server_name: Hostname = "server".to_string(); + + let server_client_address = Address::new(server_name.clone(), "client".to_string()); + let server_gossip_address = Address::new(server_name.clone(), "gossip".to_string()); + + let (_, gossip_trigger_rx) = hydroflow::util::unbounded_channel::<()>(); + + // Create the kv server + fleet.add_host(server_name.clone(), |ctx| { + let client_input = ctx.new_inbox::("client".to_string()); + let client_output = ctx.new_outbox::("client".to_string()); + + let gossip_input = ctx.new_inbox::("gossip".to_string()); + let gossip_output = ctx.new_outbox::("gossip".to_string()); + + let member_data = MemberDataBuilder::new(server_name.clone()) + .add_protocol(Protocol::new( + "client".into(), + server_client_address.clone(), + )) + .add_protocol(Protocol::new( + "gossip".into(), + server_gossip_address.clone(), + )) + .build(); + + server( + client_input, + client_output, + gossip_input, + gossip_output, + gossip_trigger_rx, + member_data, + vec![], + empty(), + ) + }); + + let client_name: Hostname = "client".to_string(); + + let key = "/sys/members/server".parse::().unwrap(); + + let (trigger_tx, trigger_rx) = hydroflow::util::unbounded_channel::<()>(); + let (response_tx, mut response_rx) = hydroflow::util::unbounded_channel::(); + + let key_clone = key.clone(); + let server_client_address_clone = server_client_address.clone(); + + fleet.add_host(client_name.clone(), |ctx| { + let client_tx = ctx.new_outbox::("client".to_string()); + let client_rx = ctx.new_inbox::("client".to_string()); + + hydroflow_syntax! { + + client_output = dest_sink(client_tx); + + source_stream(trigger_rx) + -> map(|_| (ClientRequest::Get { key: key_clone.clone() }, server_client_address_clone.clone()) ) + -> client_output; + + client_input = source_stream(client_rx) + -> for_each(|(resp, _addr)| response_tx.send(resp).unwrap()); + + } + }); + + // Send a trigger to the client to send a get request. + trigger_tx.send(()).unwrap(); + + let expected_member_data = MemberDataBuilder::new(server_name.clone()) + .add_protocol(Protocol::new( + "client".to_string(), + server_client_address.clone(), + )) + .add_protocol(Protocol::new( + "gossip".to_string(), + server_gossip_address.clone(), + )) + .build(); + + loop { + fleet.run_single_tick_all_hosts().await; + + let responses = + hydroflow::util::collect_ready_async::, _>(&mut response_rx).await; + + if !responses.is_empty() { + assert_eq!( + responses, + &[(ClientResponse::Get { + key: key.clone(), + value: HashSet::from([ + serde_json::to_string(&expected_member_data).unwrap() + ]) + })] + ); + break; + } + } + } + + #[hydroflow::test] + async fn test_multiple_values_same_tick() { + let mut fleet = Fleet::new(); + + let server_name: Hostname = "server".to_string(); + + let server_client_address = Address::new(server_name.clone(), "client".to_string()); + + let (_, gossip_trigger_rx) = hydroflow::util::unbounded_channel::<()>(); + + // Create the kv server + fleet.add_host(server_name.clone(), |ctx| { + let client_input = ctx.new_inbox::("client".to_string()); + let client_output = ctx.new_outbox::("client".to_string()); + + let gossip_input = ctx.new_inbox::("gossip".to_string()); + let gossip_output = ctx.new_outbox::("gossip".to_string()); + let server_gossip_address = Address::new(server_name.clone(), "gossip".to_string()); + + let member_data = MemberDataBuilder::new(server_name.clone()) + .add_protocol(Protocol::new( + "client".into(), + server_client_address.clone(), + )) + .add_protocol(Protocol::new( + "gossip".into(), + server_gossip_address.clone(), + )) + .build(); + + server( + client_input, + client_output, + gossip_input, + gossip_output, + gossip_trigger_rx, + member_data, + vec![], + empty(), + ) + }); + + let key = Key { + namespace: Namespace::System, + table: "table".to_string(), + row_key: "row".to_string(), + }; + let val_a = "A".to_string(); + let val_b = "B".to_string(); + + let writer_name: Hostname = "writer".to_string(); + + let (writer_trigger_tx, writer_trigger_rx) = hydroflow::util::unbounded_channel::(); + let key_clone = key.clone(); + let server_client_address_clone = server_client_address.clone(); + + fleet.add_host(writer_name.clone(), |ctx| { + let client_tx = ctx.new_outbox::("client".to_string()); + hydroflow_syntax! { + client_output = dest_sink(client_tx); + + source_stream(writer_trigger_rx) + -> map(|value| (ClientRequest::Set { key: key_clone.clone(), value: value.clone()}, server_client_address_clone.clone()) ) + -> client_output; + } + }); + + // Send two messages from the writer. + let writer = fleet.get_host_mut(&writer_name).unwrap(); + writer_trigger_tx.send(val_a.clone()).unwrap(); + writer.run_tick(); + + writer_trigger_tx.send(val_b.clone()).unwrap(); + writer.run_tick(); + + // Transmit messages across the network. + fleet.process_network().await; + + // Run the server. + let server = fleet.get_host_mut(&server_name).unwrap(); + server.run_tick(); + + // Read the value back. + let reader_name: Hostname = "reader".to_string(); + + let (reader_trigger_tx, reader_trigger_rx) = hydroflow::util::unbounded_channel::<()>(); + let (response_tx, mut response_rx) = hydroflow::util::unbounded_channel::(); + + let key_clone = key.clone(); + let server_client_address_clone = server_client_address.clone(); + + fleet.add_host(reader_name.clone(), |ctx| { + let client_tx = ctx.new_outbox::("client".to_string()); + let client_rx = ctx.new_inbox::("client".to_string()); + + hydroflow_syntax! { + client_output = dest_sink(client_tx); + + source_stream(reader_trigger_rx) + -> map(|_| (ClientRequest::Get { key: key_clone.clone() }, server_client_address_clone.clone()) ) + -> client_output; + + client_input = source_stream(client_rx) + -> for_each(|(resp, _addr)| response_tx.send(resp).unwrap()); + + } + }); + + reader_trigger_tx.send(()).unwrap(); + + loop { + fleet.run_single_tick_all_hosts().await; + + let responses = + hydroflow::util::collect_ready_async::, _>(&mut response_rx).await; + + if !responses.is_empty() { + assert_eq!( + responses, + &[ClientResponse::Get { + key, + value: HashSet::from([val_a, val_b]) + }] + ); + break; + } + } + } + + #[hydroflow::test] + async fn test_gossip() { + let subscriber = tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .with_test_writer() + .finish(); + + let _ = tracing::subscriber::set_global_default(subscriber); + + let mut fleet = Fleet::new(); + + let server_a: Hostname = "server_a".to_string(); + let server_b: Hostname = "server_b".to_string(); + + let server_a_client_address = Address::new(server_a.clone(), "client".to_string()); + let server_b_client_address = Address::new(server_b.clone(), "client".to_string()); + + let server_a_gossip_address = Address::new(server_a.clone(), "gossip".to_string()); + let server_b_gossip_address = Address::new(server_b.clone(), "gossip".to_string()); + + let seed_nodes = vec![ + SeedNode { + id: server_a.clone(), + address: server_a_gossip_address.clone(), + }, + SeedNode { + id: server_b.clone(), + address: server_b_gossip_address.clone(), + }, + ]; + + let (gossip_trigger_tx_a, gossip_trigger_rx_a) = hydroflow::util::unbounded_channel::<()>(); + + let seed_nodes_clone = seed_nodes.clone(); + fleet.add_host(server_a.clone(), |ctx| { + let client_input = ctx.new_inbox::("client".to_string()); + let client_output = ctx.new_outbox::("client".to_string()); + + let gossip_input = ctx.new_inbox::("gossip".to_string()); + let gossip_output = ctx.new_outbox::("gossip".to_string()); + + let member_data = MemberDataBuilder::new(server_a.clone()) + .add_protocol(Protocol::new( + "client".into(), + server_a_client_address.clone(), + )) + .add_protocol(Protocol::new( + "gossip".into(), + server_a_gossip_address.clone(), + )) + .build(); + + server( + client_input, + client_output, + gossip_input, + gossip_output, + gossip_trigger_rx_a, + member_data, + seed_nodes_clone, + empty(), + ) + }); + + let (_, gossip_trigger_rx_b) = hydroflow::util::unbounded_channel::<()>(); + + let seed_nodes_clone = seed_nodes.clone(); + fleet.add_host(server_b.clone(), |ctx| { + let client_input = ctx.new_inbox::("client".to_string()); + let client_output = ctx.new_outbox::("client".to_string()); + + let gossip_input = ctx.new_inbox::("gossip".to_string()); + let gossip_output = ctx.new_outbox::("gossip".to_string()); + + let member_data = MemberDataBuilder::new(server_b.clone()) + .add_protocol(Protocol::new( + "client".into(), + server_b_client_address.clone(), + )) + .add_protocol(Protocol::new( + "gossip".into(), + server_b_gossip_address.clone(), + )) + .build(); + + server( + client_input, + client_output, + gossip_input, + gossip_output, + gossip_trigger_rx_b, + member_data, + seed_nodes_clone, + empty(), + ) + }); + + let key = Key { + namespace: Namespace::User, + table: "table".to_string(), + row_key: "row".to_string(), + }; + + let writer_name: Hostname = "writer".to_string(); + + let (writer_trigger_tx, writer_trigger_rx) = hydroflow::util::unbounded_channel::(); + + let key_clone = key.clone(); + let server_a_client_address_clone = server_a_client_address.clone(); + + fleet.add_host(writer_name.clone(), |ctx| { + let client_tx = ctx.new_outbox::("client".to_string()); + hydroflow_syntax! { + client_output = dest_sink(client_tx); + + source_stream(writer_trigger_rx) + -> map(|value| (ClientRequest::Set { key: key_clone.clone(), value: value.clone()}, server_a_client_address_clone.clone()) ) + -> client_output; + } + }); + + let reader_name: Hostname = "reader".to_string(); + + let (reader_trigger_tx, reader_trigger_rx) = hydroflow::util::unbounded_channel::<()>(); + let (response_tx, mut response_rx) = hydroflow::util::unbounded_channel::(); + + let key_clone = key.clone(); + let server_b_client_address_clone = server_b_client_address.clone(); + + fleet.add_host(reader_name.clone(), |ctx| { + let client_tx = ctx.new_outbox::("client".to_string()); + let client_rx = ctx.new_inbox::("client".to_string()); + + hydroflow_syntax! { + client_output = dest_sink(client_tx); + + source_stream(reader_trigger_rx) + -> map(|_| (ClientRequest::Get { key: key_clone.clone() }, server_b_client_address_clone.clone()) ) + -> client_output; + + client_input = source_stream(client_rx) + -> for_each(|(resp, _addr)| response_tx.send(resp).unwrap()); + + } + }); + + let value = "VALUE".to_string(); + writer_trigger_tx.send(value.clone()).unwrap(); + + loop { + reader_trigger_tx.send(()).unwrap(); + fleet.run_single_tick_all_hosts().await; + let responses = + hydroflow::util::collect_ready_async::, _>(&mut response_rx).await; + + if !responses.is_empty() { + assert_eq!( + responses, + &[ClientResponse::Get { + key, + value: HashSet::from([value.clone()]) + }] + ); + break; + } + + gossip_trigger_tx_a.send(()).unwrap(); + } + } +} diff --git a/datastores/gossip_kv/kv/util.rs b/datastores/gossip_kv/kv/util.rs new file mode 100644 index 000000000000..4cc391da6e7a --- /dev/null +++ b/datastores/gossip_kv/kv/util.rs @@ -0,0 +1,87 @@ +use hydroflow::DemuxEnum; + +use crate::model::{Clock, Namespaces}; +use crate::{ClientRequest, GossipMessage, Key}; + +/// Convenience enum to represent a client request with the address of the client. Makes it +/// possible to use `demux_enum` in the surface syntax. +#[derive(Debug, DemuxEnum)] +pub enum ClientRequestWithAddress { + /// A get request with the key and the address of the client. + Get { key: Key, addr: A }, + /// A set request with the key, value and the address of the client. + Set { key: Key, value: String, addr: A }, + /// A delete request with the key and the address of the client. + Delete { key: Key, addr: A }, +} + +impl ClientRequestWithAddress { + /// Create a `ClientRequestWithAddress` from a `ClientRequest` and an address. + pub fn from_request_and_address(request: ClientRequest, addr: A) -> Self { + match request { + ClientRequest::Get { key } => Self::Get { key, addr }, + ClientRequest::Set { key, value } => Self::Set { key, value, addr }, + ClientRequest::Delete { key } => Self::Delete { key, addr }, + } + } +} + +/// Convenience enum to represent a gossip request with the address of the client. Makes it +/// possible to use `demux_enum` in the surface syntax. +#[derive(Debug, DemuxEnum)] +pub enum GossipRequestWithAddress { + /// A gossip request with the message id, writes and the address of the client. + Gossip { + message_id: String, + member_id: String, + writes: Namespaces, + addr: A, + }, + /// An ack request with the message id and the address of the client. + Ack { + message_id: String, + member_id: String, + addr: A, + }, + /// A nack request with the message id and the address of the client. + Nack { + message_id: String, + member_id: String, + addr: A, + }, +} + +impl GossipRequestWithAddress { + /// Create a `GossipRequestWithAddress` from a `GossipMessage` and an address. + pub fn from_request_and_address(request: GossipMessage, addr: A) -> Self { + match request { + GossipMessage::Gossip { + message_id, + member_id, + writes, + } => Self::Gossip { + message_id, + member_id, + writes, + addr, + }, + + GossipMessage::Ack { + message_id, + member_id, + } => Self::Ack { + message_id, + addr, + member_id, + }, + GossipMessage::Nack { + message_id, + member_id, + } => Self::Nack { + message_id, + addr, + member_id, + }, + } + } +} diff --git a/datastores/gossip_kv/load_test_server/Dockerfile b/datastores/gossip_kv/load_test_server/Dockerfile new file mode 100644 index 000000000000..91f27fdd22d5 --- /dev/null +++ b/datastores/gossip_kv/load_test_server/Dockerfile @@ -0,0 +1,11 @@ +FROM "hydroflow-gossip-kv-base-image:latest" AS builder +WORKDIR /usr/src/gossip-kv-server +COPY . . +RUN find . +RUN cargo build --release --workspace -p gossip_kv + +FROM rustlang/rust:nightly-slim +COPY --from=builder /usr/src/gossip-kv-server/target/release/load_test_server /usr/local/bin/load_test_server + +# Don't skip the trailing slash in the destination directory +CMD ["load_test_server"] diff --git a/datastores/gossip_kv/load_test_server/server.rs b/datastores/gossip_kv/load_test_server/server.rs new file mode 100644 index 000000000000..88bd40e3fb32 --- /dev/null +++ b/datastores/gossip_kv/load_test_server/server.rs @@ -0,0 +1,226 @@ +use std::convert::Infallible; +use std::num::{NonZeroU32, ParseFloatError}; +use std::thread::sleep; +use std::time::Duration; + +use clap::Parser; +use gossip_kv::membership::{MemberDataBuilder, Protocol}; +use gossip_kv::{ClientRequest, GossipMessage}; +use governor::{Quota, RateLimiter}; +use hydroflow::util::{unbounded_channel, unsync_channel}; +use prometheus::{gather, Encoder, TextEncoder}; +use tokio::sync::mpsc::UnboundedSender; +use tokio::task; +use tracing::{error, info, trace}; +use warp::Filter; + +type LoadTestAddress = u64; + +use gossip_kv::server::{server, SeedNode}; +use hydroflow::futures::sink::drain; +use hydroflow::futures::stream; +use hydroflow::tokio_stream::wrappers::UnboundedReceiverStream; +use hydroflow::tokio_stream::StreamExt; +use lattices::cc_traits::Iter; + +const UNKNOWN_ADDRESS: LoadTestAddress = 9999999999; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Parser)] +struct Opts { + /// Number of threads to run. Each thread will run an instance of the gossip-kv server transducer. + #[clap(short, long, default_value = "5")] + thread_count: usize, + + /// Frequency (in seconds) at which to send gossip messages. + #[clap(short, long, default_value = "10", value_parser = clap_duration_from_secs)] + gossip_frequency: Duration, + + /// Maximum number of SET requests to send per second. + #[clap(short, long, default_value = "1")] + max_set_throughput: u32, +} + +/// Parse duration from float string for clap args. +fn clap_duration_from_secs(arg: &str) -> Result { + arg.parse().map(Duration::from_secs_f32) +} + +fn run_server( + server_name: String, + gossip_address: LoadTestAddress, + gossip_input_rx: UnboundedReceiverStream<(GossipMessage, LoadTestAddress)>, + switchboard: Switchboard, + seed_nodes: Vec>, + opts: Opts, +) { + std::thread::spawn(move || { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + + let (gossip_output_tx, mut gossip_output_rx) = unsync_channel(None); + + let (gossip_trigger_tx, gossip_trigger_rx) = unbounded_channel(); + + let member_data = MemberDataBuilder::new(server_name.clone()) + .add_protocol(Protocol::new("gossip".into(), gossip_address)) + .build(); + + rt.block_on(async { + let local = task::LocalSet::new(); + + let (client_input_tx, client_input_rx) = unbounded_channel(); + + let put_throughput = opts.max_set_throughput; + local.spawn_local(async move { + let rate_limiter = RateLimiter::direct(Quota::per_second( + NonZeroU32::new(put_throughput).unwrap(), + )); + loop { + rate_limiter.until_ready().await; + let key = "/usr/table/key".parse().unwrap(); + let request = ClientRequest::Set { + key, + value: "FOOBAR".to_string(), + }; + client_input_tx.send((request, UNKNOWN_ADDRESS)).unwrap(); + } + }); + + let gossip_frequency = opts.gossip_frequency; + local.spawn_local(async move { + loop { + tokio::time::sleep(gossip_frequency).await; + gossip_trigger_tx.send(()).unwrap(); + } + }); + + // Networking + local.spawn_local(async move { + while let Some((msg, addr)) = gossip_output_rx.next().await { + trace!("Sending gossip message: {:?} to {}", msg, addr); + let outbox = switchboard.gossip_outboxes.get(addr as usize).unwrap(); + if let Err(e) = outbox.send((msg, gossip_address)) { + error!("Failed to send gossip message: {:?}", e); + } + } + }); + + local.spawn_local(async { + let mut server = server( + client_input_rx, + drain(), // Ignoring client responses for now. + gossip_input_rx, + gossip_output_tx, + gossip_trigger_rx, + member_data, + seed_nodes, + stream::empty(), + ); + + server.run_async().await + }); + + local.await + }); + }); +} + +struct Switchboard { + gossip_outboxes: Vec>, +} + +impl Clone for Switchboard { + fn clone(&self) -> Self { + Self { + gossip_outboxes: self.gossip_outboxes.clone(), + } + } +} + +impl Switchboard { + fn new() -> Self { + Self { + gossip_outboxes: Vec::new(), + } + } + fn new_outbox( + &mut self, + ) -> ( + LoadTestAddress, + UnboundedReceiverStream<(GossipMessage, LoadTestAddress)>, + ) { + let addr: LoadTestAddress = self.gossip_outboxes.len() as LoadTestAddress; + let (tx, rx) = unbounded_channel(); + self.gossip_outboxes.push(tx); + (addr, rx) + } +} + +async fn metrics_handler() -> Result { + let encoder = TextEncoder::new(); + let metric_families = gather(); + let mut buffer = Vec::new(); + encoder.encode(&metric_families, &mut buffer).unwrap(); + + Ok(warp::reply::with_header( + buffer, + "Content-Type", + encoder.format_type(), + )) +} + +fn main() { + tracing_subscriber::fmt::init(); + + let opts: Opts = Opts::parse(); + + std::thread::spawn(move || { + let metrics_route = warp::path("metrics").and_then(metrics_handler); + + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + + rt.block_on(async move { + info!("Starting metrics server on port 4003"); + warp::serve(metrics_route).run(([0, 0, 0, 0], 4003)).await; + }); + }); + + info!("Starting load test with with {} threads", opts.thread_count); + + let mut switchboard = Switchboard::new(); + + let outboxes: Vec<_> = (0..opts.thread_count) + .map(|_| { + let (addr, rx) = switchboard.new_outbox(); + (format!("SERVER-{}", addr), addr, rx) + }) + .collect(); + + let seed_nodes: Vec<_> = outboxes + .iter() + .map(|(name, addr, _)| SeedNode { + id: name.clone(), + address: *addr, + }) + .collect(); + + outboxes.into_iter().for_each(|(name, addr, outbox)| { + run_server( + name, + addr, + outbox, + switchboard.clone(), + seed_nodes.clone(), + opts, + ); + }); + + loop { + sleep(Duration::from_secs(1)); + } +} diff --git a/datastores/gossip_kv/server/.gitignore b/datastores/gossip_kv/server/.gitignore new file mode 100644 index 000000000000..9d1173a06139 --- /dev/null +++ b/datastores/gossip_kv/server/.gitignore @@ -0,0 +1 @@ +config/local.toml \ No newline at end of file diff --git a/datastores/gossip_kv/server/Dockerfile b/datastores/gossip_kv/server/Dockerfile new file mode 100644 index 000000000000..4032b4056fbe --- /dev/null +++ b/datastores/gossip_kv/server/Dockerfile @@ -0,0 +1,13 @@ +FROM "hydroflow-gossip-kv-base-image:latest" AS builder +WORKDIR /usr/src/gossip-kv-server +COPY . . +RUN find . +RUN cargo build --release --workspace -p gossip_kv + +FROM rustlang/rust:nightly-slim +COPY --from=builder /usr/src/gossip-kv-server/target/release/gossip_server /usr/local/bin/gossip_server + +RUN mkdir -p /config/static +# Don't skip the trailing slash in the destination directory +COPY datastores/gossip_kv/server/config/static/*.toml /config/static/ +CMD ["gossip_server"] diff --git a/datastores/gossip_kv/server/baseimage.Dockerfile b/datastores/gossip_kv/server/baseimage.Dockerfile new file mode 100644 index 000000000000..911de64a7f75 --- /dev/null +++ b/datastores/gossip_kv/server/baseimage.Dockerfile @@ -0,0 +1,23 @@ +FROM rustlang/rust:nightly AS builder +WORKDIR /usr/src/gossip-kv-server-base-image +COPY . . + +RUN apt-get update && apt-get install -y \ + python3 \ + python3.11-dev \ + libpython3.11 \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +## Build everything, including dependencies. The built dependencies will be cached, so only changing the server +## code requires lesser build time. +RUN cargo build --release --workspace -p gossip_kv + +## Copy the built file to where the actual app will be built subsequently. +RUN mkdir -p /usr/src/gossip-kv-server/target/release +RUN mv /usr/src/gossip-kv-server-base-image/target/release/build/ /usr/src/gossip-kv-server/target/release/build/ +RUN mv /usr/src/gossip-kv-server-base-image/target/release/deps/ /usr/src/gossip-kv-server/target/release/deps/ +RUN mv /usr/src/gossip-kv-server-base-image/target/release/.fingerprint/ /usr/src/gossip-kv-server/target/release/.fingerprint/ + +## Delete all the source code +RUN rm -rf /usr/src/gossip-kv-server-base-image \ No newline at end of file diff --git a/datastores/gossip_kv/server/config/mod.rs b/datastores/gossip_kv/server/config/mod.rs new file mode 100644 index 000000000000..13ff54873ad2 --- /dev/null +++ b/datastores/gossip_kv/server/config/mod.rs @@ -0,0 +1,130 @@ +use std::path::PathBuf; + +use config::{Config, ConfigError, File}; +use hydroflow::futures::future::ready; +use hydroflow::futures::{Stream, StreamExt}; +use notify::{Event, EventHandler, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; +use serde::{Deserialize, Serialize}; +use tokio::sync::mpsc::UnboundedSender; +use tracing::trace; + +/// L0 Data Store settings. +#[derive(Debug, Deserialize, Serialize)] +pub struct ServerSettings { + /// An initial set of "seed nodes" that can be used to bootstrap the gossip cluster. These + /// won't be the only nodes in the cluster, but they can be used to discover other nodes. + pub seed_nodes: Vec, +} + +const CONFIG_ROOT: &str = "config"; +const STATIC_CONFIG_PATH: &str = "static"; +const DYNAMIC_CONFIG_PATH: &str = "dynamic"; + +fn static_config_path(subpath: &str) -> PathBuf { + PathBuf::from(CONFIG_ROOT) + .join(STATIC_CONFIG_PATH) + .join(subpath) +} + +fn dynamic_config_path(subpath: &str) -> PathBuf { + PathBuf::from(CONFIG_ROOT) + .join(DYNAMIC_CONFIG_PATH) + .join(subpath) +} + +impl ServerSettings { + /// Load the settings from the configuration files. + pub fn new() -> Result { + let run_mode = std::env::var("RUN_MODE").unwrap_or_else(|_| "development".into()); + + let settings = Config::builder() + /* Load the default settings from the `config/default.toml` file. */ + .add_source(File::from(static_config_path("default.toml")).required(false)) + + /* Load additional overrides based on context (alpha, beta, production, etc.), if they exist. */ + .add_source(File::from(static_config_path(&run_mode)).required(false)) + + /* Load the local settings, if they exist. These are .gitignored to prevent accidental + check-in. */ + .add_source(File::from(static_config_path("local")).required(false)) + + /* Load the dynamic settings, if they exist. These always override any static configuration*/ + .add_source(File::from(dynamic_config_path("dynamic.toml")).required(false)) + .build()?; + + settings.try_deserialize() + } +} + +/// A seed node that can be used to bootstrap the gossip cluster. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq, Hash)] +pub struct SeedNodeSettings { + /// The ID of the seed node. + pub id: String, + + /// The address on which the seed node is listening for gossip messages. + pub address: String, +} + +/// Setup a watcher for the settings files and return a stream of settings changes. +/// +/// Returns the watcher, the initial settings, and a stream of settings changes. The watcher is +/// returned so that it can be kept alive for the lifetime of the application. Also returns a +/// snapshot of the current settings. +pub fn setup_settings_watch() -> ( + RecommendedWatcher, + ServerSettings, + impl Stream, +) { + let (tx, rx) = hydroflow::util::unbounded_channel(); + + // Setup the watcher + let mut watcher = notify::RecommendedWatcher::new( + UnboundedSenderEventHandler::new(tx), + notify::Config::default(), + ) + .unwrap(); + watcher + .watch(&PathBuf::from(CONFIG_ROOT), RecursiveMode::Recursive) + .unwrap(); + + // Read initial settings + let initial_settings = ServerSettings::new().unwrap(); + + let change_stream = rx + .map(Result::unwrap) + .map(|event| { + trace!("Event: {:?}", event); + match event.kind { + EventKind::Create(_) | EventKind::Modify(_) | EventKind::Remove(_) => { + Some(ServerSettings::new().unwrap()) + } + _ => { + trace!("Unhandled event: {:?}", event); + None + } + } + }) + .filter_map(ready); + + // If the watcher is dropped, the stream will stop producing events. So, returning the watcher. + (watcher, initial_settings, change_stream) +} + +/// Wraps an UnboundedSender to implement the notify::EventHandler trait. This allows sending +/// file notification evnts to UnboundedSender instances. +struct UnboundedSenderEventHandler { + tx: UnboundedSender>, +} + +impl UnboundedSenderEventHandler { + fn new(tx: UnboundedSender>) -> Self { + Self { tx } + } +} + +impl EventHandler for UnboundedSenderEventHandler { + fn handle_event(&mut self, event: notify::Result) { + self.tx.send(event).unwrap(); + } +} diff --git a/datastores/gossip_kv/server/config/static/default.toml b/datastores/gossip_kv/server/config/static/default.toml new file mode 100644 index 000000000000..b651079e8aa8 --- /dev/null +++ b/datastores/gossip_kv/server/config/static/default.toml @@ -0,0 +1,5 @@ +seed_nodes = [] + +#[[seed_nodes]] +#id = "gossip-kv-seed-nodes-0" +#address = "gossip-kv-seed-nodes-0.gossip-kv-seed-nodes.default.svc.cluster.local:3000" \ No newline at end of file diff --git a/datastores/gossip_kv/server/config/static/development.toml b/datastores/gossip_kv/server/config/static/development.toml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/datastores/gossip_kv/server/main.rs b/datastores/gossip_kv/server/main.rs new file mode 100644 index 000000000000..bca640e9449b --- /dev/null +++ b/datastores/gossip_kv/server/main.rs @@ -0,0 +1,191 @@ +use std::convert::Infallible; +use std::fmt::Debug; +use std::future::ready; +use std::hash::Hash; +use std::io::Error; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::num::ParseFloatError; +use std::time::Duration; + +use clap::Parser; +use gossip_kv::membership::{MemberDataBuilder, Protocol}; +use gossip_kv::server::{server, SeedNode}; +use hydroflow::futures::{Sink, SinkExt, StreamExt}; +use hydroflow::tokio_stream::wrappers::IntervalStream; +use hydroflow::util::{bind_udp_bytes, ipv4_resolve}; +use hydroflow::{bincode, bytes, tokio}; +use prometheus::{gather, Encoder, TextEncoder}; +use serde::Serialize; +use tracing::{error, info, trace}; +use warp::Filter; + +use crate::config::{setup_settings_watch, SeedNodeSettings}; +use crate::membership::member_name; + +mod config; + +mod membership; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Parser)] +struct Opts { + /// Port to listen for gossip messages. + #[clap(short, long, default_value = "3000")] + gossip_port: u16, + + /// Port to listen for client requests. + #[clap(short, long, default_value = "3001")] + client_port: u16, + + /// The duration (in seconds) between gossip rounds. + #[clap(short, long, default_value = "5", value_parser = clap_duration_from_secs)] + gossip_frequency: Duration, + + #[clap(env = "GOSSIP_MEMBER_SUFFIX_LEN", default_value = "4")] + member_suffix_len: usize, +} + +/// Parse duration from float string for clap args. +fn clap_duration_from_secs(arg: &str) -> Result { + arg.parse().map(Duration::from_secs_f32) +} + +/// Create a SeedNode from a SeedNodeSettings. +/// Performs a DNS lookup on the address. +fn make_seed_node(settings: &SeedNodeSettings) -> SeedNode { + SeedNode { + id: settings.id.clone(), + address: ipv4_resolve(&settings.address).unwrap(), + } +} + +/// Handler for the /metrics route. Used to expose prometheus metrics for the server. +async fn metrics_handler() -> Result { + let encoder = TextEncoder::new(); + let metric_families = gather(); + let mut buffer = Vec::new(); + encoder.encode(&metric_families, &mut buffer).unwrap(); + + Ok(warp::reply::with_header( + buffer, + "Content-Type", + encoder.format_type(), + )) +} + +/// Setup serialization for outbound networking messages. +fn setup_outbound_serialization( + outbound: Outbound, +) -> impl Sink<(Message, SocketAddr), Error = Error> +where + Outbound: Sink<(bytes::Bytes, SocketAddr), Error = Error>, + Message: Serialize + Debug + Send + 'static, +{ + outbound.with(|(msg, addr): (Message, SocketAddr)| { + ready(Ok::<(bytes::Bytes, SocketAddr), Error>(( + hydroflow::util::serialize_to_bytes(msg), + addr, + ))) + }) +} + +/// Setup deserialization for inbound networking messages. +fn setup_inbound_deserialization( + inbound: Inbound, +) -> impl hydroflow::futures::Stream +where + Inbound: hydroflow::futures::Stream>, + Message: for<'de> serde::Deserialize<'de> + Debug + Send + 'static, +{ + inbound.filter_map(|input| { + let mapped = match input { + Ok((bytes, addr)) => { + let msg: bincode::Result = hydroflow::util::deserialize_from_bytes(&bytes); + match msg { + Ok(msg) => Some((msg, addr)), + Err(e) => { + error!("Error deserializing message: {:?}", e); + None + } + } + } + Err(e) => { + error!("Error receiving message: {:?}", e); + None + } + }; + ready(mapped) + }) +} + +#[hydroflow::main] +async fn main() { + tracing_subscriber::fmt::init(); + + let opts: Opts = Opts::parse(); + + // Setup metrics server + let metrics_route = warp::path("metrics").and_then(metrics_handler); + tokio::spawn(async move { + info!("Starting metrics server on port 4003"); + warp::serve(metrics_route).run(([0, 0, 0, 0], 4003)).await; + }); + + // Setup protocol information for this member + let client_protocol_address = + SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), opts.client_port); + let gossip_protocol_address = + SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), opts.gossip_port); + + let member_data = MemberDataBuilder::new(member_name(opts.member_suffix_len).clone()) + .add_protocol(Protocol::new("gossip".into(), gossip_protocol_address)) + .add_protocol(Protocol::new("client".into(), client_protocol_address)) + .build(); + + // Bind to the UDP ports + let (client_outbound, client_inbound, _) = bind_udp_bytes(client_protocol_address).await; + let (gossip_outbound, gossip_inbound, _) = bind_udp_bytes(gossip_protocol_address).await; + + info!( + "Server {:?} listening for client requests on: {:?}", + member_data.id, client_protocol_address + ); + + // Setup serde for client requests + let client_ob = setup_outbound_serialization(client_outbound); + let client_ib = setup_inbound_deserialization(client_inbound); + + // Setup serde for gossip messages + let gossip_ob = setup_outbound_serialization(gossip_outbound); + let gossip_ib = setup_inbound_deserialization(gossip_inbound); + + // Setup regular gossip triggers + let gossip_rx = IntervalStream::new(tokio::time::interval(opts.gossip_frequency)).map(|_| ()); + + // Setup watcher for setting changes + let (_watcher, server_settings, settings_stream) = setup_settings_watch(); + + let seed_nodes = server_settings + .seed_nodes + .iter() + .map(make_seed_node) + .collect::>(); + + let seed_node_stream = settings_stream.map(|settings| { + trace!("Settings updated. Reloading seed nodes"); + settings.seed_nodes.iter().map(make_seed_node).collect() + }); + + // Create and run the server + let mut server = server( + client_ib, + client_ob, + gossip_ib, + gossip_ob, + gossip_rx, + member_data, + seed_nodes, + seed_node_stream, + ); + + server.run_async().await; +} diff --git a/datastores/gossip_kv/server/membership.rs b/datastores/gossip_kv/server/membership.rs new file mode 100644 index 000000000000..bdaef84b6c11 --- /dev/null +++ b/datastores/gossip_kv/server/membership.rs @@ -0,0 +1,34 @@ +use std::sync::OnceLock; + +use gossip_kv::membership::MemberId; +use rand::distributions::Distribution; +use rand::{thread_rng, Rng}; + +/// This is a simple distribution that generates a random lower-case alphanumeric +struct LowercaseAlphanumeric; + +impl Distribution for LowercaseAlphanumeric { + fn sample(&self, rng: &mut R) -> char { + let choices = b"abcdefghijklmnopqrstuvwxyz0123456789"; + choices[rng.gen_range(0..choices.len())] as char + } +} + +/// Gets a name for the current process. +pub fn member_name(random_suffix_len: usize) -> &'static MemberId { + static MEMBER_NAME: OnceLock = OnceLock::new(); + MEMBER_NAME.get_or_init(|| { + let hostname = hostname::get().unwrap().to_str().unwrap().to_string(); + + if random_suffix_len > 0 { + let suffix: String = thread_rng() + .sample_iter(&LowercaseAlphanumeric) + .take(4) + .map(char::from) + .collect(); + format!("{}-{}", hostname, suffix) + } else { + hostname + } + }) +} diff --git a/docs/docs/hydroflow/ecosystem.md b/docs/docs/hydroflow/ecosystem.md index 62e10157ec9d..44199e74523b 100644 --- a/docs/docs/hydroflow/ecosystem.md +++ b/docs/docs/hydroflow/ecosystem.md @@ -4,24 +4,22 @@ sidebar_position: 4 # The Hydro Ecosystem The Hydro Project is an evolving stack of libraries and languages for distributed programming. -A rough picture of the envisioned Hydro stack is below: +A rough picture of the Hydro stack is below: ![Hydro Stack](./img/hydro_stack.png) -The core of the Hydro stack is shown in in the grey box; components that have not been implemented are in orange. +Working down from the top: -Working up from the bottom: +- [*Hydroflow+*](../hydroflow_plus) is an end-user-facing high-level [choreographic](https://en.wikipedia.org/wiki/Choreographic_programming) [dataflow](https://en.wikipedia.org/wiki/Dataflow_programming) language. Hydroflow+ is a *global* language for programming a fleet of transducers. Programmers author dataflow pipelines that start with streams of events and data, and span boundaries across multiple `process` and (scalable) `cluster` specifications. -- [Hydroplane](https://github.com/hydro-project/hydroplane) is a service for launching and monitoring Hydroflow transducers. It works both on local developer machines with Docker, and in cloud services like AWS EKS. Over time we expect to add autoscaling features to Hydroplane, to allow users to configure the cluster to grow and shrink based on the monitored behavior and a pluggable policy. +- *Hydrolysis* is a compiler that translates a global Hydroflow+ spec to multiple single-threaded Hydroflow IR programs, which collectively implement the global spec. +This compilation phase is currently a part of the Hydroflow+ codebase, but will evolve into a standalone optimizing compiler inspired by database query optimizers and [e-graphs](https://en.wikipedia.org/wiki/E-graph). -- [Hydroflow](https://github.com/hydro-project/hydroplane) is the subject of this book; a library for defining individual transducers in a distributed system. It uses the Rust compiler to generate binaries for deployment. +- [Hydroflow IR and its compiler/runtime](https://github.com/hydro-project/hydroflow/tree/main/hydroflow) are the subject of this book. +Where Hydroflow+ is a *global* language for programming a fleet of processes, Hydroflow is a *local* language for programming a single process that participates in a distributed system. More specifically, Hydroflow is an internal representation (IR) language and runtime library that generates the low-level Rust code for an individual transducer. As a low-level IR, Hydroflow is not intended for the general-purpose programmer. For most users it is intended as a readable compiler target from Hydroflow+; advanced developers can also use it to manually program individual transducers. -- *Hydrolysis* is a compiler we envision translating from Hydrologic to Hydroflow. +- [HydroDeploy](../deploy) is a service for launching Hydroflow transducers on a variety of platforms. -- *Hydrologic* is a high-level domain-specific language that we envision for distributed programming. Unlike Hydroflow, we expect Hydrologic to abstract away many notions of distributed computing. In particular, Hydrologic will be insensitive to the specific deployment of the code—the partitioning of functionality and data across transducers, the number of replicas of each transducer, etc. Instead, programmers will provide specifications for desired properties like the number of failures to tolerate, the consistency desired at a given endpoint, the latency of a given endpoint, etc. The Hydrolysis compiler will then generate Hydroflow transducers that can be deployed by Hydroplane to meet those specifications. - -- [Metalift](https://github.com/metalift/metalift) is a framework for "lifting" code from one language to a (typically higher-level) language. We envision that Metalift will be used to translate from one of many distributed programming models/languages into our common Internal Representation, Hydrologic. +- Hydro also supports *Deterministic Simulation Testing* to aid in debugging distributed programs. Documentation on this feature is forthcoming. The Hydro stack is inspired by previous language stacks including [LLVM](https://llvm.org) and [Halide](https://halide-lang.org), which similarly expose multiple human-programmable Internal Representation langauges. - -An early paper on the Hydro vision appeared in CIDR 2021, under the title [New Directions in Cloud Programming](https://www.cidrdb.org/cidr2021/papers/cidr2021_paper16.pdf). \ No newline at end of file diff --git a/docs/docs/hydroflow/img/hydro_stack.png b/docs/docs/hydroflow/img/hydro_stack.png index d6fa04edcb0e..a5d87b7b1ad3 100644 Binary files a/docs/docs/hydroflow/img/hydro_stack.png and b/docs/docs/hydroflow/img/hydro_stack.png differ diff --git a/docs/docs/hydroflow/quickstart/example_1_simplest.mdx b/docs/docs/hydroflow/quickstart/example_1_simplest.mdx index 4a3f72c2bb34..394367386a0d 100644 --- a/docs/docs/hydroflow/quickstart/example_1_simplest.mdx +++ b/docs/docs/hydroflow/quickstart/example_1_simplest.mdx @@ -52,15 +52,15 @@ And then run the program: ## Understanding the Code Although this is a trivial program, it's useful to go through it line by line. -{getLines(exampleCode, 1)} +{getLines(exampleCode, 'use')} -This import gives you everything you need from Hydroflow to write code with Hydroflow's +This import gives you the macro you need from Hydroflow to write code in Hydroflow's [_surface syntax_](../syntax). Next, inside the main method we specify a flow by calling the `hydroflow_syntax!` macro. We assign the resulting `Hydroflow` instance to a mutable variable `flow`––mutable because we will be changing its status when we run it. -{getLines(exampleCode, 3, 6)} +{getLines(exampleCode, 'macro_call')} Hydroflow surface syntax defines a "flow" consisting of *operators* connected via `->` arrows. This simplest example uses a simple two-step linear flow. @@ -74,7 +74,7 @@ The Hydroflow surface syntax is merely a *specification*; it does not actually d until we run it. We can run this flow from within Rust via the [`run_available()` method](https://hydro-project.github.io/hydroflow/doc/hydroflow/scheduled/graph/struct.Hydroflow.html#method.run_available). -{getLines(exampleCode, 8)} +{getLines(exampleCode, 'run')} Note that `run_available()` runs the Hydroflow graph until no more work is immediately available. In this example flow, running the graph drains the iterator completely, so no diff --git a/docs/docs/hydroflow/quickstart/setup.md b/docs/docs/hydroflow/quickstart/setup.md index 027665899ba9..0c363510806a 100644 --- a/docs/docs/hydroflow/quickstart/setup.md +++ b/docs/docs/hydroflow/quickstart/setup.md @@ -99,7 +99,7 @@ Take note of the server's port number, and in a separate terminal, start a clien #shell-command-next-line cd #shell-command-next-line -cargo run -- --role client --server-addr 127.0.0.1: +cargo run -- --role client --address 127.0.0.1: Listening on 127.0.0.1: Connecting to server at 127.0.0.1: Client live! diff --git a/docs/docs/hydroflow/todo.md b/docs/docs/hydroflow/todo.md deleted file mode 100644 index b10714f83fd6..000000000000 --- a/docs/docs/hydroflow/todo.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -sidebar_position: 8 ---- - -# TODO - -## Concepts -- p1 (Mingwei) Hydroflow and Rust: how do they go together? - - State, control, scoping -- p1 State over time - - lifetimes - - explicit deletion -- p3 Coordination tricks? - - End-of-stream to Distributed EOS? - -## Docs -- p1 `hydroflow` struct and its methods -- p2 Review the ops docs - -## Operators not discussed - - dest_sink - - identity - - unzip - - p1 *fold* -- add to chapter on [state](./syntax/state.md) - - p1 *reduce* -- add to chapter on [state](./syntax/state.md) - - p1 *fold_keyed* -- add to chapter on [state](./syntax/state.md) - - p3 *sort_by_key* -- add to chapter on [state](./syntax/state.md) - - p2 *next_stratum* -- add to chapter on [time](./concepts/life_and_times.md) - - p2 *next_tick* -- add to chapter on [time](./concepts/life_and_times.md) - - p2 *inspect* -- add to chapter on [debugging](./concepts/debugging.md) - - p2 *null* -- add to chapter on [debugging](./concepts/debugging.md) - -## How-Tos and Examples -- p1 Lamport clocks -- p2 Vector clocks -- p2 A partitioned Service -- p2 A replicated Service -- p2 Interfacing with external data -- p2 Interfacing with external services -- p1 Illustrate `'static` and `'tick` lifetimes (KVS) -- p3 Illustrate the `next_stratum` operator for atomicity (eg Bloom's upsert `<+-` operator) -- p3 Illustrate ordered streams (need `zip` operator ... what's the example?) -- p3 Actor model implementation (Borrow an Akka or Ray Actors example?) -- p3 Futures emulation? (Borrow a Ray example) -- p2 Illustrate external storage source and sink (e.g. for WAL of KVS) - -## Odds and ends taken out of other chapters -- **Document the methods on the `hydroflow` struct** -- especially the run methods. - - The [`run_tick()`](https://hydro-project.github.io/hydroflow/doc/hydroflow/scheduled/graph/struct.Hydroflow.html#method.run_tick), [`run_stratum()`](https://hydro-project.github.io/hydroflow/doc/hydroflow/scheduled/graph/struct.Hydroflow.html#method.run_stratum), [`run()`](https://hydro-project.github.io/hydroflow/doc/hydroflow/scheduled/graph/struct.Hydroflow.html#method.run), and [`run_async()`](https://hydro-project.github.io/hydroflow/doc/hydroflow/scheduled/graph/struct.Hydroflow.html#method.run_async) methods provide other ways to control the graph execution. - - Also `run_available()` `next_stratum()` and `recv_events` are important - -- **Make sure `src/examples/echoserver` is the same as the template project** -- or better, find a way to do that via github actions or a github submodule - -## What's covered in examples -- Concepts covered - - cargo generate for templating - - Hydroflow program specs embedded in Rust - - Tokio Channels and how to use them in Hydroflow - - Network sources and sinks (`source_stream`) - - Built-in serde (`source_stream_serde`, `dest_sink_serde`) - - Hydroflow syntax: operators, ->, variables, indexing multi-input/output operators - - running Hydroflow via `run_available` and `run_async` - - Recursion via cyclic dataflow - - Fixpoints and Strata - - Template structure: `clap`, message types - - `source_stdin` - - Messages and `demux` - - broadcast pattern - - the `persist` operator to store and replay dataflow - - the `defer_signal` operator to gate a dataflow - - bootstrapping pipelines: `initialize` - -- Operators covered - - cross_join - - defer_signal - - demux - - dest_sink_serde - - difference - - filter - - filter_map - - flatten - - flat_map - - for_each - - initialize - - join - - map - - persist - - union - - source_iter - - source_stdin - - source_stream - - source_stream_serde - - tee - - union - - unique diff --git a/docs/docs/hydroflow_plus/aggregations.mdx b/docs/docs/hydroflow_plus/aggregations.mdx deleted file mode 100644 index 2951c1d097f5..000000000000 --- a/docs/docs/hydroflow_plus/aggregations.mdx +++ /dev/null @@ -1,40 +0,0 @@ ---- -sidebar_position: 4 ---- - -# Aggregations and Ticks -Hydroflow+ streams support aggregation operators such as `fold()`, which can be used to compute results that combine information from multiple elements along a stream. However, because Hydroflow+ streams are infinite, these operators have slightly different semantics than typical implementations. - -In particular, Hydroflow (and Hydroflow+) adhere to a _tick_ model of computation, where the stream is chunked into finite _ticks_ of data. At the beginning of each tick on each process (ticks are **not** synchronized), a batch of inputs are collected, the local dataflow graph is executed, and a batch of outputs are produced. This enables Hydroflow to support infinite streams while still being able to apply optimizations such as vectorization. - -## Specifying Windows -For most operators, such as `map` and `filter`, which operate on each element independently, the tick model is transparent. However, for operators that combine multiple elements, such as `fold`, the tick model is more visible. In particular, developers must explicitly specify whether they want aggregations such as `fold` or multi-stream operators such as `join` to operate over the latest batch of data or all data since the beginning of the stream. - -:::note - -Hydroflow+ tracks windows using the `W` type parameter on `Stream`. For streams with an unspecified window, this type will be `Async`, but with a window it will be `Windowed`. This guards against accidental aggregations since the type system will prevent you from aggregating over a stream with an `Async` window. - -::: - -To specify this **window**, Hydroflow+ offers two operators, `tick_batch()` and `all_ticks()`. The former specifies that the operator should operate over the latest batch of data, while the latter specifies that the operator should operate over all data since the beginning of the stream. - -For example, consider a pipelined aggregation across two processes. We can sum up elements on the first process in a batched manner using `tick_batch()`, then sum up the results on the second process in an unbounded manner using `all_ticks()`: - -```rust -let root_stream = process.source_stream(q!(1..=10)); -root_stream - .tick_batch() - .fold(q!(|| 0), q!(|acc, x| *acc += x)) - .send_bincode(&process2); - .all_ticks() - .fold(q!(|| 0), q!(|acc, x| acc + x)); -``` - -Note that Hydroflow+ streams are still unbounded! The `all_ticks()` operator does not wait until all elements are received, instead on each tick it will operate over all data since the beginning of the stream. - -So if we were to pass in inputs 1, 2, 3, we might get the following results on process 2: -``` -First Tick: 0 -Second Tick: (1 + 2) = 3 -Third Tick: (1 + 2) + (3) = 6 -``` diff --git a/docs/docs/hydroflow_plus/clusters.mdx b/docs/docs/hydroflow_plus/clusters.mdx deleted file mode 100644 index 5d742324c673..000000000000 --- a/docs/docs/hydroflow_plus/clusters.mdx +++ /dev/null @@ -1,89 +0,0 @@ ---- -sidebar_position: 3 ---- - -# Clusters -A key restriction of processes in Hydroflow+ is that there can only be one instance of the computation assigned to each process across the entire distributed system. This is fine for simple applications with only pipelined computation, but for scaling out we need the ability to have _multiple instances of the same computation_ running in parallel. - -Clusters solve this by providing an nearly-identical API to processes, but representing a **set of instances** running the same computation instead of a single one. What changes when using a cluster is sending data, since we need to specify _which_ instance(s) of the computation to send the data to. - -## Computing on Clusters -Instantiating clusters is done using the `cluster` method on `FlowBuilder`, taking a `ClusterSpec`: -```rust -pub fn my_flow<'a, D: Deploy<'a>>( - flow: &FlowBuilder<'a, D>, - cluster_spec: &impl ClusterSpec<'a, D> -) { - let cluster = flow.cluster(cluster_spec); -} -``` - -This API follows the same pattern as processes, where a cluster spec represents a _template_ for a cluster, which can be instantiated multiple times to create multiple clusters. - -Instantiating streams on clusters uses the same APIs as streams: `source_iter` and `source_stream` are both available. But when using these APIs, the root streams will be instantiated on _all_ instances in the cluster. - -```rust -let stream = cluster.source_iter(q!(vec![1, 2, 3])); - -stream.for_each(q!(|x| println!("{}", x))) -// will print 1, 2, 3 on **each** instance -``` - -## Sending Data -Because clusters represent a set of instances, adding networking requires us to specify _which_ instance(s) to send data to. Clusters provide different types depending on if the source or receiver is a cluster or a process. - -Elements in a cluster are identified by a **cluster ID** (a `ClusterId` where `C` is the typetag of the cluster). To get the IDs of all instances in a cluster, use the `members` method on cluster, which returns a runtime expression of type `&Vec>` (which can only be used inside `q!()` or as an argument to `source_iter`). All IDs always are ranging from 0 through the length of the IDs vector. - -This can then be passed into `source_iter` to load the IDs into the graph. -```rust -let stream = process.source_iter(cluster.members()).cloned(); -``` - -### One-to-Many -When sending data from a process to a cluster, the source must be a stream of tuples of the form `(ClusterId<_>, T)` and sends each `T` element to the instance with the matching ID. - -This is useful for partitioning data across instances. For example, we can partition a stream of elements in a round-robin fashion by using `enumerate` to add a sequence number to each element, then using `send_bincode` to send each element to the instance with the matching sequence number: -```rust -let cluster_ids = cluster.members(); -let stream = process.source_iter(q!(vec![123, 456, 789])) - .enumerate() - .map(q!(|(i, x)| ( - ClusterId::from_raw(i % cluster_ids.len() as u32), - x - ))) - .send_bincode(&cluster); -``` - -To broadcast data to all instances in a cluster, use `broadcast_{bincode,bytes}`, which acts as a shortcut for the cross product. - -```rust -let stream = process.source_iter(q!(vec![123, 456, 789])) - .broadcast_bincode(&cluster); -``` - -### Many-to-One -In the other direction, sending data from a cluster to a process, we have a stream of elements of type `T` at the sender but on the recipient side we get a stream of tuples of the form `(u32, T)`, where the `u32` is the ID of the instance that sent the element. The elements received from different instances will be interleaved. - -This is useful for aggregating data from multiple instances into a single stream. For example, we can use `send_bincode` to send data from all instances to a single process, and then print them all out: -```rust -let stream = cluster.source_iter(q!(vec![123, 456, 789])) - .send_bincode(&process) - .for_each(q!(|(id, x)| println!("{}: {}", id, x))); -``` - -If you don't care which instance sent the data, you can use `send_{bincode,bytes}_interleaved`, where the recipient receives a stream of `T` elements, but the elements received from different instances will be interleaved. -```rust -let stream = cluster.source_iter(q!(vec![123, 456, 789])) - .send_bincode_interleaved(&process) - .for_each(q!(|x| println!("{}", x))); -``` - -### Many-to-Many -Finally, when sending data from one cluster to another (or to itself as in distributed protocols), the source emits tuples of the form `(u32, T)` and sends each `T` element to the instance with the matching `u32` ID, but the recipient also gets `(u32, T)` tuples with the ID of the sender. - -We can use the same shortcuts as before. For example, we can use `broadcast_bincode_interleaved` to send data from all instances in a cluster to all instances in another cluster, and then print them all out: -```rust -let stream = cluster1.source_iter(q!(vec![123, 456, 789])) - .broadcast_bincode_interleaved(&cluster2) - .for_each(q!(|x| println!("{}", x))); -``` diff --git a/docs/docs/hydroflow_plus/cycles.mdx b/docs/docs/hydroflow_plus/cycles.mdx deleted file mode 100644 index 21d1b78fcf52..000000000000 --- a/docs/docs/hydroflow_plus/cycles.mdx +++ /dev/null @@ -1,32 +0,0 @@ ---- -sidebar_position: 5 ---- - -# Cycles -Hydroflow+ supports cyclic graphs, which are useful for iterative computations or patterns like heartbeats. - -Because streams are represented as values when constructing a Hydroflow+ graph, we can't directly create cycles since that would require a forward reference. Instead, Hydroflow+ offers an API to create a cycle by using a _placeholder_ stream, which is a stream that can be used as a placeholder for a stream that will be created later. - -We can create a cycle by using the `cycle` method on flow with a process or cluster. This returns a tuple of two values: a `HfCycle` value that can be used to complete the cycle later and the placeholder stream. - -```rust -let (complete_cycle, cycle_placeholder) = process.cycle(); -``` - -For example, consider the classic graph reachability problem, which computes the nodes reachable from a given set of roots in a directed graph. This can be modeled as an iterative fixpoint computation where we start with the roots, then repeatedly add the children of each node to the set of reachable nodes until we reach a fixpoint. - -In Hydroflow+, we can implement this using cycles: - -```rust -let roots = process.source_stream(roots); -let edges = process.source_stream(edges); - -let (complete_reached_nodes, reached_nodes) = process.cycle(); - -let reach_iteration = roots - .union(&reached_nodes) - .map(q!(|r| (r, ()))) - .join(&edges) - .map(q!(|(_from, (_, to))| to)); -complete_reached_nodes.complete(&reach_iteration); -``` diff --git a/docs/docs/hydroflow_plus/dataflow-programming.mdx b/docs/docs/hydroflow_plus/dataflow-programming.mdx new file mode 100644 index 000000000000..f88b2d389233 --- /dev/null +++ b/docs/docs/hydroflow_plus/dataflow-programming.mdx @@ -0,0 +1,13 @@ +--- +sidebar_position: 1 +--- + +# Dataflow Programming +Hydroflow+ uses a dataflow programming model, which will be familiar if you have used APIs like Rust iterators. Instead of using RPCs or async/await to describe distributed computation, Hydroflow+ instead uses **asynchronous streams**, which represent data arriving over time. Streams can represent a series of asynchronous events (e.g. inbound network requests) or a sequence of data items. + +Programs in Hydroflow+ describe how to **transform** entire collections of data using operators such as `map` (transforming elements one by one), `fold` (aggregating elements into a single value), or `join` (combining elements from multiple streams on matching keys). + +If you are familiar with Spark, Flink or Pandas, you will find Hydroflow+ syntax familiar. However, note well that the semantics for asynchronous streams in Hydroflow+ differ significantly from bulk analytics systems like those above. In particular, Hydroflow+ uses the type system to distinguish between bounded streams (originating from finite data) and unbounded streams (originated from asynchronous input). Moreover, Hydroflow+ is designed to handle asynchronous streams of small, independent events very efficiently. + + + diff --git a/docs/docs/hydroflow_plus/index.mdx b/docs/docs/hydroflow_plus/index.mdx index fe0edfd2bef4..c2ade3d3f6f3 100644 --- a/docs/docs/hydroflow_plus/index.mdx +++ b/docs/docs/hydroflow_plus/index.mdx @@ -3,26 +3,14 @@ sidebar_position: 0 --- # Introduction -Hydroflow+ layers a high-level Rust API over the Hydroflow IR, making it possible to write dataflow programs that span multiple processes with straightline, functional Rust code. Hydroflow+ is built on top of [Stageleft](./stageleft.mdx), which allows Hydroflow+ to emit regular Hydroflow programs that are compiled into efficient Rust binaries. It also integrates with [Hydro Deploy](../deploy/index.md) to make it easy to deploy and run Hydroflow+ programs on a cluster. +Hydroflow+ is a high-level distributed programming framework for Rust powered by the [Hydroflow runtime](../hydroflow/index.mdx). Unlike traditional architectures such as actors or RPCs, Hydroflow+ offers _choreographic_ APIs, where expressions and functions can describe computation that takes place across many locations. It also integrates with [Hydro Deploy](../deploy/index.md) to make it easy to deploy and run Hydroflow+ programs to the cloud. -The main logic of Hydroflow+ programs manipulates **streams**, which capture infinite ordered sequences of elements. Streams are transformed using classic functional operators such as `map`, `filter`, and `fold`, as well as relational operators such as `join`. To build **distributed** dataflow programs, Hydroflow+ also introduces the concept of **processes**, which capture _where_ a stream is being processed. +Hydroflow+ uses a two-stage compilation approach. HF+ programs are standard Rust programs, which first run on the developer's laptop to generate a _deployment plan_. This plan is then compiled to individual binaries for each machine in the distributed system (enabling zero-overhead abstractions), and are then deployed to the cloud using the generated plan along with specifications of cloud resources. -## Setup -Hydroflow+ requires a particular workspace setup, as any crate that uses Hydroflow+ must have an supporting macro crate to drive the code generation. To get started, we recommend using the Hydroflow+ template. +Hydroflow+ has been used to write a variety of high-performance distributed systems, including implementations of classic distributed protocols such as two-phase commit and Paxos. Work is ongoing to develop a distributed systems standard library that will offer these protocols and more as reusable components. -```bash -#shell-command-next-line -cargo install cargo-generate -#shell-command-next-line -cargo generate hydro-project/hydroflow template/hydroflow_plus -``` +:::caution -`cd` into the generated folder, ensure the correct nightly version of rust is installed, and test the generated project: -```bash -#shell-command-next-line -cd -#shell-command-next-line -rustup update -#shell-command-next-line -cargo test -``` +The docs for Hydroflow+ are still a work in progress. If you have any questions or run into bugs, please file an issue on the [Hydroflow GitHub repository](https://github.com/hydro-project/hydroflow). + +::: diff --git a/docs/docs/hydroflow_plus/process_streams.mdx b/docs/docs/hydroflow_plus/process_streams.mdx deleted file mode 100644 index 75559052b43a..000000000000 --- a/docs/docs/hydroflow_plus/process_streams.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Processes and Streams -Hydroflow+ involves two main concepts: -- **Processes**, which represent _where_ elements of a dataflow program are processed -- **Streams**, which define _what_ is being computed - -By combining the two, Hydroflow+ makes it possible to implement both low-level distributed protocols and high-level dataflow programs using the same API, all while supporting compile-time checks to guard against unexpected sources of nondeterminism. - -## Processes -Unlike most streaming systems, Hydroflow+ requires that all streams be associated with a particular **process**. A process is a logical unit of computation that can be deployed to a single machine. Processes are most closely related to _actors_ in actor-based systems, but use streaming operators rather than an imperative API. - -To create a process, we must take a `ProcessSpec` as an argument to our function. This trait abstracts over what the dataflow graph is being built for: compilation to a Rust binary or deployment. - -```rust -pub fn my_flow<'a, D: Deploy<'a>>( - flow: &FlowBuilder<'a, D>, - process_spec: &impl ProcessSpec<'a, D> -) { - ... -} -``` - -Process specs represent a _template_ for a process, which can be instantiated multiple times to create multiple processes. Multiple process specs can be useful to specify deployment characteristics for different sets of processes, such as deploying them to different cloud providers or regions. - -Instantiating a process from a process spec is done using the `process` method on `FlowBuilder`: - -```rust -let process = flow.process(process_spec); -``` - -## Streams -Streams are infinite ordered sequences of elements. They can be transformed using functional operators such as `map` and `filter`, relational operators such as `join`, and can be connected across processes using `send_to`. - -### Instantiating Streams -Root streams are created using methods available on an an instantiated process. - -#### `source_iter` -To create a stream from a Rust iterator, use `source_iter`. This is useful for loading static data into the graph. Each element of the iterator will be emitted _exactly once_ in the _first tick_ of execution (see [Aggregations and Ticks](./aggregations.mdx)). - -```rust -let stream = process.source_iter(q!(vec![1, 2, 3])); -``` - -#### `source_stream` -To create a stream from an asynchronous source, use `source_stream`. This takes any type that implements `futures::Stream` and emits each element as it is received. This is useful for loading data from external sources such as Kafka or a database. Typically, you will want to take the stream as a `RuntimeData` parameter to your function, and pass the stream in your runtime binary. - -```rust -pub fn my_flow<'a, D: Deploy<'a>>( - ..., - my_stream: RuntimeData> -) { - let stream = process.source_stream(my_stream); - ... -} -``` - -### Sending Streams between Processes -To send a stream from one process to another, use the `send_*` methods on the source stream. This takes a parameter of the process to send the data to. - -If sending a type that supports serialization using `serde`, use `send_bincode`, which uses the `bincode` crate to serialize the data. - -```rust -let process0 = flow.process(process_spec); -let process1 = flow.process(process_spec); - -let stream0 = process0.source_iter(...); -let stream1 = stream0.send_bincode(&process1); -``` - -To use custom serializers, you can use the `send_bytes` method to send a stream of `Bytes` values. - -```rust -let stream0 = process0.source_iter(...); -let stream1 = stream0.send_bytes(&process1); -``` diff --git a/docs/docs/hydroflow_plus/quickstart/_category_.json b/docs/docs/hydroflow_plus/quickstart/_category_.json index db70db116681..20b00e5064e9 100644 --- a/docs/docs/hydroflow_plus/quickstart/_category_.json +++ b/docs/docs/hydroflow_plus/quickstart/_category_.json @@ -1,6 +1,6 @@ { "label": "Quickstart", - "position": 1, + "position": 2, "link": { "type": "doc", "id": "hydroflow_plus/quickstart/index" diff --git a/docs/docs/hydroflow_plus/quickstart/clusters.mdx b/docs/docs/hydroflow_plus/quickstart/clusters.mdx index 4155c13e68a0..85ccee8c57df 100644 --- a/docs/docs/hydroflow_plus/quickstart/clusters.mdx +++ b/docs/docs/hydroflow_plus/quickstart/clusters.mdx @@ -1,93 +1,73 @@ --- sidebar_position: 3 --- +import CodeBlock from '@theme/CodeBlock'; +import firstTenClusterSrc from '!!raw-loader!../../../../template/hydroflow_plus/src/first_ten_cluster.rs'; +import firstTenClusterExample from '!!raw-loader!../../../../template/hydroflow_plus/examples/first_ten_cluster.rs'; +import { getLines, highlightLines, extractOutput } from '../../../src/util'; # Scaling with Clusters -So far, we have looked at distributed systems where there is a single process running each piece of the compute graph -- **compute parallelism** (like pipelining). However, we can also use Hydroflow+ to run the same computation on multiple processes -- achieving **data parallelism** (like replication and partitioning). This is done by creating a **cluster** of processes that all run the same subgraph. +So far, we have looked at distributed systems where each process is running a different piece of the compute graph -- **compute parallelism**. However, we can also use Hydroflow+ to run the same computation on multiple processes -- achieving **data parallelism** (e.g. partitioning). This is done by creating a **cluster** of processes that all run the same subgraph of code. -## Creating Clusters -Just like we use `ProcessSpec` to create processes, we use `ClusterSpec` to create clusters. We can then use the `flow.cluster(spec)` method to instantiate a cluster in our graph. Let's create a simple application where a leader process broadcasts data to a cluster of workers. +## Dataflow with Clusters +Just like we use the `Process` type to represent a virtual handle to a single node, we can use the **`Cluster`** type to represent a handle to a **set of nodes** (with size unknown at compile-time). -We start with the standard architecture, with a flow graph and a runtime entrypoint, but now take a cluster spec in addition to a process spec. +A `Stream` located on a `Cluster` can be thought of as SIMD-style programming, where each cluster member executes the same operators but on different pieces of data. -:::tip +To start, we set up a new module in `src/first_ten_cluster.rs` with a dataflow program that takes in a `Process` for a leader and `Cluster` for a set of workers. -If you have been following along with the Hydroflow+ template, you'll now need to declare a new module for this example. Create a new file at `src/broadcast.rs` and add the following to `src/lib.rs`: - -```rust title="src/lib.rs" -pub mod broadcast; -``` - -::: +{getLines(firstTenClusterSrc, 1, 6)} +We start by materializing a stream of numbers on the `leader`, as before. But rather than sending the stream to a single process, we will instead _distribute_ the data to each member of the cluster using `round_robin_bincode`. This API places data on a `cluster` in a round-robin fashion by using the order of elements to determine which cluster member each element is sent to. -```rust title="src/broadcast.rs" -use hydroflow_plus::*; -use stageleft::*; +:::info -pub struct Leader {} -pub struct Workers {} - -pub fn broadcast( - flow: &FlowBuilder, -) -> (Process, Cluster) { - let leader = flow.process(); - let workers = flow.cluster(); - - // ... - - (leader, workers) -} -``` +There are a [variety of APIs](pathname:///rustdoc/hydroflow_plus/stream/struct.Stream.html#impl-Stream%3CT,+L,+B%3E-2) for sending data to and receiving data from clusters. For example, we `broadcast_bincode` to send copies to all members (e.g. for replication), or use `send_bincode` if we have a custom partitioning algorithm. -## Broadcasting Data -When sending data between individual processes, we used the `send_bincode` operator. When sending data from a process to a cluster, we can use the `broadcast_bincode` operator instead. - -```rust -let data = leader.source_iter(q!(0..10)); -data - .broadcast_bincode(&workers) - .for_each(q!(|n| println!("{}", n))); -``` - -The `Stream` returned by `broadcast_bincode` represents the data received on _each_ process in the cluster. Because all processes in a cluster run the exact same computation, we can then use the `for_each` operator directly on that stream to print the data on each process. - -## Deploying Graphs with Clusters -To deploy this application, we must set up the Hydro Deploy configuration as before. Our deployment script (`examples/broadcast.rs`) instantiates multiple services for the leader process and the workers. Since this script defines the physical deployment, we explicitly instantiate multiple services for the cluster spec, returning a `Vec` of services. We also set a display name for each service so that we can tell them apart in the logs. +::: -```rust title="examples/broadcast.rs" -use std::cell::RefCell; +{getLines(firstTenClusterSrc, 7, 9)} -use hydro_deploy::{Deployment, HydroflowCrate}; -use hydroflow_plus::deploy::TrybuildHost; +On each cluster member, we will then do some work to transform the data (using `map`) and log the transformed values locally (using `inspect`, which is useful for debugging). -#[tokio::main] -async fn main() { - let mut deployment = Deployment::new(); +{getLines(firstTenClusterSrc, 10, 11)} - let builder = hydroflow_plus::FlowBuilder::new(); - let (leader, workers) = flow::broadcast::broadcast(&builder); +Finally, we will send the data back to the leader. We achieve this using a variant of the APIs from before: `send_bincode_interleaved`. If we used `send_bincode`, we would get a stream of (cluster ID, data) tuples. Since it is a common pattern to ignore the IDs, `send_bincode_interleaved` is available as a helper. - flow.with_default_optimize() - .with_process(&leader, TrybuildHost::new(deployment.Localhost())) - .with_cluster(&workers, (0..2) - .map(|idx| TrybuildHost::new(deployment.Localhost())) - .collect::>() - ) - .deploy(&mut deployment); +{getLines(firstTenClusterSrc, 12, 14)} - deployment.run_ctrl_c().await.unwrap(); -} -``` +## Deploying Clusters +Deployment scripts are similar to before, except that when provisioning a cluster we provide a list of deployment hosts rather than a single one. In our example, we'll launch 4 nodes for the cluster by creating a `Vec` of 4 localhost instances. -If we run this script, we should see the following output: +{highlightLines(firstTenClusterExample, [14])} +We can then launch the program: ```bash #shell-command-next-line -cargo run --example broadcast -[worker/0] 0 -[worker/1] 0 -[worker/0] 1 -[worker/1] 1 -... +cargo run --example first_ten_cluster +#highlight-next-line +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 0] 0 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 2] 4 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 2] 12 +#highlight-next-line +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 0] 8 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 3] 6 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 1] 2 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 1] 10 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 1] 18 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 0 +#highlight-next-line +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 0] 16 +[hydroflow_plus_template::first_ten_cluster::Worker (cluster 1) / 3] 14 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 8 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 16 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 2 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 10 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 18 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 4 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 12 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 6 +[hydroflow_plus_template::first_ten_cluster::Leader (process 0)] 14 ``` + +You'll notice the round-robin distribution in action here, as each cluster log is tagged with the ID of the member (e.g. `/ 0`). In our deployment, we are sending data round-robin across 4 members of the cluster, numbered `0` through `3`. Hence cluster member `0` receives values `0`, `4`, `8` (corresponding to the highlighted lines), member `1` receives values `1`, `5`, `9`, and so on. diff --git a/docs/docs/hydroflow_plus/quickstart/distributed.mdx b/docs/docs/hydroflow_plus/quickstart/distributed.mdx index a8ae364060bd..4b958cd52c86 100644 --- a/docs/docs/hydroflow_plus/quickstart/distributed.mdx +++ b/docs/docs/hydroflow_plus/quickstart/distributed.mdx @@ -7,29 +7,79 @@ import firstTenDistExample from '!!raw-loader!../../../../template/hydroflow_plu import { getLines, extractOutput } from '../../../src/util'; # Adding Distribution -Continuing from our previous example, we will now look at how to deploy our program to run on multiple processes. +Continuing from our previous example, we will now look at how to deploy our program to run on two processes. -We achieve this by using [Hydro Deploy](../../deploy/index.md). Hydroflow+ integrates with Hydro Deploy to automatically construct the topology based on the flow graph. We can create a new file `examples/first_ten_distributed.rs` with the following contents: +We'll start by updating our dataflow function signature to take two processes (in a new file, `src/first_ten_distributed.rs`). At this point, we'll need to add a lifetime parameter `'a` which represents the lifetime of data referenced by our dataflow logic. This lifetime needs to be the same across all the processes, so it can't be elided. + + +```rust title="src/first_ten_distributed.rs" +use hydroflow_plus::*; + +pub fn first_ten_distributed<'a>(p1: &Process<'a>, p2: &Process<'a>) +``` + +:::info + +The Hydroflow+ template only contains the final version of this program. In order to follow along with the tutorial, we recommend overwriting `src/first_ten_distributed.rs` according to the following snippets. + +::: + +Now, we'll use a new API, `send_bincode` to establish a network between our processes (`bincode` is the serialization format we are using). Given a stream on process `p1`, we can send the data to `p2` by calling `.send_bincode(p2)`, which returns a stream on `p2`. So to make our program distributed, it only takes a single line change. + +```rust title="src/first_ten_distributed.rs" +pub fn first_ten_distributed<'a>(p1: &Process<'a>, p2: &Process<'a>) { + p1.source_iter(q!(0..10)) + // highlight-next-line + .send_bincode(p2) + .for_each(q!(|n| println!("{}", n))); +} +``` + +Then, we can update our deployment script to launch both processes on localhost. Hydro Deploy will automatically handle service discovery and networking, since it knows the full network topology. {firstTenDistExample} -Most importantly, we specify a `DeployProcessSpec`, which constructs a Hydro Deploy service for each process in the flow graph. In our case, we use the `TrybuildHost` service type, which compiles and deploys a Hydroflow+ graph. +We can then launch the program: +```bash +#shell-command-next-line +cargo run --example first_ten_distributed +[() (process 1)] 0 +[() (process 1)] 1 +[() (process 1)] 2 +[() (process 1)] 3 +[() (process 1)] 4 +[() (process 1)] 5 +[() (process 1)] 6 +[() (process 1)] 7 +[() (process 1)] 8 +[() (process 1)] 9 +``` + +You'll notice that our logs are not particularly descriptive, just showing `()` as an identifier. Furthermore, our processes have the same Rust type, which could lead to accidentally mixing up streams across the machines (this will throw an exception, but it would be nice to have a compile error). + +To fix this, we can use the optional type parameter on `Process`, which lets us add a "type tag" that acts as an identifier. We'll define two structs to act as these tags and use them in the function signature: + +{getLines(firstTenDistSrc, 3, 10)} + +:::info + +This is the final version of our dataflow which you will find in the Hydroflow+ template. -We can then run our distributed dataflow with: +::: -<>{/* TODO(mingwei): grab this output from a tested snapshot file */} +If you are using an IDE extension like [Rust Analyzer](https://rust-analyzer.github.io/), you'll see these types attached to each stream. And if we launch the program again, we'll see much better logs: ```bash #shell-command-next-line cargo run --example first_ten_distributed -[service/1] 0 -[service/1] 1 -[service/1] 2 -[service/1] 3 -[service/1] 4 -[service/1] 5 -[service/1] 6 -[service/1] 7 -[service/1] 8 -[service/1] 9 +[first_ten_distributed::P2 (process 1)] 0 +[first_ten_distributed::P2 (process 1)] 1 +[first_ten_distributed::P2 (process 1)] 2 +[first_ten_distributed::P2 (process 1)] 3 +[first_ten_distributed::P2 (process 1)] 4 +[first_ten_distributed::P2 (process 1)] 5 +[first_ten_distributed::P2 (process 1)] 6 +[first_ten_distributed::P2 (process 1)] 7 +[first_ten_distributed::P2 (process 1)] 8 +[first_ten_distributed::P2 (process 1)] 9 ``` diff --git a/docs/docs/hydroflow_plus/quickstart/first-dataflow.mdx b/docs/docs/hydroflow_plus/quickstart/first-dataflow.mdx new file mode 100644 index 000000000000..75ca4a9f5552 --- /dev/null +++ b/docs/docs/hydroflow_plus/quickstart/first-dataflow.mdx @@ -0,0 +1,78 @@ +--- +sidebar_position: 1 +--- + +import CodeBlock from '@theme/CodeBlock'; +import firstTenSrc from '!!raw-loader!../../../../template/hydroflow_plus/src/first_ten.rs'; +import firstTenExampleSrc from '!!raw-loader!../../../../template/hydroflow_plus/examples/first_ten.rs'; +import { getLines, extractOutput } from '../../../src/util'; + +# Your First Dataflow +Let's look a minimal example of a Hydroflow+ program. We'll start with a simple dataflow that prints out the first 10 natural numbers. + +:::tip + +We recommend using the Hydroflow+ template to get started with a new project: + +```bash +#shell-command-next-line +cargo install cargo-generate +#shell-command-next-line +cargo generate gh:hydro-project/hydroflow template/hydroflow_plus +``` + +::: + +## Writing a Dataflow +In Hydroflow+, streams are attached to a **location**, which is either a virtual handle to a **single machine** (the **`Process`** type) or **set of machines** (the **`Cluster`** type). A single piece of Hydroflow+ code can describe a distributed program that runs across multiple processes and clusters, each with their own local state and data. + +We'll write our first dataflow in `src/first_ten.rs`. This program will run on a single machine, so we take a single `&Process` parameter. We can materialize a stream on this machine using `process.source_iter` (which emits values from a static in-memory collection), and then print out the values using `for_each`. + +{firstTenSrc} + +:::caution + +You'll notice that the arguments to `source_iter` and `for_each` are wrapped in `q!` macros. The top-level Hydroflow+ program (`first_ten`) is responsible for setting up the dataflow structure, whereas the `q!` macro is used to mark the Rust code that will be executed at **runtime**. Generally, runtime code in a `q!` macro is a snippet of Rust code that defines a static source of data or a closure. + +If you forget to wrap a block in `q!` when that is required, you'll see an error like: +``` +closure is expected to take 5 arguments, but it takes X arguments +``` + +::: + +## Running the Dataflow +To run a Hydroflow+ program, we need to write some deployment configuration in `examples/first_ten.rs`. + +:::tip + +When using Hydroflow+, we will *always* place our deployment scripts in the `examples` directory. This is required because deployment is done via [Hydro Deploy](../../deploy/index.md) which is a _dev dependency_---i.e. not part of the dependencies used for generating binaries (but available to programs in the `examples` directory). + +::: + +{firstTenExampleSrc} + +First, we initialize a new [Hydro Deploy](../../deploy/index.md) deployment with `Deployment::new()`. Then, we create a `FlowBuilder` which will store the entire dataflow program and manage its compilation. + +To create a `Process`, we call `flow.process()`. After the dataflow has been created (by invoking the `hydroflow_plus_template::first_ten::first_ten` function we created earlier), we must map each instantiated `Process` to a deployment target using `flow.with_process` (in this case we deploy to localhost). + +Finally, we call `flow.deploy(&mut deployment)` to provision the dataflow program on the target machine. This returns a struct with handles to the instantiated machines, which we must store in the `_nodes` variable to prevent them from being dropped. Then, we can start the dataflow program and block until `Ctrl-C` using `deployment.run_ctrl_c()`. + +We can then launch the program using the following command: + +```bash +#shell-command-next-line +cargo run --example first_ten +[() (process 0)] 0 +[() (process 0)] 1 +[() (process 0)] 2 +[() (process 0)] 3 +[() (process 0)] 4 +[() (process 0)] 5 +[() (process 0)] 6 +[() (process 0)] 7 +[() (process 0)] 8 +[() (process 0)] 9 +``` + +In the next section, we will look at how to distribute this program across multiple processes. diff --git a/docs/docs/hydroflow_plus/quickstart/index.mdx b/docs/docs/hydroflow_plus/quickstart/index.mdx index d366e2f61046..c53a66903f61 100644 --- a/docs/docs/hydroflow_plus/quickstart/index.mdx +++ b/docs/docs/hydroflow_plus/quickstart/index.mdx @@ -1,7 +1,23 @@ # Quickstart In this tutorial, we'll walk through the basics of Hydroflow+ by building a simple dataflow that prints out the first 10 natural numbers. We'll start with a single process, then pipeline the computation, and finally distribute it across a cluster. -To get started with a new project, we'll use the Hydroflow+ template. The template comes with a pre-configured build system and an implementation of the following examples. +:::tip + +First you will need to install Rust. We recommend the conventional installation +method, `rustup`, which allows you to easily manage and update Rust versions: [**Install Rust**](https://www.rust-lang.org/tools/install) + +The link in the previous line will take you to the Rust website that shows you how to +install `rustup` and the Rust package manager `cargo` (and the +internally-used `rustc` compiler). `cargo` is Rust's main development tool, +used for building, running, and testing Rust code. + +We recommend using VS Code with the `rust-analyzer` extension (and NOT the +`Rust` extension). + +::: + +## Getting Started with Hydroflow+ +To get started with a new project, we'll use the Hydroflow+ template. The template comes with a simple distributed program. ```bash #shell-command-next-line @@ -13,10 +29,8 @@ cargo generate gh:hydro-project/hydroflow template/hydroflow_plus cd my-example-project ``` -After `cd`ing into the generated folder, ensure the correct nightly version of rust is installed and test the generated project: +After `cd`ing into the generated folder, we can run tests for the included sample: ```bash #shell-command-next-line -rustup update -#shell-command-next-line cargo test -``` \ No newline at end of file +``` diff --git a/docs/docs/hydroflow_plus/quickstart/structure.mdx b/docs/docs/hydroflow_plus/quickstart/structure.mdx deleted file mode 100644 index 54c13f1588a0..000000000000 --- a/docs/docs/hydroflow_plus/quickstart/structure.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -sidebar_position: 1 ---- -import CodeBlock from '@theme/CodeBlock'; -import firstTenSrc from '!!raw-loader!../../../../template/hydroflow_plus/src/first_ten_distributed.rs'; -import { getLines, extractOutput } from '../../../src/util'; - -# Your First Dataflow -Hydroflow+ programs require special structure to support code generation and distributed deployments. There are two main components of a Hydroflow+ program: -- The **flow graph** describes the dataflow logic of the program. -- The **deployment** describes how to map the flow graph to a physical deployment. - -:::tip - -We recommend using the Hydroflow+ template to get started with a new project. The template comes with a pre-configured build system and the following example pre-implemented. - -```bash -#shell-command-next-line -cargo install cargo-generate -#shell-command-next-line -cargo generate gh:hydro-project/hydroflow template/hydroflow_plus -``` - -`cd` into the generated folder, ensure the correct nightly version of rust is installed, and test the generated project: -```bash -#shell-command-next-line -cd -#shell-command-next-line -rustup update -#shell-command-next-line -cargo test -``` - -::: - - -Let's look a minimal example of a Hydroflow+ program. We'll start with a simple flow graph that prints out the first 10 natural numbers. First, we'll define the **flow graph**. - - -## The Flow Graph - -{getLines(firstTenSrc, 1, 17)} - -To build a Hydroflow+ application, we need to define a dataflow that spans multiple processes. The `FlowBuilder` parameter captures the global dataflow, and we can instantiate processes to define boundaries between distributed logic. When defining a process, we also pass in a type parameter to a "tag" that identifies the process. When transforming streams, the Rust type system will guarantee that we are operating on streams on the same process. - -{getLines(firstTenSrc, 8, 9)} - -Now, we can build out the dataflow to run on this process. Every dataflow starts at a source that is bound to a specific process. First, we instantiate a stream that emits the first 10 natural numbers. - -{getLines(firstTenSrc, 11)} - -In Hydroflow+, whenever there are snippets of Rust code passed to operators (like `source_iter`, `map`, or `for_each`), we use the `q!` macro to mark them. For example, we may use Rust snippets to define static sources of data or closures that transform them. - -To print out these numbers, we can use the `for_each` operator (note that the body of `for_each` is a closure wrapped in `q!`): - -{getLines(firstTenSrc, 12, 14)} - -In the next section, we will look at how to deploy this program to run on multiple processs. diff --git a/docs/docs/hydroflow_plus/stageleft.mdx b/docs/docs/hydroflow_plus/stageleft.mdx index f2a4ef062ce2..e4ac5014c9e8 100644 --- a/docs/docs/hydroflow_plus/stageleft.mdx +++ b/docs/docs/hydroflow_plus/stageleft.mdx @@ -1,8 +1,10 @@ --- title: Stageleft -sidebar_position: 6 +sidebar_position: 3 --- import StageleftDocs from '../../../stageleft/README.md' +Under the hood, Hydroflow+ uses a library called Stageleft to power the `q!` macro and code generation logic. The following docs, from the Stageleft README, outline the core architecture of Stageleft. + diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 6ce7eea1c1be..846e3e20dd41 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -1,8 +1,8 @@ // @ts-check // Note: type annotations allow type checking and IDEs autocompletion -const lightCodeTheme = require('prism-react-renderer/themes/github'); -const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const lightCodeTheme = require('prism-react-renderer').themes.github; +const darkCodeTheme = require('prism-react-renderer').themes.dracula; const math = require('remark-math'); const katex = require('rehype-katex'); @@ -132,6 +132,10 @@ const config = { type: 'docSidebar', sidebarId: 'deploySidebar', label: 'Hydro Deploy', + }, + { + href: 'pathname:///rustdoc/hydroflow/', + label: 'Rustdoc', } ] }, @@ -210,7 +214,7 @@ const config = { prism: { theme: lightCodeTheme, darkTheme: darkCodeTheme, - additionalLanguages: ['rust'], + additionalLanguages: ['rust', 'bash'], magicComments: [ { className: 'theme-code-block-highlighted-line', diff --git a/docs/package-lock.json b/docs/package-lock.json index e5db154843e3..046e857f96dd 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,27 +8,27 @@ "name": "docs", "version": "0.0.0", "dependencies": { - "@docusaurus/core": "^2.4.3", - "@docusaurus/plugin-ideal-image": "^2.4.3", - "@docusaurus/preset-classic": "^2.4.3", - "@docusaurus/theme-mermaid": "^2.4.3", - "@mdx-js/react": "^1.6.22", + "@docusaurus/core": "^3.6.1", + "@docusaurus/plugin-ideal-image": "^3.6.1", + "@docusaurus/preset-classic": "^3.6.1", + "@docusaurus/theme-mermaid": "^3.6.1", + "@mdx-js/react": "^3.1.0", "@monaco-editor/react": "^4.4.6", - "mermaid": "^9.3.0", - "prism-react-renderer": "^1.3.5", + "mermaid": "^11.4.0", + "prism-react-renderer": "^2.4.0", "raw-loader": "^4.0.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-katex": "^3.0.1", - "rehype-katex": "^5.0.0", - "remark-math": "^3.0.1", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "website_playground": "file:../website_playground/pkg" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^2.4.3" + "@docusaurus/module-type-aliases": "^3.6.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } }, "../website_playground/pkg": { @@ -36,34 +36,31 @@ "version": "0.0.0" }, "node_modules/@algolia/autocomplete-core": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", - "license": "MIT", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.6.tgz", + "integrity": "sha512-lkDoW4I7h2kKlIgf3pUt1LqvxyYKkVyiypoGLlUnhPSnCpmeOwudM6rNq6YYsCmdQtnDQoW5lUNNuj6ASg3qeg==", "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-plugin-algolia-insights": "1.17.6", + "@algolia/autocomplete-shared": "1.17.6" } }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", - "license": "MIT", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.6.tgz", + "integrity": "sha512-17NnaacuFzSWVuZu4NKzVeaFIe9Abpw8w+/gjc7xhZFtqj+GadufzodIdchwiB2eM2cDdiR3icW7gbNTB3K2YA==", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.6" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", - "license": "MIT", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.6.tgz", + "integrity": "sha512-Cvg5JENdSCMuClwhJ1ON1/jSuojaYMiUW2KePm18IkdCzPJj/NXojaOxw58RFtQFpJgfVW8h2E8mEoDtLlMdeA==", "dependencies": { - "@algolia/autocomplete-shared": "1.9.3" + "@algolia/autocomplete-shared": "1.17.6" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -71,10 +68,9 @@ } }, "node_modules/@algolia/autocomplete-shared": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", - "license": "MIT", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.6.tgz", + "integrity": "sha512-aq/3V9E00Tw2GC/PqgyPGXtqJUlVc17v4cn1EUhSc+O/4zd04Uwb3UmPm8KDaYQQOrkt1lwvCj2vG2wRE5IKhw==", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" @@ -84,7 +80,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz", "integrity": "sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==", - "license": "MIT", "dependencies": { "@algolia/cache-common": "4.24.0" } @@ -92,23 +87,34 @@ "node_modules/@algolia/cache-common": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.24.0.tgz", - "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==", - "license": "MIT" + "integrity": "sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==" }, "node_modules/@algolia/cache-in-memory": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz", "integrity": "sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==", - "license": "MIT", "dependencies": { "@algolia/cache-common": "4.24.0" } }, + "node_modules/@algolia/client-abtesting": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.13.0.tgz", + "integrity": "sha512-6CoQjlMi1pmQYMQO8tXfuGxSPf6iKX5FP9MuMe6IWmvC81wwTvOehnwchyBl2wuPVhcw2Ar53K53mQ60DAC64g==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/client-account": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.24.0.tgz", "integrity": "sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/client-search": "4.24.0", @@ -119,7 +125,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0", "@algolia/transporter": "4.24.0" @@ -129,7 +134,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/requester-common": "4.24.0", @@ -140,7 +144,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.24.0.tgz", "integrity": "sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/client-search": "4.24.0", @@ -152,7 +155,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0", "@algolia/transporter": "4.24.0" @@ -162,7 +164,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/requester-common": "4.24.0", @@ -170,11 +171,23 @@ } }, "node_modules/@algolia/client-common": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.2.5.tgz", - "integrity": "sha512-ITE85veJWwClnoNyv7Zydh9U0eKA82cDy8pLw+2hzL+zlzFIvV68ihGOEQ/kXt8N4v+R4MFzvsxnIpMruQzEug==", - "license": "MIT", - "peer": true, + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.13.0.tgz", + "integrity": "sha512-2SP6bGGWOTN920MLZv8s7yIR3OqY03vEe4U+vb2MGdL8a/8EQznF3L/nTC/rGf/hvEfZlX2tGFxPJaF2waravg==", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.13.0.tgz", + "integrity": "sha512-ldHTe+LVgC6L4Wr6doAQQ7Ku0jAdhaaPg1T+IHzmmiRZb2Uq5OsjW2yC65JifOmzPCiMkIZE2mGRpWgkn5ktlw==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, "engines": { "node": ">= 14.0.0" } @@ -183,7 +196,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.24.0.tgz", "integrity": "sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/requester-common": "4.24.0", @@ -194,22 +206,34 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0", "@algolia/transporter": "4.24.0" } }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.13.0.tgz", + "integrity": "sha512-pYo0jbLUtPDN1r341UHTaF2fgN5rbaZfDZqjPRKPM+FRlRmxFxqFQm1UUfpkSUWYGn7lECwDpbKYiKUf81MTwA==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/client-search": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.2.5.tgz", - "integrity": "sha512-OVDLzm5BEUbJmjfMm7b0Xx8vkK+NyEh7whPHuap2qy0x7RxQDLMXjiKsBbt1WNq+9nfX6+M/f2t0CJ8ENVuyYQ==", - "license": "MIT", - "peer": true, + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.13.0.tgz", + "integrity": "sha512-s2ge3uZ6Zg2sPSFibqijgEYsuorxcc8KVHg3I95nOPHvFHdnBtSHymhZvq4sp/fu8ijt/Y8jLwkuqm5myn+2Sg==", "dependencies": { - "@algolia/client-common": "5.2.5", - "@algolia/requester-browser-xhr": "5.2.5", - "@algolia/requester-node-http": "5.2.5" + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -218,29 +242,53 @@ "node_modules/@algolia/events": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", - "license": "MIT" + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, + "node_modules/@algolia/ingestion": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.13.0.tgz", + "integrity": "sha512-fm5LEOe4FPDOc1D+M9stEs8hfcdmbdD+pt9og5shql6ueTZJANDbFoQhDOpiPJizR/ps1GwmjkWfUEywx3sV+Q==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/@algolia/logger-common": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.24.0.tgz", - "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==", - "license": "MIT" + "integrity": "sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==" }, "node_modules/@algolia/logger-console": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.24.0.tgz", "integrity": "sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==", - "license": "MIT", "dependencies": { "@algolia/logger-common": "4.24.0" } }, + "node_modules/@algolia/monitoring": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.13.0.tgz", + "integrity": "sha512-e8Hshlnm2G5fapyUgWTBwhJ22yXcnLtPC4LWZKx7KOvv35GcdoHtlUBX94I/sWCJLraUr65JvR8qOo3LXC43dg==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/@algolia/recommend": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-4.24.0.tgz", "integrity": "sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==", - "license": "MIT", "dependencies": { "@algolia/cache-browser-local-storage": "4.24.0", "@algolia/cache-common": "4.24.0", @@ -259,7 +307,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0", "@algolia/transporter": "4.24.0" @@ -269,7 +316,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/requester-common": "4.24.0", @@ -280,7 +326,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0" } @@ -289,19 +334,16 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.2.5.tgz", - "integrity": "sha512-Ri73PphNy1ceig94xJW9bPdN7uIYFAjpsABpp2Fsun4DmeZD5a4rMCNwwOXXsbC8h+lUzW34zpUf+h4Nk+eaqA==", - "license": "MIT", - "peer": true, + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.13.0.tgz", + "integrity": "sha512-NV6oSCt5lFuzfsVQoSBpewEWf/h4ySr7pv2bfwu9yF/jc/g39pig8+YpuqsxlRWBm/lTGVA2V0Ai9ySwrNumIA==", "dependencies": { - "@algolia/client-common": "5.2.5" + "@algolia/client-common": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -310,17 +352,25 @@ "node_modules/@algolia/requester-common": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.24.0.tgz", - "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==", - "license": "MIT" + "integrity": "sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==" + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.13.0.tgz", + "integrity": "sha512-094bK4rumf+rXJazxv3mq6eKRM0ep5AxIo8T0YmOdldswQt79apeufFiPLN19nHEWH22xR2FelimD+T/wRSP+Q==", + "dependencies": { + "@algolia/client-common": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } }, "node_modules/@algolia/requester-node-http": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.2.5.tgz", - "integrity": "sha512-/tTdEuWcWHSe/mGMomWkuaFDoRcpfl/jvGISVTPRq3pJvM1FPAzxlh2MXge6C30aUS9bxh3V0aWwgKFCilzyMQ==", - "license": "MIT", - "peer": true, + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.13.0.tgz", + "integrity": "sha512-JY5xhEYMgki53Wm+A6R2jUpOUdD0zZnBq+PC5R1TGMNOYL1s6JjDrJeMsvaI2YWxYMUSoCnRoltN/yf9RI8n3A==", "dependencies": { - "@algolia/client-common": "5.2.5" + "@algolia/client-common": "5.13.0" }, "engines": { "node": ">= 14.0.0" @@ -330,7 +380,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.24.0.tgz", "integrity": "sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==", - "license": "MIT", "dependencies": { "@algolia/cache-common": "4.24.0", "@algolia/logger-common": "4.24.0", @@ -338,24 +387,44 @@ } }, "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "dependencies": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "license": "MIT", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", "picocolors": "^1.0.0" }, "engines": { @@ -363,33 +432,33 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.21.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.7.tgz", - "integrity": "sha512-KYMqFYTaenzMK4yUtf4EW9wc4N9ef80FsbMtkwool5zpwl4YrT1SdWYSTRcT94KO4hannogdS+LxY7L+arP3gA==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.8.tgz", - "integrity": "sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helpers": "^7.21.5", - "@babel/parser": "^7.21.8", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -403,89 +472,83 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", - "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", - "license": "MIT", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dependencies": { - "@babel/types": "^7.25.6", + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.21.5.tgz", - "integrity": "sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", "dependencies": { - "@babel/types": "^7.21.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.5.tgz", - "integrity": "sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.8.tgz", - "integrity": "sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-member-expression-to-functions": "^7.21.5", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.21.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/helper-split-export-declaration": "^7.18.6", - "semver": "^6.3.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -498,19 +561,18 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.21.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.8.tgz", - "integrity": "sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.3.1", - "semver": "^6.3.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -523,135 +585,92 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", - "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz", + "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", "dependencies": { - "@babel/helper-compilation-targets": "^7.17.7", - "@babel/helper-plugin-utils": "^7.16.7", + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2", - "semver": "^6.1.2" + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.21.5.tgz", - "integrity": "sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", - "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.5.tgz", - "integrity": "sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dependencies": { - "@babel/types": "^7.21.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.5.tgz", - "integrity": "sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dependencies": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-simple-access": "^7.21.5", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", - "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.21.5.tgz", - "integrity": "sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", - "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-wrap-function": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -661,214 +680,143 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.21.5.tgz", - "integrity": "sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dependencies": { - "@babel/helper-environment-visitor": "^7.21.5", - "@babel/helper-member-expression-to-functions": "^7.21.5", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.21.5.tgz", - "integrity": "sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", "dependencies": { - "@babel/types": "^7.21.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", - "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", - "dependencies": { - "@babel/types": "^7.20.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", - "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dependencies": { - "@babel/helper-function-name": "^7.19.0", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.5.tgz", - "integrity": "sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.5", - "@babel/types": "^7.21.5" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "license": "MIT", + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "license": "MIT", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" + "node": ">=6.9.0" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", - "license": "MIT", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dependencies": { - "@babel/types": "^7.25.6" - }, - "bin": { - "parser": "bin/babel-parser.js" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", - "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -878,13 +826,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", - "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-proposal-optional-chaining": "^7.20.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -893,31 +841,25 @@ "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-async-generator-functions": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", - "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "engines": { "node": ">=6.9.0" }, @@ -925,29 +867,23 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-class-static-block": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", - "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { - "@babel/core": "^7.12.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-dynamic-import": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", - "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -956,13 +892,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-export-namespace-from": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", - "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -971,13 +906,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-json-strings": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", - "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -986,13 +920,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", - "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1001,28 +934,27 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1031,16 +963,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1049,13 +979,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-optional-catch-binding": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", - "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1064,14 +995,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1080,13 +1009,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1095,15 +1023,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", - "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1112,49 +1038,61 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.12.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "node_modules/@babel/plugin-transform-classes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1163,70 +1101,85 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", - "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1235,120 +1188,85 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.21.5.tgz", - "integrity": "sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1357,14 +1275,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", - "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dependencies": { - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-remap-async-to-generator": "^7.18.9" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1373,12 +1290,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", - "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1387,34 +1306,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", - "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", - "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.21.0", - "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-replace-supers": "^7.20.7", - "@babel/helper-split-export-declaration": "^7.18.6", - "globals": "^11.1.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1423,13 +1323,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.21.5.tgz", - "integrity": "sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/template": "^7.20.7" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1438,27 +1338,27 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", - "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", - "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1467,12 +1367,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", - "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1481,13 +1381,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", - "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1496,12 +1395,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.5.tgz", - "integrity": "sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==", + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1510,14 +1411,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", - "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dependencies": { - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1526,12 +1426,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", - "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1540,12 +1440,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", - "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1554,13 +1455,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", - "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dependencies": { - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1569,14 +1469,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.5.tgz", - "integrity": "sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dependencies": { - "@babel/helper-module-transforms": "^7.21.5", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-simple-access": "^7.21.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1585,15 +1484,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", - "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dependencies": { - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-validator-identifier": "^7.19.1" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1602,13 +1500,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", - "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dependencies": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1617,27 +1514,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", - "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.20.5", - "@babel/helper-plugin-utils": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", - "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.25.9.tgz", + "integrity": "sha512-Ncw2JFsJVuvfRsa2lSHiC55kETQVLSnsYGQ1JDDwkUeWGTL/8Tom8aLTnlqgoeuopWrbbGndrc9AlLYrIosrow==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1646,13 +1528,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", - "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz", + "integrity": "sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1661,12 +1542,16 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", - "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==", + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz", + "integrity": "sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1675,12 +1560,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", - "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz", + "integrity": "sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/plugin-transform-react-jsx": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1689,12 +1574,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.21.3.tgz", - "integrity": "sha512-4DVcFeWe/yDYBLp0kBmOGFJ6N2UYg7coGid1gdxb4co62dy/xISDMaYBXBVXEDhfgMk7qkbcYiGtwd5Q/hwDDQ==", + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", + "integrity": "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1703,12 +1589,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", - "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" }, "engines": { "node": ">=6.9.0" @@ -1717,30 +1604,27 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz", - "integrity": "sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==", + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/types": "^7.21.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", - "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1749,13 +1633,17 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", - "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -1764,27 +1652,20 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.21.5.tgz", - "integrity": "sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", - "regenerator-transform": "^0.15.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", - "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1793,17 +1674,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz", - "integrity": "sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==", + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dependencies": { - "@babel/helper-module-imports": "^7.21.4", - "@babel/helper-plugin-utils": "^7.20.2", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "semver": "^6.3.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1812,21 +1689,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", - "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1835,13 +1703,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", - "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1850,12 +1717,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", - "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1864,12 +1731,16 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", - "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.9.tgz", + "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1878,12 +1749,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", - "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1892,15 +1763,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.21.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz", - "integrity": "sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==", + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-typescript": "^7.20.0" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1909,12 +1778,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.21.5.tgz", - "integrity": "sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1923,102 +1793,95 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", - "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/preset-env": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.21.5.tgz", - "integrity": "sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==", - "dependencies": { - "@babel/compat-data": "^7.21.5", - "@babel/helper-compilation-targets": "^7.21.5", - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.20.7", - "@babel/plugin-proposal-async-generator-functions": "^7.20.7", - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-class-static-block": "^7.21.0", - "@babel/plugin-proposal-dynamic-import": "^7.18.6", - "@babel/plugin-proposal-export-namespace-from": "^7.18.9", - "@babel/plugin-proposal-json-strings": "^7.18.6", - "@babel/plugin-proposal-logical-assignment-operators": "^7.20.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", - "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", - "@babel/plugin-proposal-optional-chaining": "^7.21.0", - "@babel/plugin-proposal-private-methods": "^7.18.6", - "@babel/plugin-proposal-private-property-in-object": "^7.21.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.20.0", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-transform-arrow-functions": "^7.21.5", - "@babel/plugin-transform-async-to-generator": "^7.20.7", - "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.21.0", - "@babel/plugin-transform-classes": "^7.21.0", - "@babel/plugin-transform-computed-properties": "^7.21.5", - "@babel/plugin-transform-destructuring": "^7.21.3", - "@babel/plugin-transform-dotall-regex": "^7.18.6", - "@babel/plugin-transform-duplicate-keys": "^7.18.9", - "@babel/plugin-transform-exponentiation-operator": "^7.18.6", - "@babel/plugin-transform-for-of": "^7.21.5", - "@babel/plugin-transform-function-name": "^7.18.9", - "@babel/plugin-transform-literals": "^7.18.9", - "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.20.11", - "@babel/plugin-transform-modules-commonjs": "^7.21.5", - "@babel/plugin-transform-modules-systemjs": "^7.20.11", - "@babel/plugin-transform-modules-umd": "^7.18.6", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.20.5", - "@babel/plugin-transform-new-target": "^7.18.6", - "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.21.3", - "@babel/plugin-transform-property-literals": "^7.18.6", - "@babel/plugin-transform-regenerator": "^7.21.5", - "@babel/plugin-transform-reserved-words": "^7.18.6", - "@babel/plugin-transform-shorthand-properties": "^7.18.6", - "@babel/plugin-transform-spread": "^7.20.7", - "@babel/plugin-transform-sticky-regex": "^7.18.6", - "@babel/plugin-transform-template-literals": "^7.18.9", - "@babel/plugin-transform-typeof-symbol": "^7.18.9", - "@babel/plugin-transform-unicode-escapes": "^7.21.5", - "@babel/plugin-transform-unicode-regex": "^7.18.6", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.21.5", - "babel-plugin-polyfill-corejs2": "^0.3.3", - "babel-plugin-polyfill-corejs3": "^0.6.0", - "babel-plugin-polyfill-regenerator": "^0.4.1", - "core-js-compat": "^3.25.1", - "semver": "^6.3.0" + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -2031,37 +1894,34 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", "@babel/types": "^7.4.4", "esutils": "^2.0.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" } }, "node_modules/@babel/preset-react": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", - "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.25.9.tgz", + "integrity": "sha512-D3to0uSPiWE7rBrdIICCd0tJSIGpLaaGptna2+w7Pft5xMqLpA1sz99DK5TZ1TjGbdQ/VI1eCSZ06dv3lT4JOw==", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-react-display-name": "^7.18.6", - "@babel/plugin-transform-react-jsx": "^7.18.6", - "@babel/plugin-transform-react-jsx-development": "^7.18.6", - "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-transform-react-display-name": "^7.25.9", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/plugin-transform-react-jsx-development": "^7.25.9", + "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2071,15 +1931,15 @@ } }, "node_modules/@babel/preset-typescript": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.21.5.tgz", - "integrity": "sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", "dependencies": { - "@babel/helper-plugin-utils": "^7.21.5", - "@babel/helper-validator-option": "^7.21.0", - "@babel/plugin-syntax-jsx": "^7.21.4", - "@babel/plugin-transform-modules-commonjs": "^7.21.5", - "@babel/plugin-transform-typescript": "^7.21.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2088,59 +1948,52 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.21.5.tgz", - "integrity": "sha512-FRqFlFKNazWYykft5zvzuEl1YyTDGsIRrjV9rvxvYkUC7W/ueBng1X68Xd6uRMzAaJ0xMKn08/wem5YS1lpX8w==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.26.0.tgz", + "integrity": "sha512-YXHu5lN8kJCb1LOb9PgV6pvak43X2h4HvRApcN5SdWeaItQOzfn1hgP6jasD6KWQyJDBxrVmA9o9OivlnNJK/w==", "dependencies": { - "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.11" + "core-js-pure": "^3.30.2", + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "license": "MIT", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", - "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.6", - "@babel/parser": "^7.25.6", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2149,23 +2002,55 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", - "license": "MIT", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@braintree/sanitize-url": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz", - "integrity": "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.0.tgz", + "integrity": "sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==" + }, + "node_modules/@chevrotain/cst-dts-gen": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", + "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", + "dependencies": { + "@chevrotain/gast": "11.0.3", + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/gast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", + "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", + "dependencies": { + "@chevrotain/types": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/@chevrotain/regexp-to-ast": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", + "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==" + }, + "node_modules/@chevrotain/types": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", + "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==" + }, + "node_modules/@chevrotain/utils": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", + "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==" }, "node_modules/@colors/colors": { "version": "1.5.0", @@ -2185,21 +2070,19 @@ } }, "node_modules/@docsearch/css": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.6.1.tgz", - "integrity": "sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==", - "license": "MIT" + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.7.0.tgz", + "integrity": "sha512-1OorbTwi1eeDmr0v5t+ckSRlt1zM5GHjm92iIl3kUu7im3GHuP+csf6E0WBg8pdXQczTWP9J9+o9n+Vg6DH5cQ==" }, "node_modules/@docsearch/react": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.6.1.tgz", - "integrity": "sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==", - "license": "MIT", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.7.0.tgz", + "integrity": "sha512-8e6tdDfkYoxafEEPuX5eE1h9cTkLvhe4KgoFkO5JCddXSQONnN1FHcDZRI4r8894eMpbYq6rdJF0dVYh8ikwNQ==", "dependencies": { - "@algolia/autocomplete-core": "1.9.3", - "@algolia/autocomplete-preset-algolia": "1.9.3", - "@docsearch/css": "3.6.1", - "algoliasearch": "^4.19.1" + "@algolia/autocomplete-core": "1.17.6", + "@algolia/autocomplete-preset-algolia": "1.17.6", + "@docsearch/css": "3.7.0", + "algoliasearch": "^5.12.0" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", @@ -2222,185 +2105,291 @@ } } }, - "node_modules/@docusaurus/core": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-2.4.3.tgz", - "integrity": "sha512-dWH5P7cgeNSIg9ufReX6gaCl/TmrGKD38Orbwuz05WPhAQtFXHd5B8Qym1TiXfvUNvwoYKkAJOJuGe8ou0Z7PA==", - "license": "MIT", + "node_modules/@docsearch/react/node_modules/@algolia/client-analytics": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.13.0.tgz", + "integrity": "sha512-pS3qyXiWTwKnrt/jE79fqkNqZp7kjsFNlJDcBGkSWid74DNc6DmArlkvPqyLxnoaYGjUGACT6g56n7E3mVV2TA==", "dependencies": { - "@babel/core": "^7.18.6", - "@babel/generator": "^7.18.7", + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/client-personalization": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.13.0.tgz", + "integrity": "sha512-RnCfOSN4OUJDuMNHFca2M8lY64Tmw0kQOZikge4TknTqHmlbKJb8IbJE7Rol79Z80W2Y+B1ydcjV7DPje4GMRA==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/@algolia/recommend": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.13.0.tgz", + "integrity": "sha512-53/wW96oaj1FKMzGdFcZ/epygfTppLDUvgI1thLkd475EtVZCH3ZZVUNCEvf1AtnNyH1RnItkFzX8ayWCpx2PQ==", + "dependencies": { + "@algolia/client-common": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docsearch/react/node_modules/algoliasearch": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.13.0.tgz", + "integrity": "sha512-04lyQX3Ev/oLYQx+aagamQDXvkUUfX1mwrLrus15+9fNaYj28GDxxEzbwaRfvmHFcZyoxvup7mMtDTTw8SrTEQ==", + "dependencies": { + "@algolia/client-abtesting": "5.13.0", + "@algolia/client-analytics": "5.13.0", + "@algolia/client-common": "5.13.0", + "@algolia/client-insights": "5.13.0", + "@algolia/client-personalization": "5.13.0", + "@algolia/client-query-suggestions": "5.13.0", + "@algolia/client-search": "5.13.0", + "@algolia/ingestion": "1.13.0", + "@algolia/monitoring": "1.13.0", + "@algolia/recommend": "5.13.0", + "@algolia/requester-browser-xhr": "5.13.0", + "@algolia/requester-fetch": "5.13.0", + "@algolia/requester-node-http": "5.13.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@docusaurus/babel": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.6.1.tgz", + "integrity": "sha512-JcKaunW8Ml2nTnfnvFc55T00Y+aCpNWnf1KY/gG+wWxHYDH0IdXOOz+k6NAlEAerW8+VYLfUqRIqHZ7N/DVXvQ==", + "dependencies": { + "@babel/core": "^7.25.9", + "@babel/generator": "^7.25.9", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.18.6", - "@babel/preset-env": "^7.18.6", - "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@babel/runtime": "^7.18.6", - "@babel/runtime-corejs3": "^7.18.6", - "@babel/traverse": "^7.18.8", - "@docusaurus/cssnano-preset": "2.4.3", - "@docusaurus/logger": "2.4.3", - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-common": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "@slorber/static-site-generator-webpack-plugin": "^4.0.7", - "@svgr/webpack": "^6.2.1", - "autoprefixer": "^10.4.7", - "babel-loader": "^8.2.5", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.25.9", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.25.9", + "@babel/runtime": "^7.25.9", + "@babel/runtime-corejs3": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", "babel-plugin-dynamic-import-node": "^2.3.3", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@docusaurus/bundler": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.6.1.tgz", + "integrity": "sha512-vHSEx8Ku9x/gfIC6k4xb8J2nTxagLia0KvZkPZhxfkD1+n8i+Dj4BZPWTmv+kCA17RbgAvECG0XRZ0/ZEspQBQ==", + "dependencies": { + "@babel/core": "^7.25.9", + "@docusaurus/babel": "3.6.1", + "@docusaurus/cssnano-preset": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "autoprefixer": "^10.4.14", + "babel-loader": "^9.2.1", + "clean-css": "^5.3.2", + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.8.1", + "css-minimizer-webpack-plugin": "^5.0.1", + "cssnano": "^6.1.2", + "file-loader": "^6.2.0", + "html-minifier-terser": "^7.2.0", + "mini-css-extract-plugin": "^2.9.1", + "null-loader": "^4.0.1", + "postcss": "^8.4.26", + "postcss-loader": "^7.3.3", + "react-dev-utils": "^12.0.1", + "terser-webpack-plugin": "^5.3.9", + "tslib": "^2.6.0", + "url-loader": "^4.1.1", + "webpack": "^5.95.0", + "webpackbar": "^6.0.1" + }, + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "@docusaurus/faster": "*" + }, + "peerDependenciesMeta": { + "@docusaurus/faster": { + "optional": true + } + } + }, + "node_modules/@docusaurus/core": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.6.1.tgz", + "integrity": "sha512-cDKxPihiM2z7G+4QtpTczS7uxNfNG6naSqM65OmAJET0CFRHbc9mDlLFtQF0lsVES91SHqfcGaaLZmi2FjdwWA==", + "dependencies": { + "@docusaurus/babel": "3.6.1", + "@docusaurus/bundler": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", "boxen": "^6.2.1", "chalk": "^4.1.2", "chokidar": "^3.5.3", - "clean-css": "^5.3.0", - "cli-table3": "^0.6.2", + "cli-table3": "^0.6.3", "combine-promises": "^1.1.0", "commander": "^5.1.0", - "copy-webpack-plugin": "^11.0.0", - "core-js": "^3.23.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^4.0.0", - "cssnano": "^5.1.12", + "core-js": "^3.31.1", "del": "^6.1.1", - "detect-port": "^1.3.0", + "detect-port": "^1.5.1", "escape-html": "^1.0.3", - "eta": "^2.0.0", - "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "html-minifier-terser": "^6.1.0", - "html-tags": "^3.2.0", - "html-webpack-plugin": "^5.5.0", - "import-fresh": "^3.3.0", + "eta": "^2.2.0", + "eval": "^0.1.8", + "fs-extra": "^11.1.1", + "html-tags": "^3.3.1", + "html-webpack-plugin": "^5.6.0", "leven": "^3.1.0", "lodash": "^4.17.21", - "mini-css-extract-plugin": "^2.6.1", - "postcss": "^8.4.14", - "postcss-loader": "^7.0.0", + "p-map": "^4.0.0", "prompts": "^2.4.2", "react-dev-utils": "^12.0.1", "react-helmet-async": "^1.3.0", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2", + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0", "react-loadable-ssr-addon-v5-slorber": "^1.0.1", - "react-router": "^5.3.3", + "react-router": "^5.3.4", "react-router-config": "^5.1.1", - "react-router-dom": "^5.3.3", + "react-router-dom": "^5.3.4", "rtl-detect": "^1.0.4", - "semver": "^7.3.7", - "serve-handler": "^6.1.3", + "semver": "^7.5.4", + "serve-handler": "^6.1.6", "shelljs": "^0.8.5", - "terser-webpack-plugin": "^5.3.3", - "tslib": "^2.4.0", - "update-notifier": "^5.1.0", - "url-loader": "^4.1.1", - "wait-on": "^6.0.1", - "webpack": "^5.73.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-dev-server": "^4.9.3", - "webpack-merge": "^5.8.0", - "webpackbar": "^5.0.2" + "tslib": "^2.6.0", + "update-notifier": "^6.0.2", + "webpack": "^5.95.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-dev-server": "^4.15.2", + "webpack-merge": "^6.0.1" }, "bin": { "docusaurus": "bin/docusaurus.mjs" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "@mdx-js/react": "^3.0.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/cssnano-preset": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-2.4.3.tgz", - "integrity": "sha512-ZvGSRCi7z9wLnZrXNPG6DmVPHdKGd8dIn9pYbEOFiYihfv4uDR3UtxogmKf+rT8ZlKFf5Lqne8E8nt08zNM8CA==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.6.1.tgz", + "integrity": "sha512-ZxYUmNeyQHW2w4/PJ7d07jQDuxzmKr9uPAQ6IVe5dTkeIeV0mDBB3jOLeJkNoI42Ru9JKEqQ9aVDtM9ct6QHnw==", "dependencies": { - "cssnano-preset-advanced": "^5.3.8", - "postcss": "^8.4.14", - "postcss-sort-media-queries": "^4.2.1", - "tslib": "^2.4.0" + "cssnano-preset-advanced": "^6.1.2", + "postcss": "^8.4.38", + "postcss-sort-media-queries": "^5.2.0", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } }, "node_modules/@docusaurus/logger": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-2.4.3.tgz", - "integrity": "sha512-Zxws7r3yLufk9xM1zq9ged0YHs65mlRmtsobnFkdZTxWXdTYlWWLWdKyNKAsVC+D7zg+pv2fGbyabdOnyZOM3w==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.6.1.tgz", + "integrity": "sha512-OvetI/nnOMBSqCkUzKAQhnIjhxduECK4qTu3tq/8/h/qqvLsvKURojm04WPE54L+Uy+UXMas0hnbBJd8zDlEOw==", "dependencies": { "chalk": "^4.1.2", - "tslib": "^2.4.0" + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } }, "node_modules/@docusaurus/lqip-loader": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/lqip-loader/-/lqip-loader-2.4.3.tgz", - "integrity": "sha512-hdumVOGbI4eiQQsZvbbosnm86FNkp23GikNanC0MJIIz8j3sCg8I0GEmg9nnVZor/2tE4ud5AWqjsVrx1CwcjA==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/lqip-loader/-/lqip-loader-3.6.1.tgz", + "integrity": "sha512-H/VVvnvFupFhQ81FuTyA/XHxEZPKh99T6Wg6KgN+/yvcn7869RdgrlDhKDnXZ7j2u80eFsVNjAcPfW1cSAtK6A==", "dependencies": { - "@docusaurus/logger": "2.4.3", + "@docusaurus/logger": "3.6.1", "file-loader": "^6.2.0", "lodash": "^4.17.21", - "sharp": "^0.30.7", - "tslib": "^2.4.0" + "sharp": "^0.32.3", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } }, "node_modules/@docusaurus/mdx-loader": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-2.4.3.tgz", - "integrity": "sha512-b1+fDnWtl3GiqkL0BRjYtc94FZrcDDBV1j8446+4tptB9BAOlePwG2p/pK6vGvfL53lkOsszXMghr2g67M0vCw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.18.8", - "@babel/traverse": "^7.18.8", - "@docusaurus/logger": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@mdx-js/mdx": "^1.6.22", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.6.1.tgz", + "integrity": "sha512-KPIsYi0S3X3/rNrW3V1fgOu5t6ahYWc31zTHHod8pacFxdmk9Uf6uuw+Jd6Cly1ilgal+41Ku+s0gmMuqKqiqg==", + "dependencies": { + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@mdx-js/mdx": "^3.0.0", + "@slorber/remark-comment": "^1.0.0", "escape-html": "^1.0.3", + "estree-util-value-to-estree": "^3.0.1", "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "image-size": "^1.0.1", - "mdast-util-to-string": "^2.0.0", - "remark-emoji": "^2.2.0", + "fs-extra": "^11.1.1", + "image-size": "^1.0.2", + "mdast-util-mdx": "^3.0.0", + "mdast-util-to-string": "^4.0.0", + "rehype-raw": "^7.0.0", + "remark-directive": "^3.0.0", + "remark-emoji": "^4.0.0", + "remark-frontmatter": "^5.0.0", + "remark-gfm": "^4.0.0", "stringify-object": "^3.3.0", - "tslib": "^2.4.0", - "unified": "^9.2.2", - "unist-util-visit": "^2.0.3", + "tslib": "^2.6.0", + "unified": "^11.0.3", + "unist-util-visit": "^5.0.0", "url-loader": "^4.1.1", - "webpack": "^5.73.0" + "vfile": "^6.0.1", + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/module-type-aliases": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-2.4.3.tgz", - "integrity": "sha512-cwkBkt1UCiduuvEAo7XZY01dJfRn7UR/75mBgOdb1hKknhrabJZ8YH+7savd/y9kLExPyrhe0QwdS9GuzsRRIA==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.6.1.tgz", + "integrity": "sha512-J+q1jgm7TnEfVIUZImSFeLA1rghb6nwtoB9siHdcgKpDqFJ9/S7xhQL2aEKE7iZMZYzpu+2F390E9A7GkdEJNA==", "dependencies": { - "@docusaurus/react-loadable": "5.5.2", - "@docusaurus/types": "2.4.3", + "@docusaurus/types": "3.6.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", "@types/react-router-dom": "*", "react-helmet-async": "*", - "react-loadable": "npm:@docusaurus/react-loadable@5.5.2" + "react-loadable": "npm:@docusaurus/react-loadable@6.0.0" }, "peerDependencies": { "react": "*", @@ -2408,193 +2397,190 @@ } }, "node_modules/@docusaurus/plugin-content-blog": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.4.3.tgz", - "integrity": "sha512-PVhypqaA0t98zVDpOeTqWUTvRqCEjJubtfFUQ7zJNYdbYTbS/E/ytq6zbLVsN/dImvemtO/5JQgjLxsh8XLo8Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/logger": "2.4.3", - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-common": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "cheerio": "^1.0.0-rc.12", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.6.1.tgz", + "integrity": "sha512-FUmsn3xg/XD/K/4FQd8XHrs92aQdZO5LUtpHnRvO1/6DY87SMz6B6ERAN9IGQQld//M2/LVTHkZy8oVhQZQHIQ==", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "cheerio": "1.0.0-rc.12", "feed": "^4.2.2", - "fs-extra": "^10.1.0", + "fs-extra": "^11.1.1", "lodash": "^4.17.21", "reading-time": "^1.5.0", - "tslib": "^2.4.0", - "unist-util-visit": "^2.0.3", + "srcset": "^4.0.0", + "tslib": "^2.6.0", + "unist-util-visit": "^5.0.0", "utility-types": "^3.10.0", - "webpack": "^5.73.0" + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-content-docs": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.4.3.tgz", - "integrity": "sha512-N7Po2LSH6UejQhzTCsvuX5NOzlC+HiXOVvofnEPj0WhMu1etpLEXE6a4aTxrtg95lQ5kf0xUIdjX9sh3d3G76A==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/logger": "2.4.3", - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/module-type-aliases": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "@types/react-router-config": "^5.0.6", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.6.1.tgz", + "integrity": "sha512-Uq8kyn5DYCDmkUlB9sWChhWghS4lUFNiQU+RXcAXJ3qCVXsBpPsh6RF+npQG1N+j4wAbjydM1iLLJJzp+x3eMQ==", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@types/react-router-config": "^5.0.7", "combine-promises": "^1.1.0", - "fs-extra": "^10.1.0", - "import-fresh": "^3.3.0", + "fs-extra": "^11.1.1", "js-yaml": "^4.1.0", "lodash": "^4.17.21", - "tslib": "^2.4.0", + "tslib": "^2.6.0", "utility-types": "^3.10.0", - "webpack": "^5.73.0" + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-content-pages": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.4.3.tgz", - "integrity": "sha512-txtDVz7y3zGk67q0HjG0gRttVPodkHqE0bpJ+7dOaTH40CQFLSh7+aBeGnPOTl+oCPG+hxkim4SndqPqXjQ8Bg==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.6.1.tgz", + "integrity": "sha512-TZtL+2zq20gqGalzoIT2rEF1T4YCZ26jTvlCJXs78+incIajfdHtmdOq7rQW0oV7oqTjpGllbp788nY/vY9jgw==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "fs-extra": "^10.1.0", - "tslib": "^2.4.0", - "webpack": "^5.73.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "fs-extra": "^11.1.1", + "tslib": "^2.6.0", + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-debug": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-2.4.3.tgz", - "integrity": "sha512-LkUbuq3zCmINlFb+gAd4ZvYr+bPAzMC0hwND4F7V9bZ852dCX8YoWyovVUBKq4er1XsOwSQaHmNGtObtn8Av8Q==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.6.1.tgz", + "integrity": "sha512-DeKPZtoVExDSYCbzoz7y5Dhc6+YPqRWfVGwEEUyKopSyQYefp0OV8hvASmbJCn2WyThRgspOUhog3FSEhz+agw==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "fs-extra": "^10.1.0", - "react-json-view": "^1.21.3", - "tslib": "^2.4.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "fs-extra": "^11.1.1", + "react-json-view-lite": "^1.2.0", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-google-analytics": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.4.3.tgz", - "integrity": "sha512-KzBV3k8lDkWOhg/oYGxlK5o9bOwX7KpPc/FTWoB+SfKhlHfhq7qcQdMi1elAaVEIop8tgK6gD1E58Q+XC6otSQ==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.6.1.tgz", + "integrity": "sha512-ZEoERiDHxSfhaEeT35ukQ892NzGHWiUvfxUsnPiRuGEhMoQlxMSp60shBuSZ1sUKuZlndoEl5qAXJg09Wls/Sg==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "tslib": "^2.4.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-google-gtag": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.4.3.tgz", - "integrity": "sha512-5FMg0rT7sDy4i9AGsvJC71MQrqQZwgLNdDetLEGDHLfSHLvJhQbTCUGbGXknUgWXQJckcV/AILYeJy+HhxeIFA==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.6.1.tgz", + "integrity": "sha512-u/E9vXUsZxYaV6Brvfee8NiH/iR0cMml9P/ifz4EpH/Jfxdbw8rbCT0Nm/h7EFgEY48Uqkl5huSbIvFB9n8aTQ==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "tslib": "^2.4.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@types/gtag.js": "^0.0.12", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-google-tag-manager": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-2.4.3.tgz", - "integrity": "sha512-1jTzp71yDGuQiX9Bi0pVp3alArV0LSnHXempvQTxwCGAEzUWWaBg4d8pocAlTpbP9aULQQqhgzrs8hgTRPOM0A==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.6.1.tgz", + "integrity": "sha512-By+NKkGYV8tSo8/RyS1OXikOtqsko5jJZ/uioJfBjsBGgSbiMJ+Y/HogFBke0mgSvf7NPGKZTbYm5+FJ8YUtPQ==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "tslib": "^2.4.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/plugin-ideal-image": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-ideal-image/-/plugin-ideal-image-2.4.3.tgz", - "integrity": "sha512-cwnOKz5HwR/WwNL5lzGOWppyhaHQ2dPj1/x9hwv5VPwNmDDnWsYEwfBOTq8AYT27vFrYAH1tx9UX7QurRaIa4A==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-ideal-image/-/plugin-ideal-image-3.6.1.tgz", + "integrity": "sha512-hiGRPPlsM02aEOPlQc9rVnrckbVR6HswG7yDpZOtBEhw+ysXFsl/8gzAxFBL4ogKjN28WrlMCn/6IIkxY/EyOQ==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/lqip-loader": "2.4.3", + "@docusaurus/core": "3.6.1", + "@docusaurus/lqip-loader": "3.6.1", "@docusaurus/responsive-loader": "^1.7.0", - "@docusaurus/theme-translations": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "@endiliey/react-ideal-image": "^0.0.11", + "@docusaurus/theme-translations": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@slorber/react-ideal-image": "^0.0.12", "react-waypoint": "^10.3.0", - "sharp": "^0.30.7", - "tslib": "^2.4.0", - "webpack": "^5.73.0" + "sharp": "^0.32.3", + "tslib": "^2.6.0", + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { "jimp": "*", - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" }, "peerDependenciesMeta": { "jimp": { @@ -2603,67 +2589,53 @@ } }, "node_modules/@docusaurus/plugin-sitemap": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.4.3.tgz", - "integrity": "sha512-LRQYrK1oH1rNfr4YvWBmRzTL0LN9UAPxBbghgeFRBm5yloF6P+zv1tm2pe2hQTX/QP5bSKdnajCvfnScgKXMZQ==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/logger": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-common": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "fs-extra": "^10.1.0", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.6.1.tgz", + "integrity": "sha512-i8R/GTKew4Cufb+7YQTwfPcNOhKTJzZ1VZ5OqQwI9c3pZK2TltQyhqKDVN94KCTbSSKvOYYytYfRAB2uPnH1/A==", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "fs-extra": "^11.1.1", "sitemap": "^7.1.1", - "tslib": "^2.4.0" + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/preset-classic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-2.4.3.tgz", - "integrity": "sha512-tRyMliepY11Ym6hB1rAFSNGwQDpmszvWYJvlK1E+md4SW8i6ylNHtpZjaYFff9Mdk3i/Pg8ItQq9P0daOJAvQw==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/plugin-content-blog": "2.4.3", - "@docusaurus/plugin-content-docs": "2.4.3", - "@docusaurus/plugin-content-pages": "2.4.3", - "@docusaurus/plugin-debug": "2.4.3", - "@docusaurus/plugin-google-analytics": "2.4.3", - "@docusaurus/plugin-google-gtag": "2.4.3", - "@docusaurus/plugin-google-tag-manager": "2.4.3", - "@docusaurus/plugin-sitemap": "2.4.3", - "@docusaurus/theme-classic": "2.4.3", - "@docusaurus/theme-common": "2.4.3", - "@docusaurus/theme-search-algolia": "2.4.3", - "@docusaurus/types": "2.4.3" - }, - "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } - }, - "node_modules/@docusaurus/react-loadable": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", - "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.6.1.tgz", + "integrity": "sha512-b90Y1XRH9e+oa/E3NmiFEFOwgYUd+knFcZUy81nM3FJs038WbEA0T55NQsuPW0s7nOsCShQ7dVFyKxV+Wp31Nw==", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/plugin-content-blog": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/plugin-content-pages": "3.6.1", + "@docusaurus/plugin-debug": "3.6.1", + "@docusaurus/plugin-google-analytics": "3.6.1", + "@docusaurus/plugin-google-gtag": "3.6.1", + "@docusaurus/plugin-google-tag-manager": "3.6.1", + "@docusaurus/plugin-sitemap": "3.6.1", + "@docusaurus/theme-classic": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-search-algolia": "3.6.1", + "@docusaurus/types": "3.6.1" + }, + "engines": { + "node": ">=18.0" }, "peerDependencies": { - "react": "*" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/responsive-loader": { @@ -2690,246 +2662,227 @@ } }, "node_modules/@docusaurus/theme-classic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-2.4.3.tgz", - "integrity": "sha512-QKRAJPSGPfDY2yCiPMIVyr+MqwZCIV2lxNzqbyUW0YkrlmdzzP3WuQJPMGLCjWgQp/5c9kpWMvMxjhpZx1R32Q==", - "license": "MIT", - "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/module-type-aliases": "2.4.3", - "@docusaurus/plugin-content-blog": "2.4.3", - "@docusaurus/plugin-content-docs": "2.4.3", - "@docusaurus/plugin-content-pages": "2.4.3", - "@docusaurus/theme-common": "2.4.3", - "@docusaurus/theme-translations": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-common": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "@mdx-js/react": "^1.6.22", - "clsx": "^1.2.1", - "copy-text-to-clipboard": "^3.0.1", - "infima": "0.2.0-alpha.43", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.6.1.tgz", + "integrity": "sha512-5lVUmIXk7zp+n9Ki2lYWrmhbd6mssOlKCnnDJvY4QDi3EgjRisIu5g4yKXoWTIbiqE7m7q/dS9cbeShEtfkKng==", + "dependencies": { + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/plugin-content-blog": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/plugin-content-pages": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-translations": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "copy-text-to-clipboard": "^3.2.0", + "infima": "0.2.0-alpha.45", "lodash": "^4.17.21", "nprogress": "^0.2.0", - "postcss": "^8.4.14", - "prism-react-renderer": "^1.3.5", - "prismjs": "^1.28.0", - "react-router-dom": "^5.3.3", - "rtlcss": "^3.5.0", - "tslib": "^2.4.0", + "postcss": "^8.4.26", + "prism-react-renderer": "^2.3.0", + "prismjs": "^1.29.0", + "react-router-dom": "^5.3.4", + "rtlcss": "^4.1.0", + "tslib": "^2.6.0", "utility-types": "^3.10.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/theme-common": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-2.4.3.tgz", - "integrity": "sha512-7KaDJBXKBVGXw5WOVt84FtN8czGWhM0lbyWEZXGp8AFfL6sZQfRTluFp4QriR97qwzSyOfQb+nzcDZZU4tezUw==", - "license": "MIT", - "dependencies": { - "@docusaurus/mdx-loader": "2.4.3", - "@docusaurus/module-type-aliases": "2.4.3", - "@docusaurus/plugin-content-blog": "2.4.3", - "@docusaurus/plugin-content-docs": "2.4.3", - "@docusaurus/plugin-content-pages": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-common": "2.4.3", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.6.1.tgz", + "integrity": "sha512-18iEYNpMvarGfq9gVRpGowSZD24vZ39Iz4acqaj64180i54V9el8tVnhNr/wRvrUm1FY30A1NHLqnMnDz4rYEQ==", + "dependencies": { + "@docusaurus/mdx-loader": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", "@types/history": "^4.7.11", "@types/react": "*", "@types/react-router-config": "*", - "clsx": "^1.2.1", + "clsx": "^2.0.0", "parse-numeric-range": "^1.3.0", - "prism-react-renderer": "^1.3.5", - "tslib": "^2.4.0", - "use-sync-external-store": "^1.2.0", + "prism-react-renderer": "^2.3.0", + "tslib": "^2.6.0", "utility-types": "^3.10.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "@docusaurus/plugin-content-docs": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/theme-mermaid": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-2.4.3.tgz", - "integrity": "sha512-S1tZ3xpowtFiTrpTKmvVbRHUYGOlEG5CnPzWlO4huJT1sAwLR+pD6f9DYUlPv2+9NezF3EfUrUyW9xLH0UP58w==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.6.1.tgz", + "integrity": "sha512-ke00/VSFibzucbr64JXwPWsiu66zcqI8mnEbbmPSV1Yby5FRsfGQqcE+1cvUkAOVCl+zX8RNjv8vrRb4ilQDLQ==", "dependencies": { - "@docusaurus/core": "2.4.3", - "@docusaurus/module-type-aliases": "2.4.3", - "@docusaurus/theme-common": "2.4.3", - "@docusaurus/types": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "@mdx-js/react": "^1.6.22", - "mermaid": "^9.2.2", - "tslib": "^2.4.0" + "@docusaurus/core": "3.6.1", + "@docusaurus/module-type-aliases": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "mermaid": ">=10.4", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/theme-search-algolia": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.4.3.tgz", - "integrity": "sha512-jziq4f6YVUB5hZOB85ELATwnxBz/RmSLD3ksGQOLDPKVzat4pmI8tddNWtriPpxR04BNT+ZfpPUMFkNFetSW1Q==", - "license": "MIT", - "dependencies": { - "@docsearch/react": "^3.1.1", - "@docusaurus/core": "2.4.3", - "@docusaurus/logger": "2.4.3", - "@docusaurus/plugin-content-docs": "2.4.3", - "@docusaurus/theme-common": "2.4.3", - "@docusaurus/theme-translations": "2.4.3", - "@docusaurus/utils": "2.4.3", - "@docusaurus/utils-validation": "2.4.3", - "algoliasearch": "^4.13.1", - "algoliasearch-helper": "^3.10.0", - "clsx": "^1.2.1", - "eta": "^2.0.0", - "fs-extra": "^10.1.0", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.6.1.tgz", + "integrity": "sha512-BjmuiFRpQP1WEm8Mzu1Bb0Wdas6G65VHXDDNr7XTKgbstxalE6vuxt0ioXTDFS2YVep5748aVhKvnxR9gm2Liw==", + "dependencies": { + "@docsearch/react": "^3.5.2", + "@docusaurus/core": "3.6.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/plugin-content-docs": "3.6.1", + "@docusaurus/theme-common": "3.6.1", + "@docusaurus/theme-translations": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-validation": "3.6.1", + "algoliasearch": "^4.18.0", + "algoliasearch-helper": "^3.13.3", + "clsx": "^2.0.0", + "eta": "^2.2.0", + "fs-extra": "^11.1.1", "lodash": "^4.17.21", - "tslib": "^2.4.0", + "tslib": "^2.6.0", "utility-types": "^3.10.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@docusaurus/theme-translations": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-2.4.3.tgz", - "integrity": "sha512-H4D+lbZbjbKNS/Zw1Lel64PioUAIT3cLYYJLUf3KkuO/oc9e0QCVhIYVtUI2SfBCF2NNdlyhBDQEEMygsCedIg==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.6.1.tgz", + "integrity": "sha512-bNm5G6sueUezvyhsBegA1wwM38yW0BnqpZTE9KHO2yKnkERNMaV5x/yPJ/DNCOHjJtCcJ5Uz55g2AS75Go31xA==", "dependencies": { - "fs-extra": "^10.1.0", - "tslib": "^2.4.0" + "fs-extra": "^11.1.1", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } }, "node_modules/@docusaurus/types": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-2.4.3.tgz", - "integrity": "sha512-W6zNLGQqfrp/EoPD0bhb9n7OobP+RHpmvVzpA+Z/IuU3Q63njJM24hmT0GYboovWcDtFmnIJC9wcyx4RVPQscw==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.6.1.tgz", + "integrity": "sha512-hCB1hj9DYutVYBisnPNobz9SzEmCcf1EetJv09O49Cov3BqOkm+vnnjB3d957YJMtpLGQoKBeN/FF1DZ830JwQ==", "dependencies": { + "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", "@types/react": "*", "commander": "^5.1.0", - "joi": "^17.6.0", + "joi": "^17.9.2", "react-helmet-async": "^1.3.0", "utility-types": "^3.10.0", - "webpack": "^5.73.0", - "webpack-merge": "^5.8.0" + "webpack": "^5.95.0", + "webpack-merge": "^5.9.0" }, "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/@docusaurus/types/node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" } }, "node_modules/@docusaurus/utils": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-2.4.3.tgz", - "integrity": "sha512-fKcXsjrD86Smxv8Pt0TBFqYieZZCPh4cbf9oszUq/AMhZn3ujwpKaVYZACPX8mmjtYx0JOgNx52CREBfiGQB4A==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.6.1.tgz", + "integrity": "sha512-nS3WCvepwrnBEgSG5vQu40XG95lC9Jeh/odV5u5IhU1eQFEGDst9xBi6IK5yZdsGvbuaXBZLZtOqWYtuuFa/rQ==", "dependencies": { - "@docusaurus/logger": "2.4.3", - "@svgr/webpack": "^6.2.1", + "@docusaurus/logger": "3.6.1", + "@docusaurus/types": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "@svgr/webpack": "^8.1.0", "escape-string-regexp": "^4.0.0", "file-loader": "^6.2.0", - "fs-extra": "^10.1.0", - "github-slugger": "^1.4.0", + "fs-extra": "^11.1.1", + "github-slugger": "^1.5.0", "globby": "^11.1.0", "gray-matter": "^4.0.3", + "jiti": "^1.20.0", "js-yaml": "^4.1.0", "lodash": "^4.17.21", "micromatch": "^4.0.5", + "prompts": "^2.4.2", "resolve-pathname": "^3.0.0", "shelljs": "^0.8.5", - "tslib": "^2.4.0", + "tslib": "^2.6.0", "url-loader": "^4.1.1", - "webpack": "^5.73.0" + "utility-types": "^3.10.0", + "webpack": "^5.88.1" }, "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "node": ">=18.0" } }, "node_modules/@docusaurus/utils-common": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-2.4.3.tgz", - "integrity": "sha512-/jascp4GbLQCPVmcGkPzEQjNaAk3ADVfMtudk49Ggb+131B1WDD6HqlSmDf8MxGdy7Dja2gc+StHf01kiWoTDQ==", - "license": "MIT", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.6.1.tgz", + "integrity": "sha512-LX1qiTiC0aS8c92uZ+Wj2iNCNJyYZJIKY8/nZDKNMBfo759VYVS3RX3fKP3DznB+16sYp7++MyCz/T6fOGaRfw==", "dependencies": { - "tslib": "^2.4.0" + "@docusaurus/types": "3.6.1", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" - }, - "peerDependencies": { - "@docusaurus/types": "*" - }, - "peerDependenciesMeta": { - "@docusaurus/types": { - "optional": true - } + "node": ">=18.0" } }, "node_modules/@docusaurus/utils-validation": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-2.4.3.tgz", - "integrity": "sha512-G2+Vt3WR5E/9drAobP+hhZQMaswRwDlp6qOMi7o7ZypB+VO7N//DZWhZEwhcRGepMDJGQEwtPv7UxtYwPL9PBw==", - "license": "MIT", - "dependencies": { - "@docusaurus/logger": "2.4.3", - "@docusaurus/utils": "2.4.3", - "joi": "^17.6.0", + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.6.1.tgz", + "integrity": "sha512-+iMd6zRl5cJQm7nUP+7pSO/oAXsN79eHO34ME7l2YJt4GEAr70l5kkD58u2jEPpp+wSXT70c7x2A2lzJI1E8jw==", + "dependencies": { + "@docusaurus/logger": "3.6.1", + "@docusaurus/utils": "3.6.1", + "@docusaurus/utils-common": "3.6.1", + "fs-extra": "^11.2.0", + "joi": "^17.9.2", "js-yaml": "^4.1.0", - "tslib": "^2.4.0" + "lodash": "^4.17.21", + "tslib": "^2.6.0" }, "engines": { - "node": ">=16.14" - } - }, - "node_modules/@endiliey/react-ideal-image": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/@endiliey/react-ideal-image/-/react-ideal-image-0.0.11.tgz", - "integrity": "sha512-QxMjt/Gvur/gLxSoCy7VIyGGGrGmDN+VHcXkN3R2ApoWX0EYUE+hMgPHSW/PV6VVebZ1Nd4t2UnGRBDihu16JQ==", - "engines": { - "node": ">= 8.9.0", - "npm": "> 3" - }, - "peerDependencies": { - "prop-types": ">=15", - "react": ">=0.14.x", - "react-waypoint": ">=9.0.2" + "node": ">=18.0" } }, "node_modules/@hapi/hoek": { @@ -2945,23 +2898,42 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + }, + "node_modules/@iconify/utils": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.33.tgz", + "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", + "dependencies": { + "@antfu/install-pkg": "^0.4.0", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "mlly": "^1.7.1" + } + }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -2976,7 +2948,6 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2987,9 +2958,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "engines": { "node": ">=6.0.0" } @@ -2998,170 +2969,101 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" }, "node_modules/@mdx-js/mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", - "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "dependencies": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.0.tgz", + "integrity": "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.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/@mdx-js/mdx/node_modules/@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@mdx-js/mdx/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@mdx-js/mdx/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@mdx-js/mdx/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@mdx-js/mdx/node_modules/unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "node_modules/@mdx-js/react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.0.tgz", + "integrity": "sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==", "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "@types/mdx": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" + "@types/react": ">=16", + "react": ">=16" } }, - "node_modules/@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/@mermaid-js/parser": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", + "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==", + "dependencies": { + "langium": "3.0.0" } }, "node_modules/@monaco-editor/loader": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz", - "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", + "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", "dependencies": { "state-local": "^1.0.6" }, @@ -3170,11 +3072,11 @@ } }, "node_modules/@monaco-editor/react": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.1.tgz", - "integrity": "sha512-NNDFdP+2HojtNhCkRfE6/D6ro6pBNihaOzMbGK84lNWzRu+CfBjwzGt4jmnqimLuqp5yE5viHS2vi+QOAnD5FQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", + "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", "dependencies": { - "@monaco-editor/loader": "^1.3.3" + "@monaco-editor/loader": "^1.4.0" }, "peerDependencies": { "monaco-editor": ">= 0.25.0 < 1", @@ -3214,15 +3116,52 @@ "node": ">= 8" } }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" }, "node_modules/@sideway/address": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz", - "integrity": "sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", + "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "dependencies": { "@hapi/hoek": "^9.0.0" } @@ -3238,37 +3177,51 @@ "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==" + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" }, "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@slorber/static-site-generator-webpack-plugin": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", - "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", - "dependencies": { - "eval": "^0.1.8", - "p-map": "^4.0.0", - "webpack-sources": "^3.2.2" - }, + "node_modules/@slorber/react-ideal-image": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@slorber/react-ideal-image/-/react-ideal-image-0.0.12.tgz", + "integrity": "sha512-u8KiDTEkMA7/KAeA5ywg/P7YG4zuKhWtswfVZDH8R8HXgQsFcHIYU2WaQnGuK/Du7Wdj90I+SdFmajSGFRvoKA==", "engines": { - "node": ">=14" + "node": ">= 8.9.0", + "npm": "> 3" + }, + "peerDependencies": { + "prop-types": ">=15", + "react": ">=0.14.x", + "react-waypoint": ">=9.0.2" + } + }, + "node_modules/@slorber/remark-comment": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", + "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.1.0", + "micromark-util-symbol": "^1.0.1" } }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3309,11 +3262,11 @@ } }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3324,11 +3277,11 @@ } }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3339,11 +3292,11 @@ } }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3354,11 +3307,11 @@ } }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3369,9 +3322,9 @@ } }, "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", "engines": { "node": ">=12" }, @@ -3384,21 +3337,21 @@ } }, "node_modules/@svgr/babel-preset": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", - "@svgr/babel-plugin-remove-jsx-attribute": "*", - "@svgr/babel-plugin-remove-jsx-empty-expression": "*", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", - "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", - "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", - "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", - "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3409,18 +3362,18 @@ } }, "node_modules/@svgr/core": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.1" + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3428,15 +3381,15 @@ } }, "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "dependencies": { - "@babel/types": "^7.20.0", + "@babel/types": "^7.21.3", "entities": "^4.4.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3444,37 +3397,37 @@ } }, "node_modules/@svgr/plugin-jsx": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "dependencies": { - "@babel/core": "^7.19.6", - "@svgr/babel-preset": "^6.5.1", - "@svgr/hast-util-to-babel-ast": "^6.5.1", + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", "svg-parser": "^2.0.4" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", "url": "https://github.com/sponsors/gregberge" }, "peerDependencies": { - "@svgr/core": "^6.0.0" + "@svgr/core": "*" } }, "node_modules/@svgr/plugin-svgo": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", "dependencies": { - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "svgo": "^2.8.0" + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3485,21 +3438,21 @@ } }, "node_modules/@svgr/webpack": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", "dependencies": { - "@babel/core": "^7.19.6", - "@babel/plugin-transform-react-constant-elements": "^7.18.12", - "@babel/preset-env": "^7.19.4", + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", - "@babel/preset-typescript": "^7.18.6", - "@svgr/core": "^6.5.1", - "@svgr/plugin-jsx": "^6.5.1", - "@svgr/plugin-svgo": "^6.5.1" + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { "type": "github", @@ -3507,14 +3460,14 @@ } }, "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dependencies": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=14.16" } }, "node_modules/@trysound/sax": { @@ -3525,175 +3478,497 @@ "node": ">=10.13.0" } }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" } }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "license": "MIT" + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" }, - "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@types/d3-selection": "*" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "@types/d3-selection": "*" } }, - "node_modules/@types/hast": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", - "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", "dependencies": { - "@types/unist": "*" + "@types/d3-array": "*", + "@types/geojson": "*" } }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" }, - "node_modules/@types/http-proxy": { - "version": "1.17.11", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", - "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", "dependencies": { - "@types/node": "*" + "@types/d3-selection": "*" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@types/d3-dsv": "*" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", "dependencies": { - "@types/istanbul-lib-report": "*" + "@types/geojson": "*" } }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" - }, - "node_modules/@types/katex": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.11.1.tgz", - "integrity": "sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg==" + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" }, - "node_modules/@types/mdast": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", - "integrity": "sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==", + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "dependencies": { - "@types/unist": "*" + "@types/d3-color": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" }, - "node_modules/@types/node": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.1.tgz", - "integrity": "sha512-DqJociPbZP1lbZ5SQPk4oag6W7AyaGMO6gSfRwq3PWl4PXTwJpRQJhDq4W0kzrg3w6tJ1SwlvGZ5uKFHY13LIg==" + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" }, - "node_modules/@types/parse5": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "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==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "dependencies": { + "@types/trusted-types": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "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==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.1.tgz", + "integrity": "sha512-CRICJIl0N5cXDONAdlTv5ShATZ4HEwk6kDDIW2/w9qOWKg+NU/5F8wYRWCrONad0/UKkloNSmmyN/wX4rtpbVA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/express/node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, + "node_modules/@types/gtag.js": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", + "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + }, + "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==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/history": { + "version": "4.7.11", + "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", + "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==" + }, + "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==", + "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==" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "22.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", + "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prismjs": { + "version": "1.26.5", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", + "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + "version": "6.9.17", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==" }, "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/react": { - "version": "18.2.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz", - "integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==", + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, @@ -3707,9 +3982,9 @@ } }, "node_modules/@types/react-router-config": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.7.tgz", - "integrity": "sha512-pFFVXUIydHlcJP6wJm7sDii5mD/bCmmAY0wQzq+M+uX7bqS95AQqHZWP1iNMKrWVQSuHIzj5qi9BvrtLX2/T4w==", + "version": "5.0.11", + "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", + "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -3735,233 +4010,221 @@ "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/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.1.tgz", - "integrity": "sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==", + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", "dependencies": { - "@types/mime": "*", - "@types/node": "*" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, "node_modules/@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" }, "node_modules/@types/ws": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.4.tgz", - "integrity": "sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==", + "version": "8.5.13", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", + "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", "dependencies": { "@types/node": "*" } }, "node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "license": "MIT" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "license": "MIT" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", - "license": "MIT" + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "license": "MIT", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "license": "MIT" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "license": "MIT", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "license": "Apache-2.0", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "license": "MIT" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", - "license": "MIT", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dependencies": { - "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, "node_modules/accepts": { "version": "1.3.8", @@ -3994,10 +4257,18 @@ "node": ">= 0.6" } }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "bin": { "acorn": "bin/acorn" }, @@ -4005,19 +4276,21 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "license": "MIT", + "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==", "peerDependencies": { - "acorn": "^8" + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -4043,14 +4316,14 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4073,39 +4346,21 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "peerDependencies": { - "ajv": "^6.9.1" + "ajv": "^8.8.2" } }, "node_modules/algoliasearch": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.24.0.tgz", "integrity": "sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==", - "license": "MIT", "dependencies": { "@algolia/cache-browser-local-storage": "4.24.0", "@algolia/cache-common": "4.24.0", @@ -4125,10 +4380,9 @@ } }, "node_modules/algoliasearch-helper": { - "version": "3.22.4", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.4.tgz", - "integrity": "sha512-fvBCywguW9f+939S6awvRMstqMF1XXcd2qs1r1aGqL/PJ1go/DqN06tWmDVmhCDqBJanm++imletrQWf0G2S1g==", - "license": "MIT", + "version": "3.22.5", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.22.5.tgz", + "integrity": "sha512-lWvhdnc+aKOKx8jyA3bsdEgHzm/sglC4cYdMG4xSQyRiPLJVJtH/IVYZG3Hp6PkTEhQqhyVYkeP9z2IlcHJsWw==", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -4140,7 +4394,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.24.0.tgz", "integrity": "sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0", "@algolia/transporter": "4.24.0" @@ -4150,7 +4403,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.24.0.tgz", "integrity": "sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==", - "license": "MIT", "dependencies": { "@algolia/client-common": "4.24.0", "@algolia/requester-common": "4.24.0", @@ -4161,7 +4413,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz", "integrity": "sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0" } @@ -4170,7 +4421,6 @@ "version": "4.24.0", "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz", "integrity": "sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==", - "license": "MIT", "dependencies": { "@algolia/requester-common": "4.24.0" } @@ -4201,6 +4451,31 @@ "node": ">=8" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -4249,8 +4524,7 @@ "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" + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" }, "node_modules/argparse": { "version": "2.0.1", @@ -4258,9 +4532,9 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "node_modules/array-union": { "version": "2.1.0", @@ -4270,11 +4544,13 @@ "node": ">=8" } }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "license": "MIT" + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "bin": { + "astring": "bin/astring" + } }, "node_modules/at-least-node": { "version": "1.0.0", @@ -4285,9 +4561,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "funding": [ { "type": "opencollective", @@ -4296,14 +4572,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001464", - "fraction.js": "^4.2.0", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -4316,53 +4596,27 @@ "postcss": "^8.1.0" } }, - "node_modules/axios": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz", - "integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==", - "dependencies": { - "follow-redirects": "^1.14.7" - } + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" }, "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-plugin-apply-mdx-type-prop": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", - "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", - "dependencies": { - "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node": ">= 14.15.0" }, "peerDependencies": { - "@babel/core": "^7.11.6" + "@babel/core": "^7.12.0", + "webpack": ">=5" } }, - "node_modules/babel-plugin-apply-mdx-type-prop/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -4371,72 +4625,54 @@ "object.assign": "^4.1.0" } }, - "node_modules/babel-plugin-extract-import-names": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", - "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz", + "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", "dependencies": { - "@babel/helper-plugin-utils": "7.10.4" + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.6.2", + "semver": "^6.3.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/babel-plugin-extract-import-names/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", - "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", - "dependencies": { - "@babel/compat-data": "^7.17.7", - "@babel/helper-define-polyfill-provider": "^0.3.3", - "semver": "^6.1.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", - "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3", - "core-js-compat": "^3.25.1" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", - "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", + "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.3.3" + "@babel/helper-define-polyfill-provider": "^0.6.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4447,11 +4683,46 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base16": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz", - "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ==", - "license": "MIT" + "node_modules/bare-events": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", + "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "optional": true, + "dependencies": { + "streamx": "^2.20.0" + } }, "node_modules/base64-js": { "version": "1.5.1", @@ -4486,11 +4757,14 @@ } }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/bl": { @@ -4504,10 +4778,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "license": "MIT", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -4517,7 +4790,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -4531,7 +4804,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", "engines": { "node": ">= 0.8" } @@ -4540,24 +4812,31 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", "dependencies": { "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } @@ -4601,7 +4880,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -4610,9 +4888,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -4627,12 +4905,11 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -4677,58 +4954,46 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "10.2.14", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", + "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, + "node_modules/cacheable-request/node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "engines": { - "node": ">=8" - } - }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4771,14 +5036,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" - } - }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -4791,9 +5048,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001655", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001655.tgz", - "integrity": "sha512-jRGVy3iSGO5Uutn2owlb5gR6qsGngTw9ZTb4ali9f3glshcNmJ2noam4Mo9zia5P9Dk3jNNydy7vQjuE5dQmfg==", + "version": "1.0.30001679", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001679.tgz", + "integrity": "sha512-j2YqID/YwpLnKzCmBOS4tlZdWprXm3ZmQLBH9ZBXFOhoxLA46fwyBvx6toCBWBmnuwUY/qB3kEU6gFx8qgCroA==", "funding": [ { "type": "opencollective", @@ -4807,13 +5064,12 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ], - "license": "CC-BY-4.0" + ] }, "node_modules/ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4834,28 +5090,45 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "engines": { + "node": ">=10" + } + }, "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "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==", + "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==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "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==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "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==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4897,16 +5170,34 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/chevrotain": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", + "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", + "dependencies": { + "@chevrotain/cst-dts-gen": "11.0.3", + "@chevrotain/gast": "11.0.3", + "@chevrotain/regexp-to-ast": "11.0.3", + "@chevrotain/types": "11.0.3", + "@chevrotain/utils": "11.0.3", + "lodash-es": "4.17.21" + } + }, + "node_modules/chevrotain-allstar": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", + "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", + "dependencies": { + "lodash-es": "^4.17.21" + }, + "peerDependencies": { + "chevrotain": "^11.0.0" + } + }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4919,6 +5210,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -4929,17 +5223,17 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "funding": [ { "type": "github", @@ -4951,9 +5245,9 @@ } }, "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "dependencies": { "source-map": "~0.6.0" }, @@ -4961,6 +5255,14 @@ "node": ">= 10.0" } }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -4981,9 +5283,9 @@ } }, "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "dependencies": { "string-width": "^4.2.0" }, @@ -5025,29 +5327,18 @@ "node": ">=6" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "engines": { "node": ">=6" } }, "node_modules/collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5101,17 +5392,17 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" }, "node_modules/combine-promises": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.1.0.tgz", - "integrity": "sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", + "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", "engines": { "node": ">=10" } }, "node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5125,10 +5416,10 @@ "node": ">= 6" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" }, "node_modules/compressible": { "version": "2.0.18", @@ -5142,30 +5433,38 @@ } }, "node_modules/compressible/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", + "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", "engines": { "node": ">= 0.6" } }, "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz", + "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==", "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", + "bytes": "3.1.2", + "compressible": "~2.0.18", "debug": "2.6.9", + "negotiator": "~0.6.4", "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", + "safe-buffer": "5.2.1", "vary": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/compression/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -5179,30 +5478,41 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", + "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", "dependencies": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" + "dot-prop": "^6.0.1", + "graceful-fs": "^4.2.6", + "unique-string": "^3.0.0", + "write-file-atomic": "^3.0.3", + "xdg-basedir": "^5.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/yeoman/configstore?sponsor=1" } }, "node_modules/connect-history-api-fallback": { @@ -5214,9 +5524,12 @@ } }, "node_modules/consola": { - "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } }, "node_modules/consolidated-events": { "version": "2.0.2", @@ -5235,21 +5548,19 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "license": "MIT", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "engines": { "node": ">= 0.6" } @@ -5263,7 +5574,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -5294,32 +5604,6 @@ "webpack": "^5.1.0" } }, - "node_modules/copy-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/copy-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, "node_modules/copy-webpack-plugin/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5332,13 +5616,13 @@ } }, "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "13.1.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz", - "integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dependencies": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -5349,29 +5633,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/copy-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/copy-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/copy-webpack-plugin/node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -5384,9 +5645,9 @@ } }, "node_modules/core-js": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz", - "integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5394,11 +5655,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.30.2.tgz", - "integrity": "sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dependencies": { - "browserslist": "^4.21.5" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -5406,9 +5667,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.30.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.30.2.tgz", - "integrity": "sha512-p/npFUJXXBkCCTIlEGBdghofn00jWG6ZOtdoIXSJmAu2QBvN0IqpZXWweOytcwE6cfx8ZvVUy1vw8zxhe4Y2vg==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.39.0.tgz", + "integrity": "sha512-7fEcWwKI4rJinnK+wLTezeg2smbFFdSBP6E2kQZNbnzM2s1rpKQ6aaRteZSSg7FLU3P0HGGVo/gbpfanU36urg==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5429,33 +5690,34 @@ } }, "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz", - "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==", - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.12" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5466,37 +5728,54 @@ } }, "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "dependencies": { + "type-fest": "^1.0.1" + }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/css-declaration-sorter": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz", - "integrity": "sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew==", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=10" }, - "peerDependencies": { - "postcss": "^8.0.9" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/css-declaration-sorter": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.0.9" } }, "node_modules/css-loader": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.4.tgz", - "integrity": "sha512-0Y5uHtK5BswfaGJ+jrO+4pPg1msFBc0pwPIE1VqfpmVn6YbDfYfXMj8rfd7nt+4goAhJueO+H/I40VWJfcP1mQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", + "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.1", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" + "semver": "^7.5.4" }, "engines": { "node": ">= 12.13.0" @@ -5506,20 +5785,29 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", - "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", + "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", "dependencies": { - "cssnano": "^5.1.8", - "jest-worker": "^29.1.2", - "postcss": "^8.4.17", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" + "@jridgewell/trace-mapping": "^0.3.18", + "cssnano": "^6.0.1", + "jest-worker": "^29.4.3", + "postcss": "^8.4.24", + "schema-utils": "^4.0.1", + "serialize-javascript": "^6.0.1" }, "engines": { "node": ">= 14.15.0" @@ -5552,55 +5840,6 @@ } } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/css-select": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", @@ -5617,15 +5856,15 @@ } }, "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=8.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, "node_modules/css-what": { @@ -5651,122 +5890,137 @@ } }, "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/cssnano" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-advanced": { - "version": "5.3.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", - "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", - "license": "MIT", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", + "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", "dependencies": { - "autoprefixer": "^10.4.12", - "cssnano-preset-default": "^5.2.14", - "postcss-discard-unused": "^5.1.0", - "postcss-merge-idents": "^5.1.1", - "postcss-reduce-idents": "^5.2.0", - "postcss-zindex": "^5.1.0" + "autoprefixer": "^10.4.19", + "browserslist": "^4.23.0", + "cssnano-preset-default": "^6.1.2", + "postcss-discard-unused": "^6.0.5", + "postcss-merge-idents": "^6.0.3", + "postcss-reduce-idents": "^6.0.3", + "postcss-zindex": "^6.0.2" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", + "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", + "dependencies": { + "browserslist": "^4.23.0", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^4.0.2", + "postcss-calc": "^9.0.1", + "postcss-colormin": "^6.1.0", + "postcss-convert-values": "^6.1.0", + "postcss-discard-comments": "^6.0.2", + "postcss-discard-duplicates": "^6.0.3", + "postcss-discard-empty": "^6.0.3", + "postcss-discard-overridden": "^6.0.2", + "postcss-merge-longhand": "^6.0.5", + "postcss-merge-rules": "^6.1.1", + "postcss-minify-font-values": "^6.1.0", + "postcss-minify-gradients": "^6.0.3", + "postcss-minify-params": "^6.1.0", + "postcss-minify-selectors": "^6.0.4", + "postcss-normalize-charset": "^6.0.2", + "postcss-normalize-display-values": "^6.0.2", + "postcss-normalize-positions": "^6.0.2", + "postcss-normalize-repeat-style": "^6.0.2", + "postcss-normalize-string": "^6.0.2", + "postcss-normalize-timing-functions": "^6.0.2", + "postcss-normalize-unicode": "^6.1.0", + "postcss-normalize-url": "^6.0.2", + "postcss-normalize-whitespace": "^6.0.2", + "postcss-ordered-values": "^6.0.2", + "postcss-reduce-initial": "^6.1.0", + "postcss-reduce-transforms": "^6.0.2", + "postcss-svgo": "^6.0.3", + "postcss-unique-selectors": "^6.0.4" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", + "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dependencies": { - "css-tree": "^1.1.2" + "css-tree": "~2.2.0" }, "engines": { - "node": ">=8.0.0" + "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==", + "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==" + }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/cytoscape": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.25.0.tgz", - "integrity": "sha512-7MW3Iz57mCUo6JQCho6CmPBCbTlJr7LzyEtIkutG255HLVd4XuBg2I9BkTZLI/e4HoaOB/BiAzXuQybQ95+r9Q==", - "dependencies": { - "heap": "^0.2.6", - "lodash": "^4.17.21" - }, + "version": "3.30.3", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.3.tgz", + "integrity": "sha512-HncJ9gGJbVtw7YXtIs3+6YAFSSiKsom0amWc33Z7QbylbY2JGMrA0yz4EwrdTScZxnwclXeEZHzO5pxoy0ZE4g==", "engines": { "node": ">=0.10" } @@ -5807,9 +6061,9 @@ "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" }, "node_modules/d3": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", - "integrity": "sha512-q2WHStdhiBtD8DMmhDPyJmXUxr6VWRngKyiJ5EfXMxPw+tqT6BhNjhJZ4w3BHsNm3QoVfZLY8Orq/qPFczwKRA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", "dependencies": { "d3-array": "3", "d3-axis": "3", @@ -5847,9 +6101,9 @@ } }, "node_modules/d3-array": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.3.tgz", - "integrity": "sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "dependencies": { "internmap": "1 - 2" }, @@ -5973,17 +6227,6 @@ "node": ">= 10" } }, - "node_modules/d3-dsv/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -6025,9 +6268,9 @@ } }, "node_modules/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "dependencies": { "d3-array": "2.5.0 - 3" }, @@ -6086,6 +6329,41 @@ "node": ">=12" } }, + "node_modules/d3-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-array": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", + "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", + "dependencies": { + "internmap": "^1.0.0" + } + }, + "node_modules/d3-sankey/node_modules/d3-path": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", + "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" + }, + "node_modules/d3-sankey/node_modules/d3-shape": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", + "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", + "dependencies": { + "d3-path": "1" + } + }, + "node_modules/d3-sankey/node_modules/internmap": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", + "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" + }, "node_modules/d3-scale": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", @@ -6102,9 +6380,9 @@ } }, "node_modules/d3-scale-chromatic": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", - "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" @@ -6196,25 +6474,30 @@ } }, "node_modules/dagre-d3-es": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.9.tgz", - "integrity": "sha512-rYR4QfVmy+sR44IBDvVtcAmOReGBvRCWDpO2QjYwqgh9yijw6eSHBqaPG/LIOEy7aBsniLvtMW6pg19qJhq60w==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz", + "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==", "dependencies": { - "d3": "^7.8.2", + "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "node_modules/dayjs": { - "version": "1.11.7", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz", - "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -6225,15 +6508,30 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dependencies": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/deep-extend": { @@ -6264,15 +6562,17 @@ } }, "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -6294,10 +6594,11 @@ } }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -6330,11 +6631,11 @@ } }, "node_modules/delaunator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", - "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", "dependencies": { - "robust-predicates": "^3.0.0" + "robust-predicates": "^3.0.2" } }, "node_modules/depd": { @@ -6345,6 +6646,14 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -6354,22 +6663,10 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", - "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", - "dependencies": { - "repeat-string": "^1.5.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "engines": { "node": ">=8" } @@ -6380,9 +6677,9 @@ "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" }, "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", + "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", "dependencies": { "address": "^1.0.1", "debug": "4" @@ -6390,6 +6687,9 @@ "bin": { "detect": "bin/detect-port.js", "detect-port": "bin/detect-port.js" + }, + "engines": { + "node": ">= 4.0.0" } }, "node_modules/detect-port-alt": { @@ -6421,6 +6721,18 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "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==", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -6432,15 +6744,10 @@ "node": ">=8" } }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" - }, "node_modules/dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -6495,9 +6802,9 @@ } }, "node_modules/dompurify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.3.tgz", - "integrity": "sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==" + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", + "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==" }, "node_modules/domutils": { "version": "3.1.0", @@ -6522,14 +6829,17 @@ } }, "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "dependencies": { "is-obj": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dot-prop/node_modules/is-obj": { @@ -6545,11 +6855,6 @@ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6561,21 +6866,20 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.13", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", - "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", - "license": "ISC" - }, - "node_modules/elkjs": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", - "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" + "version": "1.5.55", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", + "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + }, "node_modules/emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -6585,18 +6889,18 @@ } }, "node_modules/emoticon": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-3.2.0.tgz", - "integrity": "sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", + "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } @@ -6613,7 +6917,6 @@ "version": "5.17.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -6645,7 +6948,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -6657,31 +6959,62 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==" + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" + }, + "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==", + "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==", + "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/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", + "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/escape-html": { @@ -6751,46 +7084,141 @@ "node": ">=4.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" + "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==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eta": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", - "engines": { - "node": ">=6.0.0" + "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==", + "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": { - "url": "https://github.com/eta-dev/eta?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" + "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==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "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==", "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" }, - "engines": { - "node": ">= 0.8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/eventemitter3": { + "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==", + "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-value-to-estree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.2.1.tgz", + "integrity": "sha512-Vt2UOjyPbNQQgT5eJh+K5aATti0OjCIAGc9SgMdOFYbohuifsWclR74l0iZTJwePMgWYdX1hlVS+dedH9XV8kw==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + } + }, + "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==", + "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==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eta": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", + "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "url": "https://github.com/eta-dev/eta?sponsor=1" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eval": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", + "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "dependencies": { + "@types/node": "*", + "require-like": ">= 0.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" @@ -6825,17 +7253,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -6845,37 +7262,36 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "license": "MIT", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -6886,11 +7302,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, "node_modules/express/node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -6916,9 +7327,9 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/express/node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", @@ -6949,10 +7360,15 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6969,22 +7385,31 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dependencies": { - "punycode": "^1.3.2" - } + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/faye-websocket": { "version": "0.11.4", "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", @@ -6996,36 +7421,6 @@ "node": ">=0.8.0" } }, - "node_modules/fbemitter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fbemitter/-/fbemitter-3.0.0.tgz", - "integrity": "sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw==", - "license": "BSD-3-Clause", - "dependencies": { - "fbjs": "^3.0.0" - } - }, - "node_modules/fbjs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz", - "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==", - "license": "MIT", - "dependencies": { - "cross-fetch": "^3.1.5", - "fbjs-css-vars": "^1.0.0", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^1.0.35" - } - }, - "node_modules/fbjs-css-vars": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", - "license": "MIT" - }, "node_modules/feed": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", @@ -7037,6 +7432,28 @@ "node": ">=0.4.0" } }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/file-loader": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", @@ -7056,10 +7473,38 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/file-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/file-loader/node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -7085,7 +7530,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -7094,12 +7538,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -7124,57 +7568,53 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/flux": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/flux/-/flux-4.0.4.tgz", - "integrity": "sha512-NCj3XlayA2UsapRpM7va6wU1+9rE5FIL7qoMcmxWHRzbp0yujihMBm9BBHZ1MDIk5h5o2Bl6eGiCe8rYELAmYw==", - "license": "BSD-3-Clause", - "dependencies": { - "fbemitter": "^3.0.0", - "fbjs": "^3.0.1" - }, - "peerDependencies": { - "react": "^15.0.2 || ^16.0.0 || ^17.0.0" + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "bin": { + "flat": "cli.js" } }, "node_modules/follow-redirects": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", - "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -7222,6 +7662,29 @@ } } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -7251,6 +7714,11 @@ "node": ">=10" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", @@ -7276,6 +7744,22 @@ "node": ">=6" } }, + "node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "engines": { + "node": ">= 14.17" + } + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -7285,15 +7769,15 @@ } }, "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "engines": { "node": "*" }, "funding": { "type": "patreon", - "url": "https://www.patreon.com/infusion" + "url": "https://github.com/sponsors/rawify" } }, "node_modules/fresh": { @@ -7310,33 +7794,45 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.14" } }, "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==" }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, + "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, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7353,7 +7849,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -7374,14 +7869,14 @@ "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" }, "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dependencies": { - "pump": "^3.0.0" - }, + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/github-from-package": { @@ -7398,6 +7893,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7427,8 +7923,7 @@ "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" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" }, "node_modules/global-dirs": { "version": "3.0.1", @@ -7518,7 +8013,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -7527,24 +8021,38 @@ } }, "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", + "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=8.6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", + "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/graceful-fs": { @@ -7600,22 +8108,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/hachure-fill": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", + "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==" + }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7628,7 +8130,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -7637,9 +8138,9 @@ } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "engines": { "node": ">= 0.4" }, @@ -7659,18 +8160,20 @@ } }, "node_modules/has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", + "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -7678,35 +8181,65 @@ "node": ">= 0.4" } }, - "node_modules/hast-to-hyperscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", - "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", + "node_modules/hast-util-from-dom": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-5.0.0.tgz", + "integrity": "sha512-d6235voAp/XR3Hh5uy7aGLbM3S4KamdW0WEgOaU1YoewnuYw4HXb5eRtv9g65m/RFGEfUY1Mw4UqCc5Y8L4Stg==", "dependencies": { - "@types/unist": "^2.0.3", - "comma-separated-tokens": "^1.0.0", - "property-information": "^5.3.0", - "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.3.0", - "unist-util-is": "^4.0.0", - "web-namespaces": "^1.0.0" + "@types/hast": "^3.0.0", + "hastscript": "^8.0.0", + "web-namespaces": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-from-parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", - "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", + "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==", + "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-html-isomorphic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-2.0.0.tgz", + "integrity": "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==", "dependencies": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" + "@types/hast": "^3.0.0", + "hast-util-from-dom": "^5.0.0", + "hast-util-from-html": "^2.0.0", + "unist-util-remove-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" }, "funding": { "type": "opencollective", @@ -7714,59 +8247,131 @@ } }, "node_modules/hast-util-is-element": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-1.1.0.tgz", - "integrity": "sha512-oUmNua0bFbdrD/ELDSSEadRVtWZOf3iF6Lbv81naqsIV99RnSCieTbWuWCY8BAeEfKJTKl0gRdokv+dELutHGQ==", + "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==", + "dependencies": { + "@types/hast": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-raw": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", - "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", - "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^6.0.0", - "hast-util-to-parse5": "^6.0.0", - "html-void-elements": "^1.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.4.tgz", + "integrity": "sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==", + "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-raw/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "node_modules/hast-util-to-estree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", + "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "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": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree/node_modules/inline-style-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", + "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + }, + "node_modules/hast-util-to-estree/node_modules/style-to-object": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "dependencies": { + "inline-style-parser": "0.1.1" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", + "integrity": "sha512-1ngXYb+V9UT5h+PxNRa1O1FYguZK/XL+gkeqvp7EdHlB9oHUG0eYRo/vY5inBdcqo3RkPMC58/H94HvkbfGdyg==", + "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": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^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": "6.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", - "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", "dependencies": { - "hast-to-hyperscript": "^9.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", @@ -7774,13 +8379,26 @@ } }, "node_modules/hast-util-to-text": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-2.0.1.tgz", - "integrity": "sha512-8nsgCARfs6VkwH2jJU9b8LNTuR4700na+0h3PqCaEk4MAnMDeu5P0tP8mjk9LLNGxIeQRLbiDbZVw6rku+pYsQ==", + "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==", + "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==", "dependencies": { - "hast-util-is-element": "^1.0.0", - "repeat-string": "^1.0.0", - "unist-util-find-after": "^3.0.0" + "@types/hast": "^3.0.0" }, "funding": { "type": "opencollective", @@ -7788,15 +8406,15 @@ } }, "node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" }, "funding": { "type": "opencollective", @@ -7811,11 +8429,6 @@ "he": "bin/he" } }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" - }, "node_modules/history": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", @@ -7881,36 +8494,51 @@ } }, "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz", + "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", + "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", "dependencies": { "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", + "clean-css": "~5.3.2", + "commander": "^10.0.0", + "entities": "^4.4.0", "param-case": "^3.0.4", "relateurl": "^0.2.7", - "terser": "^5.10.0" + "terser": "^5.15.1" }, "bin": { "html-minifier-terser": "cli.js" }, "engines": { - "node": ">=12" + "node": "^14.13.1 || >=16.0.0" } }, "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "engines": { - "node": ">= 12" + "node": ">=14" } }, "node_modules/html-tags": { @@ -7925,18 +8553,18 @@ } }, "node_modules/html-void-elements": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", - "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/html-webpack-plugin": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.1.tgz", - "integrity": "sha512-cTUzZ1+NqjGEKjmVgZKLMdiFg3m9MdRXkZW2OEe69WYVi5ONLMmlnSZdXzGGMOq0C8jGDrL6EWyEDDUioHO/pA==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz", + "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==", "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -7952,7 +8580,44 @@ "url": "https://opencollective.com/html-webpack-plugin" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "webpack": "^5.20.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/html-webpack-plugin/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" } }, "node_modules/htmlparser2": { @@ -8017,9 +8682,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -8050,6 +8715,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -8059,12 +8736,11 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" @@ -8101,17 +8777,17 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "engines": { "node": ">= 4" } }, "node_modules/image-size": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", - "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", + "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", "dependencies": { "queue": "6.0.2" }, @@ -8119,7 +8795,7 @@ "image-size": "bin/image-size.js" }, "engines": { - "node": ">=14.0.0" + "node": ">=16.x" } }, "node_modules/immer": { @@ -8147,11 +8823,11 @@ } }, "node_modules/import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/imurmurhash": { @@ -8171,10 +8847,9 @@ } }, "node_modules/infima": { - "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", - "license": "MIT", + "version": "0.2.0-alpha.45", + "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", + "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", "engines": { "node": ">=12" } @@ -8183,6 +8858,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -8199,9 +8875,9 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", + "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==" }, "node_modules/internmap": { "version": "2.0.3", @@ -8228,29 +8904,29 @@ } }, "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "engines": { "node": ">= 10" } }, "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" }, "funding": { "type": "github", @@ -8273,59 +8949,35 @@ "node": ">=8" } }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "dependencies": { - "ci-info": "^2.0.0" + "ci-info": "^3.2.0" }, "bin": { "is-ci": "bin.js" } }, - "node_modules/is-ci/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8381,9 +9033,9 @@ } }, "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8405,11 +9057,11 @@ } }, "node_modules/is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", + "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8419,7 +9071,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -8449,11 +9100,14 @@ } }, "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-plain-object": { @@ -8499,24 +9153,6 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, - "node_modules/is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -8529,9 +9165,12 @@ } }, "node_modules/is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", + "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "engines": { + "node": ">=12" + } }, "node_modules/isarray": { "version": "0.0.1", @@ -8552,11 +9191,11 @@ } }, "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8568,12 +9207,12 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -8596,21 +9235,21 @@ } }, "node_modules/jiti": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", - "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "bin": { "jiti": "bin/jiti.js" } }, "node_modules/joi": { - "version": "17.9.2", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.9.2.tgz", - "integrity": "sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw==", + "version": "17.13.3", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", + "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "dependencies": { - "@hapi/hoek": "^9.0.0", - "@hapi/topo": "^5.0.0", - "@sideway/address": "^4.1.3", + "@hapi/hoek": "^9.3.0", + "@hapi/topo": "^5.1.0", + "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } @@ -8632,20 +9271,20 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -8653,9 +9292,9 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json5": { "version": "2.2.3", @@ -8680,15 +9319,15 @@ } }, "node_modules/katex": { - "version": "0.13.24", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.13.24.tgz", - "integrity": "sha512-jZxYuKCma3VS5UuxOx/rFV1QyGSl3Uy/i0kTJF3HgQ5xMinCQVF8Zd4bMY/9aI9b9A2pjIBOsjSSm68ykTAr8w==", + "version": "0.16.11", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", + "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" ], "dependencies": { - "commander": "^8.0.0" + "commander": "^8.3.0" }, "bin": { "katex": "cli.js" @@ -8703,17 +9342,17 @@ } }, "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dependencies": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "node_modules/khroma": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz", - "integrity": "sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -8731,32 +9370,47 @@ "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==", + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + }, + "node_modules/langium": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz", + "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==", + "dependencies": { + "chevrotain": "~11.0.3", + "chevrotain-allstar": "~0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.11", + "vscode-uri": "~3.0.8" + }, "engines": { - "node": ">= 8" + "node": ">=16.0.0" } }, "node_modules/latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", + "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", "dependencies": { - "package-json": "^6.3.0" + "package-json": "^8.1.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/launch-editor": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", - "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.9.1.tgz", + "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==", "dependencies": { "picocolors": "^1.0.0", - "shell-quote": "^1.7.3" + "shell-quote": "^1.8.1" } }, "node_modules/layout-base": { @@ -8773,11 +9427,14 @@ } }, "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -8806,15 +9463,33 @@ "node": ">=8.9.0" } }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "dependencies": { - "p-locate": "^4.1.0" + "p-locate": "^6.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -8827,23 +9502,11 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/lodash.curry": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz", - "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==", - "license": "MIT" - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, - "node_modules/lodash.flow": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", - "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw==", - "license": "MIT" - }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -8854,6 +9517,15 @@ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, + "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==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -8874,11 +9546,14 @@ } }, "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "engines": { - "node": ">=0.10.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lru-cache": { @@ -8889,56 +9564,375 @@ "yallist": "^3.0.2" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "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==", + "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==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/marked": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-13.0.3.tgz", + "integrity": "sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mdast-util-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", + "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.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.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", + "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", "dependencies": { - "semver": "^6.0.0" + "@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-find-and-replace/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==", "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "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==", + "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/markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", + "node_modules/mdast-util-frontmatter/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==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", + "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", "dependencies": { - "unist-util-remove": "^2.0.0" + "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-definitions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", - "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", + "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==", + "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-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", + "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "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==", + "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==", + "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==", + "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-math": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", + "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "longest-streak": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.1.0", + "unist-util-remove-position": "^5.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==", + "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==", + "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.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.3.tgz", + "integrity": "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==", + "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==", + "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==", "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", @@ -8946,125 +9940,1905 @@ } }, "node_modules/mdast-util-to-hast": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", - "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz", + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "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==", + "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==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.4.0.tgz", + "integrity": "sha512-mxCfEYvADJqOiHfGpJXLs4/fAjHz448rH0pfY5fAoxiz70rQiDSzUUy4dNET2T08i46IVpjohPd6WWbzmRHiPA==", + "dependencies": { + "@braintree/sanitize-url": "^7.0.1", + "@iconify/utils": "^2.1.32", + "@mermaid-js/parser": "^0.3.0", + "@types/d3": "^7.4.3", + "@types/dompurify": "^3.0.5", + "cytoscape": "^3.29.2", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.2.0", + "d3": "^7.9.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.11", + "dayjs": "^1.11.10", + "dompurify": "^3.0.11 <3.1.7", + "katex": "^0.16.9", + "khroma": "^2.1.0", + "lodash-es": "^4.17.21", + "marked": "^13.0.2", + "roughjs": "^4.6.6", + "stylis": "^4.3.1", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.1" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", + "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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.1", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz", + "integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-core-commonmark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "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==", + "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-directive/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dependencies": { + "fault": "^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-frontmatter/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "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==", + "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==", + "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-autolink-literal/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "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==", + "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-footnote/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "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==", + "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-strikethrough/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "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-table/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "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==", + "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==", + "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-task-list-item/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.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-math/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", + "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.1.tgz", + "integrity": "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@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-jsx/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "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==", + "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==", + "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==", + "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-extension-mdxjs-esm/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", + "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-label": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", + "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-label/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.2.tgz", + "integrity": "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-mdx-expression/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-space/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-title": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", + "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-title/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", + "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character/node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", + "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", + "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", + "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", + "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", + "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "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-decode-string/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", + "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-events-to-acorn": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", + "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/acorn": "^4.0.0", + "@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-events-to-acorn/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", + "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", + "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", + "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "micromark-util-types": "^2.0.0" } }, - "node_modules/mdast-util-to-string": { + "node_modules/micromark-util-sanitize-uri": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", - "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", + "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/memfs": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.1.tgz", - "integrity": "sha512-UWbFJKvj5k+nETdteFndTpYxdeTMox/ULeqX5k/dpaQJCCFmj5EeKv3dBcyO2xmkRAx2vppRu5dVG7SOtsGOzA==", + "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz", + "integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "fs-monkey": "^1.0.3" - }, - "engines": { - "node": ">= 4.0.0" + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { + "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/mermaid": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-9.4.3.tgz", - "integrity": "sha512-TLkQEtqhRSuEHSE34lh5bCa94KATCyluAXmFnNI2PRZwOpXFeqiJWwZl+d2CcemE1RS6QbbueSSq9QIg8Uxcyw==", + "node_modules/micromark-util-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", + "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark/node_modules/micromark-factory-space": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", + "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "@braintree/sanitize-url": "^6.0.0", - "cytoscape": "^3.23.0", - "cytoscape-cose-bilkent": "^4.1.0", - "cytoscape-fcose": "^2.1.0", - "d3": "^7.4.0", - "dagre-d3-es": "7.0.9", - "dayjs": "^1.11.7", - "dompurify": "2.4.3", - "elkjs": "^0.8.2", - "khroma": "^2.0.0", - "lodash-es": "^4.17.21", - "non-layered-tidy-tree-layout": "^2.0.2", - "stylis": "^4.1.2", - "ts-dedent": "^2.2.0", - "uuid": "^9.0.0", - "web-worker": "^1.2.0" + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/mermaid/node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "bin": { - "uuid": "dist/bin/uuid" + "node_modules/micromark/node_modules/micromark-util-character": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", + "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } + "node_modules/micromark/node_modules/micromark-util-symbol": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", + "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -9112,19 +11886,23 @@ } }, "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "dependencies": { - "schema-utils": "^4.0.0" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { "node": ">= 12.13.0" @@ -9137,55 +11915,6 @@ "webpack": "^5.0.0" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", @@ -9215,24 +11944,35 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "node_modules/mlly": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz", + "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==", + "dependencies": { + "acorn": "^8.12.1", + "pathe": "^1.1.2", + "pkg-types": "^1.2.0", + "ufo": "^1.5.4" + } + }, "node_modules/monaco-editor": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.38.0.tgz", - "integrity": "sha512-11Fkh6yzEmwx7O0YoLxeae0qEGFwmyPRlVxpg7oF9czOOCB/iCjdJrG5I67da5WiXK3YJCxoz9TJFE8Tfq/v9A==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz", + "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==", "peer": true }, "node_modules/mrmime": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", - "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "engines": { "node": ">=10" } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -9256,7 +11996,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -9270,9 +12009,9 @@ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "engines": { "node": ">= 0.6" } @@ -9292,9 +12031,9 @@ } }, "node_modules/node-abi": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.40.0.tgz", - "integrity": "sha512-zNy02qivjjRosswoYmPi8hIKJRr8MpQyeKT6qlcq/OnOgA3Rhoae+IYOqsM9V5+JnHWmxKnWOT2GxvtqdtOCXA==", + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", "dependencies": { "semver": "^7.3.5" }, @@ -9303,36 +12042,22 @@ } }, "node_modules/node-addon-api": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" }, "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", "dependencies": { - "whatwg-url": "^5.0.0" + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "node": ">=18" } }, "node_modules/node-forge": { @@ -9346,13 +12071,7 @@ "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "license": "MIT" - }, - "node_modules/non-layered-tidy-tree-layout": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", - "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -9371,11 +12090,11 @@ } }, "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", + "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9395,8 +12114,7 @@ "node_modules/nprogress": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", - "license": "MIT" + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" }, "node_modules/nth-check": { "version": "2.1.1", @@ -9406,7 +12124,71 @@ "boolbase": "^1.0.0" }, "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/null-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", + "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/null-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/null-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/null-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/null-loader/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/object-assign": { @@ -9421,7 +12203,6 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -9438,12 +12219,12 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -9525,36 +12306,39 @@ } }, "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "engines": { - "node": ">=6" + "node": ">=12.20" } }, "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "dependencies": { - "p-try": "^2.0.0" + "yocto-queue": "^1.0.0" }, "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "dependencies": { - "p-limit": "^2.2.0" + "p-limit": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -9592,27 +12376,26 @@ } }, "node_modules/package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", + "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", "dependencies": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" + "got": "^12.1.0", + "registry-auth-token": "^5.0.1", + "registry-url": "^6.0.0", + "semver": "^7.3.7" }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/package-json/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } + "node_modules/package-manager-detector": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.2.tgz", + "integrity": "sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==" }, "node_modules/param-case": { "version": "3.0.4", @@ -9635,22 +12418,29 @@ } }, "node_modules/parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", + "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "@types/unist": "^2.0.0", + "character-entities": "^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==" + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -9674,22 +12464,22 @@ "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dependencies": { - "domhandler": "^5.0.2", + "domhandler": "^5.0.3", "parse5": "^7.0.0" }, "funding": { @@ -9713,12 +12503,17 @@ "tslib": "^2.0.3" } }, + "node_modules/path-data-parser": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", + "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==" + }, "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-is-absolute": { @@ -9748,9 +12543,9 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dependencies": { "isarray": "0.0.1" } @@ -9763,11 +12558,15 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -9781,14 +12580,27 @@ } }, "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", "dependencies": { - "find-up": "^4.0.0" + "find-up": "^6.3.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-types": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.1.tgz", + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.2", + "pathe": "^1.1.2" } }, "node_modules/pkg-up": { @@ -9825,6 +12637,20 @@ "node": ">=6" } }, + "node_modules/pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", @@ -9844,10 +12670,24 @@ "node": ">=4" } }, + "node_modules/points-on-curve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", + "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==" + }, + "node_modules/points-on-path": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", + "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", + "dependencies": { + "path-data-parser": "0.1.0", + "points-on-curve": "0.2.0" + } + }, "node_modules/postcss": { - "version": "8.4.45", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz", - "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -9862,128 +12702,128 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", + "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", "dependencies": { - "postcss-selector-parser": "^6.0.9", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0" }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, "peerDependencies": { "postcss": "^8.2.2" } }, "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", + "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "colord": "^2.9.1", + "colord": "^2.9.3", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", + "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", + "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", + "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", + "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", + "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-discard-unused": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", - "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", - "license": "MIT", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", + "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-loader": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.0.tgz", - "integrity": "sha512-qLAFjvR2BFNz1H930P7mj1iuWJFjGey/nVhimfOAAQ1ZyPpcClAxP8+A55Sl8mBvM+K2a9Pjgdj10KpANWrNfw==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", + "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", "dependencies": { - "cosmiconfig": "^8.1.3", - "jiti": "^1.18.2", - "klona": "^2.0.6", - "semver": "^7.3.8" + "cosmiconfig": "^8.3.5", + "jiti": "^1.20.0", + "semver": "^7.5.4" }, "engines": { "node": ">= 14.15.0" @@ -9997,135 +12837,117 @@ "webpack": "^5.0.0" } }, - "node_modules/postcss-loader/node_modules/cosmiconfig": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", - "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", - "dependencies": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - } - }, "node_modules/postcss-merge-idents": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", - "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", - "license": "MIT", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", + "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", "dependencies": { - "cssnano-utils": "^3.1.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", + "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", "dependencies": { "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" + "stylehacks": "^6.1.1" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", + "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" + "cssnano-utils": "^4.0.2", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", + "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", + "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", + "colord": "^2.9.3", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", + "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", + "browserslist": "^4.23.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", + "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -10134,9 +12956,9 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.1.tgz", - "integrity": "sha512-Zr/dB+IlXaEqdoslLHhhqecwj73vc3rDmOpsBNBEVk7P2aqAlz+Ijy0fFbU5Ie9PtreDOIgGa9MsLWakVGl+fA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", + "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -10150,9 +12972,9 @@ } }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", + "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -10178,193 +13000,191 @@ } }, "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", + "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", + "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", + "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", + "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", + "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", + "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", + "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", + "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", "dependencies": { - "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", + "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", + "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", "dependencies": { - "cssnano-utils": "^3.1.0", + "cssnano-utils": "^4.0.2", "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-idents": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", - "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", - "license": "MIT", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", + "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", + "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", "dependencies": { - "browserslist": "^4.21.4", + "browserslist": "^4.23.0", "caniuse-api": "^3.0.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", + "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", "dependencies": { "postcss-value-parser": "^4.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "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==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -10374,47 +13194,46 @@ } }, "node_modules/postcss-sort-media-queries": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", - "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", - "license": "MIT", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", + "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", "dependencies": { - "sort-css-media-queries": "2.1.0" + "sort-css-media-queries": "2.2.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=14.0.0" }, "peerDependencies": { - "postcss": "^8.4.16" + "postcss": "^8.4.23" } }, "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", + "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", "dependencies": { "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" + "svgo": "^3.2.0" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >= 18" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", + "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", "dependencies": { - "postcss-selector-parser": "^6.0.5" + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/postcss-value-parser": { @@ -10423,21 +13242,20 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/postcss-zindex": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", - "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", - "license": "MIT", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", + "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", @@ -10459,12 +13277,30 @@ "node": ">=10" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/pretty-error": { @@ -10485,18 +13321,21 @@ } }, "node_modules/prism-react-renderer": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz", - "integrity": "sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.0.tgz", + "integrity": "sha512-327BsVCD/unU4CNLZTWVHyUHKnsqcvj2qbPlQ8MiBE2eq2rgctjigPA1Gp9HLF83kZ20zNN6jgizHJeEsyFYOw==", + "dependencies": { + "@types/prismjs": "^1.26.0", + "clsx": "^2.0.0" + }, "peerDependencies": { - "react": ">=0.14.9" + "react": ">=16.0.0" } }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", - "license": "MIT", "engines": { "node": ">=6" } @@ -10506,15 +13345,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "license": "MIT", - "dependencies": { - "asap": "~2.0.3" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -10538,17 +13368,19 @@ } }, "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - }, + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -10570,43 +13402,42 @@ } }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } }, "node_modules/pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", + "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", "dependencies": { - "escape-goat": "^2.0.0" + "escape-goat": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pure-color": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz", - "integrity": "sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA==", - "license": "MIT" - }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "license": "BSD-3-Clause", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -10642,6 +13473,22 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10662,7 +13509,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -10677,11 +13523,21 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/raw-loader": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", @@ -10698,9 +13554,37 @@ "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/raw-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/raw-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" } }, + "node_modules/raw-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/raw-loader/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -10741,29 +13625,16 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/react-base16-styling": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.6.0.tgz", - "integrity": "sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ==", - "license": "MIT", - "dependencies": { - "base16": "^1.0.0", - "lodash.curry": "^4.0.1", - "lodash.flow": "^3.3.0", - "pure-color": "^1.2.0" - } - }, "node_modules/react-dev-utils": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", @@ -10814,9 +13685,9 @@ } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "engines": { "node": ">= 12.13.0" } @@ -10863,17 +13734,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/react-dev-utils/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-error-overlay": { @@ -10907,20 +13796,15 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "node_modules/react-json-view": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/react-json-view/-/react-json-view-1.21.3.tgz", - "integrity": "sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw==", - "license": "MIT", - "dependencies": { - "flux": "^4.0.1", - "react-base16-styling": "^0.6.0", - "react-lifecycles-compat": "^3.0.4", - "react-textarea-autosize": "^8.3.2" + "node_modules/react-json-view-lite": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.5.0.tgz", + "integrity": "sha512-nWqA1E4jKPklL2jvHWs6s+7Na0qNgw9HCP6xehdQJeg6nPBTFZgGwyko9Q0oj+jQWKTTVRS30u0toM5wiuL3iw==", + "engines": { + "node": ">=14" }, "peerDependencies": { - "react": "^17.0.0 || ^16.3.0 || ^15.5.4", - "react-dom": "^17.0.0 || ^16.3.0 || ^15.5.4" + "react": "^16.13.1 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-katex": { @@ -10935,44 +13819,13 @@ "react": ">=15.3.2 <=18" } }, - "node_modules/react-katex/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/react-katex/node_modules/katex": { - "version": "0.16.11", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz", - "integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==", - "funding": [ - "https://opencollective.com/katex", - "https://github.com/sponsors/katex" - ], - "license": "MIT", - "dependencies": { - "commander": "^8.3.0" - }, - "bin": { - "katex": "cli.js" - } - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", - "license": "MIT" - }, "node_modules/react-loadable": { "name": "@docusaurus/react-loadable", - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", + "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "dependencies": { - "@types/react": "*", - "prop-types": "^15.6.2" + "@types/react": "*" }, "peerDependencies": { "react": "*" @@ -11041,23 +13894,6 @@ "react": ">=15" } }, - "node_modules/react-textarea-autosize": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", - "integrity": "sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.20.13", - "use-composed-ref": "^1.3.0", - "use-latest": "^1.2.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/react-waypoint": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/react-waypoint/-/react-waypoint-10.3.0.tgz", @@ -11073,9 +13909,9 @@ } }, "node_modules/react-waypoint/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" }, "node_modules/readable-stream": { "version": "3.6.2", @@ -11117,6 +13953,66 @@ "node": ">= 0.10" } }, + "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==", + "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.0", + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.0.tgz", + "integrity": "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q==", + "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" + } + }, + "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==", + "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==", + "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/recursive-readdir": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", @@ -11134,9 +14030,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dependencies": { "regenerate": "^1.4.2" }, @@ -11145,27 +14041,27 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", + "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.11.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -11174,80 +14070,91 @@ } }, "node_modules/registry-auth-token": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", - "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", "dependencies": { - "rc": "1.2.8" + "@pnpm/npm-conf": "^2.1.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=14" } }, "node_modules/registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", "dependencies": { - "rc": "^1.2.8" + "rc": "1.2.8" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", + "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, "node_modules/rehype-katex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-5.0.0.tgz", - "integrity": "sha512-ksSuEKCql/IiIadOHiKRMjypva9BLhuwQNascMqaoGLDVd0k2NlE2wMvgZ3rpItzRKCd6vs8s7MFbb8pcR0AEg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz", + "integrity": "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==", "dependencies": { - "@types/katex": "^0.11.0", - "hast-util-to-text": "^2.0.0", - "katex": "^0.13.0", - "rehype-parse": "^7.0.0", - "unified": "^9.0.0", - "unist-util-visit": "^2.0.0" + "@types/hast": "^3.0.0", + "@types/katex": "^0.16.0", + "hast-util-from-html-isomorphic": "^2.0.0", + "hast-util-to-text": "^4.0.0", + "katex": "^0.16.0", + "unist-util-visit-parents": "^6.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-parse": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-7.0.1.tgz", - "integrity": "sha512-fOiR9a9xH+Le19i4fGzIEowAbwG7idy2Jzs4mOrFWBSJ0sNUgy0ev871dwWnbOo371SjgjG4pwzrbgSVrKxecw==", + "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==", "dependencies": { - "hast-util-from-parse5": "^6.0.0", - "parse5": "^6.0.0" + "@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-parse/node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "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==", + "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/relateurl": { "version": "0.2.7", @@ -11257,179 +14164,135 @@ "node": ">= 0.10" } }, - "node_modules/remark-emoji": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-2.2.0.tgz", - "integrity": "sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w==", + "node_modules/remark-directive": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", + "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", "dependencies": { - "emoticon": "^3.2.0", - "node-emoji": "^1.10.0", - "unist-util-visit": "^2.0.3" - } - }, - "node_modules/remark-footnotes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", - "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", + "@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-math": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-3.0.1.tgz", - "integrity": "sha512-epT77R/HK0x7NqrWHdSV75uNLwn8g9qTyMqCRCDujL0vj/6T6+yhdrR7mjELWtkse+Fw02kijAaBuVcHBor1+Q==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/remark-emoji": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", + "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "dependencies": { + "@types/mdast": "^4.0.2", + "emoticon": "^4.0.1", + "mdast-util-find-and-replace": "^3.0.1", + "node-emoji": "^2.1.0", + "unified": "^11.0.4" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/remark-mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", - "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "node_modules/remark-frontmatter": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", + "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", "dependencies": { - "@babel/core": "7.12.9", - "@babel/helper-plugin-utils": "7.10.4", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-syntax-jsx": "7.12.1", - "@mdx-js/util": "1.6.22", - "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.2.0" + "@types/mdast": "^4.0.0", + "mdast-util-frontmatter": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0", + "unified": "^11.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" + "node_modules/remark-gfm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", + "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "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/babel" + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, - "node_modules/remark-mdx/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "node_modules/remark-math": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-6.0.0.tgz", + "integrity": "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" + "@types/mdast": "^4.0.0", + "mdast-util-math": "^3.0.0", + "micromark-extension-math": "^3.0.0", + "unified": "^11.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/plugin-syntax-jsx": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", - "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", + "node_modules/remark-mdx": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.0.tgz", + "integrity": "sha512-Ngl/H3YXyBV9RcRNdlYsZujAmhsxwzxpDzpDEhFBVAGthS4GDgnctpDjgFl/ULx5UEDzqtW1cyBSNKqYYrqLBA==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/remark-mdx/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/remark-mdx/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "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==", "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "@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-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", - "dependencies": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "node_modules/remark-rehype": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.1.tgz", + "integrity": "sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==", + "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-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", + "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==", "dependencies": { - "mdast-squeeze-paragraphs": "^4.0.0" + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" }, "funding": { "type": "opencollective", @@ -11559,11 +14422,11 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { - "is-core-module": "^2.11.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -11574,6 +14437,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -11588,11 +14456,17 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" }, "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dependencies": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/retry": { @@ -11616,100 +14490,53 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dependencies": { "glob": "^7.1.3" }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/robust-predicates": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz", - "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g==" - }, - "node_modules/rtl-detect": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.0.4.tgz", - "integrity": "sha512-EBR4I2VDSSYr7PkBmFy04uhycIpDKp+21p/jARYXlCSjQksTBQcJ0HFUPOO79EPPH5JS6VAhiIQbycf0O3JAxQ==" - }, - "node_modules/rtlcss": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-3.5.0.tgz", - "integrity": "sha512-wzgMaMFHQTnyi9YOwsx9LjOxYXJPzS8sYnFaKm6R5ysvTkwzHiB0vxnbHwchHQT65PTdBjDG21/kQBWI7q9O7A==", - "license": "MIT", - "dependencies": { - "find-up": "^5.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.3.11", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "rtlcss": "bin/rtlcss.js" - } - }, - "node_modules/rtlcss/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rtlcss/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" + "bin": { + "rimraf": "bin.js" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rtlcss/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, + "node_modules/roughjs": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", + "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "hachure-fill": "^0.5.2", + "path-data-parser": "^0.1.0", + "points-on-curve": "^0.2.0", + "points-on-path": "^0.2.1" } }, - "node_modules/rtlcss/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "license": "MIT", + "node_modules/rtl-detect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", + "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + }, + "node_modules/rtlcss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", "dependencies": { - "p-limit": "^3.0.2" + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" }, - "engines": { - "node": ">=10" + "bin": { + "rtlcss": "bin/rtlcss.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=12.0.0" } }, "node_modules/run-parallel": { @@ -11739,14 +14566,6 @@ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dependencies": { - "tslib": "^2.1.0" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11772,30 +14591,30 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" }, "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 8.9.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -11803,10 +14622,9 @@ } }, "node_modules/search-insights": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.1.tgz", - "integrity": "sha512-HHFjYH/0AqXacETlIbe9EYc3UNlQYGNNTY0fZ/sWl6SweX+GDxq9NB5+RVoPLgEFuOtCz7M9dhYxqDnhbbF0eQ==", - "license": "MIT", + "version": "2.17.2", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.2.tgz", + "integrity": "sha512-zFNpOpUO+tY2D85KrxJ+aqwnIfdEGi06UH2+xEb+Bp9Mwznmauqc9djbnBibJO5mpfUPPa8st6Sx65+vbeO45g==", "peer": true }, "node_modules/section-matter": { @@ -11827,10 +14645,11 @@ "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" }, "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "dependencies": { + "@types/node-forge": "^1.3.0", "node-forge": "^1" }, "engines": { @@ -11841,7 +14660,6 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -11850,29 +14668,23 @@ } }, "node_modules/semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", + "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", "dependencies": { - "semver": "^6.3.0" + "semver": "^7.3.5" }, "engines": { - "node": ">=8" - } - }, - "node_modules/semver-diff/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -11905,10 +14717,13 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/send/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==" + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", @@ -11919,32 +14734,31 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", + "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", + "path-to-regexp": "3.3.0", "range-parser": "1.2.0" } }, "node_modules/serve-handler/node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==" }, "node_modules/serve-index": { "version": "1.9.1", @@ -12017,14 +14831,14 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -12034,7 +14848,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -12047,12 +14860,6 @@ "node": ">= 0.4" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -12075,22 +14882,22 @@ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" }, "node_modules/sharp": { - "version": "0.30.7", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz", - "integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==", + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.1", - "node-addon-api": "^5.0.0", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", "prebuild-install": "^7.1.1", - "semver": "^7.3.7", + "semver": "^7.5.4", "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", + "tar-fs": "^3.0.4", "tunnel-agent": "^0.6.0" }, "engines": { - "node": ">=12.13.0" + "node": ">=14.15.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -12143,7 +14950,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -12205,31 +15011,6 @@ "simple-concat": "^1.0.0" } }, - "node_modules/simple-get/node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/simple-get/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -12244,13 +15025,13 @@ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, "node_modules/sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { "node": ">= 10" @@ -12265,7 +15046,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", - "license": "MIT", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", @@ -12283,8 +15063,18 @@ "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" + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } }, "node_modules/slash": { "version": "3.0.0", @@ -12294,6 +15084,15 @@ "node": ">=8" } }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/sockjs": { "version": "0.3.24", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", @@ -12304,28 +15103,34 @@ "websocket-driver": "^0.7.4" } }, + "node_modules/sockjs/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/sort-css-media-queries": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", - "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", - "license": "MIT", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", + "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", "engines": { "node": ">= 6.3.0" } }, "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "license": "BSD-3-Clause", + "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==", "engines": { "node": ">=0.10.0" } @@ -12339,10 +15144,18 @@ "source-map": "^0.6.0" } }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -12381,26 +15194,22 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + "node_modules/srcset": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", + "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==" }, - "node_modules/state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -12410,9 +15219,22 @@ } }, "node_modules/std-env": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.3.tgz", - "integrity": "sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==" + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==" + }, + "node_modules/streamx": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } }, "node_modules/string_decoder": { "version": "1.3.0", @@ -12439,9 +15261,9 @@ } }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "engines": { "node": ">=12" }, @@ -12450,9 +15272,9 @@ } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -12463,6 +15285,19 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "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==", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/stringify-object": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", @@ -12507,7 +15342,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", "engines": { "node": ">=8" }, @@ -12516,32 +15350,32 @@ } }, "node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", + "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==", "dependencies": { - "inline-style-parser": "0.1.1" + "inline-style-parser": "0.2.4" } }, "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", + "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" + "browserslist": "^4.23.0", + "postcss-selector-parser": "^6.0.16" }, "engines": { - "node": "^10 || ^12 || >=14.0" + "node": "^14 || ^16 || >=18.0" }, "peerDependencies": { - "postcss": "^8.2.15" + "postcss": "^8.4.31" } }, "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.4.tgz", + "integrity": "sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==" }, "node_modules/supports-color": { "version": "7.2.0", @@ -12571,94 +15405,35 @@ "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" }, "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" }, "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/svgo" } }, - "node_modules/svgo/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" } }, "node_modules/tapable": { @@ -12670,36 +15445,32 @@ } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" } }, "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", - "license": "BSD-2-Clause", + "version": "5.36.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", + "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -12717,7 +15488,6 @@ "version": "5.3.10", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", - "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -12747,6 +15517,29 @@ } } }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -12760,10 +15553,15 @@ "node": ">= 10.13.0" } }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -12796,6 +15594,11 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, + "node_modules/text-decoder": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", + "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==" + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12807,36 +15610,24 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "node_modules/tiny-invariant": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" }, "node_modules/tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "engines": { - "node": ">=6" - } + "node_modules/tinyexec": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -12853,38 +15644,26 @@ } }, "node_modules/totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "engines": { "node": ">=6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead" - }, - "node_modules/trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "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==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -12899,9 +15678,9 @@ } }, "node_modules/tslib": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz", - "integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==" + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -12929,7 +15708,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -12942,7 +15720,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", "engines": { "node": ">= 0.6" } @@ -12951,7 +15728,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -12968,58 +15744,40 @@ } }, "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=14.17" } }, - "node_modules/ua-parser-js": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.38.tgz", - "integrity": "sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "license": "MIT", - "engines": { - "node": "*" - } + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" }, - "node_modules/unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "engines": { "node": ">=4" } @@ -13037,9 +15795,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "engines": { "node": ">=4" } @@ -13053,16 +15811,17 @@ } }, "node_modules/unified": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.2.tgz", - "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "dependencies": { - "bail": "^1.0.0", + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" }, "funding": { "type": "opencollective", @@ -13070,70 +15829,62 @@ } }, "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", + "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dependencies": { - "crypto-random-string": "^2.0.0" + "crypto-random-string": "^4.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/unist-builder": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-builder/-/unist-builder-2.0.3.tgz", - "integrity": "sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==", + "node": ">=12" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/unist-util-find-after": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-3.0.0.tgz", - "integrity": "sha512-ojlBqfsBftYXExNu3+hHLfJQ/X1jYY/9vdm4yZWjIbf0VuWF6CRufci1ZyoD/wV2TYMKxXUoNuoqwy+CkgzAiQ==", + "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==", "dependencies": { - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-generated": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", - "integrity": "sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": { + "@types/unist": "^3.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", - "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", + "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==", "dependencies": { - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", @@ -13141,11 +15892,12 @@ } }, "node_modules/unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" }, "funding": { "type": "opencollective", @@ -13153,11 +15905,11 @@ } }, "node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "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==", "dependencies": { - "@types/unist": "^2.0.2" + "@types/unist": "^3.0.0" }, "funding": { "type": "opencollective", @@ -13165,13 +15917,13 @@ } }, "node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", @@ -13179,12 +15931,12 @@ } }, "node_modules/unist-util-visit-parents": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz", - "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" }, "funding": { "type": "opencollective", @@ -13192,9 +15944,9 @@ } }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "engines": { "node": ">= 10.0.0" } @@ -13208,9 +15960,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -13225,10 +15977,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -13238,118 +15989,73 @@ } }, "node_modules/update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dependencies": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", + "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "dependencies": { + "boxen": "^7.0.0", + "chalk": "^5.0.1", + "configstore": "^6.0.0", + "has-yarn": "^3.0.0", + "import-lazy": "^4.0.0", + "is-ci": "^3.0.1", "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" + "is-npm": "^6.0.0", + "is-yarn-global": "^0.4.0", + "latest-version": "^7.0.0", + "pupa": "^3.1.0", + "semver": "^7.3.7", + "semver-diff": "^4.0.0", + "xdg-basedir": "^5.1.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, "node_modules/update-notifier/node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", + "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" + "ansi-align": "^3.0.1", + "camelcase": "^7.0.1", + "chalk": "^5.2.0", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.1.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/update-notifier/node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "engines": { - "node": ">=6" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/update-notifier/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==" - }, - "node_modules/update-notifier/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==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/update-notifier/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/update-notifier/node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/update-notifier/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/uri-js": { @@ -13360,14 +16066,6 @@ "punycode": "^2.1.0" } }, - "node_modules/uri-js/node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, "node_modules/url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", @@ -13394,6 +16092,34 @@ } } }, + "node_modules/url-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/url-loader/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/url-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/url-loader/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -13414,9 +16140,9 @@ } }, "node_modules/url-loader/node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13430,65 +16156,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", - "license": "MIT", - "dependencies": { - "use-isomorphic-layout-effect": "^1.1.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -13500,9 +16167,9 @@ "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" }, "node_modules/utility-types": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz", - "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", "engines": { "node": ">= 4" } @@ -13516,9 +16183,13 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { "uuid": "dist/bin/uuid" } @@ -13537,14 +16208,12 @@ } }, "node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" }, "funding": { "type": "opencollective", @@ -13552,50 +16221,78 @@ } }, "node_modules/vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/wait-on": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-6.0.1.tgz", - "integrity": "sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw==", + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", "dependencies": { - "axios": "^0.25.0", - "joi": "^17.6.0", - "lodash": "^4.17.21", - "minimist": "^1.2.5", - "rxjs": "^7.5.4" + "vscode-languageserver-protocol": "3.17.5" }, "bin": { - "wait-on": "bin/wait-on" - }, - "engines": { - "node": ">=10.0.0" + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" } }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, "node_modules/watchpack": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -13613,38 +16310,26 @@ } }, "node_modules/web-namespaces": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", - "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, "node_modules/webpack": { - "version": "5.94.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", - "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", - "license": "MIT", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "dependencies": { - "@types/estree": "^1.0.5", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", @@ -13679,19 +16364,21 @@ } }, "node_modules/webpack-bundle-analyzer": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.8.0.tgz", - "integrity": "sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", "gzip-size": "^6.0.0", - "lodash": "^4.17.20", + "html-escaper": "^2.0.2", "opener": "^1.5.2", - "sirv": "^1.0.7", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", "ws": "^7.3.1" }, "bin": { @@ -13713,7 +16400,6 @@ "version": "5.3.4", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -13732,37 +16418,6 @@ "webpack": "^4.0.0 || ^5.0.0" } }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "node_modules/webpack-dev-middleware/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -13790,28 +16445,10 @@ "node": ">= 0.6" } }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", - "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", + "version": "4.15.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz", + "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -13819,7 +16456,7 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", @@ -13841,7 +16478,7 @@ "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", + "webpack-dev-middleware": "^5.3.4", "ws": "^8.13.0" }, "bin": { @@ -13866,60 +16503,10 @@ } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.1.tgz", - "integrity": "sha512-lELhBAAly9NowEsX0yZBlw9ahZG+sK/1RJ21EpzdYHKEs13Vku3LJ+MIPhh4sMs0oCCeufZQEQbMekiA4vuVIQ==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/webpack-dev-server/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" }, @@ -13937,15 +16524,16 @@ } }, "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dependencies": { "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" + "flat": "^5.0.2", + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-sources": { @@ -13956,6 +16544,34 @@ "node": ">=10.13.0" } }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, "node_modules/webpack/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -13979,7 +16595,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13994,22 +16609,72 @@ } }, "node_modules/webpackbar": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", "dependencies": { - "chalk": "^4.1.0", - "consola": "^2.15.3", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", "pretty-time": "^1.1.0", - "std-env": "^3.0.1" + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.21.3" }, "peerDependencies": { "webpack": "3 || 4 || 5" } }, + "node_modules/webpackbar/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==" + }, + "node_modules/webpackbar/node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/webpackbar/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==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/website_playground": { "resolved": "../website_playground/pkg", "link": true @@ -14035,16 +16700,6 @@ "node": ">=0.8.0" } }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -14095,9 +16750,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "engines": { "node": ">=12" }, @@ -14117,9 +16772,9 @@ } }, "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -14150,7 +16805,6 @@ "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -14168,11 +16822,14 @@ } }, "node_modules/xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/xml-js": { @@ -14186,14 +16843,6 @@ "xml-js": "bin/cli.js" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -14208,20 +16857,20 @@ } }, "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/docs/package.json b/docs/package.json index b59fcbc3c556..88bcabc662bd 100644 --- a/docs/package.json +++ b/docs/package.json @@ -15,24 +15,24 @@ "wasm-pack": "cd ../website_playground/ && wasm-pack build" }, "dependencies": { - "@docusaurus/core": "^2.4.3", - "@docusaurus/plugin-ideal-image": "^2.4.3", - "@docusaurus/preset-classic": "^2.4.3", - "@docusaurus/theme-mermaid": "^2.4.3", - "@mdx-js/react": "^1.6.22", + "@docusaurus/core": "^3.6.1", + "@docusaurus/plugin-ideal-image": "^3.6.1", + "@docusaurus/preset-classic": "^3.6.1", + "@docusaurus/theme-mermaid": "^3.6.1", + "@mdx-js/react": "^3.1.0", "@monaco-editor/react": "^4.4.6", - "mermaid": "^9.3.0", - "prism-react-renderer": "^1.3.5", + "mermaid": "^11.4.0", + "prism-react-renderer": "^2.4.0", "raw-loader": "^4.0.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-katex": "^3.0.1", - "rehype-katex": "^5.0.0", - "remark-math": "^3.0.1", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "website_playground": "file:../website_playground/pkg" }, "devDependencies": { - "@docusaurus/module-type-aliases": "^2.4.3" + "@docusaurus/module-type-aliases": "^3.6.1" }, "browserslist": { "production": [ @@ -47,6 +47,6 @@ ] }, "engines": { - "node": ">=16.14" + "node": ">=18.0" } } diff --git a/docs/src/pages/img/papers/auto-compartmentalization-src.png b/docs/src/pages/img/papers/auto-compartmentalization-src.png index 8785f09babac..042616266336 100644 Binary files a/docs/src/pages/img/papers/auto-compartmentalization-src.png and b/docs/src/pages/img/papers/auto-compartmentalization-src.png differ diff --git a/docs/src/pages/img/papers/conor-papoc-2024.png b/docs/src/pages/img/papers/conor-papoc-2024.png index f0c3ce84da1e..83b1fb2a0998 100644 Binary files a/docs/src/pages/img/papers/conor-papoc-2024.png and b/docs/src/pages/img/papers/conor-papoc-2024.png differ diff --git a/docs/src/pages/img/papers/david-papoc-2024.png b/docs/src/pages/img/papers/david-papoc-2024.png index c73169aa34e8..da31070eb398 100644 Binary files a/docs/src/pages/img/papers/david-papoc-2024.png and b/docs/src/pages/img/papers/david-papoc-2024.png differ diff --git a/docs/src/pages/img/papers/david-sigmod-2024.png b/docs/src/pages/img/papers/david-sigmod-2024.png index f6751f75f505..ec1a62174cfb 100644 Binary files a/docs/src/pages/img/papers/david-sigmod-2024.png and b/docs/src/pages/img/papers/david-sigmod-2024.png differ diff --git a/docs/src/pages/img/papers/flo.png b/docs/src/pages/img/papers/flo.png new file mode 100644 index 000000000000..0bfb73dd8ded Binary files /dev/null and b/docs/src/pages/img/papers/flo.png differ diff --git a/docs/src/pages/img/papers/hydroflow-thesis.png b/docs/src/pages/img/papers/hydroflow-thesis.png index 40515491a2c3..4a11caf97105 100644 Binary files a/docs/src/pages/img/papers/hydroflow-thesis.png and b/docs/src/pages/img/papers/hydroflow-thesis.png differ diff --git a/docs/src/pages/img/papers/joe-applied-2023.png b/docs/src/pages/img/papers/joe-applied-2023.png index 8c2d958ec16b..9c829d5ded02 100644 Binary files a/docs/src/pages/img/papers/joe-applied-2023.png and b/docs/src/pages/img/papers/joe-applied-2023.png differ diff --git a/docs/src/pages/img/papers/katara.png b/docs/src/pages/img/papers/katara.png index eea111ce35ee..814bdffb83cd 100644 Binary files a/docs/src/pages/img/papers/katara.png and b/docs/src/pages/img/papers/katara.png differ diff --git a/docs/src/pages/img/papers/keep-calm-and-crdt-on.png b/docs/src/pages/img/papers/keep-calm-and-crdt-on.png index 714e5c493656..5edf3b579d1b 100644 Binary files a/docs/src/pages/img/papers/keep-calm-and-crdt-on.png and b/docs/src/pages/img/papers/keep-calm-and-crdt-on.png differ diff --git a/docs/src/pages/img/papers/new-directions.png b/docs/src/pages/img/papers/new-directions.png index a6d419e779d1..7e325e145346 100644 Binary files a/docs/src/pages/img/papers/new-directions.png and b/docs/src/pages/img/papers/new-directions.png differ diff --git a/docs/src/pages/img/papers/suki.png b/docs/src/pages/img/papers/suki.png new file mode 100644 index 000000000000..b3db39c9ead6 Binary files /dev/null and b/docs/src/pages/img/papers/suki.png differ diff --git a/docs/src/pages/img/papers/tiemo-cidr-2024.png b/docs/src/pages/img/papers/tiemo-cidr-2024.png index 0c0a9378f96d..4188c96c3c17 100644 Binary files a/docs/src/pages/img/papers/tiemo-cidr-2024.png and b/docs/src/pages/img/papers/tiemo-cidr-2024.png differ diff --git a/docs/src/pages/img/papers/tiemo-sigmod-2024.png b/docs/src/pages/img/papers/tiemo-sigmod-2024.png index bbddb6449653..7d519860207c 100644 Binary files a/docs/src/pages/img/papers/tiemo-sigmod-2024.png and b/docs/src/pages/img/papers/tiemo-sigmod-2024.png differ diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index c55173a9b8f3..7b89d377e3bb 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -26,7 +26,7 @@ export default function Home() { justifyContent: "center", flexWrap: "wrap" }}> - { - mermaid.render(id, source, svg => { + mermaid.render(id, source).then(({ svg }) => { setSvg({ __html: svg, }); diff --git a/docs/src/pages/research.js b/docs/src/pages/research.js index 6c01039f536b..5270d26891d3 100644 --- a/docs/src/pages/research.js +++ b/docs/src/pages/research.js @@ -6,13 +6,26 @@ import Image from '@theme/IdealImage'; import styles from './research.module.css'; const papers = [ + { + title: "Flo: a Semantic Foundation for Progressive Stream Processing", + pdf: "pathname:///papers/flo.pdf", + thumb: require("./img/papers/flo.png"), + authors: <>Shadaj Laddad, Alvin Cheung, Joseph M. Hellerstein, Mae Milano, + description: [ + <>Existing streaming languages have a variety of semantic models and guarantees that are often incompatible. In this paper, we identify two general yet precise semantic properties: streaming progress and eager execution. We formally define these properties in the context of Flo, a parameterized streaming language that abstracts over dataflow operators and the underlying structure of streams., + <>To demonstrate the generality of our properties, we show how key ideas from representative streaming and incremental computation systems—Flink, LVars, and DBSP—have semantics that can be modeled in Flo and guarantees that map to our properties. + ], + conf: "POPL 2025", + links: <>PDF / arXiv + }, { title: "Optimizing Distributed Protocols with Query Rewrites", pdf: "pathname:///papers/david-sigmod-2024.pdf", thumb: require("./img/papers/david-sigmod-2024.png"), authors: <>David Chu, Rithvik Panchapakesan, Shadaj Laddad, Lucky Katahanas, Chris Liu, Kaushik Shivakumar, Natacha Crooks, Joseph M. Hellerstein, & Heidi Howard, description: [ - <>Distributed protocols such as 2PC and Paxos lie at the core of many systems in the cloud, but standard implementations do not scale. New scalable distributed protocols are developed through careful analysis and rewrites, but this process is ad hoc and error-prone. This paper presents an approach for scaling any distributed protocol by applying rule-driven rewrites, borrowing from query optimization. Distributed protocol rewrites entail a new burden: reasoning about spatiotemporal correctness. We leverage order-insensitivity and data dependency analysis to systematically identify correct coordination-free scaling opportunities. We apply this analysis to create preconditions and mechanisms for coordination-free decoupling and partitioning, two fundamental vertical and horizontal scaling techniques. Manual rule-driven applications of decoupling and partitioning improve the throughput of 2PC by 5x and Paxos by 3x, and match state-of-the-art throughput in recent work. These results point the way toward automated optimizers for distributed protocols based on correct-by-construction rewrite rules. + <>Distributed protocols such as 2PC and Paxos lie at the core of many systems in the cloud, but standard implementations do not scale. New scalable distributed protocols are developed through careful analysis and rewrites, but this process is ad hoc and error-prone. This paper presents an approach for scaling any distributed protocol by applying rule-driven rewrites, borrowing from query optimization., + <>Distributed protocol rewrites entail a new burden: reasoning about spatiotemporal correctness. We leverage order-insensitivity and data dependency analysis to systematically identify correct coordination-free scaling opportunities. We apply this analysis to create preconditions and mechanisms for coordination-free decoupling and partitioning, two fundamental vertical and horizontal scaling techniques. Manual rule-driven applications of decoupling and partitioning improve the throughput of 2PC by 5x and Paxos by 3x, and match state-of-the-art throughput in recent work. These results point the way toward automated optimizers for distributed protocols based on correct-by-construction rewrite rules. ], conf: "SIGMOD 2024", links: <>PDF / Tech Report / GitHub @@ -23,11 +36,24 @@ const papers = [ thumb: require("./img/papers/tiemo-sigmod-2024.png"), authors: <>Tiemo Bang, Chris Douglas, Natacha Crooks and Joseph M. Hellerstein, description: [ - <>Cloud object stores offer vastly different price points for object storage as a function of workload and geography. Poor object placement can thus lead to significant cost overheads. Prior cost-saving techniques attempt to optimize placement policies on the fly, deciding object placements for each object individually. In practice, these techniques do not scale to the size of the modern cloud. In this work, we leverage the static nature and pay-per-use pricing model of cloud environments to explore a different approach. Rather than computing object placements on the fly, we precompute a SkyPIE oracle---a lookup structure representing all possible placement policies and the workloads for which they are optimal. Internally, SkyPIE represents placement policies as a matrix of cost-hyperplanes, which we effectively precompute through pruning and convex optimization. By leveraging a fast geometric algorithm, online queries then are 1 to 8 orders of magnitude faster but as accurate as Integer-Linear-Programming. This makes exact optimization tractable for real workloads and we show >10x cost savings compared to state-of-the-art heuristic approaches. + <>Cloud object stores offer vastly different price points for object storage as a function of workload and geography. Poor object placement can thus lead to significant cost overheads. Prior cost-saving techniques attempt to optimize placement policies on the fly, deciding object placements for each object individually. In practice, these techniques do not scale to the size of the modern cloud. In this work, we leverage the static nature and pay-per-use pricing model of cloud environments to explore a different approach. Rather than computing object placements on the fly, we precompute a SkyPIE oracle---a lookup structure representing all possible placement policies and the workloads for which they are optimal., + <>Internally, SkyPIE represents placement policies as a matrix of cost-hyperplanes, which we effectively precompute through pruning and convex optimization. By leveraging a fast geometric algorithm, online queries then are 1 to 8 orders of magnitude faster but as accurate as Integer-Linear-Programming. This makes exact optimization tractable for real workloads and we show {">"}10x cost savings compared to state-of-the-art heuristic approaches. ], conf: "SIGMOD 2024", links: <>PDF / GitHub }, + { + title: "Suki: Choreographed Distributed Dataflow in Rust", + pdf: "pathname:///papers/suki.pdf", + thumb: require("./img/papers/suki.png"), + authors: <>Shadaj Laddad, Alvin Cheung, Joseph M. Hellerstein, + description: [ + <>Programming models for distributed dataflow have long focused on analytical workloads that allow the runtime to dynamically place and schedule compute logic. Meanwhile, models that enable fine-grained control over placement, such as actors, make global optimization difficult. In this extended abstract, we present Suki, an embedded Rust DSL that lets developers implement streaming dataflow with explicit placement of computation., + <>Key to this choreographic programming approach is our use of staged programming, which lets us expose a high-level Rust API while compiling local compute units into individual binaries with zero-overhead. + ], + conf: "CP 2024", + links: <>PDF / arXiv + }, { title: "Bigger, not Badder: Safely Scaling BFT Protocols", pdf: "pathname:///papers/david-papoc-2024.pdf", @@ -191,14 +217,20 @@ export default function Home() { {paper.conf} -

+

{paper["title"]}

{paper["authors"]}

-

{paper.description[0]} {paper.description[1]}

+

{paper.description[0]} {paper.description[1]}

{paper.links}

diff --git a/docs/src/theme/prism-include-languages.js b/docs/src/theme/prism-include-languages.js index 827cb9065199..c8fe35db80e1 100644 --- a/docs/src/theme/prism-include-languages.js +++ b/docs/src/theme/prism-include-languages.js @@ -4,27 +4,25 @@ export default function prismIncludeLanguages(PrismObject) { themeConfig: {prism}, } = siteConfig; const {additionalLanguages} = prism; - // Prism components work on the Prism instance on the window, while prism- - // react-renderer uses its own Prism instance. We temporarily mount the - // instance onto window, import components to enhance it, then remove it to - // avoid polluting global namespace. - // You can mutate PrismObject: registering plugins, deleting languages... As - // long as you don't re-assign it + + const PrismBefore = globalThis.Prism; globalThis.Prism = PrismObject; additionalLanguages.forEach((lang) => { // eslint-disable-next-line global-require, import/no-dynamic-require require(`prismjs/components/prism-${lang}`); }); - const rustLanguage = Prism.languages.rust; Prism.languages["rust,ignore"] = Prism.languages.rust; const origTokenize = PrismObject.tokenize; - PrismObject.tokenize = (text, grammar) => { - if (grammar == rustLanguage) { - text = text.split("\n").filter(line => !line.startsWith("# ")).join("\n"); + PrismObject.hooks.add("after-tokenize", function(env) { + if (env.language === "rust") { + let code = env.code.split("\n").filter(line => !line.startsWith("# ")).join("\n"); + env.tokens = origTokenize(code, env.grammar); } - return origTokenize(text, grammar); - }; + }); delete globalThis.Prism; + if (typeof PrismBefore !== 'undefined') { + globalThis.Prism = PrismObject; + } } diff --git a/docs/src/util.ts b/docs/src/util.ts index 4cd8eec79eb9..7ee441194e4d 100644 --- a/docs/src/util.ts +++ b/docs/src/util.ts @@ -1,8 +1,41 @@ -/// Grabs the specified lines `[lineStart, lineEnd]` from the string. +/// Grabs the specified lines from the string. +/// +/// Can specify a line number range `lineStart, lineEnd`, a specific line number `lineNumber` (no +/// second arg), or a section name. /// /// Lines are one-indexed (start with `1`). Both `lineStart` and `lineEnd` are inclusive. -export function getLines(str: string, lineStart: number, lineEnd?: number): string { - let lines = str.split('\n').slice(lineStart - 1, lineEnd || lineStart); +/// +/// Sections are marked in the code with a start tag `//[mysection]//` and and end tag +/// `//[/mysection]//`. The rest of these tag lines must be whitespace, and these tag lines are not +/// included in the output. However they are included for line number _counting_. +export function getLines(str: string, sectionName: string): string; +export function getLines(str: string, lineStart: number, lineEnd?: number): string; +export function getLines(str: string, lineStartOrSectionName: number | string, lineEnd?: number): string { + // `//[section]//` or `//[/section]//` (rest of line must be whitespace). + const SECTION_REGEX = /^\s*\/\/\[(\/?)(\S+)\]\/\/\s*$/; + let lines; + if ('string' === typeof lineStartOrSectionName) { + let inSection = false; + lines = str + .split('\n') + .filter(line => { + const match = SECTION_REGEX.exec(line); + if (null == match) { + return inSection; + } + const [_, end, name] = match; + if (name == lineStartOrSectionName) { + inSection = 0 === end.length; + } + return false; + }) + } + else { + lines = str + .split('\n') + .slice(lineStartOrSectionName - 1, lineEnd || lineStartOrSectionName) // Select lines before removing section lines. + .filter(line => !SECTION_REGEX.test(line)); + } const leadingWhitespace = Math.min(...lines.filter(line => 0 !== line.length).map(line => line.search(/\S/)).map(Number)); if (0 < leadingWhitespace) { lines = lines.map(line => line.slice(leadingWhitespace)); @@ -10,6 +43,16 @@ export function getLines(str: string, lineStart: number, lineEnd?: number): stri return lines.join('\n'); } +/// Adds `// highlight-next-line` annotations to the specified lines. +export function highlightLines(code: string, lines: number[]): string { + return code.split('\n').map((line, i) => { + if (lines.includes(i + 1)) { + return `// highlight-next-line\n${line}`; + } + return line; + }).join('\n'); +} + /// Extract the output from the stdout snapshots created by `surface_examples.rs`. /// /// This hides the graph output. Use `extractMermaid` to extract the graph output. @@ -40,7 +83,7 @@ ${stdOut}`; /// Extract the mermaid graph logged to stdout from the snapshots created by `surface_examples.rs`. export function extractMermaid(output: string): string { const outputLines = output.split('\n'); - // Delete the first four lines, which are the snapshot front matter. + // Delete the first four lines, which are the snapshot front matter. outputLines.splice(0, 4); // Mermaid graph starts with double-percent signs. if (!outputLines[0].startsWith('%%')) { diff --git a/docs/static/.gitignore b/docs/static/.gitignore new file mode 100644 index 000000000000..1d109a9866c6 --- /dev/null +++ b/docs/static/.gitignore @@ -0,0 +1 @@ +rustdoc/ diff --git a/docs/static/img/hydro-stack.png b/docs/static/img/hydro-stack.png new file mode 100644 index 000000000000..5b7cf22da9a3 Binary files /dev/null and b/docs/static/img/hydro-stack.png differ diff --git a/docs/static/papers/flo.pdf b/docs/static/papers/flo.pdf new file mode 100644 index 000000000000..146dab24a520 Binary files /dev/null and b/docs/static/papers/flo.pdf differ diff --git a/docs/static/papers/suki.pdf b/docs/static/papers/suki.pdf new file mode 100644 index 000000000000..e45a0aae7981 Binary files /dev/null and b/docs/static/papers/suki.pdf differ diff --git a/hydro_deploy/core/CHANGELOG.md b/hydro_deploy/core/CHANGELOG.md index 26f8b6922b0e..f526879cdf38 100644 --- a/hydro_deploy/core/CHANGELOG.md +++ b/hydro_deploy/core/CHANGELOG.md @@ -5,8 +5,82 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - add ability to have staged flows inside unit tests + Whenever a Hydroflow+ program is compiled, it depends on a generated + `__staged` module, which contains the entire contents of the crate but + with every type / function made `pub` and exported, so that the compiled + UDFs can resolve local references appropriately. + + Previously, we would not do this for `#[cfg(test)]` modules, since they + may use `dev-dependencies` and therefore the generated module may fail + to compile when not in test mode. To solve this, when running a unit + test (marked with `hydroflow_plus::deploy::init_test()`) that uses + trybuild, we emit a version of the `__staged` module with `#[cfg(test)]` + modules included _into the generated trybuild sources_ because we can + guarantee via trybuild that the appropriate `dev-dependencies` are + available. + + This by itself allows crates depending on `hydroflow_plus` to have local + unit tests with Hydroflow+ logic inside them. But we also want to use + this support for unit tests inside `hydroflow_plus` itself. To enable + that, we eliminate the `hydroflow_plus_deploy` crate and move its + contents directly to `hydroflow_plus` itself so that we can access the + trybuild machinery without incurring a circular dependency. + + Also fixes #1408 + - add API for external network inputs + This is a key step towards being able to unit-test HF+ graphs, by being + able to have controlled inputs. Outputs next. + +### Style + + - fixes for latest nightly clippy + +### Commit Statistics + + + + - 4 commits contributed to the release. + - 69 days passed between releases. + - 4 commits were understood as [conventional](https://www.conventionalcommits.org). + - 4 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1449](https://github.com/hydro-project/hydroflow/issues/1449), [#1450](https://github.com/hydro-project/hydroflow/issues/1450), [#1537](https://github.com/hydro-project/hydroflow/issues/1537) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1449](https://github.com/hydro-project/hydroflow/issues/1449)** + - Add API for external network inputs ([`8a80931`](https://github.com/hydro-project/hydroflow/commit/8a809315cd37929687fcabc34a12042db25d5767)) + * **[#1450](https://github.com/hydro-project/hydroflow/issues/1450)** + - Add ability to have staged flows inside unit tests ([`afe78c3`](https://github.com/hydro-project/hydroflow/commit/afe78c343658472513b34d28658634b253148aee)) + * **[#1537](https://github.com/hydro-project/hydroflow/issues/1537)** + - Fixes for latest nightly clippy ([`8442d1b`](https://github.com/hydro-project/hydroflow/commit/8442d1b524621a9f8b43372a9c25991efb33c25e)) +
+ ## v0.9.0 (2024-08-30) + + + + + + + + + + ### Chore - manually set versions for crates renamed in #1413 @@ -15,6 +89,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 --------- +### Refactor (BREAKING) + + - simplify process/cluster specs + --- + [//]: # (BEGIN SAPLING FOOTER) + Stack created with [Sapling](https://sapling-scm.com). Best reviewed + with + [ReviewStack](https://reviewstack.dev/hydro-project/hydroflow/pull/1394). + * #1395 + * __->__ #1394 + ### Documentation - cleanup doc comments for clippy latest @@ -79,11 +164,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - use `buildstructor` to handle excessive `Deployment` method arguments, fix #1364 Adds new method `Deployment::AzureHost` + simplify process/cluster specs + --- + [//]: # (BEGIN SAPLING FOOTER) + Stack created with [Sapling](https://sapling-scm.com). Best reviewed + with + [ReviewStack](https://reviewstack.dev/hydro-project/hydroflow/pull/1394). + * #1395 + * __->__ #1394 + - end-to-end flamegraph generation, fix #1365 + Depends on #1370 + - `Deployment.stop()` for graceful shutdown including updated `perf` profile downloading + * `perf` profile downloading moved from the `drop()` impl to `async fn + stop()` + * download perf data via stdout + * update async-ssh2-lite to 0.5 to cleanup tokio compat issues + + WIP for #1365 + - use `buildstructor` to handle excessive `Deployment` method arguments, fix #1364 + Adds new method `Deployment::AzureHost` + ### Commit Statistics - - 19 commits contributed to the release. + - 20 commits contributed to the release. + - 38 days passed between releases. - 18 commits were understood as [conventional](https://www.conventionalcommits.org). - 17 unique issues were worked on: [#1313](https://github.com/hydro-project/hydroflow/issues/1313), [#1360](https://github.com/hydro-project/hydroflow/issues/1360), [#1366](https://github.com/hydro-project/hydroflow/issues/1366), [#1369](https://github.com/hydro-project/hydroflow/issues/1369), [#1370](https://github.com/hydro-project/hydroflow/issues/1370), [#1372](https://github.com/hydro-project/hydroflow/issues/1372), [#1378](https://github.com/hydro-project/hydroflow/issues/1378), [#1394](https://github.com/hydro-project/hydroflow/issues/1394), [#1396](https://github.com/hydro-project/hydroflow/issues/1396), [#1398](https://github.com/hydro-project/hydroflow/issues/1398), [#1403](https://github.com/hydro-project/hydroflow/issues/1403), [#1411](https://github.com/hydro-project/hydroflow/issues/1411), [#1413](https://github.com/hydro-project/hydroflow/issues/1413), [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1428](https://github.com/hydro-project/hydroflow/issues/1428), [#1429](https://github.com/hydro-project/hydroflow/issues/1429), [#1431](https://github.com/hydro-project/hydroflow/issues/1431) @@ -129,6 +235,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1431](https://github.com/hydro-project/hydroflow/issues/1431)** - Only record usermode events in perf ([`c4683ca`](https://github.com/hydro-project/hydroflow/commit/c4683caca43f2927694c920b43ef35a6d1629eaa)) * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) - Manually set versions for crates renamed in #1413 ([`a2ec110`](https://github.com/hydro-project/hydroflow/commit/a2ec110ccadb97e293b19d83a155d98d94224bba)) @@ -196,6 +303,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 11 commits contributed to the release. + - 59 days passed between releases. - 10 commits were understood as [conventional](https://www.conventionalcommits.org). - 10 unique issues were worked on: [#1334](https://github.com/hydro-project/hydroflow/issues/1334), [#1338](https://github.com/hydro-project/hydroflow/issues/1338), [#1339](https://github.com/hydro-project/hydroflow/issues/1339), [#1340](https://github.com/hydro-project/hydroflow/issues/1340), [#1343](https://github.com/hydro-project/hydroflow/issues/1343), [#1345](https://github.com/hydro-project/hydroflow/issues/1345), [#1346](https://github.com/hydro-project/hydroflow/issues/1346), [#1347](https://github.com/hydro-project/hydroflow/issues/1347), [#1348](https://github.com/hydro-project/hydroflow/issues/1348), [#1356](https://github.com/hydro-project/hydroflow/issues/1356) @@ -245,6 +353,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 44 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1129](https://github.com/hydro-project/hydroflow/issues/1129), [#1157](https://github.com/hydro-project/hydroflow/issues/1157) @@ -275,6 +384,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 4 commits contributed to the release. + - 38 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1090](https://github.com/hydro-project/hydroflow/issues/1090) @@ -316,6 +426,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 4 commits contributed to the release. + - 32 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1015](https://github.com/hydro-project/hydroflow/issues/1015), [#1043](https://github.com/hydro-project/hydroflow/issues/1043), [#1084](https://github.com/hydro-project/hydroflow/issues/1084) diff --git a/hydro_deploy/core/Cargo.toml b/hydro_deploy/core/Cargo.toml index f74fc73fa066..a93ee31e7b20 100644 --- a/hydro_deploy/core/Cargo.toml +++ b/hydro_deploy/core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydro_deploy" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydro_deploy/" @@ -22,7 +22,7 @@ cargo_metadata = "0.18.0" dunce = "1.0.0" dyn-clone = "1.0.0" futures = "0.3.0" -hydroflow_deploy_integration = { path = "../hydroflow_deploy_integration", version = "^0.9.0" } +hydroflow_deploy_integration = { path = "../hydroflow_deploy_integration", version = "^0.10.0" } indicatif = "0.17.0" inferno = "0.11.0" itertools = "0.10.0" # TODO(mingwei): remove when `iter_intersperse` is stabilized. diff --git a/hydro_deploy/core/src/deployment.rs b/hydro_deploy/core/src/deployment.rs index faec27e64bf5..bcec6996e3d5 100644 --- a/hydro_deploy/core/src/deployment.rs +++ b/hydro_deploy/core/src/deployment.rs @@ -219,6 +219,11 @@ impl Deployment { /// Buildstructor methods. #[buildstructor::buildstructor] impl Deployment { + #[allow( + clippy::allow_attributes, + clippy::too_many_arguments, + reason = "buildstructor" + )] #[builder(entry = "GcpComputeEngineHost", exit = "add")] pub fn add_gcp_compute_engine_host( &mut self, diff --git a/hydro_deploy/core/src/hydroflow_crate/build.rs b/hydro_deploy/core/src/hydroflow_crate/build.rs index 61efa475a1a7..b6612ca288a1 100644 --- a/hydro_deploy/core/src/hydroflow_crate/build.rs +++ b/hydro_deploy/core/src/hydroflow_crate/build.rs @@ -167,6 +167,7 @@ pub async fn build_crate_memoized(params: BuildParams) -> Result<&'static BuildO let path_buf: PathBuf = path.clone().into(); let path = path.into_string(); let data = std::fs::read(path).unwrap(); + assert!(spawned.wait().unwrap().success()); return Ok(BuildOutput { unique_id: nanoid!(8), bin_data: data, diff --git a/hydro_deploy/core/src/hydroflow_crate/tracing_options.rs b/hydro_deploy/core/src/hydroflow_crate/tracing_options.rs index c7f2957a6200..096ae9da0ff0 100644 --- a/hydro_deploy/core/src/hydroflow_crate/tracing_options.rs +++ b/hydro_deploy/core/src/hydroflow_crate/tracing_options.rs @@ -1,3 +1,5 @@ +#![allow(clippy::too_many_arguments, reason = "buildstructor")] + use std::path::PathBuf; use inferno::collapse::dtrace::Options as DtraceOptions; diff --git a/hydro_deploy/core/src/progress.rs b/hydro_deploy/core/src/progress.rs index e4f8bdd6b4f6..545773db67d8 100644 --- a/hydro_deploy/core/src/progress.rs +++ b/hydro_deploy/core/src/progress.rs @@ -370,7 +370,9 @@ impl ProgressTracker { .lock() .unwrap(); - if progress_bar.multi_progress.println(msg.as_ref()).is_err() { + if progress_bar.current_count == 0 + || progress_bar.multi_progress.println(msg.as_ref()).is_err() + { println!("{}", msg.as_ref()); } } diff --git a/hydro_deploy/hydro_cli/CHANGELOG.md b/hydro_deploy/hydro_cli/CHANGELOG.md index 6e2875acbf5d..e87f947e1ddd 100644 --- a/hydro_deploy/hydro_cli/CHANGELOG.md +++ b/hydro_deploy/hydro_cli/CHANGELOG.md @@ -5,8 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.9.0 (2024-08-30) + + + + + + ### Chore - manually set versions for crates renamed in #1413 @@ -46,7 +77,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 8 commits contributed to the release. + - 9 commits contributed to the release. + - 38 days passed between releases. - 8 commits were understood as [conventional](https://www.conventionalcommits.org). - 7 unique issues were worked on: [#1313](https://github.com/hydro-project/hydroflow/issues/1313), [#1366](https://github.com/hydro-project/hydroflow/issues/1366), [#1370](https://github.com/hydro-project/hydroflow/issues/1370), [#1398](https://github.com/hydro-project/hydroflow/issues/1398), [#1403](https://github.com/hydro-project/hydroflow/issues/1403), [#1413](https://github.com/hydro-project/hydroflow/issues/1413), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -71,6 +103,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) - Manually set versions for crates renamed in #1413 ([`a2ec110`](https://github.com/hydro-project/hydroflow/commit/a2ec110ccadb97e293b19d83a155d98d94224bba)) @@ -130,6 +163,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 9 commits contributed to the release. + - 59 days passed between releases. - 8 commits were understood as [conventional](https://www.conventionalcommits.org). - 8 unique issues were worked on: [#1309](https://github.com/hydro-project/hydroflow/issues/1309), [#1334](https://github.com/hydro-project/hydroflow/issues/1334), [#1339](https://github.com/hydro-project/hydroflow/issues/1339), [#1340](https://github.com/hydro-project/hydroflow/issues/1340), [#1345](https://github.com/hydro-project/hydroflow/issues/1345), [#1346](https://github.com/hydro-project/hydroflow/issues/1346), [#1347](https://github.com/hydro-project/hydroflow/issues/1347), [#1356](https://github.com/hydro-project/hydroflow/issues/1356) @@ -176,6 +210,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 44 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1152](https://github.com/hydro-project/hydroflow/issues/1152), [#1157](https://github.com/hydro-project/hydroflow/issues/1157) @@ -206,6 +241,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 4 commits contributed to the release. + - 38 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1090](https://github.com/hydro-project/hydroflow/issues/1090) @@ -242,6 +278,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 28 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1015](https://github.com/hydro-project/hydroflow/issues/1015), [#1043](https://github.com/hydro-project/hydroflow/issues/1043) @@ -326,6 +363,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 7 commits contributed to the release. + - 114 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1046](https://github.com/hydro-project/hydroflow/issues/1046), [#986](https://github.com/hydro-project/hydroflow/issues/986), [#987](https://github.com/hydro-project/hydroflow/issues/987), [#994](https://github.com/hydro-project/hydroflow/issues/994) diff --git a/hydro_deploy/hydro_cli/Cargo.toml b/hydro_deploy/hydro_cli/Cargo.toml index 815fdb9f5190..5dcae2c98634 100644 --- a/hydro_deploy/hydro_cli/Cargo.toml +++ b/hydro_deploy/hydro_cli/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydro_cli" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydro_cli/" @@ -16,7 +16,7 @@ name = "hydro_cli" crate-type = ["cdylib"] [dependencies] -hydro_deploy = { path = "../core", version = "^0.9.0" } +hydro_deploy = { path = "../core", version = "^0.10.0" } tokio = { version = "1.29.0", features = [ "full" ] } anyhow = { version = "1.0.82", features = [ "backtrace" ] } clap = { version = "4.5.4", features = ["derive"] } @@ -25,7 +25,7 @@ pyo3-asyncio = { version = "0.20.0", features = ["attributes", "tokio-runtime"] pythonize = "0.20.0" futures = "0.3.0" bytes = "1.1.0" -hydroflow_deploy_integration = { path = "../hydroflow_deploy_integration", version = "^0.9.0" } +hydroflow_deploy_integration = { path = "../hydroflow_deploy_integration", version = "^0.10.0" } # request vendored openssl async-ssh2-lite = { version = "0.5.0", features = [ "vendored-openssl" ] } diff --git a/hydro_deploy/hydro_cli/src/lib.rs b/hydro_deploy/hydro_cli/src/lib.rs index 2c1de84faff7..663abe4cc907 100644 --- a/hydro_deploy/hydro_cli/src/lib.rs +++ b/hydro_deploy/hydro_cli/src/lib.rs @@ -1,6 +1,7 @@ #![expect( unused_qualifications, non_local_definitions, + unsafe_op_in_unsafe_fn, reason = "for pyo3 generated code" )] diff --git a/hydro_deploy/hydroflow_deploy_integration/CHANGELOG.md b/hydro_deploy/hydroflow_deploy_integration/CHANGELOG.md index 187072076cc4..d7f61787aaa7 100644 --- a/hydro_deploy/hydroflow_deploy_integration/CHANGELOG.md +++ b/hydro_deploy/hydroflow_deploy_integration/CHANGELOG.md @@ -5,8 +5,38 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.9.0 (2024-08-30) + + + + + ### Chore - manually set versions for crates renamed in #1413 @@ -27,7 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 4 commits contributed to the release. + - 5 commits contributed to the release. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1413](https://github.com/hydro-project/hydroflow/issues/1413), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -42,6 +72,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) - Manually set versions for crates renamed in #1413 ([`a2ec110`](https://github.com/hydro-project/hydroflow/commit/a2ec110ccadb97e293b19d83a155d98d94224bba)) - Update `RELEASING.md` notes, prep for release, wip ([`c41787f`](https://github.com/hydro-project/hydroflow/commit/c41787f527859cb9d704736ecdea5ca7bc641460)) diff --git a/hydro_deploy/hydroflow_deploy_integration/Cargo.toml b/hydro_deploy/hydroflow_deploy_integration/Cargo.toml index 37c954e85232..f87f512c81a6 100644 --- a/hydro_deploy/hydroflow_deploy_integration/Cargo.toml +++ b/hydro_deploy/hydroflow_deploy_integration/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow_deploy_integration" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow_deploy_integration/" diff --git a/hydroflow/CHANGELOG.md b/hydroflow/CHANGELOG.md index 1a5930a2bceb..714c405bee85 100644 --- a/hydroflow/CHANGELOG.md +++ b/hydroflow/CHANGELOG.md @@ -5,8 +5,100 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update `proc-macro2`, fixes span info, fix #729 + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - generalized hash trie indexes for relational tuples + Generalized Hash Tries are part of the SIGMOD '23 FreeJoin + [paper](https://dl.acm.org/doi/abs/10.1145/3589295) by + Wang/Willsey/Suciu. They provide a compressed ("factorized") + representation of relations. By operating in the factorized domain, join + algorithms can defer cross-products and achieve asymptotically optimal + performance. + + --------- + +### Bug Fixes + + - `cross_singleton()` forgot value if multiple runs in a tick, fix #1518 + Adds the minimal reproducer test from @shadaj + + Note this may have negative performance implications, as the singleton value now is stored in the state API (heap) instead of locally. If we use singleton syntax this duplicate allocation could probably be avoided. + + > Confirmed that this fixed the bugs in our Paxos implementation, no noticeable performance impact. @shadj + - cleanup temp tcp networking code, fix race condition fix #1458 + consolidate into one task to prevent races + +### Style + + - fixes for latest nightly clippy + - fixes for nightly clippy + a couple few spurious `too_many_arguments` and a spurious + `zombie_processes` still on current nightly (`clippy 0.1.84 (4392847410 + 2024-10-21)`) + +### Test + + - ignore trybuild tests inconsistent on latest nightly + +### Bug Fixes (BREAKING) + + - fix #1401 `lattice_bimorphism()` double-emit, add docs + Fixes the issue by combining the all values generated per subgraph + execution into one, which effectively de-duplicates the values. + + Adds basic docs. + +### Commit Statistics + + + + - 9 commits contributed to the release. + - 69 days passed between releases. + - 9 commits were understood as [conventional](https://www.conventionalcommits.org). + - 8 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1446](https://github.com/hydro-project/hydroflow/issues/1446), [#1497](https://github.com/hydro-project/hydroflow/issues/1497), [#1503](https://github.com/hydro-project/hydroflow/issues/1503), [#1505](https://github.com/hydro-project/hydroflow/issues/1505), [#1520](https://github.com/hydro-project/hydroflow/issues/1520), [#1522](https://github.com/hydro-project/hydroflow/issues/1522), [#1537](https://github.com/hydro-project/hydroflow/issues/1537) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1446](https://github.com/hydro-project/hydroflow/issues/1446)** + - Cleanup temp tcp networking code, fix race condition fix #1458 ([`b961233`](https://github.com/hydro-project/hydroflow/commit/b96123369cec3d6d407af973f1896b2734fd92ef)) + * **[#1497](https://github.com/hydro-project/hydroflow/issues/1497)** + - Update `proc-macro2`, fixes span info, fix #729 ([`e564b13`](https://github.com/hydro-project/hydroflow/commit/e564b133a4db192e0331d427aa80ef52cd97608c)) + * **[#1503](https://github.com/hydro-project/hydroflow/issues/1503)** + - Generalized hash trie indexes for relational tuples ([`f7e740f`](https://github.com/hydro-project/hydroflow/commit/f7e740fb2ba36d0fcf3fd196d60333552911e3a4)) + * **[#1505](https://github.com/hydro-project/hydroflow/issues/1505)** + - Fixes for nightly clippy ([`47cb703`](https://github.com/hydro-project/hydroflow/commit/47cb703e771f7d1c451ceb9d185ada96410949da)) + * **[#1520](https://github.com/hydro-project/hydroflow/issues/1520)** + - `cross_singleton()` forgot value if multiple runs in a tick, fix #1518 ([`16b730c`](https://github.com/hydro-project/hydroflow/commit/16b730c75cfca79ea5f869308b1e1e14b3e9c155)) + * **[#1522](https://github.com/hydro-project/hydroflow/issues/1522)** + - Fix #1401 `lattice_bimorphism()` double-emit, add docs ([`e796200`](https://github.com/hydro-project/hydroflow/commit/e796200743f2cc2da5a0e91c492f016ca98008e8)) + * **[#1537](https://github.com/hydro-project/hydroflow/issues/1537)** + - Fixes for latest nightly clippy ([`8442d1b`](https://github.com/hydro-project/hydroflow/commit/8442d1b524621a9f8b43372a9c25991efb33c25e)) + * **Uncategorized** + - Ignore trybuild tests inconsistent on latest nightly ([`656ee32`](https://github.com/hydro-project/hydroflow/commit/656ee328c8710bce7370c851437a80ca3db46a5a)) +
+ ## 0.9.0 (2024-08-30) + + + + + + + ### Chore - manually set versions for crates renamed in #1413 @@ -55,7 +147,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 12 commits contributed to the release. + - 13 commits contributed to the release. + - 38 days passed between releases. - 12 commits were understood as [conventional](https://www.conventionalcommits.org). - 11 unique issues were worked on: [#1370](https://github.com/hydro-project/hydroflow/issues/1370), [#1373](https://github.com/hydro-project/hydroflow/issues/1373), [#1399](https://github.com/hydro-project/hydroflow/issues/1399), [#1407](https://github.com/hydro-project/hydroflow/issues/1407), [#1409](https://github.com/hydro-project/hydroflow/issues/1409), [#1413](https://github.com/hydro-project/hydroflow/issues/1413), [#1416](https://github.com/hydro-project/hydroflow/issues/1416), [#1417](https://github.com/hydro-project/hydroflow/issues/1417), [#1420](https://github.com/hydro-project/hydroflow/issues/1420), [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1428](https://github.com/hydro-project/hydroflow/issues/1428) @@ -88,6 +181,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1428](https://github.com/hydro-project/hydroflow/issues/1428)** - Cleanup doc comments for clippy latest ([`f5f1eb0`](https://github.com/hydro-project/hydroflow/commit/f5f1eb0c612f5c0c1752360d972ef6853c5e12f0)) * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) - Manually set versions for crates renamed in #1413 ([`a2ec110`](https://github.com/hydro-project/hydroflow/commit/a2ec110ccadb97e293b19d83a155d98d94224bba)) @@ -204,6 +298,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 17 commits contributed to the release. + - 59 days passed between releases. - 16 commits were understood as [conventional](https://www.conventionalcommits.org). - 17 unique issues were worked on: [#1143](https://github.com/hydro-project/hydroflow/issues/1143), [#1216](https://github.com/hydro-project/hydroflow/issues/1216), [#1244](https://github.com/hydro-project/hydroflow/issues/1244), [#1260](https://github.com/hydro-project/hydroflow/issues/1260), [#1271](https://github.com/hydro-project/hydroflow/issues/1271), [#1273](https://github.com/hydro-project/hydroflow/issues/1273), [#1274](https://github.com/hydro-project/hydroflow/issues/1274), [#1280](https://github.com/hydro-project/hydroflow/issues/1280), [#1283](https://github.com/hydro-project/hydroflow/issues/1283), [#1295](https://github.com/hydro-project/hydroflow/issues/1295), [#1296](https://github.com/hydro-project/hydroflow/issues/1296), [#1297](https://github.com/hydro-project/hydroflow/issues/1297), [#1300](https://github.com/hydro-project/hydroflow/issues/1300), [#1309](https://github.com/hydro-project/hydroflow/issues/1309), [#1312](https://github.com/hydro-project/hydroflow/issues/1312), [#1332](https://github.com/hydro-project/hydroflow/issues/1332), [#1345](https://github.com/hydro-project/hydroflow/issues/1345) @@ -251,15 +346,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Release hydroflow_lang v0.8.0, hydroflow_datalog_core v0.8.0, hydroflow_datalog v0.8.0, hydroflow_macro v0.8.0, lattices_macro v0.5.5, lattices v0.5.6, variadics v0.0.5, pusherator v0.0.7, hydroflow v0.8.0, hydroflow_plus v0.8.0, hydro_deploy v0.8.0, hydro_cli v0.8.0, hydroflow_plus_cli_integration v0.8.0, safety bump 7 crates ([`ca6c16b`](https://github.com/hydro-project/hydroflow/commit/ca6c16b4a7ce35e155fe7fc6c7d1676c37c9e4de)) - -Other 'tick state will need to be cleared, but existing implementation does that when the iterator runs, which is good enough. There is only a problem if a singleton can reference the state before the iterator runs, in that case. allow use of generics in demux_enum::<...>() opensures turbofish syntax for the match clauses, which is needed when there are generic parameters in the typeadds a test as well yield before collect_ready_async to ensure background async tasks can send to the stream make sure tasks are spawned!!!!fix bug introduced in #978 Make inner for WithTop & WithBot privateOption is not a lattice, so it is unsafe to expose as public.I also updated documentation to lead with intention beforeimplementation (minor cleanup).To emulate this unintuitive behavior, we currently ensure that apersist::<'static>() exists before operator that references thesingleton (filter, in this case). (Note that this is equivalent tocross_join::<'static>() and not cross_join::<'tick>())However singletons also have had a different mechanism that affectsthis- currently singleton references create a next-stratum constraint,that ensures a singleton referencer must be in a later stratum than thesingleton it is referencing.Note that this actually prevents the example situation above fromhappening– the updates to y will be received all at once at the startof the next stratum.This means that actually, currently singletons are equivalent tosomething like:ruststream -> cj[0]; -y -> next_stratum() -> last() -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -last() is a hypothetical operator that only keeps the most recent itemoutput by y. next_stratum() -> last() is equivalent to reduce(|acc, item| *acc = item) (since that comes with a stratum barrier). Sotechnically this is a slightly different behavior than just cross_join,but it is more intuitive.ruststream -> cj[0]; -y -> reduce(|acc, item| { *acc = item; }) -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -Also fixes #1293 - ## 0.7.0 (2024-05-24) @@ -342,6 +428,7 @@ Also fixes #1293 - 31 commits contributed to the release. + - 44 days passed between releases. - 27 commits were understood as [conventional](https://www.conventionalcommits.org). - 23 unique issues were worked on: [#1120](https://github.com/hydro-project/hydroflow/issues/1120), [#1143](https://github.com/hydro-project/hydroflow/issues/1143), [#1152](https://github.com/hydro-project/hydroflow/issues/1152), [#1159](https://github.com/hydro-project/hydroflow/issues/1159), [#1164](https://github.com/hydro-project/hydroflow/issues/1164), [#1166](https://github.com/hydro-project/hydroflow/issues/1166), [#1167](https://github.com/hydro-project/hydroflow/issues/1167), [#1171](https://github.com/hydro-project/hydroflow/issues/1171), [#1176](https://github.com/hydro-project/hydroflow/issues/1176), [#1178](https://github.com/hydro-project/hydroflow/issues/1178), [#1182](https://github.com/hydro-project/hydroflow/issues/1182), [#1190](https://github.com/hydro-project/hydroflow/issues/1190), [#1191](https://github.com/hydro-project/hydroflow/issues/1191), [#1192](https://github.com/hydro-project/hydroflow/issues/1192), [#1193](https://github.com/hydro-project/hydroflow/issues/1193), [#1196](https://github.com/hydro-project/hydroflow/issues/1196), [#1197](https://github.com/hydro-project/hydroflow/issues/1197), [#1198](https://github.com/hydro-project/hydroflow/issues/1198), [#1199](https://github.com/hydro-project/hydroflow/issues/1199), [#1204](https://github.com/hydro-project/hydroflow/issues/1204), [#1232](https://github.com/hydro-project/hydroflow/issues/1232), [#1236](https://github.com/hydro-project/hydroflow/issues/1236), [#1238](https://github.com/hydro-project/hydroflow/issues/1238) @@ -435,6 +522,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 3 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1134](https://github.com/hydro-project/hydroflow/issues/1134), [#1148](https://github.com/hydro-project/hydroflow/issues/1148), [#1150](https://github.com/hydro-project/hydroflow/issues/1150) @@ -533,6 +621,7 @@ Also fixes #1293 - 28 commits contributed to the release. + - 34 days passed between releases. - 27 commits were understood as [conventional](https://www.conventionalcommits.org). - 18 unique issues were worked on: [#1068](https://github.com/hydro-project/hydroflow/issues/1068), [#1086](https://github.com/hydro-project/hydroflow/issues/1086), [#1087](https://github.com/hydro-project/hydroflow/issues/1087), [#1089](https://github.com/hydro-project/hydroflow/issues/1089), [#1090](https://github.com/hydro-project/hydroflow/issues/1090), [#1091](https://github.com/hydro-project/hydroflow/issues/1091), [#1093](https://github.com/hydro-project/hydroflow/issues/1093), [#1094](https://github.com/hydro-project/hydroflow/issues/1094), [#1102](https://github.com/hydro-project/hydroflow/issues/1102), [#1113](https://github.com/hydro-project/hydroflow/issues/1113), [#1125](https://github.com/hydro-project/hydroflow/issues/1125), [#1128](https://github.com/hydro-project/hydroflow/issues/1128), [#1132](https://github.com/hydro-project/hydroflow/issues/1132), [#1133](https://github.com/hydro-project/hydroflow/issues/1133), [#1137](https://github.com/hydro-project/hydroflow/issues/1137), [#1140](https://github.com/hydro-project/hydroflow/issues/1140), [#1145](https://github.com/hydro-project/hydroflow/issues/1145), [#1146](https://github.com/hydro-project/hydroflow/issues/1146) @@ -630,6 +719,7 @@ Also fixes #1293 - 10 commits contributed to the release. + - 28 days passed between releases. - 9 commits were understood as [conventional](https://www.conventionalcommits.org). - 6 unique issues were worked on: [#1015](https://github.com/hydro-project/hydroflow/issues/1015), [#1057](https://github.com/hydro-project/hydroflow/issues/1057), [#1060](https://github.com/hydro-project/hydroflow/issues/1060), [#1061](https://github.com/hydro-project/hydroflow/issues/1061), [#1084](https://github.com/hydro-project/hydroflow/issues/1084), [#1085](https://github.com/hydro-project/hydroflow/issues/1085) @@ -679,6 +769,7 @@ Also fixes #1293 - 5 commits contributed to the release. + - 4 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1041](https://github.com/hydro-project/hydroflow/issues/1041), [#1051](https://github.com/hydro-project/hydroflow/issues/1051), [#1054](https://github.com/hydro-project/hydroflow/issues/1054), [#1055](https://github.com/hydro-project/hydroflow/issues/1055) @@ -750,6 +841,8 @@ Also fixes #1293 -- - new implementation and Hydro Deploy setup -- + - new implementation and Hydro Deploy setup + -- ### Bug Fixes @@ -788,6 +881,7 @@ Also fixes #1293 - 27 commits contributed to the release. + - 110 days passed between releases. - 26 commits were understood as [conventional](https://www.conventionalcommits.org). - 23 unique issues were worked on: [#1003](https://github.com/hydro-project/hydroflow/issues/1003), [#1005](https://github.com/hydro-project/hydroflow/issues/1005), [#1024](https://github.com/hydro-project/hydroflow/issues/1024), [#1025](https://github.com/hydro-project/hydroflow/issues/1025), [#1026](https://github.com/hydro-project/hydroflow/issues/1026), [#1032](https://github.com/hydro-project/hydroflow/issues/1032), [#1036](https://github.com/hydro-project/hydroflow/issues/1036), [#899](https://github.com/hydro-project/hydroflow/issues/899), [#909](https://github.com/hydro-project/hydroflow/issues/909), [#942](https://github.com/hydro-project/hydroflow/issues/942), [#945](https://github.com/hydro-project/hydroflow/issues/945), [#948](https://github.com/hydro-project/hydroflow/issues/948), [#950](https://github.com/hydro-project/hydroflow/issues/950), [#959](https://github.com/hydro-project/hydroflow/issues/959), [#960](https://github.com/hydro-project/hydroflow/issues/960), [#967](https://github.com/hydro-project/hydroflow/issues/967), [#971](https://github.com/hydro-project/hydroflow/issues/971), [#974](https://github.com/hydro-project/hydroflow/issues/974), [#978](https://github.com/hydro-project/hydroflow/issues/978), [#979](https://github.com/hydro-project/hydroflow/issues/979), [#984](https://github.com/hydro-project/hydroflow/issues/984), [#986](https://github.com/hydro-project/hydroflow/issues/986), [#996](https://github.com/hydro-project/hydroflow/issues/996) @@ -943,6 +1037,7 @@ Also fixes #1293 - 46 commits contributed to the release. + - 56 days passed between releases. - 43 commits were understood as [conventional](https://www.conventionalcommits.org). - 19 unique issues were worked on: [#882](https://github.com/hydro-project/hydroflow/issues/882), [#884](https://github.com/hydro-project/hydroflow/issues/884), [#885](https://github.com/hydro-project/hydroflow/issues/885), [#886](https://github.com/hydro-project/hydroflow/issues/886), [#887](https://github.com/hydro-project/hydroflow/issues/887), [#892](https://github.com/hydro-project/hydroflow/issues/892), [#893](https://github.com/hydro-project/hydroflow/issues/893), [#896](https://github.com/hydro-project/hydroflow/issues/896), [#897](https://github.com/hydro-project/hydroflow/issues/897), [#898](https://github.com/hydro-project/hydroflow/issues/898), [#902](https://github.com/hydro-project/hydroflow/issues/902), [#906](https://github.com/hydro-project/hydroflow/issues/906), [#918](https://github.com/hydro-project/hydroflow/issues/918), [#919](https://github.com/hydro-project/hydroflow/issues/919), [#923](https://github.com/hydro-project/hydroflow/issues/923), [#924](https://github.com/hydro-project/hydroflow/issues/924), [#926](https://github.com/hydro-project/hydroflow/issues/926), [#932](https://github.com/hydro-project/hydroflow/issues/932), [#935](https://github.com/hydro-project/hydroflow/issues/935) @@ -1098,6 +1193,7 @@ Also fixes #1293 - 25 commits contributed to the release. + - 42 days passed between releases. - 22 commits were understood as [conventional](https://www.conventionalcommits.org). - 23 unique issues were worked on: [#820](https://github.com/hydro-project/hydroflow/issues/820), [#821](https://github.com/hydro-project/hydroflow/issues/821), [#822](https://github.com/hydro-project/hydroflow/issues/822), [#823](https://github.com/hydro-project/hydroflow/issues/823), [#833](https://github.com/hydro-project/hydroflow/issues/833), [#835](https://github.com/hydro-project/hydroflow/issues/835), [#837](https://github.com/hydro-project/hydroflow/issues/837), [#840](https://github.com/hydro-project/hydroflow/issues/840), [#842](https://github.com/hydro-project/hydroflow/issues/842), [#843](https://github.com/hydro-project/hydroflow/issues/843), [#844](https://github.com/hydro-project/hydroflow/issues/844), [#845](https://github.com/hydro-project/hydroflow/issues/845), [#846](https://github.com/hydro-project/hydroflow/issues/846), [#848](https://github.com/hydro-project/hydroflow/issues/848), [#851](https://github.com/hydro-project/hydroflow/issues/851), [#853](https://github.com/hydro-project/hydroflow/issues/853), [#857](https://github.com/hydro-project/hydroflow/issues/857), [#861](https://github.com/hydro-project/hydroflow/issues/861), [#870](https://github.com/hydro-project/hydroflow/issues/870), [#872](https://github.com/hydro-project/hydroflow/issues/872), [#874](https://github.com/hydro-project/hydroflow/issues/874), [#878](https://github.com/hydro-project/hydroflow/issues/878), [#880](https://github.com/hydro-project/hydroflow/issues/880) @@ -1257,6 +1353,7 @@ Also fixes #1293 - 34 commits contributed to the release. + - 33 days passed between releases. - 31 commits were understood as [conventional](https://www.conventionalcommits.org). - 25 unique issues were worked on: [#739](https://github.com/hydro-project/hydroflow/issues/739), [#743](https://github.com/hydro-project/hydroflow/issues/743), [#745](https://github.com/hydro-project/hydroflow/issues/745), [#748](https://github.com/hydro-project/hydroflow/issues/748), [#749](https://github.com/hydro-project/hydroflow/issues/749), [#755](https://github.com/hydro-project/hydroflow/issues/755), [#761](https://github.com/hydro-project/hydroflow/issues/761), [#763](https://github.com/hydro-project/hydroflow/issues/763), [#765](https://github.com/hydro-project/hydroflow/issues/765), [#772](https://github.com/hydro-project/hydroflow/issues/772), [#773](https://github.com/hydro-project/hydroflow/issues/773), [#774](https://github.com/hydro-project/hydroflow/issues/774), [#775](https://github.com/hydro-project/hydroflow/issues/775), [#778](https://github.com/hydro-project/hydroflow/issues/778), [#780](https://github.com/hydro-project/hydroflow/issues/780), [#784](https://github.com/hydro-project/hydroflow/issues/784), [#788](https://github.com/hydro-project/hydroflow/issues/788), [#789](https://github.com/hydro-project/hydroflow/issues/789), [#791](https://github.com/hydro-project/hydroflow/issues/791), [#792](https://github.com/hydro-project/hydroflow/issues/792), [#799](https://github.com/hydro-project/hydroflow/issues/799), [#801](https://github.com/hydro-project/hydroflow/issues/801), [#803](https://github.com/hydro-project/hydroflow/issues/803), [#804](https://github.com/hydro-project/hydroflow/issues/804), [#809](https://github.com/hydro-project/hydroflow/issues/809) @@ -1350,6 +1447,7 @@ Also fixes #1293 - 4 commits contributed to the release. + - 1 day passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -1426,6 +1524,7 @@ Also fixes #1293 - 18 commits contributed to the release. + - 6 days passed between releases. - 17 commits were understood as [conventional](https://www.conventionalcommits.org). - 12 unique issues were worked on: [#686](https://github.com/hydro-project/hydroflow/issues/686), [#690](https://github.com/hydro-project/hydroflow/issues/690), [#692](https://github.com/hydro-project/hydroflow/issues/692), [#696](https://github.com/hydro-project/hydroflow/issues/696), [#697](https://github.com/hydro-project/hydroflow/issues/697), [#702](https://github.com/hydro-project/hydroflow/issues/702), [#706](https://github.com/hydro-project/hydroflow/issues/706), [#708](https://github.com/hydro-project/hydroflow/issues/708), [#714](https://github.com/hydro-project/hydroflow/issues/714), [#716](https://github.com/hydro-project/hydroflow/issues/716), [#719](https://github.com/hydro-project/hydroflow/issues/719), [#721](https://github.com/hydro-project/hydroflow/issues/721) @@ -1494,6 +1593,7 @@ Also fixes #1293 - 8 commits contributed to the release. + - 2 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#661](https://github.com/hydro-project/hydroflow/issues/661), [#671](https://github.com/hydro-project/hydroflow/issues/671), [#677](https://github.com/hydro-project/hydroflow/issues/677), [#684](https://github.com/hydro-project/hydroflow/issues/684) @@ -1542,6 +1642,7 @@ Also fixes #1293 - 19 commits contributed to the release. + - 18 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 14 unique issues were worked on: [#625](https://github.com/hydro-project/hydroflow/issues/625), [#638](https://github.com/hydro-project/hydroflow/issues/638), [#640](https://github.com/hydro-project/hydroflow/issues/640), [#641](https://github.com/hydro-project/hydroflow/issues/641), [#642](https://github.com/hydro-project/hydroflow/issues/642), [#644](https://github.com/hydro-project/hydroflow/issues/644), [#649](https://github.com/hydro-project/hydroflow/issues/649), [#650](https://github.com/hydro-project/hydroflow/issues/650), [#651](https://github.com/hydro-project/hydroflow/issues/651), [#654](https://github.com/hydro-project/hydroflow/issues/654), [#656](https://github.com/hydro-project/hydroflow/issues/656), [#657](https://github.com/hydro-project/hydroflow/issues/657), [#660](https://github.com/hydro-project/hydroflow/issues/660), [#667](https://github.com/hydro-project/hydroflow/issues/667) @@ -1607,6 +1708,7 @@ Also fixes #1293 - 7 commits contributed to the release. + - 7 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 6 unique issues were worked on: [#622](https://github.com/hydro-project/hydroflow/issues/622), [#629](https://github.com/hydro-project/hydroflow/issues/629), [#632](https://github.com/hydro-project/hydroflow/issues/632), [#633](https://github.com/hydro-project/hydroflow/issues/633), [#634](https://github.com/hydro-project/hydroflow/issues/634), [#635](https://github.com/hydro-project/hydroflow/issues/635) diff --git a/hydroflow/Cargo.toml b/hydroflow/Cargo.toml index 3d4400e9deb3..056d96b1c3d3 100644 --- a/hydroflow/Cargo.toml +++ b/hydroflow/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow/" @@ -42,13 +42,13 @@ bincode = "1.3.1" byteorder = "1.3.2" bytes = "1.1.0" futures = "0.3.0" -hydroflow_deploy_integration = { optional = true, path = "../hydro_deploy/hydroflow_deploy_integration", version = "^0.9.0" } -hydroflow_datalog = { optional = true, path = "../hydroflow_datalog", version = "^0.9.0" } -hydroflow_lang = { path = "../hydroflow_lang", version = "^0.9.0", features = [ "clap-derive" ] } -hydroflow_macro = { optional = true, path = "../hydroflow_macro", version = "^0.9.0" } +hydroflow_deploy_integration = { optional = true, path = "../hydro_deploy/hydroflow_deploy_integration", version = "^0.10.0" } +hydroflow_datalog = { optional = true, path = "../hydroflow_datalog", version = "^0.10.0" } +hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0" } +hydroflow_macro = { optional = true, path = "../hydroflow_macro", version = "^0.10.0" } itertools = "0.10.0" -lattices = { path = "../lattices", version = "^0.5.7", features = [ "serde" ] } -pusherator = { path = "../pusherator", version = "^0.0.8" } +lattices = { path = "../lattices", version = "^0.5.8", features = [ "serde" ] } +pusherator = { path = "../pusherator", version = "^0.0.9" } pyo3 = { optional = true, version = "0.20" } ref-cast = "1.0.0" regex = "1.10.4" @@ -60,11 +60,11 @@ slotmap = "1.0.0" smallvec = "1.6.1" tokio-stream = { version = "0.1.3", default-features = false, features = [ "time", "io-util", "sync" ] } tracing = "0.1.37" -variadics = { path = "../variadics", version = "^0.0.6" } +variadics = { path = "../variadics", version = "^0.0.7" } web-time = "1.0.0" # added to workaround `cargo smart-release` https://github.com/Byron/cargo-smart-release/issues/16 -multiplatform_test = { path = "../multiplatform_test", version = "^0.2.0", optional = true } +multiplatform_test = { path = "../multiplatform_test", version = "^0.3.0", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio = { version = "1.29.0", features = [ "full" ] } @@ -81,11 +81,13 @@ tokio-util = { version = "0.7.5", features = [ "codec" ] } getrandom = { version = "0.2.6", features = [ "js" ] } [dev-dependencies] +hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0", features = [ "clap-derive" ] } + chrono = { version = "0.4.20", features = [ "serde", "clock" ], default-features = false } clap = { version = "4.5.4", features = [ "derive" ] } colored = "2.0" insta = "1.39" -multiplatform_test = { path = "../multiplatform_test", version = "^0.2.0" } +multiplatform_test = { path = "../multiplatform_test", version = "^0.3.0" } wasm-bindgen-test = "0.3.33" rand = { version = "0.8.0", features = [ "small_rng" ] } rand_distr = "0.4.3" diff --git a/hydroflow/examples/example_1_simplest.rs b/hydroflow/examples/example_1_simplest.rs index f93182cd7dd6..8f7b84b46140 100644 --- a/hydroflow/examples/example_1_simplest.rs +++ b/hydroflow/examples/example_1_simplest.rs @@ -1,9 +1,15 @@ +//[use]// use hydroflow::hydroflow_syntax; +//[/use]// +//[macro_call]// pub fn main() { let mut flow = hydroflow_syntax! { source_iter(0..10) -> for_each(|n| println!("Hello {}", n)); }; + //[/macro_call]// + //[run]// flow.run_available(); + //[/run]// } diff --git a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/map_union.rs b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/map_union.rs index 1be9a9c4e9b8..92127af97e60 100644 --- a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/map_union.rs +++ b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/map_union.rs @@ -15,7 +15,7 @@ pub struct MapUnionHashMapWrapper<'a, const SIZE: usize>( pub &'a MapUnionHashMap>, ); -impl<'a, const SIZE: usize> Serialize for MapUnionHashMapWrapper<'a, SIZE> { +impl Serialize for MapUnionHashMapWrapper<'_, SIZE> { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/my_last_write_wins.rs b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/my_last_write_wins.rs index 91fc1b71dfb4..74b3041bfbe7 100644 --- a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/my_last_write_wins.rs +++ b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/my_last_write_wins.rs @@ -11,7 +11,7 @@ use crate::protocol::MyLastWriteWins; #[repr(transparent)] pub struct MyLastWriteWinsWrapper<'a, const SIZE: usize>(pub &'a MyLastWriteWins); -impl<'a, const SIZE: usize> Serialize for MyLastWriteWinsWrapper<'a, SIZE> { +impl Serialize for MyLastWriteWinsWrapper<'_, SIZE> { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/point.rs b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/point.rs index b0410e203947..98b2552a5c28 100644 --- a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/point.rs +++ b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/point.rs @@ -10,7 +10,7 @@ use crate::buffer_pool::{AutoReturnBuffer, AutoReturnBufferDeserializer, BufferP #[repr(transparent)] pub struct PointWrapper<'a, const SIZE: usize>(pub &'a Point, ()>); -impl<'a, const SIZE: usize> Serialize for PointWrapper<'a, SIZE> { +impl Serialize for PointWrapper<'_, SIZE> { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/with_bot.rs b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/with_bot.rs index f5204743b698..d7af4a572f24 100644 --- a/hydroflow/examples/kvs_bench/protocol/serialization/lattices/with_bot.rs +++ b/hydroflow/examples/kvs_bench/protocol/serialization/lattices/with_bot.rs @@ -14,7 +14,7 @@ pub struct WithBotWrapper<'a, const SIZE: usize>( pub &'a WithBot, ()>>, ); -impl<'a, const SIZE: usize> Serialize for WithBotWrapper<'a, SIZE> { +impl Serialize for WithBotWrapper<'_, SIZE> { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/hydroflow/examples/kvs_bench/protocol/serialization/mod.rs b/hydroflow/examples/kvs_bench/protocol/serialization/mod.rs index db7686f995a2..29fdfb142503 100644 --- a/hydroflow/examples/kvs_bench/protocol/serialization/mod.rs +++ b/hydroflow/examples/kvs_bench/protocol/serialization/mod.rs @@ -116,7 +116,7 @@ enum KvsRequestField { Delete, } struct KvsRequestFieldVisitor; -impl<'de> Visitor<'de> for KvsRequestFieldVisitor { +impl Visitor<'_> for KvsRequestFieldVisitor { type Value = KvsRequestField; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { diff --git a/hydroflow/src/compiled/pull/anti_join.rs b/hydroflow/src/compiled/pull/anti_join.rs index 9e11f691f1c1..97421b7de62d 100644 --- a/hydroflow/src/compiled/pull/anti_join.rs +++ b/hydroflow/src/compiled/pull/anti_join.rs @@ -12,7 +12,7 @@ where pos_state: &'a mut FxHashSet<(Key, V)>, } -impl<'a, Key, V, Ipos> Iterator for AntiJoin<'a, Key, V, Ipos> +impl Iterator for AntiJoin<'_, Key, V, Ipos> where Key: Eq + std::hash::Hash + Clone, V: Eq + std::hash::Hash + Clone, diff --git a/hydroflow/src/compiled/pull/cross_join.rs b/hydroflow/src/compiled/pull/cross_join.rs index 90f743d9bc92..6b9629fa65f9 100644 --- a/hydroflow/src/compiled/pull/cross_join.rs +++ b/hydroflow/src/compiled/pull/cross_join.rs @@ -30,7 +30,7 @@ where state: &'a mut CrossJoinState, } -impl<'a, I1, V1: 'static, I2, V2: 'static> Iterator for CrossJoin<'a, I1, V1, I2, V2> +impl Iterator for CrossJoin<'_, I1, V1, I2, V2> where V1: Eq + Clone, V2: Eq + Clone, diff --git a/hydroflow/src/compiled/pull/symmetric_hash_join.rs b/hydroflow/src/compiled/pull/symmetric_hash_join.rs index d240e6a347ad..1665c9940a05 100644 --- a/hydroflow/src/compiled/pull/symmetric_hash_join.rs +++ b/hydroflow/src/compiled/pull/symmetric_hash_join.rs @@ -18,8 +18,8 @@ where rhs_state: &'a mut RhsState, } -impl<'a, Key, I1, V1, I2, V2, LhsState, RhsState> Iterator - for SymmetricHashJoin<'a, Key, I1, V1, I2, V2, LhsState, RhsState> +impl Iterator + for SymmetricHashJoin<'_, Key, I1, V1, I2, V2, LhsState, RhsState> where Key: Eq + std::hash::Hash + Clone, V1: Clone, diff --git a/hydroflow/src/scheduled/graph.rs b/hydroflow/src/scheduled/graph.rs index 85d71d98bfe0..2d4e96962ee2 100644 --- a/hydroflow/src/scheduled/graph.rs +++ b/hydroflow/src/scheduled/graph.rs @@ -47,7 +47,7 @@ pub struct Hydroflow<'a> { /// See [`Self::diagnostics()`]. diagnostics: Option>>, } -impl<'a> Default for Hydroflow<'a> { +impl Default for Hydroflow<'_> { fn default() -> Self { let stratum_queues = vec![Default::default()]; // Always initialize stratum #0. let (event_queue_send, event_queue_recv) = mpsc::unbounded_channel(); @@ -69,7 +69,7 @@ impl<'a> Default for Hydroflow<'a> { } /// Methods for [`TeeingHandoff`] teeing and dropping. -impl<'a> Hydroflow<'a> { +impl Hydroflow<'_> { /// Tees a [`TeeingHandoff`]. pub fn teeing_handoff_tee( &mut self, @@ -794,7 +794,7 @@ impl<'a> Hydroflow<'a> { } } -impl<'a> Hydroflow<'a> { +impl Hydroflow<'_> { /// Alias for [`Context::request_task`]. pub fn request_task(&mut self, future: Fut) where @@ -814,7 +814,7 @@ impl<'a> Hydroflow<'a> { } } -impl<'a> Drop for Hydroflow<'a> { +impl Drop for Hydroflow<'_> { fn drop(&mut self) { self.abort_tasks(); } diff --git a/hydroflow/src/scheduled/graph_ext.rs b/hydroflow/src/scheduled/graph_ext.rs index 6f54413d832e..1d0be9d28dd6 100644 --- a/hydroflow/src/scheduled/graph_ext.rs +++ b/hydroflow/src/scheduled/graph_ext.rs @@ -126,7 +126,7 @@ pub trait GraphExt { W: 'static + Handoff + CanReceive; } -impl<'a> GraphExt for Hydroflow<'a> { +impl GraphExt for Hydroflow<'_> { subgraph_ext!(impl add_subgraph_sink, (recv_port: R), ()); subgraph_ext!( impl add_subgraph_2sink, diff --git a/hydroflow/src/scheduled/net/mod.rs b/hydroflow/src/scheduled/net/mod.rs index 48ffc2e6115f..10664f8a58d3 100644 --- a/hydroflow/src/scheduled/net/mod.rs +++ b/hydroflow/src/scheduled/net/mod.rs @@ -96,7 +96,7 @@ impl Message { } } -impl<'a> Hydroflow<'a> { +impl Hydroflow<'_> { fn register_read_tcp_stream(&mut self, reader: OwnedReadHalf) -> RecvPort> { let reader = FramedRead::new(reader, LengthDelimitedCodec::new()); let (send_port, recv_port) = self.make_edge("tcp ingress handoff"); diff --git a/hydroflow/src/scheduled/net/network_vertex.rs b/hydroflow/src/scheduled/net/network_vertex.rs index 13077e6290e8..b2db71169646 100644 --- a/hydroflow/src/scheduled/net/network_vertex.rs +++ b/hydroflow/src/scheduled/net/network_vertex.rs @@ -18,7 +18,7 @@ pub type Address = String; // These methods can't be wrapped up in a trait because async methods are not // allowed in traits (yet). -impl<'a> Hydroflow<'a> { +impl Hydroflow<'_> { // TODO(justin): document these, but they're derivatives of inbound_tcp_vertex_internal. pub async fn inbound_tcp_vertex_port(&mut self, port: u16) -> RecvPort> where diff --git a/hydroflow/src/util/simulation.rs b/hydroflow/src/util/simulation.rs index f1611be636e7..86b2bc785644 100644 --- a/hydroflow/src/util/simulation.rs +++ b/hydroflow/src/util/simulation.rs @@ -177,7 +177,7 @@ fn sink_from_fn(mut f: impl FnMut(T)) -> impl Sink { }) } -impl<'context> TransducerBuilderContext<'context> { +impl TransducerBuilderContext<'_> { /// Create a new inbox on the host with the given interface name. Returns a stream that can /// be read by the transducer using the source_stream hydroflow operator. pub fn new_inbox( diff --git a/hydroflow/src/util/tcp.rs b/hydroflow/src/util/tcp.rs index 5f1cab36003b..9c50c3094160 100644 --- a/hydroflow/src/util/tcp.rs +++ b/hydroflow/src/util/tcp.rs @@ -1,16 +1,16 @@ #![cfg(not(target_arch = "wasm32"))] -use std::cell::RefCell; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::HashMap; +use std::fmt::Debug; use std::net::SocketAddr; -use std::pin::pin; -use std::rc::Rc; use futures::{SinkExt, StreamExt}; use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; use tokio::net::{TcpListener, TcpSocket, TcpStream}; +use tokio::select; use tokio::task::spawn_local; +use tokio_stream::StreamMap; use tokio_util::codec::{ BytesCodec, Decoder, Encoder, FramedRead, FramedWrite, LengthDelimitedCodec, LinesCodec, }; @@ -74,69 +74,90 @@ pub type TcpFramedSink = Sender<(T, SocketAddr)>; pub type TcpFramedStream = Receiver::Item, SocketAddr), ::Error>>; +// TODO(mingwei): this temporary code should be replaced with a properly thought out networking system. /// Create a listening tcp socket, and then as new connections come in, receive their data and forward it to a queue. -pub async fn bind_tcp>( +pub async fn bind_tcp( endpoint: SocketAddr, codec: Codec, -) -> Result<(TcpFramedSink, TcpFramedStream, SocketAddr), std::io::Error> { +) -> Result<(TcpFramedSink, TcpFramedStream, SocketAddr), std::io::Error> +where + Item: 'static, + Codec: 'static + Clone + Decoder + Encoder, + >::Error: Debug, +{ let listener = TcpListener::bind(endpoint).await?; let bound_endpoint = listener.local_addr()?; - let (tx_egress, mut rx_egress) = unsync_channel(None); - let (tx_ingress, rx_ingress) = unsync_channel(None); - - let clients = Rc::new(RefCell::new(HashMap::new())); - - spawn_local({ - let clients = clients.clone(); - - async move { - while let Some((payload, addr)) = rx_egress.next().await { - let client = clients.borrow_mut().remove(&addr); - - if let Some(mut sender) = client { - let _ = SinkExt::send(&mut sender, payload).await; - clients.borrow_mut().insert(addr, sender); - } - } - } - }); + let (send_egress, mut recv_egress) = unsync_channel::<(Item, SocketAddr)>(None); + let (send_ingres, recv_ingres) = unsync_channel(None); spawn_local(async move { + let send_ingress = send_ingres; + // Map of `addr -> peers`, to send messages to. + let mut peers_send = HashMap::new(); + // `StreamMap` of `addr -> peers`, to receive messages from. Automatically removes streams + // when they disconnect. + let mut peers_recv = StreamMap::>::new(); + loop { - let (stream, peer_addr) = if let Ok((stream, _)) = listener.accept().await { - if let Ok(peer_addr) = stream.peer_addr() { - (stream, peer_addr) - } else { - continue; + // Calling methods in a loop, futures must be cancel-safe. + select! { + // `biased` means the cases will be prioritized in the order they are listed. + // First we accept any new connections + // This is not strictly neccessary, but lets us do our internal work (send outgoing + // messages) before accepting more work (receiving more messages, accepting new + // clients). + biased; + // Send outgoing messages. + msg_send = recv_egress.next() => { + let Some((payload, peer_addr)) = msg_send else { + // `None` if the send side has been dropped (no more send messages will ever come). + continue; + }; + let Some(stream) = peers_send.get_mut(&peer_addr) else { + tracing::warn!("Dropping message to non-connected peer: {}", peer_addr); + continue; + }; + if let Err(err) = SinkExt::send(stream, payload).await { + tracing::error!("IO or codec error sending message to peer {}, disconnecting: {:?}", peer_addr, err); + peers_send.remove(&peer_addr); // `Drop` disconnects. + }; } - } else { - continue; - }; - - let mut tx_ingress = tx_ingress.clone(); - - let (send, recv) = tcp_framed(stream, codec.clone()); - - // TODO: Using peer_addr here as the key is a little bit sketchy. - // It's possible that a client could send a message, disconnect, then another client connects from the same IP address (and the same src port), and then the response could be sent to that new client. - // This can be solved by using monotonically increasing IDs for each new client, but would break the similarity with the UDP versions of this function. - clients.borrow_mut().insert(peer_addr, send); - - spawn_local({ - let clients = clients.clone(); - async move { - let mapped = recv.map(|x| Ok(x.map(|x| (x, peer_addr)))); - let _ = tx_ingress.send_all(&mut pin!(mapped)).await; - - clients.borrow_mut().remove(&peer_addr); + // Receive incoming messages. + msg_recv = peers_recv.next(), if !peers_recv.is_empty() => { + // If `peers_recv` is empty then `next()` will immediately return `None` which + // would cause the loop to spin. + let Some((peer_addr, payload_result)) = msg_recv else { + continue; // => `peers_recv.is_empty()`. + }; + if let Err(err) = send_ingress.send(payload_result.map(|payload| (payload, peer_addr))).await { + tracing::error!("Error passing along received message: {:?}", err); + } } - }); + // Accept new clients. + new_peer = listener.accept() => { + let Ok((stream, _addr)) = new_peer else { + continue; + }; + let Ok(peer_addr) = stream.peer_addr() else { + continue; + }; + let (peer_send, peer_recv) = tcp_framed(stream, codec.clone()); + + // TODO: Using peer_addr here as the key is a little bit sketchy. + // It's possible that a peer could send a message, disconnect, then another peer connects from the + // same IP address (and the same src port), and then the response could be sent to that new client. + // This can be solved by using monotonically increasing IDs for each new peer, but would break the + // similarity with the UDP versions of this function. + peers_send.insert(peer_addr, peer_send); + peers_recv.insert(peer_addr, peer_recv); + } + } } }); - Ok((tx_egress, rx_ingress, bound_endpoint)) + Ok((send_egress, recv_ingres, bound_endpoint)) } /// The inverse of [`bind_tcp`]. @@ -144,37 +165,69 @@ pub async fn bind_tcp> /// When messages enqueued into the returned sender, tcp sockets will be created and connected as /// necessary to send out the requests. As the responses come back, they will be forwarded to the /// returned receiver. -pub fn connect_tcp>( - codec: Codec, -) -> (TcpFramedSink, TcpFramedStream) { - let (tx_egress, mut rx_egress) = unsync_channel(None); - let (tx_ingress, rx_ingress) = unsync_channel(None); +pub fn connect_tcp(codec: Codec) -> (TcpFramedSink, TcpFramedStream) +where + Item: 'static, + Codec: 'static + Clone + Decoder + Encoder, + >::Error: Debug, +{ + let (send_egress, mut recv_egress) = unsync_channel(None); + let (send_ingres, recv_ingres) = unsync_channel(None); spawn_local(async move { - let mut streams = HashMap::new(); + let send_ingres = send_ingres; + // Map of `addr -> peers`, to send messages to. + let mut peers_send = HashMap::new(); + // `StreamMap` of `addr -> peers`, to receive messages from. Automatically removes streams + // when they disconnect. + let mut peers_recv = StreamMap::new(); - while let Some((payload, addr)) = rx_egress.next().await { - let stream = match streams.entry(addr) { - Occupied(entry) => entry.into_mut(), - Vacant(entry) => { - let socket = TcpSocket::new_v4().unwrap(); - let stream = socket.connect(addr).await.unwrap(); - - let (send, recv) = tcp_framed(stream, codec.clone()); - - let mut tx_ingress = tx_ingress.clone(); - spawn_local(async move { - let mapped = recv.map(|x| Ok(x.map(|x| (x, addr)))); - let _ = tx_ingress.send_all(&mut pin!(mapped)).await; - }); - - entry.insert(send) + loop { + // Calling methods in a loop, futures must be cancel-safe. + select! { + // `biased` means the cases will be prioritized in the order they are listed. + // This is not strictly neccessary, but lets us do our internal work (send outgoing + // messages) before accepting more work (receiving more messages). + biased; + // Send outgoing messages. + msg_send = recv_egress.next() => { + let Some((payload, peer_addr)) = msg_send else { + // `None` if the send side has been dropped (no more send messages will ever come). + continue; + }; + + let stream = match peers_send.entry(peer_addr) { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => { + let socket = TcpSocket::new_v4().unwrap(); + let stream = socket.connect(peer_addr).await.unwrap(); + + let (peer_send, peer_recv) = tcp_framed(stream, codec.clone()); + + peers_recv.insert(peer_addr, peer_recv); + entry.insert(peer_send) + } + }; + + if let Err(err) = stream.send(payload).await { + tracing::error!("IO or codec error sending message to peer {}, disconnecting: {:?}", peer_addr, err); + peers_send.remove(&peer_addr); // `Drop` disconnects. + } } - }; - - let _ = stream.send(payload).await; + // Receive incoming messages. + msg_recv = peers_recv.next(), if !peers_recv.is_empty() => { + // If `peers_recv` is empty then `next()` will immediately return `None` which + // would cause the loop to spin. + let Some((peer_addr, payload_result)) = msg_recv else { + continue; // => `peers_recv.is_empty()`. + }; + if let Err(err) = send_ingres.send(payload_result.map(|payload| (payload, peer_addr))).await { + tracing::error!("Error passing along received message: {:?}", err); + } + } + } } }); - (tx_egress, rx_ingress) + (send_egress, recv_ingres) } diff --git a/hydroflow/tests/compile-fail/surface_loop_cycle.rs b/hydroflow/tests/compile-fail/surface_loop_cycle.rs new file mode 100644 index 000000000000..0ddf384b4564 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_cycle.rs @@ -0,0 +1,9 @@ +fn main() { + let mut df = hydroflow::hydroflow_syntax! { + loop { + a = identity() -> identity() -> identity() -> identity(); + a -> a; + } + }; + df.run_available(); +} diff --git a/hydroflow/tests/compile-fail/surface_loop_cycle.stderr b/hydroflow/tests/compile-fail/surface_loop_cycle.stderr new file mode 100644 index 000000000000..dc056047cbf9 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_cycle.stderr @@ -0,0 +1,23 @@ +error: Operator forms an illegal cycle within a `loop { ... }` block (1/4). + --> tests/compile-fail/surface_loop_cycle.rs:4:31 + | +4 | a = identity() -> identity() -> identity() -> identity(); + | ^^^^^^^^^^ + +error: Operator forms an illegal cycle within a `loop { ... }` block (2/4). + --> tests/compile-fail/surface_loop_cycle.rs:4:45 + | +4 | a = identity() -> identity() -> identity() -> identity(); + | ^^^^^^^^^^ + +error: Operator forms an illegal cycle within a `loop { ... }` block (3/4). + --> tests/compile-fail/surface_loop_cycle.rs:4:59 + | +4 | a = identity() -> identity() -> identity() -> identity(); + | ^^^^^^^^^^ + +error: Operator forms an illegal cycle within a `loop { ... }` block (4/4). + --> tests/compile-fail/surface_loop_cycle.rs:4:17 + | +4 | a = identity() -> identity() -> identity() -> identity(); + | ^^^^^^^^^^ diff --git a/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.rs b/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.rs new file mode 100644 index 000000000000..808bfae7a0e2 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.rs @@ -0,0 +1,10 @@ +fn main() { + let mut df = hydroflow::hydroflow_syntax! { + a = source_iter(0..10); + loop { + b = a -> batch(); + } + b -> null(); + }; + df.run_available(); +} diff --git a/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.stderr b/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.stderr new file mode 100644 index 000000000000..e0343ead3779 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_missing_unwindowing.stderr @@ -0,0 +1,5 @@ +error: Operator `null(...)` exiting a loop context must be an un-windowing operator, but is not. + --> tests/compile-fail/surface_loop_missing_unwindowing.rs:7:14 + | +7 | b -> null(); + | ^^^^^^ diff --git a/hydroflow/tests/compile-fail/surface_loop_missing_windowing.rs b/hydroflow/tests/compile-fail/surface_loop_missing_windowing.rs new file mode 100644 index 000000000000..2177d2ad0e8c --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_missing_windowing.rs @@ -0,0 +1,9 @@ +fn main() { + let mut df = hydroflow::hydroflow_syntax! { + a = source_iter(0..10); + loop { + a -> null(); + } + }; + df.run_available(); +} diff --git a/hydroflow/tests/compile-fail/surface_loop_missing_windowing.stderr b/hydroflow/tests/compile-fail/surface_loop_missing_windowing.stderr new file mode 100644 index 000000000000..1735ebd48911 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_missing_windowing.stderr @@ -0,0 +1,5 @@ +error: Operator `null(...)` entering a loop context must be a windowing operator, but is not. + --> tests/compile-fail/surface_loop_missing_windowing.rs:5:18 + | +5 | a -> null(); + | ^^^^^^ diff --git a/hydroflow/tests/compile-fail/surface_loop_multiple_window.rs b/hydroflow/tests/compile-fail/surface_loop_multiple_window.rs new file mode 100644 index 000000000000..eb0eb775bf29 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_multiple_window.rs @@ -0,0 +1,11 @@ +fn main() { + let mut df = hydroflow::hydroflow_syntax! { + a = source_iter(0..10); + loop { + loop { + a -> batch() -> null(); + } + } + }; + df.run_available(); +} diff --git a/hydroflow/tests/compile-fail/surface_loop_multiple_window.stderr b/hydroflow/tests/compile-fail/surface_loop_multiple_window.stderr new file mode 100644 index 000000000000..00a863b05482 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_multiple_window.stderr @@ -0,0 +1,5 @@ +error: Operator input edge may not cross multiple loop contexts. + --> tests/compile-fail/surface_loop_multiple_window.rs:6:22 + | +6 | a -> batch() -> null(); + | ^^^^^^^ diff --git a/hydroflow/tests/compile-fail/surface_loop_source.rs b/hydroflow/tests/compile-fail/surface_loop_source.rs new file mode 100644 index 000000000000..edea1a7ad958 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_source.rs @@ -0,0 +1,8 @@ +fn main() { + let mut df = hydroflow::hydroflow_syntax! { + loop { + source_iter(0..10) -> null(); + } + }; + df.run_available(); +} diff --git a/hydroflow/tests/compile-fail/surface_loop_source.stderr b/hydroflow/tests/compile-fail/surface_loop_source.stderr new file mode 100644 index 000000000000..34bbb210a144 --- /dev/null +++ b/hydroflow/tests/compile-fail/surface_loop_source.stderr @@ -0,0 +1,5 @@ +error: Source operator `source_iter(...)` must be at the root level, not within any `loop { ... }` contexts. + --> tests/compile-fail/surface_loop_source.rs:4:13 + | +4 | source_iter(0..10) -> null(); + | ^^^^^^^^^^^^^^^^^^ diff --git a/hydroflow/tests/compile-fail/surface_source_iter_badtype.rs b/hydroflow/tests/compile-fail/surface_source_iter_badtype.rs.ignore similarity index 68% rename from hydroflow/tests/compile-fail/surface_source_iter_badtype.rs rename to hydroflow/tests/compile-fail/surface_source_iter_badtype.rs.ignore index 026c5f14bf66..f97ad44dfcf2 100644 --- a/hydroflow/tests/compile-fail/surface_source_iter_badtype.rs +++ b/hydroflow/tests/compile-fail/surface_source_iter_badtype.rs.ignore @@ -2,7 +2,7 @@ use hydroflow::hydroflow_syntax; fn main() { let mut df = hydroflow_syntax! { - source_iter(5) -> for_each(std::mem::drop); + source_iter(()) -> for_each(std::mem::drop); }; df.run_available(); } diff --git a/hydroflow/tests/compile-fail/surface_source_iter_badtype.stderr b/hydroflow/tests/compile-fail/surface_source_iter_badtype.stderr index 9866f73a5d6b..85d2c8e16e8d 100644 --- a/hydroflow/tests/compile-fail/surface_source_iter_badtype.stderr +++ b/hydroflow/tests/compile-fail/surface_source_iter_badtype.stderr @@ -1,45 +1,44 @@ -error[E0277]: `{integer}` is not an iterator +error[E0277]: `()` is not an iterator --> tests/compile-fail/surface_source_iter_badtype.rs:5:21 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ------------^- +5 | source_iter(()) -> for_each(std::mem::drop); + | ------------^^- | | | - | | `{integer}` is not an iterator + | | `()` is not an iterator | required by a bound introduced by this call | - = help: the trait `Iterator` is not implemented for `{integer}`, which is required by `{integer}: IntoIterator` - = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end` - = note: required for `{integer}` to implement `IntoIterator` + = help: the trait `Iterator` is not implemented for `()`, which is required by `(): IntoIterator` + = note: required for `()` to implement `IntoIterator` note: required by a bound in `check_iter` --> tests/compile-fail/surface_source_iter_badtype.rs:5:9 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ^^^^^^^^^^^^^^ required by this bound in `check_iter` +5 | source_iter(()) -> for_each(std::mem::drop); + | ^^^^^^^^^^^^^^^ required by this bound in `check_iter` -error[E0277]: `{integer}` is not an iterator +error[E0277]: `()` is not an iterator --> tests/compile-fail/surface_source_iter_badtype.rs:5:9 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ^^^^^^^^^^^^^^ `{integer}` is not an iterator +5 | source_iter(()) -> for_each(std::mem::drop); + | ^^^^^^^^^^^^^^^ `()` is not an iterator | - = help: the trait `Iterator` is not implemented for `{integer}`, which is required by `{integer}: IntoIterator` - = note: required for `{integer}` to implement `IntoIterator` + = help: the trait `Iterator` is not implemented for `()`, which is required by `(): IntoIterator` + = note: required for `()` to implement `IntoIterator` note: required by a bound in `check_iter` --> tests/compile-fail/surface_source_iter_badtype.rs:5:9 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ^^^^^^^^^^^^^^ required by this bound in `check_iter` +5 | source_iter(()) -> for_each(std::mem::drop); + | ^^^^^^^^^^^^^^^ required by this bound in `check_iter` -error[E0277]: `{integer}` is not an iterator +error[E0277]: `()` is not an iterator --> tests/compile-fail/surface_source_iter_badtype.rs:5:9 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `{integer}` is not an iterator +5 | source_iter(()) -> for_each(std::mem::drop); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator | - = help: the trait `Iterator` is not implemented for `{integer}`, which is required by `{integer}: IntoIterator` - = note: required for `{integer}` to implement `IntoIterator` + = help: the trait `Iterator` is not implemented for `()`, which is required by `(): IntoIterator` + = note: required for `()` to implement `IntoIterator` note: required by a bound in `check_iter` --> tests/compile-fail/surface_source_iter_badtype.rs:5:9 | -5 | source_iter(5) -> for_each(std::mem::drop); - | ^^^^^^^^^^^^^^ required by this bound in `check_iter` +5 | source_iter(()) -> for_each(std::mem::drop); + | ^^^^^^^^^^^^^^^ required by this bound in `check_iter` diff --git a/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_dot.snap new file mode 100644 index 000000000000..7957a90e7979 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_dot.snap @@ -0,0 +1,158 @@ +--- +source: hydroflow/tests/surface_cross_singleton.rs +expression: "df.meta_graph().unwrap().to_dot(& Default :: default())" +--- +digraph { + node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; + edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; + n1v1 [label="(n1v1) source_stream(cross_rx)", shape=invhouse, fillcolor="#88aaff"] + n2v1 [label="(n2v1) sort()", shape=invhouse, fillcolor="#88aaff"] + n3v1 [label="(n3v1) tee()", shape=house, fillcolor="#ffff88"] + n4v1 [label="(n4v1) defer_tick_lazy()", shape=invhouse, fillcolor="#88aaff"] + n5v1 [label="(n5v1) source_iter([0])", shape=invhouse, fillcolor="#88aaff"] + n6v1 [label="(n6v1) persist::<'static>()", shape=invhouse, fillcolor="#88aaff"] + n7v1 [label="(n7v1) union()", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) cross_singleton()", shape=invhouse, fillcolor="#88aaff"] + n9v1 [label="(n9v1) tee()", shape=house, fillcolor="#ffff88"] + n10v1 [label="(n10v1) for_each(|x| egress_tx.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n11v1 [label="(n11v1) fold(|| 0, |_, _| {})", shape=invhouse, fillcolor="#88aaff"] + n12v1 [label="(n12v1) cross_singleton()", shape=invhouse, fillcolor="#88aaff"] + n13v1 [label="(n13v1) fold(|| 0, |_, _| {})", shape=invhouse, fillcolor="#88aaff"] + n14v1 [label="(n14v1) flat_map(|_| [])", shape=invhouse, fillcolor="#88aaff"] + n15v1 [label="(n15v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n16v1 [label="(n16v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n17v1 [label="(n17v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n18v1 [label="(n18v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n19v1 [label="(n19v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n20v1 [label="(n20v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n21v1 [label="(n21v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n22v1 [label="(n22v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n23v1 [label="(n23v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n24v1 [label="(n24v1) identity()", shape=invhouse, fillcolor="#88aaff"] + n25v1 [label="(n25v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n2v1 -> n3v1 + n1v1 -> n15v1 + n3v1 -> n16v1 + n4v1 -> n7v1 [label="0"] + n14v1 -> n17v1 + n5v1 -> n6v1 + n6v1 -> n7v1 [label="1"] + n7v1 -> n18v1 + n8v1 -> n9v1 + n9v1 -> n10v1 + n9v1 -> n19v1 + n3v1 -> n20v1 + n11v1 -> n21v1 + n13v1 -> n22v1 + n12v1 -> n23v1 + n15v1 -> n2v1 [color=red] + n16v1 -> n8v1 [label="input"] + n17v1 -> n24v1 + n18v1 -> n8v1 [label="single", color=red] + n19v1 -> n11v1 [color=red] + n20v1 -> n12v1 [label="input"] + n21v1 -> n12v1 [label="single", color=red] + n22v1 -> n14v1 + n23v1 -> n13v1 [color=red] + n24v1 -> n25v1 + n25v1 -> n4v1 [color=red] + subgraph "cluster n1v1" { + fillcolor="#dddddd" + style=filled + label = "sg_1v1\nstratum 0" + n1v1 + subgraph "cluster_sg_1v1_var_teed_in" { + label="var teed_in" + n1v1 + } + } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 1" + n2v1 + n3v1 + subgraph "cluster_sg_2v1_var_teed_in" { + label="var teed_in" + n2v1 + n3v1 + } + } + subgraph "cluster n3v1" { + fillcolor="#dddddd" + style=filled + label = "sg_3v1\nstratum 0" + n4v1 + n5v1 + n6v1 + n7v1 + subgraph "cluster_sg_3v1_var_persisted_stream" { + label="var persisted_stream" + n5v1 + n6v1 + } + subgraph "cluster_sg_3v1_var_unioned_stream" { + label="var unioned_stream" + n7v1 + } + } + subgraph "cluster n4v1" { + fillcolor="#dddddd" + style=filled + label = "sg_4v1\nstratum 1" + n8v1 + n9v1 + n10v1 + subgraph "cluster_sg_4v1_var_join" { + label="var join" + n8v1 + n9v1 + } + } + subgraph "cluster n5v1" { + fillcolor="#dddddd" + style=filled + label = "sg_5v1\nstratum 2" + n11v1 + subgraph "cluster_sg_5v1_var_folded_thing" { + label="var folded_thing" + n11v1 + } + } + subgraph "cluster n6v1" { + fillcolor="#dddddd" + style=filled + label = "sg_6v1\nstratum 3" + n12v1 + subgraph "cluster_sg_6v1_var_joined_folded" { + label="var joined_folded" + n12v1 + } + } + subgraph "cluster n7v1" { + fillcolor="#dddddd" + style=filled + label = "sg_7v1\nstratum 4" + n13v1 + subgraph "cluster_sg_7v1_var_deferred_stream" { + label="var deferred_stream" + n13v1 + } + } + subgraph "cluster n8v1" { + fillcolor="#dddddd" + style=filled + label = "sg_8v1\nstratum 4" + n14v1 + subgraph "cluster_sg_8v1_var_deferred_stream" { + label="var deferred_stream" + n14v1 + } + } + subgraph "cluster n9v1" { + fillcolor="#dddddd" + style=filled + label = "sg_9v1\nstratum 5" + n24v1 + } +} diff --git a/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_mermaid.snap new file mode 100644 index 000000000000..ae77d69d57cc --- /dev/null +++ b/hydroflow/tests/snapshots/surface_cross_singleton__union_defer_tick@graphvis_mermaid.snap @@ -0,0 +1,124 @@ +--- +source: hydroflow/tests/surface_cross_singleton.rs +expression: "df.meta_graph().unwrap().to_mermaid(& Default :: default())" +--- +%%{init:{'theme':'base','themeVariables':{'clusterBkg':'#ddd','clusterBorder':'#888'}}}%% +flowchart TD +classDef pullClass fill:#8af,stroke:#000,text-align:left,white-space:pre +classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre +classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre +linkStyle default stroke:#aaa +1v1[\"(1v1) source_stream(cross_rx)"/]:::pullClass +2v1[\"(2v1) sort()"/]:::pullClass +3v1[/"(3v1) tee()"\]:::pushClass +4v1[\"(4v1) defer_tick_lazy()"/]:::pullClass +5v1[\"(5v1) source_iter([0])"/]:::pullClass +6v1[\"(6v1) persist::<'static>()"/]:::pullClass +7v1[\"(7v1) union()"/]:::pullClass +8v1[\"(8v1) cross_singleton()"/]:::pullClass +9v1[/"(9v1) tee()"\]:::pushClass +10v1[/"(10v1) for_each(|x| egress_tx.send(x).unwrap())"\]:::pushClass +11v1[\"(11v1) fold(|| 0, |_, _| {})"/]:::pullClass +12v1[\"(12v1) cross_singleton()"/]:::pullClass +13v1[\"(13v1) fold(|| 0, |_, _| {})"/]:::pullClass +14v1[\"(14v1) flat_map(|_| [])"/]:::pullClass +15v1["(15v1) handoff"]:::otherClass +16v1["(16v1) handoff"]:::otherClass +17v1["(17v1) handoff"]:::otherClass +18v1["(18v1) handoff"]:::otherClass +19v1["(19v1) handoff"]:::otherClass +20v1["(20v1) handoff"]:::otherClass +21v1["(21v1) handoff"]:::otherClass +22v1["(22v1) handoff"]:::otherClass +23v1["(23v1) handoff"]:::otherClass +24v1[\"(24v1) identity()"/]:::pullClass +25v1["(25v1) handoff"]:::otherClass +2v1-->3v1 +1v1-->15v1 +3v1-->16v1 +4v1-->|0|7v1 +14v1-->17v1 +5v1-->6v1 +6v1-->|1|7v1 +7v1-->18v1 +8v1-->9v1 +9v1-->10v1 +9v1-->19v1 +3v1-->20v1 +11v1-->21v1 +13v1-->22v1 +12v1-->23v1 +15v1--x2v1; linkStyle 15 stroke:red +16v1-->|input|8v1 +17v1-->24v1 +18v1--x|single|8v1; linkStyle 18 stroke:red +19v1--x11v1; linkStyle 19 stroke:red +20v1-->|input|12v1 +21v1--x|single|12v1; linkStyle 21 stroke:red +22v1-->14v1 +23v1--x13v1; linkStyle 23 stroke:red +24v1-->25v1 +25v1--o4v1; linkStyle 25 stroke:red +subgraph sg_1v1 ["sg_1v1 stratum 0"] + 1v1 + subgraph sg_1v1_var_teed_in ["var teed_in"] + 1v1 + end +end +subgraph sg_2v1 ["sg_2v1 stratum 1"] + 2v1 + 3v1 + subgraph sg_2v1_var_teed_in ["var teed_in"] + 2v1 + 3v1 + end +end +subgraph sg_3v1 ["sg_3v1 stratum 0"] + 4v1 + 5v1 + 6v1 + 7v1 + subgraph sg_3v1_var_persisted_stream ["var persisted_stream"] + 5v1 + 6v1 + end + subgraph sg_3v1_var_unioned_stream ["var unioned_stream"] + 7v1 + end +end +subgraph sg_4v1 ["sg_4v1 stratum 1"] + 8v1 + 9v1 + 10v1 + subgraph sg_4v1_var_join ["var join"] + 8v1 + 9v1 + end +end +subgraph sg_5v1 ["sg_5v1 stratum 2"] + 11v1 + subgraph sg_5v1_var_folded_thing ["var folded_thing"] + 11v1 + end +end +subgraph sg_6v1 ["sg_6v1 stratum 3"] + 12v1 + subgraph sg_6v1_var_joined_folded ["var joined_folded"] + 12v1 + end +end +subgraph sg_7v1 ["sg_7v1 stratum 4"] + 13v1 + subgraph sg_7v1_var_deferred_stream ["var deferred_stream"] + 13v1 + end +end +subgraph sg_8v1 ["sg_8v1 stratum 4"] + 14v1 + subgraph sg_8v1_var_deferred_stream ["var deferred_stream"] + 14v1 + end +end +subgraph sg_9v1 ["sg_9v1 stratum 5"] + 24v1 +end diff --git a/hydroflow/tests/snapshots/surface_examples__example_1_simplest.snap b/hydroflow/tests/snapshots/surface_examples__example_1_simplest.snap index fa30505c69cd..065e174f4cb3 100644 --- a/hydroflow/tests/snapshots/surface_examples__example_1_simplest.snap +++ b/hydroflow/tests/snapshots/surface_examples__example_1_simplest.snap @@ -12,4 +12,3 @@ Hello 6 Hello 7 Hello 8 Hello 9 - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_dot.snap index e8a4194cc706..9e81d0e6973d 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_dot.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_dot.snap @@ -12,22 +12,18 @@ digraph { n5v1 [label="(n5v1) map(SetUnionSingletonSet::new_from)", shape=invhouse, fillcolor="#88aaff"] n6v1 [label="(n6v1) state::<'static, SetUnionHashSet>()", shape=invhouse, fillcolor="#88aaff"] n7v1 [label="(n7v1) lattice_bimorphism(CartesianProductBimorphism::>::default(), lhs, rhs)", shape=invhouse, fillcolor="#88aaff"] - n8v1 [label="(n8v1) lattice_reduce()", shape=invhouse, fillcolor="#88aaff"] - n9v1 [label="(n9v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n8v1 [label="(n8v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n11v1 [label="(n11v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n12v1 [label="(n12v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n2v1 -> n3v1 n1v1 -> n2v1 n5v1 -> n6v1 n4v1 -> n5v1 - n3v1 -> n10v1 - n6v1 -> n11v1 - n8v1 -> n9v1 - n7v1 -> n12v1 - n10v1 -> n7v1 [label="0"] - n11v1 -> n7v1 [label="1"] - n12v1 -> n8v1 [color=red] + n3v1 -> n9v1 + n6v1 -> n10v1 + n7v1 -> n8v1 + n9v1 -> n7v1 [label="0"] + n10v1 -> n7v1 [label="1"] n3v1 -> n7v1 [color=red] n6v1 -> n7v1 [color=red] subgraph "cluster n1v1" { @@ -63,22 +59,11 @@ digraph { style=filled label = "sg_3v1\nstratum 1" n7v1 + n8v1 subgraph "cluster_sg_3v1_var_my_join" { label="var my_join" n7v1 - } - } - subgraph "cluster n4v1" { - fillcolor="#dddddd" - style=filled - label = "sg_4v1\nstratum 1" - n8v1 - n9v1 - subgraph "cluster_sg_4v1_var_my_join" { - label="var my_join" n8v1 - n9v1 } } } - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_mermaid.snap index 9a8e0c4a1c46..60c4b26b33f7 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product@graphvis_mermaid.snap @@ -15,24 +15,20 @@ linkStyle default stroke:#aaa 5v1[\"(5v1) map(SetUnionSingletonSet::new_from)"/]:::pullClass 6v1[\"(6v1) state::<'static, SetUnionHashSet<u32>>()"/]:::pullClass 7v1[\"(7v1) lattice_bimorphism(CartesianProductBimorphism::<HashSet<_>>::default(), lhs, rhs)"/]:::pullClass -8v1[\"(8v1) lattice_reduce()"/]:::pullClass -9v1[/"(9v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +8v1[/"(8v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +9v1["(9v1) handoff"]:::otherClass 10v1["(10v1) handoff"]:::otherClass -11v1["(11v1) handoff"]:::otherClass -12v1["(12v1) handoff"]:::otherClass 2v1-->3v1 1v1-->2v1 5v1-->6v1 4v1-->5v1 -3v1-->10v1 -6v1-->11v1 -8v1-->9v1 -7v1-->12v1 -10v1-->|0|7v1 -11v1-->|1|7v1 -12v1-->8v1; linkStyle 10 stroke:#060 -3v1--x7v1; linkStyle 11 stroke:red -6v1--x7v1; linkStyle 12 stroke:red +3v1-->9v1 +6v1-->10v1 +7v1-->8v1 +9v1-->|0|7v1 +10v1-->|1|7v1 +3v1--x7v1; linkStyle 9 stroke:red +6v1--x7v1; linkStyle 10 stroke:red subgraph sg_1v1 ["sg_1v1 stratum 0"] 1v1 2v1 @@ -55,16 +51,9 @@ subgraph sg_2v1 ["sg_2v1 stratum 0"] end subgraph sg_3v1 ["sg_3v1 stratum 1"] 7v1 + 8v1 subgraph sg_3v1_var_my_join ["var my_join"] 7v1 - end -end -subgraph sg_4v1 ["sg_4v1 stratum 1"] - 8v1 - 9v1 - subgraph sg_4v1_var_my_join ["var my_join"] 8v1 - 9v1 end end - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_dot.snap new file mode 100644 index 000000000000..a1f6888a2b86 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_dot.snap @@ -0,0 +1,69 @@ +--- +source: hydroflow/tests/surface_lattice_bimorphism.rs +expression: "df.meta_graph().unwrap().to_dot(& Default :: default())" +--- +digraph { + node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; + edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; + n1v1 [label="(n1v1) source_iter(0..1)", shape=invhouse, fillcolor="#88aaff"] + n2v1 [label="(n2v1) map(SetUnionSingletonSet::new_from)", shape=invhouse, fillcolor="#88aaff"] + n3v1 [label="(n3v1) state::<'static, SetUnionHashSet>()", shape=invhouse, fillcolor="#88aaff"] + n4v1 [label="(n4v1) source_iter(1..2)", shape=invhouse, fillcolor="#88aaff"] + n5v1 [label="(n5v1) map(SetUnionSingletonSet::new_from)", shape=invhouse, fillcolor="#88aaff"] + n6v1 [label="(n6v1) state::<'static, SetUnionHashSet>()", shape=invhouse, fillcolor="#88aaff"] + n7v1 [label="(n7v1) lattice_bimorphism(CartesianProductBimorphism::>::default(), lhs, rhs)", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n2v1 -> n3v1 + n1v1 -> n2v1 + n5v1 -> n6v1 + n4v1 -> n5v1 + n3v1 -> n9v1 + n6v1 -> n10v1 + n7v1 -> n8v1 + n9v1 -> n7v1 [label="0"] + n10v1 -> n7v1 [label="1"] + n3v1 -> n7v1 [color=red] + n6v1 -> n7v1 [color=red] + subgraph "cluster n1v1" { + fillcolor="#dddddd" + style=filled + label = "sg_1v1\nstratum 0" + n1v1 + n2v1 + n3v1 + subgraph "cluster_sg_1v1_var_lhs" { + label="var lhs" + n1v1 + n2v1 + n3v1 + } + } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 0" + n4v1 + n5v1 + n6v1 + subgraph "cluster_sg_2v1_var_rhs" { + label="var rhs" + n4v1 + n5v1 + n6v1 + } + } + subgraph "cluster n3v1" { + fillcolor="#dddddd" + style=filled + label = "sg_3v1\nstratum 1" + n7v1 + n8v1 + subgraph "cluster_sg_3v1_var_my_join" { + label="var my_join" + n7v1 + n8v1 + } + } +} diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_mermaid.snap new file mode 100644 index 000000000000..08e6a806fc42 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_1401@graphvis_mermaid.snap @@ -0,0 +1,59 @@ +--- +source: hydroflow/tests/surface_lattice_bimorphism.rs +expression: "df.meta_graph().unwrap().to_mermaid(& Default :: default())" +--- +%%{init:{'theme':'base','themeVariables':{'clusterBkg':'#ddd','clusterBorder':'#888'}}}%% +flowchart TD +classDef pullClass fill:#8af,stroke:#000,text-align:left,white-space:pre +classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre +classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre +linkStyle default stroke:#aaa +1v1[\"(1v1) source_iter(0..1)"/]:::pullClass +2v1[\"(2v1) map(SetUnionSingletonSet::new_from)"/]:::pullClass +3v1[\"(3v1) state::<'static, SetUnionHashSet<u32>>()"/]:::pullClass +4v1[\"(4v1) source_iter(1..2)"/]:::pullClass +5v1[\"(5v1) map(SetUnionSingletonSet::new_from)"/]:::pullClass +6v1[\"(6v1) state::<'static, SetUnionHashSet<u32>>()"/]:::pullClass +7v1[\"(7v1) lattice_bimorphism(CartesianProductBimorphism::<HashSet<_>>::default(), lhs, rhs)"/]:::pullClass +8v1[/"(8v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +9v1["(9v1) handoff"]:::otherClass +10v1["(10v1) handoff"]:::otherClass +2v1-->3v1 +1v1-->2v1 +5v1-->6v1 +4v1-->5v1 +3v1-->9v1 +6v1-->10v1 +7v1-->8v1 +9v1-->|0|7v1 +10v1-->|1|7v1 +3v1--x7v1; linkStyle 9 stroke:red +6v1--x7v1; linkStyle 10 stroke:red +subgraph sg_1v1 ["sg_1v1 stratum 0"] + 1v1 + 2v1 + 3v1 + subgraph sg_1v1_var_lhs ["var lhs"] + 1v1 + 2v1 + 3v1 + end +end +subgraph sg_2v1 ["sg_2v1 stratum 0"] + 4v1 + 5v1 + 6v1 + subgraph sg_2v1_var_rhs ["var rhs"] + 4v1 + 5v1 + 6v1 + end +end +subgraph sg_3v1 ["sg_3v1 stratum 1"] + 7v1 + 8v1 + subgraph sg_3v1_var_my_join ["var my_join"] + 7v1 + 8v1 + end +end diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_dot.snap index 8e00b09a5bba..239b30948c41 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_dot.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_dot.snap @@ -12,24 +12,20 @@ digraph { n5v1 [label="(n5v1) map(SetUnionSingletonSet::new_from)", shape=invhouse, fillcolor="#88aaff"] n6v1 [label="(n6v1) state::<'tick, SetUnionHashSet>()", shape=invhouse, fillcolor="#88aaff"] n7v1 [label="(n7v1) lattice_bimorphism(CartesianProductBimorphism::>::default(), lhs, rhs)", shape=invhouse, fillcolor="#88aaff"] - n8v1 [label="(n8v1) lattice_reduce()", shape=invhouse, fillcolor="#88aaff"] - n9v1 [label="(n9v1) inspect(|x| println!(\"{:?}: {:?}\", context.current_tick(), x))", shape=invhouse, fillcolor="#88aaff"] - n10v1 [label="(n10v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n8v1 [label="(n8v1) inspect(|x| println!(\"{:?}: {:?}\", context.current_tick(), x))", shape=invhouse, fillcolor="#88aaff"] + n9v1 [label="(n9v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n11v1 [label="(n11v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n12v1 [label="(n12v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n13v1 [label="(n13v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n2v1 -> n3v1 n1v1 -> n2v1 n5v1 -> n6v1 n4v1 -> n5v1 - n3v1 -> n11v1 [label="items"] - n6v1 -> n12v1 [label="items"] - n9v1 -> n10v1 + n3v1 -> n10v1 [label="items"] + n6v1 -> n11v1 [label="items"] n8v1 -> n9v1 - n7v1 -> n13v1 - n11v1 -> n7v1 [label="0"] - n12v1 -> n7v1 [label="1"] - n13v1 -> n8v1 [color=red] + n7v1 -> n8v1 + n10v1 -> n7v1 [label="0"] + n11v1 -> n7v1 [label="1"] n3v1 -> n7v1 [color=red] n6v1 -> n7v1 [color=red] subgraph "cluster n1v1" { @@ -65,24 +61,13 @@ digraph { style=filled label = "sg_3v1\nstratum 1" n7v1 - subgraph "cluster_sg_3v1_var_my_join" { - label="var my_join" - n7v1 - } - } - subgraph "cluster n4v1" { - fillcolor="#dddddd" - style=filled - label = "sg_4v1\nstratum 1" n8v1 n9v1 - n10v1 - subgraph "cluster_sg_4v1_var_my_join" { + subgraph "cluster_sg_3v1_var_my_join" { label="var my_join" + n7v1 n8v1 n9v1 - n10v1 } } } - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_mermaid.snap index 639b4d963c73..a71d84cc9f12 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__cartesian_product_tick_state@graphvis_mermaid.snap @@ -15,26 +15,22 @@ linkStyle default stroke:#aaa 5v1[\"(5v1) map(SetUnionSingletonSet::new_from)"/]:::pullClass 6v1[\"(6v1) state::<'tick, SetUnionHashSet<u32>>()"/]:::pullClass 7v1[\"(7v1) lattice_bimorphism(CartesianProductBimorphism::<HashSet<_>>::default(), lhs, rhs)"/]:::pullClass -8v1[\"(8v1) lattice_reduce()"/]:::pullClass -9v1[\"(9v1) inspect(|x| println!("{:?}: {:?}", context.current_tick(), x))"/]:::pullClass -10v1[/"(10v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +8v1[\"(8v1) inspect(|x| println!("{:?}: {:?}", context.current_tick(), x))"/]:::pullClass +9v1[/"(9v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +10v1["(10v1) handoff"]:::otherClass 11v1["(11v1) handoff"]:::otherClass -12v1["(12v1) handoff"]:::otherClass -13v1["(13v1) handoff"]:::otherClass 2v1-->3v1 1v1-->2v1 5v1-->6v1 4v1-->5v1 -3v1-->|items|11v1 -6v1-->|items|12v1 -9v1-->10v1 +3v1-->|items|10v1 +6v1-->|items|11v1 8v1-->9v1 -7v1-->13v1 -11v1-->|0|7v1 -12v1-->|1|7v1 -13v1-->8v1; linkStyle 11 stroke:#060 -3v1--x7v1; linkStyle 12 stroke:red -6v1--x7v1; linkStyle 13 stroke:red +7v1-->8v1 +10v1-->|0|7v1 +11v1-->|1|7v1 +3v1--x7v1; linkStyle 10 stroke:red +6v1--x7v1; linkStyle 11 stroke:red subgraph sg_1v1 ["sg_1v1 stratum 0"] 1v1 2v1 @@ -57,18 +53,11 @@ subgraph sg_2v1 ["sg_2v1 stratum 0"] end subgraph sg_3v1 ["sg_3v1 stratum 1"] 7v1 - subgraph sg_3v1_var_my_join ["var my_join"] - 7v1 - end -end -subgraph sg_4v1 ["sg_4v1 stratum 1"] 8v1 9v1 - 10v1 - subgraph sg_4v1_var_my_join ["var my_join"] + subgraph sg_3v1_var_my_join ["var my_join"] + 7v1 8v1 9v1 - 10v1 end end - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_dot.snap index 4f4c53e737d3..11eb8a895be1 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_dot.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_dot.snap @@ -12,22 +12,18 @@ digraph { n5v1 [label="(n5v1) map(|(k, v)| MapUnionSingletonMap::new_from((k, SetUnionSingletonSet::new_from(v))))", shape=invhouse, fillcolor="#88aaff"] n6v1 [label="(n6v1) state::<'static, MapUnionHashMap>>()", shape=invhouse, fillcolor="#88aaff"] n7v1 [label="(n7v1) lattice_bimorphism(\l KeyedBimorphism::<\l HashMap<_, _>,\l _,\l >::new(CartesianProductBimorphism::>::default()),\l lhs,\l rhs,\l)\l", shape=invhouse, fillcolor="#88aaff"] - n8v1 [label="(n8v1) lattice_reduce()", shape=invhouse, fillcolor="#88aaff"] - n9v1 [label="(n9v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n8v1 [label="(n8v1) for_each(|x| out_send.send(x).unwrap())", shape=house, fillcolor="#ffff88"] + n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n11v1 [label="(n11v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n12v1 [label="(n12v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n2v1 -> n3v1 n1v1 -> n2v1 n5v1 -> n6v1 n4v1 -> n5v1 - n3v1 -> n10v1 - n6v1 -> n11v1 - n8v1 -> n9v1 - n7v1 -> n12v1 - n10v1 -> n7v1 [label="0"] - n11v1 -> n7v1 [label="1"] - n12v1 -> n8v1 [color=red] + n3v1 -> n9v1 + n6v1 -> n10v1 + n7v1 -> n8v1 + n9v1 -> n7v1 [label="0"] + n10v1 -> n7v1 [label="1"] n3v1 -> n7v1 [color=red] n6v1 -> n7v1 [color=red] subgraph "cluster n1v1" { @@ -63,22 +59,11 @@ digraph { style=filled label = "sg_3v1\nstratum 1" n7v1 + n8v1 subgraph "cluster_sg_3v1_var_my_join" { label="var my_join" n7v1 - } - } - subgraph "cluster n4v1" { - fillcolor="#dddddd" - style=filled - label = "sg_4v1\nstratum 1" - n8v1 - n9v1 - subgraph "cluster_sg_4v1_var_my_join" { - label="var my_join" n8v1 - n9v1 } } } - diff --git a/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_mermaid.snap index c271ea026819..f4a08363658f 100644 --- a/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_lattice_bimorphism__join@graphvis_mermaid.snap @@ -15,24 +15,20 @@ linkStyle default stroke:#aaa 5v1[\"(5v1) map(|(k, v)| MapUnionSingletonMap::new_from((k, SetUnionSingletonSet::new_from(v))))"/]:::pullClass 6v1[\"(6v1) state::<'static, MapUnionHashMap<usize, SetUnionHashSet<usize>>>()"/]:::pullClass 7v1[\"
(7v1)
lattice_bimorphism(
KeyedBimorphism::<
HashMap<_, _>,
_,
>::new(CartesianProductBimorphism::<HashSet<_>>::default()),
lhs,
rhs,
)
"/]:::pullClass -8v1[\"(8v1) lattice_reduce()"/]:::pullClass -9v1[/"(9v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +8v1[/"(8v1) for_each(|x| out_send.send(x).unwrap())"\]:::pushClass +9v1["(9v1) handoff"]:::otherClass 10v1["(10v1) handoff"]:::otherClass -11v1["(11v1) handoff"]:::otherClass -12v1["(12v1) handoff"]:::otherClass 2v1-->3v1 1v1-->2v1 5v1-->6v1 4v1-->5v1 -3v1-->10v1 -6v1-->11v1 -8v1-->9v1 -7v1-->12v1 -10v1-->|0|7v1 -11v1-->|1|7v1 -12v1-->8v1; linkStyle 10 stroke:#060 -3v1--x7v1; linkStyle 11 stroke:red -6v1--x7v1; linkStyle 12 stroke:red +3v1-->9v1 +6v1-->10v1 +7v1-->8v1 +9v1-->|0|7v1 +10v1-->|1|7v1 +3v1--x7v1; linkStyle 9 stroke:red +6v1--x7v1; linkStyle 10 stroke:red subgraph sg_1v1 ["sg_1v1 stratum 0"] 1v1 2v1 @@ -55,16 +51,9 @@ subgraph sg_2v1 ["sg_2v1 stratum 0"] end subgraph sg_3v1 ["sg_3v1 stratum 1"] 7v1 + 8v1 subgraph sg_3v1_var_my_join ["var my_join"] 7v1 - end -end -subgraph sg_4v1 ["sg_4v1 stratum 1"] - 8v1 - 9v1 - subgraph sg_4v1_var_my_join ["var my_join"] 8v1 - 9v1 end end - diff --git a/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_dot.snap new file mode 100644 index 000000000000..e566a3c1a17b --- /dev/null +++ b/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_dot.snap @@ -0,0 +1,72 @@ +--- +source: hydroflow/tests/surface_loop.rs +expression: "df.meta_graph().unwrap().to_dot(& Default :: default())" +--- +digraph { + node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; + edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; + n1v1 [label="(n1v1) source_iter([\"alice\", \"bob\"])", shape=invhouse, fillcolor="#88aaff"] + n2v1 [label="(n2v1) source_stream(iter_batches_stream(0..12, 3))", shape=invhouse, fillcolor="#88aaff"] + n3v1 [label="(n3v1) batch()", shape=invhouse, fillcolor="#88aaff"] + n4v1 [label="(n4v1) flatten()", shape=invhouse, fillcolor="#88aaff"] + n5v1 [label="(n5v1) batch()", shape=invhouse, fillcolor="#88aaff"] + n6v1 [label="(n6v1) flatten()", shape=invhouse, fillcolor="#88aaff"] + n7v1 [label="(n7v1) cross_join::<'static, 'tick>()", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) all_once()", shape=invhouse, fillcolor="#88aaff"] + n9v1 [label="(n9v1) for_each(|all| println!(\"{}: {:?}\", context.current_tick(), all))", shape=house, fillcolor="#ffff88"] + n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n11v1 [label="(n11v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n12v1 [label="(n12v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n4v1 -> n7v1 [label="0"] + n3v1 -> n4v1 + n1v1 -> n10v1 + n6v1 -> n7v1 [label="1"] + n5v1 -> n6v1 + n2v1 -> n11v1 + n8v1 -> n9v1 + n7v1 -> n12v1 + n10v1 -> n3v1 + n11v1 -> n5v1 + n12v1 -> n8v1 [color=red] + subgraph "cluster n1v1" { + fillcolor="#dddddd" + style=filled + label = "sg_1v1\nstratum 0" + n1v1 + subgraph "cluster_sg_1v1_var_users" { + label="var users" + n1v1 + } + } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 0" + n2v1 + subgraph "cluster_sg_2v1_var_messages" { + label="var messages" + n2v1 + } + } + subgraph "cluster n3v1" { + fillcolor="#dddddd" + style=filled + label = "sg_3v1\nstratum 0" + n3v1 + n4v1 + n5v1 + n6v1 + n7v1 + subgraph "cluster_sg_3v1_var_cp" { + label="var cp" + n7v1 + } + } + subgraph "cluster n4v1" { + fillcolor="#dddddd" + style=filled + label = "sg_4v1\nstratum 1" + n8v1 + n9v1 + } +} diff --git a/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_mermaid.snap new file mode 100644 index 000000000000..68f67faccaf8 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_loop__flo_nested@graphvis_mermaid.snap @@ -0,0 +1,59 @@ +--- +source: hydroflow/tests/surface_loop.rs +expression: "df.meta_graph().unwrap().to_mermaid(& Default :: default())" +--- +%%{init:{'theme':'base','themeVariables':{'clusterBkg':'#ddd','clusterBorder':'#888'}}}%% +flowchart TD +classDef pullClass fill:#8af,stroke:#000,text-align:left,white-space:pre +classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre +classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre +linkStyle default stroke:#aaa +1v1[\"(1v1) source_iter(["alice", "bob"])"/]:::pullClass +2v1[\"(2v1) source_stream(iter_batches_stream(0..12, 3))"/]:::pullClass +3v1[\"(3v1) batch()"/]:::pullClass +4v1[\"(4v1) flatten()"/]:::pullClass +5v1[\"(5v1) batch()"/]:::pullClass +6v1[\"(6v1) flatten()"/]:::pullClass +7v1[\"(7v1) cross_join::<'static, 'tick>()"/]:::pullClass +8v1[\"(8v1) all_once()"/]:::pullClass +9v1[/"(9v1) for_each(|all| println!("{}: {:?}", context.current_tick(), all))"\]:::pushClass +10v1["(10v1) handoff"]:::otherClass +11v1["(11v1) handoff"]:::otherClass +12v1["(12v1) handoff"]:::otherClass +4v1-->|0|7v1 +3v1-->4v1 +1v1-->10v1 +6v1-->|1|7v1 +5v1-->6v1 +2v1-->11v1 +8v1-->9v1 +7v1-->12v1 +10v1-->3v1 +11v1-->5v1 +12v1--x8v1; linkStyle 10 stroke:red +subgraph sg_1v1 ["sg_1v1 stratum 0"] + 1v1 + subgraph sg_1v1_var_users ["var users"] + 1v1 + end +end +subgraph sg_2v1 ["sg_2v1 stratum 0"] + 2v1 + subgraph sg_2v1_var_messages ["var messages"] + 2v1 + end +end +subgraph sg_3v1 ["sg_3v1 stratum 0"] + 3v1 + 4v1 + 5v1 + 6v1 + 7v1 + subgraph sg_3v1_var_cp ["var cp"] + 7v1 + end +end +subgraph sg_4v1 ["sg_4v1 stratum 1"] + 8v1 + 9v1 +end diff --git a/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_dot.snap new file mode 100644 index 000000000000..57f118a3fee3 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_dot.snap @@ -0,0 +1,63 @@ +--- +source: hydroflow/tests/surface_loop.rs +expression: "df.meta_graph().unwrap().to_dot(& Default :: default())" +--- +digraph { + node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; + edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; + n1v1 [label="(n1v1) source_iter([\"alice\", \"bob\"])", shape=invhouse, fillcolor="#88aaff"] + n2v1 [label="(n2v1) source_stream(iter_batches_stream(0..12, 3))", shape=invhouse, fillcolor="#88aaff"] + n3v1 [label="(n3v1) batch()", shape=invhouse, fillcolor="#88aaff"] + n4v1 [label="(n4v1) flatten()", shape=invhouse, fillcolor="#88aaff"] + n5v1 [label="(n5v1) batch()", shape=invhouse, fillcolor="#88aaff"] + n6v1 [label="(n6v1) flatten()", shape=invhouse, fillcolor="#88aaff"] + n7v1 [label="(n7v1) cross_join::<'static, 'tick>()", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) for_each(|(user, message)| {\l println!(\"{}: notify {} of {}\", context.current_tick(), user, message)\l})\l", shape=house, fillcolor="#ffff88"] + n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n4v1 -> n7v1 [label="0"] + n3v1 -> n4v1 + n1v1 -> n9v1 + n6v1 -> n7v1 [label="1"] + n5v1 -> n6v1 + n2v1 -> n10v1 + n7v1 -> n8v1 + n9v1 -> n3v1 + n10v1 -> n5v1 + subgraph "cluster n1v1" { + fillcolor="#dddddd" + style=filled + label = "sg_1v1\nstratum 0" + n1v1 + subgraph "cluster_sg_1v1_var_users" { + label="var users" + n1v1 + } + } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 0" + n2v1 + subgraph "cluster_sg_2v1_var_messages" { + label="var messages" + n2v1 + } + } + subgraph "cluster n3v1" { + fillcolor="#dddddd" + style=filled + label = "sg_3v1\nstratum 0" + n3v1 + n4v1 + n5v1 + n6v1 + n7v1 + n8v1 + subgraph "cluster_sg_3v1_var_cp" { + label="var cp" + n7v1 + n8v1 + } + } +} diff --git a/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_mermaid.snap new file mode 100644 index 000000000000..3fdd6bd94591 --- /dev/null +++ b/hydroflow/tests/snapshots/surface_loop__flo_syntax@graphvis_mermaid.snap @@ -0,0 +1,53 @@ +--- +source: hydroflow/tests/surface_loop.rs +expression: "df.meta_graph().unwrap().to_mermaid(& Default :: default())" +--- +%%{init:{'theme':'base','themeVariables':{'clusterBkg':'#ddd','clusterBorder':'#888'}}}%% +flowchart TD +classDef pullClass fill:#8af,stroke:#000,text-align:left,white-space:pre +classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre +classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre +linkStyle default stroke:#aaa +1v1[\"(1v1) source_iter(["alice", "bob"])"/]:::pullClass +2v1[\"(2v1) source_stream(iter_batches_stream(0..12, 3))"/]:::pullClass +3v1[\"(3v1) batch()"/]:::pullClass +4v1[\"(4v1) flatten()"/]:::pullClass +5v1[\"(5v1) batch()"/]:::pullClass +6v1[\"(6v1) flatten()"/]:::pullClass +7v1[\"(7v1) cross_join::<'static, 'tick>()"/]:::pullClass +8v1[/"
(8v1)
for_each(|(user, message)| {
println!("{}: notify {} of {}", context.current_tick(), user, message)
})
"\]:::pushClass +9v1["(9v1) handoff"]:::otherClass +10v1["(10v1) handoff"]:::otherClass +4v1-->|0|7v1 +3v1-->4v1 +1v1-->9v1 +6v1-->|1|7v1 +5v1-->6v1 +2v1-->10v1 +7v1-->8v1 +9v1-->3v1 +10v1-->5v1 +subgraph sg_1v1 ["sg_1v1 stratum 0"] + 1v1 + subgraph sg_1v1_var_users ["var users"] + 1v1 + end +end +subgraph sg_2v1 ["sg_2v1 stratum 0"] + 2v1 + subgraph sg_2v1_var_messages ["var messages"] + 2v1 + end +end +subgraph sg_3v1 ["sg_3v1 stratum 0"] + 3v1 + 4v1 + 5v1 + 6v1 + 7v1 + 8v1 + subgraph sg_3v1_var_cp ["var cp"] + 7v1 + 8v1 + end +end diff --git a/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_dot.snap index 5e416ed49975..62351287df30 100644 --- a/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_dot.snap +++ b/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_dot.snap @@ -1,6 +1,6 @@ --- source: hydroflow/tests/surface_scheduling.rs -expression: "df.meta_graph().unwrap().to_dot(&Default::default())" +expression: "df.meta_graph().unwrap().to_dot(& Default :: default())" --- digraph { node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; @@ -9,41 +9,43 @@ digraph { n2v1 [label="(n2v1) union()", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) tee()", shape=house, fillcolor="#ffff88"] n4v1 [label="(n4v1) map(|n| n + TickDuration::SINGLE_TICK)", shape=house, fillcolor="#ffff88"] - n5v1 [label="(n5v1) filter(|&n| n < TickInstant::new(10))", shape=invhouse, fillcolor="#88aaff"] + n5v1 [label="(n5v1) filter(|&n| n < TickInstant::new(10))", shape=house, fillcolor="#ffff88"] n6v1 [label="(n6v1) next_stratum()", shape=invhouse, fillcolor="#88aaff"] - n7v1 [label="(n7v1) for_each(|v| out_send.send(v).unwrap())", shape=house, fillcolor="#ffff88"] - n8v1 [label="(n8v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n7v1 [label="(n7v1) defer_tick()", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) for_each(|v| out_send.send(v).unwrap())", shape=house, fillcolor="#ffff88"] n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n3v1 - n6v1 -> n2v1 - n5v1 -> n8v1 - n4v1 -> n9v1 + n7v1 -> n2v1 + n6v1 -> n9v1 + n5v1 -> n10v1 + n4v1 -> n5v1 n3v1 -> n4v1 - n3v1 -> n7v1 - n8v1 -> n6v1 [color=red] - n9v1 -> n5v1 + n3v1 -> n8v1 + n9v1 -> n7v1 [color=red] + n10v1 -> n6v1 [color=red] subgraph "cluster n1v1" { fillcolor="#dddddd" style=filled label = "sg_1v1\nstratum 0" - n5v1 - } - subgraph "cluster n2v1" { - fillcolor="#dddddd" - style=filled - label = "sg_2v1\nstratum 1" n1v1 - n6v1 + n7v1 n2v1 n3v1 n4v1 - n7v1 - subgraph "cluster_sg_2v1_var_union_tee" { + n5v1 + n8v1 + subgraph "cluster_sg_1v1_var_union_tee" { label="var union_tee" n2v1 n3v1 } } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 1" + n6v1 + } } - diff --git a/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_mermaid.snap index b898992f1a1f..defafae56088 100644 --- a/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_scheduling__stratum_loop@graphvis_mermaid.snap @@ -1,6 +1,6 @@ --- source: hydroflow/tests/surface_scheduling.rs -expression: "df.meta_graph().unwrap().to_mermaid(&Default::default())" +expression: "df.meta_graph().unwrap().to_mermaid(& Default :: default())" --- %%{init:{'theme':'base','themeVariables':{'clusterBkg':'#ddd','clusterBorder':'#888'}}}%% flowchart TD @@ -12,33 +12,35 @@ linkStyle default stroke:#aaa 2v1[\"(2v1) union()"/]:::pullClass 3v1[/"(3v1) tee()"\]:::pushClass 4v1[/"(4v1) map(|n| n + TickDuration::SINGLE_TICK)"\]:::pushClass -5v1[\"(5v1) filter(|&n| n < TickInstant::new(10))"/]:::pullClass +5v1[/"(5v1) filter(|&n| n < TickInstant::new(10))"\]:::pushClass 6v1[\"(6v1) next_stratum()"/]:::pullClass -7v1[/"(7v1) for_each(|v| out_send.send(v).unwrap())"\]:::pushClass -8v1["(8v1) handoff"]:::otherClass +7v1[\"(7v1) defer_tick()"/]:::pullClass +8v1[/"(8v1) for_each(|v| out_send.send(v).unwrap())"\]:::pushClass 9v1["(9v1) handoff"]:::otherClass +10v1["(10v1) handoff"]:::otherClass 1v1-->2v1 2v1-->3v1 -6v1-->2v1 -5v1-->8v1 -4v1-->9v1 +7v1-->2v1 +6v1-->9v1 +5v1-->10v1 +4v1-->5v1 3v1-->4v1 -3v1-->7v1 -8v1--x6v1; linkStyle 7 stroke:red -9v1-->5v1 +3v1-->8v1 +9v1--o7v1; linkStyle 8 stroke:red +10v1--x6v1; linkStyle 9 stroke:red subgraph sg_1v1 ["sg_1v1 stratum 0"] - 5v1 -end -subgraph sg_2v1 ["sg_2v1 stratum 1"] 1v1 - 6v1 + 7v1 2v1 3v1 4v1 - 7v1 - subgraph sg_2v1_var_union_tee ["var union_tee"] + 5v1 + 8v1 + subgraph sg_1v1_var_union_tee ["var union_tee"] 2v1 3v1 end end - +subgraph sg_2v1 ["sg_2v1 stratum 1"] + 6v1 +end diff --git a/hydroflow/tests/snapshots/surface_singleton__fold_singleton@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_singleton__fold_singleton@graphvis_mermaid.snap index cfc332878447..3775b3febceb 100644 --- a/hydroflow/tests/snapshots/surface_singleton__fold_singleton@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_singleton__fold_singleton@graphvis_mermaid.snap @@ -53,4 +53,3 @@ subgraph sg_3v1 ["sg_3v1 stratum 1"] 3v1 end end - diff --git a/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_dot.snap b/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_dot.snap index 74d09d7f66a3..3a4356ee0bc7 100644 --- a/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_dot.snap +++ b/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_dot.snap @@ -61,4 +61,3 @@ digraph { } } } - diff --git a/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_mermaid.snap b/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_mermaid.snap index 54cd4484ba3c..3a8ee979cc01 100644 --- a/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_mermaid.snap +++ b/hydroflow/tests/snapshots/surface_singleton__multi_tick@graphvis_mermaid.snap @@ -53,4 +53,3 @@ subgraph sg_2v1 ["sg_2v1 stratum 0"] 3v1 end end - diff --git a/hydroflow/tests/surface_cross_singleton.rs b/hydroflow/tests/surface_cross_singleton.rs index 5dedaa432655..497670a28dcc 100644 --- a/hydroflow/tests/surface_cross_singleton.rs +++ b/hydroflow/tests/surface_cross_singleton.rs @@ -2,7 +2,7 @@ use hydroflow::util::collect_ready; use hydroflow::{assert_graphvis_snapshots, hydroflow_syntax}; use multiplatform_test::multiplatform_test; -#[multiplatform_test] +#[multiplatform_test(test, wasm, env_tracing)] pub fn test_basic() { let (single_tx, single_rx) = hydroflow::util::unbounded_channel::<()>(); let (egress_tx, mut egress_rx) = hydroflow::util::unbounded_channel(); @@ -26,3 +26,46 @@ pub fn test_basic() { let out: Vec<_> = collect_ready(&mut egress_rx); assert_eq!(out, vec![(1, ()), (2, ()), (3, ())]); } + +#[multiplatform_test(test, wasm, env_tracing)] +pub fn test_union_defer_tick() { + let (cross_tx, cross_rx) = hydroflow::util::unbounded_channel::(); + let (egress_tx, mut egress_rx) = hydroflow::util::unbounded_channel(); + + let mut df = hydroflow_syntax! { + teed_in = source_stream(cross_rx) -> sort() -> tee(); + teed_in -> [input]join; + + deferred_stream -> defer_tick_lazy() -> [0]unioned_stream; + + persisted_stream = source_iter([0]) -> persist::<'static>(); + persisted_stream -> [1]unioned_stream; + + unioned_stream = union(); + unioned_stream -> [single]join; + + join = cross_singleton() -> tee(); + + join -> for_each(|x| egress_tx.send(x).unwrap()); + + folded_thing = join -> fold(|| 0, |_, _| {}); + + teed_in -> [input]joined_folded; + folded_thing -> [single]joined_folded; + joined_folded = cross_singleton(); + deferred_stream = joined_folded -> fold(|| 0, |_, _| {}) -> flat_map(|_| []); + }; + assert_graphvis_snapshots!(df); + + df.run_available(); + let out: Vec<_> = collect_ready(&mut egress_rx); + assert_eq!(out, vec![]); + + cross_tx.send(1).unwrap(); + cross_tx.send(2).unwrap(); + cross_tx.send(3).unwrap(); + df.run_available(); + + let out: Vec<_> = collect_ready(&mut egress_rx); + assert_eq!(out, vec![(1, 0), (2, 0), (3, 0)]); +} diff --git a/hydroflow/tests/surface_lattice_bimorphism.rs b/hydroflow/tests/surface_lattice_bimorphism.rs index 401b0953018f..9909bc0832a5 100644 --- a/hydroflow/tests/surface_lattice_bimorphism.rs +++ b/hydroflow/tests/surface_lattice_bimorphism.rs @@ -2,9 +2,14 @@ use std::collections::{HashMap, HashSet}; use hydroflow::util::collect_ready; use hydroflow::{assert_graphvis_snapshots, hydroflow_syntax}; +use lattices::ght::lattice::{DeepJoinLatticeBimorphism, GhtBimorphism}; +use lattices::ght::GeneralizedHashTrieNode; use lattices::map_union::{KeyedBimorphism, MapUnionHashMap, MapUnionSingletonMap}; use lattices::set_union::{CartesianProductBimorphism, SetUnionHashSet, SetUnionSingletonSet}; +use lattices::GhtType; use multiplatform_test::multiplatform_test; +use variadics::variadic_collections::VariadicHashSet; +use variadics::CloneVariadic; #[multiplatform_test] pub fn test_cartesian_product() { @@ -22,7 +27,6 @@ pub fn test_cartesian_product() { rhs -> [1]my_join; my_join = lattice_bimorphism(CartesianProductBimorphism::>::default(), #lhs, #rhs) - -> lattice_reduce() -> for_each(|x| out_send.send(x).unwrap()); }; @@ -42,6 +46,33 @@ pub fn test_cartesian_product() { ); } +#[multiplatform_test(test, wasm, env_tracing)] +pub fn test_cartesian_product_1401() { + let (out_send, out_recv) = hydroflow::util::unbounded_channel::<_>(); + + let mut df = hydroflow_syntax! { + lhs = source_iter(0..1) + -> map(SetUnionSingletonSet::new_from) + -> state::<'static, SetUnionHashSet>(); + rhs = source_iter(1..2) + -> map(SetUnionSingletonSet::new_from) + -> state::<'static, SetUnionHashSet>(); + + lhs -> [0]my_join; + rhs -> [1]my_join; + + my_join = lattice_bimorphism(CartesianProductBimorphism::>::default(), #lhs, #rhs) + -> for_each(|x| out_send.send(x).unwrap()); + }; + assert_graphvis_snapshots!(df); + df.run_available(); + + assert_eq!( + &[SetUnionHashSet::new(HashSet::from_iter([(0, 1)]))], + &*collect_ready::, _>(out_recv) + ); +} + #[multiplatform_test] pub fn test_join() { let (out_send, out_recv) = hydroflow::util::unbounded_channel::<_>(); @@ -58,7 +89,6 @@ pub fn test_join() { rhs -> [1]my_join; my_join = lattice_bimorphism(KeyedBimorphism::, _>::new(CartesianProductBimorphism::>::default()), #lhs, #rhs) - -> lattice_reduce() -> for_each(|x| out_send.send(x).unwrap()); }; @@ -100,7 +130,6 @@ pub fn test_cartesian_product_tick_state() { rhs[items] -> [1]my_join; my_join = lattice_bimorphism(CartesianProductBimorphism::>::default(), #lhs, #rhs) - -> lattice_reduce() -> inspect(|x| println!("{:?}: {:?}", context.current_tick(), x)) -> for_each(|x| out_send.send(x).unwrap()); }; @@ -134,3 +163,47 @@ pub fn test_cartesian_product_tick_state() { &*collect_ready::, _>(&mut out_recv) ); } + +#[multiplatform_test] +fn test_ght_join_bimorphism() { + type MyGhtATrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSet); + type MyGhtBTrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSet); + + type JoinSchema = variadics::var_type!(u32, u64, u16, &'static str, &'static str); + + type MyNodeBim = <(MyGhtATrie, MyGhtBTrie) as DeepJoinLatticeBimorphism< + VariadicHashSet, + >>::DeepJoinLatticeBimorphism; + type MyBim = GhtBimorphism; + + let mut hf = hydroflow_syntax! { + lhs = source_iter([ + var_expr!(123, 2, 5, "hello"), + var_expr!(50, 1, 1, "hi"), + var_expr!(5, 1, 7, "hi"), + var_expr!(5, 1, 7, "bye"), + ]) + -> map(|row| MyGhtATrie::new_from([row])) + -> state::<'tick, MyGhtATrie>(); + rhs = source_iter([ + var_expr!(5, 1, 8, "hi"), + var_expr!(5, 1, 7, "world"), + var_expr!(5, 1, 7, "folks"), + var_expr!(10, 1, 2, "hi"), + var_expr!(12, 10, 98, "bye"), + ]) + -> map(|row| MyGhtBTrie::new_from([row])) + -> state::<'tick, MyGhtBTrie>(); + + lhs[items] -> [0]my_join; + rhs[items] -> [1]my_join; + + + my_join = lattice_bimorphism(MyBim::default(), #lhs, #rhs) + -> enumerate() + -> inspect(|x| println!("{:?} {:#?}", context.current_tick(), x)) + -> flat_map(|(_num, ght)| ght.recursive_iter().map(::clone_ref_var).collect::>()) + -> null(); + }; + hf.run_available(); +} diff --git a/hydroflow/tests/surface_lattice_generalized_hash_trie.rs b/hydroflow/tests/surface_lattice_generalized_hash_trie.rs new file mode 100644 index 000000000000..ece19b084ab9 --- /dev/null +++ b/hydroflow/tests/surface_lattice_generalized_hash_trie.rs @@ -0,0 +1,73 @@ +use hydroflow::hydroflow_syntax; +use hydroflow::lattices::ght::lattice::{DeepJoinLatticeBimorphism, GhtBimorphism}; +use hydroflow::lattices::ght::GeneralizedHashTrieNode; +use hydroflow::lattices::GhtType; +use hydroflow::util::collect_ready; +use hydroflow::variadics::{var_expr, var_type}; +use variadics::variadic_collections::VariadicHashSet; // Import the Insert trait + +#[test] +fn test_basic() { + type MyGht = GhtType!(u16, u32 => u64: VariadicHashSet); + type FlatTup = var_type!(u16, u32, u64); + let input: Vec = vec![ + var_expr!(42, 314, 43770), + var_expr!(42, 315, 43770), + var_expr!(42, 314, 30619), + var_expr!(43, 10, 600), + ]; + let mut merged = MyGht::default(); + for i in input.clone() { + merged.insert(i); + } + println!("merged: {:?}", merged); + let mut df = hydroflow_syntax! { + source_iter(input) + -> map(|t| MyGht::new_from(vec![t])) + -> lattice_fold::<'static>(MyGht::default) + -> inspect(|t| println!("{:?}", t)) + -> assert(|x: &MyGht| x.eq(&merged)) + -> null(); + }; + df.run_available(); +} + +#[test] +fn test_join() { + type MyGht = GhtType!(u8 => u16: VariadicHashSet); + type ResultGht = GhtType!(u8 => u16, u16: VariadicHashSet); + let (out_send, out_recv) = hydroflow::util::unbounded_channel::<_>(); + + let r = vec![ + var_expr!(1, 10), + var_expr!(2, 20), + var_expr!(3, 30), + var_expr!(4, 40), + ]; + let s = vec![var_expr!(1, 10), var_expr!(5, 50)]; + + type MyNodeBim = <(MyGht, MyGht) as DeepJoinLatticeBimorphism< + VariadicHashSet, + >>::DeepJoinLatticeBimorphism; + type MyBim = GhtBimorphism; + + let mut df = hydroflow_syntax! { + R = source_iter(r) + -> map(|t| MyGht::new_from([t])) + -> state::(); + S = source_iter(s) + -> map(|t| MyGht::new_from([t])) + -> state::(); + R[items] -> [0]my_join; + S[items] -> [1]my_join; + my_join = lattice_bimorphism(MyBim::default(), #R, #S) + -> lattice_reduce() + -> for_each(|x| out_send.send(x).unwrap()); + }; + df.run_available(); + + assert_eq!( + &[ResultGht::new_from(vec![var_expr!(1, 10, 10),])], + &*collect_ready::, _>(out_recv) + ); +} diff --git a/hydroflow/tests/surface_loop.rs b/hydroflow/tests/surface_loop.rs new file mode 100644 index 000000000000..ec026fd9d8a3 --- /dev/null +++ b/hydroflow/tests/surface_loop.rs @@ -0,0 +1,38 @@ +use hydroflow::util::iter_batches_stream; +use hydroflow::{assert_graphvis_snapshots, hydroflow_syntax}; +use multiplatform_test::multiplatform_test; + +#[multiplatform_test] +pub fn test_flo_syntax() { + let mut df = hydroflow_syntax! { + users = source_iter(["alice", "bob"]); + messages = source_stream(iter_batches_stream(0..12, 3)); + loop { + // TODO(mingwei): cross_join type negotion should allow us to eliminate `flatten()`. + users -> batch() -> flatten() -> [0]cp; + messages -> batch() -> flatten() -> [1]cp; + cp = cross_join::<'static, 'tick>() -> for_each(|(user, message)| println!("{}: notify {} of {}", context.current_tick(), user, message)); + } + }; + assert_graphvis_snapshots!(df); + df.run_available(); +} + +#[multiplatform_test] +pub fn test_flo_nested() { + let mut df = hydroflow_syntax! { + users = source_iter(["alice", "bob"]); + messages = source_stream(iter_batches_stream(0..12, 3)); + loop { + // TODO(mingwei): cross_join type negotion should allow us to eliminate `flatten()`. + users -> batch() -> flatten() -> [0]cp; + messages -> batch() -> flatten() -> [1]cp; + cp = cross_join::<'static, 'tick>(); + loop { + cp -> all_once() -> for_each(|all| println!("{}: {:?}", context.current_tick(), all)); + } + } + }; + assert_graphvis_snapshots!(df); + df.run_available(); +} diff --git a/hydroflow/tests/surface_parser.rs b/hydroflow/tests/surface_parser.rs index ca0fc2c6a557..ad7a137dfd50 100644 --- a/hydroflow/tests/surface_parser.rs +++ b/hydroflow/tests/surface_parser.rs @@ -236,3 +236,16 @@ pub fn test_parser_forwardref_self_middle() { self_ref = map(|a: usize| a) -> [0]self_ref[1] -> map(|b: usize| b); }; } + +#[multiplatform_test] +pub fn test_flo_syntax() { + hydroflow_parser! { + users = source_stream(0..); + messages = source_stream(0..); + loop { + users -> batch() -> flatten() -> [0]cp; + messages -> batch() -> flatten() -> [1]cp; + cp = cross_join() -> for_each(|(user, message)| println!("notify {} of {}", user, message)); + } + } +} diff --git a/hydroflow/tests/surface_scheduling.rs b/hydroflow/tests/surface_scheduling.rs index 1bff6147ba27..ef7a8f72dcf8 100644 --- a/hydroflow/tests/surface_scheduling.rs +++ b/hydroflow/tests/surface_scheduling.rs @@ -13,7 +13,7 @@ pub fn test_stratum_loop() { let mut df = hydroflow_syntax! { source_iter([TickInstant::new(0)]) -> union_tee; union_tee = union() -> tee(); - union_tee -> map(|n| n + TickDuration::SINGLE_TICK) -> filter(|&n| n < TickInstant::new(10)) -> next_stratum() -> union_tee; + union_tee -> map(|n| n + TickDuration::SINGLE_TICK) -> filter(|&n| n < TickInstant::new(10)) -> next_stratum() -> defer_tick() -> union_tee; union_tee -> for_each(|v| out_send.send(v).unwrap()); }; assert_graphvis_snapshots!(df); @@ -35,7 +35,7 @@ pub fn test_stratum_loop() { &*hydroflow::util::collect_ready::, _>(&mut out_recv) ); assert_eq!( - (TickInstant::new(11), 0), + (TickInstant::new(10), 0), (df.current_tick(), df.current_stratum()) ); } diff --git a/hydroflow/tests/surface_warnings.rs b/hydroflow/tests/surface_warnings.rs index ae71f41c5aee..fa9826083cd5 100644 --- a/hydroflow/tests/surface_warnings.rs +++ b/hydroflow/tests/surface_warnings.rs @@ -17,7 +17,7 @@ fn test_degenerate_union() { { source_iter([1, 2, 3]) -> union() -> for_each(|x| result_send.send(x).unwrap()); }, - "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:0:0", + "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:2:38", }; df.run_available(); @@ -30,7 +30,7 @@ fn test_empty_union() { { union() -> for_each(|x: usize| println!("{}", x)); }, - "Warning: `union` should have at least 2 input(s), actually has 0.\n --> $FILE:0:0", + "Warning: `union` should have at least 2 input(s), actually has 0.\n --> $FILE:2:12", }; df.run_available(); } @@ -43,7 +43,7 @@ fn test_degenerate_tee() { { source_iter([1, 2, 3]) -> tee() -> for_each(|x| result_send.send(x).unwrap()); }, - "Warning: `tee` should have at least 2 output(s), actually has 1.\n --> $FILE:0:0" + "Warning: `tee` should have at least 2 output(s), actually has 1.\n --> $FILE:2:38" }; df.run_available(); @@ -59,7 +59,7 @@ fn test_empty_tee() { { source_iter([1, 2, 3]) -> inspect(|&x| output_inner.borrow_mut().push(x)) -> tee(); }, - "Warning: `tee` should have at least 2 output(s), actually has 0.\n --> $FILE:0:0", + "Warning: `tee` should have at least 2 output(s), actually has 0.\n --> $FILE:2:89", }; df.run_available(); @@ -86,7 +86,7 @@ pub fn test_warped_diamond() { nodes -> [0]init; new_node[1] -> map(|n| (n, 'b')) -> [1]init; }, - "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:0:0", + "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:3:20", }; df.run_available(); } @@ -111,8 +111,8 @@ pub fn test_warped_diamond_2() { ntwk = source_iter([4, 5, 6]) -> tee(); }, - "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:0:0", - "Warning: `tee` should have at least 2 output(s), actually has 0.\n --> $FILE:0:0", + "Warning: `union` should have at least 2 input(s), actually has 1.\n --> $FILE:3:20", + "Warning: `tee` should have at least 2 output(s), actually has 0.\n --> $FILE:16:45", }; hf.run_available(); } diff --git a/hydroflow_datalog/CHANGELOG.md b/hydroflow_datalog/CHANGELOG.md index 2e9897912924..c8dd77928a2f 100644 --- a/hydroflow_datalog/CHANGELOG.md +++ b/hydroflow_datalog/CHANGELOG.md @@ -5,8 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.9.0 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -18,7 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 1 commit contributed to the release. + - 2 commits contributed to the release. + - 38 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -30,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.8.0 (2024-07-23) @@ -47,6 +77,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 59 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -76,6 +107,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 83 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -105,6 +137,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 32 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -135,6 +168,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 110 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -162,6 +196,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 56 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -191,6 +226,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 42 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -223,6 +259,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 33 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#780](https://github.com/hydro-project/hydroflow/issues/780), [#801](https://github.com/hydro-project/hydroflow/issues/801) @@ -253,6 +290,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 7 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -285,6 +323,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 2 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#677](https://github.com/hydro-project/hydroflow/issues/677), [#684](https://github.com/hydro-project/hydroflow/issues/684) @@ -315,6 +354,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 25 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#660](https://github.com/hydro-project/hydroflow/issues/660) diff --git a/hydroflow_datalog/Cargo.toml b/hydroflow_datalog/Cargo.toml index 93633dfe7d1f..58a62cab9d3b 100644 --- a/hydroflow_datalog/Cargo.toml +++ b/hydroflow_datalog/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow_datalog" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow_datalog/" @@ -25,4 +25,4 @@ proc-macro-crate = "1.0.0" # Note: If we ever compile this proc macro crate to WASM (e.g., if we are # building on a WASM host), we may need to turn diagnostics off for WASM if # proc_macro2 does not support WASM at that time. -hydroflow_datalog_core = { path = "../hydroflow_datalog_core", version = "^0.9.0" } +hydroflow_datalog_core = { path = "../hydroflow_datalog_core", version = "^0.10.0" } diff --git a/hydroflow_datalog_core/CHANGELOG.md b/hydroflow_datalog_core/CHANGELOG.md index 09fb9147413e..64d92a4d7c41 100644 --- a/hydroflow_datalog_core/CHANGELOG.md +++ b/hydroflow_datalog_core/CHANGELOG.md @@ -5,8 +5,48 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update rust-sitter + The latest Rust Sitter drops the dependency on `tree-sitter-cli`, which + eliminates many transitive dependencies. + - update pinned rust version, clippy lints, remove some dead code + +### Style + + - fixes for latest nightly clippy + +### Commit Statistics + + + + - 3 commits contributed to the release. + - 69 days passed between releases. + - 3 commits were understood as [conventional](https://www.conventionalcommits.org). + - 3 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1495](https://github.com/hydro-project/hydroflow/issues/1495), [#1537](https://github.com/hydro-project/hydroflow/issues/1537) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1495](https://github.com/hydro-project/hydroflow/issues/1495)** + - Update rust-sitter ([`4f6d400`](https://github.com/hydro-project/hydroflow/commit/4f6d400d0992594f8f12992fb6939378b12fadd6)) + * **[#1537](https://github.com/hydro-project/hydroflow/issues/1537)** + - Fixes for latest nightly clippy ([`8442d1b`](https://github.com/hydro-project/hydroflow/commit/8442d1b524621a9f8b43372a9c25991efb33c25e)) +
+ ## 0.9.0 (2024-08-30) + + + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -27,7 +67,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 4 commits contributed to the release. + - 5 commits contributed to the release. + - 38 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1417](https://github.com/hydro-project/hydroflow/issues/1417), [#1420](https://github.com/hydro-project/hydroflow/issues/1420), [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1432](https://github.com/hydro-project/hydroflow/issues/1432) @@ -45,6 +86,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) * **[#1432](https://github.com/hydro-project/hydroflow/issues/1432)** - Cleanup handling of span locations #1268, workaround fix #729 ([`9c352f5`](https://github.com/hydro-project/hydroflow/commit/9c352f50a5a8d1b2187b34d5847a23b7397fe6ec)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.8.0 (2024-07-23) @@ -118,6 +161,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 5 commits contributed to the release. + - 59 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1250](https://github.com/hydro-project/hydroflow/issues/1250), [#1295](https://github.com/hydro-project/hydroflow/issues/1295), [#1300](https://github.com/hydro-project/hydroflow/issues/1300), [#1332](https://github.com/hydro-project/hydroflow/issues/1332) @@ -139,15 +183,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Release hydroflow_lang v0.8.0, hydroflow_datalog_core v0.8.0, hydroflow_datalog v0.8.0, hydroflow_macro v0.8.0, lattices_macro v0.5.5, lattices v0.5.6, variadics v0.0.5, pusherator v0.0.7, hydroflow v0.8.0, hydroflow_plus v0.8.0, hydro_deploy v0.8.0, hydro_cli v0.8.0, hydroflow_plus_cli_integration v0.8.0, safety bump 7 crates ([`ca6c16b`](https://github.com/hydro-project/hydroflow/commit/ca6c16b4a7ce35e155fe7fc6c7d1676c37c9e4de)) - -Other 'tick state will need to be cleared, but existing implementation does that when the iterator runs, which is good enough. There is only a problem if a singleton can reference the state before the iterator runs, in that case.To emulate this unintuitive behavior, we currently ensure that apersist::<'static>() exists before operator that references thesingleton (filter, in this case). (Note that this is equivalent tocross_join::<'static>() and not cross_join::<'tick>())However singletons also have had a different mechanism that affectsthis- currently singleton references create a next-stratum constraint,that ensures a singleton referencer must be in a later stratum than thesingleton it is referencing.Note that this actually prevents the example situation above fromhappening– the updates to y will be received all at once at the startof the next stratum.This means that actually, currently singletons are equivalent tosomething like:ruststream -> cj[0]; -y -> next_stratum() -> last() -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -last() is a hypothetical operator that only keeps the most recent itemoutput by y. next_stratum() -> last() is equivalent to reduce(|acc, item| *acc = item) (since that comes with a stratum barrier). Sotechnically this is a slightly different behavior than just cross_join,but it is more intuitive.ruststream -> cj[0]; -y -> reduce(|acc, item| { *acc = item; }) -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -Also fixes #1293 - ## 0.7.0 (2024-05-24) @@ -179,6 +214,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 48 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 5 unique issues were worked on: [#1160](https://github.com/hydro-project/hydroflow/issues/1160), [#1166](https://github.com/hydro-project/hydroflow/issues/1166), [#1168](https://github.com/hydro-project/hydroflow/issues/1168), [#1176](https://github.com/hydro-project/hydroflow/issues/1176), [#1192](https://github.com/hydro-project/hydroflow/issues/1192) @@ -241,6 +277,7 @@ Also fixes #1293 - 9 commits contributed to the release. + - 34 days passed between releases. - 8 commits were understood as [conventional](https://www.conventionalcommits.org). - 7 unique issues were worked on: [#1086](https://github.com/hydro-project/hydroflow/issues/1086), [#1091](https://github.com/hydro-project/hydroflow/issues/1091), [#1094](https://github.com/hydro-project/hydroflow/issues/1094), [#1132](https://github.com/hydro-project/hydroflow/issues/1132), [#1135](https://github.com/hydro-project/hydroflow/issues/1135), [#1136](https://github.com/hydro-project/hydroflow/issues/1136), [#1137](https://github.com/hydro-project/hydroflow/issues/1137) @@ -282,6 +319,7 @@ Also fixes #1293 - 2 commits contributed to the release. + - 28 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -315,6 +353,7 @@ Also fixes #1293 - 3 commits contributed to the release. + - 4 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1041](https://github.com/hydro-project/hydroflow/issues/1041) @@ -364,6 +403,7 @@ Also fixes #1293 - 7 commits contributed to the release. + - 110 days passed between releases. - 6 commits were understood as [conventional](https://www.conventionalcommits.org). - 5 unique issues were worked on: [#1016](https://github.com/hydro-project/hydroflow/issues/1016), [#1023](https://github.com/hydro-project/hydroflow/issues/1023), [#1033](https://github.com/hydro-project/hydroflow/issues/1033), [#945](https://github.com/hydro-project/hydroflow/issues/945), [#989](https://github.com/hydro-project/hydroflow/issues/989) @@ -420,6 +460,7 @@ Also fixes #1293 - 11 commits contributed to the release. + - 56 days passed between releases. - 10 commits were understood as [conventional](https://www.conventionalcommits.org). - 7 unique issues were worked on: [#882](https://github.com/hydro-project/hydroflow/issues/882), [#893](https://github.com/hydro-project/hydroflow/issues/893), [#896](https://github.com/hydro-project/hydroflow/issues/896), [#898](https://github.com/hydro-project/hydroflow/issues/898), [#906](https://github.com/hydro-project/hydroflow/issues/906), [#924](https://github.com/hydro-project/hydroflow/issues/924), [#926](https://github.com/hydro-project/hydroflow/issues/926) @@ -487,6 +528,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 42 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#833](https://github.com/hydro-project/hydroflow/issues/833), [#845](https://github.com/hydro-project/hydroflow/issues/845), [#870](https://github.com/hydro-project/hydroflow/issues/870), [#872](https://github.com/hydro-project/hydroflow/issues/872) @@ -527,6 +569,7 @@ Also fixes #1293 - 3 commits contributed to the release. + - 33 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#780](https://github.com/hydro-project/hydroflow/issues/780), [#801](https://github.com/hydro-project/hydroflow/issues/801) @@ -557,6 +600,7 @@ Also fixes #1293 - 2 commits contributed to the release. + - 1 day passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -602,6 +646,7 @@ Also fixes #1293 - 5 commits contributed to the release. + - 6 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#697](https://github.com/hydro-project/hydroflow/issues/697), [#702](https://github.com/hydro-project/hydroflow/issues/702), [#714](https://github.com/hydro-project/hydroflow/issues/714), [#716](https://github.com/hydro-project/hydroflow/issues/716) @@ -642,6 +687,7 @@ Also fixes #1293 - 4 commits contributed to the release. + - 2 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#673](https://github.com/hydro-project/hydroflow/issues/673), [#677](https://github.com/hydro-project/hydroflow/issues/677), [#684](https://github.com/hydro-project/hydroflow/issues/684) @@ -678,6 +724,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 25 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#639](https://github.com/hydro-project/hydroflow/issues/639), [#642](https://github.com/hydro-project/hydroflow/issues/642), [#660](https://github.com/hydro-project/hydroflow/issues/660) diff --git a/hydroflow_datalog_core/Cargo.toml b/hydroflow_datalog_core/Cargo.toml index c2ee69bf0eac..79b541b1bf30 100644 --- a/hydroflow_datalog_core/Cargo.toml +++ b/hydroflow_datalog_core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow_datalog_core" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow_datalog_core/" @@ -22,11 +22,11 @@ quote = "1.0.35" slotmap = "1.0.0" syn = { version = "2.0.46", features = [ "parsing", "extra-traits" ] } proc-macro2 = "1.0.74" -rust-sitter = "0.4.2" -hydroflow_lang = { path = "../hydroflow_lang", version = "^0.9.0" } +rust-sitter = "0.4.3" +hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0" } [build-dependencies] -rust-sitter-tool = "0.4.2" +rust-sitter-tool = "0.4.3" [dev-dependencies] insta = "1.39" diff --git a/hydroflow_datalog_core/src/grammar.rs b/hydroflow_datalog_core/src/grammar.rs index fe9f95360f42..10345e0c38ac 100644 --- a/hydroflow_datalog_core/src/grammar.rs +++ b/hydroflow_datalog_core/src/grammar.rs @@ -136,7 +136,11 @@ pub mod datalog { } #[derive(Debug, Clone)] - #[expect(clippy::manual_non_exhaustive, reason = "`()` used for leaf")] + #[allow( + clippy::allow_attributes, + clippy::manual_non_exhaustive, + reason = "`()` used for leaf" + )] pub struct AtNode { #[rust_sitter::leaf(text = "@")] _at: (), diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_and_comments@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_and_comments@datalog_program.snap index ecb90385183f..7cae1cac97e2 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_and_comments@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_and_comments@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () . 1 , g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + val . 0) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Operator\":\"identity ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":24,\"version\":1}],\"version\":5},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":7,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":2,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":false,\"version\":1}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () . 1 , g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + val . 0) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Operator\":\"identity ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":24,\"version\":1}],\"version\":5},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":7,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":2,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":false,\"version\":1}]}", ); df.__assign_diagnostics("[]"); let (hoff_1v3_send, hoff_1v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_fold_keyed_expr@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_fold_keyed_expr@datalog_program.snap index 2571aa97ad2e..244fe6fcb3b6 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_fold_keyed_expr@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__aggregations_fold_keyed_expr@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 % 2 ,) , (row . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + val . 0) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 , a . 0 . unwrap () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 % 2 ,) , (row . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + val . 0) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 , a . 0 . unwrap () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__anti_join@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__anti_join@datalog_program.snap index 7846d1ef1f36..5c182bc0857a 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__anti_join@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__anti_join@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints_1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints_2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints_3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"anti_join ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (_ , _ ,)) | (kv . 0 . 0 , kv . 1 . 0 , kv . 1 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ , _ ,) | ((_v . 0 ,) , (_v . 1 , _v . 2 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (_v . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 1 , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":5},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints_1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints_2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints_3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"anti_join ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (_ , _ ,)) | (kv . 0 . 0 , kv . 1 . 0 , kv . 1 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ , _ ,) | ((_v . 0 ,) , (_v . 1 , _v . 2 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (_v . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 1 , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":5},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__collect_vec@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__collect_vec@datalog_program.snap index 872c2f668cec..90dae240e971 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__collect_vec@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__collect_vec@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , ((row . 0 , row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev ; set . insert (val . 0) ; set }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; set }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . into_iter () . collect :: < Vec < _ > > () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , ((row . 0 , row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev ; set . insert (val . 0) ; set }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; set }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . into_iter () . collect :: < Vec < _ > > () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_9v3_send, hoff_9v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple@datalog_program.snap index 1e92fc65bce3..a7191e5f2d54 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple_then_flat@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple_then_flat@datalog_program.snap index 2cbc8a5f4d24..6689588a52fa 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple_then_flat@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__detuple_then_flat@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 0 . into_iter () . map (move | __flattened_element | (__flattened_element , :: std :: clone :: Clone :: clone (& row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 1 . into_iter () . map (move | __flattened_element | (:: std :: clone :: Clone :: clone (& row . 0) , __flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 0 . into_iter () . map (move | __flattened_element | (__flattened_element , :: std :: clone :: Clone :: clone (& row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 1 . into_iter () . map (move | __flattened_element | (:: std :: clone :: Clone :: clone (& row . 0) , __flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_lhs@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_lhs@datalog_program.snap index c4206cfd331f..cb69eb657cf6 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_lhs@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_lhs@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 + 123 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 . clone () + row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 - row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 % (row . 0 + 5) ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 * 5 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"2\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"3\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"4\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"4\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"5\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"5\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 + 123 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 . clone () + row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 - row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((123 % (row . 0 + 5) ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 * 5 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"2\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"3\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"4\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"4\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"5\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"5\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_1v3_send, hoff_1v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_predicate@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_predicate@datalog_program.snap index 8dff199f6780..88dec76ae23f 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_predicate@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__expr_predicate@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 == 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 != 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 - 1 == 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((3 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 - 1 == 1 - 1)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((4 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"2\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"3\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_1_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_3_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_5_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_7_filter\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 == 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 != 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 - 1 == 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((3 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ ,) | row . 0 - 1 == 1 - 1)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((4 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"2\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"3\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_1_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_3_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_5_filter\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_7_filter\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_1v3_send, hoff_1v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flat_then_detuple@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flat_then_detuple@datalog_program.snap index 3a14f2488ed8..e4af75fc146c 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flat_then_detuple@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flat_then_detuple@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ ,) | row . 0 . into_iter () . map (move | __flattened_element | (__flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ ,) | row . 0 . into_iter () . map (move | __flattened_element | (__flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flatten@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flatten@datalog_program.snap index dbb1c6a05089..9ca19090821f 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flatten@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__flatten@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 1 . into_iter () . map (move | __flattened_element | (:: std :: clone :: Clone :: clone (& row . 0) , __flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"flat_map (| row : (_ , _ ,) | row . 1 . into_iter () . map (move | __flattened_element | (:: std :: clone :: Clone :: clone (& row . 0) , __flattened_element ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__index@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__index@datalog_program.snap index efa067605866..4fba2d1f01a3 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__index@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__index@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result3 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result4 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result5 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 ,) , ((row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ ,) , _)) | (g . 0 , a . 0 . unwrap () . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 ,) , ((row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'static , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ ,) , _)) | (g . 0 , a . 0 . unwrap () . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":35,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":25,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":39,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":45,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":49,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":52,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":15,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":29,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":31,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":34,\"version\":1},{\"idx\":35,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1},{\"idx\":34,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":33,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":38,\"version\":1},{\"idx\":39,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":37,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":36,\"version\":1},{\"idx\":21,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":36,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":3},{\"idx\":37,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":40,\"version\":1},{\"idx\":16,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":3},{\"idx\":51,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":44,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":42,\"version\":1},{\"idx\":43,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":42,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":3},{\"idx\":47,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":48,\"version\":1},{\"idx\":49,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":46,\"version\":1},{\"idx\":13,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":46,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":3},{\"idx\":41,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":50,\"version\":1},{\"idx\":10,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":25,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":33,\"version\":1},{\"idx\":34,\"version\":1},{\"idx\":35,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":36,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":37,\"version\":1},{\"idx\":38,\"version\":1},{\"idx\":39,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":42,\"version\":1},{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1},{\"idx\":45,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":29,\"version\":1},{\"idx\":46,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1},{\"idx\":49,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result4_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result5_insert\",\"version\":1},{\"value\":\"result5\",\"version\":1},{\"value\":\"result5\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_persisted_insert\",\"version\":1},{\"value\":\"ints_persisted\",\"version\":1},{\"value\":\"ints_persisted\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result3 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result4 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result5 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 ,) , ((row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ ,) , _)) | (g . 0 , a . 0 . unwrap () . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 ,) , ((row . 1) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'static , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ ,) , _)) | (g . 0 , a . 0 . unwrap () . 1 , __enumerate_index ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"enumerate :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (__enumerate_index , (g , a)) : (_ , ((_ , _ ,) , _)) | (g . 0 , g . 1 , __enumerate_index ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":35,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":25,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":39,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":23,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":45,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":49,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":3},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":52,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":15,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":29,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":31,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":34,\"version\":1},{\"idx\":35,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1},{\"idx\":34,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":33,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":38,\"version\":1},{\"idx\":39,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":37,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":36,\"version\":1},{\"idx\":21,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":36,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":3},{\"idx\":37,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":40,\"version\":1},{\"idx\":16,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":3},{\"idx\":51,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":44,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":42,\"version\":1},{\"idx\":43,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":42,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":3},{\"idx\":47,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":48,\"version\":1},{\"idx\":49,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":46,\"version\":1},{\"idx\":13,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":46,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":3},{\"idx\":41,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":50,\"version\":1},{\"idx\":10,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":25,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":33,\"version\":1},{\"idx\":34,\"version\":1},{\"idx\":35,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":36,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":37,\"version\":1},{\"idx\":38,\"version\":1},{\"idx\":39,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":42,\"version\":1},{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1},{\"idx\":45,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":29,\"version\":1},{\"idx\":46,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1},{\"idx\":49,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":\"ints\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result4_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result5_insert\",\"version\":1},{\"value\":\"result5\",\"version\":1},{\"value\":\"result5\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_persisted_insert\",\"version\":1},{\"value\":\"ints_persisted\",\"version\":1},{\"value\":\"ints_persisted\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_other@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_other@datalog_program.snap index 3a750740ca36..99a2e6d0dd0b 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_other@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_other@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ , _ ,) , (() , ())) | (kv . 0 . 0 , kv . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 , _v . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 , _v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ , _ ,) , (() , ())) | (kv . 0 . 0 , kv . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 , _v . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 , _v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_10v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_self@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_self@datalog_program.snap index 0b5cd7f8294d..cb8e9d725099 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_self@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__join_with_self@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ , _ ,) , (() , ())) | (kv . 0 . 0 , kv . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 , _v . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 , _v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":\"input\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ , _ ,) , (() , ())) | (kv . 0 . 0 , kv . 0 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 , _v . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 , _v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":\"input\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_4v3_send, hoff_4v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program-2.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program-2.snap index f9e805b2d63d..1bf96f5b575f 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program-2.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program-2.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ , _ , _ ,) | row . 0 == row . 1 && row . 2 == row . 3)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 0 . clone () , row . 0 , row . 2 . clone () , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ , _ , _ ,) | row . 0 == row . 1 && row . 2 == row . 3)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 0 . clone () , row . 0 , row . 2 . clone () , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program.snap index 07759fdcbc84..c6c17b45f5db 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__local_constraints@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ ,) | row . 0 == row . 1)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 . clone () , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ ,) | row . 0 == row . 1)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 . clone () , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max@datalog_program.snap index c3e12b920a4b..7db7f024c77a 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (std :: cmp :: max (prev , val . 0)) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , (row . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , (_ ,) , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (std :: cmp :: max (prev , val . 0)) } else { Some (val . 0) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (a . 0 . unwrap () , g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max_all@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max_all@datalog_program.snap index 319c1fba5170..a0bfbfe795ce 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max_all@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__max_all@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , (row . 0 , row . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > , Option < _ > ,) > (| | (None , None ,) , | old : & mut (Option < _ > , Option < _ > ,) , val : (_ , _ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (std :: cmp :: max (prev , val . 0)) } else { Some (val . 0) } ; old . 1 = if let Some (prev) = old . 1 . take () { Some (std :: cmp :: max (prev , val . 1)) } else { Some (val . 1) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () , a . 1 . unwrap () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , (row . 0 , row . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > , Option < _ > ,) > (| | (None , None ,) , | old : & mut (Option < _ > , Option < _ > ,) , val : (_ , _ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (std :: cmp :: max (prev , val . 0)) } else { Some (val . 0) } ; old . 1 = if let Some (prev) = old . 1 . take () { Some (std :: cmp :: max (prev , val . 1)) } else { Some (val . 1) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () , a . 1 . unwrap () ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__minimal_program@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__minimal_program@datalog_program.snap index 0e148142fd48..7693f926774f 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__minimal_program@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__minimal_program@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multi_detuple@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multi_detuple@datalog_program.snap index 13d8c8d8c3b6..21e2d593d126 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multi_detuple@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multi_detuple@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ , _ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 , row_untuple . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ , _ , _ ,) | (row_untuple . 0 , row_untuple . 1 , row_untuple . 2 . 0 , row_untuple . 2 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 0 , row . 1 , row . 2 , row . 3 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ , _ ,) | (row_untuple . 0 . 0 , row_untuple . 0 . 1 , row_untuple . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row_untuple : (_ , _ , _ ,) | (row_untuple . 0 , row_untuple . 1 , row_untuple . 2 . 0 , row_untuple . 2 . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 0 , row . 1 , row . 2 , row . 3 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"source_reader_0\",\"version\":1},{\"value\":\"source_reader_0\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multiple_contributors@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multiple_contributors@datalog_program.snap index a60f67142010..30706f984277 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multiple_contributors@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__multiple_contributors@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":\"out_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":\"out_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_10v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__non_copy_but_clone@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__non_copy_but_clone@datalog_program.snap index 83bdd91fba52..b3c4c5b04bc7 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__non_copy_but_clone@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__non_copy_but_clone@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (strings)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 . clone () , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"strings_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (strings)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 . clone () , row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"strings_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist@datalog_program.snap index 2f0da258c6ff..c1a1a5851b0f 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result3 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result4 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'static , 'static , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'static , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ , _ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 0 . 1 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | (() , (_v . 0 , _v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 0 , row . 1 , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"anti_join ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ()) | (kv . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (_v . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":34,\"version\":1},{\"idx\":14,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":28,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":25,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":35,\"version\":1},{\"idx\":11,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":22,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":19,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":36,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":13,\"version\":3},{\"idx\":33,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":50,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":3},{\"idx\":31,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":58,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":19,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":63,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":22,\"version\":3},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":68,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":61,\"version\":1},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":28,\"version\":3},{\"idx\":3,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":65,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":30,\"version\":1},{\"idx\":31,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1},{\"idx\":16,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":32,\"version\":1},{\"idx\":13,\"version\":3}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":3},{\"idx\":7,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":37,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":39,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":42,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":43,\"version\":1},{\"idx\":41,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":29,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":44,\"version\":1},{\"idx\":41,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":26,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":45,\"version\":1},{\"idx\":46,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":42,\"version\":1},{\"idx\":47,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":48,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":48,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":3},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":49,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":46,\"version\":1},{\"idx\":49,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":54,\"version\":1},{\"idx\":51,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":53,\"version\":1},{\"idx\":54,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":23,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":56,\"version\":1},{\"idx\":20,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":55,\"version\":1},{\"idx\":56,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":55,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":3},{\"idx\":65,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":57,\"version\":1},{\"idx\":58,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":52,\"version\":1},{\"idx\":57,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":3},{\"idx\":44,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":60,\"version\":1},{\"idx\":61,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":59,\"version\":1},{\"idx\":60,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":59,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":3},{\"idx\":51,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":62,\"version\":1},{\"idx\":63,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":27,\"version\":1},{\"idx\":62,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":29,\"version\":3},{\"idx\":43,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":64,\"version\":1},{\"idx\":17,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":64,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":3},{\"idx\":53,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":67,\"version\":1},{\"idx\":68,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":66,\"version\":1},{\"idx\":67,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":32,\"version\":1},{\"idx\":66,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":9,\"version\":1},\"version\":1},{\"value\":{\"idx\":10,\"version\":1},\"version\":1},{\"value\":{\"idx\":11,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1},{\"idx\":41,\"version\":1},{\"idx\":42,\"version\":1},{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1},{\"idx\":45,\"version\":1},{\"idx\":46,\"version\":1},{\"idx\":49,\"version\":1},{\"idx\":50,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":37,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":53,\"version\":1},{\"idx\":54,\"version\":1},{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1},{\"idx\":57,\"version\":1},{\"idx\":58,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":59,\"version\":1},{\"idx\":60,\"version\":1},{\"idx\":61,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":62,\"version\":1},{\"idx\":63,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":39,\"version\":1},{\"idx\":64,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":65,\"version\":1},{\"idx\":30,\"version\":1},{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1},{\"idx\":66,\"version\":1},{\"idx\":67,\"version\":1},{\"idx\":68,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":55,\"version\":1},{\"idx\":56,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":34,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":35,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":36,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result4_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"intermediate_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"intermediate_persist_insert\",\"version\":1},{\"value\":\"intermediate_persist\",\"version\":1},{\"value\":\"intermediate_persist\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_7\",\"version\":1},{\"value\":\"join_7\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result3 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result4 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'static , 'static , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'static , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : (() , ((_ , _ ,) , (_ ,))) | (kv . 1 . 0 . 0 , kv . 1 . 0 . 1 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | (() , (_v . 0 , _v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (() , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 0 , row . 1 , row . 2 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"anti_join ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ()) | (kv . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | (_v . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"persist :: < 'static > ()\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":34,\"version\":1},{\"idx\":14,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":28,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":25,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":35,\"version\":1},{\"idx\":11,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":22,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":19,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":36,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":13,\"version\":3},{\"idx\":33,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":50,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":3},{\"idx\":31,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":58,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":19,\"version\":3},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":63,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":22,\"version\":3},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":68,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":61,\"version\":1},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":28,\"version\":3},{\"idx\":3,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":65,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":30,\"version\":1},{\"idx\":31,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1},{\"idx\":16,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":32,\"version\":1},{\"idx\":13,\"version\":3}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":3},{\"idx\":7,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":37,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":39,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":41,\"version\":1},{\"idx\":42,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":43,\"version\":1},{\"idx\":41,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":29,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":44,\"version\":1},{\"idx\":41,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":26,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":45,\"version\":1},{\"idx\":46,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":47,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":42,\"version\":1},{\"idx\":47,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":48,\"version\":1},{\"idx\":45,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":48,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":14,\"version\":3},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":49,\"version\":1},{\"idx\":50,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":46,\"version\":1},{\"idx\":49,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":54,\"version\":1},{\"idx\":51,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":53,\"version\":1},{\"idx\":54,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":23,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":56,\"version\":1},{\"idx\":20,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":55,\"version\":1},{\"idx\":56,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":55,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":3},{\"idx\":65,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":57,\"version\":1},{\"idx\":58,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":52,\"version\":1},{\"idx\":57,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":3},{\"idx\":44,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":60,\"version\":1},{\"idx\":61,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":59,\"version\":1},{\"idx\":60,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":59,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":20,\"version\":3},{\"idx\":51,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":62,\"version\":1},{\"idx\":63,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":27,\"version\":1},{\"idx\":62,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":29,\"version\":3},{\"idx\":43,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":64,\"version\":1},{\"idx\":17,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":64,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":3},{\"idx\":53,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":67,\"version\":1},{\"idx\":68,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":66,\"version\":1},{\"idx\":67,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":32,\"version\":1},{\"idx\":66,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"2\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"3\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":9,\"version\":1},\"version\":1},{\"value\":{\"idx\":10,\"version\":1},\"version\":1},{\"value\":{\"idx\":11,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":8,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1},{\"value\":{\"idx\":7,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":33,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":43,\"version\":1},{\"idx\":44,\"version\":1},{\"idx\":41,\"version\":1},{\"idx\":42,\"version\":1},{\"idx\":47,\"version\":1},{\"idx\":48,\"version\":1},{\"idx\":45,\"version\":1},{\"idx\":46,\"version\":1},{\"idx\":49,\"version\":1},{\"idx\":50,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":37,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":53,\"version\":1},{\"idx\":54,\"version\":1},{\"idx\":51,\"version\":1},{\"idx\":52,\"version\":1},{\"idx\":57,\"version\":1},{\"idx\":58,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":38,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":59,\"version\":1},{\"idx\":60,\"version\":1},{\"idx\":61,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":62,\"version\":1},{\"idx\":63,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":39,\"version\":1},{\"idx\":64,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":65,\"version\":1},{\"idx\":30,\"version\":1},{\"idx\":31,\"version\":1},{\"idx\":32,\"version\":1},{\"idx\":66,\"version\":1},{\"idx\":67,\"version\":1},{\"idx\":68,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":40,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":55,\"version\":1},{\"idx\":56,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":34,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":35,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":36,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result4_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"intermediate_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"intermediate_persist_insert\",\"version\":1},{\"value\":\"intermediate_persist\",\"version\":1},{\"value\":\"intermediate_persist\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_7\",\"version\":1},{\"value\":\"join_7\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist_uniqueness@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist_uniqueness@datalog_program.snap index ed9e278356b7..6ded593c5ed3 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist_uniqueness@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__persist_uniqueness@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | (() , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'static , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":8,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":8,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":3},{\"idx\":3,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":7,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"difference :: < 'tick , 'static > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"defer_tick ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | (() , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'static , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":11,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":8,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":5},{\"value\":[{\"idx\":8,\"version\":3},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":3},{\"idx\":3,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":7,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Path\":\"pos\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":5},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Path\":\"neg\"}],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":5,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":2,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__send_to_node@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__send_to_node@datalog_program.snap index ae7b3312a109..d8e50a5296d1 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__send_to_node@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__send_to_node@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| (node , data) | async_send_result (node , data))\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (async_receive_result)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| v : (_ , _ ,) | (v . 1 , (v . 0 ,)))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_async_send\",\"version\":1},{\"value\":\"result_async_send\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (ints)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| (node , data) | async_send_result (node , data))\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (async_receive_result)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| v : (_ , _ ,) | (v . 1 , (v . 0 ,)))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result_async_send\",\"version\":1},{\"value\":\"result_async_send\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_12v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__simple_filter@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__simple_filter@datalog_program.snap index 7be3dad3e838..70f57da4ff37 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__simple_filter@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__simple_filter@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ ,) | row . 0 > row . 1 && row . 1 == row . 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_1_filter\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"filter (| row : & (_ , _ ,) | row . 0 > row . 1 && row . 1 == row . 0)\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 0 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ ,) , _) | (g . 0 , g . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"predicate_1_filter\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_7v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__single_column_program@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__single_column_program@datalog_program.snap index fbbddeb2e483..ded1b15e735e 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__single_column_program@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__single_column_program@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (() , ())) | (kv . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (() , ())) | (kv . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_10v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__transitive_closure@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__transitive_closure@datalog_program.snap index ff630c42e379..53702adc0a27 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__transitive_closure@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__transitive_closure@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (edges)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (seed_reachable)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | reachable . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (() , (_ ,))) | (kv . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"edges_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"seed_reachable_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"reachable_insert\",\"version\":1},{\"value\":\"reachable_insert\",\"version\":1},{\"value\":\"reachable\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_3\",\"version\":1},{\"value\":\"join_3\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"union ()\"},\"version\":1},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (edges)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (seed_reachable)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | reachable . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , (() , (_ ,))) | (kv . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | ((row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":17,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":7,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":16,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":16,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":7,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":12,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"edges_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"seed_reachable_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"reachable_insert\",\"version\":1},{\"value\":\"reachable_insert\",\"version\":1},{\"value\":\"reachable\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_3\",\"version\":1},{\"value\":\"join_3\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_6v3_send, hoff_6v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__triple_relation_join@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__triple_relation_join@datalog_program.snap index 969ec389b954..4257e5e0d620 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__triple_relation_join@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__triple_relation_join@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ , _ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 0 . 1 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ , _ ,) | ((_v . 2 ,) , (_v . 1 , _v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 3 , row . 0 , row . 2 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"source_stream (in1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in2)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (in3)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ , _ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 0 . 1 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ , _ ,) | ((_v . 2 ,) , (_v . 1 , _v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ , _ ,) | ((row . 3 , row . 0 , row . 2 , row . 1 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ , _ , _ , _ ,) , _) | (g . 0 , g . 1 , g . 2 , g . 3 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":15,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":21,\"version\":1},{\"idx\":22,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":26,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in1_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"in3_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_4\",\"version\":1},{\"value\":\"join_4\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let mut sg_1v1_node_13v1_stream = { diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_fields@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_fields@datalog_program.snap index 277d0b9c27e3..7b2cbee6fe7c 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_fields@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_fields@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":\"input\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":2},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (input)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | out . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , (_ ,))) | (kv . 0 . 0 , kv . 1 . 0 . 0 , kv . 1 . 1 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 1 ,) , (_v . 0 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ , _ ,) | ((row . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : ((_ ,) , _) | (g . 0 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":6,\"version\":3},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":null,\"version\":2},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":6,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":12,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":7,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":12,\"version\":1},{\"idx\":9,\"version\":1},{\"idx\":10,\"version\":1},{\"idx\":13,\"version\":1},{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"input_insert\",\"version\":1},{\"value\":\"input\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"out_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_4v3_send, hoff_4v3_recv) = df diff --git a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_join_count@datalog_program.snap b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_join_count@datalog_program.snap index 61ba10cfba10..505939142a53 100644 --- a/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_join_count@datalog_program.snap +++ b/hydroflow_datalog_core/src/snapshots/hydroflow_datalog_core__tests__wildcard_join_count@datalog_program.snap @@ -9,7 +9,7 @@ fn main() { use hydroflow::{var_expr, var_args}; let mut df = hydroflow::scheduled::graph::Hydroflow::new(); df.__assign_meta_graph( - "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , ())) | (kv . 0 . 0 , kv . 1 . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , (() ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + 1) } else { Some (1) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () ,))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , ())) | (kv . 0 . 0 , kv . 1 . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":6,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":30,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":29,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":7,\"version\":3},{\"idx\":26,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":10,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":7,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":27,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":3},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":29,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":28,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":6,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":29,\"version\":1},{\"idx\":30,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_5\",\"version\":1},{\"value\":\"join_5\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", + "{\"nodes\":[{\"value\":null,\"version\":0},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Operator\":\"tee ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"unique :: < 'tick > ()\"},\"version\":1},{\"value\":{\"Handoff\":{}},\"version\":3},{\"value\":{\"Operator\":\"source_stream (ints1)\"},\"version\":1},{\"value\":{\"Operator\":\"source_stream (ints2)\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"for_each (| v | result2 . send (v) . unwrap ())\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , ())) | (kv . 0 . 0 , kv . 1 . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , (() ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some (prev + 1) } else { Some (1) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () ,))\"},\"version\":1},{\"value\":{\"Operator\":\"join :: < 'tick , 'tick , hydroflow :: compiled :: pull :: HalfMultisetJoinState > ()\"},\"version\":1},{\"value\":{\"Operator\":\"map (| kv : ((_ ,) , ((_ ,) , ())) | (kv . 0 . 0 , kv . 1 . 0 . 0 ,))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ , _ ,) | ((_v . 0 ,) , (_v . 1 ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| _v : (_ ,) | ((_v . 0 ,) , ()))\"},\"version\":1},{\"value\":{\"Operator\":\"map (| row : (_ , _ ,) | (() , ((row . 0) ,)))\"},\"version\":1},{\"value\":{\"Operator\":\"fold_keyed :: < 'tick , () , (Option < _ > ,) > (| | (None ,) , | old : & mut (Option < _ > ,) , val : (_ ,) | { old . 0 = if let Some (prev) = old . 0 . take () { Some ({ let prev : (hydroflow :: rustc_hash :: FxHashSet < _ > , _) = prev ; let mut set : hydroflow :: rustc_hash :: FxHashSet < _ > = prev . 0 ; if set . insert (val . 0) { (set , prev . 1 + 1) } else { (set , prev . 1) } }) } else { Some ({ let mut set = hydroflow :: rustc_hash :: FxHashSet :: < _ > :: default () ; set . insert (val . 0) ; (set , 1) }) } ; })\"},\"version\":1},{\"value\":{\"Operator\":\"map (| (g , a) : (() , _) | (a . 0 . unwrap () . 1 ,))\"},\"version\":1}],\"graph\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":5,\"version\":1},{\"idx\":6,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":23,\"version\":1},{\"idx\":8,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":9,\"version\":3},{\"idx\":20,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":30,\"version\":1},{\"idx\":11,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":12,\"version\":3},{\"idx\":19,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":1,\"version\":3},{\"idx\":29,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":4,\"version\":3},{\"idx\":27,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":8,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":12,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":1},{\"idx\":9,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":7,\"version\":3},{\"idx\":26,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":21,\"version\":1},{\"idx\":10,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":18,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":3,\"version\":1},{\"idx\":7,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":27,\"version\":1},{\"idx\":24,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":6,\"version\":1},{\"idx\":4,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":10,\"version\":3},{\"idx\":22,\"version\":1}],\"version\":3},{\"value\":[{\"idx\":29,\"version\":1},{\"idx\":30,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":28,\"version\":1},{\"idx\":1,\"version\":3}],\"version\":3},{\"value\":[{\"idx\":25,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1}],\"ports\":[{\"value\":null,\"version\":0},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"0\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",{\"Int\":\"0\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",{\"Int\":\"1\"}],\"version\":1},{\"value\":[{\"Int\":\"1\"},\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1},{\"value\":[\"Elided\",\"Elided\"],\"version\":3},{\"value\":[\"Elided\",\"Elided\"],\"version\":1}],\"node_loops\":[{\"value\":null,\"version\":0}],\"loop_nodes\":[{\"value\":null,\"version\":0}],\"loop_parent\":[{\"value\":null,\"version\":0}],\"loop_children\":[{\"value\":null,\"version\":0}],\"node_subgraph\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":null,\"version\":0},{\"value\":{\"idx\":1,\"version\":1},\"version\":1},{\"value\":{\"idx\":2,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":5,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":3,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":6,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1},{\"value\":{\"idx\":4,\"version\":1},\"version\":1}],\"subgraph_nodes\":[{\"value\":null,\"version\":0},{\"value\":[{\"idx\":13,\"version\":1},{\"idx\":2,\"version\":1},{\"idx\":3,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":14,\"version\":1},{\"idx\":5,\"version\":1},{\"idx\":6,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":22,\"version\":1},{\"idx\":23,\"version\":1},{\"idx\":8,\"version\":1},{\"idx\":15,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":29,\"version\":1},{\"idx\":30,\"version\":1},{\"idx\":11,\"version\":1},{\"idx\":16,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":19,\"version\":1},{\"idx\":20,\"version\":1},{\"idx\":17,\"version\":1},{\"idx\":18,\"version\":1},{\"idx\":21,\"version\":1}],\"version\":1},{\"value\":[{\"idx\":26,\"version\":1},{\"idx\":27,\"version\":1},{\"idx\":24,\"version\":1},{\"idx\":25,\"version\":1},{\"idx\":28,\"version\":1}],\"version\":1}],\"subgraph_stratum\":[{\"value\":null,\"version\":0},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1},{\"value\":1,\"version\":1},{\"value\":1,\"version\":1},{\"value\":0,\"version\":1},{\"value\":0,\"version\":1}],\"node_singleton_references\":[{\"value\":null,\"version\":0},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1},{\"value\":[],\"version\":1}],\"node_varnames\":[{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"ints1_insert\",\"version\":1},{\"value\":\"ints1\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"ints2_insert\",\"version\":1},{\"value\":\"ints2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":\"result_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"result2_insert\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_2\",\"version\":1},{\"value\":\"join_2\",\"version\":1},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":null,\"version\":0},{\"value\":\"join_5\",\"version\":1},{\"value\":\"join_5\",\"version\":1}],\"subgraph_laziness\":[{\"value\":null,\"version\":0}]}", ); df.__assign_diagnostics("[]"); let (hoff_1v3_send, hoff_1v3_recv) = df diff --git a/hydroflow_lang/CHANGELOG.md b/hydroflow_lang/CHANGELOG.md index c6d3b14035a3..5bf10ccccd08 100644 --- a/hydroflow_lang/CHANGELOG.md +++ b/hydroflow_lang/CHANGELOG.md @@ -5,8 +5,91 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - generalized hash trie indexes for relational tuples + Generalized Hash Tries are part of the SIGMOD '23 FreeJoin + [paper](https://dl.acm.org/doi/abs/10.1145/3589295) by + Wang/Willsey/Suciu. They provide a compressed ("factorized") + representation of relations. By operating in the factorized domain, join + algorithms can defer cross-products and achieve asymptotically optimal + performance. + + --------- + - Added state_by operator. + For https://github.com/hydro-project/hydroflow/issues/1467 + +### Bug Fixes + + - `cross_singleton()` forgot value if multiple runs in a tick, fix #1518 + Adds the minimal reproducer test from @shadaj + + Note this may have negative performance implications, as the singleton value now is stored in the state API (heap) instead of locally. If we use singleton syntax this duplicate allocation could probably be avoided. + + > Confirmed that this fixed the bugs in our Paxos implementation, no noticeable performance impact. @shadj + +### Refactor + + - update topo-sort to detect cycles + +### Style + + - fixes for nightly clippy + a couple few spurious `too_many_arguments` and a spurious + `zombie_processes` still on current nightly (`clippy 0.1.84 (4392847410 + 2024-10-21)`) + +### Bug Fixes (BREAKING) + + - fix #1401 `lattice_bimorphism()` double-emit, add docs + Fixes the issue by combining the all values generated per subgraph + execution into one, which effectively de-duplicates the values. + + Adds basic docs. + +### Commit Statistics + + + + - 7 commits contributed to the release. + - 69 days passed between releases. + - 7 commits were understood as [conventional](https://www.conventionalcommits.org). + - 7 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1469](https://github.com/hydro-project/hydroflow/issues/1469), [#1503](https://github.com/hydro-project/hydroflow/issues/1503), [#1505](https://github.com/hydro-project/hydroflow/issues/1505), [#1512](https://github.com/hydro-project/hydroflow/issues/1512), [#1520](https://github.com/hydro-project/hydroflow/issues/1520), [#1522](https://github.com/hydro-project/hydroflow/issues/1522) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1469](https://github.com/hydro-project/hydroflow/issues/1469)** + - Added state_by operator. ([`d83cb83`](https://github.com/hydro-project/hydroflow/commit/d83cb83df59e647ba99bd896e7605ee18b9a84f6)) + * **[#1503](https://github.com/hydro-project/hydroflow/issues/1503)** + - Generalized hash trie indexes for relational tuples ([`f7e740f`](https://github.com/hydro-project/hydroflow/commit/f7e740fb2ba36d0fcf3fd196d60333552911e3a4)) + * **[#1505](https://github.com/hydro-project/hydroflow/issues/1505)** + - Fixes for nightly clippy ([`47cb703`](https://github.com/hydro-project/hydroflow/commit/47cb703e771f7d1c451ceb9d185ada96410949da)) + * **[#1512](https://github.com/hydro-project/hydroflow/issues/1512)** + - Update topo-sort to detect cycles ([`32e2970`](https://github.com/hydro-project/hydroflow/commit/32e297094fed9908ca7bf77e7068bc0a6ea52eae)) + * **[#1520](https://github.com/hydro-project/hydroflow/issues/1520)** + - `cross_singleton()` forgot value if multiple runs in a tick, fix #1518 ([`16b730c`](https://github.com/hydro-project/hydroflow/commit/16b730c75cfca79ea5f869308b1e1e14b3e9c155)) + * **[#1522](https://github.com/hydro-project/hydroflow/issues/1522)** + - Fix #1401 `lattice_bimorphism()` double-emit, add docs ([`e796200`](https://github.com/hydro-project/hydroflow/commit/e796200743f2cc2da5a0e91c492f016ca98008e8)) +
+ ## 0.9.0 (2024-08-30) + + + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -46,7 +129,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 10 commits contributed to the release. + - 11 commits contributed to the release. + - 38 days passed between releases. - 10 commits were understood as [conventional](https://www.conventionalcommits.org). - 10 unique issues were worked on: [#1362](https://github.com/hydro-project/hydroflow/issues/1362), [#1373](https://github.com/hydro-project/hydroflow/issues/1373), [#1407](https://github.com/hydro-project/hydroflow/issues/1407), [#1409](https://github.com/hydro-project/hydroflow/issues/1409), [#1412](https://github.com/hydro-project/hydroflow/issues/1412), [#1417](https://github.com/hydro-project/hydroflow/issues/1417), [#1420](https://github.com/hydro-project/hydroflow/issues/1420), [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1428](https://github.com/hydro-project/hydroflow/issues/1428), [#1432](https://github.com/hydro-project/hydroflow/issues/1432) @@ -76,6 +160,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cleanup doc comments for clippy latest ([`f5f1eb0`](https://github.com/hydro-project/hydroflow/commit/f5f1eb0c612f5c0c1752360d972ef6853c5e12f0)) * **[#1432](https://github.com/hydro-project/hydroflow/issues/1432)** - Cleanup handling of span locations #1268, workaround fix #729 ([`9c352f5`](https://github.com/hydro-project/hydroflow/commit/9c352f50a5a8d1b2187b34d5847a23b7397fe6ec)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.8.0 (2024-07-23) @@ -177,6 +263,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 14 commits contributed to the release. + - 59 days passed between releases. - 13 commits were understood as [conventional](https://www.conventionalcommits.org). - 13 unique issues were worked on: [#1143](https://github.com/hydro-project/hydroflow/issues/1143), [#1216](https://github.com/hydro-project/hydroflow/issues/1216), [#1260](https://github.com/hydro-project/hydroflow/issues/1260), [#1266](https://github.com/hydro-project/hydroflow/issues/1266), [#1271](https://github.com/hydro-project/hydroflow/issues/1271), [#1280](https://github.com/hydro-project/hydroflow/issues/1280), [#1285](https://github.com/hydro-project/hydroflow/issues/1285), [#1295](https://github.com/hydro-project/hydroflow/issues/1295), [#1296](https://github.com/hydro-project/hydroflow/issues/1296), [#1297](https://github.com/hydro-project/hydroflow/issues/1297), [#1300](https://github.com/hydro-project/hydroflow/issues/1300), [#1312](https://github.com/hydro-project/hydroflow/issues/1312), [#1332](https://github.com/hydro-project/hydroflow/issues/1332) @@ -217,15 +304,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix unnecessary `&` for clippy ([`b7275c2`](https://github.com/hydro-project/hydroflow/commit/b7275c2a770283cf8012a107ec422931e1f7338a)) - -Other 'tick state will need to be cleared, but existing implementation does that when the iterator runs, which is good enough. There is only a problem if a singleton can reference the state before the iterator runs, in that case. allow use of generics in demux_enum::<...>() opensures turbofish syntax for the match clauses, which is needed when there are generic parameters in the typeadds a test as wellTo emulate this unintuitive behavior, we currently ensure that apersist::<'static>() exists before operator that references thesingleton (filter, in this case). (Note that this is equivalent tocross_join::<'static>() and not cross_join::<'tick>())However singletons also have had a different mechanism that affectsthis- currently singleton references create a next-stratum constraint,that ensures a singleton referencer must be in a later stratum than thesingleton it is referencing.Note that this actually prevents the example situation above fromhappening– the updates to y will be received all at once at the startof the next stratum.This means that actually, currently singletons are equivalent tosomething like:ruststream -> cj[0]; -y -> next_stratum() -> last() -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -last() is a hypothetical operator that only keeps the most recent itemoutput by y. next_stratum() -> last() is equivalent to reduce(|acc, item| *acc = item) (since that comes with a stratum barrier). Sotechnically this is a slightly different behavior than just cross_join,but it is more intuitive.ruststream -> cj[0]; -y -> reduce(|acc, item| { *acc = item; }) -> cj[1]; -cj = cross_join() -> filter(|(item, y)| ...) -> ... -Also fixes #1293 - ## 0.7.0 (2024-05-24) @@ -293,6 +371,7 @@ Also fixes #1293 - 23 commits contributed to the release. + - 44 days passed between releases. - 21 commits were understood as [conventional](https://www.conventionalcommits.org). - 15 unique issues were worked on: [#1143](https://github.com/hydro-project/hydroflow/issues/1143), [#1152](https://github.com/hydro-project/hydroflow/issues/1152), [#1157](https://github.com/hydro-project/hydroflow/issues/1157), [#1159](https://github.com/hydro-project/hydroflow/issues/1159), [#1160](https://github.com/hydro-project/hydroflow/issues/1160), [#1167](https://github.com/hydro-project/hydroflow/issues/1167), [#1171](https://github.com/hydro-project/hydroflow/issues/1171), [#1176](https://github.com/hydro-project/hydroflow/issues/1176), [#1182](https://github.com/hydro-project/hydroflow/issues/1182), [#1190](https://github.com/hydro-project/hydroflow/issues/1190), [#1192](https://github.com/hydro-project/hydroflow/issues/1192), [#1193](https://github.com/hydro-project/hydroflow/issues/1193), [#1198](https://github.com/hydro-project/hydroflow/issues/1198), [#1204](https://github.com/hydro-project/hydroflow/issues/1204), [#1232](https://github.com/hydro-project/hydroflow/issues/1232) @@ -364,6 +443,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 3 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1134](https://github.com/hydro-project/hydroflow/issues/1134), [#1148](https://github.com/hydro-project/hydroflow/issues/1148), [#1150](https://github.com/hydro-project/hydroflow/issues/1150) @@ -432,6 +512,7 @@ Also fixes #1293 - 18 commits contributed to the release. + - 34 days passed between releases. - 17 commits were understood as [conventional](https://www.conventionalcommits.org). - 13 unique issues were worked on: [#1086](https://github.com/hydro-project/hydroflow/issues/1086), [#1087](https://github.com/hydro-project/hydroflow/issues/1087), [#1089](https://github.com/hydro-project/hydroflow/issues/1089), [#1090](https://github.com/hydro-project/hydroflow/issues/1090), [#1091](https://github.com/hydro-project/hydroflow/issues/1091), [#1109](https://github.com/hydro-project/hydroflow/issues/1109), [#1128](https://github.com/hydro-project/hydroflow/issues/1128), [#1130](https://github.com/hydro-project/hydroflow/issues/1130), [#1133](https://github.com/hydro-project/hydroflow/issues/1133), [#1136](https://github.com/hydro-project/hydroflow/issues/1136), [#1137](https://github.com/hydro-project/hydroflow/issues/1137), [#1145](https://github.com/hydro-project/hydroflow/issues/1145), [#1146](https://github.com/hydro-project/hydroflow/issues/1146) @@ -488,6 +569,7 @@ Also fixes #1293 - 3 commits contributed to the release. + - 28 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1061](https://github.com/hydro-project/hydroflow/issues/1061), [#1070](https://github.com/hydro-project/hydroflow/issues/1070) @@ -537,6 +619,7 @@ Also fixes #1293 - 9 commits contributed to the release. + - 4 days passed between releases. - 8 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1041](https://github.com/hydro-project/hydroflow/issues/1041), [#1053](https://github.com/hydro-project/hydroflow/issues/1053), [#1055](https://github.com/hydro-project/hydroflow/issues/1055) @@ -631,6 +714,7 @@ Also fixes #1293 - 28 commits contributed to the release. + - 110 days passed between releases. - 26 commits were understood as [conventional](https://www.conventionalcommits.org). - 20 unique issues were worked on: [#1005](https://github.com/hydro-project/hydroflow/issues/1005), [#1009](https://github.com/hydro-project/hydroflow/issues/1009), [#1016](https://github.com/hydro-project/hydroflow/issues/1016), [#1017](https://github.com/hydro-project/hydroflow/issues/1017), [#1021](https://github.com/hydro-project/hydroflow/issues/1021), [#1023](https://github.com/hydro-project/hydroflow/issues/1023), [#1026](https://github.com/hydro-project/hydroflow/issues/1026), [#1033](https://github.com/hydro-project/hydroflow/issues/1033), [#1036](https://github.com/hydro-project/hydroflow/issues/1036), [#1040](https://github.com/hydro-project/hydroflow/issues/1040), [#899](https://github.com/hydro-project/hydroflow/issues/899), [#945](https://github.com/hydro-project/hydroflow/issues/945), [#947](https://github.com/hydro-project/hydroflow/issues/947), [#948](https://github.com/hydro-project/hydroflow/issues/948), [#949](https://github.com/hydro-project/hydroflow/issues/949), [#950](https://github.com/hydro-project/hydroflow/issues/950), [#959](https://github.com/hydro-project/hydroflow/issues/959), [#960](https://github.com/hydro-project/hydroflow/issues/960), [#978](https://github.com/hydro-project/hydroflow/issues/978), [#989](https://github.com/hydro-project/hydroflow/issues/989) @@ -779,6 +863,7 @@ Also fixes #1293 - 42 commits contributed to the release. + - 56 days passed between releases. - 41 commits were understood as [conventional](https://www.conventionalcommits.org). - 14 unique issues were worked on: [#882](https://github.com/hydro-project/hydroflow/issues/882), [#883](https://github.com/hydro-project/hydroflow/issues/883), [#884](https://github.com/hydro-project/hydroflow/issues/884), [#892](https://github.com/hydro-project/hydroflow/issues/892), [#896](https://github.com/hydro-project/hydroflow/issues/896), [#898](https://github.com/hydro-project/hydroflow/issues/898), [#902](https://github.com/hydro-project/hydroflow/issues/902), [#906](https://github.com/hydro-project/hydroflow/issues/906), [#923](https://github.com/hydro-project/hydroflow/issues/923), [#924](https://github.com/hydro-project/hydroflow/issues/924), [#926](https://github.com/hydro-project/hydroflow/issues/926), [#932](https://github.com/hydro-project/hydroflow/issues/932), [#933](https://github.com/hydro-project/hydroflow/issues/933), [#935](https://github.com/hydro-project/hydroflow/issues/935) @@ -904,6 +989,7 @@ Also fixes #1293 - 17 commits contributed to the release. + - 42 days passed between releases. - 14 commits were understood as [conventional](https://www.conventionalcommits.org). - 16 unique issues were worked on: [#820](https://github.com/hydro-project/hydroflow/issues/820), [#821](https://github.com/hydro-project/hydroflow/issues/821), [#822](https://github.com/hydro-project/hydroflow/issues/822), [#823](https://github.com/hydro-project/hydroflow/issues/823), [#833](https://github.com/hydro-project/hydroflow/issues/833), [#835](https://github.com/hydro-project/hydroflow/issues/835), [#840](https://github.com/hydro-project/hydroflow/issues/840), [#843](https://github.com/hydro-project/hydroflow/issues/843), [#844](https://github.com/hydro-project/hydroflow/issues/844), [#845](https://github.com/hydro-project/hydroflow/issues/845), [#851](https://github.com/hydro-project/hydroflow/issues/851), [#853](https://github.com/hydro-project/hydroflow/issues/853), [#861](https://github.com/hydro-project/hydroflow/issues/861), [#870](https://github.com/hydro-project/hydroflow/issues/870), [#872](https://github.com/hydro-project/hydroflow/issues/872), [#873](https://github.com/hydro-project/hydroflow/issues/873) @@ -1014,6 +1100,7 @@ Also fixes #1293 - 17 commits contributed to the release. + - 33 days passed between releases. - 14 commits were understood as [conventional](https://www.conventionalcommits.org). - 15 unique issues were worked on: [#741](https://github.com/hydro-project/hydroflow/issues/741), [#765](https://github.com/hydro-project/hydroflow/issues/765), [#773](https://github.com/hydro-project/hydroflow/issues/773), [#774](https://github.com/hydro-project/hydroflow/issues/774), [#775](https://github.com/hydro-project/hydroflow/issues/775), [#778](https://github.com/hydro-project/hydroflow/issues/778), [#780](https://github.com/hydro-project/hydroflow/issues/780), [#784](https://github.com/hydro-project/hydroflow/issues/784), [#789](https://github.com/hydro-project/hydroflow/issues/789), [#792](https://github.com/hydro-project/hydroflow/issues/792), [#799](https://github.com/hydro-project/hydroflow/issues/799), [#801](https://github.com/hydro-project/hydroflow/issues/801), [#803](https://github.com/hydro-project/hydroflow/issues/803), [#804](https://github.com/hydro-project/hydroflow/issues/804), [#809](https://github.com/hydro-project/hydroflow/issues/809) @@ -1084,6 +1171,7 @@ Also fixes #1293 - 5 commits contributed to the release. + - 1 day passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#728](https://github.com/hydro-project/hydroflow/issues/728), [#730](https://github.com/hydro-project/hydroflow/issues/730) @@ -1153,6 +1241,7 @@ Also fixes #1293 - 13 commits contributed to the release. + - 6 days passed between releases. - 12 commits were understood as [conventional](https://www.conventionalcommits.org). - 8 unique issues were worked on: [#696](https://github.com/hydro-project/hydroflow/issues/696), [#697](https://github.com/hydro-project/hydroflow/issues/697), [#702](https://github.com/hydro-project/hydroflow/issues/702), [#704](https://github.com/hydro-project/hydroflow/issues/704), [#706](https://github.com/hydro-project/hydroflow/issues/706), [#714](https://github.com/hydro-project/hydroflow/issues/714), [#716](https://github.com/hydro-project/hydroflow/issues/716), [#719](https://github.com/hydro-project/hydroflow/issues/719) @@ -1205,6 +1294,7 @@ Also fixes #1293 - 6 commits contributed to the release. + - 2 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 5 unique issues were worked on: [#661](https://github.com/hydro-project/hydroflow/issues/661), [#673](https://github.com/hydro-project/hydroflow/issues/673), [#676](https://github.com/hydro-project/hydroflow/issues/676), [#677](https://github.com/hydro-project/hydroflow/issues/677), [#684](https://github.com/hydro-project/hydroflow/issues/684) @@ -1252,6 +1342,7 @@ Also fixes #1293 - 11 commits contributed to the release. + - 25 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 7 unique issues were worked on: [#638](https://github.com/hydro-project/hydroflow/issues/638), [#639](https://github.com/hydro-project/hydroflow/issues/639), [#642](https://github.com/hydro-project/hydroflow/issues/642), [#649](https://github.com/hydro-project/hydroflow/issues/649), [#654](https://github.com/hydro-project/hydroflow/issues/654), [#660](https://github.com/hydro-project/hydroflow/issues/660), [#667](https://github.com/hydro-project/hydroflow/issues/667) diff --git a/hydroflow_lang/Cargo.toml b/hydroflow_lang/Cargo.toml index 40fc75f5d0fc..b1321b5ebf72 100644 --- a/hydroflow_lang/Cargo.toml +++ b/hydroflow_lang/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow_lang" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow_lang/" diff --git a/hydroflow_lang/src/graph/flat_graph_builder.rs b/hydroflow_lang/src/graph/flat_graph_builder.rs index 2095b5768099..10c90a46c1a6 100644 --- a/hydroflow_lang/src/graph/flat_graph_builder.rs +++ b/hydroflow_lang/src/graph/flat_graph_builder.rs @@ -11,8 +11,11 @@ use quote::ToTokens; use syn::spanned::Spanned; use syn::{Error, Ident, ItemUse}; -use super::{GraphEdgeId, GraphNode, GraphNodeId, HydroflowGraph, PortIndexValue}; +use super::ops::defer_tick::DEFER_TICK; +use super::ops::FloType; +use super::{GraphEdgeId, GraphLoopId, GraphNode, GraphNodeId, HydroflowGraph, PortIndexValue}; use crate::diagnostic::{Diagnostic, Level}; +use crate::graph::graph_algorithms; use crate::graph::ops::{PortListSpec, RangeTrait}; use crate::parse::{HfCode, HfStatement, Operator, Pipeline}; use crate::pretty_span::PrettySpan; @@ -103,6 +106,7 @@ impl FlatGraphBuilder { import_expr: Span::call_site(), }, Some(Ident::new("input", Span::call_site())), + None, ), builder.flat_graph.insert_node( GraphNode::ModuleBoundary { @@ -110,6 +114,7 @@ impl FlatGraphBuilder { import_expr: Span::call_site(), }, Some(Ident::new("output", Span::call_site())), + None, ), )); builder.process_statements(input.statements); @@ -134,15 +139,24 @@ impl FlatGraphBuilder { (self.flat_graph, self.uses, self.diagnostics) } - /// Add a single [`HfStatement`] line to this `HydroflowGraph`. + /// Add a single [`HfStatement`] line to this `HydroflowGraph` in the root context. pub fn add_statement(&mut self, stmt: HfStatement) { + self.add_statement_with_loop(stmt, None) + } + + /// Add a single [`HfStatement`] line to this `HydroflowGraph` in the given loop context. + pub fn add_statement_with_loop( + &mut self, + stmt: HfStatement, + current_loop: Option, + ) { match stmt { HfStatement::Use(yuse) => { self.uses.push(yuse); } HfStatement::Named(named) => { let stmt_span = named.span(); - let ends = self.add_pipeline(named.pipeline, Some(&named.name)); + let ends = self.add_pipeline(named.pipeline, Some(&named.name), current_loop); match self.varname_ends.entry(named.name) { Entry::Vacant(vacant_entry) => { vacant_entry.insert(VarnameInfo::new(ends)); @@ -171,20 +185,32 @@ impl FlatGraphBuilder { } } HfStatement::Pipeline(pipeline_stmt) => { - let ends = self.add_pipeline(pipeline_stmt.pipeline, None); + let ends = self.add_pipeline(pipeline_stmt.pipeline, None, current_loop); Self::helper_check_unused_port(&mut self.diagnostics, &ends, true); Self::helper_check_unused_port(&mut self.diagnostics, &ends, false); } + HfStatement::Loop(loop_statement) => { + let inner_loop = self.flat_graph.insert_loop(current_loop); + for stmt in loop_statement.statements { + self.add_statement_with_loop(stmt, Some(inner_loop)); + } + } } } /// Helper: Add a pipeline, i.e. `a -> b -> c`. Return the input and output ends for it. - fn add_pipeline(&mut self, pipeline: Pipeline, current_varname: Option<&Ident>) -> Ends { + fn add_pipeline( + &mut self, + pipeline: Pipeline, + current_varname: Option<&Ident>, + current_loop: Option, + ) -> Ends { match pipeline { Pipeline::Paren(ported_pipeline_paren) => { let (inn_port, pipeline_paren, out_port) = PortIndexValue::from_ported(ported_pipeline_paren); - let og_ends = self.add_pipeline(*pipeline_paren.pipeline, current_varname); + let og_ends = + self.add_pipeline(*pipeline_paren.pipeline, current_varname, current_loop); Self::helper_combine_ends(&mut self.diagnostics, og_ends, inn_port, out_port) } Pipeline::Name(pipeline_name) => { @@ -222,8 +248,8 @@ impl FlatGraphBuilder { } Pipeline::Link(pipeline_link) => { // Add the nested LHS and RHS of this link. - let lhs_ends = self.add_pipeline(*pipeline_link.lhs, current_varname); - let rhs_ends = self.add_pipeline(*pipeline_link.rhs, current_varname); + let lhs_ends = self.add_pipeline(*pipeline_link.lhs, current_varname, current_loop); + let rhs_ends = self.add_pipeline(*pipeline_link.rhs, current_varname, current_loop); // Outer (first and last) ends. let outer_ends = Ends { @@ -240,9 +266,11 @@ impl FlatGraphBuilder { } Pipeline::Operator(operator) => { let op_span = Some(operator.span()); - let nid = self - .flat_graph - .insert_node(GraphNode::Operator(operator), current_varname.cloned()); + let nid = self.flat_graph.insert_node( + GraphNode::Operator(operator), + current_varname.cloned(), + current_loop, + ); Ends { inn: Some((PortIndexValue::Elided(op_span), GraphDet::Determined(nid))), out: Some((PortIndexValue::Elided(op_span), GraphDet::Determined(nid))), @@ -279,7 +307,7 @@ impl FlatGraphBuilder { self.diagnostics.push(Diagnostic::spanned( import.span(), Level::Error, - err.to_string(), + format!("Error in module: {}", err), )); return Ends { @@ -314,7 +342,7 @@ impl FlatGraphBuilder { match node { GraphNode::Operator(_) => { let varname = other.node_varname(other_node_id); - let new_id = self.flat_graph.insert_node(node.clone(), varname); + let new_id = self.flat_graph.insert_node(node.clone(), varname, None); node_mapping.insert(other_node_id, new_id); } GraphNode::ModuleBoundary { input, .. } => { @@ -324,6 +352,7 @@ impl FlatGraphBuilder { import_expr: parent_span, }, Some(Ident::new(&format!("module_{}", input), parent_span)), + None, ); node_mapping.insert(other_node_id, new_id); @@ -562,6 +591,7 @@ impl FlatGraphBuilder { self.make_operator_instances(); self.check_operator_errors(); self.warn_unused_port_indexing(); + self.check_loop_errors(); } /// Make `OperatorInstance`s for each operator node. @@ -888,4 +918,147 @@ impl FlatGraphBuilder { } } } + + /// Check for loop context-related errors. + fn check_loop_errors(&mut self) { + // All inputs must be declared in the root block. + for (node_id, node) in self.flat_graph.nodes() { + let Some(op_inst) = self.flat_graph.node_op_inst(node_id) else { + continue; + }; + let loop_id = self.flat_graph.node_loop(node_id); + + // Source operators must be at the top level. + if Some(FloType::Source) == op_inst.op_constraints.flo_type && loop_id.is_some() { + self.diagnostics.push(Diagnostic::spanned( + node.span(), + Level::Error, + format!( + "Source operator `{}(...)` must be at the root level, not within any `loop {{ ... }}` contexts.", + op_inst.op_constraints.name + ) + )); + } + } + + // Check windowing and un-windowing operators, for loop inputs and outputs respectively. + for (_edge_id, (pred_id, node_id)) in self.flat_graph.edges() { + let Some(op_inst) = self.flat_graph.node_op_inst(node_id) else { + continue; + }; + let flo_type = &op_inst.op_constraints.flo_type; + + let pred_loop_id = self.flat_graph.node_loop(pred_id); + let loop_id = self.flat_graph.node_loop(node_id); + + let span = self.flat_graph.node(node_id).span(); + + let (is_input, is_output) = { + let parent_pred_loop_id = + pred_loop_id.and_then(|lid| self.flat_graph.loop_parent(lid)); + let parent_loop_id = loop_id.and_then(|lid| self.flat_graph.loop_parent(lid)); + let is_same = pred_loop_id == loop_id; + let is_input = !is_same && parent_loop_id == pred_loop_id; + let is_output = !is_same && parent_pred_loop_id == loop_id; + if !(is_input || is_output || is_same) { + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + "Operator input edge may not cross multiple loop contexts.", + )); + continue; + } + (is_input, is_output) + }; + + match flo_type { + None => { + if is_input { + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + format!( + "Operator `{}(...)` entering a loop context must be a windowing operator, but is not.", + op_inst.op_constraints.name + ) + )); + } + if is_output { + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + format!( + "Operator `{}(...)` exiting a loop context must be an un-windowing operator, but is not.", + op_inst.op_constraints.name + ) + )); + } + } + Some(FloType::Windowing) => { + if !is_input { + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + format!( + "Windowing operator `{}(...)` must be the first input operator into a `loop {{ ... }} context.", + op_inst.op_constraints.name + ) + )); + } + } + Some(FloType::Unwindowing) => { + if !is_output { + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + format!( + "Un-windowing operator `{}(...)` must be the first output operator after exiting a `loop {{ ... }} context.", + op_inst.op_constraints.name + ) + )); + } + } + Some(FloType::Source) => { + // Handled above. + } + } + } + + // Must be a DAG (excluding `next_tick()` operators). + // TODO(mingwei): Nested loop blocks should count as a single node. + for (loop_id, loop_nodes) in self.flat_graph.loops() { + // Filter out `defer_tick()` operators. + let filter_defer_tick = |&node_id: &GraphNodeId| { + self.flat_graph + .node_op_inst(node_id) + .map(|op_inst| DEFER_TICK.name != op_inst.op_constraints.name) + .unwrap_or(true) + }; + + let topo_sort_result = graph_algorithms::topo_sort( + loop_nodes.iter().copied().filter(filter_defer_tick), + |dst| { + self.flat_graph + .node_predecessor_nodes(dst) + .filter(|&src| Some(loop_id) == self.flat_graph.node_loop(src)) + .filter(filter_defer_tick) + }, + ); + if let Err(cycle) = topo_sort_result { + let len = cycle.len(); + for (i, node_id) in cycle.into_iter().enumerate() { + let span = self.flat_graph.node(node_id).span(); + self.diagnostics.push(Diagnostic::spanned( + span, + Level::Error, + format!( + "Operator forms an illegal cycle within a `loop {{ ... }}` block ({}/{}).", + i + 1, + len + ), + )); + } + } + } + } } diff --git a/hydroflow_lang/src/graph/flat_to_partitioned.rs b/hydroflow_lang/src/graph/flat_to_partitioned.rs index 4c732fe5b0aa..418c6b4b0300 100644 --- a/hydroflow_lang/src/graph/flat_to_partitioned.rs +++ b/hydroflow_lang/src/graph/flat_to_partitioned.rs @@ -116,7 +116,7 @@ fn find_subgraph_unionfind( continue; } - // Ignore if would join stratum crossers (next edges). + // Do not connect stratum crossers (next edges). if barrier_crossers .iter_node_pairs(partitioned_graph) .any(|((x_src, x_dst), _)| { @@ -129,6 +129,11 @@ fn find_subgraph_unionfind( continue; } + // Do not connect across loop contexts. + if partitioned_graph.node_loop(src) != partitioned_graph.node_loop(dst) { + continue; + } + if can_connect_colorize(&mut node_color, src, dst) { // At this point we have selected this edge and its src & dst to be // within a single subgraph. @@ -165,7 +170,8 @@ fn make_subgraph_collect( !matches!(pred, GraphNode::Handoff { .. }) }) }, - ); + ) + .expect("Subgraphs are in-out trees."); let mut grouped_nodes: SecondaryMap> = Default::default(); for node_id in topo_sort { diff --git a/hydroflow_lang/src/graph/graph_algorithms.rs b/hydroflow_lang/src/graph/graph_algorithms.rs index 96ec1e357df2..478d1b2a63ed 100644 --- a/hydroflow_lang/src/graph/graph_algorithms.rs +++ b/hydroflow_lang/src/graph/graph_algorithms.rs @@ -3,7 +3,7 @@ use std::collections::btree_map::Entry; use std::collections::{BTreeMap, BTreeSet}; -/// Computers the topological sort of the nodes of a possibly cyclic graph by ordering strongly +/// Computes the topological sort of the nodes of a possibly cyclic graph by ordering strongly /// connected components together. pub fn topo_sort_scc( mut nodes_fn: NodesFn, @@ -23,16 +23,21 @@ where let topo_sort_order = { // Condensed each SCC into a single node for toposort. let mut condensed_preds: BTreeMap> = Default::default(); - for u in (nodes_fn)() { - condensed_preds - .entry(scc[&u]) - .or_default() - .extend((preds_fn)(u).into_iter().map(|v| scc[&v])); + for v in (nodes_fn)() { + let v = scc[&v]; + condensed_preds.entry(v).or_default().extend( + (preds_fn)(v) + .into_iter() + .map(|u| scc[&u]) + .filter(|&u| v != u), + ); } topo_sort((nodes_fn)(), |v| { condensed_preds.get(&v).into_iter().flatten().cloned() }) + .map_err(drop) + .expect("No cycles after SCC condensing.") }; topo_sort_order } @@ -40,13 +45,16 @@ where /// Topologically sorts a set of nodes. Returns a list where the order of `Id`s will agree with /// the order of any path through the graph. /// -/// This naturally requires a directed acyclic graph (DAG). +/// This succeeds if the input is a directed acyclic graph (DAG). +/// +/// If the input has a cycle, an `Err` will be returned containing the cycle. Each node in the +/// cycle will be listed exactly once. /// /// pub fn topo_sort( node_ids: NodeIds, mut preds_fn: PredsFn, -) -> Vec +) -> Result, Vec> where Id: Copy + Eq + Ord, NodeIds: IntoIterator, @@ -58,28 +66,49 @@ where fn pred_dfs_postorder( node_id: Id, preds_fn: &mut PredsFn, - marked: &mut BTreeSet, + marked: &mut BTreeMap, // `false` => temporary, `true` => permanent. order: &mut Vec, - ) where + ) -> Result<(), ()> + where Id: Copy + Eq + Ord, PredsFn: FnMut(Id) -> PredsIter, PredsIter: IntoIterator, { - if marked.insert(node_id) { - for next_pred in (preds_fn)(node_id) { - pred_dfs_postorder(next_pred, preds_fn, marked, order); + match marked.get(&node_id) { + Some(_permanent @ true) => Ok(()), + Some(_temporary @ false) => { + // Cycle found! + order.clear(); + order.push(node_id); + Err(()) + } + None => { + marked.insert(node_id, false); + for next_pred in (preds_fn)(node_id) { + pred_dfs_postorder(next_pred, preds_fn, marked, order).map_err(|()| { + if order.len() == 1 || order.first().unwrap() != order.last().unwrap() { + order.push(node_id); + } + })?; + } + order.push(node_id); + marked.insert(node_id, true); + Ok(()) } - order.push(node_id); - } else { - // TODO(mingwei): cycle found! } } for node_id in node_ids { - pred_dfs_postorder(node_id, &mut preds_fn, &mut marked, &mut order); + if pred_dfs_postorder(node_id, &mut preds_fn, &mut marked, &mut order).is_err() { + // Cycle found. + let end = order.last().unwrap(); + let beg = order.iter().position(|n| n == end).unwrap(); + order.drain(0..=beg); + return Err(order); + } } - order + Ok(order) } /// Finds the strongly connected components in the graph. A strongly connected component is a @@ -156,6 +185,8 @@ where #[cfg(test)] mod test { + use itertools::Itertools; + use super::*; #[test] @@ -179,6 +210,13 @@ mod test { .filter(move |&&(_, dst)| v == dst) .map(|&(src, _)| src) }); + assert!( + sort.is_ok(), + "Did not expect cycle: {:?}", + sort.unwrap_err() + ); + + let sort = sort.unwrap(); println!("{:?}", sort); let position: BTreeMap<_, _> = sort.iter().enumerate().map(|(i, &x)| (x, i)).collect(); @@ -187,6 +225,54 @@ mod test { } } + #[test] + pub fn test_toposort_cycle() { + // https://commons.wikimedia.org/wiki/File:Directed_graph,_cyclic.svg + // ┌────►C──────┐ + // │ │ + // │ ▼ + // A───────►B E ─────►F + // ▲ │ + // │ │ + // └─────D◄─────┘ + let edges = [ + ('A', 'B'), + ('B', 'C'), + ('C', 'E'), + ('D', 'B'), + ('E', 'F'), + ('E', 'D'), + ]; + let ids = edges + .iter() + .flat_map(|&(a, b)| [a, b]) + .collect::>(); + let cycle_rotations = BTreeSet::from_iter([ + ['B', 'C', 'E', 'D'], + ['C', 'E', 'D', 'B'], + ['E', 'D', 'B', 'C'], + ['D', 'B', 'C', 'E'], + ]); + + let permutations = ids.iter().copied().permutations(ids.len()); + for permutation in permutations { + let result = topo_sort(permutation.iter().copied(), |v| { + edges + .iter() + .filter(move |&&(_, dst)| v == dst) + .map(|&(src, _)| src) + }); + assert!(result.is_err()); + let cycle = result.unwrap_err(); + assert!( + cycle_rotations.contains(&*cycle), + "cycle: {:?}, vertex order: {:?}", + cycle, + permutation + ); + } + } + #[test] pub fn test_scc_kosaraju() { // https://commons.wikimedia.org/wiki/File:Scc-1.svg diff --git a/hydroflow_lang/src/graph/hydroflow_graph.rs b/hydroflow_lang/src/graph/hydroflow_graph.rs index 18de444060d3..ac857f72cc5f 100644 --- a/hydroflow_lang/src/graph/hydroflow_graph.rs +++ b/hydroflow_lang/src/graph/hydroflow_graph.rs @@ -17,9 +17,9 @@ use super::ops::{ WriteContextArgs, OPERATORS, }; use super::{ - change_spans, get_operator_generics, Color, DiMulGraph, GraphEdgeId, GraphNode, GraphNodeId, - GraphSubgraphId, OperatorInstance, PortIndexValue, Varname, CONTEXT, HANDOFF_NODE_STR, - HYDROFLOW, MODULE_BOUNDARY_NODE_STR, + change_spans, get_operator_generics, Color, DiMulGraph, GraphEdgeId, GraphLoopId, GraphNode, + GraphNodeId, GraphSubgraphId, OperatorInstance, PortIndexValue, Varname, CONTEXT, + HANDOFF_NODE_STR, HYDROFLOW, MODULE_BOUNDARY_NODE_STR, }; use crate::diagnostic::{Diagnostic, Level}; use crate::pretty_span::{PrettyRowCol, PrettySpan}; @@ -47,6 +47,15 @@ pub struct HydroflowGraph { graph: DiMulGraph, /// Input and output port for each edge. ports: SecondaryMap, + + /// Which loop a node belongs to (or none for top-level). + node_loops: SecondaryMap, + loop_nodes: SlotMap>, + /// For the key loop, what is its parent (`None` for top-level). + loop_parent: SparseSecondaryMap, + /// For the key loop, what are its child loops. + loop_children: SecondaryMap>, + /// Which subgraph each node belongs to. node_subgraph: SecondaryMap, @@ -198,11 +207,20 @@ impl HydroflowGraph { } /// Insert a node, assigning the given varname. - pub fn insert_node(&mut self, node: GraphNode, varname_opt: Option) -> GraphNodeId { + pub fn insert_node( + &mut self, + node: GraphNode, + varname_opt: Option, + loop_opt: Option, + ) -> GraphNodeId { let node_id = self.nodes.insert(node); if let Some(varname) = varname_opt { self.node_varnames.insert(node_id, Varname(varname)); } + if let Some(loop_id) = loop_opt { + self.node_loops.insert(node_id, loop_id); + self.loop_nodes[loop_id].push(node_id); + } node_id } @@ -1521,6 +1539,48 @@ impl HydroflowGraph { } } +/// Loops +impl HydroflowGraph { + /// Iterator over all loop IDs. + pub fn loop_ids(&self) -> slotmap::basic::Keys<'_, GraphLoopId, Vec> { + self.loop_nodes.keys() + } + + /// Iterator over all loops, ID and members: `(GraphLoopId, Vec)`. + pub fn loops(&self) -> slotmap::basic::Iter<'_, GraphLoopId, Vec> { + self.loop_nodes.iter() + } + + /// Create a new loop context, with the given parent loop (or `None`). + pub fn insert_loop(&mut self, parent_loop: Option) -> GraphLoopId { + let loop_id = self.loop_nodes.insert(Vec::new()); + self.loop_children.insert(loop_id, Vec::new()); + if let Some(parent_loop) = parent_loop { + self.loop_parent.insert(loop_id, parent_loop); + self.loop_children + .get_mut(parent_loop) + .unwrap() + .push(loop_id); + } + loop_id + } + + /// Get a node's loop context (or `None` for root). + pub fn node_loop(&self, node_id: GraphNodeId) -> Option { + self.node_loops.get(node_id).copied() + } + + /// Get a loop context's parent loop context (or `None` for root). + pub fn loop_parent(&self, loop_id: GraphLoopId) -> Option { + self.loop_parent.get(loop_id).copied() + } + + /// Get a loop context's child loops. + pub fn loop_children(&self, loop_id: GraphLoopId) -> &Vec { + self.loop_children.get(loop_id).unwrap() + } +} + /// Configuration for writing graphs. #[derive(Clone, Debug, Default)] #[cfg_attr(feature = "clap-derive", derive(clap::Args))] diff --git a/hydroflow_lang/src/graph/mod.rs b/hydroflow_lang/src/graph/mod.rs index 5caa4971cde0..7cb82e22c8d9 100644 --- a/hydroflow_lang/src/graph/mod.rs +++ b/hydroflow_lang/src/graph/mod.rs @@ -45,6 +45,9 @@ new_key_type! { /// ID to identify a subgraph in [`HydroflowGraph`]. pub struct GraphSubgraphId; + + /// ID to identify a loop block in [`HydroflowGraph`]. + pub struct GraphLoopId; } /// Context identifier as a string. diff --git a/hydroflow_lang/src/graph/ops/_lattice_fold_batch.rs b/hydroflow_lang/src/graph/ops/_lattice_fold_batch.rs index d6f6f635fa21..4bdecb0c7858 100644 --- a/hydroflow_lang/src/graph/ops/_lattice_fold_batch.rs +++ b/hydroflow_lang/src/graph/ops/_lattice_fold_batch.rs @@ -42,6 +42,7 @@ pub const _LATTICE_FOLD_BATCH: OperatorConstraints = OperatorConstraints { num_args: 0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| PortListSpec::Fixed(parse_quote! { input, signal })), ports_out: None, input_delaytype_fn: |_| Some(DelayType::MonotoneAccum), diff --git a/hydroflow_lang/src/graph/ops/_lattice_join_fused_join.rs b/hydroflow_lang/src/graph/ops/_lattice_join_fused_join.rs index 7e945f0cc90c..f777acef489b 100644 --- a/hydroflow_lang/src/graph/ops/_lattice_join_fused_join.rs +++ b/hydroflow_lang/src/graph/ops/_lattice_join_fused_join.rs @@ -86,6 +86,7 @@ pub const _LATTICE_JOIN_FUSED_JOIN: OperatorConstraints = OperatorConstraints { type_args: &(2..=2), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| Some(DelayType::MonotoneAccum), diff --git a/hydroflow_lang/src/graph/ops/all_once.rs b/hydroflow_lang/src/graph/ops/all_once.rs new file mode 100644 index 000000000000..c882a7cd3523 --- /dev/null +++ b/hydroflow_lang/src/graph/ops/all_once.rs @@ -0,0 +1,9 @@ +use super::{DelayType, OperatorConstraints}; + +// Same as batch, but with a stratum barrier. +/// TODO(mingwei): docs +pub const ALL_ONCE: OperatorConstraints = OperatorConstraints { + name: "all_once", + input_delaytype_fn: |_| Some(DelayType::Stratum), + ..super::batch::BATCH +}; diff --git a/hydroflow_lang/src/graph/ops/anti_join.rs b/hydroflow_lang/src/graph/ops/anti_join.rs index a81fcd48695a..c80f6384fd45 100644 --- a/hydroflow_lang/src/graph/ops/anti_join.rs +++ b/hydroflow_lang/src/graph/ops/anti_join.rs @@ -37,6 +37,7 @@ pub const ANTI_JOIN: OperatorConstraints = OperatorConstraints { // to prevent reading uncleared data if this subgraph doesn't run. // https://github.com/hydro-project/hydroflow/issues/1298 has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { pos, neg })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/anti_join_multiset.rs b/hydroflow_lang/src/graph/ops/anti_join_multiset.rs index 3af7e569eca1..0c37c202d48a 100644 --- a/hydroflow_lang/src/graph/ops/anti_join_multiset.rs +++ b/hydroflow_lang/src/graph/ops/anti_join_multiset.rs @@ -2,12 +2,12 @@ use quote::{quote_spanned, ToTokens}; use syn::parse_quote; use super::{ - DelayType, OpInstGenerics, OperatorCategory, OperatorConstraints, - OperatorInstance, OperatorWriteOutput, Persistence, PortIndexValue, WriteContextArgs, RANGE_0, - RANGE_1, + DelayType, OpInstGenerics, OperatorCategory, OperatorConstraints, OperatorInstance, + OperatorWriteOutput, Persistence, PortIndexValue, WriteContextArgs, RANGE_0, RANGE_1, }; use crate::diagnostic::{Diagnostic, Level}; +// This implementation is largely redundant to ANTI_JOIN and should be DRY'ed /// > 2 input streams the first of type (K, T), the second of type K, /// > with output type (K, T) /// @@ -22,8 +22,6 @@ use crate::diagnostic::{Diagnostic, Level}; /// source_iter(vec!["dog", "cat", "gorilla"]) -> [neg]diff; /// diff = anti_join_multiset() -> assert_eq([("elephant", 3), ("elephant", 3)]); /// ``` - -// This implementation is largely redundant to ANTI_JOIN and should be DRY'ed pub const ANTI_JOIN_MULTISET: OperatorConstraints = OperatorConstraints { name: "anti_join_multiset", categories: &[OperatorCategory::MultiIn], @@ -39,6 +37,7 @@ pub const ANTI_JOIN_MULTISET: OperatorConstraints = OperatorConstraints { // to prevent reading uncleared data if this subgraph doesn't run. // https://github.com/hydro-project/hydroflow/issues/1298 has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { pos, neg })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/assert.rs b/hydroflow_lang/src/graph/ops/assert.rs index af3afeee9867..de859d5dddd7 100644 --- a/hydroflow_lang/src/graph/ops/assert.rs +++ b/hydroflow_lang/src/graph/ops/assert.rs @@ -26,6 +26,7 @@ pub const ASSERT: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/assert_eq.rs b/hydroflow_lang/src/graph/ops/assert_eq.rs index 0aca9dbd257f..2d08e58fcc70 100644 --- a/hydroflow_lang/src/graph/ops/assert_eq.rs +++ b/hydroflow_lang/src/graph/ops/assert_eq.rs @@ -37,6 +37,7 @@ pub const ASSERT_EQ: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/batch.rs b/hydroflow_lang/src/graph/ops/batch.rs new file mode 100644 index 000000000000..faccafdbd0c7 --- /dev/null +++ b/hydroflow_lang/src/graph/ops/batch.rs @@ -0,0 +1,79 @@ +use quote::quote_spanned; + +use super::{ + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, + RANGE_1, +}; + +/// TODO(mingwei): docs +pub const BATCH: OperatorConstraints = OperatorConstraints { + name: "batch", + categories: &[OperatorCategory::Fold, OperatorCategory::Windowing], + hard_range_inn: RANGE_1, + soft_range_inn: RANGE_1, + hard_range_out: &(0..=1), + soft_range_out: &(0..=1), + num_args: 0, + persistence_args: RANGE_0, + type_args: RANGE_0, + is_external_input: false, + has_singleton_output: true, + flo_type: Some(FloType::Windowing), + ports_inn: None, + ports_out: None, + input_delaytype_fn: |_| None, + write_fn: |wc @ &WriteContextArgs { + root, + context, + hydroflow, + op_span, + ident, + is_pull, + inputs, + outputs, + singleton_output_ident, + .. + }, + _diagnostics| { + let write_prologue = quote_spanned! {op_span=> + #[allow(clippy::redundant_closure_call)] + let #singleton_output_ident = #hydroflow.add_state( + ::std::cell::RefCell::new(::std::vec::Vec::new()) + ); + + // TODO(mingwei): Is this needed? + // Reset the value to the initializer fn if it is a new tick. + #hydroflow.set_state_tick_hook(#singleton_output_ident, move |rcell| { rcell.take(); }); + }; + + let vec_ident = wc.make_ident("vec"); + + let write_iterator = if is_pull { + // Pull. + let input = &inputs[0]; + quote_spanned! {op_span=> + let mut #vec_ident = #context.state_ref(#singleton_output_ident).borrow_mut(); + *#vec_ident = #input.collect::<::std::vec::Vec<_>>(); + let #ident = ::std::iter::once(::std::clone::Clone::clone(&*#vec_ident)); + } + } else if let Some(_output) = outputs.first() { + // Push with output. + // TODO(mingwei): Not supported - cannot tell EOS for pusherators. + panic!("Should not happen - batch must be at ingress to a loop, therefore ingress to a subgraph, so would be pull-based."); + } else { + // Push with no output. + quote_spanned! {op_span=> + let mut #vec_ident = #context.state_ref(#singleton_output_ident).borrow_mut(); + let #ident = #root::pusherator::for_each::ForEach::new(|item| { + ::std::vec::Vec::push(#vec_ident, item); + }); + } + }; + + Ok(OperatorWriteOutput { + write_prologue, + write_iterator, + ..Default::default() + }) + }, +}; diff --git a/hydroflow_lang/src/graph/ops/chain.rs b/hydroflow_lang/src/graph/ops/chain.rs new file mode 100644 index 000000000000..3ff9c90fdec4 --- /dev/null +++ b/hydroflow_lang/src/graph/ops/chain.rs @@ -0,0 +1,43 @@ +use crate::graph::PortIndexValue; + +use super::{ + DelayType, OperatorCategory, OperatorConstraints, RANGE_0, RANGE_1 +}; + +/// > 2 input streams of the same type, 1 output stream of the same type +/// +/// Chains together a pair of streams, with all the elements of the first emitted before the second. +/// +/// Since `chain` has multiple input streams, it needs to be assigned to +/// a variable to reference its multiple input ports across statements. +/// +/// ```hydroflow +/// source_iter(vec!["hello", "world"]) -> [0]my_chain; +/// source_iter(vec!["stay", "gold"]) -> [1]my_chain; +/// my_chain = chain() +/// -> map(|x| x.to_uppercase()) +/// -> assert_eq(["HELLO", "WORLD", "STAY", "GOLD"]); +/// ``` +pub const CHAIN: OperatorConstraints = OperatorConstraints { + name: "chain", + categories: &[OperatorCategory::MultiIn], + persistence_args: RANGE_0, + type_args: RANGE_0, + hard_range_inn: &(2..=2), + soft_range_inn: &(2..=2), + hard_range_out: RANGE_1, + soft_range_out: RANGE_1, + num_args: 0, + is_external_input: false, + has_singleton_output: false, + flo_type: None, + ports_inn: None, + ports_out: None, + input_delaytype_fn: |idx| match idx { + PortIndexValue::Int(idx) if idx.value == 0 => { + Some(DelayType::Stratum) + } + _else => None, + }, + write_fn: super::union::UNION.write_fn, +}; diff --git a/hydroflow_lang/src/graph/ops/cross_join.rs b/hydroflow_lang/src/graph/ops/cross_join.rs index fe4c2aeed80f..c22d0225bc7a 100644 --- a/hydroflow_lang/src/graph/ops/cross_join.rs +++ b/hydroflow_lang/src/graph/ops/cross_join.rs @@ -45,6 +45,7 @@ pub const CROSS_JOIN: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/cross_join_multiset.rs b/hydroflow_lang/src/graph/ops/cross_join_multiset.rs index e050f2818c3e..5708800bcb28 100644 --- a/hydroflow_lang/src/graph/ops/cross_join_multiset.rs +++ b/hydroflow_lang/src/graph/ops/cross_join_multiset.rs @@ -34,6 +34,7 @@ pub const CROSS_JOIN_MULTISET: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/cross_singleton.rs b/hydroflow_lang/src/graph/ops/cross_singleton.rs index 0c8780c5ccfa..6d4b3757e667 100644 --- a/hydroflow_lang/src/graph/ops/cross_singleton.rs +++ b/hydroflow_lang/src/graph/ops/cross_singleton.rs @@ -2,8 +2,8 @@ use quote::{quote_spanned, ToTokens}; use syn::parse_quote; use super::{ - DelayType, OperatorCategory, OperatorConstraints, - OperatorWriteOutput, WriteContextArgs, RANGE_0, RANGE_1, + DelayType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, + RANGE_0, RANGE_1, }; use crate::graph::PortIndexValue; @@ -39,6 +39,7 @@ pub const CROSS_SINGLETON: OperatorConstraints = OperatorConstraints { num_args: 0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { input, single })), ports_out: None, input_delaytype_fn: |idx| match idx { @@ -48,6 +49,8 @@ pub const CROSS_SINGLETON: OperatorConstraints = OperatorConstraints { _else => None, }, write_fn: |wc @ &WriteContextArgs { + context, + hydroflow, ident, op_span, inputs, @@ -57,20 +60,54 @@ pub const CROSS_SINGLETON: OperatorConstraints = OperatorConstraints { _diagnostics| { assert!(is_pull); - let input = &inputs[0]; - let singleton = &inputs[1]; - let s_taken_ident = wc.make_ident("singleton_taken"); - let singleton_value_ident = wc.make_ident("singleton_value"); + let stream_input = &inputs[0]; + let singleton_input = &inputs[1]; + let singleton_handle_ident = wc.make_ident("singleton_handle"); + + let write_prologue = quote_spanned! {op_span=> + let #singleton_handle_ident = #hydroflow.add_state( + ::std::cell::RefCell::new(::std::option::Option::None) + ); + // Reset the value if it is a new tick. + #hydroflow.set_state_tick_hook(#singleton_handle_ident, |rcell| { rcell.take(); }); + }; let write_iterator = quote_spanned! {op_span=> - let mut #s_taken_ident = #singleton; - let #ident = #s_taken_ident.next().map(|#singleton_value_ident| { - #input.map(move |x| (x, ::std::clone::Clone::clone(&#singleton_value_ident))) - }).into_iter().flatten(); + let #ident = { + #[inline(always)] + fn cross_singleton_guard( + mut singleton_state_mut: std::cell::RefMut<'_, Option>, + mut singleton_input: impl Iterator, + stream_input: impl Iterator, + ) -> impl Iterator + where + Singleton: ::std::clone::Clone, + { + let singleton_value_opt = match &*singleton_state_mut { + ::std::option::Option::Some(singleton_value) => Some(singleton_value.clone()), + ::std::option::Option::None => { + let singleton_value_opt = singleton_input.next(); + *singleton_state_mut = singleton_value_opt.clone(); + singleton_value_opt + } + }; + singleton_value_opt + .map(|singleton_value| { + stream_input.map(move |item| (item, ::std::clone::Clone::clone(&singleton_value))) + }) + .into_iter() + .flatten() + } + cross_singleton_guard( + #context.state_ref(#singleton_handle_ident).borrow_mut(), + #singleton_input, + #stream_input, + ) + }; }; Ok(OperatorWriteOutput { - write_prologue: Default::default(), + write_prologue, write_iterator, ..Default::default() }) diff --git a/hydroflow_lang/src/graph/ops/defer_signal.rs b/hydroflow_lang/src/graph/ops/defer_signal.rs index b8e6459cb233..2adb2b4a993d 100644 --- a/hydroflow_lang/src/graph/ops/defer_signal.rs +++ b/hydroflow_lang/src/graph/ops/defer_signal.rs @@ -34,6 +34,7 @@ pub const DEFER_SIGNAL: OperatorConstraints = OperatorConstraints { num_args: 0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { input, signal })), ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/defer_tick.rs b/hydroflow_lang/src/graph/ops/defer_tick.rs index fa25f1ee1a84..42c3d92ba8d8 100644 --- a/hydroflow_lang/src/graph/ops/defer_tick.rs +++ b/hydroflow_lang/src/graph/ops/defer_tick.rs @@ -72,6 +72,7 @@ pub const DEFER_TICK: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Tick), diff --git a/hydroflow_lang/src/graph/ops/defer_tick_lazy.rs b/hydroflow_lang/src/graph/ops/defer_tick_lazy.rs index 8417d9ae9a92..96c505f19c7b 100644 --- a/hydroflow_lang/src/graph/ops/defer_tick_lazy.rs +++ b/hydroflow_lang/src/graph/ops/defer_tick_lazy.rs @@ -17,6 +17,7 @@ pub const DEFER_TICK_LAZY: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::TickLazy), diff --git a/hydroflow_lang/src/graph/ops/demux.rs b/hydroflow_lang/src/graph/ops/demux.rs index b96fe44df4c5..bfedf7a9b8cc 100644 --- a/hydroflow_lang/src/graph/ops/demux.rs +++ b/hydroflow_lang/src/graph/ops/demux.rs @@ -53,6 +53,7 @@ pub const DEMUX: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: Some(|| PortListSpec::Variadic), input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/demux_enum.rs b/hydroflow_lang/src/graph/ops/demux_enum.rs index 2d3ea6e9e501..8b612c243539 100644 --- a/hydroflow_lang/src/graph/ops/demux_enum.rs +++ b/hydroflow_lang/src/graph/ops/demux_enum.rs @@ -52,6 +52,7 @@ pub const DEMUX_ENUM: OperatorConstraints = OperatorConstraints { type_args: RANGE_1, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: Some(|| PortListSpec::Variadic), input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/dest_file.rs b/hydroflow_lang/src/graph/ops/dest_file.rs index f0190bfd07f5..0067cd53242d 100644 --- a/hydroflow_lang/src/graph/ops/dest_file.rs +++ b/hydroflow_lang/src/graph/ops/dest_file.rs @@ -32,6 +32,7 @@ pub const DEST_FILE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/dest_sink.rs b/hydroflow_lang/src/graph/ops/dest_sink.rs index 7493acee85b9..ee2f5b38d610 100644 --- a/hydroflow_lang/src/graph/ops/dest_sink.rs +++ b/hydroflow_lang/src/graph/ops/dest_sink.rs @@ -93,6 +93,7 @@ pub const DEST_SINK: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/dest_sink_serde.rs b/hydroflow_lang/src/graph/ops/dest_sink_serde.rs index a517655ae88e..78b8a7ceb5fb 100644 --- a/hydroflow_lang/src/graph/ops/dest_sink_serde.rs +++ b/hydroflow_lang/src/graph/ops/dest_sink_serde.rs @@ -35,6 +35,7 @@ pub const DEST_SINK_SERDE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/difference.rs b/hydroflow_lang/src/graph/ops/difference.rs index f626e86c5658..e2e8e83d2176 100644 --- a/hydroflow_lang/src/graph/ops/difference.rs +++ b/hydroflow_lang/src/graph/ops/difference.rs @@ -34,6 +34,7 @@ pub const DIFFERENCE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { pos, neg })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/difference_multiset.rs b/hydroflow_lang/src/graph/ops/difference_multiset.rs index 8c87e9991846..603ffe05f3de 100644 --- a/hydroflow_lang/src/graph/ops/difference_multiset.rs +++ b/hydroflow_lang/src/graph/ops/difference_multiset.rs @@ -35,6 +35,7 @@ pub const DIFFERENCE_MULTISET: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { pos, neg })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/enumerate.rs b/hydroflow_lang/src/graph/ops/enumerate.rs index e4ede20d40e7..c371870afc69 100644 --- a/hydroflow_lang/src/graph/ops/enumerate.rs +++ b/hydroflow_lang/src/graph/ops/enumerate.rs @@ -32,6 +32,7 @@ pub const ENUMERATE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/filter.rs b/hydroflow_lang/src/graph/ops/filter.rs index eea8150e1810..bb2906f93fe7 100644 --- a/hydroflow_lang/src/graph/ops/filter.rs +++ b/hydroflow_lang/src/graph/ops/filter.rs @@ -30,6 +30,7 @@ pub const FILTER: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/filter_map.rs b/hydroflow_lang/src/graph/ops/filter_map.rs index 0eb9a9d2bdfd..19f912849b1e 100644 --- a/hydroflow_lang/src/graph/ops/filter_map.rs +++ b/hydroflow_lang/src/graph/ops/filter_map.rs @@ -28,6 +28,7 @@ pub const FILTER_MAP: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/flat_map.rs b/hydroflow_lang/src/graph/ops/flat_map.rs index 94de32f24aaf..85aa66fb7ce5 100644 --- a/hydroflow_lang/src/graph/ops/flat_map.rs +++ b/hydroflow_lang/src/graph/ops/flat_map.rs @@ -32,6 +32,7 @@ pub const FLAT_MAP: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/flatten.rs b/hydroflow_lang/src/graph/ops/flatten.rs index 625a71d43195..533884da6570 100644 --- a/hydroflow_lang/src/graph/ops/flatten.rs +++ b/hydroflow_lang/src/graph/ops/flatten.rs @@ -27,6 +27,7 @@ pub const FLATTEN: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/fold.rs b/hydroflow_lang/src/graph/ops/fold.rs index 2cef16c6f2e8..7072b08c2a68 100644 --- a/hydroflow_lang/src/graph/ops/fold.rs +++ b/hydroflow_lang/src/graph/ops/fold.rs @@ -45,6 +45,7 @@ pub const FOLD: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: true, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/fold_keyed.rs b/hydroflow_lang/src/graph/ops/fold_keyed.rs index c4572cae6b70..f91e3d2deadc 100644 --- a/hydroflow_lang/src/graph/ops/fold_keyed.rs +++ b/hydroflow_lang/src/graph/ops/fold_keyed.rs @@ -80,6 +80,7 @@ pub const FOLD_KEYED: OperatorConstraints = OperatorConstraints { // to prevent reading uncleared data if this subgraph doesn't run. // https://github.com/hydro-project/hydroflow/issues/1298 has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/for_each.rs b/hydroflow_lang/src/graph/ops/for_each.rs index 601b079e874e..e087aa8eb149 100644 --- a/hydroflow_lang/src/graph/ops/for_each.rs +++ b/hydroflow_lang/src/graph/ops/for_each.rs @@ -30,6 +30,7 @@ pub const FOR_EACH: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/identity.rs b/hydroflow_lang/src/graph/ops/identity.rs index a55bab030c63..ffc1f44a4fcd 100644 --- a/hydroflow_lang/src/graph/ops/identity.rs +++ b/hydroflow_lang/src/graph/ops/identity.rs @@ -33,6 +33,7 @@ pub const IDENTITY: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/initialize.rs b/hydroflow_lang/src/graph/ops/initialize.rs index 877d655a121a..e7dbe0834658 100644 --- a/hydroflow_lang/src/graph/ops/initialize.rs +++ b/hydroflow_lang/src/graph/ops/initialize.rs @@ -26,6 +26,7 @@ pub const INITIALIZE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/inspect.rs b/hydroflow_lang/src/graph/ops/inspect.rs index d99576a703c0..bdf888d92a2d 100644 --- a/hydroflow_lang/src/graph/ops/inspect.rs +++ b/hydroflow_lang/src/graph/ops/inspect.rs @@ -31,6 +31,7 @@ pub const INSPECT: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/join.rs b/hydroflow_lang/src/graph/ops/join.rs index 874d9ceaa118..764dc9b8ea34 100644 --- a/hydroflow_lang/src/graph/ops/join.rs +++ b/hydroflow_lang/src/graph/ops/join.rs @@ -91,6 +91,7 @@ pub const JOIN: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/join_fused.rs b/hydroflow_lang/src/graph/ops/join_fused.rs index e7166086c53e..867310d674a1 100644 --- a/hydroflow_lang/src/graph/ops/join_fused.rs +++ b/hydroflow_lang/src/graph/ops/join_fused.rs @@ -100,6 +100,7 @@ pub const JOIN_FUSED: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/join_fused_lhs.rs b/hydroflow_lang/src/graph/ops/join_fused_lhs.rs index 9ecefbc730c3..198e0bdb0806 100644 --- a/hydroflow_lang/src/graph/ops/join_fused_lhs.rs +++ b/hydroflow_lang/src/graph/ops/join_fused_lhs.rs @@ -34,6 +34,7 @@ pub const JOIN_FUSED_LHS: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/join_fused_rhs.rs b/hydroflow_lang/src/graph/ops/join_fused_rhs.rs index 04aae55a5063..e6f819b340d9 100644 --- a/hydroflow_lang/src/graph/ops/join_fused_rhs.rs +++ b/hydroflow_lang/src/graph/ops/join_fused_rhs.rs @@ -21,6 +21,7 @@ pub const JOIN_FUSED_RHS: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |idx| match idx { diff --git a/hydroflow_lang/src/graph/ops/join_multiset.rs b/hydroflow_lang/src/graph/ops/join_multiset.rs index d5b446c71182..338dac329b60 100644 --- a/hydroflow_lang/src/graph/ops/join_multiset.rs +++ b/hydroflow_lang/src/graph/ops/join_multiset.rs @@ -37,6 +37,7 @@ pub const JOIN_MULTISET: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/lattice_bimorphism.rs b/hydroflow_lang/src/graph/ops/lattice_bimorphism.rs index 769af75c4fe5..176258ae3331 100644 --- a/hydroflow_lang/src/graph/ops/lattice_bimorphism.rs +++ b/hydroflow_lang/src/graph/ops/lattice_bimorphism.rs @@ -6,7 +6,40 @@ use super::{ RANGE_0, RANGE_1, }; -// TODO(mingwei): +/// An operator representing a [lattice bimorphism](https://hydro.run/docs/hydroflow/lattices_crate/lattice_math#lattice-bimorphism). +/// +/// > 2 input streams, of type `LhsItem` and `RhsItem`. +/// +/// > Three argument, one `LatticeBimorphism` function `Func`, an `LhsState` singleton reference, and an `RhsState` singleton reference. +/// +/// > 1 output stream of the output type of the `LatticeBimorphism` function. +/// +/// The function must be a lattice bimorphism for both `(LhsState, RhsItem)` and `(RhsState, LhsItem)`. +/// +/// ```hydroflow +/// use std::collections::HashSet; +/// use lattices::set_union::{CartesianProductBimorphism, SetUnionHashSet, SetUnionSingletonSet}; +/// +/// lhs = source_iter(0..3) +/// -> map(SetUnionSingletonSet::new_from) +/// -> state::<'static, SetUnionHashSet>(); +/// rhs = source_iter(3..5) +/// -> map(SetUnionSingletonSet::new_from) +/// -> state::<'static, SetUnionHashSet>(); +/// +/// lhs -> [0]my_join; +/// rhs -> [1]my_join; +/// +/// my_join = lattice_bimorphism(CartesianProductBimorphism::>::default(), #lhs, #rhs) +/// -> assert_eq([SetUnionHashSet::new(HashSet::from_iter([ +/// (0, 3), +/// (0, 4), +/// (1, 3), +/// (1, 4), +/// (2, 3), +/// (2, 4), +/// ]))]); +/// ``` pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { name: "lattice_bimorphism", categories: &[OperatorCategory::MultiIn], @@ -19,6 +52,7 @@ pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, @@ -53,7 +87,7 @@ pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { lhs_state_handle: #root::scheduled::state::StateHandle<::std::cell::RefCell>, rhs_state_handle: #root::scheduled::state::StateHandle<::std::cell::RefCell>, context: &'a #root::scheduled::context::Context, - ) -> impl 'a + ::std::iter::Iterator + ) -> Option where Func: 'a + #root::lattices::LatticeBimorphism @@ -62,11 +96,12 @@ pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { RhsIter: 'a + ::std::iter::Iterator, LhsState: 'static + ::std::clone::Clone, RhsState: 'static + ::std::clone::Clone, + Output: #root::lattices::Merge, { let lhs_state = context.state_ref(lhs_state_handle); let rhs_state = context.state_ref(rhs_state_handle); - ::std::iter::from_fn(move || { + let iter = ::std::iter::from_fn(move || { // Use `from_fn` instead of `chain` to dodge multiple ownership of `func`. if let Some(lhs_item) = lhs_iter.next() { Some(func.call(lhs_item, (*rhs_state.borrow()).clone())) @@ -74,7 +109,8 @@ pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { let rhs_item = rhs_iter.next()?; Some(func.call((*lhs_state.borrow()).clone(), rhs_item)) } - }) + }); + iter.reduce(|a, b| #root::lattices::Merge::merge_owned(a, b)) } check_inputs( #func, @@ -83,7 +119,7 @@ pub const LATTICE_BIMORPHISM: OperatorConstraints = OperatorConstraints { #lhs_state_handle, #rhs_state_handle, &#context, - ) + ).into_iter() }; }; diff --git a/hydroflow_lang/src/graph/ops/lattice_fold.rs b/hydroflow_lang/src/graph/ops/lattice_fold.rs index 5475c7303138..8d85945451eb 100644 --- a/hydroflow_lang/src/graph/ops/lattice_fold.rs +++ b/hydroflow_lang/src/graph/ops/lattice_fold.rs @@ -39,6 +39,7 @@ pub const LATTICE_FOLD: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::MonotoneAccum), diff --git a/hydroflow_lang/src/graph/ops/lattice_reduce.rs b/hydroflow_lang/src/graph/ops/lattice_reduce.rs index 2d5731769c98..a38a7dc2481f 100644 --- a/hydroflow_lang/src/graph/ops/lattice_reduce.rs +++ b/hydroflow_lang/src/graph/ops/lattice_reduce.rs @@ -40,6 +40,7 @@ pub const LATTICE_REDUCE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::MonotoneAccum), diff --git a/hydroflow_lang/src/graph/ops/map.rs b/hydroflow_lang/src/graph/ops/map.rs index ed49fe48bbe5..bd03ada64c5f 100644 --- a/hydroflow_lang/src/graph/ops/map.rs +++ b/hydroflow_lang/src/graph/ops/map.rs @@ -32,6 +32,7 @@ pub const MAP: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/mod.rs b/hydroflow_lang/src/graph/ops/mod.rs index 2843e2f5b0d3..c4c35ce02065 100644 --- a/hydroflow_lang/src/graph/ops/mod.rs +++ b/hydroflow_lang/src/graph/ops/mod.rs @@ -70,6 +70,8 @@ pub struct OperatorConstraints { /// If true, [`WriteContextArgs::singleton_output_ident`] will be set to a meaningful value in /// the [`Self::write_fn`] invocation. pub has_singleton_output: bool, + /// Flo semantics type. + pub flo_type: Option, /// What named or numbered input ports to expect? pub ports_inn: Option PortListSpec>, @@ -240,10 +242,13 @@ macro_rules! declare_ops { }; } declare_ops![ + all_once::ALL_ONCE, anti_join::ANTI_JOIN, anti_join_multiset::ANTI_JOIN_MULTISET, assert::ASSERT, assert_eq::ASSERT_EQ, + batch::BATCH, + chain::CHAIN, cross_join::CROSS_JOIN, cross_join_multiset::CROSS_JOIN_MULTISET, cross_singleton::CROSS_SINGLETON, @@ -495,6 +500,8 @@ pub enum OperatorCategory { Sink, Control, CompilerFusionOperator, + Windowing, + Unwindowing, } impl OperatorCategory { /// Human-readible heading name, for docs. @@ -513,6 +520,8 @@ impl OperatorCategory { OperatorCategory::Sink => "Sinks", OperatorCategory::Control => "Control Flow Operators", OperatorCategory::CompilerFusionOperator => "Compiler Fusion Operators", + OperatorCategory::Windowing => "Windowing Operator", + OperatorCategory::Unwindowing => "Un-Windowing Operator", } } /// Human description, for docs. @@ -537,6 +546,19 @@ impl OperatorCategory { OperatorCategory::CompilerFusionOperator => { "Operators which are necessary to implement certain optimizations and rewrite rules" } + OperatorCategory::Windowing => "Operators for windowing `loop` inputs.", + OperatorCategory::Unwindowing => "Operators for collecting `loop` outputs.", } } } + +/// Operator type for Flo semantics. +#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug)] +pub enum FloType { + /// A source operator, which must be at the top level. + Source, + /// A windowing operator, for moving data into a loop context. + Windowing, + /// An un-windowing operator, for moving data out of a loop context. + Unwindowing, +} diff --git a/hydroflow_lang/src/graph/ops/multiset_delta.rs b/hydroflow_lang/src/graph/ops/multiset_delta.rs index dd47834cf2b9..46e34da6f33c 100644 --- a/hydroflow_lang/src/graph/ops/multiset_delta.rs +++ b/hydroflow_lang/src/graph/ops/multiset_delta.rs @@ -46,6 +46,7 @@ pub const MULTISET_DELTA: OperatorConstraints = OperatorConstraints { // https://github.com/hydro-project/hydroflow/issues/1298 // If `'tick` lifetimes are added. has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/next_stratum.rs b/hydroflow_lang/src/graph/ops/next_stratum.rs index 0a6238f5544e..318a3bcd5e6b 100644 --- a/hydroflow_lang/src/graph/ops/next_stratum.rs +++ b/hydroflow_lang/src/graph/ops/next_stratum.rs @@ -20,6 +20,7 @@ pub const NEXT_STRATUM: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/null.rs b/hydroflow_lang/src/graph/ops/null.rs index 73ae3f48e3d8..45f574e2c3d3 100644 --- a/hydroflow_lang/src/graph/ops/null.rs +++ b/hydroflow_lang/src/graph/ops/null.rs @@ -26,6 +26,7 @@ pub const NULL: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/partition.rs b/hydroflow_lang/src/graph/ops/partition.rs index 1f1fddb83512..d232ffd12e9a 100644 --- a/hydroflow_lang/src/graph/ops/partition.rs +++ b/hydroflow_lang/src/graph/ops/partition.rs @@ -65,6 +65,7 @@ pub const PARTITION: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: Some(|| PortListSpec::Variadic), input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/persist.rs b/hydroflow_lang/src/graph/ops/persist.rs index 187f571e5693..4f3f41d5decf 100644 --- a/hydroflow_lang/src/graph/ops/persist.rs +++ b/hydroflow_lang/src/graph/ops/persist.rs @@ -48,6 +48,7 @@ pub const PERSIST: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: true, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/persist_mut.rs b/hydroflow_lang/src/graph/ops/persist_mut.rs index 08c0b5f627d9..822d98b30e9e 100644 --- a/hydroflow_lang/src/graph/ops/persist_mut.rs +++ b/hydroflow_lang/src/graph/ops/persist_mut.rs @@ -39,6 +39,7 @@ pub const PERSIST_MUT: OperatorConstraints = OperatorConstraints { // https://github.com/hydro-project/hydroflow/issues/1298 // If `'tick` lifetimes are added. has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/persist_mut_keyed.rs b/hydroflow_lang/src/graph/ops/persist_mut_keyed.rs index a0cf662ed8a7..6e97e74b95cb 100644 --- a/hydroflow_lang/src/graph/ops/persist_mut_keyed.rs +++ b/hydroflow_lang/src/graph/ops/persist_mut_keyed.rs @@ -39,6 +39,7 @@ pub const PERSIST_MUT_KEYED: OperatorConstraints = OperatorConstraints { // https://github.com/hydro-project/hydroflow/issues/1298 // If `'tick` lifetimes are added. has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/py_udf.rs b/hydroflow_lang/src/graph/ops/py_udf.rs index 7b2bc0adb8f8..67901a58d0c7 100644 --- a/hydroflow_lang/src/graph/ops/py_udf.rs +++ b/hydroflow_lang/src/graph/ops/py_udf.rs @@ -62,6 +62,7 @@ pub const PY_UDF: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/reduce.rs b/hydroflow_lang/src/graph/ops/reduce.rs index 53530b2d49b4..03b16c2e4c09 100644 --- a/hydroflow_lang/src/graph/ops/reduce.rs +++ b/hydroflow_lang/src/graph/ops/reduce.rs @@ -43,6 +43,7 @@ pub const REDUCE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: true, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/reduce_keyed.rs b/hydroflow_lang/src/graph/ops/reduce_keyed.rs index 611bad6b1c6d..bf1fe2f8b4c7 100644 --- a/hydroflow_lang/src/graph/ops/reduce_keyed.rs +++ b/hydroflow_lang/src/graph/ops/reduce_keyed.rs @@ -70,6 +70,7 @@ pub const REDUCE_KEYED: OperatorConstraints = OperatorConstraints { // to prevent reading uncleared data if this subgraph doesn't run. // https://github.com/hydro-project/hydroflow/issues/1298 has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/sort.rs b/hydroflow_lang/src/graph/ops/sort.rs index a516e4e6368f..e10349b180a9 100644 --- a/hydroflow_lang/src/graph/ops/sort.rs +++ b/hydroflow_lang/src/graph/ops/sort.rs @@ -27,6 +27,7 @@ pub const SORT: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/sort_by_key.rs b/hydroflow_lang/src/graph/ops/sort_by_key.rs index 967da1027f73..1e7aacb603c2 100644 --- a/hydroflow_lang/src/graph/ops/sort_by_key.rs +++ b/hydroflow_lang/src/graph/ops/sort_by_key.rs @@ -27,6 +27,7 @@ pub const SORT_BY_KEY: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/graph/ops/source_file.rs b/hydroflow_lang/src/graph/ops/source_file.rs index 604da35ffbfb..664e9ec89640 100644 --- a/hydroflow_lang/src/graph/ops/source_file.rs +++ b/hydroflow_lang/src/graph/ops/source_file.rs @@ -2,8 +2,8 @@ use quote::quote_spanned; use syn::parse_quote_spanned; use super::{ - make_missing_runtime_msg, OperatorCategory, OperatorConstraints, - OperatorWriteOutput, WriteContextArgs, RANGE_0, RANGE_1, + make_missing_runtime_msg, FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, + WriteContextArgs, RANGE_0, RANGE_1, }; /// > 0 input streams, 1 output stream @@ -30,6 +30,7 @@ pub const SOURCE_FILE: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_interval.rs b/hydroflow_lang/src/graph/ops/source_interval.rs index e1759023c7df..4f77fd526958 100644 --- a/hydroflow_lang/src/graph/ops/source_interval.rs +++ b/hydroflow_lang/src/graph/ops/source_interval.rs @@ -2,8 +2,8 @@ use quote::quote_spanned; use syn::parse_quote_spanned; use super::{ - OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, - RANGE_0, RANGE_1, + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, + RANGE_1, }; /// > 0 input streams, 1 output stream @@ -54,6 +54,7 @@ pub const SOURCE_INTERVAL: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_iter.rs b/hydroflow_lang/src/graph/ops/source_iter.rs index 74dce7bf2d50..ca5a299b9c32 100644 --- a/hydroflow_lang/src/graph/ops/source_iter.rs +++ b/hydroflow_lang/src/graph/ops/source_iter.rs @@ -1,8 +1,7 @@ use quote::quote_spanned; use super::{ - OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, - RANGE_0, RANGE_1, + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, RANGE_1 }; /// > 0 input streams, 1 output stream @@ -30,6 +29,7 @@ pub const SOURCE_ITER: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_json.rs b/hydroflow_lang/src/graph/ops/source_json.rs index 40cc97cccc60..890a25372aac 100644 --- a/hydroflow_lang/src/graph/ops/source_json.rs +++ b/hydroflow_lang/src/graph/ops/source_json.rs @@ -1,7 +1,7 @@ use quote::quote_spanned; use super::{ - OpInstGenerics, OperatorCategory, OperatorConstraints, OperatorInstance, + FloType, OpInstGenerics, OperatorCategory, OperatorConstraints, OperatorInstance, OperatorWriteOutput, WriteContextArgs, RANGE_0, RANGE_1, }; @@ -27,6 +27,7 @@ pub const SOURCE_JSON: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_stdin.rs b/hydroflow_lang/src/graph/ops/source_stdin.rs index af5d8a17cc67..4a788eecc9e6 100644 --- a/hydroflow_lang/src/graph/ops/source_stdin.rs +++ b/hydroflow_lang/src/graph/ops/source_stdin.rs @@ -1,8 +1,8 @@ use quote::quote_spanned; use super::{ - OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, - RANGE_0, RANGE_1, + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, + RANGE_1, }; /// > 0 input streams, 1 output stream @@ -29,6 +29,7 @@ pub const SOURCE_STDIN: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_stream.rs b/hydroflow_lang/src/graph/ops/source_stream.rs index f5610dfbeb32..8a5b7f392e3a 100644 --- a/hydroflow_lang/src/graph/ops/source_stream.rs +++ b/hydroflow_lang/src/graph/ops/source_stream.rs @@ -1,8 +1,8 @@ use quote::quote_spanned; use super::{ - OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, - RANGE_0, RANGE_1, + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, + RANGE_1, }; /// > 0 input streams, 1 output stream @@ -36,6 +36,7 @@ pub const SOURCE_STREAM: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/source_stream_serde.rs b/hydroflow_lang/src/graph/ops/source_stream_serde.rs index cb0d7003522f..4c4fbf51d6f8 100644 --- a/hydroflow_lang/src/graph/ops/source_stream_serde.rs +++ b/hydroflow_lang/src/graph/ops/source_stream_serde.rs @@ -1,8 +1,8 @@ use quote::quote_spanned; use super::{ - OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, - RANGE_0, RANGE_1, + FloType, OperatorCategory, OperatorConstraints, OperatorWriteOutput, WriteContextArgs, RANGE_0, + RANGE_1, }; /// > 0 input streams, 1 output stream @@ -36,6 +36,7 @@ pub const SOURCE_STREAM_SERDE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: true, has_singleton_output: false, + flo_type: Some(FloType::Source), ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/spin.rs b/hydroflow_lang/src/graph/ops/spin.rs index b943cb09ac9e..c686d03d0c95 100644 --- a/hydroflow_lang/src/graph/ops/spin.rs +++ b/hydroflow_lang/src/graph/ops/spin.rs @@ -29,6 +29,7 @@ pub const SPIN: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/state.rs b/hydroflow_lang/src/graph/ops/state.rs index b2c830916afe..ddcf213af446 100644 --- a/hydroflow_lang/src/graph/ops/state.rs +++ b/hydroflow_lang/src/graph/ops/state.rs @@ -31,6 +31,7 @@ pub const STATE: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: true, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/state_by.rs b/hydroflow_lang/src/graph/ops/state_by.rs index f067059ab514..d676c5fc8439 100644 --- a/hydroflow_lang/src/graph/ops/state_by.rs +++ b/hydroflow_lang/src/graph/ops/state_by.rs @@ -32,6 +32,7 @@ pub const STATE_BY: OperatorConstraints = OperatorConstraints { type_args: &(0..=1), is_external_input: false, has_singleton_output: true, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/tee.rs b/hydroflow_lang/src/graph/ops/tee.rs index fcbf0a182d6d..01641044f328 100644 --- a/hydroflow_lang/src/graph/ops/tee.rs +++ b/hydroflow_lang/src/graph/ops/tee.rs @@ -28,6 +28,7 @@ pub const TEE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/union.rs b/hydroflow_lang/src/graph/ops/union.rs index dbc8e6af4077..ae59c8053164 100644 --- a/hydroflow_lang/src/graph/ops/union.rs +++ b/hydroflow_lang/src/graph/ops/union.rs @@ -32,6 +32,7 @@ pub const UNION: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/unique.rs b/hydroflow_lang/src/graph/ops/unique.rs index 8dbc63d2a111..28b44a049e4f 100644 --- a/hydroflow_lang/src/graph/ops/unique.rs +++ b/hydroflow_lang/src/graph/ops/unique.rs @@ -54,6 +54,7 @@ pub const UNIQUE: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/unzip.rs b/hydroflow_lang/src/graph/ops/unzip.rs index 272df573983d..ac3f04d21461 100644 --- a/hydroflow_lang/src/graph/ops/unzip.rs +++ b/hydroflow_lang/src/graph/ops/unzip.rs @@ -28,6 +28,7 @@ pub const UNZIP: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: None, ports_out: Some(|| super::PortListSpec::Fixed(parse_quote!(0, 1))), input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/zip.rs b/hydroflow_lang/src/graph/ops/zip.rs index 1cb58f85316d..290d642cc098 100644 --- a/hydroflow_lang/src/graph/ops/zip.rs +++ b/hydroflow_lang/src/graph/ops/zip.rs @@ -30,6 +30,7 @@ pub const ZIP: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| None, diff --git a/hydroflow_lang/src/graph/ops/zip_longest.rs b/hydroflow_lang/src/graph/ops/zip_longest.rs index db07f791bd55..1ed5e5c51af6 100644 --- a/hydroflow_lang/src/graph/ops/zip_longest.rs +++ b/hydroflow_lang/src/graph/ops/zip_longest.rs @@ -34,6 +34,7 @@ pub const ZIP_LONGEST: OperatorConstraints = OperatorConstraints { type_args: RANGE_0, is_external_input: false, has_singleton_output: false, + flo_type: None, ports_inn: Some(|| super::PortListSpec::Fixed(parse_quote! { 0, 1 })), ports_out: None, input_delaytype_fn: |_| Some(DelayType::Stratum), diff --git a/hydroflow_lang/src/parse.rs b/hydroflow_lang/src/parse.rs index cca523c9b34a..e08fdda44b9d 100644 --- a/hydroflow_lang/src/parse.rs +++ b/hydroflow_lang/src/parse.rs @@ -8,10 +8,10 @@ use proc_macro2::{Span, TokenStream}; use quote::ToTokens; use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; -use syn::token::{Bracket, Paren}; +use syn::token::{Brace, Bracket, Paren}; use syn::{ - bracketed, parenthesized, AngleBracketedGenericArguments, Expr, ExprPath, GenericArgument, - Ident, ItemUse, LitInt, LitStr, Path, PathArguments, PathSegment, Token, + braced, bracketed, parenthesized, AngleBracketedGenericArguments, Expr, ExprPath, + GenericArgument, Ident, ItemUse, LitInt, LitStr, Path, PathArguments, PathSegment, Token, }; use crate::process_singletons::preprocess_singletons; @@ -40,24 +40,45 @@ pub enum HfStatement { Use(ItemUse), Named(NamedHfStatement), Pipeline(PipelineStatement), + Loop(LoopStatement), } impl Parse for HfStatement { fn parse(input: ParseStream) -> syn::Result { - if input.peek(Token![use]) { + let lookahead1 = input.lookahead1(); + if lookahead1.peek(Token![use]) { Ok(Self::Use(ItemUse::parse(input)?)) - } else if input.peek2(Token![=]) { - Ok(Self::Named(NamedHfStatement::parse(input)?)) - } else { + } else if lookahead1.peek(Paren) || lookahead1.peek(Bracket) || lookahead1.peek(Token![mod]) + { Ok(Self::Pipeline(PipelineStatement::parse(input)?)) + } else if lookahead1.peek(Token![loop]) { + Ok(Self::Loop(LoopStatement::parse(input)?)) + } else if lookahead1.peek(Ident) { + let fork = input.fork(); + let _: Path = fork.parse()?; + let lookahead2 = fork.lookahead1(); + if lookahead2.peek(Token![=]) { + Ok(Self::Named(NamedHfStatement::parse(input)?)) + } else if lookahead2.peek(Token![->]) + || lookahead2.peek(Paren) + || lookahead2.peek(Bracket) + || lookahead2.peek(Token![!]) + { + Ok(Self::Pipeline(PipelineStatement::parse(input)?)) + } else { + Err(lookahead2.error()) + } + } else { + Err(lookahead1.error()) } } } impl ToTokens for HfStatement { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - HfStatement::Use(x) => x.to_tokens(tokens), - HfStatement::Named(x) => x.to_tokens(tokens), - HfStatement::Pipeline(x) => x.to_tokens(tokens), + Self::Use(x) => x.to_tokens(tokens), + Self::Named(x) => x.to_tokens(tokens), + Self::Pipeline(x) => x.to_tokens(tokens), + Self::Loop(x) => x.to_tokens(tokens), } } } @@ -197,13 +218,49 @@ impl Parse for Pipeline { impl ToTokens for Pipeline { fn to_tokens(&self, tokens: &mut TokenStream) { match self { - Pipeline::Paren(x) => x.to_tokens(tokens), - Pipeline::Link(x) => x.to_tokens(tokens), - Pipeline::Name(x) => x.to_tokens(tokens), - Pipeline::Operator(x) => x.to_tokens(tokens), - Pipeline::ModuleBoundary(x) => x.to_tokens(tokens), - Pipeline::Import(x) => x.to_tokens(tokens), + Self::Paren(x) => x.to_tokens(tokens), + Self::Link(x) => x.to_tokens(tokens), + Self::Name(x) => x.to_tokens(tokens), + Self::Operator(x) => x.to_tokens(tokens), + Self::ModuleBoundary(x) => x.to_tokens(tokens), + Self::Import(x) => x.to_tokens(tokens), + } + } +} + +pub struct LoopStatement { + pub loop_token: Token![loop], + pub ident: Option, + pub brace_token: Brace, + pub statements: Vec, +} +impl Parse for LoopStatement { + fn parse(input: ParseStream) -> syn::Result { + let loop_token = input.parse()?; + let ident = input.parse()?; + let content; + let brace_token = braced!(content in input); + let mut statements = Vec::new(); + while !content.is_empty() { + statements.push(content.parse()?); } + Ok(Self { + loop_token, + ident, + brace_token, + statements, + }) + } +} +impl ToTokens for LoopStatement { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.loop_token.to_tokens(tokens); + self.ident.to_tokens(tokens); + self.brace_token.surround(tokens, |tokens| { + for statement in self.statements.iter() { + statement.to_tokens(tokens); + } + }); } } diff --git a/hydroflow_macro/CHANGELOG.md b/hydroflow_macro/CHANGELOG.md index 8d47bde8ee0b..574b4e2cd328 100644 --- a/hydroflow_macro/CHANGELOG.md +++ b/hydroflow_macro/CHANGELOG.md @@ -5,8 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.10.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.9.0 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -22,7 +49,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 2 commits contributed to the release. + - 3 commits contributed to the release. + - 38 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1409](https://github.com/hydro-project/hydroflow/issues/1409), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -36,6 +64,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow `demux_enum` to have any number of outputs, fix #1329 ([`9e5f58e`](https://github.com/hydro-project/hydroflow/commit/9e5f58ef773f0aee39a9705d9845361a2488649b)) * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.8.0 (2024-07-23) @@ -53,6 +83,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 59 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -80,6 +111,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 83 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1204](https://github.com/hydro-project/hydroflow/issues/1204) @@ -110,6 +142,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 28 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -136,6 +169,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 4 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1041](https://github.com/hydro-project/hydroflow/issues/1041) @@ -176,12 +210,15 @@ Unchanged from previous release. -- - new implementation and Hydro Deploy setup -- + - new implementation and Hydro Deploy setup + -- ### Commit Statistics - 3 commits contributed to the release. + - 110 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#909](https://github.com/hydro-project/hydroflow/issues/909) @@ -235,6 +272,7 @@ Unchanged from previous release. - 11 commits contributed to the release. + - 56 days passed between releases. - 9 commits were understood as [conventional](https://www.conventionalcommits.org). - 6 unique issues were worked on: [#881](https://github.com/hydro-project/hydroflow/issues/881), [#882](https://github.com/hydro-project/hydroflow/issues/882), [#884](https://github.com/hydro-project/hydroflow/issues/884), [#898](https://github.com/hydro-project/hydroflow/issues/898), [#932](https://github.com/hydro-project/hydroflow/issues/932), [#938](https://github.com/hydro-project/hydroflow/issues/938) @@ -276,6 +314,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 42 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#845](https://github.com/hydro-project/hydroflow/issues/845) @@ -314,6 +353,7 @@ Unchanged from previous release. - 5 commits contributed to the release. + - 33 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#758](https://github.com/hydro-project/hydroflow/issues/758), [#780](https://github.com/hydro-project/hydroflow/issues/780), [#801](https://github.com/hydro-project/hydroflow/issues/801) @@ -360,6 +400,7 @@ Unchanged from previous release. - 5 commits contributed to the release. + - 1 day passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#728](https://github.com/hydro-project/hydroflow/issues/728), [#730](https://github.com/hydro-project/hydroflow/issues/730) @@ -391,6 +432,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 6 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#686](https://github.com/hydro-project/hydroflow/issues/686) @@ -424,6 +466,7 @@ Unchanged from previous release. - 5 commits contributed to the release. + - 2 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#661](https://github.com/hydro-project/hydroflow/issues/661), [#671](https://github.com/hydro-project/hydroflow/issues/671), [#677](https://github.com/hydro-project/hydroflow/issues/677), [#684](https://github.com/hydro-project/hydroflow/issues/684) @@ -458,6 +501,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 25 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#643](https://github.com/hydro-project/hydroflow/issues/643), [#660](https://github.com/hydro-project/hydroflow/issues/660) diff --git a/hydroflow_macro/Cargo.toml b/hydroflow_macro/Cargo.toml index bf7f97434a8b..947cd24a997e 100644 --- a/hydroflow_macro/Cargo.toml +++ b/hydroflow_macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "hydroflow_macro" publish = true -version = "0.9.0" +version = "0.10.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/hydroflow_macro/" @@ -20,13 +20,13 @@ diagnostics = [ "hydroflow_lang/diagnostics" ] # Note: If we ever compile this proc macro crate to WASM (e.g., if we are # building on a WASM host), we may need to turn diagnostics off for WASM if # proc_macro2 still does not support WASM. -hydroflow_lang = { path = "../hydroflow_lang", version = "^0.9.0" } +hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0" } proc-macro2 = "1.0.74" proc-macro-crate = "1.0.0" quote = "1.0.35" syn = { version = "2.0.46", features = [ "parsing", "extra-traits" ] } [build-dependencies] -hydroflow_lang = { path = "../hydroflow_lang", version = "^0.9.0" } +hydroflow_lang = { path = "../hydroflow_lang", version = "^0.10.0" } itertools = "0.10.0" quote = "1.0.35" diff --git a/hydroflow_macro/build.rs b/hydroflow_macro/build.rs index d630504d1a82..adf5e9459b2f 100644 --- a/hydroflow_macro/build.rs +++ b/hydroflow_macro/build.rs @@ -3,7 +3,7 @@ use std::env::VarError; use std::fmt::Write as _FmtWrite; use std::fs::File; -use std::io::{BufReader, BufWriter, Result, Write}; +use std::io::{BufWriter, Read, Result, Write}; use std::path::{Path, PathBuf}; use hydroflow_lang::graph::ops::{PortListSpec, OPERATORS}; @@ -26,14 +26,22 @@ fn book_file_writer(filename: impl AsRef) -> Result> { Ok(BufWriter::new(File::create(pathbuf)?)) } -fn write_operator_docgen(op_name: &str, mut write: &mut impl Write) -> Result<()> { +fn write_operator_docgen(op_name: &str, write: &mut impl Write) -> Result<()> { let doctest_path = PathBuf::from_iter([ std::env!("CARGO_MANIFEST_DIR"), "../docs/docgen", &*format!("{}.md", op_name), ]); - let mut read = BufReader::new(File::open(doctest_path)?); - std::io::copy(&mut read, &mut write)?; + let mut read_string = String::new(); + File::open(doctest_path)?.read_to_string(&mut read_string)?; + write!( + write, + "{}", + read_string + .split(" tests/compile-fail/send_bincode_lifetime.rs:7:5 + | +6 | fn test<'a, 'b>(p1: &Process<'a, P1>, p2: &Process<'b, P2>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +7 | p1.source_iter(q!(0..10)).send_bincode(p2).for_each(q!(|n| println!("{}", n))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b` + | + = help: consider adding the following bound: `'a: 'b` + = note: requirement occurs because of the type `hydroflow_plus::Process<'_, P1>`, which makes the generic argument `'_` invariant + = note: the struct `hydroflow_plus::Process<'a, P>` is invariant over the parameter `'a` + = help: see for more information about variance + +error: lifetime may not live long enough + --> tests/compile-fail/send_bincode_lifetime.rs:7:5 + | +6 | fn test<'a, 'b>(p1: &Process<'a, P1>, p2: &Process<'b, P2>) { + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +7 | p1.source_iter(q!(0..10)).send_bincode(p2).for_each(q!(|n| println!("{}", n))); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must outlive `'a` + | + = help: consider adding the following bound: `'b: 'a` + = note: requirement occurs because of the type `hydroflow_plus::Process<'_, P2>`, which makes the generic argument `'_` invariant + = note: the struct `hydroflow_plus::Process<'a, P>` is invariant over the parameter `'a` + = help: see for more information about variance + +help: `'a` and `'b` must be the same: replace one with the other diff --git a/hydroflow_plus/tests/compile_fail.rs b/hydroflow_plus/tests/compile_fail.rs new file mode 100644 index 000000000000..39816f304b6b --- /dev/null +++ b/hydroflow_plus/tests/compile_fail.rs @@ -0,0 +1,5 @@ +#[test] +fn test_all() { + let t = trybuild::TestCases::new(); + t.compile_fail("tests/compile-fail/*.rs"); +} diff --git a/hydroflow_plus_test/Cargo.toml b/hydroflow_plus_test/Cargo.toml index 471cbd781d04..6d57e17ebbe1 100644 --- a/hydroflow_plus_test/Cargo.toml +++ b/hydroflow_plus_test/Cargo.toml @@ -12,18 +12,18 @@ default = ["stageleft_devel"] stageleft_devel = [] [dependencies] -hydroflow_plus = { path = "../hydroflow_plus", version = "^0.9.0" } +hydroflow_plus = { path = "../hydroflow_plus", version = "^0.10.0" } tokio = { version = "1.29.0", features = [ "full" ] } -stageleft = { path = "../stageleft", version = "^0.4.0" } +stageleft = { path = "../stageleft", version = "^0.5.0" } rand = "0.8.0" serde = { version = "1.0.197", features = [ "derive" ] } [build-dependencies] -stageleft_tool = { path = "../stageleft_tool", version = "^0.3.0" } +stageleft_tool = { path = "../stageleft_tool", version = "^0.4.0" } [dev-dependencies] insta = "1.39" -hydro_deploy = { path = "../hydro_deploy/core", version = "^0.9.0" } -hydroflow_plus = { path = "../hydroflow_plus", version = "^0.9.0", features = [ "deploy" ] } +hydro_deploy = { path = "../hydro_deploy/core", version = "^0.10.0" } +hydroflow_plus = { path = "../hydroflow_plus", version = "^0.10.0", features = [ "deploy" ] } futures = "0.3.0" async-ssh2-lite = { version = "0.5.0", features = ["vendored-openssl"] } diff --git a/hydroflow_plus_test/examples/compute_pi.rs b/hydroflow_plus_test/examples/compute_pi.rs index 37c02da439f3..69ec6df97425 100644 --- a/hydroflow_plus_test/examples/compute_pi.rs +++ b/hydroflow_plus_test/examples/compute_pi.rs @@ -42,16 +42,13 @@ async fn main() { let (cluster, leader) = hydroflow_plus_test::cluster::compute_pi::compute_pi(&builder, 8192); let _nodes = builder - .with_default_optimize() .with_process( &leader, TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags), ) .with_cluster( &cluster, - (0..8) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + (0..8).map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .deploy(&mut deployment); diff --git a/hydroflow_plus_test/examples/first_ten_distributed.rs b/hydroflow_plus_test/examples/first_ten_distributed.rs index 6716c6fa52b4..2963b1bc0e96 100644 --- a/hydroflow_plus_test/examples/first_ten_distributed.rs +++ b/hydroflow_plus_test/examples/first_ten_distributed.rs @@ -40,10 +40,12 @@ async fn main() { }; let builder = hydroflow_plus::FlowBuilder::new(); - let (external_process, external_port, p1, p2) = - hydroflow_plus_test::distributed::first_ten::first_ten_distributed(&builder); + let external = builder.external_process(); + let p1 = builder.process(); + let p2 = builder.process(); + let external_port = + hydroflow_plus_test::distributed::first_ten::first_ten_distributed(&external, &p1, &p2); let nodes = builder - .with_default_optimize() .with_process( &p1, TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags), @@ -52,7 +54,7 @@ async fn main() { &p2, TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags), ) - .with_external(&external_process, deployment.Localhost() as Arc) + .with_external(&external, deployment.Localhost()) .deploy(&mut deployment); deployment.deploy().await.unwrap(); diff --git a/hydroflow_plus_test/examples/map_reduce.rs b/hydroflow_plus_test/examples/map_reduce.rs index c18d9c59bb52..960fc032277b 100644 --- a/hydroflow_plus_test/examples/map_reduce.rs +++ b/hydroflow_plus_test/examples/map_reduce.rs @@ -41,16 +41,13 @@ async fn main() { let builder = hydroflow_plus::FlowBuilder::new(); let (leader, cluster) = hydroflow_plus_test::cluster::map_reduce::map_reduce(&builder); let _nodes = builder - .with_default_optimize() .with_process( &leader, TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags), ) .with_cluster( &cluster, - (0..2) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + (0..2).map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .deploy(&mut deployment); diff --git a/hydroflow_plus_test/examples/paxos.rs b/hydroflow_plus_test/examples/paxos.rs index 31c34cb39beb..90bf86299b7a 100644 --- a/hydroflow_plus_test/examples/paxos.rs +++ b/hydroflow_plus_test/examples/paxos.rs @@ -56,30 +56,25 @@ async fn main() { let rustflags = "-C opt-level=3 -C codegen-units=1 -C strip=none -C debuginfo=2 -C lto=off"; let _nodes = builder - .with_default_optimize() .with_cluster( &proposers, (0..f + 1) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .with_cluster( &acceptors, (0..2 * f + 1) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .with_cluster( &clients, (0..num_clients) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .with_cluster( &replicas, (0..f + 1) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .deploy(&mut deployment); diff --git a/hydroflow_plus_test/examples/perf_compute_pi.rs b/hydroflow_plus_test/examples/perf_compute_pi.rs index 56d8db5a9746..da9e491ec632 100644 --- a/hydroflow_plus_test/examples/perf_compute_pi.rs +++ b/hydroflow_plus_test/examples/perf_compute_pi.rs @@ -45,13 +45,11 @@ async fn main() { let (cluster, leader) = hydroflow_plus_test::cluster::compute_pi::compute_pi(&builder, 8192); // Uncomment below, change .bin("counter_compute_pi") in order to track cardinality per operation - // let runtime_context = builder.runtime_context(); // dbg!(builder.with_default_optimize() - // .optimize_with(|ir| profiling(ir, runtime_context, RuntimeData::new("FAKE"), RuntimeData::new("FAKE"))) + // .optimize_with(|ir| profiling(ir, RuntimeData::new("FAKE"), RuntimeData::new("FAKE"))) // .ir()); let _nodes = builder - .with_default_optimize() .with_process( &leader, TrybuildHost::new(create_host(&mut deployment)) @@ -68,21 +66,19 @@ async fn main() { ) .with_cluster( &cluster, - (0..8) - .map(|idx| { - TrybuildHost::new(create_host(&mut deployment)) - .rustflags(rustflags) - .tracing( - TracingOptions::builder() - .perf_raw_outfile(format!("cluster{}.perf.data", idx)) - .dtrace_outfile(format!("cluster{}.leader.stacks", idx)) - .fold_outfile(format!("cluster{}.data.folded", idx)) - .flamegraph_outfile(format!("cluster{}.svg", idx)) - .frequency(128) - .build(), - ) - }) - .collect::>(), + (0..8).map(|idx| { + TrybuildHost::new(create_host(&mut deployment)) + .rustflags(rustflags) + .tracing( + TracingOptions::builder() + .perf_raw_outfile(format!("cluster{}.perf.data", idx)) + .dtrace_outfile(format!("cluster{}.leader.stacks", idx)) + .fold_outfile(format!("cluster{}.data.folded", idx)) + .flamegraph_outfile(format!("cluster{}.svg", idx)) + .frequency(128) + .build(), + ) + }), ) .deploy(&mut deployment); deployment.run_ctrl_c().await.unwrap(); diff --git a/hydroflow_plus_test/examples/simple_cluster.rs b/hydroflow_plus_test/examples/simple_cluster.rs index e1c22b702f45..05fe9ea71508 100644 --- a/hydroflow_plus_test/examples/simple_cluster.rs +++ b/hydroflow_plus_test/examples/simple_cluster.rs @@ -42,16 +42,13 @@ async fn main() { let (process, cluster) = hydroflow_plus_test::cluster::simple_cluster::simple_cluster(&builder); let _nodes = builder - .with_default_optimize() .with_process( &process, TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags), ) .with_cluster( &cluster, - (0..2) - .map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)) - .collect::>(), + (0..2).map(|_| TrybuildHost::new(create_host(&mut deployment)).rustflags(rustflags)), ) .deploy(&mut deployment); deployment.run_ctrl_c().await.unwrap(); diff --git a/hydroflow_plus_test/examples/two_pc.rs b/hydroflow_plus_test/examples/two_pc.rs index df946a70613c..aa3065571cca 100644 --- a/hydroflow_plus_test/examples/two_pc.rs +++ b/hydroflow_plus_test/examples/two_pc.rs @@ -15,13 +15,10 @@ async fn main() { let _rustflags = "-C opt-level=3 -C codegen-units=1 -C strip=none -C debuginfo=2 -C lto=off"; let _nodes = builder - .with_default_optimize() .with_process(&coordinator, TrybuildHost::new(deployment.Localhost())) .with_cluster( &participants, - (0..num_participants) - .map(|_| TrybuildHost::new(deployment.Localhost())) - .collect::>(), + (0..num_participants).map(|_| TrybuildHost::new(deployment.Localhost())), ) .with_process(&client, TrybuildHost::new(deployment.Localhost())) .deploy(&mut deployment); diff --git a/hydroflow_plus_test/src/cluster/compute_pi.rs b/hydroflow_plus_test/src/cluster/compute_pi.rs index 106c39fecfdc..0eff334e7160 100644 --- a/hydroflow_plus_test/src/cluster/compute_pi.rs +++ b/hydroflow_plus_test/src/cluster/compute_pi.rs @@ -1,7 +1,6 @@ use std::time::Duration; use hydroflow_plus::*; -use stageleft::*; pub struct Worker {} pub struct Leader {} @@ -14,6 +13,7 @@ pub fn compute_pi<'a>( let process = flow.process(); let trials = cluster + .tick() .spin_batch(q!(batch_size)) .map(q!(|_| rand::random::<(f64, f64)>())) .map(q!(|(x, y)| x * x + y * y < 1.0)) @@ -29,21 +29,25 @@ pub fn compute_pi<'a>( ) .all_ticks(); - trials + let estimate = trials .send_bincode_interleaved(&process) - .reduce(q!(|(inside, total), (inside_batch, total_batch)| { + .reduce_commutative(q!(|(inside, total), (inside_batch, total_batch)| { *inside += inside_batch; *total += total_batch; - })) - .sample_every(q!(Duration::from_secs(1))) - .for_each(q!(|(inside, total)| { - println!( - "pi: {} ({} trials)", - 4.0 * inside as f64 / total as f64, - total - ); })); + unsafe { + // SAFETY: intentional non-determinism + estimate.sample_every(q!(Duration::from_secs(1))) + } + .for_each(q!(|(inside, total)| { + println!( + "pi: {} ({} trials)", + 4.0 * inside as f64 / total as f64, + total + ); + })); + (cluster, process) } @@ -56,14 +60,11 @@ mod tests { fn compute_pi_ir() { let builder = hydroflow_plus::FlowBuilder::new(); let _ = super::compute_pi(&builder, 8192); - let built = builder.with_default_optimize(); + let built = builder.with_default_optimize::(); insta::assert_debug_snapshot!(built.ir()); - for (id, ir) in built - .compile::(&RuntimeData::new("FAKE")) - .hydroflow_ir() - { + for (id, ir) in built.compile(&RuntimeData::new("FAKE")).hydroflow_ir() { insta::with_settings!({snapshot_suffix => format!("surface_graph_{id}")}, { insta::assert_snapshot!(ir.surface_syntax_string()); }); diff --git a/hydroflow_plus_test/src/cluster/many_to_many.rs b/hydroflow_plus_test/src/cluster/many_to_many.rs index 90adbf03f09b..91cda6f10ca1 100644 --- a/hydroflow_plus_test/src/cluster/many_to_many.rs +++ b/hydroflow_plus_test/src/cluster/many_to_many.rs @@ -1,5 +1,4 @@ use hydroflow_plus::*; -use stageleft::*; pub fn many_to_many<'a>(flow: &FlowBuilder<'a>) -> Cluster<'a, ()> { let cluster = flow.cluster(); @@ -14,7 +13,7 @@ pub fn many_to_many<'a>(flow: &FlowBuilder<'a>) -> Cluster<'a, ()> { #[cfg(test)] mod tests { use hydro_deploy::Deployment; - use hydroflow_plus::deploy::{DeployCrateWrapper, TrybuildHost}; + use hydroflow_plus::deploy::DeployCrateWrapper; #[tokio::test] async fn many_to_many() { @@ -27,12 +26,7 @@ mod tests { insta::assert_debug_snapshot!(built.ir()); let nodes = built - .with_cluster( - &cluster, - (0..2) - .map(|_| TrybuildHost::new(deployment.Localhost())) - .collect::>(), - ) + .with_cluster(&cluster, (0..2).map(|_| deployment.Localhost())) .deploy(&mut deployment); deployment.deploy().await.unwrap(); diff --git a/hydroflow_plus_test/src/cluster/map_reduce.rs b/hydroflow_plus_test/src/cluster/map_reduce.rs index 95696d5cbcf0..42d72a221881 100644 --- a/hydroflow_plus_test/src/cluster/map_reduce.rs +++ b/hydroflow_plus_test/src/cluster/map_reduce.rs @@ -1,5 +1,4 @@ use hydroflow_plus::*; -use stageleft::*; pub struct Leader {} pub struct Worker {} @@ -12,32 +11,32 @@ pub fn map_reduce<'a>(flow: &FlowBuilder<'a>) -> (Process<'a, Leader>, Cluster<' .source_iter(q!(vec!["abc", "abc", "xyz", "abc"])) .map(q!(|s| s.to_string())); - let all_ids_vec = cluster.members(); - let words_partitioned = words - .tick_batch() - .enumerate() - .map(q!(|(i, w)| ( - ClusterId::from_raw((i % all_ids_vec.len()) as u32), - w - ))) - .all_ticks(); + let partitioned_words = words + .round_robin_bincode(&cluster) + .map(q!(|string| (string, ()))); - words_partitioned - .send_bincode(&cluster) - .map(q!(|string| (string, ()))) - .tick_batch() - .fold_keyed(q!(|| 0), q!(|count, _| *count += 1)) - .inspect(q!(|(string, count)| println!( - "partition count: {} - {}", - string, count - ))) - .all_ticks() - .send_bincode_interleaved(&process) - .tick_batch() - .persist() - .reduce_keyed(q!(|total, count| *total += count)) - .all_ticks() - .for_each(q!(|(string, count)| println!("{}: {}", string, count))); + let batches = unsafe { + // SAFETY: addition is associative so we can batch reduce + partitioned_words.timestamped(&cluster.tick()).tick_batch() + } + .fold_keyed(q!(|| 0), q!(|count, _| *count += 1)) + .inspect(q!(|(string, count)| println!( + "partition count: {} - {}", + string, count + ))) + .all_ticks() + .send_bincode_interleaved(&process); + + unsafe { + // SAFETY: addition is associative so we can batch reduce + batches + .timestamped(&process.tick()) + .tick_batch() + .persist() + .reduce_keyed_commutative(q!(|total, count| *total += count)) + } + .all_ticks() + .for_each(q!(|(string, count)| println!("{}: {}", string, count))); (process, cluster) } @@ -51,14 +50,11 @@ mod tests { fn map_reduce_ir() { let builder = hydroflow_plus::FlowBuilder::new(); let _ = super::map_reduce(&builder); - let built = builder.with_default_optimize(); + let built = builder.with_default_optimize::(); insta::assert_debug_snapshot!(built.ir()); - for (id, ir) in built - .compile::(&RuntimeData::new("FAKE")) - .hydroflow_ir() - { + for (id, ir) in built.compile(&RuntimeData::new("FAKE")).hydroflow_ir() { insta::with_settings!({snapshot_suffix => format!("surface_graph_{id}")}, { insta::assert_snapshot!(ir.surface_syntax_string()); }); diff --git a/hydroflow_plus_test/src/cluster/mod.rs b/hydroflow_plus_test/src/cluster/mod.rs index bcc449c3195d..88bcbe2d9497 100644 --- a/hydroflow_plus_test/src/cluster/mod.rs +++ b/hydroflow_plus_test/src/cluster/mod.rs @@ -3,5 +3,8 @@ pub mod many_to_many; pub mod map_reduce; pub mod paxos; pub mod paxos_bench; +pub mod paxos_kv; +pub mod quorum; +pub mod request_response; pub mod simple_cluster; pub mod two_pc; diff --git a/hydroflow_plus_test/src/cluster/paxos.rs b/hydroflow_plus_test/src/cluster/paxos.rs index 488be19c01e4..af3a3ca04f3a 100644 --- a/hydroflow_plus_test/src/cluster/paxos.rs +++ b/hydroflow_plus_test/src/cluster/paxos.rs @@ -1,568 +1,527 @@ use std::collections::HashMap; +use std::fmt::Debug; +use std::hash::Hash; use std::time::Duration; use hydroflow_plus::*; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; -use stageleft::*; -use tokio::time::Instant; -use super::paxos_bench::LeaderElected; +use super::quorum::{collect_quorum, collect_quorum_with_response}; +use super::request_response::join_responses; pub struct Proposer {} pub struct Acceptor {} -pub trait PaxosPayload: - Serialize + DeserializeOwned + PartialEq + Eq + Default + Clone + std::fmt::Debug -{ -} +pub trait PaxosPayload: Serialize + DeserializeOwned + PartialEq + Eq + Clone + Debug {} +impl PaxosPayload for T {} -#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug, Hash)] +#[derive(Serialize, Deserialize, PartialEq, Eq, Copy, Clone, Debug, Hash)] pub struct Ballot { - // Note: Important that num comes before id, since Ord is defined lexicographically pub num: u32, - pub id: ClusterId, + pub proposer_id: ClusterId, } -impl LeaderElected for Ballot { - fn leader_id(&self) -> ClusterId { - self.id +impl Ord for Ballot { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.num + .cmp(&other.num) + .then_with(|| self.proposer_id.raw_id.cmp(&other.proposer_id.raw_id)) } } -#[derive(Serialize, Deserialize, Clone, Debug)] -struct P1a { - ballot: Ballot, +impl PartialOrd for Ballot { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } } #[derive(Serialize, Deserialize, Clone, Debug)] struct LogValue

{ ballot: Ballot, - value: P, -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -struct P1b

{ - ballot: Ballot, - max_ballot: Ballot, - accepted: HashMap>, + value: Option

, // might be a hole } #[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] struct P2a

{ ballot: Ballot, - slot: i32, - value: P, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] -struct P2b

{ - ballot: Ballot, - max_ballot: Ballot, - slot: i32, - value: P, + slot: usize, + value: Option

, // might be a re-committed hole } -#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -pub fn paxos_core<'a, P: PaxosPayload, R>( - flow: &FlowBuilder<'a>, - r_to_acceptors_checkpoint: impl FnOnce( - &Cluster<'a, Acceptor>, - ) -> Stream< - (ClusterId, i32), - Unbounded, - NoTick, +/// Implements the core Paxos algorithm, which uses a cluster of propsers and acceptors +/// to sequence payloads being sent to the proposers. +/// +/// Proposers that currently are the leader will work with acceptors to sequence incoming +/// payloads, but may drop payloads if they are not the lader or lose leadership during +/// the commit process. +/// +/// Returns a stream of ballots, where new values are emitted when a new leader is elected, +/// and a stream of sequenced payloads with an index and optional payload (in the case of +/// holes in the log). +/// +/// # Safety +/// When the leader is stable, the algorithm will commit incoming payloads to the leader +/// in deterministic order. However, when the leader is changing, payloads may be +/// non-deterministically dropped. The stream of ballots is also non-deterministic because +/// leaders are elected in a non-deterministic process. +#[expect( + clippy::too_many_arguments, + clippy::type_complexity, + reason = "internal paxos code // TODO" +)] +pub unsafe fn paxos_core<'a, P: PaxosPayload, R>( + proposers: &Cluster<'a, Proposer>, + acceptors: &Cluster<'a, Acceptor>, + r_to_acceptors_checkpoint: Stream< + (ClusterId, usize), Cluster<'a, Acceptor>, + Unbounded, + NoOrder, >, - c_to_proposers: impl FnOnce( - &Cluster<'a, Proposer>, - ) -> Stream>, + c_to_proposers: Stream, Unbounded>, f: usize, i_am_leader_send_timeout: u64, i_am_leader_check_timeout: u64, i_am_leader_check_timeout_delay_multiplier: usize, ) -> ( - Cluster<'a, Proposer>, - Cluster<'a, Acceptor>, - Stream>, - Stream<(i32, P), Unbounded, NoTick, Cluster<'a, Proposer>>, + Stream, Unbounded>, + Stream<(usize, Option

), Cluster<'a, Proposer>, Unbounded, NoOrder>, ) { - let proposers = flow.cluster::(); - let acceptors = flow.cluster::(); - - let c_to_proposers = c_to_proposers(&proposers); - - // Proposers. proposers .source_iter(q!(["Proposers say hello"])) .for_each(q!(|s| println!("{}", s))); - let p_id = proposers.self_id(); - - let (p_to_proposers_i_am_leader_complete_cycle, p_to_proposers_i_am_leader) = - proposers.cycle::>(); - let (a_to_proposers_p1b_complete_cycle, a_to_proposers_p1b) = - proposers.cycle::>(); - let (a_to_proposers_p2b_complete_cycle, a_to_proposers_p2b) = - proposers.cycle::>(); - // a_to_proposers_p2b.clone().for_each(q!(|(_, p2b): (u32, P2b)| println!("Proposer received P2b: {:?}", p2b))); - // p_to_proposers_i_am_leader.clone().for_each(q!(|ballot: Ballot| println!("Proposer received I am leader: {:?}", ballot))); - // c_to_proposers.clone().for_each(q!(|payload: ClientPayload| println!("Client sent proposer payload: {:?}", payload))); - - let p_received_max_ballot = p_max_ballot( - &proposers, - a_to_proposers_p1b.clone(), - a_to_proposers_p2b.clone(), - p_to_proposers_i_am_leader.clone(), - ); - let (p_ballot_num, p_has_largest_ballot) = - p_ballot_calc(&proposers, p_received_max_ballot.latest_tick()); - - let (p_is_leader, p_log_to_try_commit, p_max_slot, p_log_holes) = p_p1b( - &proposers, - a_to_proposers_p1b.inspect(q!(|(_, p1b)| println!("Proposer received P1b: {:?}", p1b))), - p_ballot_num.clone(), - p_has_largest_ballot, - f, - ); - - let (p_to_proposers_i_am_leader_from_others, p_to_acceptors_p1a) = p_p1a( - p_ballot_num.clone(), - p_is_leader.clone(), - &proposers, - p_to_proposers_i_am_leader, - &acceptors, - i_am_leader_send_timeout, - i_am_leader_check_timeout, - i_am_leader_check_timeout_delay_multiplier, - ); - p_to_proposers_i_am_leader_complete_cycle.complete(p_to_proposers_i_am_leader_from_others); - - let (p_next_slot, p_to_acceptors_p2a) = p_p2a( - &proposers, - p_max_slot, - c_to_proposers, - p_ballot_num.clone(), - p_log_to_try_commit, - p_log_holes, - p_is_leader.clone(), - &acceptors, - ); - - // Tell clients that leader election has completed and they can begin sending messages - let p_to_clients_new_leader_elected = p_is_leader.clone() - .continue_unless(p_next_slot) - .cross_singleton(p_ballot_num) - .map(q!(move |(_is_leader, ballot_num)| Ballot { num: ballot_num, id: p_id})) // Only tell the clients once when leader election concludes - .all_ticks(); - // End tell clients that leader election has completed - let p_to_replicas = p_p2b(&proposers, a_to_proposers_p2b, f); - // Acceptors. acceptors .source_iter(q!(["Acceptors say hello"])) .for_each(q!(|s| println!("{}", s))); - let r_to_acceptors_checkpoint = r_to_acceptors_checkpoint(&acceptors); - // p_to_acceptors_p2a.clone().for_each(q!(|p2a: P2a| println!("Acceptor received P2a: {:?}", p2a))); - let (a_to_proposers_p1b_new, a_to_proposers_p2b_new) = acceptor( - p_to_acceptors_p1a.inspect(q!(|p1a| println!("Acceptor received P1a: {:?}", p1a))), - p_to_acceptors_p2a, - r_to_acceptors_checkpoint, - &proposers, - &acceptors, - f, - ); - a_to_proposers_p1b_complete_cycle.complete(a_to_proposers_p1b_new); - a_to_proposers_p2b_complete_cycle.complete(a_to_proposers_p2b_new); + let proposer_tick = proposers.tick(); + let acceptor_tick = acceptors.tick(); + + let (sequencing_max_ballot_complete_cycle, sequencing_max_ballot_forward_reference) = + proposers.forward_ref::>(); + let (a_log_complete_cycle, a_log_forward_reference) = + acceptor_tick.forward_ref::>(); + + let (p_ballot, p_is_leader, p_relevant_p1bs, a_max_ballot) = unsafe { + // SAFETY: The primary non-determinism exposed by leader election algorithm lies in which leader + // is elected, which affects both the ballot at each proposer and the leader flag. But using a stale ballot + // or leader flag will only lead to failure in sequencing rather than commiting the wrong value. Because + // ballots are non-deterministic, the acceptor max ballot is also non-deterministic, although we are + // guaranteed that the max ballot will match the current ballot of a proposer who believes they are the leader. + leader_election( + proposers, + acceptors, + &proposer_tick, + &acceptor_tick, + f, + i_am_leader_send_timeout, + i_am_leader_check_timeout, + i_am_leader_check_timeout_delay_multiplier, + sequencing_max_ballot_forward_reference, + a_log_forward_reference, + ) + }; + + let just_became_leader = p_is_leader + .clone() + .continue_unless(p_is_leader.clone().defer_tick()); + + let (p_to_replicas, a_log, sequencing_max_ballots) = unsafe { + // SAFETY: The relevant p1bs are non-deterministic because they come from a arbitrary quorum, but because + // we use a quorum, if we remain the leader there are no missing committed values when we combine the logs. + // The remaining non-determinism is in when incoming payloads are batched versus the leader flag and state + // of acceptors, which in the worst case will lead to dropped payloads as documented. + sequence_payload( + proposers, + acceptors, + &proposer_tick, + &acceptor_tick, + c_to_proposers, + r_to_acceptors_checkpoint, + p_ballot.clone(), + p_is_leader, + p_relevant_p1bs, + f, + a_max_ballot, + ) + }; + + a_log_complete_cycle.complete(unsafe { + // SAFETY: We will always write payloads to the log before acknowledging them to the proposers, + // which guarantees that if the leader changes the quorum overlap between sequencing and leader + // election will include the committed value. + a_log.latest_tick() + }); + sequencing_max_ballot_complete_cycle.complete(sequencing_max_ballots); ( - proposers, - acceptors, - p_to_clients_new_leader_elected, + // Only tell the clients once when leader election concludes + just_became_leader + .then(p_ballot) + .all_ticks() + .drop_timestamp(), p_to_replicas, ) } -#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -fn acceptor<'a, P: PaxosPayload, R>( - p_to_acceptors_p1a: Stream>, - p_to_acceptors_p2a: Stream, Unbounded, NoTick, Cluster<'a, Acceptor>>, - r_to_acceptors_checkpoint: Stream< - (ClusterId, i32), - Unbounded, - NoTick, - Cluster<'a, Acceptor>, - >, +#[expect( + clippy::type_complexity, + clippy::too_many_arguments, + reason = "internal paxos code // TODO" +)] +unsafe fn leader_election<'a, L: Clone + Debug + Serialize + DeserializeOwned>( proposers: &Cluster<'a, Proposer>, acceptors: &Cluster<'a, Acceptor>, + proposer_tick: &Tick>, + acceptor_tick: &Tick>, f: usize, + i_am_leader_send_timeout: u64, + i_am_leader_check_timeout: u64, + i_am_leader_check_timeout_delay_multiplier: usize, + p_received_p2b_ballots: Stream, Unbounded, NoOrder>, + a_log: Singleton>, Bounded>, ) -> ( - Stream<(ClusterId, P1b

), Unbounded, NoTick, Cluster<'a, Proposer>>, - Stream<(ClusterId, P2b

), Unbounded, NoTick, Cluster<'a, Proposer>>, + Singleton>, Bounded>, + Optional<(), Tick>, Bounded>, + Stream>, Bounded, NoOrder>, + Singleton>, Bounded>, ) { - // Get the latest checkpoint sequence per replica - let a_checkpoint_largest_seqs = - r_to_acceptors_checkpoint - .tick_prefix() - .reduce_keyed(q!(|curr_seq, seq| { - if seq > *curr_seq { - *curr_seq = seq; - } - })); - let a_checkpoints_quorum_reached = a_checkpoint_largest_seqs.clone().count().filter_map(q!( - move |num_received| if num_received == f + 1 { - Some(true) - } else { - None - } - )); - // Find the smallest checkpoint seq that everyone agrees to, track whenever it changes - let a_new_checkpoint = a_checkpoint_largest_seqs - .continue_if(a_checkpoints_quorum_reached) - .map(q!(|(_sender, seq)| seq)) - .min() - .unwrap_or(acceptors.singleton(q!(-1)).latest_tick()) - .delta() - .map(q!(|min_seq| ( - min_seq, - P2a { - // Create tuple with checkpoint number and dummy p2a - ballot: Ballot { - num: 0, - id: ClusterId::from_raw(0) - }, - slot: -1, - value: Default::default() - } - ))); - // .inspect(q!(|(min_seq, p2a): &(i32, P2a)| println!("Acceptor new checkpoint: {:?}", min_seq))); + let (p1b_fail_complete, p1b_fail) = + proposers.forward_ref::>(); + let (p_to_proposers_i_am_leader_complete_cycle, p_to_proposers_i_am_leader_forward_ref) = + proposers.forward_ref::>(); + let (p_is_leader_complete_cycle, p_is_leader_forward_ref) = + proposer_tick.forward_ref::>(); + // a_to_proposers_p2b.clone().for_each(q!(|(_, p2b): (u32, P2b)| println!("Proposer received P2b: {:?}", p2b))); + // p_to_proposers_i_am_leader.clone().for_each(q!(|ballot: Ballot| println!("Proposer received I am leader: {:?}", ballot))); + // c_to_proposers.clone().for_each(q!(|payload: ClientPayload| println!("Client sent proposer payload: {:?}", payload))); - let a_max_ballot = p_to_acceptors_p1a - .clone() - .map(q!(|p1a| p1a.ballot)) + let p_received_max_ballot = p1b_fail + .union(p_received_p2b_ballots) + .union(p_to_proposers_i_am_leader_forward_ref) .max() - .unwrap_or(acceptors.singleton(q!(Ballot { + .unwrap_or(proposers.singleton(q!(Ballot { num: 0, - id: ClusterId::from_raw(0) + proposer_id: ClusterId::from_raw(0) }))); - let a_p2as_to_place_in_log = p_to_acceptors_p2a + + let (p_ballot, p_has_largest_ballot) = p_ballot_calc(proposer_tick, unsafe { + // SAFETY: A stale max ballot might result in us failing to become the leader, but which proposer + // becomes the leader is non-deterministic anyway. + p_received_max_ballot + .timestamped(proposer_tick) + .latest_tick() + }); + + let (p_to_proposers_i_am_leader, p_trigger_election) = unsafe { + // SAFETY: non-determinism in heartbeats may lead to additional leader election attempts, which + // is propagated to the non-determinism of which leader is elected. + p_leader_heartbeat( + proposers, + proposer_tick, + p_is_leader_forward_ref, + p_ballot.clone(), + i_am_leader_send_timeout, + i_am_leader_check_timeout, + i_am_leader_check_timeout_delay_multiplier, + ) + }; + + p_to_proposers_i_am_leader_complete_cycle.complete(p_to_proposers_i_am_leader); + + let p_to_acceptors_p1a = p_trigger_election + .then(p_ballot.clone()) + .all_ticks() + .inspect(q!(|_| println!("Proposer leader expired, sending P1a"))) + .broadcast_bincode_interleaved(acceptors); + + let (a_max_ballot, a_to_proposers_p1b) = acceptor_p1( + acceptor_tick, + unsafe { + // SAFETY: Non-deterministic batching may result in different payloads being rejected + // by an acceptor if the payload is batched with another payload with larger ballot. + // But as documented, payloads may be non-deterministically dropped during leader election. + p_to_acceptors_p1a.timestamped(acceptor_tick).tick_batch() + }, + a_log, + proposers, + ); + + let (p_is_leader, p_accepted_values, fail_ballots) = p_p1b( + proposer_tick, + a_to_proposers_p1b.inspect(q!(|p1b| println!("Proposer received P1b: {:?}", p1b))), + p_ballot.clone(), + p_has_largest_ballot, + f, + ); + p_is_leader_complete_cycle.complete(p_is_leader.clone()); + p1b_fail_complete.complete(fail_ballots.drop_timestamp()); + + (p_ballot, p_is_leader, p_accepted_values, a_max_ballot) +} + +// Proposer logic to calculate the next ballot number. Expects p_received_max_ballot, the largest ballot received so far. Outputs streams: ballot_num, and has_largest_ballot, which only contains a value if we have the largest ballot. +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +fn p_ballot_calc<'a>( + proposer_tick: &Tick>, + p_received_max_ballot: Singleton>, Bounded>, +) -> ( + Singleton>, Bounded>, + Optional<(), Tick>, Bounded>, +) { + let (p_ballot_num_complete_cycle, p_ballot_num) = + proposer_tick.cycle_with_initial(proposer_tick.singleton(q!(0))); + + let p_new_ballot_num = p_received_max_ballot .clone() - .tick_batch() - .cross_singleton(a_max_ballot.clone().latest_tick()) // Don't consider p2as if the current ballot is higher - .filter_map(q!(|(p2a, max_ballot)| - if p2a.ballot >= max_ballot { - Some((-1, p2a)) // Signal that this isn't a checkpoint with -1 + .zip(p_ballot_num.clone()) + .map(q!(move |(received_max_ballot, ballot_num)| { + if received_max_ballot + > (Ballot { + num: ballot_num, + proposer_id: CLUSTER_SELF_ID, + }) + { + received_max_ballot.num + 1 } else { - None + ballot_num } - )); - let a_log = a_p2as_to_place_in_log - .union(a_new_checkpoint.into_stream()) - .persist() - .fold( - q!(|| (-1, HashMap::new())), - q!(|(prev_checkpoint, log), (new_checkpoint, p2a)| { - if new_checkpoint != -1 { - // This is a checkpoint message. Delete all entries up to the checkpoint - for slot in *prev_checkpoint..new_checkpoint { - log.remove(&slot); - } - *prev_checkpoint = new_checkpoint; - } else { - // This is a regular p2a message. Insert it into the log if it is not checkpointed and has a higher ballot than what was there before - if p2a.slot > *prev_checkpoint { - match log.get(&p2a.slot) { - None => { - log.insert( - p2a.slot, - LogValue { - ballot: p2a.ballot, - value: p2a.value, - }, - ); - } - Some(prev_p2a) => { - if p2a.ballot > prev_p2a.ballot { - log.insert( - p2a.slot, - LogValue { - ballot: p2a.ballot, - value: p2a.value, - }, - ); - } - } - }; - } - } - }), - ); + })); + p_ballot_num_complete_cycle.complete_next_tick(p_new_ballot_num); - let a_to_proposers_p1b_new = p_to_acceptors_p1a - .tick_batch() - .cross_singleton(a_max_ballot.clone().latest_tick()) - .cross_singleton(a_log) - .map(q!(|((p1a, max_ballot), (_prev_checkpoint, log))| ( - p1a.ballot.id, - P1b { - ballot: p1a.ballot, - max_ballot, - accepted: log - } - ))) - .all_ticks() - .send_bincode(proposers); - let a_to_proposers_p2b_new = p_to_acceptors_p2a - .tick_batch() - .cross_singleton(a_max_ballot.latest_tick()) - .map(q!(|(p2a, max_ballot)| ( - p2a.ballot.id, - P2b { - ballot: p2a.ballot, - max_ballot, - slot: p2a.slot, - value: p2a.value - } - ))) - .all_ticks() - .send_bincode(proposers); - (a_to_proposers_p1b_new, a_to_proposers_p2b_new) + let p_ballot = p_ballot_num.map(q!(move |num| Ballot { + num, + proposer_id: CLUSTER_SELF_ID + })); + + let p_has_largest_ballot = p_received_max_ballot + .clone() + .zip(p_ballot.clone()) + .filter(q!( + |(received_max_ballot, cur_ballot)| *received_max_ballot <= *cur_ballot + )) + .map(q!(|_| ())); + + // End stable leader election + (p_ballot, p_has_largest_ballot) } #[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -fn p_p2b<'a, P: PaxosPayload>( +unsafe fn p_leader_heartbeat<'a>( proposers: &Cluster<'a, Proposer>, - a_to_proposers_p2b: Stream< - (ClusterId, P2b

), - Unbounded, - NoTick, - Cluster<'a, Proposer>, - >, - f: usize, -) -> Stream<(i32, P), Unbounded, NoTick, Cluster<'a, Proposer>> { - let (p_broadcasted_p2b_slots_complete_cycle, p_broadcasted_p2b_slots) = proposers.tick_cycle(); - let (p_persisted_p2bs_complete_cycle, p_persisted_p2bs) = proposers.tick_cycle(); - let p_p2b = a_to_proposers_p2b - .clone() - .tick_batch() - .union(p_persisted_p2bs); - let p_count_matching_p2bs = p_p2b - .clone() - .filter_map(q!(|(sender, p2b)| if p2b.ballot == p2b.max_ballot { - // Only consider p2bs where max ballot = ballot, which means that no one preempted us - Some((p2b.slot, (sender, p2b))) - } else { - None - })) - .fold_keyed( - q!(|| ( - 0, - P2b { - ballot: Ballot { - num: 0, - id: ClusterId::from_raw(0) - }, - max_ballot: Ballot { - num: 0, - id: ClusterId::from_raw(0) - }, - slot: 0, - value: Default::default() - } - )), - q!(|accum, (_sender, p2b)| { - accum.0 += 1; - accum.1 = p2b; - }), - ); - let p_p2b_quorum_reached = p_count_matching_p2bs - .clone() - .filter(q!(move |(_slot, (count, _p2b))| *count > f)); - let p_to_replicas = p_p2b_quorum_reached - .clone() - .anti_join(p_broadcasted_p2b_slots) // Only tell the replicas about committed values once - .map(q!(|(_slot, (_count, p2b))| (p2b.slot, p2b.value))) - .all_ticks(); + proposer_tick: &Tick>, + p_is_leader: Optional<(), Tick>, Bounded>, + p_ballot: Singleton>, Bounded>, + i_am_leader_send_timeout: u64, // How often to heartbeat + i_am_leader_check_timeout: u64, // How often to check if heartbeat expired + i_am_leader_check_timeout_delay_multiplier: usize, /* Initial delay, multiplied by proposer pid, to stagger proposers checking for timeouts */ +) -> ( + Stream, Unbounded, NoOrder>, + Optional<(), Tick>, Bounded>, +) { + let p_to_proposers_i_am_leader = unsafe { + // SAFETY: Delays in heartbeats may lead to leader election attempts even + // if the leader is alive. This will result in the previous leader receiving + // larger ballots from its peers and it will drop its leadership. + p_is_leader + .clone() + .then(p_ballot) + .latest() + .drop_timestamp() + .sample_every(q!(Duration::from_secs(i_am_leader_send_timeout))) + } + .broadcast_bincode_interleaved(proposers); - let p_p2b_all_commit_slots = - p_count_matching_p2bs + let p_leader_expired = unsafe { + // Delayed timeouts only affect which leader wins re-election. If the leadership flag + // is gained after timeout correctly ignore the timeout. If the flag is lost after + // timeout we correctly attempt to become the leader. + p_to_proposers_i_am_leader .clone() - .filter_map(q!(move |(slot, (count, _p2b))| if count == 2 * f + 1 { - Some(slot) - } else { - None - })); - // p_p2b_all_commit_slots.inspect(q!(|slot: i32| println!("Proposer slot all received: {:?}", slot))); - let p_broadcasted_p2b_slots_new = p_p2b_quorum_reached - .clone() - .map(q!(|(slot, (_count, _p2b))| slot)) - .filter_not_in(p_p2b_all_commit_slots.clone()); - // p_broadcasted_p2b_slots_new.inspect(q!(|slot: i32| println!("Proposer slot broadcasted: {:?}", slot))); - p_broadcasted_p2b_slots_complete_cycle.complete_next_tick(p_broadcasted_p2b_slots_new); - let p_persisted_p2bs_new = p_p2b - .clone() - .map(q!(|(sender, p2b)| (p2b.slot, (sender, p2b)))) - .anti_join(p_p2b_all_commit_slots.clone()) - .map(q!(|(_slot, (sender, p2b))| (sender, p2b))); - // p_persisted_p2bs_new.inspect(q!(|(sender, p2b): (u32, P2b)| println!("Proposer persisting p2b: {:?}", p2b))); - p_persisted_p2bs_complete_cycle.complete_next_tick(p_persisted_p2bs_new); - p_to_replicas + .timeout(q!(Duration::from_secs(i_am_leader_check_timeout))) + .timestamped(proposer_tick) + .latest_tick() + .continue_unless(p_is_leader) + }; + + // Add random delay depending on node ID so not everyone sends p1a at the same time + let p_trigger_election = unsafe { + // SAFETY: If the leader "un-expires" due to non-determinstic delay, we return + // to a stable leader state. If the leader remains expired, non-deterministic + // delay is propagated to the non-determinism of which leader is elected. + p_leader_expired.continue_if( + proposers + .source_interval_delayed( + q!(Duration::from_secs( + (CLUSTER_SELF_ID.raw_id + * i_am_leader_check_timeout_delay_multiplier as u32) + .into() + )), + q!(Duration::from_secs(i_am_leader_check_timeout)), + ) + .timestamped(proposer_tick) + .tick_batch() + .first(), + ) + }; + (p_to_proposers_i_am_leader, p_trigger_election) } -// Proposer logic to send p2as, outputting the next slot and the p2as to send to acceptors. -#[expect( - clippy::type_complexity, - clippy::too_many_arguments, - reason = "internal paxos code // TODO" -)] -fn p_p2a<'a, P: PaxosPayload>( +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +fn acceptor_p1<'a, L: Serialize + DeserializeOwned + Clone>( + acceptor_tick: &Tick>, + p_to_acceptors_p1a: Stream>, Bounded, NoOrder>, + a_log: Singleton>, Bounded>, proposers: &Cluster<'a, Proposer>, - p_max_slot: Optional>, - c_to_proposers: Stream>, - p_ballot_num: Singleton>, - p_log_to_try_commit: Stream, Bounded, Tick, Cluster<'a, Proposer>>, - p_log_holes: Stream, Bounded, Tick, Cluster<'a, Proposer>>, - p_is_leader: Optional>, - acceptors: &Cluster<'a, Acceptor>, ) -> ( - Optional>, - Stream, Unbounded, NoTick, Cluster<'a, Acceptor>>, + Singleton>, Bounded>, + Stream<(Ballot, Result), Cluster<'a, Proposer>, Unbounded, NoOrder>, ) { - let p_id = proposers.self_id(); - let (p_next_slot_complete_cycle, p_next_slot) = - proposers.tick_cycle::>(); - let p_next_slot_after_reconciling_p1bs = p_max_slot - .unwrap_or(proposers.singleton(q!(-1)).latest_tick()) - // .inspect(q!(|max_slot| println!("{} p_max_slot: {:?}", context.current_tick(), max_slot))) - .continue_unless(p_next_slot.clone()) - .map(q!(|max_slot| max_slot + 1)); - - // Send p2as - let p_indexed_payloads = c_to_proposers + let a_max_ballot = p_to_acceptors_p1a .clone() - .tick_batch() - .enumerate() - .cross_singleton(p_next_slot.clone()) - // .inspect(q!(|next| println!("{} p_indexed_payloads next slot: {}", context.current_tick(), next)))) - .cross_singleton(p_ballot_num.clone()) - // .inspect(q!(|ballot_num| println!("{} p_indexed_payloads ballot_num: {}", context.current_tick(), ballot_num)))) - .map(q!(move |(((index, payload), next_slot), ballot_num)| P2a { ballot: Ballot { num: ballot_num, id: p_id }, slot: next_slot + index as i32, value: payload })); - // .inspect(q!(|p2a: &P2a| println!("{} p_indexed_payloads P2a: {:?}", context.current_tick(), p2a))); - let p_to_acceptors_p2a = p_log_to_try_commit - .union(p_log_holes) - .continue_unless(p_next_slot.clone()) // Only resend p1b stuff once. Once it's resent, next_slot will exist. - .union(p_indexed_payloads) - .continue_if(p_is_leader.clone()) - .all_ticks() - .broadcast_bincode_interleaved(acceptors); + .inspect(q!(|p1a| println!("Acceptor received P1a: {:?}", p1a))) + .persist() + .max() + .unwrap_or(acceptor_tick.singleton(q!(Ballot { + num: 0, + proposer_id: ClusterId::from_raw(0) + }))); - let p_num_payloads = c_to_proposers.clone().tick_batch().count(); - let p_exists_payloads = p_num_payloads - .clone() - .filter(q!(|num_payloads| *num_payloads > 0)); - let p_next_slot_after_sending_payloads = p_num_payloads - .continue_if(p_exists_payloads.clone()) - .clone() - .cross_singleton(p_next_slot.clone()) - .map(q!( - |(num_payloads, next_slot)| next_slot + num_payloads as i32 - )); - let p_next_slot_if_no_payloads = p_next_slot.clone().continue_unless(p_exists_payloads); - let p_new_next_slot_calculated = p_next_slot_after_reconciling_p1bs - // .inspect(q!(|slot| println!("{} p_new_next_slot_after_reconciling_p1bs: {:?}", context.current_tick(), slot))) - .union(p_next_slot_after_sending_payloads) - // .inspect(q!(|slot| println!("{} p_next_slot_after_sending_payloads: {:?}", context.current_tick(), slot)))) - .union(p_next_slot_if_no_payloads) - // .inspect(q!(|slot| println!("{} p_next_slot_if_no_payloads: {:?}", context.current_tick(), slot)))) - .continue_if(p_is_leader.clone()); - let p_new_next_slot_default = p_is_leader // Default next slot to 0 if there haven't been any payloads at all - .clone() - .continue_unless(p_new_next_slot_calculated.clone()) - .map(q!(|_| 0)); - // .inspect(q!(|slot| println!("{} p_new_next_slot_default: {:?}", context.current_tick(), slot))); - let p_new_next_slot = p_new_next_slot_calculated.union(p_new_next_slot_default); - p_next_slot_complete_cycle.complete_next_tick(p_new_next_slot); - (p_next_slot, p_to_acceptors_p2a) + ( + a_max_ballot.clone(), + p_to_acceptors_p1a + .cross_singleton(a_max_ballot) + .cross_singleton(a_log) + .map(q!(|((ballot, max_ballot), log)| ( + ballot.proposer_id, + ( + ballot, + if ballot == max_ballot { + Ok(log) + } else { + Err(max_ballot) + } + ) + ))) + .all_ticks() + .send_bincode_interleaved(proposers), + ) } // Proposer logic for processing p1bs, determining if the proposer is now the leader, which uncommitted messages to commit, what the maximum slot is in the p1bs, and which no-ops to commit to fill log holes. #[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -fn p_p1b<'a, P: PaxosPayload>( - proposers: &Cluster<'a, Proposer>, +fn p_p1b<'a, P: Clone + Serialize + DeserializeOwned>( + proposer_tick: &Tick>, a_to_proposers_p1b: Stream< - (ClusterId, P1b

), - Unbounded, - NoTick, + (Ballot, Result), Cluster<'a, Proposer>, + Unbounded, + NoOrder, >, - p_ballot_num: Singleton>, - p_has_largest_ballot: Optional<(Ballot, u32), Bounded, Tick, Cluster<'a, Proposer>>, + p_ballot: Singleton>, Bounded>, + p_has_largest_ballot: Optional<(), Tick>, Bounded>, f: usize, ) -> ( - Optional>, - Stream, Bounded, Tick, Cluster<'a, Proposer>>, - Optional>, - Stream, Bounded, Tick, Cluster<'a, Proposer>>, + Optional<(), Tick>, Bounded>, + Stream>, Bounded, NoOrder>, + Stream>, Unbounded, NoOrder>, ) { - let p_id = proposers.self_id(); - let p_relevant_p1bs = a_to_proposers_p1b - .clone() - .tick_prefix() - .cross_singleton(p_ballot_num.clone()) - .filter(q!(move |((_sender, p1b), ballot_num)| p1b.ballot - == Ballot { - num: *ballot_num, - id: p_id - })); - let p_received_quorum_of_p1bs = p_relevant_p1bs - .clone() - .map(q!(|((sender, _p1b), _ballot_num)| { sender })) - .unique() - .count() - .filter_map(q!(move |num_received| if num_received > f { - Some(true) + let (quorums, fails) = collect_quorum_with_response( + a_to_proposers_p1b.timestamped(proposer_tick), + f + 1, + 2 * f + 1, + ); + + let p_received_quorum_of_p1bs = unsafe { + // SAFETY: All the values for a quorum will be emitted in a single batch, + // so we will not split up the quorum. + quorums.tick_batch() + } + .persist() + .fold_keyed_commutative( + q!(|| vec![]), + q!(|logs, log| { + // even though this is non-commutative, we use `flatten_unordered` later + logs.push(log); + }), + ) + .max_by_key(q!(|t| t.0)) + .zip(p_ballot.clone()) + .filter_map(q!( + move |((quorum_ballot, quorum_accepted), my_ballot)| if quorum_ballot == my_ballot { + Some(quorum_accepted) } else { None - })); - let p_is_leader = p_received_quorum_of_p1bs.continue_if(p_has_largest_ballot.clone()); + } + )); - let p_p1b_highest_entries_and_count = p_relevant_p1bs + let p_is_leader = p_received_quorum_of_p1bs .clone() - .flat_map(q!(|((_, p1b), _)| p1b.accepted.into_iter())) // Convert HashMap log back to stream - .fold_keyed(q!(|| (0, LogValue { ballot: Ballot { num: 0, id: ClusterId::from_raw(0) }, value: Default::default() })), q!(|curr_entry, new_entry| { - let same_values = new_entry.value == curr_entry.1.value; - let higher_ballot = new_entry.ballot > curr_entry.1.ballot; - // Increment count if the values are the same - if same_values { - curr_entry.0 += 1; - } - // Replace the ballot with the largest one - if higher_ballot { - curr_entry.1.ballot = new_entry.ballot; - // Replace the value with the one from the largest ballot, if necessary - if !same_values { - curr_entry.0 = 1; - curr_entry.1.value = new_entry.value; + .map(q!(|_| ())) + .continue_if(p_has_largest_ballot.clone()); + + ( + p_is_leader, + // we used an unordered accumulator, so flattened has no order + p_received_quorum_of_p1bs.flatten_unordered(), + fails.map(q!(|(_, ballot)| ballot)), + ) +} + +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +fn recommit_after_leader_election<'a, P: PaxosPayload>( + accepted_logs: Stream< + HashMap>, + Tick>, + Bounded, + NoOrder, + >, + p_ballot: Singleton>, Bounded>, + f: usize, +) -> ( + Stream, Tick>, Bounded, NoOrder>, + Optional>, Bounded>, +) { + let p_p1b_highest_entries_and_count = accepted_logs + .flatten_unordered() // Convert HashMap log back to stream + .fold_keyed_commutative::<(usize, Option>), _, _>(q!(|| (0, None)), q!(|curr_entry, new_entry| { + if let Some(curr_entry_payload) = &mut curr_entry.1 { + let same_values = new_entry.value == curr_entry_payload.value; + let higher_ballot = new_entry.ballot > curr_entry_payload.ballot; + // Increment count if the values are the same + if same_values { + curr_entry.0 += 1; + } + // Replace the ballot with the largest one + if higher_ballot { + curr_entry_payload.ballot = new_entry.ballot; + // Replace the value with the one from the largest ballot, if necessary + if !same_values { + curr_entry.0 = 1; + curr_entry_payload.value = new_entry.value; + } } + } else { + *curr_entry = (1, Some(new_entry)); } - })); + })) + .map(q!(|(slot, (count, entry))| (slot, (count, entry.unwrap())))); let p_log_to_try_commit = p_p1b_highest_entries_and_count .clone() - .cross_singleton(p_ballot_num.clone()) - .filter_map(q!( - move |((slot, (count, entry)), ballot_num)| if count <= f as u32 { + .cross_singleton(p_ballot.clone()) + .filter_map(q!(move |((slot, (count, entry)), ballot)| { + if count <= f { Some(P2a { - ballot: Ballot { - num: ballot_num, - id: p_id, - }, + ballot, slot, value: entry.value, }) } else { None } - )); + })); let p_max_slot = p_p1b_highest_entries_and_count .clone() .map(q!(|(slot, _)| slot)) @@ -572,169 +531,278 @@ fn p_p1b<'a, P: PaxosPayload>( .map(q!(|(slot, _)| slot)); let p_log_holes = p_max_slot .clone() - .flat_map(q!(|max_slot| 0..max_slot)) + .flat_map_ordered(q!(|max_slot| 0..max_slot)) .filter_not_in(p_proposed_slots) - .cross_singleton(p_ballot_num.clone()) - .map(q!(move |(slot, ballot_num)| P2a { - ballot: Ballot { - num: ballot_num, - id: p_id - }, + .cross_singleton(p_ballot.clone()) + .map(q!(|(slot, ballot)| P2a { + ballot, slot, - value: Default::default() + value: None })); - (p_is_leader, p_log_to_try_commit, p_max_slot, p_log_holes) + + (p_log_to_try_commit.union(p_log_holes), p_max_slot) } -// Proposer logic to calculate the largest ballot received so far. -#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -fn p_max_ballot<'a, P: PaxosPayload>( +#[expect( + clippy::type_complexity, + clippy::too_many_arguments, + reason = "internal paxos code // TODO" +)] +unsafe fn sequence_payload<'a, P: PaxosPayload, R>( proposers: &Cluster<'a, Proposer>, - a_to_proposers_p1b: Stream< - (ClusterId, P1b

), + acceptors: &Cluster<'a, Acceptor>, + proposer_tick: &Tick>, + acceptor_tick: &Tick>, + c_to_proposers: Stream, Unbounded>, + r_to_acceptors_checkpoint: Stream< + (ClusterId, usize), + Cluster<'a, Acceptor>, Unbounded, - NoTick, - Cluster<'a, Proposer>, + NoOrder, >, - a_to_proposers_p2b: Stream< - (ClusterId, P2b

), - Unbounded, - NoTick, - Cluster<'a, Proposer>, + + p_ballot: Singleton>, Bounded>, + p_is_leader: Optional<(), Tick>, Bounded>, + + p_relevant_p1bs: Stream< + HashMap>, + Tick>, + Bounded, + NoOrder, >, - p_to_proposers_i_am_leader: Stream>, -) -> Singleton> { - let p_received_p1b_ballots = a_to_proposers_p1b - .clone() - .map(q!(|(_, p1b)| p1b.max_ballot)); - let p_received_p2b_ballots = a_to_proposers_p2b - .clone() - .map(q!(|(_, p2b)| p2b.max_ballot)); - p_received_p1b_ballots - .union(p_received_p2b_ballots) - .union(p_to_proposers_i_am_leader) - .max() - .unwrap_or(proposers.singleton(q!(Ballot { - num: 0, - id: ClusterId::from_raw(0) - }))) -} + f: usize, -// Proposer logic to calculate the next ballot number. Expects p_received_max_ballot, the largest ballot received so far. Outputs streams: ballot_num, and has_largest_ballot, which only contains a value if we have the largest ballot. -#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -fn p_ballot_calc<'a>( - proposers: &Cluster<'a, Proposer>, - p_received_max_ballot: Singleton>, + a_max_ballot: Singleton>, Bounded>, ) -> ( - Singleton>, - Optional<(Ballot, u32), Bounded, Tick, Cluster<'a, Proposer>>, + Stream<(usize, Option

), Cluster<'a, Proposer>, Unbounded, NoOrder>, + Singleton>, Timestamped>, Unbounded>, + Stream, Unbounded, NoOrder>, ) { - let p_id = proposers.self_id(); - let (p_ballot_num_complete_cycle, p_ballot_num) = - proposers.tick_cycle_with_initial(proposers.singleton(q!(0)).latest_tick()); + let (p_log_to_recommit, p_max_slot) = + recommit_after_leader_election(p_relevant_p1bs, p_ballot.clone(), f); + + let indexed_payloads = index_payloads(proposer_tick, p_max_slot, unsafe { + // SAFETY: We batch payloads so that we can compute the correct slot based on + // base slot. In the case of a leader re-election, the base slot is updated which + // affects the computed payload slots. This non-determinism can lead to non-determinism + // in which payloads are committed when the leader is changing, which is documented at + // the function level. + c_to_proposers + .timestamped(proposer_tick) + .tick_batch() + .continue_if(p_is_leader.clone()) + }); + + let payloads_to_send = indexed_payloads + .cross_singleton(p_ballot.clone()) + .map(q!(|((slot, payload), ballot)| ( + (slot, ballot), + Some(payload) + ))) + .union(p_log_to_recommit.map(q!(|p2a| ((p2a.slot, p2a.ballot), p2a.value)))) + .continue_if(p_is_leader) + .all_ticks(); - let p_new_ballot_num = p_received_max_ballot - .clone() - .cross_singleton(p_ballot_num.clone()) - .map(q!(move |(received_max_ballot, ballot_num)| { - if received_max_ballot - > (Ballot { - num: ballot_num, - id: p_id, - }) - { - received_max_ballot.num + 1 - } else { - ballot_num - } - })); - p_ballot_num_complete_cycle.complete_next_tick(p_new_ballot_num); + let (a_log, a_to_proposers_p2b) = acceptor_p2( + acceptor_tick, + a_max_ballot.clone(), + payloads_to_send + .clone() + .map(q!(|((slot, ballot), value)| P2a { + ballot, + slot, + value + })) + .broadcast_bincode_interleaved(acceptors), + r_to_acceptors_checkpoint, + proposers, + f, + ); - let p_has_largest_ballot = p_received_max_ballot - .clone() - .cross_singleton(p_ballot_num.clone()) - .filter(q!( - move |(received_max_ballot, ballot_num)| *received_max_ballot - <= Ballot { - num: *ballot_num, - id: p_id - } - )); + // TOOD: only persist if we are the leader + let (quorums, fails) = collect_quorum( + a_to_proposers_p2b.timestamped(proposer_tick), + f + 1, + 2 * f + 1, + ); - // End stable leader election - (p_ballot_num, p_has_largest_ballot) + let p_to_replicas = join_responses(proposer_tick, quorums.map(q!(|k| (k, ()))), unsafe { + // SAFETY: The metadata will always be generated before we get a quorum + // because `payloads_to_send` is used to send the payloads to acceptors. + payloads_to_send.tick_batch() + }); + + ( + p_to_replicas + .map(q!(|((slot, _ballot), (value, _))| (slot, value))) + .drop_timestamp(), + a_log.map(q!(|(_ckpnt, log)| log)), + fails.map(q!(|(_, ballot)| ballot)).drop_timestamp(), + ) } -// Proposer logic to send "I am leader" messages periodically to other proposers, or send p1a to acceptors if other leaders expired. -#[expect( - clippy::too_many_arguments, - clippy::type_complexity, - reason = "internal paxos code // TODO" -)] -fn p_p1a<'a>( - p_ballot_num: Singleton>, - p_is_leader: Optional>, +#[derive(Clone)] +enum CheckpointOrP2a

{ + Checkpoint(usize), + P2a(P2a

), +} + +// Proposer logic to send p2as, outputting the next slot and the p2as to send to acceptors. +fn index_payloads<'a, P: PaxosPayload>( + proposer_tick: &Tick>, + p_max_slot: Optional>, Bounded>, + c_to_proposers: Stream>, Bounded>, +) -> Stream<(usize, P), Tick>, Bounded> { + let (p_next_slot_complete_cycle, p_next_slot) = + proposer_tick.cycle_with_initial::>(proposer_tick.singleton(q!(0))); + let p_next_slot_after_reconciling_p1bs = p_max_slot.map(q!(|max_slot| max_slot + 1)); + + let base_slot = p_next_slot_after_reconciling_p1bs.unwrap_or(p_next_slot); + + let p_indexed_payloads = c_to_proposers + .enumerate() + .cross_singleton(base_slot.clone()) + .map(q!(|((index, payload), base_slot)| ( + base_slot + index, + payload + ))); + + let p_num_payloads = p_indexed_payloads.clone().count(); + let p_next_slot_after_sending_payloads = + p_num_payloads + .clone() + .zip(base_slot) + .map(q!(|(num_payloads, base_slot)| base_slot + num_payloads)); + + p_next_slot_complete_cycle.complete_next_tick(p_next_slot_after_sending_payloads); + p_indexed_payloads +} + +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +fn acceptor_p2<'a, P: PaxosPayload, R>( + acceptor_tick: &Tick>, + a_max_ballot: Singleton>, Bounded>, + p_to_acceptors_p2a: Stream, Cluster<'a, Acceptor>, Unbounded, NoOrder>, + r_to_acceptors_checkpoint: Stream< + (ClusterId, usize), + Cluster<'a, Acceptor>, + Unbounded, + NoOrder, + >, proposers: &Cluster<'a, Proposer>, - p_to_proposers_i_am_leader: Stream>, - acceptors: &Cluster<'a, Acceptor>, - i_am_leader_send_timeout: u64, // How often to heartbeat - i_am_leader_check_timeout: u64, // How often to check if heartbeat expired - i_am_leader_check_timeout_delay_multiplier: usize, /* Initial delay, multiplied by proposer pid, to stagger proposers checking for timeouts */ + f: usize, ) -> ( - Stream>, - Stream>, + Singleton< + (Option, HashMap>), + Timestamped>, + Unbounded, + >, + Stream<((usize, Ballot), Result<(), Ballot>), Cluster<'a, Proposer>, Unbounded, NoOrder>, ) { - let p_id = proposers.self_id(); - let p_to_proposers_i_am_leader_new = p_ballot_num - .clone() - .continue_if( - proposers - .source_interval(q!(Duration::from_secs(i_am_leader_send_timeout))) - .latest_tick(), - ) - .continue_if(p_is_leader.clone()) - .map(q!(move |ballot_num| Ballot { - num: ballot_num, - id: p_id - })) - .all_ticks() - .broadcast_bincode_interleaved(proposers); + let p_to_acceptors_p2a_batch = unsafe { + // SAFETY: we use batches to ensure that the log is updated before sending + // a confirmation to the proposer. Because we use `persist()` on these + // messages before folding into the log, non-deterministic batch boundaries + // will not affect the eventual log state. + p_to_acceptors_p2a.timestamped(acceptor_tick).tick_batch() + }; - let p_latest_received_i_am_leader = p_to_proposers_i_am_leader.clone().fold( - q!(|| None), - q!(|latest, _| { - // Note: May want to check received ballot against our own? - *latest = Some(Instant::now()); - }), - ); - // Add random delay depending on node ID so not everyone sends p1a at the same time - let p_leader_expired = proposers.source_interval_delayed(q!(Duration::from_secs((p_id.raw_id * i_am_leader_check_timeout_delay_multiplier as u32).into())), q!(Duration::from_secs(i_am_leader_check_timeout))) - .cross_singleton(p_latest_received_i_am_leader.clone()) - .latest_tick() - // .inspect(q!(|v| println!("Proposer checking if leader expired"))) - // .continue_if(p_is_leader.clone().count().filter(q!(|c| *c == 0)).inspect(q!(|c| println!("Proposer is_leader count: {}", c)))) - .continue_unless(p_is_leader) - .filter(q!(move |(_, latest_received_i_am_leader)| { - if let Some(latest_received_i_am_leader) = latest_received_i_am_leader { - (Instant::now().duration_since(*latest_received_i_am_leader)) > Duration::from_secs(i_am_leader_check_timeout) + // Get the latest checkpoint sequence per replica + let a_checkpoint_largest_seqs = unsafe { + // SAFETY: if a checkpoint is delayed, its effect is that the log may contain slots + // that do not need to be saved (because the data is at all replicas). This affects + // the logs that will be collected during a leader re-election, but eventually the + // same checkpoint will arrive at acceptors and those slots will be eventually deleted. + r_to_acceptors_checkpoint + .timestamped(acceptor_tick) + .tick_batch() + } + .persist() + .reduce_keyed_commutative(q!(|curr_seq, seq| { + if seq > *curr_seq { + *curr_seq = seq; + } + })); + let a_checkpoints_quorum_reached = a_checkpoint_largest_seqs.clone().count().filter_map(q!( + move |num_received| if num_received == f + 1 { + Some(true) + } else { + None + } + )); + // Find the smallest checkpoint seq that everyone agrees to, track whenever it changes + let a_new_checkpoint = a_checkpoint_largest_seqs + .continue_if(a_checkpoints_quorum_reached) + .map(q!(|(_sender, seq)| seq)) + .min() + .delta() + .map(q!(|min_seq| CheckpointOrP2a::Checkpoint(min_seq))); + // .inspect(q!(|(min_seq, p2a): &(i32, P2a)| println!("Acceptor new checkpoint: {:?}", min_seq))); + + let a_p2as_to_place_in_log = p_to_acceptors_p2a_batch + .clone() + .cross_singleton(a_max_ballot.clone()) // Don't consider p2as if the current ballot is higher + .filter_map(q!(|(p2a, max_ballot)| + if p2a.ballot >= max_ballot { + Some(CheckpointOrP2a::P2a(p2a)) } else { - true + None } - })); - p_leader_expired - .clone() + )); + let a_log = a_p2as_to_place_in_log + .union(a_new_checkpoint.into_stream()) .all_ticks() - .for_each(q!(|_| println!("Proposer leader expired"))); - - let p_to_acceptors_p1a = p_ballot_num - .continue_if(p_leader_expired) - .map(q!(move |ballot_num| P1a { - ballot: Ballot { - num: ballot_num, - id: p_id - } - })) + .fold_commutative( + q!(|| (None, HashMap::new())), + q!(|(prev_checkpoint, log), checkpoint_or_p2a| { + match checkpoint_or_p2a { + CheckpointOrP2a::Checkpoint(new_checkpoint) => { + if prev_checkpoint + .map(|prev| new_checkpoint > prev) + .unwrap_or(true) + { + for slot in (prev_checkpoint.unwrap_or(0))..new_checkpoint { + log.remove(&slot); + } + + *prev_checkpoint = Some(new_checkpoint); + } + } + CheckpointOrP2a::P2a(p2a) => { + // This is a regular p2a message. Insert it into the log if it is not checkpointed and has a higher ballot than what was there before + if prev_checkpoint.map(|prev| p2a.slot > prev).unwrap_or(true) + && log + .get(&p2a.slot) + .map(|prev_p2a: &LogValue<_>| p2a.ballot > prev_p2a.ballot) + .unwrap_or(true) + { + log.insert( + p2a.slot, + LogValue { + ballot: p2a.ballot, + value: p2a.value, + }, + ); + } + } + } + }), + ); + + let a_to_proposers_p2b = p_to_acceptors_p2a_batch + .cross_singleton(a_max_ballot) + .map(q!(|(p2a, max_ballot)| ( + p2a.ballot.proposer_id, + ( + (p2a.slot, p2a.ballot), + if p2a.ballot == max_ballot { + Ok(()) + } else { + Err(max_ballot) + } + ) + ))) .all_ticks() - .broadcast_bincode_interleaved(acceptors); - (p_to_proposers_i_am_leader_new, p_to_acceptors_p1a) + .send_bincode_interleaved(proposers); + (a_log, a_to_proposers_p2b) } diff --git a/hydroflow_plus_test/src/cluster/paxos_bench.rs b/hydroflow_plus_test/src/cluster/paxos_bench.rs index 5b72192b093c..4d87409fbde1 100644 --- a/hydroflow_plus_test/src/cluster/paxos_bench.rs +++ b/hydroflow_plus_test/src/cluster/paxos_bench.rs @@ -1,47 +1,16 @@ use std::cell::RefCell; -use std::collections::HashMap; use std::rc::Rc; -use std::time::{Duration, SystemTime}; +use std::time::Duration; use hydroflow_plus::*; -use serde::{Deserialize, Serialize}; -use stageleft::*; +use tokio::time::Instant; -use super::paxos::{paxos_core, Acceptor, Ballot, PaxosPayload, Proposer}; - -pub trait LeaderElected: Ord + Clone { - fn leader_id(&self) -> ClusterId; -} - -pub struct Replica {} +use super::paxos::{Acceptor, Ballot, Proposer}; +use super::paxos_kv::{paxos_kv, KvPayload, Replica}; +use super::quorum::collect_quorum; pub struct Client {} -#[derive(Serialize, serde::Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Debug)] -pub struct ReplicaPayload { - // Note: Important that seq is the first member of the struct for sorting - pub seq: i32, - pub key: u32, - pub value: String, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] -pub struct ClientPayload { - pub key: u32, - pub value: String, -} - -impl Default for ClientPayload { - fn default() -> Self { - Self { - key: 0, - value: "".to_string(), - } - } -} - -impl PaxosPayload for ClientPayload {} - // Important: By convention, all relations that represent booleans either have a single "true" value or nothing. // This allows us to use the continue_if_exists() and continue_if_empty() operators as if they were if (true) and if (false) statements. #[expect(clippy::too_many_arguments, reason = "internal paxos code // TODO")] @@ -60,355 +29,241 @@ pub fn paxos_bench<'a>( Cluster<'a, Client>, Cluster<'a, Replica>, ) { + let proposers = flow.cluster::(); + let acceptors = flow.cluster::(); let clients = flow.cluster::(); let replicas = flow.cluster::(); - let (c_to_proposers_complete_cycle, c_to_proposers) = clients.cycle(); - - let (proposers, acceptors, p_to_clients_new_leader_elected, r_new_processed_payloads) = - paxos_with_replica( - flow, - &replicas, - c_to_proposers, - f, - i_am_leader_send_timeout, - i_am_leader_check_timeout, - i_am_leader_check_timeout_delay_multiplier, - checkpoint_frequency, - ); + let (new_leader_elected_complete, new_leader_elected) = + clients.forward_ref::>(); - c_to_proposers_complete_cycle.complete(bench_client( + let client_tick = clients.tick(); + let cur_leader_id = new_leader_elected + .inspect(q!(|ballot| println!( + "Client notified that leader was elected: {:?}", + ballot + ))) + .max() + .map(q!(|ballot: Ballot| ballot.proposer_id)); + + let leader_changed = unsafe { + // SAFETY: we are okay if we miss a transient leader ID, because we + // will eventually get the latest one and can restart requests then + cur_leader_id + .clone() + .timestamped(&client_tick) + .latest_tick() + .delta() + .map(q!(|_| ())) + .all_ticks() + .drop_timestamp() + }; + + bench_client( &clients, - p_to_clients_new_leader_elected.broadcast_bincode_interleaved(&clients), - r_new_processed_payloads.send_bincode(&clients), - num_clients_per_node, - median_latency_window_size, - f, - )); + leader_changed, + |c_to_proposers| { + let to_proposers = unsafe { + // SAFETY: the risk here is that we send a batch of requests + // with a stale leader ID, but because the leader ID comes from the + // network there is no way to guarantee that it is up to date + + // TODO(shadaj): we should retry if we get an error due to sending + // to a stale leader + c_to_proposers + .timestamped(&client_tick) + .tick_batch() + .cross_singleton(cur_leader_id.timestamped(&client_tick).latest_tick()) + .all_ticks() + } + .map(q!(move |((key, value), leader_id)| ( + leader_id, + KvPayload { + key, + // we use our ID as part of the value and use that so the replica only notifies us + value: (CLUSTER_SELF_ID, value) + } + ))) + .send_bincode_interleaved(&proposers); - (proposers, acceptors, clients, replicas) -} + let to_proposers = unsafe { + // SAFETY: clients "own" certain keys, so interleaving elements from clients will not affect + // the order of writes to the same key + to_proposers.assume_ordering() + }; -#[expect( - clippy::type_complexity, - clippy::too_many_arguments, - reason = "internal paxos code // TODO" -)] -fn paxos_with_replica<'a>( - flow: &FlowBuilder<'a>, - replicas: &Cluster<'a, Replica>, - c_to_proposers: Stream< - (ClusterId, ClientPayload), - Unbounded, - NoTick, - Cluster<'a, Client>, - >, - f: usize, - i_am_leader_send_timeout: u64, - i_am_leader_check_timeout: u64, - i_am_leader_check_timeout_delay_multiplier: usize, - checkpoint_frequency: usize, -) -> ( - Cluster<'a, Proposer>, - Cluster<'a, Acceptor>, - Stream>, - Stream<(ClusterId, ReplicaPayload), Unbounded, NoTick, Cluster<'a, Replica>>, -) { - let (r_to_acceptors_checkpoint_complete_cycle, r_to_acceptors_checkpoint) = - replicas.cycle::>(); - - let (proposers, acceptors, p_to_clients_new_leader_elected, p_to_replicas) = paxos_core( - flow, - |acceptors| r_to_acceptors_checkpoint.broadcast_bincode(acceptors), - |proposers| c_to_proposers.send_bincode_interleaved(proposers), - f, - i_am_leader_send_timeout, - i_am_leader_check_timeout, - i_am_leader_check_timeout_delay_multiplier, - ); + let (new_leader_elected, processed_payloads) = unsafe { + // SAFETY: Non-deterministic leader notifications are handled in `to_proposers`. We do not + // care about the order in which key writes are processed, which is the non-determinism in + // `processed_payloads`. + paxos_kv( + &proposers, + &acceptors, + &replicas, + to_proposers, + f, + i_am_leader_send_timeout, + i_am_leader_check_timeout, + i_am_leader_check_timeout_delay_multiplier, + checkpoint_frequency, + ) + }; - let (r_to_acceptors_checkpoint_new, r_new_processed_payloads) = replica( - replicas, - p_to_replicas - .map(q!(|(slot, data)| ReplicaPayload { - seq: slot, - key: data.key, - value: data.value - })) - .broadcast_bincode_interleaved(replicas), - checkpoint_frequency, + new_leader_elected_complete + .complete(new_leader_elected.broadcast_bincode_interleaved(&clients)); + + let c_received_payloads = processed_payloads + .map(q!(|payload| ( + payload.value.0, + ((payload.key, payload.value.1), Ok(())) + ))) + .send_bincode_interleaved(&clients); + + // we only mark a transaction as committed when all replicas have applied it + let (c_quorum_payloads, _) = collect_quorum::<_, _, _, ()>( + c_received_payloads.timestamped(&client_tick), + f + 1, + f + 1, + ); + + c_quorum_payloads.drop_timestamp() + }, + num_clients_per_node, + median_latency_window_size, ); - r_to_acceptors_checkpoint_complete_cycle.complete(r_to_acceptors_checkpoint_new); - - ( - proposers, - acceptors, - p_to_clients_new_leader_elected, - r_new_processed_payloads, - ) -} - -// Replicas. All relations for replicas will be prefixed with r. Expects ReplicaPayload on p_to_replicas, outputs a stream of (client address, ReplicaPayload) after processing. -#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] -pub fn replica<'a>( - replicas: &Cluster<'a, Replica>, - p_to_replicas: Stream>, - checkpoint_frequency: usize, -) -> ( - Stream>, - Stream<(ClusterId, ReplicaPayload), Unbounded, NoTick, Cluster<'a, Replica>>, -) { - let (r_buffered_payloads_complete_cycle, r_buffered_payloads) = replicas.tick_cycle(); - // p_to_replicas.inspect(q!(|payload: ReplicaPayload| println!("Replica received payload: {:?}", payload))); - let r_sorted_payloads = p_to_replicas - .clone() - .tick_batch() - .union(r_buffered_payloads) // Combine with all payloads that we've received and not processed yet - .sort(); - // Create a cycle since we'll use this seq before we define it - let (r_highest_seq_complete_cycle, r_highest_seq) = - replicas.tick_cycle::>(); - let empty_slot = replicas.singleton_first_tick(q!(-1)); - // Either the max sequence number executed so far or -1. Need to union otherwise r_highest_seq is empty and joins with it will fail - let r_highest_seq_with_default = r_highest_seq.union(empty_slot); - // Find highest the sequence number of any payload that can be processed in this tick. This is the payload right before a hole. - let r_highest_seq_processable_payload = r_sorted_payloads - .clone() - .cross_singleton(r_highest_seq_with_default) - .fold( - q!(|| -1), - q!(|filled_slot, (sorted_payload, highest_seq)| { - // Note: This function only works if the input is sorted on seq. - let next_slot = std::cmp::max(*filled_slot, highest_seq); - - *filled_slot = if sorted_payload.seq == next_slot + 1 { - sorted_payload.seq - } else { - *filled_slot - }; - }), - ); - // Find all payloads that can and cannot be processed in this tick. - let r_processable_payloads = r_sorted_payloads - .clone() - .cross_singleton(r_highest_seq_processable_payload.clone()) - .filter(q!( - |(sorted_payload, highest_seq)| sorted_payload.seq <= *highest_seq - )) - .map(q!(|(sorted_payload, _)| { sorted_payload })); - let r_new_non_processable_payloads = r_sorted_payloads - .clone() - .cross_singleton(r_highest_seq_processable_payload.clone()) - .filter(q!( - |(sorted_payload, highest_seq)| sorted_payload.seq > *highest_seq - )) - .map(q!(|(sorted_payload, _)| { sorted_payload })); - // Save these, we can process them once the hole has been filled - r_buffered_payloads_complete_cycle.complete_next_tick(r_new_non_processable_payloads); - - let r_kv_store = r_processable_payloads - .clone() - .persist() // Optimization: all_ticks() + fold() = fold, where the state of the previous fold is saved and persisted values are deleted. - .fold(q!(|| (HashMap::::new(), -1)), q!(|state, payload| { - let kv_store = &mut state.0; - let last_seq = &mut state.1; - kv_store.insert(payload.key, payload.value); - debug_assert!(payload.seq == *last_seq + 1, "Hole in log between seq {} and {}", *last_seq, payload.seq); - *last_seq = payload.seq; - // println!("Replica kv store: {:?}", kv_store); - })); - // Update the highest seq for the next tick - let r_new_highest_seq = r_kv_store.map(q!(|(_kv_store, highest_seq)| highest_seq)); - r_highest_seq_complete_cycle.complete_next_tick(r_new_highest_seq.clone().into()); - - // Send checkpoints to the acceptors when we've processed enough payloads - let (r_checkpointed_seqs_complete_cycle, r_checkpointed_seqs) = - replicas.tick_cycle::>(); - let r_max_checkpointed_seq = r_checkpointed_seqs - .persist() - .max() - .unwrap_or(replicas.singleton(q!(-1)).latest_tick()); - let r_checkpoint_seq_new = r_max_checkpointed_seq - .cross_singleton(r_new_highest_seq) - .filter_map(q!( - move |(max_checkpointed_seq, new_highest_seq)| if new_highest_seq - max_checkpointed_seq - >= checkpoint_frequency as i32 - { - Some(new_highest_seq) - } else { - None - } - )); - r_checkpointed_seqs_complete_cycle.complete_next_tick(r_checkpoint_seq_new.clone()); - - // Tell clients that the payload has been committed. All ReplicaPayloads contain the client's machine ID (to string) as value. - let r_to_clients = p_to_replicas.map(q!(|payload| ( - ClusterId::from_raw(payload.value.parse::().unwrap()), - payload - ))); - (r_checkpoint_seq_new.all_ticks(), r_to_clients) + (proposers, acceptors, clients, replicas) } -// Clients. All relations for clients will be prefixed with c. All ClientPayloads will contain the virtual client number as key and the client's machine ID (to string) as value. Expects p_to_clients_leader_elected containing Ballots whenever the leader is elected, and r_to_clients_payload_applied containing ReplicaPayloads whenever a payload is committed. Outputs (leader address, ClientPayload) when a new leader is elected or when the previous payload is committed. -fn bench_client<'a, B: LeaderElected + std::fmt::Debug>( +fn bench_client<'a>( clients: &Cluster<'a, Client>, - p_to_clients_leader_elected: Stream>, - r_to_clients_payload_applied: Stream< - (ClusterId, ReplicaPayload), - Unbounded, - NoTick, - Cluster<'a, Client>, - >, + trigger_restart: Stream<(), Cluster<'a, Client>, Unbounded>, + transaction_cycle: impl FnOnce( + Stream<(u32, u32), Cluster<'a, Client>, Unbounded>, + ) -> Stream<(u32, u32), Cluster<'a, Client>, Unbounded, NoOrder>, num_clients_per_node: usize, median_latency_window_size: usize, - f: usize, -) -> Stream<(ClusterId, ClientPayload), Unbounded, NoTick, Cluster<'a, Client>> { - let c_id = clients.self_id(); +) { + let client_tick = clients.tick(); // r_to_clients_payload_applied.clone().inspect(q!(|payload: &(u32, ReplicaPayload)| println!("Client received payload: {:?}", payload))); - // Only keep the latest leader - let c_max_leader_ballot = p_to_clients_leader_elected - .inspect(q!(|ballot| println!( - "Client notified that leader was elected: {:?}", - ballot - ))) - .max(); - let c_new_leader_ballot = c_max_leader_ballot.clone().latest_tick().delta(); + // Whenever the leader changes, make all clients send a message - let c_new_payloads_when_leader_elected = - c_new_leader_ballot - .clone() - .flat_map(q!(move |leader_ballot| (0..num_clients_per_node).map( - move |i| ( - leader_ballot.leader_id(), - ClientPayload { - key: i as u32, - value: c_id.raw_id.to_string() - } - ) - ))); - // Whenever replicas confirm that a payload was committed, collected it and wait for a quorum - let (c_pending_quorum_payloads_complete_cycle, c_pending_quorum_payloads) = - clients.tick_cycle(); - let c_received_payloads = r_to_clients_payload_applied - .tick_batch() - .map(q!(|(sender, replica_payload)| ( - replica_payload.key, - sender - ))) - .union(c_pending_quorum_payloads); - let c_received_quorum_payloads = c_received_payloads - .clone() - .fold_keyed( - q!(|| 0), - q!(|curr_count, _sender| { - *curr_count += 1; // Assumes the same replica will only send commit once - }), - ) - .filter_map(q!(move |(key, count)| { - if count == f + 1 { - Some(key) - } else { - None - } - })); - let c_new_pending_quorum_payloads = - c_received_payloads.anti_join(c_received_quorum_payloads.clone()); - c_pending_quorum_payloads_complete_cycle.complete_next_tick(c_new_pending_quorum_payloads); + let restart_this_tick = unsafe { + // SAFETY: non-deterministic delay in restarting requests + // is okay because once it is restarted statistics should reach + // steady state regardless of when the restart happes + trigger_restart + .timestamped(&client_tick) + .tick_batch() + .last() + }; + + let c_new_payloads_when_restart = restart_this_tick.clone().flat_map_ordered(q!(move |_| (0 + ..num_clients_per_node) + .map(move |i| ( + (CLUSTER_SELF_ID.raw_id * (num_clients_per_node as u32)) + i as u32, + 0 + )))); + + let (c_to_proposers_complete_cycle, c_to_proposers) = + clients.forward_ref::>(); + let c_received_quorum_payloads = unsafe { + // SAFETY: because the transaction processor is required to handle arbitrary reordering + // across *different* keys, we are safe because delaying a transaction result for a key + // will only affect when the next request for that key is emitted with respect to other + // keys + transaction_cycle(c_to_proposers) + .timestamped(&client_tick) + .tick_batch() + }; + // Whenever all replicas confirm that a payload was committed, send another payload let c_new_payloads_when_committed = c_received_quorum_payloads .clone() - .cross_singleton(c_max_leader_ballot.clone().latest_tick()) - .map(q!(move |(key, leader_ballot)| ( - leader_ballot.leader_id(), - ClientPayload { - key, - value: c_id.raw_id.to_string() - } - ))); - let c_to_proposers = c_new_payloads_when_leader_elected - .union(c_new_payloads_when_committed) - .all_ticks(); + .map(q!(|payload| (payload.0, payload.1 + 1))); + c_to_proposers_complete_cycle.complete( + c_new_payloads_when_restart + .chain(unsafe { + // SAFETY: we don't send a new write for the same key until the previous one is committed, + // so this contains only a single write per key, and we don't care about order + // across keys + c_new_payloads_when_committed.assume_ordering() + }) + .all_ticks() + .drop_timestamp(), + ); // Track statistics let (c_timers_complete_cycle, c_timers) = - clients.tick_cycle::>(); - let c_new_timers_when_leader_elected = c_new_leader_ballot - .map(q!(|_| SystemTime::now())) - .flat_map(q!( + client_tick.cycle::>(); + let c_new_timers_when_leader_elected = restart_this_tick + .map(q!(|_| Instant::now())) + .flat_map_ordered(q!( move |now| (0..num_clients_per_node).map(move |virtual_id| (virtual_id, now)) )); let c_updated_timers = c_received_quorum_payloads .clone() - .map(q!(|key| (key as usize, SystemTime::now()))); + .map(q!(|(key, _prev_count)| (key as usize, Instant::now()))); let c_new_timers = c_timers .clone() // Update c_timers in tick+1 so we can record differences during this tick (to track latency) .union(c_new_timers_when_leader_elected) .union(c_updated_timers.clone()) - .reduce_keyed(q!(|curr_time, new_time| { + .reduce_keyed_commutative(q!(|curr_time, new_time| { if new_time > *curr_time { *curr_time = new_time; } })); c_timers_complete_cycle.complete_next_tick(c_new_timers); - let c_stats_output_timer = clients.source_interval(q!(Duration::from_secs(1))); + let c_stats_output_timer = unsafe { + // SAFETY: intentionally sampling statistics + clients + .source_interval(q!(Duration::from_secs(1))) + .timestamped(&client_tick) + .tick_batch() + } + .first(); - let c_latency_reset = c_stats_output_timer - .clone() - .latest_tick() - .map(q!(|_| None)) - .defer_tick(); + let c_latency_reset = c_stats_output_timer.clone().map(q!(|_| None)).defer_tick(); let c_latencies = c_timers .join(c_updated_timers) .map(q!(|(_virtual_id, (prev_time, curr_time))| Some( - curr_time.duration_since(prev_time).unwrap().as_micros() + curr_time.duration_since(prev_time) ))) .union(c_latency_reset.into_stream()) .all_ticks() - .fold( + .flatten_ordered() + .fold_commutative( // Create window with ring buffer using vec + wraparound index // TODO: Would be nice if I could use vec![] instead, but that doesn't work in HF+ with RuntimeData *median_latency_window_size q!(move || ( - Rc::new(RefCell::new(Vec::::with_capacity( + Rc::new(RefCell::new(Vec::::with_capacity( median_latency_window_size ))), 0usize, - false )), - q!(move |(latencies, write_index, has_any_value), latency| { + q!(move |(latencies, write_index), latency| { let mut latencies_mut = latencies.borrow_mut(); - if let Some(latency) = latency { - // Insert into latencies - if let Some(prev_latency) = latencies_mut.get_mut(*write_index) { - *prev_latency = latency; - } else { - latencies_mut.push(latency); - } - *has_any_value = true; - // Increment write index and wrap around - *write_index += 1; - if *write_index == median_latency_window_size { - *write_index = 0; - } + if *write_index < latencies_mut.len() { + latencies_mut[*write_index] = latency; } else { - // reset latencies - latencies_mut.clear(); - *write_index = 0; - *has_any_value = false; + latencies_mut.push(latency); } + // Increment write index and wrap around + *write_index = (*write_index + 1) % median_latency_window_size; }), - ); + ) + .map(q!(|(latencies, _)| latencies)); + let c_throughput_new_batch = c_received_quorum_payloads .clone() .count() - .continue_unless(c_stats_output_timer.clone().latest_tick()) + .continue_unless(c_stats_output_timer.clone()) .map(q!(|batch_size| (batch_size, false))); let c_throughput_reset = c_stats_output_timer .clone() - .latest_tick() .map(q!(|_| (0, true))) .defer_tick(); @@ -416,40 +271,33 @@ fn bench_client<'a, B: LeaderElected + std::fmt::Debug>( .union(c_throughput_reset) .all_ticks() .fold( - q!(|| (0, 0)), - q!(|(total, num_ticks), (batch_size, reset)| { + q!(|| 0), + q!(|total, (batch_size, reset)| { if reset { *total = 0; - *num_ticks = 0; } else { - *total += batch_size as u32; - *num_ticks += 1; + *total += batch_size; } }), ); - c_stats_output_timer - .cross_singleton(c_latencies) - .cross_singleton(c_throughput) - .tick_samples() - .for_each(q!(move |( - (_, (latencies, _write_index, has_any_value)), - (throughput, num_ticks), - )| { - let mut latencies_mut = latencies.borrow_mut(); - let median_latency = if has_any_value { - let (_, median, _) = - latencies_mut.select_nth_unstable(median_latency_window_size / 2); - *median - } else { - 0 - }; - println!("Median latency: {}ms", median_latency as f64 / 1000.0); - println!("Throughput: {} requests/s", throughput); - println!("Num ticks per second: {}", num_ticks); - })); + unsafe { + // SAFETY: intentionally sampling statistics + c_latencies.zip(c_throughput).latest_tick() + } + .continue_if(c_stats_output_timer) + .all_ticks() + .for_each(q!(move |(latencies, throughput)| { + let mut latencies_mut = latencies.borrow_mut(); + if latencies_mut.len() > 0 { + let middle_idx = latencies_mut.len() / 2; + let (_, median, _) = latencies_mut.select_nth_unstable(middle_idx); + println!("Median latency: {}ms", median.as_micros() as f64 / 1000.0); + } + + println!("Throughput: {} requests/s", throughput); + })); // End track statistics - c_to_proposers } #[cfg(test)] @@ -461,12 +309,12 @@ mod tests { fn paxos_ir() { let builder = hydroflow_plus::FlowBuilder::new(); let _ = super::paxos_bench(&builder, 1, 1, 1, 1, 1, 1, 1); - let built = builder.with_default_optimize(); + let built = builder.with_default_optimize::(); hydroflow_plus::ir::dbg_dedup_tee(|| { insta::assert_debug_snapshot!(built.ir()); }); - let _ = built.compile::(&RuntimeData::new("FAKE")); + let _ = built.compile(&RuntimeData::new("FAKE")); } } diff --git a/hydroflow_plus_test/src/cluster/paxos_kv.rs b/hydroflow_plus_test/src/cluster/paxos_kv.rs new file mode 100644 index 000000000000..d157d67380d1 --- /dev/null +++ b/hydroflow_plus_test/src/cluster/paxos_kv.rs @@ -0,0 +1,202 @@ +use std::collections::HashMap; +use std::fmt::Debug; +use std::hash::Hash; + +use hydroflow_plus::*; +use serde::de::DeserializeOwned; +use serde::{Deserialize, Serialize}; + +use super::paxos::{paxos_core, Acceptor, Ballot, Proposer}; + +pub struct Replica {} + +pub trait KvKey: Serialize + DeserializeOwned + Hash + Eq + Clone + Debug {} +impl KvKey for K {} + +pub trait KvValue: Serialize + DeserializeOwned + Eq + Clone + Debug {} +impl KvValue for V {} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] +pub struct KvPayload { + pub key: K, + pub value: V, +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug)] +pub struct SequencedKv { + // Note: Important that seq is the first member of the struct for sorting + pub seq: usize, + pub kv: Option>, +} + +impl Ord for SequencedKv { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.seq.cmp(&other.seq) + } +} + +impl PartialOrd for SequencedKv { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +/// Sets up a linearizable key-value store using Paxos. +/// +/// # Safety +/// Notifications for leader election are non-deterministic. When the leader is changing, +/// writes may be dropped by the old leader. +#[expect( + clippy::type_complexity, + clippy::too_many_arguments, + reason = "internal paxos code // TODO" +)] +pub unsafe fn paxos_kv<'a, K: KvKey, V: KvValue>( + proposers: &Cluster<'a, Proposer>, + acceptors: &Cluster<'a, Acceptor>, + replicas: &Cluster<'a, Replica>, + c_to_proposers: Stream, Cluster<'a, Proposer>, Unbounded>, + f: usize, + i_am_leader_send_timeout: u64, + i_am_leader_check_timeout: u64, + i_am_leader_check_timeout_delay_multiplier: usize, + checkpoint_frequency: usize, +) -> ( + Stream, Unbounded>, + Stream, Cluster<'a, Replica>, Unbounded>, +) { + let (r_to_acceptors_checkpoint_complete_cycle, r_to_acceptors_checkpoint) = + replicas.forward_ref::>(); + + let (p_to_clients_new_leader_elected, p_to_replicas) = unsafe { + // SAFETY: Leader election non-determinism and non-deterministic dropping of writes is documented. + paxos_core( + proposers, + acceptors, + r_to_acceptors_checkpoint.broadcast_bincode(acceptors), + c_to_proposers, + f, + i_am_leader_send_timeout, + i_am_leader_check_timeout, + i_am_leader_check_timeout_delay_multiplier, + ) + }; + + let (r_to_acceptors_checkpoint_new, r_new_processed_payloads) = replica( + replicas, + p_to_replicas + .map(q!(|(slot, kv)| SequencedKv { seq: slot, kv })) + .broadcast_bincode_interleaved(replicas), + checkpoint_frequency, + ); + + r_to_acceptors_checkpoint_complete_cycle.complete(r_to_acceptors_checkpoint_new); + + (p_to_clients_new_leader_elected, r_new_processed_payloads) +} + +// Replicas. All relations for replicas will be prefixed with r. Expects ReplicaPayload on p_to_replicas, outputs a stream of (client address, ReplicaPayload) after processing. +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +pub fn replica<'a, K: KvKey, V: KvValue>( + replicas: &Cluster<'a, Replica>, + p_to_replicas: Stream, Cluster<'a, Replica>, Unbounded, NoOrder>, + checkpoint_frequency: usize, +) -> ( + Stream, Unbounded>, + Stream, Cluster<'a, Replica>, Unbounded>, +) { + let replica_tick = replicas.tick(); + + let (r_buffered_payloads_complete_cycle, r_buffered_payloads) = replica_tick.cycle(); + // p_to_replicas.inspect(q!(|payload: ReplicaPayload| println!("Replica received payload: {:?}", payload))); + let r_sorted_payloads = unsafe { + // SAFETY: because we fill slots one-by-one, we can safely batch + // because non-determinism is resolved when we sort by slots + p_to_replicas + .timestamped(&replica_tick) + .tick_batch() + } + .union(r_buffered_payloads) // Combine with all payloads that we've received and not processed yet + .sort(); + // Create a cycle since we'll use this seq before we define it + let (r_highest_seq_complete_cycle, r_highest_seq) = + replica_tick.cycle::>(); + // Find highest the sequence number of any payload that can be processed in this tick. This is the payload right before a hole. + let r_highest_seq_processable_payload = r_sorted_payloads + .clone() + .cross_singleton(r_highest_seq.into_singleton()) + .fold( + q!(|| None), + q!(|filled_slot, (sorted_payload, highest_seq)| { + let expected_next_slot = std::cmp::max( + filled_slot.map(|v| v + 1).unwrap_or(0), + highest_seq.map(|v| v + 1).unwrap_or(0), + ); + + if sorted_payload.seq == expected_next_slot { + *filled_slot = Some(sorted_payload.seq); + } + }), + ) + .filter_map(q!(|v| v)); + // Find all payloads that can and cannot be processed in this tick. + let r_processable_payloads = r_sorted_payloads + .clone() + .cross_singleton(r_highest_seq_processable_payload.clone()) + .filter(q!( + |(sorted_payload, highest_seq)| sorted_payload.seq <= *highest_seq + )) + .map(q!(|(sorted_payload, _)| { sorted_payload })); + let r_new_non_processable_payloads = r_sorted_payloads + .clone() + .cross_singleton(r_highest_seq_processable_payload.clone()) + .filter(q!( + |(sorted_payload, highest_seq)| sorted_payload.seq > *highest_seq + )) + .map(q!(|(sorted_payload, _)| { sorted_payload })); + // Save these, we can process them once the hole has been filled + r_buffered_payloads_complete_cycle.complete_next_tick(r_new_non_processable_payloads); + + let r_kv_store = r_processable_payloads + .clone() + .persist() // Optimization: all_ticks() + fold() = fold, where the state of the previous fold is saved and persisted values are deleted. + .fold(q!(|| (HashMap::new(), None)), q!(|(kv_store, last_seq), payload| { + if let Some(kv) = payload.kv { + kv_store.insert(kv.key, kv.value); + } + + debug_assert!(payload.seq == (last_seq.map(|s| s + 1).unwrap_or(0)), "Hole in log between seq {:?} and {}", *last_seq, payload.seq); + *last_seq = Some(payload.seq); + })); + // Update the highest seq for the next tick + let r_new_highest_seq = r_kv_store.filter_map(q!(|(_kv_store, highest_seq)| highest_seq)); + r_highest_seq_complete_cycle.complete_next_tick(r_new_highest_seq.clone()); + + // Send checkpoints to the acceptors when we've processed enough payloads + let (r_checkpointed_seqs_complete_cycle, r_checkpointed_seqs) = + replica_tick.cycle::>(); + let r_max_checkpointed_seq = r_checkpointed_seqs.persist().max().into_singleton(); + let r_checkpoint_seq_new = + r_max_checkpointed_seq + .zip(r_new_highest_seq) + .filter_map(q!( + move |(max_checkpointed_seq, new_highest_seq)| if max_checkpointed_seq + .map(|m| new_highest_seq - m >= checkpoint_frequency) + .unwrap_or(true) + { + Some(new_highest_seq) + } else { + None + } + )); + r_checkpointed_seqs_complete_cycle.complete_next_tick(r_checkpoint_seq_new.clone()); + + // Tell clients that the payload has been committed. All ReplicaPayloads contain the client's machine ID (to string) as value. + let r_to_clients = r_processable_payloads + .filter_map(q!(|payload| payload.kv)) + .all_ticks(); + ( + r_checkpoint_seq_new.all_ticks().drop_timestamp(), + r_to_clients.drop_timestamp(), + ) +} diff --git a/hydroflow_plus_test/src/cluster/pbft.rs b/hydroflow_plus_test/src/cluster/pbft.rs deleted file mode 100644 index ce128330fa8b..000000000000 --- a/hydroflow_plus_test/src/cluster/pbft.rs +++ /dev/null @@ -1,390 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::time::{Duration, SystemTime}; - -use hydroflow_plus::*; -use serde::{Deserialize, Serialize}; -use stageleft::*; -use tokio::time::Instant; - -pub struct Client {} -pub struct Replica {} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct Request { - pub client_id: u32, - pub operation: String, - pub timestamp: u64, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct Reply { - pub view: u32, - pub timestamp: u64, - pub client_id: u32, - pub replica_id: u32, - pub result: String, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct PrePrepare { - pub view: u32, - pub sequence_number: u64, - pub request: Request, - pub digest: String, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct Prepare { - pub view: u32, - pub sequence_number: u64, - pub digest: String, - pub replica_id: u32, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct Commit { - pub view: u32, - pub sequence_number: u64, - pub digest: String, - pub replica_id: u32, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct ViewChange { - pub view: u32, - pub replica_id: u32, - pub last_sequence_number: u64, - pub P: Vec, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct NewView { - pub view: u32, - pub V: Vec, - pub O: Vec, -} - -#[derive(Serialize, Deserialize, PartialEq, Eq, Clone, Debug, Hash)] -pub struct Prepared { - pub view: u32, - pub sequence_number: u64, - pub digest: String, -} - -pub fn pbft<'a>( - flow: &FlowBuilder<'a>, - num_clients_per_node: usize, - f: usize, - throughput_window_size: usize, - view_timeout: u64, -) -> ( - Cluster, - Cluster, -) { - let clients = flow.cluster::(); - let replicas = flow.cluster::(); - - let client_id = flow.cluster_self_id(&clients); - let replica_id = flow.cluster_self_id(&replicas); - - let num_replicas = 3 * f + 1; - - // Define the current view number, starting from 0 - let (current_view_cycle, current_view_stream) = flow.tick_cycle_with_initial( - &replicas, - flow.singleton(&replicas, q!(0u32)).latest_tick(), - ); - let current_view = current_view_stream.latest(); - - // Each replica determines if it's the primary (leader) for the current view - let is_primary = current_view - .map(q!(move |view| (*view % (num_replicas as u32)) == replica_id)) - .latest_tick(); - - // Client sends requests - let client_requests = flow.source_iter(&clients, q!([ - Request { - client_id, - operation: "operation1".to_string(), - timestamp: 1, - }, - Request { - client_id, - operation: "operation2".to_string(), - timestamp: 2, - }, - Request { - client_id, - operation: "operation3".to_string(), - timestamp: 3, - }, - ])); - - // Clients broadcast requests to all replicas - let requests_to_replicas = client_requests.broadcast_bincode(&replicas); - - // Each replica filters requests intended for the current primary - let requests_to_primary = requests_to_replicas - .cross_singleton(current_view.clone()) - .filter(q!(move |(request, view)| { - (*view % (num_replicas as u32)) == replica_id - })) - .map(q!(|(request, _)| request.clone())) - .continue_if(is_primary.clone()); - - // The primary processes the requests and creates PrePrepare messages - let (sequence_number_cycle, sequence_number_stream) = flow.tick_cycle_with_initial( - &replicas, - flow.singleton(&replicas, q!(0u64)).latest_tick(), - ); - let sequence_number = sequence_number_stream.latest(); - - let pre_prepares = requests_to_primary - .enumerate() - .cross_singleton(current_view.clone()) - .cross_singleton(sequence_number.clone()) - .map(q!(move |(((index, request), view), seq_num)| PrePrepare { - view: *view, - sequence_number: *seq_num + index as u64 + 1, - request: request.clone(), - digest: format!("{:?}", request), - })) - .persist(); - - // Update the sequence number for the next batch - let next_sequence_number = sequence_number - .cross_singleton(pre_prepares.clone().count()) - .map(q!(|(seq_num, count)| seq_num + count as u64)) - .defer_tick(); - sequence_number_cycle.complete(next_sequence_number.into()); - - // The primary broadcasts PrePrepare messages to all replicas - let pre_prepares_broadcast = pre_prepares.clone().broadcast_bincode(&replicas); - - // Replicas receive PrePrepare messages - let received_pre_prepares = pre_prepares_broadcast.tick_batch(); - - // Replicas verify PrePrepare messages and create Prepare messages - let prepares = received_pre_prepares - .cross_singleton(replica_id.clone()) - .map(q!(|pre_prepare, replica_id| Prepare { - view: pre_prepare.view, - sequence_number: pre_prepare.sequence_number, - digest: pre_prepare.digest.clone(), - replica_id, - })) - .broadcast_bincode(&replicas); - - // Replicas receive Prepare messages - let received_prepares = prepares.tick_batch(); - - // Collect Prepare messages - let prepare_counts = received_prepares - .map(q!(|prepare| ((prepare.view, prepare.sequence_number, prepare.digest.clone()), prepare.replica_id))) - .fold_keyed( - q!(|| HashSet::new()), - q!(|set, replica_id| { set.insert(replica_id); }), - ); - - // Check if enough Prepare messages have been collected to move to the Commit phase - let prepared_certificates = prepare_counts - .filter(q!(move |(_, set)| set.len() >= 2 * f)) - .map(q!(|(key, _)| Prepared { - view: key.0, - sequence_number: key.1, - digest: key.2.clone(), - })) - .persist(); - - // Replicas create Commit messages and broadcast them - let commits = prepared_certificates - .cross_singleton(replica_id.clone()) - .map(q!(|cert, replica_id| Commit { - view: cert.view, - sequence_number: cert.sequence_number, - digest: cert.digest.clone(), - replica_id, - })) - .broadcast_bincode(&replicas); - - // Replicas receive Commit messages - let received_commits = commits.tick_batch(); - - // Collect Commit messages - let commit_counts = received_commits - .map(q!(|commit| ((commit.view, commit.sequence_number, commit.digest.clone()), commit.replica_id))) - .fold_keyed( - q!(|| HashSet::new()), - q!(|set, replica_id| { set.insert(replica_id); }), - ); - - // Replicas execute requests after receiving enough Commit messages - let executed_requests = commit_counts - .filter(q!(move |(_, set)| set.len() >= 2 * f + 1)) - .map(q!(|(key, _)| { - println!("Replica {} executed request at view {}, seq {}", replica_id, key.0, key.1); - (key.1, key.2.clone()) - })) - .persist(); - - // Maintain the highest sequence number executed - let highest_sequence_number_stream = executed_requests - .map(q!(|(seq_num, _)| seq_num)) - .max() - .unwrap_or(flow.singleton(&replicas, q!(0u64)).latest_tick()); - - let highest_sequence_number = highest_sequence_number_stream.latest_tick(); - - // View change mechanism - - // Define a timeout to detect primary failure - let timeout_interval = flow - .source_interval(&replicas, q!(Duration::from_secs(view_timeout))) - .latest_tick(); - - // Replicas send ViewChange messages upon timeout - let view_changes = timeout_interval - .cross_singleton(current_view.clone()) - .cross_singleton(replica_id.clone()) - .cross_singleton(highest_sequence_number.clone()) - .cross_singleton(prepared_certificates.clone().collect()) - .map(q!(move |(((((), view), replica_id), last_seq_num), prepared)| ViewChange { - view: *view + 1, - replica_id, - last_sequence_number: *last_seq_num, - P: prepared.clone(), - })) - .broadcast_bincode(&replicas); - - // Replicas receive ViewChange messages - let received_view_changes = view_changes.tick_batch(); - - let view_change_counts = received_view_changes - .map(q!(|vc| (vc.view, vc))) - .fold_keyed( - q!(|| Vec::new()), - q!(|vec, vc| { vec.push(vc); }), - ); - - // Check if enough ViewChange messages have been collected to form a NewView - let new_views = view_change_counts - .filter(q!(move |(_, vec)| vec.len() >= 2 * f + 1)) - .map(q!(|(view, vcs)| NewView { - view, - V: vcs.clone(), - O: vec![], // This should be constructed based on V and P - })) - .broadcast_bincode(&replicas); - - // Replicas receive NewView messages and update the current view - let received_new_views = new_views.tick_batch(); - - let updated_view = received_new_views - .map(q!(|nv| nv.view)) - .latest_tick(); - - // Update the current view - current_view_cycle.complete(updated_view.into()); - - // Each replica determines if it is the new primary after view change - let new_is_primary = updated_view - .map(q!(move |view| (*view % (num_replicas as u32)) == replica_id)) - .latest_tick(); - - // The new primary processes any pending requests from ViewChange messages and generates new PrePrepare messages - // For simplicity, we'll assume there are no pending requests in this example - // In practice, you would reconstruct O based on the V and P collections in the NewView message - - // Benchmark code similar to Paxos implementation - - // Track throughput - - // Define a timer for statistics output - let stats_interval = flow.source_interval(&clients, q!(Duration::from_secs(1))); - - // Collect the number of executed requests - let executed_requests_count = executed_requests - .count() - .continue_unless(stats_interval.clone().latest_tick()) - .map(q!(|count| (count, false))); - - let reset_throughput = stats_interval - .clone() - .latest_tick() - .map(q!(|_| (0usize, true))) - .defer_tick(); - - let throughput = executed_requests_count - .union(reset_throughput) - .all_ticks() - .fold( - q!(|| 0usize), - q!(|(total, (count, reset))| { - if reset { - *total = 0; - } else { - *total += count; - } - }), - ); - - // Output throughput - stats_interval - .cross_singleton(throughput.clone()) - .tick_samples() - .for_each(q!(move |(_, total)| { - println!("Throughput: {} requests/s", total); - })); - - // Latency tracking - - // Create cycles to track request send and execution times - let (request_times_cycle, request_times_stream) = flow.cycle(&clients); - let request_times = request_times_stream.latest_tick(); - - // When clients send requests, record the timestamp - let client_request_times = client_requests - .map(q!(move |_| (client_id, SystemTime::now()))) - .persist(); - - request_times_cycle.complete(client_request_times.into()); - - // When replicas execute requests, record the timestamp - let execution_times = executed_requests - .map(q!(move |(seq_num, digest)| (seq_num, digest, SystemTime::now()))) - .broadcast_bincode(&clients); - - // Clients receive execution times and calculate latency - let latencies = execution_times - .cross_singleton(request_times.clone()) - .map(q!(|((seq_num, digest, exec_time), (client_id, send_time))| { - let latency = exec_time.duration_since(send_time).unwrap_or(Duration::ZERO); - latency.as_millis() - })) - .collect() - .latest_tick(); - - // Calculate average latency over the window - let average_latency = latencies - .map(q!(move |latencies_vec| { - if latencies_vec.is_empty() { - 0 - } else { - let sum: u128 = latencies_vec.iter().sum(); - (sum / latencies_vec.len() as u128) as usize - } - })); - - // Output latency - stats_interval - .cross_singleton(average_latency) - .tick_samples() - .for_each(q!(move |(_, avg_latency)| { - println!("Average Latency: {} ms", avg_latency); - })); - - ( - clients, - replicas, - ) -} diff --git a/hydroflow_plus_test/src/cluster/quorum.rs b/hydroflow_plus_test/src/cluster/quorum.rs new file mode 100644 index 000000000000..7a6547e17018 --- /dev/null +++ b/hydroflow_plus_test/src/cluster/quorum.rs @@ -0,0 +1,178 @@ +use std::hash::Hash; + +use hydroflow_plus::*; +use location::NoTick; + +#[expect(clippy::type_complexity, reason = "internal paxos code // TODO")] +pub fn collect_quorum_with_response< + 'a, + L: Location<'a> + NoTick, + Order, + K: Clone + Eq + Hash, + V: Clone, + E: Clone, +>( + responses: Stream<(K, Result), Timestamped, Unbounded, Order>, + min: usize, + max: usize, +) -> ( + Stream<(K, V), Timestamped, Unbounded, Order>, + Stream<(K, E), Timestamped, Unbounded, Order>, +) { + let tick = responses.timestamp_source(); + let (not_all_complete_cycle, not_all) = tick.cycle::>(); + + let current_responses = not_all.union(unsafe { + // SAFETY: we always persist values that have not reached quorum, so even + // with arbitrary batching we always produce deterministic quorum results + responses.clone().tick_batch() + }); + + let count_per_key = current_responses.clone().fold_keyed_commutative( + q!(move || (0, 0)), + q!(move |accum, value| { + if value.is_ok() { + accum.0 += 1; + } else { + accum.1 += 1; + } + }), + ); + + let not_reached_min_count = + count_per_key + .clone() + .filter_map(q!(move |(key, (success, _error))| if success < min { + Some(key) + } else { + None + })); + + let reached_min_count = + count_per_key + .clone() + .filter_map(q!(move |(key, (success, _error))| if success >= min { + Some(key) + } else { + None + })); + + let just_reached_quorum = if max == min { + not_all_complete_cycle + .complete_next_tick(current_responses.clone().anti_join(reached_min_count)); + + current_responses.anti_join(not_reached_min_count) + } else { + let (min_but_not_max_complete_cycle, min_but_not_max) = tick.cycle(); + + let received_from_all = + count_per_key.filter_map(q!( + move |(key, (success, error))| if (success + error) >= max { + Some(key) + } else { + None + } + )); + + min_but_not_max_complete_cycle + .complete_next_tick(reached_min_count.filter_not_in(received_from_all.clone())); + + not_all_complete_cycle + .complete_next_tick(current_responses.clone().anti_join(received_from_all)); + + current_responses + .anti_join(not_reached_min_count) + .anti_join(min_but_not_max) + }; + + ( + just_reached_quorum + .filter_map(q!(move |(key, res)| match res { + Ok(v) => Some((key, v)), + Err(_) => None, + })) + .all_ticks(), + responses.filter_map(q!(move |(key, res)| match res { + Ok(_) => None, + Err(e) => Some((key, e)), + })), + ) +} + +#[expect(clippy::type_complexity, reason = "quorum types are complex")] +pub fn collect_quorum<'a, L: Location<'a> + NoTick, Order, K: Clone + Eq + Hash, E: Clone>( + responses: Stream<(K, Result<(), E>), Timestamped, Unbounded, Order>, + min: usize, + max: usize, +) -> ( + Stream, Unbounded, Order>, + Stream<(K, E), Timestamped, Unbounded, Order>, +) { + let tick = responses.timestamp_source(); + let (not_all_complete_cycle, not_all) = tick.cycle::>(); + + let current_responses = not_all.union(unsafe { + // SAFETY: we always persist values that have not reached quorum, so even + // with arbitrary batching we always produce deterministic quorum results + responses.clone().tick_batch() + }); + + let count_per_key = current_responses.clone().fold_keyed_commutative( + q!(move || (0, 0)), + q!(move |accum, value| { + if value.is_ok() { + accum.0 += 1; + } else { + accum.1 += 1; + } + }), + ); + + let reached_min_count = + count_per_key + .clone() + .filter_map(q!(move |(key, (success, _error))| if success >= min { + Some(key) + } else { + None + })); + + let just_reached_quorum = if max == min { + not_all_complete_cycle.complete_next_tick( + current_responses + .clone() + .anti_join(reached_min_count.clone()), + ); + + reached_min_count + } else { + let (min_but_not_max_complete_cycle, min_but_not_max) = tick.cycle(); + + let received_from_all = + count_per_key.filter_map(q!( + move |(key, (success, error))| if (success + error) >= max { + Some(key) + } else { + None + } + )); + + min_but_not_max_complete_cycle.complete_next_tick( + reached_min_count + .clone() + .filter_not_in(received_from_all.clone()), + ); + + not_all_complete_cycle.complete_next_tick(current_responses.anti_join(received_from_all)); + + reached_min_count.filter_not_in(min_but_not_max) + }; + + ( + just_reached_quorum.all_ticks(), + responses.filter_map(q!(move |(key, res)| match res { + Ok(_) => None, + Err(e) => Some((key, e)), + })), + ) +} diff --git a/hydroflow_plus_test/src/cluster/request_response.rs b/hydroflow_plus_test/src/cluster/request_response.rs new file mode 100644 index 000000000000..492c06da865e --- /dev/null +++ b/hydroflow_plus_test/src/cluster/request_response.rs @@ -0,0 +1,42 @@ +use std::hash::Hash; + +use hydroflow_plus::*; +use location::NoTick; + +type JoinResponses = Stream<(K, (M, V)), Timestamped, Unbounded, NoOrder>; + +/// Given an incoming stream of request-response responses, joins with metadata generated +/// at request time that is stored in-memory. +/// +/// The metadata must be generated in the same or a previous tick than the response, +/// typically at request time. Only one response element should be produced with a given +/// key, same for the metadata stream. +pub fn join_responses<'a, K: Clone + Eq + Hash, M: Clone, V: Clone, L: Location<'a> + NoTick>( + tick: &Tick, + responses: Stream<(K, V), Timestamped, Unbounded, NoOrder>, + metadata: Stream<(K, M), Tick, Bounded, NoOrder>, +) -> JoinResponses { + let (remaining_to_join_complete_cycle, remaining_to_join) = + tick.cycle::>(); + + let remaining_and_new: Stream<(K, M), Tick, Bounded, _> = remaining_to_join.union(metadata); + + let responses = unsafe { + // SAFETY: because we persist the metadata, delays resulting from + // batching boundaries do not affect the output contents. + responses.tick_batch() + }; + + // TODO(shadaj): we should have a "split-join" operator + // that returns both join and anti-join without cloning + let joined_this_tick = + remaining_and_new + .clone() + .join(responses.clone()) + .map(q!(|(key, (meta, resp))| (key, (meta, resp)))); + + remaining_to_join_complete_cycle + .complete_next_tick(remaining_and_new.anti_join(responses.map(q!(|(key, _)| key)))); + + joined_this_tick.all_ticks() +} diff --git a/hydroflow_plus_test/src/cluster/simple_cluster.rs b/hydroflow_plus_test/src/cluster/simple_cluster.rs index 771a7ed1c97b..64b7e5045f9b 100644 --- a/hydroflow_plus_test/src/cluster/simple_cluster.rs +++ b/hydroflow_plus_test/src/cluster/simple_cluster.rs @@ -1,19 +1,16 @@ use hydroflow_plus::*; -use stageleft::*; pub fn decouple_cluster<'a>(flow: &FlowBuilder<'a>) -> (Cluster<'a, ()>, Cluster<'a, ()>) { let cluster1 = flow.cluster(); let cluster2 = flow.cluster(); - let cluster_self_id = cluster2.self_id(); - let cluster1_self_id = cluster1.self_id(); cluster1 - .source_iter(q!(vec!(cluster1_self_id))) + .source_iter(q!(vec!(CLUSTER_SELF_ID))) // .for_each(q!(|message| println!("hey, {}", message))) .inspect(q!(|message| println!("Cluster1 node sending message: {}", message))) .decouple_cluster(&cluster2) .for_each(q!(move |message| println!( "My self id is {}, my message is {}", - cluster_self_id, message + CLUSTER_SELF_ID, message ))); (cluster1, cluster2) } @@ -35,17 +32,13 @@ pub fn simple_cluster<'a>(flow: &FlowBuilder<'a>) -> (Process<'a, ()>, Cluster<' let numbers = process.source_iter(q!(0..5)); let ids = process.source_iter(cluster.members()).map(q!(|&id| id)); - let cluster_self_id = cluster.self_id(); - ids.cross_product(numbers) .map(q!(|(id, n)| (id, (id, n)))) .send_bincode(&cluster) - .tick_batch() .inspect(q!(move |n| println!( "cluster received: {:?} (self cluster id: {})", - n, cluster_self_id + n, CLUSTER_SELF_ID ))) - .all_ticks() .send_bincode(&process) .for_each(q!(|(id, d)| println!("node received: ({}, {:?})", id, d))); @@ -55,7 +48,7 @@ pub fn simple_cluster<'a>(flow: &FlowBuilder<'a>) -> (Process<'a, ()>, Cluster<' #[cfg(test)] mod tests { use hydro_deploy::Deployment; - use hydroflow_plus::deploy::{DeployCrateWrapper, TrybuildHost}; + use hydroflow_plus::deploy::DeployCrateWrapper; #[tokio::test] async fn simple_cluster() { @@ -68,13 +61,8 @@ mod tests { insta::assert_debug_snapshot!(built.ir()); let nodes = built - .with_process(&node, TrybuildHost::new(deployment.Localhost())) - .with_cluster( - &cluster, - (0..2) - .map(|_| TrybuildHost::new(deployment.Localhost())) - .collect::>(), - ) + .with_process(&node, deployment.Localhost()) + .with_cluster(&cluster, (0..2).map(|_| deployment.Localhost())) .deploy(&mut deployment); deployment.deploy().await.unwrap(); @@ -128,8 +116,8 @@ mod tests { let built = builder.with_default_optimize(); let nodes = built - .with_process(&process1, TrybuildHost::new(deployment.Localhost())) - .with_process(&process2, TrybuildHost::new(deployment.Localhost())) + .with_process(&process1, deployment.Localhost()) + .with_process(&process2, deployment.Localhost()) .deploy(&mut deployment); deployment.deploy().await.unwrap(); @@ -150,18 +138,8 @@ mod tests { let built = builder.with_default_optimize(); let nodes = built - .with_cluster( - &cluster1, - (0..3) - .map(|_| TrybuildHost::new(deployment.Localhost())) - .collect::>(), - ) - .with_cluster( - &cluster2, - (0..3) - .map(|_| TrybuildHost::new(deployment.Localhost())) - .collect::>(), - ) + .with_cluster(&cluster1, (0..3).map(|_| deployment.Localhost())) + .with_cluster(&cluster2, (0..3).map(|_| deployment.Localhost())) .deploy(&mut deployment); deployment.deploy().await.unwrap(); diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir.snap index 70a8dd42e91b..751772daad6c 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir.snap @@ -6,13 +6,13 @@ expression: built.ir() ForEach { f: stageleft :: runtime_support :: fn1_type_hint :: < (u64 , u64) , () > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (inside , total) | { println ! ("pi: {} ({} trials)" , 4.0 * inside as f64 / total as f64 , total) ; } }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((u64 , u64) , ()) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + f: stageleft :: runtime_support :: fn1_type_hint :: < ((u64 , u64) , ()) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), input: CrossSingleton( Reduce { f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (u64 , u64) , (u64 , u64) , () > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (inside , total) , (inside_batch , total_batch) | { * inside += inside_batch ; * total += total_batch ; } }), input: Persist( Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: compute_pi :: Worker > , (u64 , u64)) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: compute_pi :: Worker > , (u64 , u64)) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), input: Network { from_location: Cluster( 0, @@ -51,9 +51,9 @@ expression: built.ir() input: Map { f: stageleft :: runtime_support :: fn1_type_hint :: < () , (f64 , f64) > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | _ | rand :: random :: < (f64 , f64) > () }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: location :: * ; | _ | () }), + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: location :: tick :: * ; | _ | () }), input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < () , std :: ops :: Range < usize > > ({ use hydroflow_plus :: __staged :: location :: * ; let batch_size = { use crate :: __staged :: cluster :: compute_pi :: * ; let batch_size = 8192usize ; batch_size } ; move | _ | 0 .. batch_size }), + f: stageleft :: runtime_support :: fn1_type_hint :: < () , std :: ops :: Range < usize > > ({ use hydroflow_plus :: __staged :: location :: tick :: * ; let batch_size__free = { use crate :: __staged :: cluster :: compute_pi :: * ; let batch_size__free = 8192usize ; batch_size__free } ; move | _ | 0 .. batch_size__free }), input: Source { source: Spin, location_kind: Cluster( @@ -70,10 +70,10 @@ expression: built.ir() ), }, Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), input: Source { - source: Interval( - stageleft :: runtime_support :: type_hint :: < core :: time :: Duration > ({ use crate :: __staged :: cluster :: compute_pi :: * ; Duration :: from_secs (1) }), + source: Stream( + { use hydroflow_plus :: __staged :: location :: * ; let interval__free = { use crate :: __staged :: cluster :: compute_pi :: * ; Duration :: from_secs (1) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval (interval__free)) }, ), location_kind: Process( 1, diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_0.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_0.snap index 41e4f54f9479..6e5ae9003103 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_0.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_0.snap @@ -3,13 +3,13 @@ source: hydroflow_plus_test/src/cluster/compute_pi.rs expression: ir.surface_syntax_string() --- 1v1 = spin (); -2v1 = flat_map (stageleft :: runtime_support :: fn1_type_hint :: < () , std :: ops :: Range < usize > > ({ use hydroflow_plus :: __staged :: location :: * ; let batch_size = { use crate :: __staged :: cluster :: compute_pi :: * ; let batch_size = 8192usize ; batch_size } ; move | _ | 0 .. batch_size })); -3v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: location :: * ; | _ | () })); +2v1 = flat_map (stageleft :: runtime_support :: fn1_type_hint :: < () , std :: ops :: Range < usize > > ({ use hydroflow_plus :: __staged :: location :: tick :: * ; let batch_size__free = { use crate :: __staged :: cluster :: compute_pi :: * ; let batch_size__free = 8192usize ; batch_size__free } ; move | _ | 0 .. batch_size__free })); +3v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: location :: tick :: * ; | _ | () })); 4v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < () , (f64 , f64) > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | _ | rand :: random :: < (f64 , f64) > () })); 5v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (f64 , f64) , bool > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (x , y) | x * x + y * y < 1.0 })); 6v1 = fold :: < 'tick > (stageleft :: runtime_support :: fn0_type_hint :: < (u64 , u64) > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | | (0u64 , 0u64) }) , stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (u64 , u64) , bool , () > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (inside , total) , sample_inside | { if sample_inside { * inside += 1 ; } * total += 1 ; } })); 7v1 = map (| data | { hydroflow_plus :: runtime_support :: bincode :: serialize :: < (u64 , u64) > (& data) . unwrap () . into () }); -8v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c1_port = "port_0" ; let env = FAKE ; { env . port (c1_port) . connect_local_blocking :: < ConnectedDirect > () . into_sink () } }); +8v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c1_port__free = "port_0" ; let env__free = FAKE ; { env__free . port (c1_port__free) . connect_local_blocking :: < ConnectedDirect > () . into_sink () } }); 1v1 -> 2v1; 2v1 -> 3v1; diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_1.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_1.snap index c73fdb714a8e..d884f0ba97ca 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_1.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__compute_pi__tests__compute_pi_ir@surface_graph_1.snap @@ -2,14 +2,14 @@ source: hydroflow_plus_test/src/cluster/compute_pi.rs expression: ir.surface_syntax_string() --- -1v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env = FAKE ; let p2_port = "port_0" ; { env . port (p2_port) . connect_local_blocking :: < ConnectedTagged < ConnectedDirect > > () . into_source () } }); +1v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env__free = FAKE ; let p2_port__free = "port_0" ; { env__free . port (p2_port__free) . connect_local_blocking :: < ConnectedTagged < ConnectedDirect > > () . into_source () } }); 2v1 = map (| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: compute_pi :: Worker > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (u64 , u64) > (& b) . unwrap ()) }); -3v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: compute_pi :: Worker > , (u64 , u64)) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b })); +3v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: compute_pi :: Worker > , (u64 , u64)) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b })); 4v1 = reduce :: < 'static > (stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (u64 , u64) , (u64 , u64) , () > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (inside , total) , (inside_batch , total_batch) | { * inside += inside_batch ; * total += total_batch ; } })); -5v1 = source_interval (stageleft :: runtime_support :: type_hint :: < core :: time :: Duration > ({ use crate :: __staged :: cluster :: compute_pi :: * ; Duration :: from_secs (1) })); -6v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () })); +5v1 = source_stream ({ use hydroflow_plus :: __staged :: location :: * ; let interval__free = { use crate :: __staged :: cluster :: compute_pi :: * ; Duration :: from_secs (1) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval (interval__free)) }); +6v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () })); 7v1 = cross_singleton (); -8v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < ((u64 , u64) , ()) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d })); +8v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < ((u64 , u64) , ()) , (u64 , u64) > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d })); 9v1 = for_each (stageleft :: runtime_support :: fn1_type_hint :: < (u64 , u64) , () > ({ use crate :: __staged :: cluster :: compute_pi :: * ; | (inside , total) | { println ! ("pi: {} ({} trials)" , 4.0 * inside as f64 / total as f64 , total) ; } })); 1v1 -> 2v1; diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__many_to_many__tests__many_to_many.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__many_to_many__tests__many_to_many.snap index d58ad11b7168..6c202ced1d14 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__many_to_many__tests__many_to_many.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__many_to_many__tests__many_to_many.snap @@ -4,7 +4,7 @@ expression: built.ir() --- [ ForEach { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < () > , i32) , () > ({ use crate :: __staged :: cluster :: many_to_many :: * ; | n | println ! ("cluster received: {:?}" , n) }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) , () > ({ use crate :: __staged :: cluster :: many_to_many :: * ; | n | println ! ("cluster received: {:?}" , n) }), input: Network { from_location: Cluster( 0, @@ -36,7 +36,7 @@ expression: built.ir() ), ), input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < () > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < () > > > (__hydroflow_plus_cluster_ids_0) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < () > > > (__hydroflow_plus_cluster_ids_0) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), input: Source { source: Iter( { use crate :: __staged :: cluster :: many_to_many :: * ; 0 .. 2 }, diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir.snap index c895c3413a7c..2f1d441de9d8 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir.snap @@ -9,7 +9,7 @@ expression: built.ir() f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | total , count | * total += count }), input: Persist( Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , (std :: string :: String , i32)) , (std :: string :: String , i32) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , (std :: string :: String , i32)) , (std :: string :: String , i32) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), input: Network { from_location: Cluster( 1, @@ -78,9 +78,10 @@ expression: built.ir() ), ), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , std :: string :: String) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , std :: string :: String) > ({ use crate :: __staged :: cluster :: map_reduce :: * ; let all_ids_vec = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > > > (__hydroflow_plus_cluster_ids_1) } ; | (i , w) | (ClusterId :: from_raw ((i % all_ids_vec . len ()) as u32) , w) }), - input: Enumerate( - Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , std :: string :: String) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , std :: string :: String) > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > > > (__hydroflow_plus_cluster_ids_1) } ; | (i , w) | (ids__free [i % ids__free . len ()] , w) }), + input: Enumerate { + is_static: true, + input: Map { f: stageleft :: runtime_support :: fn1_type_hint :: < & str , std :: string :: String > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | s | s . to_string () }), input: Source { source: Iter( @@ -91,7 +92,7 @@ expression: built.ir() ), }, }, - ), + }, }, }, }, diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_0.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_0.snap index 06befe0c8323..417b0bc0ff76 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_0.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_0.snap @@ -4,13 +4,13 @@ expression: ir.surface_syntax_string() --- 1v1 = source_iter ({ use crate :: __staged :: cluster :: map_reduce :: * ; vec ! ["abc" , "abc" , "xyz" , "abc"] }); 2v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < & str , std :: string :: String > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | s | s . to_string () })); -3v1 = enumerate (); -4v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (usize , std :: string :: String) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , std :: string :: String) > ({ use crate :: __staged :: cluster :: map_reduce :: * ; let all_ids_vec = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > > > (__hydroflow_plus_cluster_ids_1) } ; | (i , w) | (ClusterId :: from_raw ((i % all_ids_vec . len ()) as u32) , w) })); +3v1 = enumerate :: < 'static > (); +4v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (usize , std :: string :: String) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , std :: string :: String) > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > > > (__hydroflow_plus_cluster_ids_1) } ; | (i , w) | (ids__free [i % ids__free . len ()] , w) })); 5v1 = map (| (id , data) : (hydroflow_plus :: ClusterId < _ > , std :: string :: String) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < std :: string :: String > (& data) . unwrap () . into ()) }); -6v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env = FAKE ; let p1_port = "port_0" ; { env . port (p1_port) . connect_local_blocking :: < ConnectedDemux < ConnectedDirect > > () . into_sink () } }); -7v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env = FAKE ; let p2_port = "port_1" ; { env . port (p2_port) . connect_local_blocking :: < ConnectedTagged < ConnectedDirect > > () . into_source () } }); +6v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env__free = FAKE ; let p1_port__free = "port_0" ; { env__free . port (p1_port__free) . connect_local_blocking :: < ConnectedDemux < ConnectedDirect > > () . into_sink () } }); +7v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let env__free = FAKE ; let p2_port__free = "port_1" ; { env__free . port (p2_port__free) . connect_local_blocking :: < ConnectedTagged < ConnectedDirect > > () . into_source () } }); 8v1 = map (| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: map_reduce :: Worker > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (std :: string :: String , i32) > (& b) . unwrap ()) }); -9v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , (std :: string :: String , i32)) , (std :: string :: String , i32) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b })); +9v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: map_reduce :: Worker > , (std :: string :: String , i32)) , (std :: string :: String , i32) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b })); 10v1 = reduce_keyed :: < 'static > (stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | total , count | * total += count })); 11v1 = for_each (stageleft :: runtime_support :: fn1_type_hint :: < (std :: string :: String , i32) , () > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | (string , count) | println ! ("{}: {}" , string , count) })); diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_1.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_1.snap index 2c79806257e9..4024ed117c8d 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_1.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__map_reduce__tests__map_reduce_ir@surface_graph_1.snap @@ -2,13 +2,13 @@ source: hydroflow_plus_test/src/cluster/map_reduce.rs expression: ir.surface_syntax_string() --- -1v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c2_port = "port_0" ; let env = FAKE ; { env . port (c2_port) . connect_local_blocking :: < ConnectedDirect > () . into_source () } }); +1v1 = source_stream ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c2_port__free = "port_0" ; let env__free = FAKE ; { env__free . port (c2_port__free) . connect_local_blocking :: < ConnectedDirect > () . into_source () } }); 2v1 = map (| res | { hydroflow_plus :: runtime_support :: bincode :: deserialize :: < std :: string :: String > (& res . unwrap ()) . unwrap () }); 3v1 = map (stageleft :: runtime_support :: fn1_type_hint :: < std :: string :: String , (std :: string :: String , ()) > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | string | (string , ()) })); 4v1 = fold_keyed :: < 'tick > (stageleft :: runtime_support :: fn0_type_hint :: < i32 > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | | 0 }) , stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , () , () > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | count , _ | * count += 1 })); 5v1 = inspect (stageleft :: runtime_support :: fn1_borrow_type_hint :: < (std :: string :: String , i32) , () > ({ use crate :: __staged :: cluster :: map_reduce :: * ; | (string , count) | println ! ("partition count: {} - {}" , string , count) })); 6v1 = map (| data | { hydroflow_plus :: runtime_support :: bincode :: serialize :: < (std :: string :: String , i32) > (& data) . unwrap () . into () }); -7v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c1_port = "port_1" ; let env = FAKE ; { env . port (c1_port) . connect_local_blocking :: < ConnectedDirect > () . into_sink () } }); +7v1 = dest_sink ({ use hydroflow_plus :: __staged :: deploy :: deploy_runtime :: * ; let c1_port__free = "port_1" ; let env__free = FAKE ; { env__free . port (c1_port__free) . connect_local_blocking :: < ConnectedDirect > () . into_sink () } }); 1v1 -> 2v1; 2v1 -> 3v1; diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__paxos_bench__tests__paxos_ir.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__paxos_bench__tests__paxos_ir.snap index f20193cd83b1..30433787404a 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__paxos_bench__tests__paxos_ir.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__paxos_bench__tests__paxos_ir.snap @@ -10,272 +10,194 @@ expression: built.ir() { use crate :: __staged :: cluster :: paxos :: * ; ["Proposers say hello"] }, ), location_kind: Cluster( - 2, + 0, + ), + }, + }, + ForEach { + f: stageleft :: runtime_support :: fn1_type_hint :: < & str , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | s | println ! ("{}" , s) }), + input: Source { + source: Iter( + { use crate :: __staged :: cluster :: paxos :: * ; ["Acceptors say hello"] }, + ), + location_kind: Cluster( + 1, ), }, }, CycleSink { ident: Ident { - sym: cycle_3, + sym: cycle_4, }, - location_kind: Cluster( + location_kind: Tick( 2, + Cluster( + 0, + ), ), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , u32) , u32 > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | (received_max_ballot , ballot_num) | { if received_max_ballot > (Ballot { num : ballot_num , id : p_id , }) { received_max_ballot . num + 1 } else { ballot_num } } }), - input: CrossSingleton( - Tee { - inner: : Union( - Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), - input: Persist( - Union( - Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ , p1b) | p1b . max_ballot }), - input: Tee { - inner: : CycleSource { - ident: Ident { - sym: cycle_1, - }, - location_kind: Cluster( - 2, - ), + input: DeferTick( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , u32) , u32 > ({ use crate :: __staged :: cluster :: paxos :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_0) ; move | (received_max_ballot , ballot_num) | { if received_max_ballot > (Ballot { num : ballot_num , proposer_id : CLUSTER_SELF_ID__free , }) { received_max_ballot . num + 1 } else { ballot_num } } }), + input: CrossSingleton( + Tee { + inner: : Chain( + Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), + input: Persist( + Chain( + Chain( + CycleSource { + ident: Ident { + sym: cycle_1, }, + location_kind: Cluster( + 0, + ), }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ , p2b) | p2b . max_ballot }), - input: Tee { - inner: : CycleSource { - ident: Ident { - sym: cycle_2, - }, - location_kind: Cluster( - 2, - ), + CycleSource { + ident: Ident { + sym: cycle_0, }, + location_kind: Cluster( + 0, + ), }, - }, - ), - Tee { - inner: : CycleSource { + ), + CycleSource { ident: Ident { - sym: cycle_0, + sym: cycle_2, }, location_kind: Cluster( - 2, + 0, ), }, - }, - ), - ), - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos :: * ; Ballot { num : 0 , id : ClusterId :: from_raw (0) } } ; [e] }, - ), - location_kind: Cluster( - 2, + ), ), }, - ), - ), - }, - Tee { - inner: : Union( - CycleSource { - ident: Ident { - sym: cycle_3, - }, - location_kind: Cluster( - 2, + Persist( + Source { + source: Iter( + { use hydroflow_plus :: __staged :: location :: * ; let e__free = { use crate :: __staged :: cluster :: paxos :: * ; Ballot { num : 0 , proposer_id : ClusterId :: from_raw (0) } } ; [e__free] }, + ), + location_kind: Cluster( + 0, + ), + }, ), - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos :: * ; 0 } ; [e] }, - ), - location_kind: Cluster( - 2, - ), - }, ), - ), - }, - ), - }, - }, - ForEach { - f: stageleft :: runtime_support :: fn1_type_hint :: < (tokio :: time :: Instant , core :: option :: Option < tokio :: time :: Instant >) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | _ | println ! ("Proposer leader expired") }), - input: Tee { - inner: : Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (tokio :: time :: Instant , core :: option :: Option < tokio :: time :: Instant >) , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_check_timeout = 1u64 ; move | (_ , latest_received_i_am_leader) | { if let Some (latest_received_i_am_leader) = latest_received_i_am_leader { (Instant :: now () . duration_since (* latest_received_i_am_leader)) > Duration :: from_secs (i_am_leader_check_timeout) } else { true } } }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((tokio :: time :: Instant , core :: option :: Option < tokio :: time :: Instant >) , ()) , (tokio :: time :: Instant , core :: option :: Option < tokio :: time :: Instant >) > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - CrossSingleton( - Source { - source: Stream( - { use hydroflow_plus :: __staged :: location :: * ; let delay = { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_check_timeout_delay_multiplier = 1usize ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; Duration :: from_secs ((p_id . raw_id * i_am_leader_check_timeout_delay_multiplier as u32) . into ()) } ; let interval = { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_check_timeout = 1u64 ; Duration :: from_secs (i_am_leader_check_timeout) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval_at (tokio :: time :: Instant :: now () + delay , interval)) }, - ), - location_kind: Cluster( + }, + Tee { + inner: : Chain( + CycleSource { + ident: Ident { + sym: cycle_4, + }, + location_kind: Tick( 2, + Cluster( + 0, + ), ), }, - Tee { - inner: : Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < core :: option :: Option < tokio :: time :: Instant > > ({ use crate :: __staged :: cluster :: paxos :: * ; | | None }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < core :: option :: Option < tokio :: time :: Instant > , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | latest , _ | { * latest = Some (Instant :: now ()) ; } }), - input: Persist( - Tee { - inner: , - }, + Persist( + Source { + source: Iter( + { use hydroflow_plus :: __staged :: location :: * ; let e__free = { use crate :: __staged :: cluster :: paxos :: * ; 0 } ; [e__free] }, + ), + location_kind: Cluster( + 0, ), }, - }, + ), ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , bool , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (bool , ()) , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , core :: option :: Option < bool > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f = 1usize ; move | num_received | if num_received > f { Some (true) } else { None } }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Unique( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , u32) , hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((sender , _p1b) , _ballot_num) | { sender } }), - input: Tee { - inner: : Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < ((hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , u32) , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | ((_sender , p1b) , ballot_num) | p1b . ballot == Ballot { num : * ballot_num , id : p_id } }), - input: CrossSingleton( - Persist( - Tee { - inner: : Inspect { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ , p1b) | println ! ("Proposer received P1b: {:?}" , p1b) }), - input: Tee { - inner: , - }, - }, - }, - ), - Tee { - inner: , - }, - ), - }, - }, - }, - ), - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , u32) , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Tee { - inner: : Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , u32) , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | (received_max_ballot , ballot_num) | * received_max_ballot <= Ballot { num : * ballot_num , id : p_id } }), - input: CrossSingleton( - Tee { - inner: , - }, - Tee { - inner: , - }, - ), - }, - }, - }, - ), - }, - }, - }, - }, - }, - ), - }, + }, + ), }, - }, + ), }, CycleSink { ident: Ident { - sym: cycle_0, + sym: cycle_2, }, location_kind: Cluster( - 2, + 0, ), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), - input: Network { - from_location: Cluster( - 2, - ), - from_key: None, - to_location: Cluster( - 2, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: Ballot) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& data) . unwrap () . into ()) }", - ], - }, + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 0, ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& b) . unwrap ()) }", - ], - }, + from_key: None, + to_location: Cluster( + 0, ), - ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > > > (__hydroflow_plus_cluster_ids_2) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < u32 , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | ballot_num | Ballot { num : ballot_num , id : p_id } }), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: Ballot) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& data) . unwrap () . into ()) }", + ], + }, + ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > > > (__hydroflow_plus_cluster_ids_0) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , ()) , u32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , ()) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), input: CrossSingleton( Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , ()) , u32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , ()) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), input: CrossSingleton( Tee { - inner: , + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < u32 , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_0) ; move | num | Ballot { num , proposer_id : CLUSTER_SELF_ID__free } }), + input: Tee { + inner: , + }, + }, }, Map { f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Source { - source: Interval( - { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_send_timeout = 1u64 ; Duration :: from_secs (i_am_leader_send_timeout) }, - ), - location_kind: Cluster( - 2, - ), + input: Tee { + inner: : CycleSource { + ident: Ident { + sym: cycle_3, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + }, }, }, ), }, Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < bool , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Tee { - inner: , + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), + input: Source { + source: Stream( + { use hydroflow_plus :: __staged :: location :: * ; let interval__free = { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_send_timeout__free = 1u64 ; Duration :: from_secs (i_am_leader_send_timeout__free) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval (interval__free)) }, + ), + location_kind: Cluster( + 0, + ), }, }, ), @@ -287,100 +209,84 @@ expression: built.ir() }, CycleSink { ident: Ident { - sym: cycle_4, + sym: cycle_6, }, - location_kind: Cluster( + location_kind: Tick( 2, + Cluster( + 0, + ), ), input: DeferTick( - Union( - Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , ()) , i32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Union( - Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | max_slot | max_slot + 1 }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , ()) , i32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Union( - Tee { - inner: : Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (u32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , _) | slot }), - input: Tee { - inner: : FoldKeyed { - init: stageleft :: runtime_support :: fn0_type_hint :: < (u32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | | (0 , LogValue { ballot : Ballot { num : 0 , id : ClusterId :: from_raw (0) } , value : Default :: default () }) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (u32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | curr_entry , new_entry | { let same_values = new_entry . value == curr_entry . 1 . value ; let higher_ballot = new_entry . ballot > curr_entry . 1 . ballot ; if same_values { curr_entry . 0 += 1 ; } if higher_ballot { curr_entry . 1 . ballot = new_entry . ballot ; if ! same_values { curr_entry . 0 = 1 ; curr_entry . 1 . value = new_entry . value ; } } } }), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , u32) , std :: collections :: hash_map :: IntoIter < i32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((_ , p1b) , _) | p1b . accepted . into_iter () }), - input: Tee { - inner: , - }, - }, - }, - }, + Difference( + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , (usize , usize)) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: Ballot > > ({ use crate :: __staged :: cluster :: quorum :: * ; let min__free = 2usize ; move | (key , (success , _error)) | if success >= min__free { Some (key) } else { None } }), + input: Tee { + inner: : FoldKeyed { + init: stageleft :: runtime_support :: fn0_type_hint :: < (usize , usize) > ({ use crate :: __staged :: cluster :: quorum :: * ; move | | (0 , 0) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (usize , usize) , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot > , () > ({ use crate :: __staged :: cluster :: quorum :: * ; move | accum , value | { if value . is_ok () { accum . 0 += 1 ; } else { accum . 1 += 1 ; } } }), + input: Tee { + inner: : Chain( + CycleSource { + ident: Ident { + sym: cycle_5, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + }, + Tee { + inner: : Inspect { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | p1b | println ! ("Proposer received P1b: {:?}" , p1b) }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) , (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 1, + ), + from_key: None, + to_location: Cluster( + 0, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > (& data) . unwrap () . into ()) }", + ], }, - }, - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos :: * ; - 1 } ; [e] }, - ), - location_kind: Cluster( - 2, - ), - }, + ), ), - ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: : CycleSource { - ident: Ident { - sym: cycle_4, - }, - location_kind: Cluster( - 2, - ), - }, + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Acceptor > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > (& b) . unwrap ()) }", + ], }, - }, - }, - }, - ), - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , i32) , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | (num_payloads , next_slot) | next_slot + num_payloads as i32 }), - input: CrossSingleton( - Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , ()) , usize > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Tee { - inner: : Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + ), + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot) , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((ballot , max_ballot) , log) | (ballot . proposer_id , (ballot , if ballot == max_ballot { Ok (log) } else { Err (max_ballot) })) }), + input: CrossSingleton( + CrossSingleton( + Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), input: Network { from_location: Cluster( 0, ), from_key: None, to_location: Cluster( - 2, + 1, ), to_key: None, serialize_pipeline: Some( @@ -388,7 +294,7 @@ expression: built.ir() Operator { path: "map", args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > (& data) . unwrap () . into ()) }", + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: Ballot) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& data) . unwrap () . into ()) }", ], }, ), @@ -399,333 +305,474 @@ expression: built.ir() Operator { path: "map", args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > (& b) . unwrap ()) }", + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& b) . unwrap ()) }", ], }, ), ), - input: CycleSource { - ident: Ident { - sym: cycle_0, + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_1) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + input: Inspect { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | _ | println ! ("Proposer leader expired, sending P1a") }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , ()) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Tee { + inner: , + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (() , ()) , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (() , ()) , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), + input: CrossSingleton( + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < core :: option :: Option < tokio :: time :: Instant > , core :: option :: Option < () > > ({ use hydroflow_plus :: __staged :: stream :: * ; let duration__free = { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_check_timeout__free = 1u64 ; Duration :: from_secs (i_am_leader_check_timeout__free) } ; move | latest_received | { if let Some (latest_received) = latest_received { if Instant :: now () . duration_since (latest_received) > duration__free { Some (()) } else { None } } else { Some (()) } } }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < core :: option :: Option < tokio :: time :: Instant > > ({ use hydroflow_plus :: __staged :: stream :: * ; | | None }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < core :: option :: Option < tokio :: time :: Instant > , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | latest , _ | { * latest = Some (Instant :: now ()) ; } }), + input: Persist( + Tee { + inner: , + }, + ), + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), + input: Filter { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: optional :: * ; | c | * c == 0 }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), + input: Tee { + inner: , + }, + }, + }, + }, + ), + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), + input: Source { + source: Stream( + { use hydroflow_plus :: __staged :: location :: * ; let delay__free = { use crate :: __staged :: cluster :: paxos :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_0) ; let i_am_leader_check_timeout_delay_multiplier__free = 1usize ; Duration :: from_secs ((CLUSTER_SELF_ID__free . raw_id * i_am_leader_check_timeout_delay_multiplier__free as u32) . into ()) } ; let interval__free = { use crate :: __staged :: cluster :: paxos :: * ; let i_am_leader_check_timeout__free = 1u64 ; Duration :: from_secs (i_am_leader_check_timeout__free) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval_at (tokio :: time :: Instant :: now () + delay__free , interval__free)) }, + ), + location_kind: Cluster( + 0, + ), + }, + }, + ), + }, + }, + ), + }, }, - location_kind: Cluster( - 0, - ), }, }, }, }, + Tee { + inner: : Chain( + Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), + input: Persist( + Inspect { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | p1a | println ! ("Acceptor received P1a: {:?}" , p1a) }), + input: Tee { + inner: , + }, + }, + ), + }, + Persist( + Source { + source: Iter( + { use hydroflow_plus :: __staged :: location :: * ; let e__free = { use crate :: __staged :: cluster :: paxos :: * ; Ballot { num : 0 , proposer_id : ClusterId :: from_raw (0) } } ; [e__free] }, + ), + location_kind: Cluster( + 1, + ), + }, + ), + ), + }, + ), + CycleSource { + ident: Ident { + sym: cycle_0, + }, + location_kind: Tick( + 3, + Cluster( + 1, + ), + ), }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Tee { - inner: : Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; | num_payloads | * num_payloads > 0 }), - input: Tee { - inner: , - }, + ), + }, + }, + }, + }, + }, + ), + }, + }, + }, + }, + Tee { + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , (usize , usize)) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: Ballot > > ({ use crate :: __staged :: cluster :: quorum :: * ; let max__free = 3usize ; move | (key , (success , error)) | if (success + error) >= max__free { Some (key) } else { None } }), + input: Tee { + inner: , + }, + }, + }, + ), + ), + }, + CycleSink { + ident: Ident { + sym: cycle_5, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + input: DeferTick( + AntiJoin( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), + ), + }, + CycleSink { + ident: Ident { + sym: cycle_3, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (() , ()) , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | _ | () }), + input: Tee { + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > >) , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > > > ({ use crate :: __staged :: cluster :: paxos :: * ; move | ((quorum_ballot , quorum_accepted) , my_ballot) | if quorum_ballot == my_ballot { Some (quorum_accepted) } else { None } }), + input: CrossSingleton( + Reduce { + f: { let key_fn = stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > >) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | t | t . 0 }) ; move | curr , new | { if key_fn (& new) > key_fn (& * curr) { * curr = new ; } } }, + input: FoldKeyed { + init: stageleft :: runtime_support :: fn0_type_hint :: < std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | | vec ! [] }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | logs , log | { logs . push (log) ; } }), + input: Persist( + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) , core :: option :: Option < (hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) > > ({ use crate :: __staged :: cluster :: quorum :: * ; move | (key , res) | match res { Ok (v) => Some ((key , v)) , Err (_) => None , } }), + input: AntiJoin( + AntiJoin( + Tee { + inner: , + }, + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , (usize , usize)) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: Ballot > > ({ use crate :: __staged :: cluster :: quorum :: * ; let min__free = 2usize ; move | (key , (success , _error)) | if success < min__free { Some (key) } else { None } }), + input: Tee { + inner: , }, }, + ), + CycleSource { + ident: Ident { + sym: cycle_6, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), }, ), }, - }, - Tee { - inner: , - }, - ), + ), + }, + }, + Tee { + inner: , }, ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , ()) , i32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + }, + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | _ | () }), + input: Filter { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot) , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; | (received_max_ballot , cur_ballot) | * received_max_ballot <= * cur_ballot }), input: CrossSingleton( Tee { - inner: , + inner: , }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , usize , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , - }, - }, - }, + Tee { + inner: , }, ), }, - ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < bool , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Tee { - inner: , - }, - }, - ), - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < bool , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | _ | 0 }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (bool , ()) , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Tee { - inner: , - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , - }, - }, - }, }, - ), + }, }, - }, - ), - ), + ), + }, + }, }, CycleSink { ident: Ident { - sym: cycle_5, + sym: cycle_1, }, location_kind: Cluster( + 0, + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ , ballot) | ballot }), + input: FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , core :: result :: Result < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , hydroflow_plus_test :: cluster :: paxos :: Ballot >) , core :: option :: Option < (hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot) > > ({ use crate :: __staged :: cluster :: quorum :: * ; move | (key , res) | match res { Ok (_) => None , Err (e) => Some ((key , e)) , } }), + input: Tee { + inner: , + }, + }, + }, + }, + CycleSink { + ident: Ident { + sym: cycle_7, + }, + location_kind: Tick( 2, + Cluster( + 0, + ), ), input: DeferTick( - Difference( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , (_count , _p2b)) | slot }), - input: Tee { - inner: : Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (i32 , (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , bool > ({ use crate :: __staged :: cluster :: paxos :: * ; let f = 1usize ; move | (_slot , (count , _p2b)) | * count > f }), + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , usize) , usize > ({ use crate :: __staged :: cluster :: paxos :: * ; | (num_payloads , base_slot) | base_slot + num_payloads }), + input: CrossSingleton( + Tee { + inner: : Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , (usize , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), input: Tee { - inner: : FoldKeyed { - init: stageleft :: runtime_support :: fn0_type_hint :: < (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | | (0 , P2b { ballot : Ballot { num : 0 , id : ClusterId :: from_raw (0) } , max_ballot : Ballot { num : 0 , id : ClusterId :: from_raw (0) } , slot : 0 , value : Default :: default () }) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | accum , (_sender , p2b) | { accum . 0 += 1 ; accum . 1 = p2b ; } }), - input: FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , core :: option :: Option < (i32 , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) > > ({ use crate :: __staged :: cluster :: paxos :: * ; | (sender , p2b) | if p2b . ballot == p2b . max_ballot { Some ((p2b . slot , (sender , p2b))) } else { None } }), - input: Tee { - inner: : Union( - Tee { - inner: , + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) , usize) , (usize , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((index , payload) , base_slot) | (base_slot + index , payload) }), + input: CrossSingleton( + Enumerate { + is_static: false, + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , ()) , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 2, + ), + from_key: None, + to_location: Cluster( + 0, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > (& data) . unwrap () . into ()) }", + ], + }, + ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((u32 , u32) , hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer >) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | ((key , value) , leader_id) | (leader_id , KvPayload { key , value : (CLUSTER_SELF_ID__free , value) }) }), + input: CrossSingleton( + CycleSource { + ident: Ident { + sym: cycle_1, + }, + location_kind: Cluster( + 2, + ), + }, + Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | ballot : Ballot | ballot . proposer_id }), + input: Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), + input: Persist( + Inspect { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | ballot | println ! ("Client notified that leader was elected: {:?}" , ballot) }), + input: CycleSource { + ident: Ident { + sym: cycle_0, + }, + location_kind: Cluster( + 2, + ), + }, + }, + ), + }, + }, + }, + ), + }, + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), + input: Tee { + inner: , + }, + }, + ), + }, + }, + Tee { + inner: : Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , usize > ({ use crate :: __staged :: cluster :: paxos :: * ; | max_slot | max_slot + 1 }), + input: Tee { + inner: : Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , usize , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , (usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >)) , usize > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , _) | slot }), + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , (usize , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >)) , (usize , (usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >)) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , (count , entry)) | (slot , (count , entry . unwrap ())) }), + input: FoldKeyed { + init: stageleft :: runtime_support :: fn0_type_hint :: < (usize , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | | (0 , None) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (usize , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | curr_entry , new_entry | { if let Some (curr_entry_payload) = & mut curr_entry . 1 { let same_values = new_entry . value == curr_entry_payload . value ; let higher_ballot = new_entry . ballot > curr_entry_payload . ballot ; if same_values { curr_entry . 0 += 1 ; } if higher_ballot { curr_entry_payload . ballot = new_entry . ballot ; if ! same_values { curr_entry . 0 = 1 ; curr_entry_payload . value = new_entry . value ; } } } else { * curr_entry = (1 , Some (new_entry)) ; } } }), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > ({ use hydroflow_plus :: __staged :: stream :: * ; | d | d }), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > , std :: vec :: Vec < std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > > ({ use hydroflow_plus :: __staged :: optional :: * ; | v | v }), + input: Tee { + inner: , + }, + }, + }, + }, + }, + }, + }, + }, + }, }, - CycleSource { - ident: Ident { - sym: cycle_6, + Chain( + CycleSource { + ident: Ident { + sym: cycle_7, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), }, - location_kind: Cluster( - 2, + Persist( + Source { + source: Iter( + { use hydroflow_plus :: __staged :: location :: * ; let e__free = { use crate :: __staged :: cluster :: paxos :: * ; 0 } ; [e__free] }, + ), + location_kind: Cluster( + 0, + ), + }, ), - }, + ), ), }, - }, + ), }, }, }, }, - }, - Tee { - inner: : FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , core :: option :: Option < i32 > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f = 1usize ; move | (slot , (count , _p2b)) | if count == 2 * f + 1 { Some (slot) } else { None } }), - input: Tee { - inner: , - }, - }, - }, - ), - ), - }, - CycleSink { - ident: Ident { - sym: cycle_6, - }, - location_kind: Cluster( - 2, - ), - input: DeferTick( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_slot , (sender , p2b)) | (sender , p2b) }), - input: AntiJoin( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , (i32 , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (sender , p2b) | (p2b . slot , (sender , p2b)) }), - input: Tee { - inner: , - }, - }, Tee { - inner: , + inner: , }, ), }, ), }, - ForEach { - f: stageleft :: runtime_support :: fn1_type_hint :: < & str , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | s | println ! ("{}" , s) }), - input: Source { - source: Iter( - { use crate :: __staged :: cluster :: paxos :: * ; ["Acceptors say hello"] }, - ), - location_kind: Cluster( - 3, - ), - }, - }, CycleSink { ident: Ident { - sym: cycle_1, + sym: cycle_9, }, - location_kind: Cluster( + location_kind: Tick( 2, - ), - input: Network { - from_location: Cluster( - 3, - ), - from_key: None, - to_location: Cluster( - 2, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& data) . unwrap () . into ()) }", - ], - }, - ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Acceptor > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& b) . unwrap ()) }", - ], - }, - ), + Cluster( + 0, ), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus_test :: cluster :: paxos :: P1a , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (i32 , std :: collections :: hash_map :: HashMap < i32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > >)) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: P1b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((p1a , max_ballot) , (_prev_checkpoint , log)) | (p1a . ballot . id , P1b { ballot : p1a . ballot , max_ballot , accepted : log }) }), - input: CrossSingleton( - CrossSingleton( - Tee { - inner: : Inspect { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P1a , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | p1a | println ! ("Acceptor received P1a: {:?}" , p1a) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: P1a) , hydroflow_plus_test :: cluster :: paxos :: P1a > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), - input: Network { - from_location: Cluster( - 2, - ), - from_key: None, - to_location: Cluster( - 3, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: P1a) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: P1a > (& data) . unwrap () . into ()) }", - ], - }, - ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: P1a > (& b) . unwrap ()) }", - ], - }, - ), - ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P1a , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_3) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < u32 , hydroflow_plus_test :: cluster :: paxos :: P1a > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | ballot_num | P1a { ballot : Ballot { num : ballot_num , id : p_id } } }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , ()) , u32 > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Tee { - inner: , - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (tokio :: time :: Instant , core :: option :: Option < tokio :: time :: Instant >) , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Tee { - inner: , - }, - }, - ), - }, - }, - }, - }, - }, - }, - }, - Tee { - inner: : Union( - Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), - input: Persist( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P1a , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | p1a | p1a . ballot }), - input: Tee { - inner: , + ), + input: DeferTick( + Difference( + Tee { + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (usize , usize)) , core :: option :: Option < (usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) > > ({ use crate :: __staged :: cluster :: quorum :: * ; let min__free = 2usize ; move | (key , (success , _error)) | if success >= min__free { Some (key) } else { None } }), + input: Tee { + inner: : FoldKeyed { + init: stageleft :: runtime_support :: fn0_type_hint :: < (usize , usize) > ({ use crate :: __staged :: cluster :: quorum :: * ; move | | (0 , 0) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (usize , usize) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot > , () > ({ use crate :: __staged :: cluster :: quorum :: * ; move | accum , value | { if value . is_ok () { accum . 0 += 1 ; } else { accum . 1 += 1 ; } } }), + input: Tee { + inner: : Chain( + CycleSource { + ident: Ident { + sym: cycle_8, }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), }, - ), - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos :: * ; Ballot { num : 0 , id : ClusterId :: from_raw (0) } } ; [e] }, - ), - location_kind: Cluster( - 3, - ), - }, - ), - ), - }, - ), - Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < (i32 , std :: collections :: hash_map :: HashMap < i32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | | (- 1 , HashMap :: new ()) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (i32 , std :: collections :: hash_map :: HashMap < i32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > >) , (i32 , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | (prev_checkpoint , log) , (new_checkpoint , p2a) | { if new_checkpoint != - 1 { for slot in * prev_checkpoint .. new_checkpoint { log . remove (& slot) ; } * prev_checkpoint = new_checkpoint ; } else { if p2a . slot > * prev_checkpoint { match log . get (& p2a . slot) { None => { log . insert (p2a . slot , LogValue { ballot : p2a . ballot , value : p2a . value , } ,) ; } Some (prev_p2a) => { if p2a . ballot > prev_p2a . ballot { log . insert (p2a . slot , LogValue { ballot : p2a . ballot , value : p2a . value , } ,) ; } } } ; } } } }), - input: Persist( - Union( - FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < (i32 , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > > ({ use crate :: __staged :: cluster :: paxos :: * ; | (p2a , max_ballot) | if p2a . ballot >= max_ballot { Some ((- 1 , p2a)) } else { None } }), - input: CrossSingleton( Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), input: Network { from_location: Cluster( - 2, + 1, ), from_key: None, to_location: Cluster( - 3, + 0, ), to_key: None, serialize_pipeline: Some( @@ -733,7 +780,7 @@ expression: built.ir() Operator { path: "map", args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& data) . unwrap () . into ()) }", + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > (& data) . unwrap () . into ()) }", ], }, ), @@ -744,250 +791,348 @@ expression: built.ir() Operator { path: "map", args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& b) . unwrap ()) }", + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Acceptor > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >) > (& b) . unwrap ()) }", ], }, ), ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_3) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , ()) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , ()) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Union( - FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((i32 , (u32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , u32) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f = 1usize ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | ((slot , (count , entry)) , ballot_num) | if count <= f as u32 { Some (P2a { ballot : Ballot { num : ballot_num , id : p_id , } , slot , value : entry . value , }) } else { None } }), - input: CrossSingleton( - Tee { - inner: , - }, - Tee { - inner: , - }, - ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >)) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (p2a , max_ballot) | (p2a . ballot . proposer_id , ((p2a . slot , p2a . ballot) , if p2a . ballot == max_ballot { Ok (()) } else { Err (max_ballot) })) }), + input: CrossSingleton( + Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 0, + ), + from_key: None, + to_location: Cluster( + 1, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > (& data) . unwrap () . into ()) }", + ], }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , u32) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | (slot , ballot_num) | P2a { ballot : Ballot { num : ballot_num , id : p_id } , slot , value : Default :: default () } }), - input: CrossSingleton( - Difference( - FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , std :: ops :: Range < i32 > > ({ use crate :: __staged :: cluster :: paxos :: * ; | max_slot | 0 .. max_slot }), - input: Tee { - inner: , + ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_1) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((slot , ballot) , value) | P2a { ballot , slot , value } }), + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) , ()) , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) , hydroflow_plus_test :: cluster :: paxos :: Ballot) , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((slot , payload) , ballot) | ((slot , ballot) , Some (payload)) }), + input: CrossSingleton( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), }, - }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | p2a | ((p2a . slot , p2a . ballot) , p2a . value) }), + input: Chain( + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , (usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >)) , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f__free = 1usize ; move | ((slot , (count , entry)) , ballot) | { if count <= f__free { Some (P2a { ballot , slot , value : entry . value , }) } else { None } } }), + input: CrossSingleton( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , ballot) | P2a { ballot , slot , value : None } }), + input: CrossSingleton( + Difference( + FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , std :: ops :: Range < usize > > ({ use crate :: __staged :: cluster :: paxos :: * ; | max_slot | 0 .. max_slot }), + input: Tee { + inner: , + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , (usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >)) , usize > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , _) | slot }), + input: Tee { + inner: , + }, + }, + ), + Tee { + inner: , + }, + ), + }, + ), + }, + ), Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (u32 , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | (slot , _) | slot }), + f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), input: Tee { - inner: , + inner: , }, }, ), - Tee { - inner: , - }, - ), - }, - ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: stream :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , - }, - }, - }, - }, - ), - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (((usize , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) , i32) , u32) , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | (((index , payload) , next_slot) , ballot_num) | P2a { ballot : Ballot { num : ballot_num , id : p_id } , slot : next_slot + index as i32 , value : payload } }), - input: CrossSingleton( - CrossSingleton( - Enumerate( - Tee { - inner: , }, - ), - Tee { - inner: , }, - ), - Tee { - inner: , }, - ), - }, - ), - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < bool , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), - input: Tee { - inner: , + }, }, }, - ), - }, + }, + Tee { + inner: , + }, + ), }, }, }, }, - Tee { - inner: , - }, ), }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , (i32 , hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | min_seq | (min_seq , P2a { ballot : Ballot { num : 0 , id : ClusterId :: from_raw (0) } , slot : - 1 , value : Default :: default () }) }), - input: Delta( - Union( - Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new < * curr { * curr = new ; } } }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , i32) , i32 > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_sender , seq) | seq }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , i32) , ()) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , i32) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Tee { - inner: : ReduceKeyed { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | curr_seq , seq | { if seq > * curr_seq { * curr_seq = seq ; } } }), - input: Persist( - Network { - from_location: Cluster( - 1, - ), - from_key: None, - to_location: Cluster( - 3, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , i32) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < i32 > (& data) . unwrap () . into ()) }", - ], - }, - ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < i32 > (& b) . unwrap ()) }", - ], - }, - ), - ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < i32 , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_3) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), - input: CycleSource { - ident: Ident { - sym: cycle_0, - }, - location_kind: Cluster( - 1, - ), - }, - }, + }, + }, + }, + }, + Tee { + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (usize , usize)) , core :: option :: Option < (usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) > > ({ use crate :: __staged :: cluster :: quorum :: * ; let max__free = 3usize ; move | (key , (success , error)) | if (success + error) >= max__free { Some (key) } else { None } }), + input: Tee { + inner: , + }, + }, + }, + ), + ), + }, + CycleSink { + ident: Ident { + sym: cycle_8, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + input: DeferTick( + AntiJoin( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), + ), + }, + CycleSink { + ident: Ident { + sym: cycle_10, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + input: DeferTick( + AntiJoin( + Tee { + inner: : Chain( + CycleSource { + ident: Ident { + sym: cycle_10, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + }, + Tee { + inner: , + }, + ), + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , ()) , (usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) > ({ use crate :: __staged :: cluster :: request_response :: * ; | (key , _) | key }), + input: Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , ()) > ({ use crate :: __staged :: cluster :: paxos :: * ; | k | (k , ()) }), + input: Difference( + Tee { + inner: , + }, + CycleSource { + ident: Ident { + sym: cycle_9, + }, + location_kind: Tick( + 2, + Cluster( + 0, + ), + ), + }, + ), + }, + }, + }, + ), + ), + }, + CycleSink { + ident: Ident { + sym: cycle_0, + }, + location_kind: Tick( + 3, + Cluster( + 1, + ), + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (core :: option :: Option < usize > , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ckpnt , log) | log }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < (core :: option :: Option < usize > , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | | (None , HashMap :: new ()) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (core :: option :: Option < usize > , std :: collections :: hash_map :: HashMap < usize , hydroflow_plus_test :: cluster :: paxos :: LogValue < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > >) , hydroflow_plus_test :: cluster :: paxos :: CheckpointOrP2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | (prev_checkpoint , log) , checkpoint_or_p2a | { match checkpoint_or_p2a { CheckpointOrP2a :: Checkpoint (new_checkpoint) => { if prev_checkpoint . map (| prev | new_checkpoint > prev) . unwrap_or (true) { for slot in (prev_checkpoint . unwrap_or (0)) .. new_checkpoint { log . remove (& slot) ; } * prev_checkpoint = Some (new_checkpoint) ; } } CheckpointOrP2a :: P2a (p2a) => { if prev_checkpoint . map (| prev | p2a . slot > prev) . unwrap_or (true) && log . get (& p2a . slot) . map (| prev_p2a : & LogValue < _ > | p2a . ballot > prev_p2a . ballot) . unwrap_or (true) { log . insert (p2a . slot , LogValue { ballot : p2a . ballot , value : p2a . value , } ,) ; } } } } }), + input: Persist( + Chain( + FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos :: CheckpointOrP2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | (p2a , max_ballot) | if p2a . ballot >= max_ballot { Some (CheckpointOrP2a :: P2a (p2a)) } else { None } }), + input: CrossSingleton( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , hydroflow_plus_test :: cluster :: paxos :: CheckpointOrP2a < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > ({ use crate :: __staged :: cluster :: paxos :: * ; | min_seq | CheckpointOrP2a :: Checkpoint (min_seq) }), + input: Delta( + Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , usize , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new < * curr { * curr = new ; } } }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > , usize) , usize > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_sender , seq) | seq }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > , usize) , ()) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > , usize) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Tee { + inner: : ReduceKeyed { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , usize , () > ({ use crate :: __staged :: cluster :: paxos :: * ; | curr_seq , seq | { if seq > * curr_seq { * curr_seq = seq ; } } }), + input: Persist( + Network { + from_location: Cluster( + 3, + ), + from_key: None, + to_location: Cluster( + 1, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , usize) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < usize > (& data) . unwrap () . into ()) }", + ], }, ), - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < bool , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), - input: FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , core :: option :: Option < bool > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f = 1usize ; move | num_received | if num_received == f + 1 { Some (true) } else { None } }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , i32) , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < usize > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Acceptor > > > (__hydroflow_plus_cluster_ids_1) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + input: CycleSource { + ident: Ident { + sym: cycle_0, }, + location_kind: Cluster( + 3, + ), }, }, }, ), }, }, - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos :: * ; - 1 } ; [e] }, - ), - location_kind: Cluster( - 3, - ), + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < bool , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | _u | () }), + input: FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , core :: option :: Option < bool > > ({ use crate :: __staged :: cluster :: paxos :: * ; let f__free = 1usize ; move | num_received | if num_received == f__free + 1 { Some (true) } else { None } }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > , usize) , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), + input: Tee { + inner: , + }, + }, + }, }, ), - ), - ), + }, + }, }, ), - ), - }, + }, + ), ), }, }, }, CycleSink { ident: Ident { - sym: cycle_2, + sym: cycle_0, }, location_kind: Cluster( - 2, + 0, ), - input: Network { - from_location: Cluster( - 3, - ), - from_key: None, - to_location: Cluster( - 2, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& data) . unwrap () . into ()) }", - ], - }, - ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Acceptor > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > > (& b) . unwrap ()) }", - ], - }, - ), - ), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: P2a < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (p2a , max_ballot) | (p2a . ballot . id , P2b { ballot : p2a . ballot , max_ballot , slot : p2a . slot , value : p2a . value }) }), - input: CrossSingleton( - Tee { - inner: , - }, - Tee { - inner: , - }, - ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_ , ballot) | ballot }), + input: FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , core :: result :: Result < () , hydroflow_plus_test :: cluster :: paxos :: Ballot >) , core :: option :: Option < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot) > > ({ use crate :: __staged :: cluster :: quorum :: * ; move | (key , res) | match res { Ok (_) => None , Err (e) => Some ((key , e)) , } }), + input: Tee { + inner: , + }, }, }, }, @@ -995,68 +1140,67 @@ expression: built.ir() ident: Ident { sym: cycle_1, }, - location_kind: Cluster( - 1, + location_kind: Tick( + 8, + Cluster( + 3, + ), ), input: DeferTick( Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , i32) , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (sorted_payload , _) | { sorted_payload } }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , usize) , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (sorted_payload , _) | { sorted_payload } }), input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , i32) , bool > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (sorted_payload , highest_seq) | sorted_payload . seq > * highest_seq }), + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , usize) , bool > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (sorted_payload , highest_seq) | sorted_payload . seq > * highest_seq }), input: CrossSingleton( Tee { - inner: : Sort( - Union( - Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload) , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), - input: Network { - from_location: Cluster( - 2, - ), - from_key: None, - to_location: Cluster( - 1, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > (& data) . unwrap () . into ()) }", - ], - }, - ), + inner: : Sort( + Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 0, + ), + from_key: None, + to_location: Cluster( + 3, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) >) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > (& data) . unwrap () . into ()) }", + ], + }, ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > (& b) . unwrap ()) }", - ], - }, - ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > (& b) . unwrap ()) }", + ], + }, ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > > > (__hydroflow_plus_cluster_ids_1) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + ), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > > > (__hydroflow_plus_cluster_ids_3) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (slot , kv) | SequencedKv { seq : slot , kv } }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (slot , data) | ReplicaPayload { seq : slot , key : data . key , value : data . value } }), + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , ())) , (usize , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > >) > ({ use crate :: __staged :: cluster :: paxos :: * ; | ((slot , _ballot) , (value , _)) | (slot , value) }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , (usize , hydroflow_plus_test :: cluster :: paxos :: P2b < hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload >)) , (i32 , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) > ({ use crate :: __staged :: cluster :: paxos :: * ; | (_slot , (_count , p2b)) | (p2b . slot , p2b . value) }), - input: AntiJoin( + f: stageleft :: runtime_support :: fn1_type_hint :: < ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , ())) , ((usize , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > , ())) > ({ use crate :: __staged :: cluster :: request_response :: * ; | (key , (meta , resp)) | (key , (meta , resp)) }), + input: Join( Tee { - inner: , + inner: , }, - CycleSource { - ident: Ident { - sym: cycle_5, - }, - location_kind: Cluster( - 2, - ), + Tee { + inner: , }, ), }, @@ -1069,40 +1213,54 @@ expression: built.ir() ident: Ident { sym: cycle_1, }, - location_kind: Cluster( - 1, + location_kind: Tick( + 8, + Cluster( + 3, + ), ), }, ), ), }, Tee { - inner: : Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < i32 > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | | - 1 }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , (hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , i32) , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | filled_slot , (sorted_payload , highest_seq) | { let next_slot = std :: cmp :: max (* filled_slot , highest_seq) ; * filled_slot = if sorted_payload . seq == next_slot + 1 { sorted_payload . seq } else { * filled_slot } ; } }), - input: CrossSingleton( - Tee { - inner: , - }, - Union( - CycleSource { - ident: Ident { - sym: cycle_2, - }, - location_kind: Cluster( - 1, - ), + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < core :: option :: Option < usize > , core :: option :: Option < usize > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | v | v }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < core :: option :: Option < usize > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | | None }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < core :: option :: Option < usize > , (hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , core :: option :: Option < usize >) , () > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | filled_slot , (sorted_payload , highest_seq) | { let expected_next_slot = std :: cmp :: max (filled_slot . map (| v | v + 1) . unwrap_or (0) , highest_seq . map (| v | v + 1) . unwrap_or (0) ,) ; if sorted_payload . seq == expected_next_slot { * filled_slot = Some (sorted_payload . seq) ; } } }), + input: CrossSingleton( + Tee { + inner: , }, - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos_bench :: * ; - 1 } ; [e] }, - ), - location_kind: Cluster( - 1, + Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , core :: option :: Option < usize > > ({ use hydroflow_plus :: __staged :: optional :: * ; | v | Some (v) }), + input: CycleSource { + ident: Ident { + sym: cycle_2, + }, + location_kind: Tick( + 8, + Cluster( + 3, + ), + ), + }, + }, + Persist( + Source { + source: Iter( + [:: std :: option :: Option :: None], + ), + location_kind: Cluster( + 3, + ), + }, ), - }, + ), ), - ), + }, }, }, ), @@ -1114,28 +1272,31 @@ expression: built.ir() ident: Ident { sym: cycle_2, }, - location_kind: Cluster( - 1, + location_kind: Tick( + 8, + Cluster( + 3, + ), ), input: DeferTick( Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , std :: string :: String > , i32) , i32 > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (_kv_store , highest_seq) | highest_seq }), + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , core :: option :: Option < usize >) , core :: option :: Option < usize > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (_kv_store , highest_seq) | highest_seq }), input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , std :: string :: String > , i32) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | | (HashMap :: < u32 , String > :: new () , - 1) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , std :: string :: String > , i32) , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | state , payload | { let kv_store = & mut state . 0 ; let last_seq = & mut state . 1 ; kv_store . insert (payload . key , payload . value) ; debug_assert ! (payload . seq == * last_seq + 1 , "Hole in log between seq {} and {}" , * last_seq , payload . seq) ; * last_seq = payload . seq ; } }), + init: stageleft :: runtime_support :: fn0_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , core :: option :: Option < usize >) > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | | (HashMap :: new () , None) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (std :: collections :: hash_map :: HashMap < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , core :: option :: Option < usize >) , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , () > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (kv_store , last_seq) , payload | { if let Some (kv) = payload . kv { kv_store . insert (kv . key , kv . value) ; } debug_assert ! (payload . seq == (last_seq . map (| s | s + 1) . unwrap_or (0)) , "Hole in log between seq {:?} and {}" , * last_seq , payload . seq) ; * last_seq = Some (payload . seq) ; } }), input: Persist( Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , i32) , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (sorted_payload , _) | { sorted_payload } }), + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , usize) , hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (sorted_payload , _) | { sorted_payload } }), input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , i32) , bool > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (sorted_payload , highest_seq) | sorted_payload . seq <= * highest_seq }), + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , usize) , bool > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | (sorted_payload , highest_seq) | sorted_payload . seq <= * highest_seq }), input: CrossSingleton( Tee { - inner: , + inner: , }, Tee { - inner: , + inner: , }, ), }, @@ -1151,127 +1312,228 @@ expression: built.ir() ident: Ident { sym: cycle_3, }, - location_kind: Cluster( - 1, + location_kind: Tick( + 8, + Cluster( + 3, + ), ), input: DeferTick( Tee { - inner: : FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < (i32 , i32) , core :: option :: Option < i32 > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let checkpoint_frequency = 1usize ; move | (max_checkpointed_seq , new_highest_seq) | if new_highest_seq - max_checkpointed_seq >= checkpoint_frequency as i32 { Some (new_highest_seq) } else { None } }), + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < (core :: option :: Option < usize > , usize) , core :: option :: Option < usize > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; let checkpoint_frequency__free = 1usize ; move | (max_checkpointed_seq , new_highest_seq) | if max_checkpointed_seq . map (| m | new_highest_seq - m >= checkpoint_frequency__free) . unwrap_or (true) { Some (new_highest_seq) } else { None } }), input: CrossSingleton( - Union( - Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < i32 , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), - input: Persist( - CycleSource { - ident: Ident { - sym: cycle_3, + Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , core :: option :: Option < usize > > ({ use hydroflow_plus :: __staged :: optional :: * ; | v | Some (v) }), + input: Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , usize , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), + input: Persist( + CycleSource { + ident: Ident { + sym: cycle_3, + }, + location_kind: Tick( + 8, + Cluster( + 3, + ), + ), + }, + ), + }, + }, + Persist( + Source { + source: Iter( + [:: std :: option :: Option :: None], + ), + location_kind: Cluster( + 3, + ), + }, + ), + ), + Tee { + inner: , + }, + ), + }, + }, + ), + }, + CycleSink { + ident: Ident { + sym: cycle_0, + }, + location_kind: Cluster( + 3, + ), + input: Tee { + inner: , + }, + }, + CycleSink { + ident: Ident { + sym: cycle_0, + }, + location_kind: Cluster( + 2, + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 0, + ), + from_key: None, + to_location: Cluster( + 2, + ), + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: Ballot) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& data) . unwrap () . into ()) }", + ], + }, + ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids__free = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > > > (__hydroflow_plus_cluster_ids_2) } ; | b | ids__free . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus_test :: cluster :: paxos :: Ballot , ()) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Tee { + inner: , + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < () , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (() , ()) , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Tee { + inner: , + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: optional :: * ; | _u | () }), + input: Filter { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: optional :: * ; | c | * c == 0 }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), + input: DeferTick( + Tee { + inner: , + }, + ), + }, + }, }, - location_kind: Cluster( - 1, - ), - }, - ), - }, - Persist( - Source { - source: Iter( - { use hydroflow_plus :: __staged :: location :: * ; let e = { use crate :: __staged :: cluster :: paxos_bench :: * ; - 1 } ; [e] }, - ), - location_kind: Cluster( - 1, ), }, - ), + }, ), - Tee { - inner: , - }, - ), + }, }, }, - ), - }, - CycleSink { - ident: Ident { - sym: cycle_0, - }, - location_kind: Cluster( - 1, - ), - input: Tee { - inner: , }, }, CycleSink { ident: Ident { - sym: cycle_1, + sym: cycle_2, }, - location_kind: Cluster( + location_kind: Tick( 0, + Cluster( + 2, + ), ), input: DeferTick( AntiJoin( Tee { - inner: : Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload) , (u32 , hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica >) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (sender , replica_payload) | (replica_payload . key , sender) }), - input: Network { - from_location: Cluster( - 1, - ), - from_key: None, - to_location: Cluster( - 0, + inner: : Chain( + CycleSource { + ident: Ident { + sym: cycle_2, + }, + location_kind: Tick( + 0, + Cluster( + 2, ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > (& data) . unwrap () . into ()) }", - ], - }, + ), + }, + Tee { + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > , ((u32 , u32) , core :: result :: Result < () , () >)) , ((u32 , u32) , core :: result :: Result < () , () >) > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), + input: Network { + from_location: Cluster( + 3, ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload > (& b) . unwrap ()) }", - ], - }, + from_key: None, + to_location: Cluster( + 2, ), - ), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , hydroflow_plus_test :: cluster :: paxos_bench :: ReplicaPayload) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | payload | (ClusterId :: from_raw (payload . value . parse :: < u32 > () . unwrap ()) , payload) }), - input: Tee { - inner: , + to_key: None, + serialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , ((u32 , u32) , core :: result :: Result < () , () >)) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < ((u32 , u32) , core :: result :: Result < () , () >) > (& data) . unwrap () . into ()) }", + ], + }, + ), + ), + instantiate_fn: , + deserialize_pipeline: Some( + Operator( + Operator { + path: "map", + args: [ + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_kv :: Replica > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < ((u32 , u32) , core :: result :: Result < () , () >) > (& b) . unwrap ()) }", + ], + }, + ), + ), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , ((u32 , u32) , core :: result :: Result < () , () >)) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | payload | (payload . value . 0 , ((payload . key , payload . value . 1) , Ok (()))) }), + input: FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos_kv :: SequencedKv < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > , core :: option :: Option < hydroflow_plus_test :: cluster :: paxos_kv :: KvPayload < u32 , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > , u32) > > > ({ use crate :: __staged :: cluster :: paxos_kv :: * ; | payload | payload . kv }), + input: Tee { + inner: , + }, + }, }, }, }, }, - CycleSource { - ident: Ident { - sym: cycle_1, - }, - location_kind: Cluster( - 0, - ), - }, ), }, Tee { - inner: : FilterMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , usize) , core :: option :: Option < u32 > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let f = 1usize ; move | (key , count) | { if count == f + 1 { Some (key) } else { None } } }), - input: FoldKeyed { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | | 0 }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Replica > , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | curr_count , _sender | { * curr_count += 1 ; } }), - input: Tee { - inner: , + inner: : FilterMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((u32 , u32) , (usize , usize)) , core :: option :: Option < (u32 , u32) > > ({ use crate :: __staged :: cluster :: quorum :: * ; let min__free = 2usize ; move | (key , (success , _error)) | if success >= min__free { Some (key) } else { None } }), + input: Tee { + inner: : FoldKeyed { + init: stageleft :: runtime_support :: fn0_type_hint :: < (usize , usize) > ({ use crate :: __staged :: cluster :: quorum :: * ; move | | (0 , 0) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (usize , usize) , core :: result :: Result < () , () > , () > ({ use crate :: __staged :: cluster :: quorum :: * ; move | accum , value | { if value . is_ok () { accum . 0 += 1 ; } else { accum . 1 += 1 ; } } }), + input: Tee { + inner: , + }, }, }, }, @@ -1281,118 +1543,81 @@ expression: built.ir() }, CycleSink { ident: Ident { - sym: cycle_2, + sym: cycle_1, }, location_kind: Cluster( - 0, + 2, + ), + input: Chain( + FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < () , std :: iter :: Map < std :: ops :: Range < usize > , _ > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; let num_clients_per_node__free = 1usize ; move | _ | (0 .. num_clients_per_node__free) . map (move | i | ((CLUSTER_SELF_ID__free . raw_id * (num_clients_per_node__free as u32)) + i as u32 , 0)) }), + input: Tee { + inner: : Reduce { + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < () , () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | * curr = new }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | () }), + input: Delta( + Tee { + inner: , + }, + ), + }, + }, + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , u32) , (u32 , u32) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | payload | (payload . 0 , payload . 1 + 1) }), + input: Tee { + inner: : Tee { + inner: , + }, + }, + }, + ), + }, + CycleSink { + ident: Ident { + sym: cycle_3, + }, + location_kind: Tick( + 1, + Cluster( + 2, + ), ), input: DeferTick( ReduceKeyed { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < std :: time :: SystemTime , std :: time :: SystemTime , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | curr_time , new_time | { if new_time > * curr_time { * curr_time = new_time ; } } }), - input: Union( - Union( + f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < tokio :: time :: Instant , tokio :: time :: Instant , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | curr_time , new_time | { if new_time > * curr_time { * curr_time = new_time ; } } }), + input: Chain( + Chain( Tee { - inner: : CycleSource { + inner: : CycleSource { ident: Ident { - sym: cycle_2, + sym: cycle_3, }, - location_kind: Cluster( - 0, + location_kind: Tick( + 1, + Cluster( + 2, + ), ), }, }, FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < std :: time :: SystemTime , std :: iter :: Map < std :: ops :: Range < usize > , _ > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let num_clients_per_node = 1usize ; move | now | (0 .. num_clients_per_node) . map (move | virtual_id | (virtual_id , now)) }), + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , std :: iter :: Map < std :: ops :: Range < usize > , _ > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let num_clients_per_node__free = 1usize ; move | now | (0 .. num_clients_per_node__free) . map (move | virtual_id | (virtual_id , now)) }), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: time :: SystemTime > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | SystemTime :: now () }), + f: stageleft :: runtime_support :: fn1_type_hint :: < () , tokio :: time :: Instant > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | Instant :: now () }), input: Tee { - inner: : Delta( - Tee { - inner: : Reduce { - f: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | curr , new | { if new > * curr { * curr = new ; } } }), - input: Persist( - Inspect { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | ballot | println ! ("Client notified that leader was elected: {:?}" , ballot) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos :: Ballot) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use hydroflow_plus :: __staged :: stream :: * ; | (_ , b) | b }), - input: Network { - from_location: Cluster( - 2, - ), - from_key: None, - to_location: Cluster( - 0, - ), - to_key: None, - serialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , hydroflow_plus_test :: cluster :: paxos :: Ballot) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& data) . unwrap () . into ()) }", - ], - }, - ), - ), - instantiate_fn: , - deserialize_pipeline: Some( - Operator( - Operator { - path: "map", - args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < hydroflow_plus_test :: cluster :: paxos :: Ballot > (& b) . unwrap ()) }", - ], - }, - ), - ), - input: FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: slice :: Iter < hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > > , _ > > ({ use hydroflow_plus :: __staged :: stream :: * ; let ids = unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < hydroflow_plus_test :: cluster :: paxos_bench :: Client > > > (__hydroflow_plus_cluster_ids_0) } ; | b | ids . iter () . map (move | id | (:: std :: clone :: Clone :: clone (id) , :: std :: clone :: Clone :: clone (& b))) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (bool , u32) , hydroflow_plus_test :: cluster :: paxos :: Ballot > ({ use crate :: __staged :: cluster :: paxos :: * ; let p_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos :: Proposer > :: from_raw (__hydroflow_plus_cluster_self_id_2) ; move | (_is_leader , ballot_num) | Ballot { num : ballot_num , id : p_id } }), - input: CrossSingleton( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (bool , ()) , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Tee { - inner: , - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , i32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , - }, - }, - }, - }, - ), - }, - Tee { - inner: , - }, - ), - }, - }, - }, - }, - }, - ), - }, - }, - ), + inner: , }, }, }, ), Tee { - inner: : Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < u32 , (usize , std :: time :: SystemTime) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | key | (key as usize , SystemTime :: now ()) }), + inner: : Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , u32) , (usize , tokio :: time :: Instant) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (key , _prev_count) | (key as usize , Instant :: now ()) }), input: Tee { - inner: , + inner: , }, }, }, @@ -1401,118 +1626,103 @@ expression: built.ir() ), }, ForEach { - f: stageleft :: runtime_support :: fn1_type_hint :: < ((() , (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < u128 > > > , usize , bool)) , (u32 , i32)) , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let median_latency_window_size = 1usize ; move | ((_ , (latencies , _write_index , has_any_value)) , (throughput , num_ticks) ,) | { let mut latencies_mut = latencies . borrow_mut () ; let median_latency = if has_any_value { let (_ , median , _) = latencies_mut . select_nth_unstable (median_latency_window_size / 2) ; * median } else { 0 } ; println ! ("Median latency: {}ms" , median_latency as f64 / 1000.0) ; println ! ("Throughput: {} requests/s" , throughput) ; println ! ("Num ticks per second: {}" , num_ticks) ; } }), - input: CrossSingleton( - CrossSingleton( - Tee { - inner: : Source { - source: Interval( - { use crate :: __staged :: cluster :: paxos_bench :: * ; Duration :: from_secs (1) }, - ), - location_kind: Cluster( - 0, - ), - }, - }, - Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < u128 > > > , usize , bool) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let median_latency_window_size = 1usize ; move | | (Rc :: new (RefCell :: new (Vec :: < u128 > :: with_capacity (median_latency_window_size))) , 0usize , false) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < u128 > > > , usize , bool) , core :: option :: Option < u128 > , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let median_latency_window_size = 1usize ; move | (latencies , write_index , has_any_value) , latency | { let mut latencies_mut = latencies . borrow_mut () ; if let Some (latency) = latency { if let Some (prev_latency) = latencies_mut . get_mut (* write_index) { * prev_latency = latency ; } else { latencies_mut . push (latency) ; } * has_any_value = true ; * write_index += 1 ; if * write_index == median_latency_window_size { * write_index = 0 ; } } else { latencies_mut . clear () ; * write_index = 0 ; * has_any_value = false ; } } }), - input: Persist( - Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , (std :: time :: SystemTime , std :: time :: SystemTime)) , core :: option :: Option < u128 > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (_virtual_id , (prev_time , curr_time)) | Some (curr_time . duration_since (prev_time) . unwrap () . as_micros ()) }), - input: Join( - Tee { - inner: , - }, - Tee { - inner: , - }, - ), - }, - DeferTick( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < () , core :: option :: Option < u128 > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | None }), - input: Tee { - inner: , - }, + f: stageleft :: runtime_support :: fn1_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; move | (latencies , throughput) | { let mut latencies_mut = latencies . borrow_mut () ; if latencies_mut . len () > 0 { let middle_idx = latencies_mut . len () / 2 ; let (_ , median , _) = latencies_mut . select_nth_unstable (middle_idx) ; println ! ("Median latency: {}ms" , median . as_micros () as f64 / 1000.0) ; } println ! ("Throughput: {} requests/s" , throughput) ; } }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < ((std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) , ()) , (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + input: CrossSingleton( + CrossSingleton( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) , std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (latencies , _) | latencies }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let median_latency_window_size__free = 1usize ; move | | (Rc :: new (RefCell :: new (Vec :: < Duration > :: with_capacity (median_latency_window_size__free))) , 0usize ,) }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (std :: rc :: Rc < core :: cell :: RefCell < std :: vec :: Vec < core :: time :: Duration > > > , usize) , core :: time :: Duration , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let median_latency_window_size__free = 1usize ; move | (latencies , write_index) , latency | { let mut latencies_mut = latencies . borrow_mut () ; if * write_index < latencies_mut . len () { latencies_mut [* write_index] = latency ; } else { latencies_mut . push (latency) ; } * write_index = (* write_index + 1) % median_latency_window_size__free ; } }), + input: Persist( + FlatMap { + f: stageleft :: runtime_support :: fn1_type_hint :: < core :: option :: Option < core :: time :: Duration > , core :: option :: Option < core :: time :: Duration > > ({ use hydroflow_plus :: __staged :: stream :: * ; | d | d }), + input: Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , (tokio :: time :: Instant , tokio :: time :: Instant)) , core :: option :: Option < core :: time :: Duration > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (_virtual_id , (prev_time , curr_time)) | Some (curr_time . duration_since (prev_time)) }), + input: Join( + Tee { + inner: , + }, + Tee { + inner: , + }, + ), + }, + DeferTick( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , core :: option :: Option < core :: time :: Duration > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | None }), + input: Tee { + inner: : Source { + source: Stream( + { use hydroflow_plus :: __staged :: location :: * ; let interval__free = { use crate :: __staged :: cluster :: paxos_bench :: * ; Duration :: from_secs (1) } ; tokio_stream :: wrappers :: IntervalStream :: new (tokio :: time :: interval (interval__free)) }, + ), + location_kind: Cluster( + 2, + ), + }, + }, + }, + ), + ), }, ), - ), - ), - }, - ), - Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < (u32 , i32) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | | (0 , 0) }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < (u32 , i32) , (usize , bool) , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | (total , num_ticks) , (batch_size , reset) | { if reset { * total = 0 ; * num_ticks = 0 ; } else { * total += batch_size as u32 ; * num_ticks += 1 ; } } }), - input: Persist( - Union( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , (usize , bool) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | batch_size | (batch_size , false) }), - input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , ()) , usize > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), - input: CrossSingleton( - Fold { - init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , u32 , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), - input: Tee { - inner: , - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), - input: Filter { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), - input: Fold { + }, + }, + Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | | 0 }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , (usize , bool) , () > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | total , (batch_size , reset) | { if reset { * total = 0 ; } else { * total += batch_size ; } } }), + input: Persist( + Chain( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , (usize , bool) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | batch_size | (batch_size , false) }), + input: Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < (usize , ()) , usize > ({ use hydroflow_plus :: __staged :: singleton :: * ; | (d , _signal) | d }), + input: CrossSingleton( + Fold { init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), - acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , () , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , (u32 , u32) , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), input: Tee { - inner: , + inner: , + }, + }, + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < usize , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), + input: Filter { + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < usize , bool > ({ use hydroflow_plus :: __staged :: singleton :: * ; | c | * c == 0 }), + input: Fold { + init: stageleft :: runtime_support :: fn0_type_hint :: < usize > ({ use hydroflow_plus :: __staged :: stream :: * ; | | 0usize }), + acc: stageleft :: runtime_support :: fn2_borrow_mut_type_hint :: < usize , tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: stream :: * ; | count , _ | * count += 1 }), + input: Tee { + inner: , + }, + }, }, }, + ), + }, + }, + DeferTick( + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , (usize , bool) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | (0 , true) }), + input: Tee { + inner: , }, }, ), - }, - }, - DeferTick( - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < () , (usize , bool) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; | _ | (0 , true) }), - input: Tee { - inner: , - }, - }, + ), ), - ), - ), - }, - ), - }, - CycleSink { - ident: Ident { - sym: cycle_0, - }, - location_kind: Cluster( - 0, - ), - input: Union( - FlatMap { - f: stageleft :: runtime_support :: fn1_type_hint :: < hydroflow_plus_test :: cluster :: paxos :: Ballot , std :: iter :: Map < std :: ops :: Range < usize > , _ > > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let c_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (__hydroflow_plus_cluster_self_id_0) ; let num_clients_per_node = 1usize ; move | leader_ballot | (0 .. num_clients_per_node) . map (move | i | (leader_ballot . leader_id () , ClientPayload { key : i as u32 , value : c_id . raw_id . to_string () })) }), - input: Tee { - inner: , - }, - }, - Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (u32 , hydroflow_plus_test :: cluster :: paxos :: Ballot) , (hydroflow_plus :: location :: ClusterId < hydroflow_plus_test :: cluster :: paxos :: Proposer > , hydroflow_plus_test :: cluster :: paxos_bench :: ClientPayload) > ({ use crate :: __staged :: cluster :: paxos_bench :: * ; let c_id = hydroflow_plus :: ClusterId :: < hydroflow_plus_test :: cluster :: paxos_bench :: Client > :: from_raw (__hydroflow_plus_cluster_self_id_0) ; move | (key , leader_ballot) | (leader_ballot . leader_id () , ClientPayload { key , value : c_id . raw_id . to_string () }) }), - input: CrossSingleton( - Tee { - inner: , - }, - Tee { - inner: , }, ), - }, - ), + Map { + f: stageleft :: runtime_support :: fn1_type_hint :: < tokio :: time :: Instant , () > ({ use hydroflow_plus :: __staged :: singleton :: * ; | _u | () }), + input: Tee { + inner: , + }, + }, + ), + }, }, ] diff --git a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__simple_cluster__tests__simple_cluster.snap b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__simple_cluster__tests__simple_cluster.snap index 8fd05b1df972..e7083d8ccf6d 100644 --- a/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__simple_cluster__tests__simple_cluster.snap +++ b/hydroflow_plus_test/src/cluster/snapshots/hydroflow_plus_test__cluster__simple_cluster__tests__simple_cluster.snap @@ -4,7 +4,7 @@ expression: built.ir() --- [ ForEach { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < () > , (hydroflow_plus :: location :: ClusterId < () > , i32)) , () > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | (id , d) | println ! ("node received: ({}, {:?})" , id , d) }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32)) , () > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | (id , d) | println ! ("node received: ({}, {:?})" , id , d) }), input: Network { from_location: Cluster( 1, @@ -19,7 +19,7 @@ expression: built.ir() Operator { path: "map", args: [ - "| data | { hydroflow_plus :: runtime_support :: bincode :: serialize :: < (hydroflow_plus :: location :: ClusterId < () > , i32) > (& data) . unwrap () . into () }", + "| data | { hydroflow_plus :: runtime_support :: bincode :: serialize :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) > (& data) . unwrap () . into () }", ], }, ), @@ -30,13 +30,13 @@ expression: built.ir() Operator { path: "map", args: [ - "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < () > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (hydroflow_plus :: location :: ClusterId < () > , i32) > (& b) . unwrap ()) }", + "| res | { let (id , b) = res . unwrap () ; (hydroflow_plus :: ClusterId :: < () > :: from_raw (id) , hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) > (& b) . unwrap ()) }", ], }, ), ), input: Inspect { - f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus :: location :: ClusterId < () > , i32) , () > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; let cluster_self_id = hydroflow_plus :: ClusterId :: < () > :: from_raw (__hydroflow_plus_cluster_self_id_1) ; move | n | println ! ("cluster received: {:?} (self cluster id: {})" , n , cluster_self_id) }), + f: stageleft :: runtime_support :: fn1_borrow_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) , () > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; let CLUSTER_SELF_ID__free = hydroflow_plus :: ClusterId :: < () > :: from_raw (__hydroflow_plus_cluster_self_id_1) ; move | n | println ! ("cluster received: {:?} (self cluster id: {})" , n , CLUSTER_SELF_ID__free) }), input: Network { from_location: Process( 0, @@ -51,7 +51,7 @@ expression: built.ir() Operator { path: "map", args: [ - "| (id , data) : (hydroflow_plus :: ClusterId < _ > , (hydroflow_plus :: location :: ClusterId < () > , i32)) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < (hydroflow_plus :: location :: ClusterId < () > , i32) > (& data) . unwrap () . into ()) }", + "| (id , data) : (hydroflow_plus :: ClusterId < _ > , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32)) | { (id . raw_id , hydroflow_plus :: runtime_support :: bincode :: serialize :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) > (& data) . unwrap () . into ()) }", ], }, ), @@ -62,18 +62,18 @@ expression: built.ir() Operator { path: "map", args: [ - "| res | { hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (hydroflow_plus :: location :: ClusterId < () > , i32) > (& res . unwrap ()) . unwrap () }", + "| res | { hydroflow_plus :: runtime_support :: bincode :: deserialize :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) > (& res . unwrap ()) . unwrap () }", ], }, ), ), input: Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: ClusterId < () > , i32) , (hydroflow_plus :: location :: ClusterId < () > , (hydroflow_plus :: location :: ClusterId < () > , i32)) > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | (id , n) | (id , (id , n)) }), + f: stageleft :: runtime_support :: fn1_type_hint :: < (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32) , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , (hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , i32)) > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | (id , n) | (id , (id , n)) }), input: Delta( CrossProduct( Persist( Map { - f: stageleft :: runtime_support :: fn1_type_hint :: < & hydroflow_plus :: location :: ClusterId < () > , hydroflow_plus :: location :: ClusterId < () > > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | & id | id }), + f: stageleft :: runtime_support :: fn1_type_hint :: < & hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > , hydroflow_plus :: location :: cluster :: cluster_id :: ClusterId < () > > ({ use crate :: __staged :: cluster :: simple_cluster :: * ; | & id | id }), input: Source { source: Iter( unsafe { :: std :: mem :: transmute :: < _ , & :: std :: vec :: Vec < hydroflow_plus :: ClusterId < () > > > (__hydroflow_plus_cluster_ids_1) }, diff --git a/hydroflow_plus_test/src/cluster/two_pc.rs b/hydroflow_plus_test/src/cluster/two_pc.rs index 42f944cb419f..4a5f8220cb60 100644 --- a/hydroflow_plus_test/src/cluster/two_pc.rs +++ b/hydroflow_plus_test/src/cluster/two_pc.rs @@ -1,5 +1,6 @@ use hydroflow_plus::*; -use stageleft::*; + +use super::quorum::collect_quorum; // if the variable start with p, that means current work is at the participant side. if start with c, at coordinator side. // @@ -33,7 +34,7 @@ pub fn two_pc<'a>( let c_receive_client_transactions = client_transaction.send_bincode(&coordinator); c_receive_client_transactions .clone() - .inspect(q!(|t| println!( + .for_each(q!(|t| println!( "receive transaction {}, ready to broadcast", t ))); @@ -41,47 +42,46 @@ pub fn two_pc<'a>( // broadcast prepare message to participants. let p_receive_prepare = c_receive_client_transactions.broadcast_bincode(&participants); - // assume all participants reply commit - let p_ready_to_commit = p_receive_prepare.map(q!(|t| (t, String::from("commit")))); + // participant 1 aborts transaction 1 + let p_ready_to_commit = p_receive_prepare.map(q!(move |t| ( + t, + if t == 1 && CLUSTER_SELF_ID.raw_id == 1 { + "abort".to_string() + } else { + "commit".to_string() + } + ))); let c_received_reply = p_ready_to_commit.send_bincode(&coordinator); // c_received_reply.clone().inspect(q!(|(id, (t, reply))| println!("participant {id} said {reply} for transaction {t}"))); // collect votes from participant. - // aborted transactions. - let c_participant_voted_abort = c_received_reply - .clone() - .filter(q!(|(_id, (_t, reply))| reply == "abort")) - .map(q!(|(id, (t, _reply))| (t, id))); - let p_receive_abort = c_participant_voted_abort.broadcast_bincode(&participants); - p_receive_abort.clone().inspect(q!(|(t, id)| println!( - "{} vote abort for transaction {}", - id, t - ))); + let coordinator_tick = coordinator.tick(); + let (c_all_commit, c_participant_voted_abort) = collect_quorum( + c_received_reply + .map(q!(|(id, (t, reply))| ( + t, + if reply == "commit" { Ok(()) } else { Err(id) } + ))) + .timestamped(&coordinator_tick), + num_participants as usize, + num_participants as usize, + ); + + let p_receive_abort = c_participant_voted_abort + // TODO(shadaj): if multiple participants vote abort we should deduplicate + .inspect(q!(|(t, id)| println!( + "{} vote abort for transaction {}", + id, t + ))) + .broadcast_bincode(&participants); let c_receive_ack = p_receive_abort.send_bincode(&coordinator); c_receive_ack.for_each(q!(|(id, (t, _))| println!( "Coordinator receive participant {} abort for transaction {}", id, t ))); - // committed transactions - let c_participant_voted_commit = c_received_reply - .filter(q!(|(_id, (_t, reply))| reply == "commit")) - .map(q!(|(id, (t, _reply))| (t, id))) - // fold_keyed: 1 input stream of type (K, V1), 1 output stream of type (K, V2). - // The output will have one tuple for each distinct K, with an accumulated value of type V2. - .tick_batch().fold_keyed(q!(|| 0), q!(|old: &mut u32, _| *old += 1)).filter_map(q!(move |(t, count)| { - // here I set the participant to 3. If want more or less participant, fix line 26 of examples/broadcast.rs - if count == num_participants { - Some(t) - } else { - None - } - })); - // broadcast commit transactions to participants. - let p_receive_commit = c_participant_voted_commit - .all_ticks() - .broadcast_bincode(&participants); + let p_receive_commit = c_all_commit.broadcast_bincode(&participants); // p_receive_commit.clone().for_each(q!(|t| println!("commit for transaction {}", t))); let c_receive_ack = p_receive_commit.send_bincode(&coordinator); diff --git a/hydroflow_plus_test/src/distributed/first_ten.rs b/hydroflow_plus_test/src/distributed/first_ten.rs index 18b7703f8ab4..5099e7d4e50e 100644 --- a/hydroflow_plus_test/src/distributed/first_ten.rs +++ b/hydroflow_plus_test/src/distributed/first_ten.rs @@ -1,7 +1,6 @@ use hydroflow_plus::*; -use location::{ExternalBincodeSink, ExternalProcess}; +use location::external_process::ExternalBincodeSink; use serde::{Deserialize, Serialize}; -use stageleft::*; #[derive(Serialize, Deserialize)] struct SendOverNetwork { @@ -12,67 +11,54 @@ pub struct P1 {} pub struct P2 {} pub fn first_ten_distributed<'a>( - flow: &FlowBuilder<'a>, -) -> ( - ExternalProcess<'a, ()>, - ExternalBincodeSink, - Process<'a, P1>, - Process<'a, P2>, -) { - let external_process = flow.external_process::<()>(); - let process = flow.process::(); - let second_process = flow.process::(); - - let (numbers_external_port, numbers_external) = - external_process.source_external_bincode(&process); + external: &ExternalProcess<'a, ()>, + process: &Process<'a, P1>, + second_process: &Process<'a, P2>, +) -> ExternalBincodeSink { + let (numbers_external_port, numbers_external) = external.source_external_bincode(process); numbers_external.for_each(q!(|n| println!("hi: {:?}", n))); let numbers = process.source_iter(q!(0..10)); numbers .map(q!(|n| SendOverNetwork { n })) - .send_bincode(&second_process) + .send_bincode(second_process) .for_each(q!(|n| println!("{}", n.n))); - ( - external_process, - numbers_external_port, - process, - second_process, - ) + numbers_external_port } #[cfg(test)] mod tests { - use std::sync::Arc; - use futures::SinkExt; - use hydro_deploy::{Deployment, Host}; - use hydroflow_plus::deploy::{DeployCrateWrapper, TrybuildHost}; + use hydro_deploy::Deployment; + use hydroflow_plus::deploy::DeployCrateWrapper; #[tokio::test] async fn first_ten_distributed() { let mut deployment = Deployment::new(); let builder = hydroflow_plus::FlowBuilder::new(); - let (external_process, external_port, first_node, second_node) = - super::first_ten_distributed(&builder); + let external = builder.external_process(); + let p1 = builder.process(); + let p2 = builder.process(); + let external_port = super::first_ten_distributed(&external, &p1, &p2); let built = builder.with_default_optimize(); insta::assert_debug_snapshot!(built.ir()); let nodes = built - .with_process(&first_node, TrybuildHost::new(deployment.Localhost())) - .with_process(&second_node, TrybuildHost::new(deployment.Localhost())) - .with_external(&external_process, deployment.Localhost() as Arc) + .with_process(&p1, deployment.Localhost()) + .with_process(&p2, deployment.Localhost()) + .with_external(&external, deployment.Localhost()) .deploy(&mut deployment); deployment.deploy().await.unwrap(); let mut external_port = nodes.connect_sink_bincode(external_port).await; - let mut first_node_stdout = nodes.get_process(&first_node).stdout().await; - let mut second_node_stdout = nodes.get_process(&second_node).stdout().await; + let mut first_node_stdout = nodes.get_process(&p1).stdout().await; + let mut second_node_stdout = nodes.get_process(&p2).stdout().await; deployment.start().await.unwrap(); diff --git a/hydroflow_plus_test_local/Cargo.toml b/hydroflow_plus_test_local/Cargo.toml index b38ed516dfa9..b8f301a0ce31 100644 --- a/hydroflow_plus_test_local/Cargo.toml +++ b/hydroflow_plus_test_local/Cargo.toml @@ -11,15 +11,15 @@ workspace = true stageleft_devel = [] [dependencies] -hydroflow = { path = "../hydroflow", version = "^0.9.0", default-features = false } # , features = ["debugging"] } -hydroflow_plus = { path = "../hydroflow_plus", version = "^0.9.0" } -stageleft = { path = "../stageleft", version = "^0.4.0" } +hydroflow = { path = "../hydroflow", version = "^0.10.0", default-features = false } # , features = ["debugging"] } +hydroflow_plus = { path = "../hydroflow_plus", version = "^0.10.0" } +stageleft = { path = "../stageleft", version = "^0.5.0" } rand = "0.8.0" hydroflow_plus_test_local_macro = { path = "../hydroflow_plus_test_local_macro" } [build-dependencies] -stageleft_tool = { path = "../stageleft_tool", version = "^0.3.0" } +stageleft_tool = { path = "../stageleft_tool", version = "^0.4.0" } [dev-dependencies] insta = "1.39" diff --git a/hydroflow_plus_test_local/src/local/chat_app.rs b/hydroflow_plus_test_local/src/local/chat_app.rs index 6ede979ea63f..b34d8e8dcecc 100644 --- a/hydroflow_plus_test_local/src/local/chat_app.rs +++ b/hydroflow_plus_test_local/src/local/chat_app.rs @@ -1,8 +1,9 @@ +use hydroflow::tokio::sync::mpsc::UnboundedSender; +use hydroflow::tokio_stream::wrappers::UnboundedReceiverStream; use hydroflow_plus::deploy::SingleProcessGraph; -use hydroflow_plus::tokio::sync::mpsc::UnboundedSender; -use hydroflow_plus::tokio_stream::wrappers::UnboundedReceiverStream; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::{q, Quoted, RuntimeData}; +use stageleft::{Quoted, RuntimeData}; #[stageleft::entry] pub fn chat_app<'a>( @@ -13,13 +14,29 @@ pub fn chat_app<'a>( replay_messages: bool, ) -> impl Quoted<'a, Hydroflow<'a>> { let process = flow.process::<()>(); - - let users = process.source_stream(users_stream).tick_batch().persist(); + let tick = process.tick(); + + let users = unsafe { + // SAFETY: intentionally non-deterministic to not send messaged + // to users that joined after the message was sent + process + .source_stream(users_stream) + .timestamped(&tick) + .tick_batch() + } + .persist(); let messages = process.source_stream(messages); let messages = if replay_messages { - messages.tick_batch().persist() + unsafe { + // SAFETY: see above + messages.timestamped(&tick).tick_batch() + } + .persist() } else { - messages.tick_batch() + unsafe { + // SAFETY: see above + messages.timestamped(&tick).tick_batch() + } }; // do this after the persist to test pullup @@ -34,21 +51,20 @@ pub fn chat_app<'a>( output.send(t).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::runtime] #[cfg(test)] mod tests { - use hydroflow_plus::assert_graphvis_snapshots; - use hydroflow_plus::util::collect_ready; + use hydroflow::assert_graphvis_snapshots; + use hydroflow::util::collect_ready; #[test] fn test_chat_app_no_replay() { - let (users_send, users) = hydroflow_plus::util::unbounded_channel(); - let (messages_send, messages) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (users_send, users) = hydroflow::util::unbounded_channel(); + let (messages_send, messages) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut chat_server = super::chat_app!(users, messages, &out, false); assert_graphvis_snapshots!(chat_server); @@ -89,9 +105,9 @@ mod tests { #[test] fn test_chat_app_replay() { - let (users_send, users) = hydroflow_plus::util::unbounded_channel(); - let (messages_send, messages) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (users_send, users) = hydroflow::util::unbounded_channel(); + let (messages_send, messages) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut chat_server = super::chat_app!(users, messages, &out, true); assert_graphvis_snapshots!(chat_server); diff --git a/hydroflow_plus_test_local/src/local/compute_pi.rs b/hydroflow_plus_test_local/src/local/compute_pi.rs index af4882fa2cfa..79ef4e3ba939 100644 --- a/hydroflow_plus_test_local/src/local/compute_pi.rs +++ b/hydroflow_plus_test_local/src/local/compute_pi.rs @@ -1,13 +1,15 @@ use std::time::Duration; use hydroflow_plus::deploy::SingleProcessGraph; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::*; +use stageleft::{Quoted, RuntimeData}; pub fn compute_pi<'a>(flow: &FlowBuilder<'a>, batch_size: RuntimeData) -> Process<'a, ()> { let process = flow.process(); + let tick = process.tick(); - let trials = process + let trials = tick .spin_batch(q!(batch_size)) .map(q!(|_| rand::random::<(f64, f64)>())) .map(q!(|(x, y)| x * x + y * y < 1.0)) @@ -21,21 +23,25 @@ pub fn compute_pi<'a>(flow: &FlowBuilder<'a>, batch_size: RuntimeData) -> *total += 1; }), ) - .all_ticks(); - - trials - .reduce(q!(|(inside, total), (inside_batch, total_batch)| { - *inside += inside_batch; - *total += total_batch; - })) - .sample_every(q!(Duration::from_secs(1))) - .for_each(q!(|(inside, total)| { - println!( - "pi: {} ({} trials)", - 4.0 * inside as f64 / total as f64, - total - ); - })); + .all_ticks() + .drop_timestamp(); + + let estimate = trials.reduce(q!(|(inside, total), (inside_batch, total_batch)| { + *inside += inside_batch; + *total += total_batch; + })); + + unsafe { + // SAFETY: intentional non-determinism + estimate.sample_every(q!(Duration::from_secs(1))) + } + .for_each(q!(|(inside, total)| { + println!( + "pi: {} ({} trials)", + 4.0 * inside as f64 / total as f64, + total + ); + })); process } @@ -46,6 +52,5 @@ pub fn compute_pi_runtime<'a>( batch_size: RuntimeData, ) -> impl Quoted<'a, Hydroflow<'a>> { let _ = compute_pi(&flow, batch_size); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } diff --git a/hydroflow_plus_test_local/src/local/count_elems.rs b/hydroflow_plus_test_local/src/local/count_elems.rs index 04818fed51ad..06497ea964be 100644 --- a/hydroflow_plus_test_local/src/local/count_elems.rs +++ b/hydroflow_plus_test_local/src/local/count_elems.rs @@ -1,8 +1,9 @@ +use hydroflow::tokio::sync::mpsc::UnboundedSender; +use hydroflow::tokio_stream::wrappers::UnboundedReceiverStream; use hydroflow_plus::deploy::SingleProcessGraph; -use hydroflow_plus::tokio::sync::mpsc::UnboundedSender; -use hydroflow_plus::tokio_stream::wrappers::UnboundedReceiverStream; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::{q, Quoted, RuntimeData}; +use stageleft::{Quoted, RuntimeData}; pub fn count_elems_generic<'a, T: 'a>( flow: FlowBuilder<'a>, @@ -10,20 +11,21 @@ pub fn count_elems_generic<'a, T: 'a>( output: RuntimeData<&'a UnboundedSender>, ) -> impl Quoted<'a, Hydroflow<'a>> { let process = flow.process::<()>(); + let tick = process.tick(); let source = process.source_stream(input_stream); - let count = source - .map(q!(|_| 1)) - .tick_batch() - .fold(q!(|| 0), q!(|a, b| *a += b)) - .all_ticks(); + let count = unsafe { + // SAFETY: intentionally using ticks + source.map(q!(|_| 1)).timestamped(&tick).tick_batch() + } + .fold(q!(|| 0), q!(|a, b| *a += b)) + .all_ticks(); count.for_each(q!(|v| { output.send(v).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::entry] @@ -38,13 +40,13 @@ pub fn count_elems<'a>( #[stageleft::runtime] #[cfg(test)] mod tests { - use hydroflow_plus::assert_graphvis_snapshots; - use hydroflow_plus::util::collect_ready; + use hydroflow::assert_graphvis_snapshots; + use hydroflow::util::collect_ready; #[test] pub fn test_count() { - let (in_send, input) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (in_send, input) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut count = super::count_elems!(input, &out); assert_graphvis_snapshots!(count); diff --git a/hydroflow_plus_test_local/src/local/first_ten.rs b/hydroflow_plus_test_local/src/local/first_ten.rs index 8da36aa823c6..2b027036e570 100644 --- a/hydroflow_plus_test_local/src/local/first_ten.rs +++ b/hydroflow_plus_test_local/src/local/first_ten.rs @@ -1,6 +1,7 @@ use hydroflow_plus::deploy::SingleProcessGraph; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::*; +use stageleft::Quoted; pub fn first_ten(flow: &FlowBuilder) { let process = flow.process::<()>(); @@ -11,8 +12,7 @@ pub fn first_ten(flow: &FlowBuilder) { #[stageleft::entry] pub fn first_ten_runtime<'a>(flow: FlowBuilder<'a>) -> impl Quoted<'a, Hydroflow<'a>> { first_ten(&flow); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::runtime] diff --git a/hydroflow_plus_test_local/src/local/graph_reachability.rs b/hydroflow_plus_test_local/src/local/graph_reachability.rs index c3a27f6c1d3f..c694b970a704 100644 --- a/hydroflow_plus_test_local/src/local/graph_reachability.rs +++ b/hydroflow_plus_test_local/src/local/graph_reachability.rs @@ -1,8 +1,9 @@ +use hydroflow::tokio::sync::mpsc::UnboundedSender; +use hydroflow::tokio_stream::wrappers::UnboundedReceiverStream; use hydroflow_plus::deploy::SingleProcessGraph; -use hydroflow_plus::tokio::sync::mpsc::UnboundedSender; -use hydroflow_plus::tokio_stream::wrappers::UnboundedReceiverStream; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::*; +use stageleft::{Quoted, RuntimeData}; #[stageleft::entry] pub fn graph_reachability<'a>( @@ -16,35 +17,44 @@ pub fn graph_reachability<'a>( let roots = process.source_stream(roots); let edges = process.source_stream(edges); - let (set_reached_cycle, reached_cycle) = process.cycle(); + let reachability_tick = process.tick(); + let (set_reached_cycle, reached_cycle) = reachability_tick.cycle::>(); - let reached = roots.union(reached_cycle); + let reached = unsafe { + // SAFETY: roots can be inserted on any tick because we are fixpointing + roots + .timestamped(&reachability_tick) + .tick_batch() + .union(reached_cycle) + }; let reachable = reached .clone() .map(q!(|r| (r, ()))) - .join(edges) + .join(unsafe { + // SAFETY: edges can be inserted on any tick because we are fixpointing + edges.timestamped(&reachability_tick).tick_batch().persist() + }) .map(q!(|(_from, (_, to))| to)); - set_reached_cycle.complete(reachable); + set_reached_cycle.complete_next_tick(reached.clone().union(reachable)); - reached.unique().for_each(q!(|v| { + reached.all_ticks().unique().for_each(q!(|v| { reached_out.send(v).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::runtime] #[cfg(test)] mod tests { - use hydroflow_plus::assert_graphvis_snapshots; - use hydroflow_plus::util::collect_ready; + use hydroflow::assert_graphvis_snapshots; + use hydroflow::util::collect_ready; #[test] pub fn test_reachability() { - let (roots_send, roots) = hydroflow_plus::util::unbounded_channel(); - let (edges_send, edges) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (roots_send, roots) = hydroflow::util::unbounded_channel(); + let (edges_send, edges) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut reachability = super::graph_reachability!(roots, edges, &out); assert_graphvis_snapshots!(reachability); @@ -57,6 +67,9 @@ mod tests { edges_send.send((3, 4)).unwrap(); edges_send.send((4, 5)).unwrap(); + reachability.run_tick(); + reachability.run_tick(); + reachability.run_tick(); reachability.run_tick(); assert_eq!( diff --git a/hydroflow_plus_test_local/src/local/negation.rs b/hydroflow_plus_test_local/src/local/negation.rs index 9fb75b678198..a44dc6505de6 100644 --- a/hydroflow_plus_test_local/src/local/negation.rs +++ b/hydroflow_plus_test_local/src/local/negation.rs @@ -1,7 +1,8 @@ +use hydroflow::tokio::sync::mpsc::UnboundedSender; use hydroflow_plus::deploy::SingleProcessGraph; -use hydroflow_plus::tokio::sync::mpsc::UnboundedSender; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::{q, Quoted, RuntimeData}; +use stageleft::{Quoted, RuntimeData}; #[stageleft::entry] pub fn test_difference<'a>( @@ -11,13 +12,26 @@ pub fn test_difference<'a>( persist2: bool, ) -> impl Quoted<'a, Hydroflow<'a>> { let process = flow.process::<()>(); - - let mut source = process.source_iter(q!(0..5)).tick_batch(); + let tick = process.tick(); + + let mut source = unsafe { + // SAFETY: intentionally using ticks + process + .source_iter(q!(0..5)) + .timestamped(&tick) + .tick_batch() + }; if persist1 { source = source.persist(); } - let mut source2 = process.source_iter(q!(3..6)).tick_batch(); + let mut source2 = unsafe { + // SAFETY: intentionally using ticks + process + .source_iter(q!(3..6)) + .timestamped(&tick) + .tick_batch() + }; if persist2 { source2 = source2.persist(); } @@ -26,8 +40,7 @@ pub fn test_difference<'a>( output.send(v).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::entry] @@ -38,16 +51,27 @@ pub fn test_anti_join<'a>( persist2: bool, ) -> impl Quoted<'a, Hydroflow<'a>> { let process = flow.process::<()>(); - - let mut source = process - .source_iter(q!(0..5)) - .map(q!(|v| (v, v))) - .tick_batch(); + let tick = process.tick(); + + let mut source = unsafe { + // SAFETY: intentionally using ticks + process + .source_iter(q!(0..5)) + .map(q!(|v| (v, v))) + .timestamped(&tick) + .tick_batch() + }; if persist1 { source = source.persist(); } - let mut source2 = process.source_iter(q!(3..6)).tick_batch(); + let mut source2 = unsafe { + // SAFETY: intentionally using ticks + process + .source_iter(q!(3..6)) + .timestamped(&tick) + .tick_batch() + }; if persist2 { source2 = source2.persist(); } @@ -56,19 +80,18 @@ pub fn test_anti_join<'a>( output.send(v.0).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() } #[stageleft::runtime] #[cfg(test)] mod tests { - use hydroflow_plus::assert_graphvis_snapshots; - use hydroflow_plus::util::collect_ready; + use hydroflow::assert_graphvis_snapshots; + use hydroflow::util::collect_ready; #[test] fn test_difference_tick_tick() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_difference!(&out, false, false); assert_graphvis_snapshots!(flow); @@ -84,7 +107,7 @@ mod tests { #[test] fn test_difference_tick_static() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_difference!(&out, false, true); assert_graphvis_snapshots!(flow); @@ -100,7 +123,7 @@ mod tests { #[test] fn test_difference_static_tick() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_difference!(&out, true, false); assert_graphvis_snapshots!(flow); @@ -119,7 +142,7 @@ mod tests { #[test] fn test_difference_static_static() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_difference!(&out, true, true); assert_graphvis_snapshots!(flow); @@ -135,7 +158,7 @@ mod tests { #[test] fn test_anti_join_tick_tick() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_anti_join!(&out, false, false); assert_graphvis_snapshots!(flow); @@ -151,7 +174,7 @@ mod tests { #[test] fn test_anti_join_tick_static() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_anti_join!(&out, false, true); assert_graphvis_snapshots!(flow); @@ -167,7 +190,7 @@ mod tests { #[test] fn test_anti_join_static_tick() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_anti_join!(&out, true, false); assert_graphvis_snapshots!(flow); @@ -186,7 +209,7 @@ mod tests { #[test] fn test_anti_join_static_static() { - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut flow = super::test_anti_join!(&out, true, true); assert_graphvis_snapshots!(flow); diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_dot.snap index 357ce04046f0..aa61b78fad2f 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_dot.snap @@ -9,7 +9,7 @@ digraph { n2v1 [label="(n2v1) source_stream(messages)", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l std::string::String,\l std::string::String,\l >({\l use crate::__staged::local::chat_app::*;\l |s| s.to_uppercase()\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) cross_join_multiset::<'static, 'tick>()", shape=invhouse, fillcolor="#88aaff"] - n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, std::string::String),\l (),\l >({\l use crate::__staged::local::chat_app::*;\l let output = output;\l |t| {\l output.send(t).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, std::string::String),\l (),\l >({\l use crate::__staged::local::chat_app::*;\l let output__free = output;\l |t| {\l output__free.send(t).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n2v1 -> n3v1 n1v1 -> n4v1 [label="0"] n3v1 -> n4v1 [label="1"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_mermaid.snap index 1e4f82827685..d7f3ff6decc9 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_no_replay@graphvis_mermaid.snap @@ -12,7 +12,7 @@ linkStyle default stroke:#aaa 2v1[\"(2v1) source_stream(messages)"/]:::pullClass 3v1[\"

(3v1)
map(
stageleft::runtime_support::fn1_type_hint::<
std::string::String,
std::string::String,
>({
use crate::__staged::local::chat_app::*;
|s| s.to_uppercase()
}),
)
"/]:::pullClass 4v1[\"(4v1) cross_join_multiset::<'static, 'tick>()"/]:::pullClass -5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, std::string::String),
(),
>({
use crate::__staged::local::chat_app::*;
let output = output;
|t| {
output.send(t).unwrap();
}
}),
)
"\]:::pushClass +5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, std::string::String),
(),
>({
use crate::__staged::local::chat_app::*;
let output__free = output;
|t| {
output__free.send(t).unwrap();
}
}),
)
"\]:::pushClass 2v1-->3v1 1v1-->|0|4v1 3v1-->|1|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_dot.snap index 4126022abd7e..3fb6e6d48cf8 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_dot.snap @@ -10,7 +10,7 @@ digraph { n3v1 [label="(n3v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l std::string::String,\l std::string::String,\l >({\l use crate::__staged::local::chat_app::*;\l |s| s.to_uppercase()\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) cross_join_multiset::<'static, 'static>()", shape=invhouse, fillcolor="#88aaff"] n5v1 [label="(n5v1) multiset_delta()", shape=invhouse, fillcolor="#88aaff"] - n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, std::string::String),\l (),\l >({\l use crate::__staged::local::chat_app::*;\l let output = output;\l |t| {\l output.send(t).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, std::string::String),\l (),\l >({\l use crate::__staged::local::chat_app::*;\l let output__free = output;\l |t| {\l output__free.send(t).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n2v1 -> n3v1 n1v1 -> n4v1 [label="0"] n3v1 -> n4v1 [label="1"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_mermaid.snap index 893b860d09ba..9c3d82a4e5e8 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__chat_app__tests__chat_app_replay@graphvis_mermaid.snap @@ -13,7 +13,7 @@ linkStyle default stroke:#aaa 3v1[\"
(3v1)
map(
stageleft::runtime_support::fn1_type_hint::<
std::string::String,
std::string::String,
>({
use crate::__staged::local::chat_app::*;
|s| s.to_uppercase()
}),
)
"/]:::pullClass 4v1[\"(4v1) cross_join_multiset::<'static, 'static>()"/]:::pullClass 5v1[\"(5v1) multiset_delta()"/]:::pullClass -6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, std::string::String),
(),
>({
use crate::__staged::local::chat_app::*;
let output = output;
|t| {
output.send(t).unwrap();
}
}),
)
"\]:::pushClass +6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, std::string::String),
(),
>({
use crate::__staged::local::chat_app::*;
let output__free = output;
|t| {
output__free.send(t).unwrap();
}
}),
)
"\]:::pushClass 2v1-->3v1 1v1-->|0|4v1 3v1-->|1|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_dot.snap index 177414b8d207..374f7193775e 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_dot.snap @@ -8,7 +8,7 @@ digraph { n1v1 [label="(n1v1) source_stream(input_stream)", shape=invhouse, fillcolor="#88aaff"] n2v1 [label="(n2v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l usize,\l u32,\l >({\l use crate::__staged::local::count_elems::*;\l |_| 1\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) fold::<\l 'tick,\l>(\l stageleft::runtime_support::fn0_type_hint::<\l u32,\l >({\l use crate::__staged::local::count_elems::*;\l || 0\l }),\l stageleft::runtime_support::fn2_borrow_mut_type_hint::<\l u32,\l u32,\l (),\l >({\l use crate::__staged::local::count_elems::*;\l |a, b| *a += b\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] - n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::count_elems::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::count_elems::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n5v1 [label="(n5v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_mermaid.snap index f0e71c8608e7..47423697fb14 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__count_elems__tests__count@graphvis_mermaid.snap @@ -11,7 +11,7 @@ linkStyle default stroke:#aaa 1v1[\"(1v1) source_stream(input_stream)"/]:::pullClass 2v1[\"
(2v1)
map(
stageleft::runtime_support::fn1_type_hint::<
usize,
u32,
>({
use crate::__staged::local::count_elems::*;
|_| 1
}),
)
"/]:::pullClass 3v1[\"
(3v1)
fold::<
'tick,
>(
stageleft::runtime_support::fn0_type_hint::<
u32,
>({
use crate::__staged::local::count_elems::*;
|| 0
}),
stageleft::runtime_support::fn2_borrow_mut_type_hint::<
u32,
u32,
(),
>({
use crate::__staged::local::count_elems::*;
|a, b| *a += b
}),
)
"/]:::pullClass -4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::count_elems::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::count_elems::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 5v1["(5v1) handoff"]:::otherClass 1v1-->2v1 2v1-->5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_dot.snap index 9cf66d710d8e..a29934f0eb58 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_dot.snap @@ -6,91 +6,131 @@ digraph { node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; n1v1 [label="(n1v1) source_stream(roots)", shape=invhouse, fillcolor="#88aaff"] - n2v1 [label="(n2v1) union()", shape=invhouse, fillcolor="#88aaff"] + n2v1 [label="(n2v1) chain()", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) tee()", shape=house, fillcolor="#ffff88"] n4v1 [label="(n4v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (u32, ()),\l >({\l use crate::__staged::local::graph_reachability::*;\l |r| (r, ())\l }),\l)\l", shape=house, fillcolor="#ffff88"] n5v1 [label="(n5v1) source_stream(edges)", shape=invhouse, fillcolor="#88aaff"] - n6v1 [label="(n6v1) join_multiset::<'static, 'static>()", shape=invhouse, fillcolor="#88aaff"] - n7v1 [label="(n7v1) multiset_delta()", shape=invhouse, fillcolor="#88aaff"] - n8v1 [label="(n8v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, ((), u32)),\l u32,\l >({\l use crate::__staged::local::graph_reachability::*;\l |(_from, (_, to))| to\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] - n9v1 [label="(n9v1) persist::<'static>()", shape=house, fillcolor="#ffff88"] - n10v1 [label="(n10v1) unique::<'tick>()", shape=house, fillcolor="#ffff88"] - n11v1 [label="(n11v1) multiset_delta()", shape=house, fillcolor="#ffff88"] - n12v1 [label="(n12v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::graph_reachability::*;\l let reached_out = reached_out;\l |v| {\l reached_out.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] - n13v1 [label="(n13v1) handoff", shape=parallelogram, fillcolor="#ddddff"] - n1v1 -> n2v1 [label="0"] - n8v1 -> n2v1 [label="1"] + n6v1 [label="(n6v1) join_multiset::<'tick, 'static>()", shape=invhouse, fillcolor="#88aaff"] + n7v1 [label="(n7v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, ((), u32)),\l u32,\l >({\l use crate::__staged::local::graph_reachability::*;\l |(_from, (_, to))| to\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] + n8v1 [label="(n8v1) chain()", shape=invhouse, fillcolor="#88aaff"] + n9v1 [label="(n9v1) defer_tick_lazy()", shape=invhouse, fillcolor="#88aaff"] + n10v1 [label="(n10v1) persist::<'static>()", shape=house, fillcolor="#ffff88"] + n11v1 [label="(n11v1) unique::<'tick>()", shape=house, fillcolor="#ffff88"] + n12v1 [label="(n12v1) multiset_delta()", shape=house, fillcolor="#ffff88"] + n13v1 [label="(n13v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::graph_reachability::*;\l let reached_out__free = reached_out;\l |v| {\l reached_out__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n14v1 [label="(n14v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n15v1 [label="(n15v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n16v1 [label="(n16v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n17v1 [label="(n17v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n18v1 [label="(n18v1) identity()", shape=invhouse, fillcolor="#88aaff"] + n19v1 [label="(n19v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n20v1 [label="(n20v1) handoff", shape=parallelogram, fillcolor="#ddddff"] + n1v1 -> n14v1 + n9v1 -> n2v1 [label="1"] n2v1 -> n3v1 n3v1 -> n4v1 - n4v1 -> n13v1 - n5v1 -> n6v1 [label="1"] + n4v1 -> n15v1 + n5v1 -> n20v1 n6v1 -> n7v1 - n7v1 -> n8v1 - n3v1 -> n9v1 - n9v1 -> n10v1 + n3v1 -> n16v1 + n7v1 -> n8v1 [label="1"] + n8v1 -> n17v1 + n3v1 -> n10v1 n10v1 -> n11v1 n11v1 -> n12v1 - n13v1 -> n6v1 [label="0"] + n12v1 -> n13v1 + n14v1 -> n2v1 [label="0", color=red] + n15v1 -> n6v1 [label="0"] + n16v1 -> n8v1 [label="0", color=red] + n17v1 -> n18v1 + n18v1 -> n19v1 + n19v1 -> n9v1 [color=red] + n20v1 -> n6v1 [label="1"] subgraph "cluster n1v1" { fillcolor="#dddddd" style=filled label = "sg_1v1\nstratum 0" - n13v1 n1v1 - n5v1 + subgraph "cluster_sg_1v1_var_stream_0" { + label="var stream_0" + n1v1 + } + } + subgraph "cluster n2v1" { + fillcolor="#dddddd" + style=filled + label = "sg_2v1\nstratum 2" n6v1 n7v1 n8v1 + subgraph "cluster_sg_2v1_var_stream_5" { + label="var stream_5" + n6v1 + } + subgraph "cluster_sg_2v1_var_stream_6" { + label="var stream_6" + n7v1 + } + subgraph "cluster_sg_2v1_var_stream_7" { + label="var stream_7" + n8v1 + } + } + subgraph "cluster n3v1" { + fillcolor="#dddddd" + style=filled + label = "sg_3v1\nstratum 1" + n9v1 n2v1 n3v1 n4v1 - n9v1 n10v1 n11v1 n12v1 - subgraph "cluster_sg_1v1_var_stream_0" { - label="var stream_0" - n1v1 - } - subgraph "cluster_sg_1v1_var_stream_1" { + n13v1 + subgraph "cluster_sg_3v1_var_stream_1" { label="var stream_1" n2v1 } - subgraph "cluster_sg_1v1_var_stream_10" { + subgraph "cluster_sg_3v1_var_stream_10" { label="var stream_10" n11v1 } - subgraph "cluster_sg_1v1_var_stream_2" { + subgraph "cluster_sg_3v1_var_stream_11" { + label="var stream_11" + n12v1 + } + subgraph "cluster_sg_3v1_var_stream_2" { label="var stream_2" n3v1 } - subgraph "cluster_sg_1v1_var_stream_3" { + subgraph "cluster_sg_3v1_var_stream_3" { label="var stream_3" n4v1 } - subgraph "cluster_sg_1v1_var_stream_4" { - label="var stream_4" - n5v1 - } - subgraph "cluster_sg_1v1_var_stream_5" { - label="var stream_5" - n6v1 - } - subgraph "cluster_sg_1v1_var_stream_6" { - label="var stream_6" - n7v1 - } - subgraph "cluster_sg_1v1_var_stream_7" { - label="var stream_7" - n8v1 - } - subgraph "cluster_sg_1v1_var_stream_8" { + subgraph "cluster_sg_3v1_var_stream_8" { label="var stream_8" n9v1 } - subgraph "cluster_sg_1v1_var_stream_9" { + subgraph "cluster_sg_3v1_var_stream_9" { label="var stream_9" n10v1 } } + subgraph "cluster n4v1" { + fillcolor="#dddddd" + style=filled + label = "sg_4v1\nstratum 3" + n18v1 + } + subgraph "cluster n5v1" { + fillcolor="#dddddd" + style=filled + label = "sg_5v1\nstratum 0" + n5v1 + subgraph "cluster_sg_5v1_var_stream_4" { + label="var stream_4" + n5v1 + } + } } diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_mermaid.snap index 29f937404769..bdd9a1910fc6 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__graph_reachability__tests__reachability@graphvis_mermaid.snap @@ -9,76 +9,103 @@ classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre linkStyle default stroke:#aaa 1v1[\"(1v1) source_stream(roots)"/]:::pullClass -2v1[\"(2v1) union()"/]:::pullClass +2v1[\"(2v1) chain()"/]:::pullClass 3v1[/"(3v1) tee()"\]:::pushClass 4v1[/"
(4v1)
map(
stageleft::runtime_support::fn1_type_hint::<
u32,
(u32, ()),
>({
use crate::__staged::local::graph_reachability::*;
|r| (r, ())
}),
)
"\]:::pushClass 5v1[\"(5v1) source_stream(edges)"/]:::pullClass -6v1[\"(6v1) join_multiset::<'static, 'static>()"/]:::pullClass -7v1[\"(7v1) multiset_delta()"/]:::pullClass -8v1[\"
(8v1)
map(
stageleft::runtime_support::fn1_type_hint::<
(u32, ((), u32)),
u32,
>({
use crate::__staged::local::graph_reachability::*;
|(_from, (_, to))| to
}),
)
"/]:::pullClass -9v1[/"(9v1) persist::<'static>()"\]:::pushClass -10v1[/"(10v1) unique::<'tick>()"\]:::pushClass -11v1[/"(11v1) multiset_delta()"\]:::pushClass -12v1[/"
(12v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::graph_reachability::*;
let reached_out = reached_out;
|v| {
reached_out.send(v).unwrap();
}
}),
)
"\]:::pushClass -13v1["(13v1) handoff"]:::otherClass -1v1-->|0|2v1 -8v1-->|1|2v1 +6v1[\"(6v1) join_multiset::<'tick, 'static>()"/]:::pullClass +7v1[\"
(7v1)
map(
stageleft::runtime_support::fn1_type_hint::<
(u32, ((), u32)),
u32,
>({
use crate::__staged::local::graph_reachability::*;
|(_from, (_, to))| to
}),
)
"/]:::pullClass +8v1[\"(8v1) chain()"/]:::pullClass +9v1[\"(9v1) defer_tick_lazy()"/]:::pullClass +10v1[/"(10v1) persist::<'static>()"\]:::pushClass +11v1[/"(11v1) unique::<'tick>()"\]:::pushClass +12v1[/"(12v1) multiset_delta()"\]:::pushClass +13v1[/"
(13v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::graph_reachability::*;
let reached_out__free = reached_out;
|v| {
reached_out__free.send(v).unwrap();
}
}),
)
"\]:::pushClass +14v1["(14v1) handoff"]:::otherClass +15v1["(15v1) handoff"]:::otherClass +16v1["(16v1) handoff"]:::otherClass +17v1["(17v1) handoff"]:::otherClass +18v1[\"(18v1) identity()"/]:::pullClass +19v1["(19v1) handoff"]:::otherClass +20v1["(20v1) handoff"]:::otherClass +1v1-->14v1 +9v1-->|1|2v1 2v1-->3v1 3v1-->4v1 -4v1-->13v1 -5v1-->|1|6v1 +4v1-->15v1 +5v1-->20v1 6v1-->7v1 -7v1-->8v1 -3v1-->9v1 -9v1-->10v1 +3v1-->16v1 +7v1-->|1|8v1 +8v1-->17v1 +3v1-->10v1 10v1-->11v1 11v1-->12v1 -13v1-->|0|6v1 +12v1-->13v1 +14v1--x|0|2v1; linkStyle 14 stroke:red +15v1-->|0|6v1 +16v1--x|0|8v1; linkStyle 16 stroke:red +17v1-->18v1 +18v1-->19v1 +19v1--o9v1; linkStyle 19 stroke:red +20v1-->|1|6v1 subgraph sg_1v1 ["sg_1v1 stratum 0"] - 13v1 1v1 - 5v1 + subgraph sg_1v1_var_stream_0 ["var stream_0"] + 1v1 + end +end +subgraph sg_2v1 ["sg_2v1 stratum 2"] 6v1 7v1 8v1 + subgraph sg_2v1_var_stream_5 ["var stream_5"] + 6v1 + end + subgraph sg_2v1_var_stream_6 ["var stream_6"] + 7v1 + end + subgraph sg_2v1_var_stream_7 ["var stream_7"] + 8v1 + end +end +subgraph sg_3v1 ["sg_3v1 stratum 1"] + 9v1 2v1 3v1 4v1 - 9v1 10v1 11v1 12v1 - subgraph sg_1v1_var_stream_0 ["var stream_0"] - 1v1 - end - subgraph sg_1v1_var_stream_1 ["var stream_1"] + 13v1 + subgraph sg_3v1_var_stream_1 ["var stream_1"] 2v1 end - subgraph sg_1v1_var_stream_10 ["var stream_10"] + subgraph sg_3v1_var_stream_10 ["var stream_10"] 11v1 end - subgraph sg_1v1_var_stream_2 ["var stream_2"] + subgraph sg_3v1_var_stream_11 ["var stream_11"] + 12v1 + end + subgraph sg_3v1_var_stream_2 ["var stream_2"] 3v1 end - subgraph sg_1v1_var_stream_3 ["var stream_3"] + subgraph sg_3v1_var_stream_3 ["var stream_3"] 4v1 end - subgraph sg_1v1_var_stream_4 ["var stream_4"] - 5v1 - end - subgraph sg_1v1_var_stream_5 ["var stream_5"] - 6v1 - end - subgraph sg_1v1_var_stream_6 ["var stream_6"] - 7v1 - end - subgraph sg_1v1_var_stream_7 ["var stream_7"] - 8v1 - end - subgraph sg_1v1_var_stream_8 ["var stream_8"] + subgraph sg_3v1_var_stream_8 ["var stream_8"] 9v1 end - subgraph sg_1v1_var_stream_9 ["var stream_9"] + subgraph sg_3v1_var_stream_9 ["var stream_9"] 10v1 end end +subgraph sg_4v1 ["sg_4v1 stratum 3"] + 18v1 +end +subgraph sg_5v1 ["sg_5v1 stratum 0"] + 5v1 + subgraph sg_5v1_var_stream_4 ["var stream_4"] + 5v1 + end +end diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_dot.snap index a42f15c8200d..c1d64fab31b3 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_dot.snap @@ -10,7 +10,7 @@ digraph { n3v1 [label="(n3v1) persist::<'static>()", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n5v1 [label="(n5v1) anti_join_multiset::<'tick, 'static>()", shape=invhouse, fillcolor="#88aaff"] - n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n7v1 [label="(n7v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_mermaid.snap index a551e93b7771..e461c8275ec8 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_static@graphvis_mermaid.snap @@ -13,7 +13,7 @@ linkStyle default stroke:#aaa 3v1[\"(3v1) persist::<'static>()"/]:::pullClass 4v1[\"
(4v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 5v1[\"(5v1) anti_join_multiset::<'tick, 'static>()"/]:::pullClass -6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v.0).unwrap();
}
}),
)
"\]:::pushClass +6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v.0).unwrap();
}
}),
)
"\]:::pushClass 7v1["(7v1) handoff"]:::otherClass 1v1-->2v1 2v1-->3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_dot.snap index 064e8c2ad217..125415caa1f9 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_dot.snap @@ -10,7 +10,7 @@ digraph { n3v1 [label="(n3v1) persist::<'static>()", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n5v1 [label="(n5v1) anti_join_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] - n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n6v1 [label="(n6v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n7v1 [label="(n7v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_mermaid.snap index 72e7e8e12cc0..daa59bcd9c60 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_static_tick@graphvis_mermaid.snap @@ -13,7 +13,7 @@ linkStyle default stroke:#aaa 3v1[\"(3v1) persist::<'static>()"/]:::pullClass 4v1[\"
(4v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 5v1[\"(5v1) anti_join_multiset::<'tick, 'tick>()"/]:::pullClass -6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v.0).unwrap();
}
}),
)
"\]:::pushClass +6v1[/"
(6v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v.0).unwrap();
}
}),
)
"\]:::pushClass 7v1["(7v1) handoff"]:::otherClass 1v1-->2v1 2v1-->3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_dot.snap index e08580edcfca..79936132989d 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_dot.snap @@ -9,7 +9,7 @@ digraph { n2v1 [label="(n2v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (u32, u32),\l >({\l use crate::__staged::local::negation::*;\l |v| (v, v)\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) anti_join_multiset::<'tick, 'static>()", shape=invhouse, fillcolor="#88aaff"] - n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n6v1 [label="(n6v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n4v1 [label="pos"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_mermaid.snap index bd3ed201ed8b..6d60700e2d83 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_static@graphvis_mermaid.snap @@ -12,7 +12,7 @@ linkStyle default stroke:#aaa 2v1[\"
(2v1)
map(
stageleft::runtime_support::fn1_type_hint::<
u32,
(u32, u32),
>({
use crate::__staged::local::negation::*;
|v| (v, v)
}),
)
"/]:::pullClass 3v1[\"
(3v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 4v1[\"(4v1) anti_join_multiset::<'tick, 'static>()"/]:::pullClass -5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v.0).unwrap();
}
}),
)
"\]:::pushClass +5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v.0).unwrap();
}
}),
)
"\]:::pushClass 6v1["(6v1) handoff"]:::otherClass 1v1-->2v1 2v1-->|pos|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_dot.snap index 19c6f15739b8..8a4b988f4ce0 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_dot.snap @@ -9,7 +9,7 @@ digraph { n2v1 [label="(n2v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (u32, u32),\l >({\l use crate::__staged::local::negation::*;\l |v| (v, v)\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) anti_join_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] - n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, u32),\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v.0).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n6v1 [label="(n6v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n4v1 [label="pos"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_mermaid.snap index f43ea369d190..16fd2abddc27 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__anti_join_tick_tick@graphvis_mermaid.snap @@ -12,7 +12,7 @@ linkStyle default stroke:#aaa 2v1[\"
(2v1)
map(
stageleft::runtime_support::fn1_type_hint::<
u32,
(u32, u32),
>({
use crate::__staged::local::negation::*;
|v| (v, v)
}),
)
"/]:::pullClass 3v1[\"
(3v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 4v1[\"(4v1) anti_join_multiset::<'tick, 'tick>()"/]:::pullClass -5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v.0).unwrap();
}
}),
)
"\]:::pushClass +5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
(u32, u32),
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v.0).unwrap();
}
}),
)
"\]:::pushClass 6v1["(6v1) handoff"]:::otherClass 1v1-->2v1 2v1-->|pos|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_dot.snap index 0089af5b6d8f..b9112226c9de 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_dot.snap @@ -9,7 +9,7 @@ digraph { n2v1 [label="(n2v1) persist::<'static>()", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) difference_multiset::<'tick, 'static>()", shape=invhouse, fillcolor="#88aaff"] - n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n6v1 [label="(n6v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n4v1 [label="pos"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_mermaid.snap index 78b507ade59d..c28b6b0d4d5d 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_static@graphvis_mermaid.snap @@ -12,7 +12,7 @@ linkStyle default stroke:#aaa 2v1[\"(2v1) persist::<'static>()"/]:::pullClass 3v1[\"
(3v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 4v1[\"(4v1) difference_multiset::<'tick, 'static>()"/]:::pullClass -5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 6v1["(6v1) handoff"]:::otherClass 1v1-->2v1 2v1-->|pos|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_dot.snap index 319db4ff376f..1e9a8e2cf4e5 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_dot.snap @@ -9,7 +9,7 @@ digraph { n2v1 [label="(n2v1) persist::<'static>()", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n4v1 [label="(n4v1) difference_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] - n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n5v1 [label="(n5v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n6v1 [label="(n6v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n4v1 [label="pos"] diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_mermaid.snap index b2582dbf4bbd..e7d673d11e08 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_static_tick@graphvis_mermaid.snap @@ -12,7 +12,7 @@ linkStyle default stroke:#aaa 2v1[\"(2v1) persist::<'static>()"/]:::pullClass 3v1[\"
(3v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 4v1[\"(4v1) difference_multiset::<'tick, 'tick>()"/]:::pullClass -5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +5v1[/"
(5v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 6v1["(6v1) handoff"]:::otherClass 1v1-->2v1 2v1-->|pos|4v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_dot.snap index 3686d5a6bff6..1eea0f181a5a 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_dot.snap @@ -8,7 +8,7 @@ digraph { n1v1 [label="(n1v1) source_iter({\l use crate::__staged::local::negation::*;\l 0..5\l})\l", shape=invhouse, fillcolor="#88aaff"] n2v1 [label="(n2v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) difference_multiset::<'tick, 'static>()", shape=invhouse, fillcolor="#88aaff"] - n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n5v1 [label="(n5v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n3v1 [label="pos"] n2v1 -> n5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_mermaid.snap index 4de7f82c02b4..ad3cf51c3a1c 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_static@graphvis_mermaid.snap @@ -11,7 +11,7 @@ linkStyle default stroke:#aaa 1v1[\"
(1v1)
source_iter({
use crate::__staged::local::negation::*;
0..5
})
"/]:::pullClass 2v1[\"
(2v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 3v1[\"(3v1) difference_multiset::<'tick, 'static>()"/]:::pullClass -4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 5v1["(5v1) handoff"]:::otherClass 1v1-->|pos|3v1 2v1-->5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_dot.snap index 2ef95dfc528c..67dc43c1e7fe 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_dot.snap @@ -8,7 +8,7 @@ digraph { n1v1 [label="(n1v1) source_iter({\l use crate::__staged::local::negation::*;\l 0..5\l})\l", shape=invhouse, fillcolor="#88aaff"] n2v1 [label="(n2v1) source_iter({\l use crate::__staged::local::negation::*;\l 3..6\l})\l", shape=invhouse, fillcolor="#88aaff"] n3v1 [label="(n3v1) difference_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] - n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n4v1 [label="(n4v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::negation::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n5v1 [label="(n5v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n3v1 [label="pos"] n2v1 -> n5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_mermaid.snap index 7b67d52f7b82..af952d07e1d6 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__negation__tests__difference_tick_tick@graphvis_mermaid.snap @@ -11,7 +11,7 @@ linkStyle default stroke:#aaa 1v1[\"
(1v1)
source_iter({
use crate::__staged::local::negation::*;
0..5
})
"/]:::pullClass 2v1[\"
(2v1)
source_iter({
use crate::__staged::local::negation::*;
3..6
})
"/]:::pullClass 3v1[\"(3v1) difference_multiset::<'tick, 'tick>()"/]:::pullClass -4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +4v1[/"
(4v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::negation::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 5v1["(5v1) handoff"]:::otherClass 1v1-->|pos|3v1 2v1-->5v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_dot.snap index 600618e9b6b1..ac9a190ad283 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_dot.snap @@ -12,7 +12,7 @@ digraph { n5v1 [label="(n5v1) join_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] n6v1 [label="(n6v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, ((), ())),\l u32,\l >({\l use crate::__staged::local::teed_join::*;\l |t| t.0\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n7v3 [label="(n7v3) handoff", shape=parallelogram, fillcolor="#ddddff"] - n8v1 [label="(n8v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n8v1 [label="(n8v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n9v1 [label="(n9v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 n2v1 -> n3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_mermaid.snap index 78c612ffe837..4da0aa56994c 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join@graphvis_mermaid.snap @@ -15,7 +15,7 @@ linkStyle default stroke:#aaa 5v1[\"(5v1) join_multiset::<'tick, 'tick>()"/]:::pullClass 6v1[\"
(6v1)
map(
stageleft::runtime_support::fn1_type_hint::<
(u32, ((), ())),
u32,
>({
use crate::__staged::local::teed_join::*;
|t| t.0
}),
)
"/]:::pullClass 7v3["(7v3) handoff"]:::otherClass -8v1[/"
(8v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +8v1[/"
(8v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 9v1["(9v1) handoff"]:::otherClass 1v1-->2v1 2v1-->3v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_dot.snap index 82416ab8855c..c557ed3d7ad5 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_dot.snap @@ -6,7 +6,7 @@ digraph { node [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace", style=filled]; edge [fontname="Monaco,Menlo,Consolas,"Droid Sans Mono",Inconsolata,"Courier New",monospace"]; n1v1 [label="(n1v1) source_iter({\l use crate::__staged::local::teed_join::*;\l 0..5\l})\l", shape=invhouse, fillcolor="#88aaff"] - n2v1 [label="(n2v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n2v1 [label="(n2v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n1v1 -> n2v1 subgraph "cluster n1v1" { fillcolor="#dddddd" diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_mermaid.snap index 9cbaddadeb1a..72cdbf388e0e 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_multi_node@graphvis_mermaid.snap @@ -9,7 +9,7 @@ classDef pushClass fill:#ff8,stroke:#000,text-align:left,white-space:pre classDef otherClass fill:#fdc,stroke:#000,text-align:left,white-space:pre linkStyle default stroke:#aaa 1v1[\"
(1v1)
source_iter({
use crate::__staged::local::teed_join::*;
0..5
})
"/]:::pullClass -2v1[/"
(2v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +2v1[/"
(2v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 1v1-->2v1 subgraph sg_1v1 ["sg_1v1 stratum 0"] 1v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_dot.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_dot.snap index 267d3d849447..d35e86f614ec 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_dot.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_dot.snap @@ -12,8 +12,8 @@ digraph { n5v1 [label="(n5v1) join_multiset::<'tick, 'tick>()", shape=invhouse, fillcolor="#88aaff"] n6v1 [label="(n6v1) map(\l stageleft::runtime_support::fn1_type_hint::<\l (u32, ((), ())),\l u32,\l >({\l use crate::__staged::local::teed_join::*;\l |t| t.0\l }),\l)\l", shape=invhouse, fillcolor="#88aaff"] n7v1 [label="(n7v1) tee()", shape=house, fillcolor="#ffff88"] - n8v1 [label="(n8v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] - n9v1 [label="(n9v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output = output;\l |v| {\l output.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n8v1 [label="(n8v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] + n9v1 [label="(n9v1) for_each(\l stageleft::runtime_support::fn1_type_hint::<\l u32,\l (),\l >({\l use crate::__staged::local::teed_join::*;\l let output__free = output;\l |v| {\l output__free.send(v).unwrap();\l }\l }),\l)\l", shape=house, fillcolor="#ffff88"] n10v1 [label="(n10v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n11v1 [label="(n11v1) handoff", shape=parallelogram, fillcolor="#ddddff"] n1v1 -> n2v1 diff --git a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_mermaid.snap b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_mermaid.snap index e8ddfbbd0b98..5efe825e367d 100644 --- a/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_mermaid.snap +++ b/hydroflow_plus_test_local/src/local/snapshots/hydroflow_plus_test_local__local__teed_join__tests__teed_join_twice@graphvis_mermaid.snap @@ -15,8 +15,8 @@ linkStyle default stroke:#aaa 5v1[\"(5v1) join_multiset::<'tick, 'tick>()"/]:::pullClass 6v1[\"
(6v1)
map(
stageleft::runtime_support::fn1_type_hint::<
(u32, ((), ())),
u32,
>({
use crate::__staged::local::teed_join::*;
|t| t.0
}),
)
"/]:::pullClass 7v1[/"(7v1) tee()"\]:::pushClass -8v1[/"
(8v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass -9v1[/"
(9v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output = output;
|v| {
output.send(v).unwrap();
}
}),
)
"\]:::pushClass +8v1[/"
(8v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass +9v1[/"
(9v1)
for_each(
stageleft::runtime_support::fn1_type_hint::<
u32,
(),
>({
use crate::__staged::local::teed_join::*;
let output__free = output;
|v| {
output__free.send(v).unwrap();
}
}),
)
"\]:::pushClass 10v1["(10v1) handoff"]:::otherClass 11v1["(11v1) handoff"]:::otherClass 1v1-->2v1 diff --git a/hydroflow_plus_test_local/src/local/teed_join.rs b/hydroflow_plus_test_local/src/local/teed_join.rs index 951ad9608874..979a5a149945 100644 --- a/hydroflow_plus_test_local/src/local/teed_join.rs +++ b/hydroflow_plus_test_local/src/local/teed_join.rs @@ -1,9 +1,10 @@ +use hydroflow::futures::stream::Stream; +use hydroflow::tokio::sync::mpsc::UnboundedSender; +use hydroflow::tokio_stream::wrappers::UnboundedReceiverStream; use hydroflow_plus::deploy::MultiGraph; -use hydroflow_plus::futures::stream::Stream; -use hydroflow_plus::tokio::sync::mpsc::UnboundedSender; -use hydroflow_plus::tokio_stream::wrappers::UnboundedReceiverStream; +use hydroflow_plus::hydroflow::scheduled::graph::Hydroflow; use hydroflow_plus::*; -use stageleft::{q, Quoted, RuntimeData}; +use stageleft::{Quoted, RuntimeData}; struct N0 {} struct N1 {} @@ -18,8 +19,15 @@ pub fn teed_join<'a, S: Stream + Unpin + 'a>( ) -> impl Quoted<'a, Hydroflow<'a>> { let node_zero = flow.process::(); let node_one = flow.process::(); - - let source = node_zero.source_stream(input_stream).tick_batch(); + let n0_tick = node_zero.tick(); + + let source = unsafe { + // SAFETY: intentionally using ticks + node_zero + .source_stream(input_stream) + .timestamped(&n0_tick) + .tick_batch() + }; let map1 = source.clone().map(q!(|v| (v + 1, ()))); let map2 = source.map(q!(|v| (v - 1, ()))); @@ -40,21 +48,20 @@ pub fn teed_join<'a, S: Stream + Unpin + 'a>( output.send(v).unwrap(); })); - flow.with_default_optimize() - .compile_no_network::() + flow.compile_no_network::() .with_dynamic_id(subgraph_id) } #[stageleft::runtime] #[cfg(test)] mod tests { - use hydroflow_plus::assert_graphvis_snapshots; - use hydroflow_plus::util::collect_ready; + use hydroflow::assert_graphvis_snapshots; + use hydroflow::util::collect_ready; #[test] fn test_teed_join() { - let (in_send, input) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (in_send, input) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut joined = super::teed_join!(input, &out, false, 0); assert_graphvis_snapshots!(joined); @@ -71,8 +78,8 @@ mod tests { #[test] fn test_teed_join_twice() { - let (in_send, input) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (in_send, input) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut joined = super::teed_join!(input, &out, true, 0); assert_graphvis_snapshots!(joined); @@ -89,8 +96,8 @@ mod tests { #[test] fn test_teed_join_multi_node() { - let (_, input) = hydroflow_plus::util::unbounded_channel(); - let (out, mut out_recv) = hydroflow_plus::util::unbounded_channel(); + let (_, input) = hydroflow::util::unbounded_channel(); + let (out, mut out_recv) = hydroflow::util::unbounded_channel(); let mut joined = super::teed_join!(input, &out, true, 1); assert_graphvis_snapshots!(joined); diff --git a/hydroflow_plus_test_local_macro/Cargo.toml b/hydroflow_plus_test_local_macro/Cargo.toml index 67427cf11a03..57da63e32396 100644 --- a/hydroflow_plus_test_local_macro/Cargo.toml +++ b/hydroflow_plus_test_local_macro/Cargo.toml @@ -12,9 +12,9 @@ proc-macro = true path = "../hydroflow_plus_test_local/src/lib.rs" [dependencies] -hydroflow_plus = { path = "../hydroflow_plus", version = "^0.9.0" } -stageleft = { path = "../stageleft", version = "^0.4.0" } +hydroflow_plus = { path = "../hydroflow_plus", version = "^0.10.0" } +stageleft = { path = "../stageleft", version = "^0.5.0" } rand = "0.8.0" [build-dependencies] -stageleft_tool = { path = "../stageleft_tool", version = "^0.3.0" } +stageleft_tool = { path = "../stageleft_tool", version = "^0.4.0" } diff --git a/lattices/CHANGELOG.md b/lattices/CHANGELOG.md index ceb4043f103a..24698a4b3b12 100644 --- a/lattices/CHANGELOG.md +++ b/lattices/CHANGELOG.md @@ -5,8 +5,58 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.5.8 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - generalized hash trie indexes for relational tuples + Generalized Hash Tries are part of the SIGMOD '23 FreeJoin + [paper](https://dl.acm.org/doi/abs/10.1145/3589295) by + Wang/Willsey/Suciu. They provide a compressed ("factorized") + representation of relations. By operating in the factorized domain, join + algorithms can defer cross-products and achieve asymptotically optimal + performance. + + --------- + +### Style + + - fixes for nightly clippy + a couple few spurious `too_many_arguments` and a spurious + `zombie_processes` still on current nightly (`clippy 0.1.84 (4392847410 + 2024-10-21)`) + +### Commit Statistics + + + + - 3 commits contributed to the release. + - 69 days passed between releases. + - 3 commits were understood as [conventional](https://www.conventionalcommits.org). + - 3 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1503](https://github.com/hydro-project/hydroflow/issues/1503), [#1505](https://github.com/hydro-project/hydroflow/issues/1505) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1503](https://github.com/hydro-project/hydroflow/issues/1503)** + - Generalized hash trie indexes for relational tuples ([`f7e740f`](https://github.com/hydro-project/hydroflow/commit/f7e740fb2ba36d0fcf3fd196d60333552911e3a4)) + * **[#1505](https://github.com/hydro-project/hydroflow/issues/1505)** + - Fixes for nightly clippy ([`47cb703`](https://github.com/hydro-project/hydroflow/commit/47cb703e771f7d1c451ceb9d185ada96410949da)) +
+ ## 0.5.7 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -22,7 +72,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 2 commits contributed to the release. + - 3 commits contributed to the release. + - 38 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1428](https://github.com/hydro-project/hydroflow/issues/1428) @@ -36,6 +87,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) * **[#1428](https://github.com/hydro-project/hydroflow/issues/1428)** - Cleanup doc comments for clippy latest ([`f5f1eb0`](https://github.com/hydro-project/hydroflow/commit/f5f1eb0c612f5c0c1752360d972ef6853c5e12f0)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.5.6 (2024-07-23) @@ -81,6 +134,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 5 commits contributed to the release. + - 59 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1244](https://github.com/hydro-project/hydroflow/issues/1244), [#1250](https://github.com/hydro-project/hydroflow/issues/1250), [#1309](https://github.com/hydro-project/hydroflow/issues/1309), [#1326](https://github.com/hydro-project/hydroflow/issues/1326) @@ -129,6 +183,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 9 commits contributed to the release. + - 48 days passed between releases. - 6 commits were understood as [conventional](https://www.conventionalcommits.org). - 7 unique issues were worked on: [#1155](https://github.com/hydro-project/hydroflow/issues/1155), [#1156](https://github.com/hydro-project/hydroflow/issues/1156), [#1174](https://github.com/hydro-project/hydroflow/issues/1174), [#1181](https://github.com/hydro-project/hydroflow/issues/1181), [#1230](https://github.com/hydro-project/hydroflow/issues/1230), [#1233](https://github.com/hydro-project/hydroflow/issues/1233), [#1236](https://github.com/hydro-project/hydroflow/issues/1236) @@ -157,9 +212,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Definitions of linearity and bilinearity in algebra lib ([`d8e4d9d`](https://github.com/hydro-project/hydroflow/commit/d8e4d9dc784ae28fcefe5f32a0561698c1196d31)) - -set_union: is not a latticemap_union - not safe to expose mapunion_find - K is not a latticeVecUnion - not safe to expose vecWithTop/WithBot - already pubPair - Changed in this commitDomPair - Already correctly done with left pub andright private.Conflict / Point - T is not a lattice type.() - No nested types here. - ## 0.5.4 (2024-04-05) @@ -175,6 +227,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 34 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1127](https://github.com/hydro-project/hydroflow/issues/1127) @@ -214,6 +267,7 @@ Unchanged from previous release. - 5 commits contributed to the release. + - 28 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1061](https://github.com/hydro-project/hydroflow/issues/1061), [#1062](https://github.com/hydro-project/hydroflow/issues/1062), [#1084](https://github.com/hydro-project/hydroflow/issues/1084) @@ -245,6 +299,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 4 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1052](https://github.com/hydro-project/hydroflow/issues/1052) @@ -289,6 +344,7 @@ Unchanged from previous release. - 8 commits contributed to the release. + - 110 days passed between releases. - 6 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1032](https://github.com/hydro-project/hydroflow/issues/1032), [#942](https://github.com/hydro-project/hydroflow/issues/942), [#960](https://github.com/hydro-project/hydroflow/issues/960), [#967](https://github.com/hydro-project/hydroflow/issues/967) @@ -339,6 +395,7 @@ Unchanged from previous release. - 7 commits contributed to the release. + - 56 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#915](https://github.com/hydro-project/hydroflow/issues/915), [#922](https://github.com/hydro-project/hydroflow/issues/922) @@ -407,6 +464,7 @@ Unchanged from previous release. - 10 commits contributed to the release. + - 42 days passed between releases. - 9 commits were understood as [conventional](https://www.conventionalcommits.org). - 8 unique issues were worked on: [#822](https://github.com/hydro-project/hydroflow/issues/822), [#849](https://github.com/hydro-project/hydroflow/issues/849), [#854](https://github.com/hydro-project/hydroflow/issues/854), [#860](https://github.com/hydro-project/hydroflow/issues/860), [#865](https://github.com/hydro-project/hydroflow/issues/865), [#866](https://github.com/hydro-project/hydroflow/issues/866), [#867](https://github.com/hydro-project/hydroflow/issues/867), [#879](https://github.com/hydro-project/hydroflow/issues/879) @@ -496,6 +554,7 @@ Unchanged from previous release. - 18 commits contributed to the release. + - 33 days passed between releases. - 17 commits were understood as [conventional](https://www.conventionalcommits.org). - 12 unique issues were worked on: [#742](https://github.com/hydro-project/hydroflow/issues/742), [#744](https://github.com/hydro-project/hydroflow/issues/744), [#761](https://github.com/hydro-project/hydroflow/issues/761), [#763](https://github.com/hydro-project/hydroflow/issues/763), [#765](https://github.com/hydro-project/hydroflow/issues/765), [#766](https://github.com/hydro-project/hydroflow/issues/766), [#767](https://github.com/hydro-project/hydroflow/issues/767), [#772](https://github.com/hydro-project/hydroflow/issues/772), [#773](https://github.com/hydro-project/hydroflow/issues/773), [#780](https://github.com/hydro-project/hydroflow/issues/780), [#789](https://github.com/hydro-project/hydroflow/issues/789), [#793](https://github.com/hydro-project/hydroflow/issues/793) @@ -556,6 +615,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 1 day passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -582,6 +642,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 6 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#691](https://github.com/hydro-project/hydroflow/issues/691) @@ -615,6 +676,7 @@ Unchanged from previous release. - 5 commits contributed to the release. + - 2 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#671](https://github.com/hydro-project/hydroflow/issues/671), [#674](https://github.com/hydro-project/hydroflow/issues/674), [#687](https://github.com/hydro-project/hydroflow/issues/687) @@ -662,6 +724,7 @@ Unchanged from previous release. - 14 commits contributed to the release. + - 18 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 10 unique issues were worked on: [#625](https://github.com/hydro-project/hydroflow/issues/625), [#637](https://github.com/hydro-project/hydroflow/issues/637), [#638](https://github.com/hydro-project/hydroflow/issues/638), [#642](https://github.com/hydro-project/hydroflow/issues/642), [#644](https://github.com/hydro-project/hydroflow/issues/644), [#645](https://github.com/hydro-project/hydroflow/issues/645), [#658](https://github.com/hydro-project/hydroflow/issues/658), [#660](https://github.com/hydro-project/hydroflow/issues/660), [#664](https://github.com/hydro-project/hydroflow/issues/664), [#667](https://github.com/hydro-project/hydroflow/issues/667) diff --git a/lattices/Cargo.toml b/lattices/Cargo.toml index b4daacad7ee7..844d53d311c3 100644 --- a/lattices/Cargo.toml +++ b/lattices/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "lattices" publish = true -version = "0.5.7" +version = "0.5.8" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/lattices/" @@ -18,7 +18,10 @@ serde = ["dep:serde"] cc-traits = "2.0.0" sealed = "0.5.0" serde = { version = "1.0.197", features = ["derive"], optional = true } -lattices_macro = { path = "../lattices_macro", version = "^0.5.6" } +lattices_macro = { path = "../lattices_macro", version = "^0.5.7" } +ref-cast = "1.0.23" +variadics = { path = "../variadics", version = "^0.0.7" } +variadics_macro = { path = "../variadics_macro", version = "^0.5.5" } [dev-dependencies] trybuild = "1.0.0" diff --git a/lattices/src/collections.rs b/lattices/src/collections.rs index 13494e6fe915..42bc8ec24cf8 100644 --- a/lattices/src/collections.rs +++ b/lattices/src/collections.rs @@ -84,7 +84,8 @@ impl Len for VecSet { } } impl CollectionRef for VecSet { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -103,7 +104,8 @@ where } } impl CollectionMut for VecSet { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -119,7 +121,8 @@ where } } impl Iter for VecSet { - type Iter<'a> = std::slice::Iter<'a, T> + type Iter<'a> + = std::slice::Iter<'a, T> where Self: 'a; @@ -128,7 +131,8 @@ impl Iter for VecSet { } } impl IterMut for VecSet { - type IterMut<'a> = std::slice::IterMut<'a, T> + type IterMut<'a> + = std::slice::IterMut<'a, T> where Self: 'a; @@ -176,7 +180,8 @@ impl Len for VecMap { } } impl CollectionRef for VecMap { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -198,7 +203,8 @@ where } } impl CollectionMut for VecMap { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -220,7 +226,8 @@ impl Keyed for VecMap { type Key = K; } impl KeyedRef for VecMap { - type KeyRef<'a> = &'a Self::Key + type KeyRef<'a> + = &'a Self::Key where Self: 'a; @@ -254,18 +261,20 @@ impl SimpleKeyedRef for VecMap { simple_keyed_ref!(); } impl MapIter for VecMap { - type Iter<'a> = std::iter::Zip, std::slice::Iter<'a, V>> - where - Self: 'a; + type Iter<'a> + = std::iter::Zip, std::slice::Iter<'a, V>> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.keys.iter().zip(self.vals.iter()) } } impl MapIterMut for VecMap { - type IterMut<'a> = std::iter::Zip, std::slice::IterMut<'a, V>> - where - Self: 'a; + type IterMut<'a> + = std::iter::Zip, std::slice::IterMut<'a, V>> + where + Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_> { self.keys.iter().zip(self.vals.iter_mut()) @@ -307,7 +316,10 @@ impl Collection for EmptySet { } impl CollectionRef for EmptySet { - type ItemRef<'a> = &'a Self::Item where Self::Item: 'a; + type ItemRef<'a> + = &'a Self::Item + where + Self::Item: 'a; covariant_item_ref!(); } @@ -328,7 +340,10 @@ impl Len for EmptySet { } impl Iter for EmptySet { - type Iter<'a> = std::iter::Empty<&'a T> where T: 'a; + type Iter<'a> + = std::iter::Empty<&'a T> + where + T: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::empty() @@ -371,7 +386,8 @@ impl Len for SingletonSet { } } impl CollectionRef for SingletonSet { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -390,7 +406,8 @@ where } } impl CollectionMut for SingletonSet { - type ItemMut<'a> = &'a mut T + type ItemMut<'a> + = &'a mut T where Self: 'a; @@ -406,16 +423,18 @@ where } } impl Iter for SingletonSet { - type Iter<'a> = std::iter::Once<&'a T> - where - Self: 'a; + type Iter<'a> + = std::iter::Once<&'a T> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::once(&self.0) } } impl IterMut for SingletonSet { - type IterMut<'a> = std::iter::Once<&'a mut T> + type IterMut<'a> + = std::iter::Once<&'a mut T> where Self: 'a; @@ -457,7 +476,8 @@ impl Len for EmptyMap { } } impl CollectionRef for EmptyMap { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -476,7 +496,8 @@ where } } impl CollectionMut for EmptyMap { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -495,9 +516,10 @@ impl Keyed for EmptyMap { type Key = K; } impl KeyedRef for EmptyMap { - type KeyRef<'a> = &'a Self::Key - where - Self: 'a; + type KeyRef<'a> + = &'a Self::Key + where + Self: 'a; covariant_key_ref!(); } @@ -520,9 +542,10 @@ where } } impl Iter for EmptyMap { - type Iter<'a> = std::iter::Empty<&'a V> - where - Self: 'a; + type Iter<'a> + = std::iter::Empty<&'a V> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::empty() @@ -532,18 +555,20 @@ impl SimpleKeyedRef for EmptyMap { simple_keyed_ref!(); } impl MapIter for EmptyMap { - type Iter<'a> = std::iter::Empty<(&'a K, &'a V)> - where - Self: 'a; + type Iter<'a> + = std::iter::Empty<(&'a K, &'a V)> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::empty() } } impl MapIterMut for EmptyMap { - type IterMut<'a> = std::iter::Empty<(&'a K, &'a mut V)> - where - Self: 'a; + type IterMut<'a> + = std::iter::Empty<(&'a K, &'a mut V)> + where + Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_> { std::iter::empty() @@ -576,7 +601,8 @@ impl Len for SingletonMap { } } impl CollectionRef for SingletonMap { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -595,7 +621,8 @@ where } } impl CollectionMut for SingletonMap { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -614,9 +641,10 @@ impl Keyed for SingletonMap { type Key = K; } impl KeyedRef for SingletonMap { - type KeyRef<'a> = &'a Self::Key - where - Self: 'a; + type KeyRef<'a> + = &'a Self::Key + where + Self: 'a; covariant_key_ref!(); } @@ -639,9 +667,10 @@ where } } impl Iter for SingletonMap { - type Iter<'a> = std::iter::Once<&'a V> - where - Self: 'a; + type Iter<'a> + = std::iter::Once<&'a V> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::once(&self.1) @@ -651,18 +680,20 @@ impl SimpleKeyedRef for SingletonMap { simple_keyed_ref!(); } impl MapIter for SingletonMap { - type Iter<'a> = std::iter::Once<(&'a K, &'a V)> - where - Self: 'a; + type Iter<'a> + = std::iter::Once<(&'a K, &'a V)> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { std::iter::once((&self.0, &self.1)) } } impl MapIterMut for SingletonMap { - type IterMut<'a> = std::iter::Once<(&'a K, &'a mut V)> - where - Self: 'a; + type IterMut<'a> + = std::iter::Once<(&'a K, &'a mut V)> + where + Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_> { std::iter::once((&self.0, &mut self.1)) @@ -716,7 +747,8 @@ impl Len for OptionSet { } } impl CollectionRef for OptionSet { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -735,7 +767,8 @@ where } } impl CollectionMut for OptionSet { - type ItemMut<'a> = &'a mut T + type ItemMut<'a> + = &'a mut T where Self: 'a; @@ -751,16 +784,18 @@ where } } impl Iter for OptionSet { - type Iter<'a> = std::option::Iter<'a, T> - where - Self: 'a; + type Iter<'a> + = std::option::Iter<'a, T> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.0.iter() } } impl IterMut for OptionSet { - type IterMut<'a> = std::option::IterMut<'a, T> + type IterMut<'a> + = std::option::IterMut<'a, T> where Self: 'a; @@ -803,7 +838,8 @@ impl Len for OptionMap { } } impl CollectionRef for OptionMap { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -825,7 +861,8 @@ where } } impl CollectionMut for OptionMap { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -847,9 +884,10 @@ impl Keyed for OptionMap { type Key = K; } impl KeyedRef for OptionMap { - type KeyRef<'a> = &'a Self::Key - where - Self: 'a; + type KeyRef<'a> + = &'a Self::Key + where + Self: 'a; covariant_key_ref!(); } @@ -878,9 +916,10 @@ where } } impl Iter for OptionMap { - type Iter<'a> = std::option::IntoIter<&'a V> - where - Self: 'a; + type Iter<'a> + = std::option::IntoIter<&'a V> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.0.as_ref().map(|(_k, v)| v).into_iter() @@ -890,18 +929,20 @@ impl SimpleKeyedRef for OptionMap { simple_keyed_ref!(); } impl MapIter for OptionMap { - type Iter<'a> = std::option::IntoIter<(&'a K, &'a V)> - where - Self: 'a; + type Iter<'a> + = std::option::IntoIter<(&'a K, &'a V)> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.0.as_ref().map(|(k, v)| (k, v)).into_iter() } } impl MapIterMut for OptionMap { - type IterMut<'a> = std::option::IntoIter<(&'a K, &'a mut V)> - where - Self: 'a; + type IterMut<'a> + = std::option::IntoIter<(&'a K, &'a mut V)> + where + Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_> { self.0.as_mut().map(|(k, v)| (&*k, v)).into_iter() @@ -945,7 +986,8 @@ impl Len for ArraySet { } } impl CollectionRef for ArraySet { - type ItemRef<'a> = &'a T + type ItemRef<'a> + = &'a T where Self: 'a; @@ -967,7 +1009,8 @@ where } } impl CollectionMut for ArraySet { - type ItemMut<'a> = &'a mut T + type ItemMut<'a> + = &'a mut T where Self: 'a; @@ -986,9 +1029,10 @@ where } } impl Iter for ArraySet { - type Iter<'a> = std::slice::Iter<'a, T> - where - Self: 'a; + type Iter<'a> + = std::slice::Iter<'a, T> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.0.iter() @@ -1035,7 +1079,8 @@ impl Len for ArrayMap { } } impl CollectionRef for ArrayMap { - type ItemRef<'a> = &'a Self::Item + type ItemRef<'a> + = &'a Self::Item where Self: 'a; @@ -1057,7 +1102,8 @@ where } } impl CollectionMut for ArrayMap { - type ItemMut<'a> = &'a mut Self::Item + type ItemMut<'a> + = &'a mut Self::Item where Self: 'a; @@ -1079,9 +1125,10 @@ impl Keyed for ArrayMap { type Key = K; } impl KeyedRef for ArrayMap { - type KeyRef<'a> = &'a Self::Key - where - Self: 'a; + type KeyRef<'a> + = &'a Self::Key + where + Self: 'a; covariant_key_ref!(); } @@ -1110,9 +1157,10 @@ where } } impl Iter for ArrayMap { - type Iter<'a> = std::slice::Iter<'a, V> - where - Self: 'a; + type Iter<'a> + = std::slice::Iter<'a, V> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.vals.iter() @@ -1122,18 +1170,20 @@ impl SimpleKeyedRef for ArrayMap { simple_keyed_ref!(); } impl MapIter for ArrayMap { - type Iter<'a> = std::iter::Zip, std::slice::Iter<'a, V>> - where - Self: 'a; + type Iter<'a> + = std::iter::Zip, std::slice::Iter<'a, V>> + where + Self: 'a; fn iter(&self) -> Self::Iter<'_> { self.keys.iter().zip(self.vals.iter()) } } impl MapIterMut for ArrayMap { - type IterMut<'a> = std::iter::Zip, std::slice::IterMut<'a, V>> - where - Self: 'a; + type IterMut<'a> + = std::iter::Zip, std::slice::IterMut<'a, V>> + where + Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_> { self.keys.iter().zip(self.vals.iter_mut()) diff --git a/lattices/src/ght/colt.rs b/lattices/src/ght/colt.rs new file mode 100644 index 000000000000..b4b22239cd81 --- /dev/null +++ b/lattices/src/ght/colt.rs @@ -0,0 +1,306 @@ +//! COLT from Wang/Willsey/Suciu + +use std::hash::Hash; + +use variadics::variadic_collections::VariadicCollection; +use variadics::{var_expr, var_type, PartialEqVariadic, SplitBySuffix, VariadicExt}; + +use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf}; + +/// Data structure design for our COLT is unique. +/// +/// In the paper, the COLT is an unbalanced trie that "grows upward" from leaves lazily +/// on access via the `force` method. +/// Unfortunately, unbalanced tries break our types: a node's type to be defined via the +/// type of its children, recursively -- meaning all paths need to be the same type (and length)! +/// +/// To work around this, our COLT is a variadic *list* GHTs (a forest) of increasing height, +/// starting with a trie of height 0 and continuing until a trie of height |key| - 1. +/// Our `force` method does not add a node above a leaf L as in the paper. Instead +/// it `take`s L from the current trie and merges it into the next trie to the right which is 1 taller. +// +/// The following trait provides the behavior we need from the nodes in a COLT forest. Every +/// `ColtForestNode` is a `GeneralizedHashTrieNode` with some extra methods. +pub trait ColtForestNode: GeneralizedHashTrieNode { + /// result of `force`ing a node + type Force: GeneralizedHashTrieNode; + + /// Force the generation of a parent node, as in the Wang/Willsey/Suciu COLT structure, + /// to be merged into the next trie to the right. + fn force(self) -> Option; + + /// Force the generation of a parent node but retain ref to this node + fn force_drain(&mut self) -> Option; +} + +// Force only acts on leaves +impl ColtForestNode for GhtInner +where + Head: 'static + Hash + Eq + Clone, + Node: 'static + ColtForestNode, + ::Schema: + SplitBySuffix::SuffixSchema)>, +{ + type Force = Node; // where Node:GeneralizedHashTrieNode; + fn force(self) -> Option { + None + } + + fn force_drain(&mut self) -> Option { + None + } +} + +// Leaf case +impl ColtForestNode + for GhtLeaf +where + Head: 'static + Clone + Hash + Eq, + Rest: 'static + Clone + Hash + Eq + VariadicExt, + Schema: 'static + Hash + Eq + Clone + VariadicExt + PartialEqVariadic, + Rest: PartialEqVariadic, + Schema: SplitBySuffix, + Schema: SplitBySuffix, + >::Prefix: Eq + Hash + Clone, + >::Prefix: Eq + Hash + Clone, + Storage: VariadicCollection + Default + IntoIterator, + GhtLeaf: GeneralizedHashTrieNode, + GhtInner>: + GeneralizedHashTrieNode, +{ + type Force = GhtInner>; + fn force(mut self) -> Option { + let mut retval = Self::Force::default(); + self.forced = true; + for row in self.into_iter().unwrap() { + retval.insert(row); + } + Some(retval) + } + + fn force_drain(&mut self) -> Option>> { + let mut retval = Self::Force::default(); + self.forced = true; + for row in self.elements.drain() { + retval.insert(row); + } + Some(retval) + } +} + +/// Emulate the `get` and iter` functions for a single Ght node +/// [`GhtGet`] across a forest of ColtForestNodes. +/// +/// The "current" ColtGet node (corresponding to the "current" GhtGet node) at depth +/// d from the root is a variadic list of nodes, each at depth d in its their +/// respective trie in the forest, Tries of height d or smaller are omitted, +/// hence the first element in any ColtGet is a GhtLeaf. +pub trait ColtGet { + /// Schema variadic: the schema of the relation stored in this COLT. + /// This type is the same in all Tries and nodes of the COLT. + type Schema: VariadicExt + Eq + Hash + Clone; + /// The type of Storage + /// This type is the same in all Tries and nodes of the COLT + type Storage: VariadicCollection; + /// SuffixSchema variadic: the suffix of the schema *from this node of the trie + /// downward*. The first entry in this variadic is of type Head. + /// This type is the same in all Tries of the COLT (but changes as we traverse downward) + type SuffixSchema: VariadicExt + Eq + Hash + Clone; + /// The type of the first column in the SuffixSchema + /// This type is the same in all Tries of the COLT (but changes as we traverse downward) + type Head: Eq + Hash; + + /// Type returned by [`Self::get`]. + type Get; + + /// Following the spec in Wang/Willsey/Suciu, on an Inner node this retrieves the value + /// (child) associated with the given "head" key. It returns an `Option` containing a + /// reference to the value if found, or `None` if not found. + /// On a Leaf node, returns None. + fn get(self, head: &Self::Head) -> Self::Get; + + /// Iterator for the "head" keys (from inner nodes) or nothing (from leaf nodes). + fn iter(&self) -> impl Iterator; +} + +/// `ColtGet` without the first (head) trie. +pub trait ColtGetTail: ColtGet { + /// merge an inner node into the head of this tail of the forest + fn merge(&mut self, inner_to_merge: InnerToMerge); +} + +impl<'a, Rest, Schema, SuffixSchema, Storage> ColtGet for var_type!(&'a mut GhtLeaf, ...Rest) +where + Rest: ColtGetTail< + as ColtForestNode>::Force, + Storage = Storage, + >, + ::SuffixSchema: 'a, + GhtLeaf: ColtForestNode, + Schema: Clone + Hash + Eq + VariadicExt, + SuffixSchema: Clone + Hash + Eq + VariadicExt, + Storage: VariadicCollection, +{ + type Schema = Schema; + type Head = Rest::Head; + type SuffixSchema = SuffixSchema; + type Get = Rest::Get; + type Storage = Rest::Storage; + + fn get(self, head: &Self::Head) -> Self::Get { + let (first, mut rest) = self; + let forced = first.force_drain().unwrap(); + ColtGetTail::merge(&mut rest, forced); + Rest::get(rest, head) + } + + fn iter(&self) -> impl Iterator { + std::iter::empty() + } +} + +// we only merge in GhtInner> nodes, so this +// should never be called. +impl<'a, Rest, Schema, SuffixSchema, T, Storage> ColtGetTail for var_type!(&'a mut GhtLeaf, ...Rest) +where + Rest: ColtGetTail< + as ColtForestNode>::Force, + Storage = Storage, + >, + ::SuffixSchema: 'a, + GhtLeaf: ColtForestNode, + Schema: Clone + Hash + Eq + VariadicExt, + SuffixSchema: Clone + Hash + Eq + VariadicExt, + Storage: VariadicCollection, +{ + fn merge(&mut self, _inner_to_merge: T) { + panic!(); + } +} + +impl<'a, Head, Head2, Rest, Node> ColtGet for var_type!(&'a mut GhtInner>, ...Rest) +where + Rest: ColtGet, + Head: Eq + Hash + Clone, + Head2: Eq + Hash + Clone, + Node: GeneralizedHashTrieNode, + GhtInner>: GeneralizedHashTrieNode< + Head = Rest::Head, + SuffixSchema = Rest::SuffixSchema, + Schema = Rest::Schema, + Storage = Rest::Storage, + >, + GhtInner: GeneralizedHashTrieNode, +{ + type Schema = Rest::Schema; + type Head = Rest::Head; + type SuffixSchema = Rest::SuffixSchema; + type Get = var_type!(&'a mut GhtInner, ...Rest::Get); + type Storage = Rest::Storage; + + fn get(self, head: &Self::Head) -> Self::Get { + let (first, rest) = self; + // create a child entry here for this get, to absorb future forces + // TODO(mingwei): extra clone here if entry already exists. + let child = first.children.entry(head.clone()).or_default(); + var_expr!(child, ...Rest::get(rest, head)) + } + + fn iter(&self) -> impl Iterator { + self.0.children.keys().cloned().chain(Rest::iter(&self.1)) + } +} + +impl<'a, Head, Rest, Schema, ValType, Storage> ColtGet for var_type!(&'a mut GhtInner>, ...Rest) +where + Rest: ColtGet, + Head: Eq + Hash + Clone, + Schema: Eq + Hash + Clone + PartialEqVariadic, + ValType: Eq + Hash + Clone + PartialEqVariadic, + Storage: VariadicCollection, + GhtLeaf: GeneralizedHashTrieNode, + Schema: 'static + Eq + VariadicExt + Hash + Clone + SplitBySuffix + PartialEqVariadic, + >::Prefix: Eq + Hash + Clone, + GhtInner>: + GeneralizedHashTrieNode + GhtGet, + GhtInner>: + GeneralizedHashTrieNode, + GhtLeaf: + GeneralizedHashTrieNode + GhtGet, +{ + type Schema = Rest::Schema; + type Head = Rest::Head; + type SuffixSchema = Rest::SuffixSchema; + type Get = var_type!(&'a mut GhtLeaf, ...Rest::Get); + type Storage = Rest::Storage; + + fn get(self, head: &Self::Head) -> Self::Get { + let (first, rest) = self; + let child = first.children.entry(head.clone()).or_default(); + var_expr!(child, ...Rest::get(rest, head)) + } + + fn iter(&self) -> impl Iterator { + self.0.children.keys().cloned().chain(Rest::iter(&self.1)) + } +} + +impl<'a, Head, Rest, Schema, ValType, Storage> + ColtGetTail>> for var_type!(&'a mut GhtInner>, ...Rest) +where + Rest: ColtGet, + Head: Eq + Hash + Clone, + Schema: Eq + Hash + Clone + PartialEqVariadic, + ValType: Eq + Hash + Clone + PartialEqVariadic, + Storage: VariadicCollection, + var_type!(&'a mut GhtInner>, ...Rest): + ColtGet, + GhtLeaf: GeneralizedHashTrieNode, + Schema: 'static + Eq + VariadicExt + Hash + Clone + SplitBySuffix + PartialEqVariadic, + >::Prefix: Eq + Hash + Clone, + GhtInner>: + GeneralizedHashTrieNode + GhtGet, +{ + fn merge(&mut self, inner_to_merge: GhtInner>) { + let (head, _rest) = self; + // can't use Merge with COLT bc columnstore is not a lattice!! + head.merge_node(inner_to_merge); + } +} + +impl<'a, Head, Node> ColtGet for var_type!(&'a mut GhtInner) +where + GhtInner: GeneralizedHashTrieNode, + Head: Clone + Eq + Hash, + Node: GeneralizedHashTrieNode, +{ + type Schema = as GeneralizedHashTrieNode>::Schema; + type SuffixSchema = as GeneralizedHashTrieNode>::SuffixSchema; + type Head = Head; + type Get = var_type!(&'a mut Node); + type Storage = Node::Storage; + + fn get(self, head: &Self::Head) -> Self::Get { + let child = self.0.children.entry(head.clone()).or_default(); + var_expr!(child) + } + + fn iter(&self) -> impl Iterator { + self.0.children.keys().cloned() + } +} +impl ColtGetTail>> for var_type!(&mut GhtInner>) +where + GhtInner>: + GeneralizedHashTrieNode + GhtGet, + GhtLeaf: GeneralizedHashTrieNode, + Head: Clone + Eq + Hash, + Schema: Clone + Eq + Hash + VariadicExt, + Storage: VariadicCollection, +{ + fn merge(&mut self, inner_to_merge: GhtInner>) { + let (head, _rest) = self; + // can't use Merge with COLT bc columnstore is not a lattice!! + head.merge_node(inner_to_merge); + } +} diff --git a/lattices/src/ght/lattice.rs b/lattices/src/ght/lattice.rs new file mode 100644 index 000000000000..11b8a6aabdec --- /dev/null +++ b/lattices/src/ght/lattice.rs @@ -0,0 +1,439 @@ +//! Lattice traits for GHT + +use core::cmp::Ordering::{Equal, Greater, Less}; +use std::cmp::Ordering; +use std::collections::HashMap; +use std::hash::Hash; + +use variadics::variadic_collections::VariadicSet; +use variadics::{var_expr, var_type, CloneVariadic, PartialEqVariadic, SplitBySuffix, VariadicExt}; + +use crate::ght::{GeneralizedHashTrieNode, GhtGet, GhtInner, GhtLeaf}; +use crate::{IsBot, IsTop, LatticeBimorphism, LatticeOrd, Merge}; + +impl Merge> for GhtInner +where + Node: GeneralizedHashTrieNode + Merge, + Node::Storage: VariadicSet, // multiset is not a lattice! + Self: GeneralizedHashTrieNode, + Head: Hash + Eq + Clone, +{ + fn merge(&mut self, other: GhtInner) -> bool { + let mut changed = false; + + for (k, v) in other.children { + match self.children.entry(k) { + std::collections::hash_map::Entry::Occupied(mut occupied) => { + changed |= occupied.get_mut().merge_node(v); + } + std::collections::hash_map::Entry::Vacant(vacant) => { + vacant.insert(v); + changed = true; + } + } + } + changed + } +} + +impl Merge> + for GhtLeaf +where + Schema: Eq + Hash, + Storage: VariadicSet + Extend + IntoIterator, +{ + fn merge(&mut self, other: GhtLeaf) -> bool { + let old_len = self.elements.len(); + self.elements.extend(other.elements); + self.elements.len() > old_len + } +} + +impl PartialEq> for GhtInner +where + Head: Hash + Eq + 'static + Clone, + Node: GeneralizedHashTrieNode + 'static + PartialEq, + Node::Storage: VariadicSet, // multiset is not a lattice! + Node::Schema: SplitBySuffix, + GhtInner: GhtGet, + as GhtGet>::Get: PartialEq, +{ + fn eq(&self, other: &GhtInner) -> bool { + if self.children.len() != other.children.len() { + return false; + } + + for head in self.iter() { + let other_node = other.get(&head); + if other_node.is_none() { + return false; + } + let this_node = self.get(&head); + if this_node.is_none() { + return false; + } + if this_node.unwrap() != other_node.unwrap() { + return false; + } + } + true + } +} + +impl PartialOrd> for GhtInner +where + Head: Hash + Eq + 'static + Clone, + Node: 'static + GeneralizedHashTrieNode + PartialEq + PartialOrd, + Node::Storage: VariadicSet, // multiset is not a lattice! + Node::Schema: SplitBySuffix, +{ + fn partial_cmp(&self, other: &GhtInner) -> Option { + let mut self_any_greater = false; + let mut other_any_greater = false; + if self.children.is_empty() && other.children.is_empty() { + Some(Equal) + } else { + for k in self.children.keys().chain(other.children.keys()) { + match (self.children.get(k), other.children.get(k)) { + (Some(self_value), Some(other_value)) => { + match self_value.partial_cmp(other_value)? { + Greater => { + self_any_greater = true; + } + Less => { + other_any_greater = true; + } + Equal => {} + } + } + (Some(_), None) => { + self_any_greater = true; + } + (None, Some(_)) => { + other_any_greater = true; + } + (None, None) => unreachable!(), + } + } + match (self_any_greater, other_any_greater) { + (true, false) => Some(Greater), + (false, true) => Some(Less), + (false, false) => Some(Equal), + (true, true) => unreachable!(), + } + } + } +} + +impl PartialOrd> + for GhtLeaf +where + Schema: Eq + Hash + PartialEqVariadic, + SuffixSchema: Eq + Hash, + Storage: VariadicSet + PartialEq, +{ + fn partial_cmp(&self, other: &GhtLeaf) -> Option { + match self.elements.len().cmp(&other.elements.len()) { + Greater => { + if other.elements.iter().all(|tup| self.elements.contains(tup)) { + Some(Greater) + } else { + None + } + } + Equal => { + if self + .elements + .iter() + .all(|head| other.elements.contains(head)) + { + Some(Equal) + } else { + None + } + } + Less => { + if self + .elements + .iter() + .all(|head| other.elements.contains(head)) + { + Some(Less) + } else { + None + } + } + } + } +} + +impl LatticeOrd> for GhtInner +where + Self: PartialOrd>, + Head: Clone, + Node: GeneralizedHashTrieNode, + Node::Storage: VariadicSet, // multiset is not a lattice! +{ +} +impl LatticeOrd> + for GhtLeaf +where + Schema: Eq + Hash + PartialEqVariadic, + SuffixSchema: Eq + Hash, + Storage: VariadicSet + PartialEq, +{ +} + +impl IsBot for GhtInner +where + Head: Clone, + Node: GeneralizedHashTrieNode + IsBot, +{ + fn is_bot(&self) -> bool { + self.children.iter().all(|(_, v)| v.is_bot()) + } +} + +impl IsBot for GhtLeaf +where + Schema: Eq + Hash, + SuffixSchema: Eq + Hash, + Storage: VariadicSet, +{ + fn is_bot(&self) -> bool { + self.elements.is_empty() + } +} + +impl IsTop for GhtInner +where + Head: Clone, + Node: GeneralizedHashTrieNode, + Node::Storage: VariadicSet, // multiset is not a lattice! +{ + fn is_top(&self) -> bool { + false + } +} + +impl IsTop for GhtLeaf +where + Schema: Eq + Hash, + SuffixSchema: Eq + Hash, + Storage: VariadicSet, +{ + fn is_top(&self) -> bool { + false + } +} + +////////////////////////// +// BiMorphisms for GHT +// + +/// Bimorphism for the cartesian product of two GHT *subtries*. +/// +/// Output is a set of all possible pairs of +/// *suffixes* from the two subtries. If you use this at the root of a GHT, it's a full cross-product. +/// If you use this at an internal node, it provides a 'factorized' representation with only the suffix +/// cross-products expanded. +pub struct GhtCartesianProductBimorphism { + _phantom: std::marker::PhantomData GhtOut>, +} +impl Default for GhtCartesianProductBimorphism { + fn default() -> Self { + Self { + _phantom: Default::default(), + } + } +} +impl<'a, 'b, GhtA, GhtB, GhtOut> LatticeBimorphism<&'a GhtA, &'b GhtB> + for GhtCartesianProductBimorphism +where + GhtA: GeneralizedHashTrieNode, + GhtA::Storage: VariadicSet, // multiset is not a lattice! + GhtB: GeneralizedHashTrieNode, + GhtB::Storage: VariadicSet, // multiset is not a lattice! + GhtOut: FromIterator, + GhtA::SuffixSchema: CloneVariadic, + GhtB::SuffixSchema: CloneVariadic, +{ + type Output = GhtOut; + + fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output { + ght_a.recursive_iter().flat_map(|a| { + let (_a_prefix, a_suffix) = >::split_by_suffix_ref(a); + ght_b + .recursive_iter() + .map(move |b| { + let (_b_prefix, b_suffix) = >::split_by_suffix_ref(b); + var_expr!(...::clone_ref_var(a_suffix), ...::clone_ref_var(b_suffix)) + }) + }).collect() + } +} + +/// Forms the cartesian product of the ValTypes only +/// Used on GhtLeaf nodes to implement DeepJoinLatticeBimorphism +pub struct GhtValTypeProductBimorphism { + _phantom: std::marker::PhantomData GhtOut>, +} +impl Default for GhtValTypeProductBimorphism { + fn default() -> Self { + Self { + _phantom: Default::default(), + } + } +} +impl<'a, 'b, GhtA, GhtB, GhtOut> LatticeBimorphism<&'a GhtA, &'b GhtB> + for GhtValTypeProductBimorphism +where + GhtA: GeneralizedHashTrieNode, + GhtA::Storage: VariadicSet, // multiset is not a lattice! + GhtB: GeneralizedHashTrieNode, + GhtB::Storage: VariadicSet, // multiset is not a lattice! + GhtOut: FromIterator, + GhtA::Schema: Eq + Hash + CloneVariadic, + GhtB::Schema: Eq + Hash + SplitBySuffix, + GhtB::ValType: CloneVariadic, +{ + type Output = GhtOut; + + fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output { + ght_a.recursive_iter().flat_map(|a| { + ght_b + .recursive_iter() + .map(move |b| { + let (_prefix_b, suffix_b) + = >::split_by_suffix_ref(b); + var_expr!(...::clone_ref_var(a), ...::clone_ref_var(suffix_b)) + } + ) + }).collect() + } +} + +/// Composable bimorphism, wraps an existing morphism by partitioning it per key. +/// +/// For example, `GhtKeyedBimorphism<..., GhtCartesianProduct<...>>` is a join. +#[derive(Default)] +pub struct GhtBimorphism { + bimorphism: Bimorphism, + // _phantom: std::marker::PhantomData MapOut>, +} +impl GhtBimorphism { + /// Create a `KeyedBimorphism` using `bimorphism` for handling values. + pub fn new(bimorphism: Bimorphism) -> Self { + Self { + bimorphism, + // _phantom: std::marker::PhantomData, + } + } +} + +impl LatticeBimorphism for GhtBimorphism +where + GhtA: GeneralizedHashTrieNode, + GhtA::Storage: VariadicSet, // multiset is not a lattice! + GhtB: GeneralizedHashTrieNode, + GhtB::Storage: VariadicSet, // multiset is not a lattice! + GhtOut: GeneralizedHashTrieNode, // FromIterator, + for<'a, 'b> ValFunc: LatticeBimorphism<&'a GhtA, &'b GhtB, Output = GhtOut>, +{ + type Output = GhtOut; + + fn call(&mut self, ght_a: GhtA, ght_b: GhtB) -> Self::Output { + let node_bim = &mut self.bimorphism; // GhtNodeKeyedBimorphism::::new(self.bimorphism); + node_bim.call(&ght_a, &ght_b) + } +} + +#[derive(Default)] +/// bimorphism trait for equijoining Ght Nodes +pub struct GhtNodeKeyedBimorphism { + bimorphism: Bimorphism, +} +/// bimorphism implementation for equijoining Ght Nodes +impl GhtNodeKeyedBimorphism { + /// initialize bimorphism + pub fn new(bimorphism: Bimorphism) -> Self { + Self { bimorphism } + } +} +/// bimorphism implementation for equijoining Ght Nodes +impl<'a, 'b, Head, GhtA, GhtB, ValFunc> LatticeBimorphism<&'a GhtA, &'b GhtB> + for GhtNodeKeyedBimorphism +where + Head: Clone + Hash + Eq, + ValFunc: LatticeBimorphism<&'a GhtA::Get, &'b GhtB::Get>, + ValFunc::Output: GeneralizedHashTrieNode, + GhtA: GeneralizedHashTrieNode + GhtGet, + GhtB: GeneralizedHashTrieNode + GhtGet, + GhtA::Storage: VariadicSet, // multiset is not a lattice! + GhtB::Storage: VariadicSet, // multiset is not a lattice! + ::AsRefVar<'a>: CloneVariadic, + ::AsRefVar<'b>: CloneVariadic, +{ + type Output = GhtInner; // HashMap; // GhtOut; + + fn call(&mut self, ght_a: &'a GhtA, ght_b: &'b GhtB) -> Self::Output { + let mut children = HashMap::::new(); + // for head in ght_b.iter_keys() { + for head in ght_b.iter() { + if let Some(get_a) = ght_a.get(&head) { + let get_b = ght_b.get(&head).unwrap(); + let val = self.bimorphism.call(get_a, get_b); + children.insert(head.clone(), val); + } + } + GhtInner { children } + } +} + +/// bimorphism trait for equijoin on full tuple (keys in all GhtInner nodes) +pub trait DeepJoinLatticeBimorphism { + /// bimorphism type for equijoin on full tuple (keys in all GhtInner nodes) + type DeepJoinLatticeBimorphism; +} +/// bimorphism implementation for equijoin on full tuple (keys in all GhtInner nodes) +impl DeepJoinLatticeBimorphism + for (GhtInner, GhtInner) +where + Head: 'static + Hash + Eq + Clone, + NodeA: 'static + GeneralizedHashTrieNode, + NodeB: 'static + GeneralizedHashTrieNode, + NodeA::Storage: VariadicSet, // multiset is not a lattice! + NodeB::Storage: VariadicSet, // multiset is not a lattice! + (NodeA, NodeB): DeepJoinLatticeBimorphism, + Storage: VariadicSet, +{ + type DeepJoinLatticeBimorphism = GhtNodeKeyedBimorphism< + <(NodeA, NodeB) as DeepJoinLatticeBimorphism>::DeepJoinLatticeBimorphism, + >; +} +impl + DeepJoinLatticeBimorphism + for ( + GhtLeaf, + GhtLeaf, + ) +where + SchemaA: 'static + VariadicExt + Eq + Hash + SplitBySuffix, /* + AsRefVariadicPartialEq */ + ValTypeA: 'static + VariadicExt + Eq + Hash, // + AsRefVariadicPartialEq + SchemaB: 'static + VariadicExt + Eq + Hash + SplitBySuffix, /* + AsRefVariadicPartialEq */ + ValTypeB: 'static + VariadicExt + Eq + Hash, // + AsRefVariadicPartialEq + StorageA: VariadicSet, + StorageB: VariadicSet, + StorageOut: VariadicSet, + for<'x> SchemaA::AsRefVar<'x>: CloneVariadic, + for<'x> SchemaB::AsRefVar<'x>: CloneVariadic, + var_type!(...SchemaA, ...ValTypeB): Eq + Hash, +{ + type DeepJoinLatticeBimorphism = GhtValTypeProductBimorphism< + GhtLeaf< + var_type!(...SchemaA, ...ValTypeB), + var_type!(...ValTypeA, ...ValTypeB), + StorageOut, + >, + >; +} diff --git a/lattices/src/ght/macros.rs b/lattices/src/ght/macros.rs new file mode 100644 index 000000000000..174f124518ef --- /dev/null +++ b/lattices/src/ght/macros.rs @@ -0,0 +1,117 @@ +//! Macros for GHT +#[macro_export] +/// Internal macro for constructing a Ght struct with the given schema and storage type +/// +/// Should not be used directly, use `GhtType!` instead +macro_rules! GhtTypeWithSchema { + // Empty key & Val (Leaf) + (() => () => $( $schema:ty ),+ : $storage:ident) => ( + $crate::ght::GhtLeaf::<$( $schema ),*, () > + ); + + // Empty key (Leaf) + (() => $( $z:ty ),* => $schema:ty : $storage:ident) => ( + $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::variadics::variadic_collections::$storage<$schema> > + ); + + // Singleton key & Empty val (Inner over Leaf) + ($a:ty => () => $schema:ty : $storage:ident) => ( + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, (), $crate::variadics::variadic_collections::$storage<$schema> >> + ); + + // Singleton key (Inner over Leaf) + ($a:ty => $( $z:ty ),* => $schema:ty : $storage:ident) => ( + $crate::ght::GhtInner::<$a, $crate::ght::GhtLeaf::<$schema, $crate::variadics::var_type!($( $z ),*), $crate::variadics::variadic_collections::$storage<$schema> >> + ); + + // Recursive case with empty val + ($a:ty, $( $b:ty ),* => () => $schema:ty : $storage:ident) => ( + $crate::ght::GhtInner::<$a, $crate::GhtTypeWithSchema!($( $b ),* => () => $schema : $storage)> + ); + + // Recursive case + ($a:ty, $( $b:ty ),* => $( $z:ty ),* => $schema:ty : $storage:ident) => ( + $crate::ght::GhtInner::<$a, $crate::GhtTypeWithSchema!($( $b ),* => $( $z ),* => $schema : $storage)> + ); +} + +#[macro_export] +/// Public macro for constructing a Ght struct with the given schema and storage type +/// +/// # Example +/// ``` +/// use lattices::GhtType; +/// use variadics::variadic_collections::VariadicHashSet; +/// +/// // This generates a Ght struct with (u16, u32) as key, (u64) as val, and VariadicHashSet as storage +/// type MyHashGht = GhtType!(u16, u32 => u64: VariadicHashSet); +/// let my_ght = MyHashGht::default(); +/// +/// /// // This generates a Ght struct with (u16, u32) as key, () as val, and VariadicCountedHashSet as storage +/// type MyMultisetGht = GhtType!(u16, u32 => (): VariadicCountedHashSet); +/// let my_ght = MyMultisetGht::default(); +/// +/// // This generates a Ght struct with (u16, u32) as key, () as val, and VariadicColumnSet as storage +/// type MyColumnarMultisetGht = GhtType!(u16, u32 => (): VariadicColumnMultiset); +/// let my_ght = MyColumnarMultisetGht::default(); +/// ``` +macro_rules! GhtType { + // Empty key + (() => $( $z:ty ),*: $storage:ident) => ( + $crate::GhtTypeWithSchema!(() => $( $z ),* => $crate::variadics::var_type!($( $z ),*): $storage) + ); + + // Recursive case empty val + ($( $b:ty ),* => (): $storage:ident) => ( + $crate::GhtTypeWithSchema!($( $b ),* => () => $crate::variadics::var_type!($( $b ),*): $storage) + ); + + // Recursive case + ($( $b:ty ),* => $( $z:ty ),*: $storage:ident) => ( + $crate::GhtTypeWithSchema!($( $b ),* => $( $z ),* => $crate::variadics::var_type!($( $b ),*, $( $z ),*): $storage) + ); +} + +#[macro_export] +/// Construct a forest of Ghts (i.e. a ColtForest) with the given schema and storage type. +/// +/// # Example +/// ``` +/// use lattices::ColtType; +/// +/// type MyColt = ColtType!(u16, u32, u64); +/// ``` +macro_rules! ColtType { + // Base case: single type to empty + ($a:ty => ()) => { + $crate::variadics::var_type!($crate::GhtType!($a => (): VariadicColumnMultiset)) + }; + // Base case: single type to single type + ($a:ty => $c:ty) => { + ($crate::GhtType!($a => $c: VariadicColumnMultiset), $crate::ColtType!($a, $c => ())) + }; + // Recursive case: single type to multiple types + ($a:ty => $c:ty, $( $d:ty ),*) => { + ($crate::GhtType!($a => $c, $( $d ),*: VariadicColumnMultiset), $crate::ColtType!($a, $c => $( $d ),*)) + }; + // Base case: multiple types to empty + ($a:ty, $( $b:ty ),* => ()) => { + $crate::variadics::var_type!($crate::GhtType!($a, $( $b ),* => (): VariadicColumnMultiset)) + }; + // Base case: multiple types to single type + ($a:ty, $( $b:ty ),* => $c:ty) => { + ($crate::GhtType!($a, $( $b ),* => $c: VariadicColumnMultiset), $crate::ColtType!($a, $( $b ),*, $c => ())) + }; + // Recursive case: multiple types to multiple types + ($a:ty, $( $b:ty ),* => $c:ty, $( $d:ty ),*) => { + ($crate::GhtType!($a, $( $b ),* => $c, $( $d ),*: VariadicColumnMultiset), $crate::ColtType!($a, $( $b ),*, $c => $( $d ),*)) + }; + // General case: single type + ($a:ty) => { + ($crate::GhtType!(() => $a: VariadicColumnMultiset), $crate::ColtType!($a => ())) + }; + // General case: multiple types + ($a:ty, $( $b:ty ),*) => { + ($crate::GhtType!(() => $a, $( $b ),*: VariadicColumnMultiset), $crate::ColtType!($a => $( $b ),*)) + }; +} diff --git a/lattices/src/ght/mod.rs b/lattices/src/ght/mod.rs new file mode 100644 index 000000000000..9496a43cd1e6 --- /dev/null +++ b/lattices/src/ght/mod.rs @@ -0,0 +1,545 @@ +//! GHT from the Wang/Willsey/Suciu Freejoin work +use std::collections::HashMap; +use std::fmt::Debug; +use std::hash::Hash; +use std::marker::PhantomData; + +use variadics::variadic_collections::VariadicCollection; +use variadics::{ + var_args, var_type, PartialEqVariadic, RefVariadic, Split, SplitBySuffix, VariadicExt, +}; + +pub mod colt; +pub mod lattice; +pub mod macros; +pub mod test; + +/// The GeneralizedHashTrieNode trait captures the properties of nodes in a Ght. +/// +/// The Ght, defined by Wang/Willsey/Suciu, is a hash-based trie for storing tuples. +/// It is parameterized by an ordered schema [`VariadicExt`] of the relation stored in the trie. +/// It is a tree of [`GhtInner`] nodes, with [`GhtLeaf`] nodes at the leaves. +/// The trie is keyed on a prefix of the schema [`Self::KeyType`], +/// and the remaining columns [`Self::ValType`] are stored in the leaf. +/// All leaf nodes use the same `[Self::Storage]` type to store the data. +pub trait GeneralizedHashTrieNode: Default { + // types that are the same in all nodes of the trie + /// Schema variadic: the schema of the relation stored in this trie. + type Schema: VariadicExt + Eq + Hash + Clone + SplitBySuffix; + /// The prefix of columns in [`Self::Schema`] that the trie is keyed on + type KeyType: VariadicExt + Eq + Hash + Clone; + /// The suffix of columns in [`Self::Schema`] that are not part of the trie keys + type ValType: VariadicExt + Eq + Hash + Clone; + /// The type that holds the data in the leaves + type Storage: VariadicCollection + + Default + + IntoIterator; + + // types that vary per node + /// SuffixSchema variadic: the suffix of [`Self::Schema`] from this node of the trie + /// downward. The first entry in this variadic is of type [`Self::Head`]. + type SuffixSchema: VariadicExt + Eq + Hash + Clone; + /// The first field in [`Self::SuffixSchema`], and the key for the next node in the trie. + type Head: Eq + Hash + Clone; + + /// Create a new Ght from the iterator. + fn new_from(input: impl IntoIterator) -> Self; + + /// Merge a matching Ght node into this node + fn merge_node(&mut self, other: Self) -> bool; + + /// Report the height of this node. This is the length of path from this node to a leaf - 1. + /// E.g. if we have GhtInner> the height is 2 + /// This is a static property of the type of this node, so simply invokes the static method. + fn height(&self) -> usize { + Self::HEIGHT + } + + /// The height of this node in the GhT. Leaf = 0. + const HEIGHT: usize; + + /// Inserts an item into the hash trie. + fn insert(&mut self, row: Self::Schema) -> bool; + + /// Returns `true` if the (entire) row is found below in the trie, `false` otherwise. + /// See [`GhtGet::get`] to look just for "head" keys in this node + fn contains<'a>(&'a self, row: ::AsRefVar<'a>) -> bool; + + /// Iterate through (entire) rows stored in this HashTrie. + fn recursive_iter(&self) -> impl Iterator::AsRefVar<'_>>; + + /// return the leaf below that contains this row, or `None` if not found. + fn find_containing_leaf( + &self, + row: ::AsRefVar<'_>, + ) -> Option<&'_ GhtLeaf>; + + /// into_iter for leaf elements, or None for inner nodes + fn into_iter(self) -> Option>; + + /// pull all the data out of this trie node but retain the reference + fn drain(&mut self) -> Option>; +} + +/// internal node of a HashTrie +#[derive(Debug, Clone)] +pub struct GhtInner +where + Head: Clone, + Node: GeneralizedHashTrieNode, +{ + pub(crate) children: HashMap, +} + +impl Default for GhtInner +where + Head: Clone, + Node: GeneralizedHashTrieNode, +{ + fn default() -> Self { + let children = Default::default(); + Self { children } + } +} + +impl GeneralizedHashTrieNode for GhtInner +where + Head: 'static + Hash + Eq + Clone, + Node: 'static + GeneralizedHashTrieNode, + Node::Schema: SplitBySuffix, +{ + type Schema = Node::Schema; + type KeyType = Node::KeyType; + type ValType = Node::ValType; + type Storage = Node::Storage; + type SuffixSchema = var_type!(Head, ...Node::SuffixSchema); + type Head = Head; + + fn new_from(input: impl IntoIterator) -> Self { + let mut retval: Self = Default::default(); + for row in input { + retval.insert(row); + } + retval + } + + fn merge_node(&mut self, other: Self) -> bool { + let mut changed = false; + + for (k, v) in other.children { + match self.children.entry(k) { + std::collections::hash_map::Entry::Occupied(mut occupied) => { + changed |= occupied.get_mut().merge_node(v) + } + std::collections::hash_map::Entry::Vacant(vacant) => { + vacant.insert(v); + changed = true + } + } + } + changed + } + + const HEIGHT: usize = Node::HEIGHT + 1; + + fn insert(&mut self, row: Self::Schema) -> bool { + let (_prefix, var_args!(head, ..._rest)) = + Self::Schema::split_by_suffix_ref(row.as_ref_var()); + self.children.entry(head.clone()).or_default().insert(row) + } + + fn contains<'a>(&'a self, row: ::AsRefVar<'a>) -> bool { + let (_prefix, var_args!(head, ..._rest)) = Self::Schema::split_by_suffix_ref(row); + if let Some(node) = self.children.get(head) { + node.contains(row) + } else { + false + } + } + + fn recursive_iter(&self) -> impl Iterator::AsRefVar<'_>> { + self.children + .iter() + .flat_map(|(_k, vs)| vs.recursive_iter()) + } + + fn find_containing_leaf( + &self, + row: ::AsRefVar<'_>, + ) -> Option<&'_ GhtLeaf> { + let (_prefix, var_args!(head, ..._rest)) = Self::Schema::split_by_suffix_ref(row); + self.children + .get(head) + .and_then(|child| child.find_containing_leaf(row)) + } + + fn into_iter(self) -> Option> { + None::>> + } + + fn drain(&mut self) -> Option> { + None::>> + } +} + +impl FromIterator for GhtInner +where + Head: 'static + Hash + Eq + Clone, + Node: 'static + GeneralizedHashTrieNode + Clone, + Node::Schema: SplitBySuffix, +{ + fn from_iter>(iter: Iter) -> Self { + let mut out = Self::default(); + for row in iter { + out.insert(row); + } + out + } +} + +/// leaf node of a HashTrie +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct GhtLeaf +where + Schema: Eq + Hash, + Storage: VariadicCollection, +{ + pub(crate) elements: Storage, + pub(crate) forced: bool, + /// defines ValType for the parents, recursively + pub(crate) _suffix_schema: PhantomData, +} +impl Default for GhtLeaf +where + Schema: Eq + Hash, + Storage: VariadicCollection + Default, +{ + fn default() -> Self { + let elements = Storage::default(); + Self { + elements, + forced: false, + _suffix_schema: PhantomData, + } + } +} + +impl GeneralizedHashTrieNode + for GhtLeaf +where + Schema: 'static + + Eq + + VariadicExt + + Hash + + Clone + + SplitBySuffix + + PartialEqVariadic, + ValHead: Clone + Eq + Hash, + var_type!(ValHead, ...ValRest): Clone + Eq + Hash + PartialEqVariadic, + >::Prefix: Eq + Hash + Clone, + Storage: VariadicCollection + Default + IntoIterator, +{ + type Schema = Schema; + type SuffixSchema = var_type!(ValHead, ...ValRest); + type ValType = var_type!(ValHead, ...ValRest); + type KeyType = >::Prefix; + type Head = ValHead; + type Storage = Storage; + + fn new_from(input: impl IntoIterator) -> Self { + let mut retval: Self = Default::default(); + for i in input { + retval.insert(i); + } + retval + } + + fn merge_node(&mut self, other: Self) -> bool { + let old_len = self.elements.len(); + self.elements.extend(other.elements); + self.elements.len() > old_len + } + + const HEIGHT: usize = 0; + + fn insert(&mut self, row: Self::Schema) -> bool { + self.elements.insert(row); + true + } + + fn contains<'a>(&'a self, row: ::AsRefVar<'a>) -> bool { + self.elements.iter().any(|r| Schema::eq_ref(r, row)) + } + + fn recursive_iter(&self) -> impl Iterator::AsRefVar<'_>> { + self.elements.iter() + } + + fn find_containing_leaf( + &self, + row: ::AsRefVar<'_>, + ) -> Option<&'_ GhtLeaf<::Schema, Self::ValType, Self::Storage>> + { + // TODO(mingwei): actually use the hash set as a hash set + if self + .elements + .iter() + .any(|x| ::eq_ref(row, x)) + { + Some(self) + } else { + None + } + } + + fn into_iter(self) -> Option> { + Some(self.elements.into_iter()) + } + + fn drain(&mut self) -> Option> { + Some(self.elements.drain()) + } +} + +impl GeneralizedHashTrieNode for GhtLeaf +where + Schema: 'static + Eq + VariadicExt + Hash + Clone + PartialEqVariadic, + Storage: VariadicCollection + Default + IntoIterator, +{ + type Schema = Schema; + type SuffixSchema = (); + type ValType = (); + type KeyType = Schema; + type Head = (); + type Storage = Storage; + + fn new_from(input: impl IntoIterator) -> Self { + let mut retval: Self = Default::default(); + for i in input { + retval.insert(i); + } + retval + } + + fn merge_node(&mut self, other: Self) -> bool { + let old_len = self.elements.len(); + self.elements.extend(other.elements); + self.elements.len() > old_len + } + + const HEIGHT: usize = 0; + + fn insert(&mut self, row: Self::Schema) -> bool { + self.elements.insert(row); + true + } + + fn contains<'a>(&'a self, row: ::AsRefVar<'a>) -> bool { + self.elements.iter().any(|r| Schema::eq_ref(r, row)) + } + + fn recursive_iter(&self) -> impl Iterator::AsRefVar<'_>> { + self.elements.iter() + } + + fn find_containing_leaf( + &self, + row: ::AsRefVar<'_>, + ) -> Option<&'_ GhtLeaf<::Schema, Self::ValType, Self::Storage>> + { + // TODO(mingwei): actually use the hash set as a hash set + if self + .elements + .iter() + .any(|x| ::eq_ref(row, x)) + { + Some(self) + } else { + None + } + } + + fn into_iter(self) -> Option> { + Some(self.elements.into_iter()) + } + + fn drain(&mut self) -> Option> { + Some(self.elements.drain()) + } +} + +impl FromIterator for GhtLeaf +where + Schema: Eq + Hash, + Storage: VariadicCollection + Default + FromIterator, +{ + fn from_iter>(iter: Iter) -> Self { + let elements = iter.into_iter().collect(); + Self { + elements, + forced: false, + _suffix_schema: PhantomData, + } + } +} + +/// A trait for the get and iter methods from Wang/Willsey/Suciu, which +/// work differently on leaves than internal nodes +pub trait GhtGet: GeneralizedHashTrieNode { + /// Type returned by [`Self::get`]. + type Get: GeneralizedHashTrieNode; + + /// On an Inner node, retrieves the value (child) associated with the given "head" key. + /// returns an `Option` containing a reference to the value if found, or `None` if not found. + /// On a Leaf node, returns None. + fn get<'a>(&'a self, head: &Self::Head) -> Option<&'a Self::Get>; + + /// get, but mutable output + fn get_mut<'a>(&'a mut self, head: &Self::Head) -> Option<&'a mut Self::Get>; + + /// Iterator for the "head" keys (from inner nodes) or nothing (from leaf nodes). + fn iter(&self) -> impl Iterator; + + /// Iterator for the tuples (from leaf nodes) or nothing (from inner nodes). + fn iter_tuples(&self) -> impl Iterator::AsRefVar<'_>>; +} + +impl GhtGet for GhtInner +where + Head: 'static + Eq + Hash + Clone, + Node: 'static + GeneralizedHashTrieNode, + Node::Schema: SplitBySuffix, +{ + /// Type returned by [`Self::get`]. + type Get = Node; + + /// On an Inner node, retrieves the value (child) associated with the given "head" key. + /// returns an `Option` containing a reference to the value if found, or `None` if not found. + /// On a Leaf node, returns None. + fn get<'a>(&'a self, head: &Self::Head) -> Option<&'a Self::Get> { + self.children.get(head) + } + + fn get_mut<'a>(&'a mut self, head: &Self::Head) -> Option<&'a mut Self::Get> { + self.children.get_mut(head) + } + + fn iter(&self) -> impl Iterator { + self.children.keys().cloned() + } + + fn iter_tuples(&self) -> impl Iterator::AsRefVar<'_>> { + std::iter::empty() + } +} + +impl GhtGet for GhtLeaf +where + Schema: 'static + Eq + Hash + Clone + PartialEqVariadic + SplitBySuffix, + ValType: Eq + Hash + Clone + PartialEqVariadic, + >::Prefix: Eq + Hash + Clone, + GhtLeaf: GeneralizedHashTrieNode, + Storage: VariadicCollection, +{ + /// Type returned by [`Self::get`]. + type Get = GhtLeaf; + + /// On an Inner node, retrieves the value (child) associated with the given "head" key. + /// returns an `Option` containing a reference to the value if found, or `None` if not found. + /// On a Leaf node, returns None. + fn get<'a>(&'a self, _head: &Self::Head) -> Option<&'a Self::Get> { + None + } + fn get_mut<'a>(&'a mut self, _head: &Self::Head) -> Option<&'a mut Self::Get> { + None + } + + fn iter(&self) -> impl Iterator { + std::iter::empty() + } + + fn iter_tuples(&self) -> impl Iterator::AsRefVar<'_>> { + self.elements.iter() + } +} + +/// A trait to iterate through the items in a Ght based on a prefix of the schema. +pub trait GhtPrefixIter { + /// the schema output + type Item: VariadicExt; + /// given a prefix, return an iterator through the items below + fn prefix_iter<'a>( + &'a self, + prefix: KeyPrefix, + ) -> impl Iterator::AsRefVar<'a>> + where + Self::Item: 'a; +} + +impl<'k, Head, Node, PrefixRest> GhtPrefixIter + for GhtInner +where + Head: Eq + Hash + Clone, + Node: GeneralizedHashTrieNode + GhtPrefixIter, +{ + type Item = >::Item; + fn prefix_iter<'a>( + &'a self, + prefix: var_type!(&'k Head, ...PrefixRest), + ) -> impl Iterator::AsRefVar<'a>> + where + Self::Item: 'a, + { + let var_args!(head, ...rest) = prefix; + self.children + .get(head) + .map(|node| node.prefix_iter(rest)) + .into_iter() + .flatten() + } +} +impl GhtPrefixIter for GhtInner +where + Self: GeneralizedHashTrieNode, + Head: Eq + Hash + Clone, + Node: GeneralizedHashTrieNode, +{ + type Item = ::Schema; + fn prefix_iter<'a>( + &'a self, + _prefix: var_type!(), + ) -> impl Iterator::AsRefVar<'a>> + where + Self::Item: 'a, + { + self.recursive_iter() + } +} + +impl GhtPrefixIter + for GhtLeaf +where + KeyPrefixRef: 'static + RefVariadic, + Schema: 'static + VariadicExt + Hash + Eq + SplitBySuffix, + ValType: VariadicExt, + ValType: Split, + KeyPrefixRef::UnRefVar: PartialEqVariadic, + Storage: 'static + VariadicCollection, +{ + type Item = Schema; + fn prefix_iter<'a>( + &'a self, + prefix: KeyPrefixRef, + ) -> impl Iterator::AsRefVar<'a>> + where + Self::Item: 'a, + { + self.elements.iter().filter(move |&row| { + let (_row_prefix, row_mid_suffix) = + >::split_by_suffix_ref(row); + let (row_mid, _row_suffix): (::AsRefVar<'_>, _) = + >::split_ref(row_mid_suffix); + ::eq_ref(prefix.unref_ref(), row_mid) + }) + } +} diff --git a/lattices/src/ght/test.rs b/lattices/src/ght/test.rs new file mode 100644 index 000000000000..e24238c2de34 --- /dev/null +++ b/lattices/src/ght/test.rs @@ -0,0 +1,943 @@ +//! Tests for the GHT code +#[cfg(test)] +mod tests { + use std::collections::HashSet; + + #[test] + fn basic_test() { + use variadics::var_expr; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + // Example usage + type MyTrie1 = GhtType!(u32, u32 => &'static str: VariadicCountedHashSet); + + fn ght_type() {} + ght_type::(); + + let htrie1 = MyTrie1::new_from(vec![var_expr!(42, 314, "hello")]); + assert!(htrie1.contains(var_expr!(&42, &314, &"hello"))); + assert_eq!(htrie1.recursive_iter().count(), 1); + + type MyTrie2 = GhtType!(u32 => u32: VariadicCountedHashSet); + let htrie2 = MyTrie2::new_from(vec![var_expr!(42, 314)]); + assert!(htrie2.contains(var_expr!(&42, &314))); + assert_eq!(htrie1.recursive_iter().count(), 1); + + type MyTrie3 = GhtType!(u32, u64, u16 => &'static str: VariadicCountedHashSet); + let htrie3 = MyTrie3::new_from(vec![ + var_expr!(123, 2, 5, "hello"), + var_expr!(50, 1, 1, "hi"), + var_expr!(5, 1, 7, "hi"), + var_expr!(5, 1, 7, "bye"), + ]); + assert!(htrie3.contains(var_expr!(&50, &1, &1, &"hi"))); + assert_eq!(htrie3.recursive_iter().count(), 4); + } + #[test] + fn test_ght_node_type_macro() { + use variadics::var_expr; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + // 0 => 1 + type LilTrie = GhtType!(() => u32: VariadicCountedHashSet); + let _j = LilTrie::default(); + let _l = LilTrie::new_from(vec![var_expr!(1)]); + + // 0 => >1 + type LilTrie2 = GhtType!(() => u32, u64: VariadicCountedHashSet); + let _l = LilTrie2::default(); + let _l = LilTrie2::new_from(vec![var_expr!(1, 1)]); + + // 1 => 0 + type KeyNoValTrie = GhtType!(u32 => (): VariadicCountedHashSet); + let l = KeyNoValTrie::new_from(vec![var_expr!(1)]); + let _: KeyNoValTrie = l; + + // 1 => 1 + type SmallTrie = GhtType!(u32 => &'static str: VariadicCountedHashSet); + type SmallKeyedTrie = GhtType!(u32 => &'static str: VariadicCountedHashSet); + let l = SmallTrie::new_from(vec![var_expr!(1, "hello")]); + let _: SmallKeyedTrie = l; + + // 1 => >1 + type SmallKeyLongValTrie = GhtType!(u32 => u64, u16, &'static str: VariadicCountedHashSet); + let _x = SmallKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]); + + // >1 => 0 + type LongKeyNoValTrie = GhtType!(u32, u64 => (): VariadicCountedHashSet); + let l = LongKeyNoValTrie::new_from(vec![var_expr!(1, 999)]); + let _: LongKeyNoValTrie = l; + + // >1 => 1 + type LongKeySmallValTrie = GhtType!(u32, u16 => &'static str: VariadicCountedHashSet); + type LongKeySmallValKeyedTrie = GhtType!(u32, u16 => &'static str: VariadicCountedHashSet); + let x = LongKeySmallValTrie::new_from(vec![var_expr!(1, 314, "hello")]); + let _: LongKeySmallValKeyedTrie = x; + let _ = LongKeySmallValTrie::new_from(vec![var_expr!(1, 314, "hello")]); + + // >1 => >1 + type LongKeyLongValTrie = GhtType!(u32, u64 => u16, &'static str: VariadicCountedHashSet); + let _x = LongKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]); + } + + #[test] + fn test_insert() { + use variadics::var_expr; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type MyGht = GhtType!(u16, u32 => u64: VariadicCountedHashSet); + let mut htrie = MyGht::default(); + htrie.insert(var_expr!(42, 314, 43770)); + assert_eq!(htrie.recursive_iter().count(), 1); + assert_eq!(MyGht::HEIGHT, 2); + htrie.insert(var_expr!(42, 315, 43770)); + assert_eq!(htrie.recursive_iter().count(), 2); + htrie.insert(var_expr!(42, 314, 30619)); + assert_eq!(htrie.recursive_iter().count(), 3); + htrie.insert(var_expr!(43, 10, 600)); + assert_eq!(htrie.recursive_iter().count(), 4); + assert!(htrie.contains(var_expr!(&42, &314, &30619))); + assert!(htrie.contains(var_expr!(&42, &315, &43770))); + assert!(htrie.contains(var_expr!(&43, &10, &600))); + + type LongKeyLongValTrie = GhtType!(u32, u64 => u16, &'static str: VariadicCountedHashSet); + let mut htrie = LongKeyLongValTrie::new_from(vec![var_expr!(1, 999, 222, "hello")]); + htrie.insert(var_expr!(1, 999, 111, "bye")); + htrie.insert(var_expr!(1, 1000, 123, "cya")); + assert!(htrie.contains(var_expr!(&1, &999, &222, &"hello"))); + assert!(htrie.contains(var_expr!(&1, &999, &111, &"bye"))); + assert!(htrie.contains(var_expr!(&1, &1000, &123, &"cya"))); + } + + #[test] + fn test_scale() { + use variadics::var_expr; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type MyGht = GhtType!(bool, usize, &'static str => i32: VariadicCountedHashSet); + let mut htrie = MyGht::new_from(vec![var_expr!(true, 1, "hello", -5)]); + assert_eq!(htrie.recursive_iter().count(), 1); + for i in 1..1000000 { + htrie.insert(var_expr!(true, 1, "hello", i)); + } + assert_eq!(htrie.recursive_iter().count(), 1000000); + } + + #[test] + fn test_contains() { + use variadics::{var_expr, VariadicExt}; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type MyGht = GhtType!(u16, u32 => u64: VariadicCountedHashSet); + let htrie = MyGht::new_from(vec![var_expr!(42_u16, 314_u32, 43770_u64)]); + let x = var_expr!(&42, &314, &43770); + assert!(htrie.contains(x)); + assert!(htrie.contains(var_expr!(42, 314, 43770).as_ref_var())); + assert!(htrie.contains(var_expr!(&42, &314, &43770))); + assert!(!htrie.contains(var_expr!(42, 314, 30619).as_ref_var())); + assert!(!htrie.contains(var_expr!(&42, &315, &43770))); + assert!(!htrie.contains(var_expr!(&43, &314, &43770))); + } + + #[test] + fn test_get() { + use variadics::{var_expr, VariadicExt}; + + use crate::ght::{GeneralizedHashTrieNode, GhtGet}; + use crate::GhtType; + + type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSet); + let ht_root = MyGht::new_from(vec![var_expr!(42, 314, 43770)]); + + let inner = ht_root.get(&42).unwrap(); + let t = inner.recursive_iter().next().unwrap(); + assert_eq!(t, var_expr!(&42, &314, &43770)); + + let leaf = inner.get(&314).unwrap(); + let t = leaf.recursive_iter().next().unwrap(); + assert_eq!(t, var_expr!(42, 314, 43770).as_ref_var()); + } + + #[test] + fn test_iter() { + use variadics::var_expr; + + use crate::ght::{GeneralizedHashTrieNode, GhtGet}; + use crate::GhtType; + type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSet); + let ht_root = MyGht::new_from(vec![var_expr!(42, 314, 43770)]); + let inner_key = ht_root.iter().next().unwrap(); + let inner = ht_root.get(&inner_key).unwrap(); + let t = inner.recursive_iter().next().unwrap(); + assert_eq!(t, var_expr!(&42, &314, &43770)); + + let leaf_key = inner.iter().next().unwrap(); + let leaf = inner.get(&leaf_key).unwrap(); + // iter() on leaf should return None + let t = leaf.iter().next(); + assert!(t.is_none()); + } + + #[test] + fn test_recursive_iter() { + use variadics::{var_expr, var_type, VariadicExt}; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type MyGht = GhtType!(u32, u32 => u32: VariadicCountedHashSet); + type InputType = var_type!(u32, u32, u32); + type ResultType<'a> = var_type!(&'a u32, &'a u32, &'a u32); + let input: HashSet = HashSet::from_iter( + [ + (42, 314, 30619), + (42, 314, 43770), + (42, 315, 43770), + (43, 10, 600), + ] + .iter() + .map(|&(a, b, c)| var_expr!(a, b, c)), + ); + let htrie = MyGht::new_from(input.clone()); + let result = input.iter().map(|v| v.as_ref_var()).collect(); + let v: HashSet = htrie.recursive_iter().collect(); + assert_eq!(v, result); + } + + #[test] + fn test_prefix_iter_leaf() { + use variadics::variadic_collections::VariadicCountedHashSet; + use variadics::{var_expr, var_type}; + + use crate::ght::{GeneralizedHashTrieNode, GhtLeaf, GhtPrefixIter}; + + type InputType = var_type!(u8, u16, u32); + type ResultType<'a> = var_type!(&'a u8, &'a u16, &'a u32); + + let input: HashSet = HashSet::from_iter( + [ + (42, 314, 30619), + (42, 314, 43770), + (42, 315, 43770), + (43, 10, 600), + ] + .iter() + .map(|&(a, b, c)| var_expr!(a, b, c)), + ); + let leaf = + GhtLeaf::>::new_from( + input.clone(), + ); + // let key = var_expr!(42u8).as_ref_var(); + let key = (); // (var_expr!().as_ref_var();) + let v: HashSet = leaf.prefix_iter(key).collect(); + let result = input + .iter() + // .filter(|t: &&InputType| t.0 == 42) + .map(|t: &InputType| var_expr!(&t.0, &t.1 .0, &t.1 .1 .0)) + .collect(); + assert_eq!(v, result); + } + + #[test] + fn test_prefix_iter() { + use variadics::{var_expr, var_type, VariadicExt}; + + use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter}; + use crate::GhtType; + + type MyGht = GhtType!(u8, u16 => u32: VariadicCountedHashSet); + type InputType = var_type!(u8, u16, u32); + type ResultType<'a> = var_type!(&'a u8, &'a u16, &'a u32); + let input: HashSet = HashSet::from_iter( + [ + (42, 314, 30619), + (42, 314, 43770), + (42, 315, 43770), + (43, 10, 600), + ] + .iter() + .map(|&(a, b, c)| var_expr!(a, b, c)), + ); + let htrie = MyGht::new_from(input.clone()); + + let v: HashSet = htrie.prefix_iter(var_expr!(42, 315).as_ref_var()).collect(); + let result = HashSet::from_iter([var_expr!(&42, &315, &43770)].iter().copied()); + assert_eq!(v, result); + + let v: HashSet = htrie.prefix_iter(var_expr!(42u8).as_ref_var()).collect(); + let result = input + .iter() + .filter(|t: &&InputType| t.0 == 42) + .map(|t: &InputType| var_expr!(&t.0, &t.1 .0, &t.1 .1 .0)) + .collect(); + assert_eq!(v, result); + + for row in htrie.prefix_iter(var_expr!(42, 315, 43770).as_ref_var()) { + assert_eq!(row, var_expr!(&42, &315, &43770)); + } + } + + #[test] + fn test_prefix_iter_complex() { + use variadics::{var_expr, var_type, VariadicExt}; + + use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter}; + use crate::GhtType; + + type MyGht = GhtType!(bool, u32, &'static str => i32: VariadicCountedHashSet); + type InputType = var_type!(bool, u32, &'static str, i32); + type ResultType<'a> = var_type!(&'a bool, &'a u32, &'a &'static str, &'a i32); + let input: HashSet = HashSet::from_iter( + [ + (true, 1, "hello", -5), + (true, 1, "hi", -2), + (true, 1, "hi", -3), + (true, 1, "hi", -4), + (true, 1, "hi", -5), + (true, 2, "hello", 1), + (false, 10, "bye", 5), + ] + .iter() + .map(|&(a, b, c, d)| var_expr!(a, b, c, d)), + ); + + let htrie = MyGht::new_from(input.clone()); + + let v: HashSet = htrie + .prefix_iter(var_expr!(true, 1, "hi").as_ref_var()) + .collect(); + let result = input + .iter() + .filter(|t: &&InputType| t.0 && t.1.0 == 1 && t.1.1.0 == "hi") + //.map(|t: &InputType| (&t.0, &t.1 .0, (&t.1 .1 .0, (&t.1 .1 .1 .0, ())))) + .map(|t| t.as_ref_var()) + .collect(); + assert_eq!(v, result); + + let v: HashSet = htrie.prefix_iter(var_expr!(true).as_ref_var()).collect(); + let result = input + .iter() + .filter(|t: &&InputType| t.0) + .map(|t: &InputType| t.as_ref_var()) + .collect(); + assert_eq!(v, result); + } + + #[test] + fn test_merge() { + use variadics::{var_expr, var_type}; + + use crate::ght::GeneralizedHashTrieNode; + use crate::{GhtType, Merge}; + + type MyGht = GhtType!(u32, u64 => u16, &'static str: VariadicHashSet); + + let mut test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + let test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + + assert_eq!( + test_ght1 + .recursive_iter() + .collect::>() + .len(), + 1 + ); + test_ght1.merge(test_ght2.clone()); + // merge does not contain duplicate copy of the tuple + assert_eq!( + test_ght1 + .recursive_iter() + .collect::>() + .len(), + 1 + ); + assert!(!test_ght1.merge(test_ght2.clone())); + + let mut test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + let mut test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + test_ght1.merge(test_ght2.clone()); + + test_ght1.insert(var_expr!(42, 314, 20, "goodbye")); + test_ght2.insert(var_expr!(42, 314, 20, "again")); + + // change on merge + assert!(test_ght1.merge(test_ght2.clone())); + for k in test_ght2.recursive_iter() { + assert!(test_ght1.contains(k)) + } + } + + #[test] + fn test_node_lattice() { + use variadics::var_expr; + + use crate::ght::GeneralizedHashTrieNode; + use crate::{GhtType, NaiveLatticeOrd}; + + type MyGht = GhtType!(u32, u64 => u16, &'static str: VariadicHashSet); + type MyGhtNode = GhtType!(u32, u64 => u16, &'static str: VariadicHashSet); + + let mut test_vec: Vec = Vec::new(); + + let empty_ght = MyGht::new_from(vec![]); + let test_ght1 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + let mut test_ght2 = MyGht::new_from(vec![var_expr!(42, 314, 10, "hello")]); + test_ght2.insert(var_expr!(42, 314, 20, "again")); + let mut test_ght3 = test_ght2.clone(); + test_ght3.insert(var_expr!(42, 400, 1, "level 2")); + let mut test_ght4 = test_ght3.clone(); + test_ght4.insert(var_expr!(43, 1, 1, "level 1")); + + let test_vec_wrap = [empty_ght, test_ght1, test_ght2, test_ght3, test_ght4]; + + for ght in test_vec_wrap.iter().cloned() { + ght.naive_cmp(&ght.clone()); + test_vec.push(ght); + } + crate::test::check_all(&test_vec); + crate::test::check_all(&test_vec_wrap); + } + + #[test] + fn test_cartesian_bimorphism() { + use variadics::var_expr; + + use crate::ght::lattice::GhtCartesianProductBimorphism; + use crate::ght::GeneralizedHashTrieNode; + use crate::{GhtType, LatticeBimorphism}; + + type MyGhtA = GhtType!(u32, u64 => u16, &'static str: VariadicHashSet); + type MyGhtB = GhtType!(u32, u64, u16 => &'static str: VariadicHashSet); + + let mut ght_a = MyGhtA::default(); + let mut ght_b = MyGhtB::default(); + + ght_a.insert(var_expr!(123, 2, 5, "hello")); + ght_a.insert(var_expr!(50, 1, 1, "hi")); + ght_a.insert(var_expr!(5, 1, 7, "hi")); + ght_b.insert(var_expr!(5, 1, 8, "hi")); + ght_b.insert(var_expr!(10, 1, 2, "hi")); + ght_b.insert(var_expr!(12, 10, 98, "bye")); + + type MyGhtAb = GhtType!(u32, u64, u16, &'static str, u32, u64 => u16, &'static str: VariadicCountedHashSet); + + let mut bim = GhtCartesianProductBimorphism::::default(); + let ght_out = bim.call(&ght_a, &ght_b); + assert_eq!( + ght_out.recursive_iter().count(), + ght_a.recursive_iter().count() * ght_b.recursive_iter().count() + ); + } + + #[test] + fn test_join_bimorphism() { + use variadics::variadic_collections::{VariadicCountedHashSet, VariadicHashSet}; + use variadics::{var_expr, var_type}; + + use crate::ght::lattice::{ + DeepJoinLatticeBimorphism, GhtNodeKeyedBimorphism, GhtValTypeProductBimorphism, + }; + use crate::ght::{GeneralizedHashTrieNode, GhtInner, GhtLeaf}; + use crate::{GhtType, LatticeBimorphism}; + + type ResultSchemaType = var_type!(u32, u64, u16, &'static str, &'static str); + type ResultSchemaRefType<'a> = var_type!( + &'a u32, + &'a u64, + &'a u16, + &'a &'static str, + &'a &'static str + ); + type MyGhtATrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSet); + type MyGhtBTrie = GhtType!(u32, u64, u16 => &'static str: VariadicHashSet); + + let mut ght_a = MyGhtATrie::default(); + let mut ght_b = MyGhtBTrie::default(); + + ght_a.insert(var_expr!(123, 2, 5, "hello")); + ght_a.insert(var_expr!(50, 1, 1, "hi")); + ght_a.insert(var_expr!(5, 1, 7, "hi")); + + ght_b.insert(var_expr!(5, 1, 8, "hi")); + ght_b.insert(var_expr!(5, 1, 7, "world")); + ght_b.insert(var_expr!(10, 1, 2, "hi")); + ght_b.insert(var_expr!(12, 10, 98, "bye")); + + let result: HashSet = [var_expr!(&5, &1, &7, &"hi", &"world")] + .iter() + .copied() + .collect(); + { + // here we manually construct the proper bimorphism stack. + // note that the bottommost bimorphism is GhtValTypeProductBimorphism, + // which ensures that the Schema of the resulting output GhtLeaf and GhtInner + // nodes correctly includes the key columns, not just the cross-product of the values. + type MyGhtOut = GhtInner< + &'static str, + GhtLeaf< + ResultSchemaType, + var_type!(&'static str), + VariadicCountedHashSet, + >, + >; + // let mut bim = GhtNodeKeyedBimorphism::new(GhtNodeKeyedBimorphism::new( + // GhtNodeKeyedBimorphism::new(GhtValTypeProductBimorphism::::default()), + // )); + let mut bim = GhtNodeKeyedBimorphism::new(GhtNodeKeyedBimorphism::new( + GhtNodeKeyedBimorphism::new(GhtValTypeProductBimorphism::::default()), + )); + let out = bim.call(&ght_a, &ght_b); + let out: HashSet = out.recursive_iter().collect(); + assert_eq!(out, result.iter().copied().collect()); + } + { + // Here we use DeepJoinLatticeBimorphism as a more compact representation of the + // manual stack of bimorphisms above. This is the recommended approach. + type MyNodeBim<'a> = <(MyGhtATrie, MyGhtBTrie) as DeepJoinLatticeBimorphism< + VariadicHashSet, + >>::DeepJoinLatticeBimorphism; + let mut bim = ::default(); + let out = bim.call(&ght_a, &ght_b); + let out: HashSet = out.recursive_iter().collect(); + assert_eq!(out, result.iter().copied().collect()); + } + } + + #[test] + fn test_ght_with_tuple_macro() { + use variadics::{var_expr, VariadicExt}; + use variadics_macro::tuple; + + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type MyRoot = GhtType!(u16, u32 => u64: VariadicCountedHashSet); + + let mut trie1 = MyRoot::default(); + assert_eq!(3, <::Schema>::LEN); + trie1.insert(var_expr!(1, 2, 3)); + let t = trie1.recursive_iter().next().unwrap(); + let tup = tuple!(t, 3); + assert_eq!(tup, (&1, &2, &3)); + } + + #[test] + fn test_triangle_generic_join() { + use std::hash::{BuildHasherDefault, DefaultHasher}; + + use variadics::var_expr; + + use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter}; + use crate::GhtType; + + const MATCHES: u32 = 1000; + type MyGht = GhtType!(u32 => u32: VariadicCountedHashSet); + + let r_iter = (0..MATCHES) + .map(|i| (0, i)) + .chain((1..MATCHES).map(|i| (i, 0))); + + let s_iter = (0..MATCHES) + .map(|i| (0, i)) + .chain((1..MATCHES).map(|i| (i, 0))); + + let t_iter = (0..MATCHES) + .map(|i| (0, i)) + .chain((1..MATCHES).map(|i| (i, 0))); + + let rx_ght = MyGht::new_from(r_iter.clone().map(|(x, y)| var_expr!(x, y))); + let sb_ght = MyGht::new_from(s_iter.clone().map(|(y, b)| var_expr!(b, y))); + let tx_ght = MyGht::new_from(t_iter.clone().map(|(z, x)| var_expr!(x, z))); + + let r_x = r_iter + .clone() + .map(|(x, _y)| x) + .collect::>>(); + let t_x = s_iter + .clone() + .map(|(_z, x)| x) + .collect::>>(); + let x_inter = r_x.intersection(&t_x); + let len = x_inter.clone().count(); + if len > 1 { + assert_eq!(1000, len); + } + + let mut output: Vec<(u32, u32, u32)> = Vec::new(); + let mut x_iters = 0usize; + let mut y_iters = 0usize; + let mut z_iters = 0usize; + for a in x_inter { + x_iters += 1; + let r = rx_ght + .prefix_iter(var_expr!(a)) + .map(|(_x, (y, ()))| *y) + .collect::>>(); + let s_y = s_iter + .clone() + .map(|(y, _z)| y) + .collect::>>(); + let y_inter = r.intersection(&s_y); + let len = y_inter.clone().count(); + if len > 1 { + assert_eq!(1000, len); + } + for b in y_inter { + y_iters += 1; + let s = sb_ght + .prefix_iter(var_expr!(b)) + .map(|(_b, (z, ()))| *z) + .collect::>>(); + let t = tx_ght + .prefix_iter(var_expr!(a)) + .map(|(_x, (z, ()))| *z) + .collect::>>(); + let z_inter = s.intersection(&t); + let len = z_inter.clone().count(); + if len > 1 { + assert_eq!(1000, len); + } + for c in z_inter { + z_iters += 1; + output.push((*a, *b, *c)); + } + } + } + + assert_eq!(1000, x_iters); + assert_eq!(1999, y_iters); + assert_eq!(2998, z_iters); + assert_eq!(2998, output.len()); + } + + fn clover_setup( + matches: usize, + ) -> ( + impl Iterator, + impl Iterator, + impl Iterator, + ) { + let r_iter = (1..matches) + .map(|i| (1u32, i as u32)) + .chain((1..matches).map(|i| (2, i as u32))) + .chain([(0, 0)]); + + let s_iter = (1..matches) + .map(|i| (2u32, i as u32)) + .chain((1..matches).map(|i| (3, i as u32))) + .chain([(0, 0)]); + + let t_iter = (1..matches) + .map(|i| (3u32, i as u32)) + .chain((1..matches).map(|i| (1, i as u32))) + .chain([(0, 0)]); + (r_iter, s_iter, t_iter) + } + + #[test] + fn clover_generic_join() { + use variadics::var_expr; + + use crate::ght::{GeneralizedHashTrieNode, GhtGet}; + use crate::GhtType; + + const MATCHES: usize = 1000; + let (r_iter, s_iter, t_iter) = clover_setup(MATCHES); + + type MyGht = GhtType!(u32 => u32: VariadicCountedHashSet); + let rx_ght = MyGht::new_from(r_iter.map(|(x, a)| var_expr!(x, a))); + let sx_ght = MyGht::new_from(s_iter.map(|(x, b)| var_expr!(x, b))); + let tx_ght = MyGht::new_from(t_iter.map(|(x, c)| var_expr!(x, c))); + for x in rx_ght.iter() { + if let (Some(r), Some(s), Some(t)) = (rx_ght.get(&x), sx_ght.get(&x), tx_ght.get(&x)) { + // All unwraps succeeded, use `r`, `s`, `t` here + for a in r.iter() { + for b in s.iter() { + for c in t.iter() { + assert_eq!((x, a, b, c), (0, 0, 0, 0)); + } + } + } + } else { + // If any unwrap fails, continue to the next iteration + continue; + } + } + } + + #[test] + fn clover_factorized_join() { + use variadics::var_expr; + + use crate::ght::{GeneralizedHashTrieNode, GhtGet}; + use crate::GhtType; + + const MATCHES: usize = 1000; + let (r_iter, s_iter, t_iter) = clover_setup(MATCHES); + + type Ght1 = GhtType!(() => u32, u32: VariadicCountedHashSet); + type Ght2 = GhtType!(u32 => u32: VariadicCountedHashSet); + let rx_ght = Ght1::new_from(r_iter.map(|(x, a)| var_expr!(x, a))); + let sx_ght = Ght2::new_from(s_iter.map(|(x, b)| var_expr!(x, b))); + let tx_ght = Ght2::new_from(t_iter.map(|(x, c)| var_expr!(x, c))); + + for t in rx_ght.recursive_iter() { + let (x, (a, ())): (&u32, (&u32, _)) = t; + if let (Some(s), Some(t)) = (sx_ght.get(x), tx_ght.get(x)) { + // All unwraps succeeded, use `s`, `t` here + for b in s.iter() { + for c in t.iter() { + assert_eq!((x, a, b, c), (&0, &0, 0, 0)); + } + } + } else { + // If any unwrap fails, continue to the next iteration + continue; + } + } + } + + #[test] + fn test_force() { + use variadics::var_expr; + + use crate::ght::colt::ColtForestNode; + use crate::ght::GeneralizedHashTrieNode; + use crate::GhtType; + + type LeafType = GhtType!(() => u16, u32, u64: VariadicCountedHashSet); + let n = LeafType::new_from(vec![ + var_expr!(1, 1, 1), + var_expr!(1, 2, 2), + var_expr!(1, 3, 3), + var_expr!(2, 4, 4), + ]); + let out = n.force().unwrap(); + assert_eq!(out.height(), 1); + } + + #[test] + fn test_forest_macro() { + use crate::ColtType; + + type Forest4 = ColtType!(u8, u16, u32, u64); + let _f4 = Forest4::default(); + + type Forest3 = ColtType!(u8, u16, u32); + let _f3 = Forest3::default(); + + type Forest2 = ColtType!(u8, u16); + let _f2 = Forest2::default(); + + type Forest1 = ColtType!(u8); + let _f2 = Forest1::default(); + + type Forest01 = ColtType!(() => u16); + let _f01 = Forest01::default(); + + type Forest02 = ColtType!(() => u8, u16); + let _f02 = Forest02::default(); + + type Forest10 = ColtType!(u8 => ()); + let _f10 = Forest10::default(); + + type Forest11 = ColtType!(u8 => u16); + let _f11 = Forest11::default(); + + type Forest12 = ColtType!(u8 => u16, u32); + let _f12 = Forest12::default(); + + type Forest20 = ColtType!(u8, u16 => ()); + let _f20 = Forest20::default(); + + type Forest21 = ColtType!(u8, u16 => u32); + let _f21 = Forest21::default(); + + type Forest22 = ColtType!(u8, u16 => u32, u64); + let _f22 = Forest22::default(); + } + + #[test] + fn test_colt_little_get() { + use variadics::variadic_collections::VariadicCollection; + use variadics::{var_expr, VariadicExt}; + + use crate::ght::colt::ColtGet; + use crate::ght::GeneralizedHashTrieNode; + use crate::ColtType; + + type MyForest = ColtType!(u8); + + let mut forest = MyForest::default(); + + forest.0.insert(var_expr!(1)); + forest.0.insert(var_expr!(2)); + forest.0.insert(var_expr!(3)); + + assert_eq!(2, forest.len()); + assert_eq!(3, forest.0.elements.len()); + + let result = ColtGet::get(forest.as_mut_var(), &3); + assert_eq!(1, result.len()); + assert_eq!(0, forest.0.elements.len()); + assert!(forest.0.forced); + } + + #[test] + fn test_colt_get() { + use variadics::variadic_collections::VariadicCollection; + use variadics::{var_expr, VariadicExt}; + + use crate::ght::colt::ColtGet; + use crate::ght::{GeneralizedHashTrieNode, GhtGet}; + use crate::ColtType; + + type MyForest = ColtType!(u8, u16, u32, u64); + let mut forest = MyForest::default(); + forest.0.insert(var_expr!(1, 1, 1, 1)); + forest.0.insert(var_expr!(2, 2, 2, 2)); + forest.0.insert(var_expr!(3, 3, 3, 3)); + + let len = forest.len(); + assert_eq!(5, len); + { + let get_result = ColtGet::get(forest.as_mut_var(), &1); + assert_eq!(get_result.len(), len - 1); + assert_eq!(get_result.0.height(), 0); + let get_result2 = ColtGet::get(get_result, &1); + assert_eq!(get_result2.len(), len - 2); + let get_result3 = ColtGet::get(get_result2, &1); + assert_eq!(get_result3.len(), len - 3); + assert_eq!( + get_result3.0.elements.iter().next(), + Some(var_expr!(1, 1, 1, 1).as_ref_var()) + ); + assert_eq!(get_result3.1 .0.children.len(), 0); + } + { + let get_result = ColtGet::get(forest.as_mut_var(), &3); + assert_eq!(get_result.len(), len - 1); + let get_result2 = ColtGet::get(get_result, &3); + assert_eq!(get_result2.len(), len - 2); + assert_eq!( + get_result2.0.elements.iter().next(), + Some(var_expr!(3, 3, 3, 3).as_ref_var()) + ); + assert_eq!(get_result2.1 .0.children.len(), 0); + } + assert!(forest.0.forced); + assert_eq!(3, forest.1 .0.children.len()); // keys 1, 2 and 3 + assert_eq!(0, forest.1 .0.get(&1).unwrap().elements.len()); + assert_eq!(1, forest.1 .0.get(&2).unwrap().elements.len()); + assert_eq!(0, forest.1 .0.get(&3).unwrap().elements.len()); + assert_eq!(2, forest.1 .1 .0.children.len()); // keys 1 and 3 + assert_eq!( + 0, + forest + .1 + .1 + .0 + .get(&1) + .unwrap() + .get(&1) + .unwrap() + .elements + .len() + ); + assert!(forest.1 .1 .0.get(&2).is_none()); + assert_eq!( + 1, + forest + .1 + .1 + .0 + .get(&3) + .unwrap() + .get(&3) + .unwrap() + .elements + .len() + ); + assert_eq!( + 1, + forest + .1 + .1 + .1 + .0 + .get(&1) + .unwrap() + .get(&1) + .unwrap() + .get(&1) + .unwrap() + .elements + .len() + ); + } + + #[test] + fn test_colt_scale() { + use variadics::variadic_collections::VariadicCollection; + use variadics::{var_expr, VariadicExt}; + + use crate::ght::colt::ColtGet; + use crate::ght::{GeneralizedHashTrieNode, GhtPrefixIter}; + + type MyColt = crate::ColtType!(i32, bool, usize, &'static str); + let mut forest = MyColt::default(); + for i in 1..100000 { + forest.0.insert(var_expr!(i, true, 1, "hello")); + } + { + let result = forest.as_mut_var().get(&3); + assert_eq!(result.len(), 4); + } + // check: first Leaf trie is forced + assert!(forest.0.forced); + assert_eq!(forest.0.elements.len(), 0); + { + let result = forest.as_mut_var().get(&3); + let result2 = result.get(&true); + assert_eq!(result2.len(), 3); + } + { + // check: leaf below 3 in first non-empty trie is forced + let result = forest.as_mut_var().get(&3); + assert!(result.0.forced); + assert_eq!(result.0.elements.len(), 0); + } + // check: prefix (3, true) is now found in the third trie: forest.1.1.0 + assert!(forest + .1 + .1 + .0 + .prefix_iter(var_expr!(3, true).as_ref_var()) + .next() + .is_some()); + { + let result = forest.as_mut_var().get(&3); + let result2 = result.get(&true); + assert_eq!(result2.len(), 3); + let result3 = result2.get(&1); + assert_eq!(result3.len(), 2); + let result4 = result3.get(&"hello"); + assert_eq!(result4.0.elements.len(), 1); + assert_eq!( + result4.0.elements.iter().next(), + Some(var_expr!(3, true, 1, "hello").as_ref_var()) + ); + } + } +} diff --git a/lattices/src/lib.rs b/lattices/src/lib.rs index c8fc0804819e..bac63c543b16 100644 --- a/lattices/src/lib.rs +++ b/lattices/src/lib.rs @@ -3,14 +3,15 @@ use std::cmp::Ordering::{self, *}; -pub use cc_traits; use sealed::sealed; +pub use {cc_traits, variadics}; /// Module for definiting algebraic structures and properties. pub mod algebra; pub mod collections; mod conflict; mod dom_pair; +pub mod ght; pub mod map_union; pub mod map_union_with_tombstones; mod ord; diff --git a/lattices/src/test.rs b/lattices/src/test.rs index 2b2068906c46..80306c7752ad 100644 --- a/lattices/src/test.rs +++ b/lattices/src/test.rs @@ -329,8 +329,8 @@ pub fn cartesian_power( (size, Some(size)) } } - impl<'a, T, const N: usize> ExactSizeIterator for CartesianPower<'a, T, N> {} - impl<'a, T, const N: usize> Clone for CartesianPower<'a, T, N> { + impl ExactSizeIterator for CartesianPower<'_, T, N> {} + impl Clone for CartesianPower<'_, T, N> { fn clone(&self) -> Self { Self { items: self.items, diff --git a/lattices/src/vec_union.rs b/lattices/src/vec_union.rs index 731f6009711f..e9ef26994348 100644 --- a/lattices/src/vec_union.rs +++ b/lattices/src/vec_union.rs @@ -98,13 +98,13 @@ where { fn eq(&self, other: &VecUnion) -> bool { if self.vec.len() != other.vec.len() { - return false; + false + } else { + self.vec + .iter() + .zip(other.vec.iter()) + .all(|(val_self, val_other)| val_self == val_other) } - return self - .vec - .iter() - .zip(other.vec.iter()) - .all(|(val_self, val_other)| val_self == val_other); } } diff --git a/lattices/tests/compile-fail/non_lattice_field.stderr b/lattices/tests/compile-fail/non_lattice_field.stderr index f2630b97f64e..7b8e66201e53 100644 --- a/lattices/tests/compile-fail/non_lattice_field.stderr +++ b/lattices/tests/compile-fail/non_lattice_field.stderr @@ -8,11 +8,11 @@ error[E0277]: the trait bound `String: Merge` is not satisfied `()` implements `Merge<()>` `Conflict` implements `Merge>` `DomPair` implements `Merge>` + `GhtInner` implements `Merge>` + `GhtLeaf` implements `Merge>` `MapUnion` implements `Merge>` `MapUnionWithTombstones` implements `Merge>` `Max` implements `Merge>` - `Min` implements `Merge>` - `NotALattice` implements `Merge` and $N others = help: see issue #48214 = note: this error originates in the derive macro `Lattice` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -31,11 +31,11 @@ error[E0277]: the trait bound `String: IsBot` is not satisfied () Conflict DomPair + GhtInner + GhtLeaf MapUnion MapUnionWithTombstones Max<()> - Max - Max and $N others = help: see issue #48214 = note: this error originates in the derive macro `Lattice` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -54,11 +54,11 @@ error[E0277]: the trait bound `String: IsTop` is not satisfied () Conflict DomPair + GhtInner + GhtLeaf MapUnion MapUnionWithTombstones Max<()> - Max - Max and $N others = help: see issue #48214 = note: this error originates in the derive macro `Lattice` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/lattices_macro/CHANGELOG.md b/lattices_macro/CHANGELOG.md index 6234c31f39b4..4f06af34a7f8 100644 --- a/lattices_macro/CHANGELOG.md +++ b/lattices_macro/CHANGELOG.md @@ -1,7 +1,34 @@ +## v0.5.7 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## v0.5.6 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -13,7 +40,8 @@ - - 1 commit contributed to the release. + - 2 commits contributed to the release. + - 38 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -25,6 +53,8 @@ * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## v0.5.5 (2024-07-23) diff --git a/lattices_macro/Cargo.toml b/lattices_macro/Cargo.toml index 7daa07140178..6a7dd5e8636b 100644 --- a/lattices_macro/Cargo.toml +++ b/lattices_macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "lattices_macro" publish = true -version = "0.5.6" +version = "0.5.7" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/lattices/" diff --git a/multiplatform_test/CHANGELOG.md b/multiplatform_test/CHANGELOG.md index ab716140ec61..f02c6cbb9faf 100644 --- a/multiplatform_test/CHANGELOG.md +++ b/multiplatform_test/CHANGELOG.md @@ -5,8 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.3.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.2.0 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -18,7 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 1 commit contributed to the release. + - 2 commits contributed to the release. + - 97 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -30,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.1.0 (2024-05-24) diff --git a/multiplatform_test/Cargo.toml b/multiplatform_test/Cargo.toml index cccc85ec4c15..926f07804ef7 100644 --- a/multiplatform_test/Cargo.toml +++ b/multiplatform_test/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "multiplatform_test" publish = true -version = "0.2.0" +version = "0.3.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/multiplatform_test/" diff --git a/pusherator/CHANGELOG.md b/pusherator/CHANGELOG.md index 72128d0236fc..14c0fa4e081f 100644 --- a/pusherator/CHANGELOG.md +++ b/pusherator/CHANGELOG.md @@ -5,8 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.0.9 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 69 days passed between releases. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) +
+ ## 0.0.8 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -18,7 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 1 commit contributed to the release. + - 2 commits contributed to the release. + - 38 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -30,6 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.0.7 (2024-07-23) @@ -47,6 +77,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 59 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -74,6 +105,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 83 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1204](https://github.com/hydro-project/hydroflow/issues/1204) @@ -102,6 +134,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 32 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -132,6 +165,7 @@ Unchanged from previous release. - 2 commits contributed to the release. + - 166 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -164,6 +198,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 42 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#822](https://github.com/hydro-project/hydroflow/issues/822), [#835](https://github.com/hydro-project/hydroflow/issues/835) @@ -193,6 +228,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 44 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#780](https://github.com/hydro-project/hydroflow/issues/780) @@ -224,6 +260,7 @@ Unchanged from previous release. - 3 commits contributed to the release. + - 25 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#660](https://github.com/hydro-project/hydroflow/issues/660) diff --git a/pusherator/Cargo.toml b/pusherator/Cargo.toml index 4c454c1f0611..e02eb53f0d75 100644 --- a/pusherator/Cargo.toml +++ b/pusherator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "pusherator" publish = true -version = "0.0.8" +version = "0.0.9" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/pusherator/" @@ -16,4 +16,4 @@ demux = [ "dep:variadics" ] [dependencies] either = "1.0.0" -variadics = { optional = true, path = "../variadics", version = "^0.0.6" } +variadics = { optional = true, path = "../variadics", version = "^0.0.7" } diff --git a/stageleft/CHANGELOG.md b/stageleft/CHANGELOG.md index 2d6df3147511..466d60124526 100644 --- a/stageleft/CHANGELOG.md +++ b/stageleft/CHANGELOG.md @@ -5,8 +5,55 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v0.5.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - add API for external network inputs + This is a key step towards being able to unit-test HF+ graphs, by being + able to have controlled inputs. Outputs next. + - splice UDFs with type hints to avoid inference failures + +### Style + + - fixes for nightly clippy + a couple few spurious `too_many_arguments` and a spurious + `zombie_processes` still on current nightly (`clippy 0.1.84 (4392847410 + 2024-10-21)`) + +### Commit Statistics + + + + - 4 commits contributed to the release. + - 69 days passed between releases. + - 4 commits were understood as [conventional](https://www.conventionalcommits.org). + - 4 unique issues were worked on: [#1434](https://github.com/hydro-project/hydroflow/issues/1434), [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1449](https://github.com/hydro-project/hydroflow/issues/1449), [#1505](https://github.com/hydro-project/hydroflow/issues/1505) + +### Commit Details + + + +
view details + + * **[#1434](https://github.com/hydro-project/hydroflow/issues/1434)** + - Splice UDFs with type hints to avoid inference failures ([`60d9bec`](https://github.com/hydro-project/hydroflow/commit/60d9becaf0b67f9819316ce6d76bd867f7d46505)) + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1449](https://github.com/hydro-project/hydroflow/issues/1449)** + - Add API for external network inputs ([`8a80931`](https://github.com/hydro-project/hydroflow/commit/8a809315cd37929687fcabc34a12042db25d5767)) + * **[#1505](https://github.com/hydro-project/hydroflow/issues/1505)** + - Fixes for nightly clippy ([`47cb703`](https://github.com/hydro-project/hydroflow/commit/47cb703e771f7d1c451ceb9d185ada96410949da)) +
+ ## v0.4.0 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -31,7 +78,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 3 commits contributed to the release. + - 4 commits contributed to the release. + - 97 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1397](https://github.com/hydro-project/hydroflow/issues/1397), [#1398](https://github.com/hydro-project/hydroflow/issues/1398), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -47,6 +95,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Use trybuild to compile subgraph binaries ([`46a8a2c`](https://github.com/hydro-project/hydroflow/commit/46a8a2cb08732bb21096e824bc4542d208c68fb2)) * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## v0.3.0 (2024-05-24) @@ -66,6 +116,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 4 commits contributed to the release. + - 48 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1104](https://github.com/hydro-project/hydroflow/issues/1104), [#1151](https://github.com/hydro-project/hydroflow/issues/1151), [#1225](https://github.com/hydro-project/hydroflow/issues/1225) @@ -108,6 +159,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 34 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1090](https://github.com/hydro-project/hydroflow/issues/1090), [#1100](https://github.com/hydro-project/hydroflow/issues/1100) @@ -137,6 +189,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 2 commits contributed to the release. + - 32 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#1070](https://github.com/hydro-project/hydroflow/issues/1070) diff --git a/stageleft/Cargo.toml b/stageleft/Cargo.toml index d58e1bfa18f0..49a0ee4c9a4b 100644 --- a/stageleft/Cargo.toml +++ b/stageleft/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stageleft" publish = true -version = "0.4.0" +version = "0.5.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/stageleft/" @@ -18,4 +18,4 @@ quote = "1.0.35" syn = { version = "2.0.46", features = [ "parsing", "extra-traits", "visit-mut" ] } proc-macro2 = "1.0.74" proc-macro-crate = "1.0.0" -stageleft_macro = { path = "../stageleft_macro", version = "^0.3.0" } +stageleft_macro = { path = "../stageleft_macro", version = "^0.4.0" } diff --git a/stageleft/src/lib.rs b/stageleft/src/lib.rs index ff23a4c4963c..ee1cdabaad1a 100644 --- a/stageleft/src/lib.rs +++ b/stageleft/src/lib.rs @@ -17,7 +17,7 @@ pub mod internal { pub use stageleft_macro::{entry, q, quse_fn, runtime, top_level_mod}; pub mod runtime_support; -use runtime_support::FreeVariable; +use runtime_support::FreeVariableWithContext; use crate::runtime_support::get_final_crate_name; @@ -99,10 +99,10 @@ pub trait QuotedContext { } pub struct BorrowBounds<'a> { - _marker: PhantomData<&'a &'a mut ()>, + _marker: PhantomData &'a ()>, } -impl<'a> QuotedContext for BorrowBounds<'a> { +impl QuotedContext for BorrowBounds<'_> { fn create() -> Self { BorrowBounds { _marker: PhantomData, @@ -110,12 +110,12 @@ impl<'a> QuotedContext for BorrowBounds<'a> { } } -pub trait Quoted<'a, T>: FreeVariable { - fn splice_untyped(self) -> syn::Expr +pub trait QuotedWithContext<'a, T, Ctx>: FreeVariableWithContext { + fn splice_untyped_ctx(self, ctx: &Ctx) -> syn::Expr where Self: Sized, { - let (prelude, value) = self.to_tokens(); + let (prelude, value) = self.to_tokens(ctx); if prelude.is_some() { panic!("Quoted value should not have prelude"); } @@ -123,9 +123,96 @@ pub trait Quoted<'a, T>: FreeVariable { syn::parse2(value.unwrap()).unwrap() } + fn splice_typed_ctx(self, ctx: &Ctx) -> syn::Expr + where + Self: Sized, + { + let inner_expr = self.splice_untyped_ctx(ctx); + let stageleft_root = stageleft_root(); + + let out_type = quote_type::(); + + syn::parse_quote! { + #stageleft_root::runtime_support::type_hint::<#out_type>(#inner_expr) + } + } + + fn splice_fn0_ctx(self, ctx: &Ctx) -> syn::Expr + where + Self: Sized, + T: Fn() -> O, + { + let inner_expr = self.splice_untyped_ctx(ctx); + let stageleft_root = stageleft_root(); + + let out_type = quote_type::(); + + syn::parse_quote! { + #stageleft_root::runtime_support::fn0_type_hint::<#out_type>(#inner_expr) + } + } + + fn splice_fn1_ctx(self, ctx: &Ctx) -> syn::Expr + where + Self: Sized, + T: Fn(I) -> O, + { + let inner_expr = self.splice_untyped_ctx(ctx); + let stageleft_root = stageleft_root(); + + let in_type = quote_type::(); + let out_type = quote_type::(); + + syn::parse_quote! { + #stageleft_root::runtime_support::fn1_type_hint::<#in_type, #out_type>(#inner_expr) + } + } + + fn splice_fn1_borrow_ctx(self, ctx: &Ctx) -> syn::Expr + where + Self: Sized, + T: Fn(&I) -> O, + { + let inner_expr = self.splice_untyped_ctx(ctx); + let stageleft_root = stageleft_root(); + + let in_type = quote_type::(); + let out_type = quote_type::(); + + syn::parse_quote! { + #stageleft_root::runtime_support::fn1_borrow_type_hint::<#in_type, #out_type>(#inner_expr) + } + } + + fn splice_fn2_borrow_mut_ctx(self, ctx: &Ctx) -> syn::Expr + where + Self: Sized, + T: Fn(&mut I1, I2) -> O, + { + let inner_expr = self.splice_untyped_ctx(ctx); + let stageleft_root = stageleft_root(); + + let in1_type = quote_type::(); + let in2_type = quote_type::(); + let out_type = quote_type::(); + + syn::parse_quote! { + #stageleft_root::runtime_support::fn2_borrow_mut_type_hint::<#in1_type, #in2_type, #out_type>(#inner_expr) + } + } + + fn splice_untyped(self) -> syn::Expr + where + Self: Sized, + Ctx: Default, + { + self.splice_untyped_ctx(&Default::default()) + } + fn splice_typed(self) -> syn::Expr where Self: Sized, + Ctx: Default, { let inner_expr = self.splice_untyped(); let stageleft_root = stageleft_root(); @@ -140,6 +227,7 @@ pub trait Quoted<'a, T>: FreeVariable { fn splice_fn0(self) -> syn::Expr where Self: Sized, + Ctx: Default, T: Fn() -> O, { let inner_expr = self.splice_untyped(); @@ -155,6 +243,7 @@ pub trait Quoted<'a, T>: FreeVariable { fn splice_fn1(self) -> syn::Expr where Self: Sized, + Ctx: Default, T: Fn(I) -> O, { let inner_expr = self.splice_untyped(); @@ -171,6 +260,7 @@ pub trait Quoted<'a, T>: FreeVariable { fn splice_fn1_borrow(self) -> syn::Expr where Self: Sized, + Ctx: Default, T: Fn(&I) -> O, { let inner_expr = self.splice_untyped(); @@ -187,6 +277,7 @@ pub trait Quoted<'a, T>: FreeVariable { fn splice_fn2_borrow_mut(self) -> syn::Expr where Self: Sized, + Ctx: Default, T: Fn(&mut I1, I2) -> O, { let inner_expr = self.splice_untyped(); @@ -202,6 +293,9 @@ pub trait Quoted<'a, T>: FreeVariable { } } +pub trait Quoted<'a, T>: QuotedWithContext<'a, T, ()> {} +impl<'a, T, F: QuotedWithContext<'a, T, ()>> Quoted<'a, T> for F {} + fn stageleft_root() -> syn::Ident { let stageleft_crate = proc_macro_crate::crate_name("stageleft") .unwrap_or_else(|_| panic!("stageleft should be present in `Cargo.toml`")); @@ -212,12 +306,19 @@ fn stageleft_root() -> syn::Ident { } } -pub trait IntoQuotedOnce<'a, T>: - FnOnce(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T +pub trait IntoQuotedOnce<'a, T, Ctx>: + for<'b> FnOnce( + &'b Ctx, + &mut String, + &mut &'static str, + &mut TokenStream, + &mut CaptureVec, + bool, + ) -> T + 'a - + Quoted<'a, T> + + QuotedWithContext<'a, T, Ctx> { - fn boxed(self) -> Box> + fn boxed(self) -> Box> where Self: Sized, { @@ -228,32 +329,60 @@ pub trait IntoQuotedOnce<'a, T>: impl< 'a, T, - F: FnOnce(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a, - > Quoted<'a, T> for F + Ctx, + F: for<'b> FnOnce( + &'b Ctx, + &mut String, + &mut &'static str, + &mut TokenStream, + &mut CaptureVec, + bool, + ) -> T + + 'a, + > QuotedWithContext<'a, T, Ctx> for F { } impl< 'a, T, - F: FnOnce(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a, - > IntoQuotedOnce<'a, T> for F + Ctx, + F: for<'b> FnOnce( + &'b Ctx, + &mut String, + &mut &'static str, + &mut TokenStream, + &mut CaptureVec, + bool, + ) -> T + + 'a, + > IntoQuotedOnce<'a, T, Ctx> for F { } impl< - 'a, T, - F: FnOnce(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a, - > FreeVariable for F + Ctx, + F: for<'b> FnOnce( + &'b Ctx, + &mut String, + &mut &'static str, + &mut TokenStream, + &mut CaptureVec, + bool, + ) -> T, + > FreeVariableWithContext for F { - fn to_tokens(self) -> (Option, Option) { + type O = T; + + fn to_tokens(self, ctx: &Ctx) -> (Option, Option) { let mut module_path = String::new(); let mut crate_name = ""; let mut expr_tokens = TokenStream::new(); let mut free_variables = Vec::new(); // this is an uninit value so we can't drop it std::mem::forget(self( + ctx, &mut module_path, &mut crate_name, &mut expr_tokens, @@ -308,16 +437,25 @@ impl< } } -pub trait IntoQuotedMut<'a, T>: - FnMut(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a +pub trait IntoQuotedMut<'a, T, Ctx>: + FnMut(&Ctx, &mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a { } impl< 'a, T, - F: FnMut(&mut String, &mut &'static str, &mut TokenStream, &mut CaptureVec, bool) -> T + 'a, - > IntoQuotedMut<'a, T> for F + Ctx, + F: FnMut( + &Ctx, + &mut String, + &mut &'static str, + &mut TokenStream, + &mut CaptureVec, + bool, + ) -> T + + 'a, + > IntoQuotedMut<'a, T, Ctx> for F { } @@ -327,11 +465,10 @@ pub struct RuntimeData { _phantom: PhantomData, } -impl<'a, T: 'a> Quoted<'a, T> for RuntimeData {} +impl<'a, T: 'a, Ctx> QuotedWithContext<'a, T, Ctx> for RuntimeData {} impl Copy for RuntimeData {} -// TODO(shadaj): relax this to allow for non-copy types impl Clone for RuntimeData { fn clone(&self) -> Self { *self @@ -347,8 +484,10 @@ impl RuntimeData { } } -impl FreeVariable for RuntimeData { - fn to_tokens(self) -> (Option, Option) { +impl FreeVariableWithContext for RuntimeData { + type O = T; + + fn to_tokens(self, _ctx: &Ctx) -> (Option, Option) { let ident = syn::Ident::new(self.ident, Span::call_site()); (None, Some(quote!(#ident))) } diff --git a/stageleft/src/runtime_support.rs b/stageleft/src/runtime_support.rs index cdca23ec078e..2f825152b74d 100644 --- a/stageleft/src/runtime_support.rs +++ b/stageleft/src/runtime_support.rs @@ -5,7 +5,7 @@ use std::mem::MaybeUninit; use proc_macro2::{Span, TokenStream}; use quote::quote; -use crate::Quoted; +use crate::QuotedWithContext; pub fn get_final_crate_name(crate_name: &str) -> TokenStream { let final_crate = proc_macro_crate::crate_name(crate_name) @@ -75,11 +75,29 @@ impl ParseFromLiteral for bool { impl_parse_from_literal_numeric!(i8, i16, i32, i64, i128, isize); impl_parse_from_literal_numeric!(u8, u16, u32, u64, u128, usize); -pub trait FreeVariable { - fn to_tokens(self) -> (Option, Option) +pub trait FreeVariableWithContext { + type O; + + fn to_tokens(self, ctx: &Ctx) -> (Option, Option) where Self: Sized; + fn uninitialized(&self, _ctx: &Ctx) -> Self::O { + #[expect(clippy::uninit_assumed_init, reason = "this code should never run")] + unsafe { + MaybeUninit::uninit().assume_init() + } + } +} + +pub trait FreeVariable: FreeVariableWithContext<(), O = O> { + fn to_tokens(self) -> (Option, Option) + where + Self: Sized, + { + FreeVariableWithContext::to_tokens(self, &()) + } + fn uninitialized(&self) -> O { #[expect(clippy::uninit_assumed_init, reason = "this code should never run")] unsafe { @@ -88,16 +106,20 @@ pub trait FreeVariable { } } +impl> FreeVariable for T {} + macro_rules! impl_free_variable_from_literal_numeric { ($($ty:ty),*) => { $( - impl FreeVariable<$ty> for $ty { - fn to_tokens(self) -> (Option, Option) { + impl FreeVariableWithContext for $ty { + type O = $ty; + + fn to_tokens(self, _ctx: &Ctx) -> (Option, Option) { (None, Some(quote!(#self))) } } - impl<'a> Quoted<'a, $ty> for $ty {} + impl<'a, Ctx> QuotedWithContext<'a, $ty, Ctx> for $ty {} )* }; } @@ -105,8 +127,10 @@ macro_rules! impl_free_variable_from_literal_numeric { impl_free_variable_from_literal_numeric!(i8, i16, i32, i64, i128, isize); impl_free_variable_from_literal_numeric!(u8, u16, u32, u64, u128, usize); -impl FreeVariable<&str> for &str { - fn to_tokens(self) -> (Option, Option) { +impl FreeVariableWithContext for &str { + type O = &'static str; + + fn to_tokens(self, _ctx: &Ctx) -> (Option, Option) { (None, Some(quote!(#self))) } } @@ -142,8 +166,10 @@ pub fn create_import( } } -impl FreeVariable for Import { - fn to_tokens(self) -> (Option, Option) { +impl FreeVariableWithContext for Import { + type O = T; + + fn to_tokens(self, _ctx: &Ctx) -> (Option, Option) { let final_crate_root = get_final_crate_name(self.crate_name); let module_path = syn::parse_str::(self.module_path).unwrap(); diff --git a/stageleft/src/type_name.rs b/stageleft/src/type_name.rs index 1077e54dde30..486fb866f0a5 100644 --- a/stageleft/src/type_name.rs +++ b/stageleft/src/type_name.rs @@ -93,6 +93,24 @@ impl VisitMut for RewriteAlloc { .chain(i.segments.iter().skip(4).cloned()), ), }; + } else if i.segments.iter().take(3).collect::>() + == vec![ + &syn::PathSegment::from(syn::Ident::new("std", Span::call_site())), + &syn::PathSegment::from(syn::Ident::new("vec", Span::call_site())), + &syn::PathSegment::from(syn::Ident::new("into_iter", Span::call_site())), + ] + { + *i = syn::Path { + leading_colon: i.leading_colon, + segments: syn::punctuated::Punctuated::from_iter( + vec![ + syn::PathSegment::from(syn::Ident::new("std", Span::call_site())), + syn::PathSegment::from(syn::Ident::new("vec", Span::call_site())), + ] + .into_iter() + .chain(i.segments.iter().skip(3).cloned()), + ), + }; } else if i.segments.iter().take(3).collect::>() == vec![ &syn::PathSegment::from(syn::Ident::new("tokio", Span::call_site())), @@ -134,10 +152,16 @@ impl VisitMut for RewriteAlloc { syn::parse2(get_final_crate_name(final_name)).unwrap(); i.segments.insert(1, parse_quote!(__staged)); + } else { + syn::visit_mut::visit_path_mut(self, i); + return; } + } else { + syn::visit_mut::visit_path_mut(self, i); + return; } - syn::visit_mut::visit_path_mut(self, i); + self.visit_path_mut(i); } } diff --git a/stageleft_macro/CHANGELOG.md b/stageleft_macro/CHANGELOG.md index 8ca48945af54..ba0e9b7679f2 100644 --- a/stageleft_macro/CHANGELOG.md +++ b/stageleft_macro/CHANGELOG.md @@ -5,8 +5,73 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v0.4.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - add ability to have staged flows inside unit tests + Whenever a Hydroflow+ program is compiled, it depends on a generated + `__staged` module, which contains the entire contents of the crate but + with every type / function made `pub` and exported, so that the compiled + UDFs can resolve local references appropriately. + + Previously, we would not do this for `#[cfg(test)]` modules, since they + may use `dev-dependencies` and therefore the generated module may fail + to compile when not in test mode. To solve this, when running a unit + test (marked with `hydroflow_plus::deploy::init_test()`) that uses + trybuild, we emit a version of the `__staged` module with `#[cfg(test)]` + modules included _into the generated trybuild sources_ because we can + guarantee via trybuild that the appropriate `dev-dependencies` are + available. + + This by itself allows crates depending on `hydroflow_plus` to have local + unit tests with Hydroflow+ logic inside them. But we also want to use + this support for unit tests inside `hydroflow_plus` itself. To enable + that, we eliminate the `hydroflow_plus_deploy` crate and move its + contents directly to `hydroflow_plus` itself so that we can access the + trybuild machinery without incurring a circular dependency. + + Also fixes #1408 + - splice UDFs with type hints to avoid inference failures + +### Bug Fixes + + - support tuple patterns + +### Commit Statistics + + + + - 4 commits contributed to the release. + - 69 days passed between releases. + - 4 commits were understood as [conventional](https://www.conventionalcommits.org). + - 4 unique issues were worked on: [#1434](https://github.com/hydro-project/hydroflow/issues/1434), [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1445](https://github.com/hydro-project/hydroflow/issues/1445), [#1450](https://github.com/hydro-project/hydroflow/issues/1450) + +### Commit Details + + + +
view details + + * **[#1434](https://github.com/hydro-project/hydroflow/issues/1434)** + - Splice UDFs with type hints to avoid inference failures ([`60d9bec`](https://github.com/hydro-project/hydroflow/commit/60d9becaf0b67f9819316ce6d76bd867f7d46505)) + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1445](https://github.com/hydro-project/hydroflow/issues/1445)** + - Support tuple patterns ([`486dfbe`](https://github.com/hydro-project/hydroflow/commit/486dfbe1fab51f1b7c7aa03a51e6e9e4e427b912)) + * **[#1450](https://github.com/hydro-project/hydroflow/issues/1450)** + - Add ability to have staged flows inside unit tests ([`afe78c3`](https://github.com/hydro-project/hydroflow/commit/afe78c343658472513b34d28658634b253148aee)) +
+ ## v0.3.0 (2024-08-30) + + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -26,7 +91,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 3 commits contributed to the release. + - 4 commits contributed to the release. + - 97 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 3 unique issues were worked on: [#1423](https://github.com/hydro-project/hydroflow/issues/1423), [#1426](https://github.com/hydro-project/hydroflow/issues/1426), [#1428](https://github.com/hydro-project/hydroflow/issues/1428) @@ -42,6 +108,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove `lazy_static` dependency ([`461ae84`](https://github.com/hydro-project/hydroflow/commit/461ae845c6c6506c733be6287eeefe6e3beca52c)) * **[#1428](https://github.com/hydro-project/hydroflow/issues/1428)** - Cleanup doc comments for clippy latest ([`f5f1eb0`](https://github.com/hydro-project/hydroflow/commit/f5f1eb0c612f5c0c1752360d972ef6853c5e12f0)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## v0.2.0 (2024-05-24) @@ -60,6 +128,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 48 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1104](https://github.com/hydro-project/hydroflow/issues/1104), [#1151](https://github.com/hydro-project/hydroflow/issues/1151) @@ -105,6 +174,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 5 commits contributed to the release. + - 67 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1090](https://github.com/hydro-project/hydroflow/issues/1090), [#1100](https://github.com/hydro-project/hydroflow/issues/1100), [#1117](https://github.com/hydro-project/hydroflow/issues/1117), [#1124](https://github.com/hydro-project/hydroflow/issues/1124) diff --git a/stageleft_macro/Cargo.toml b/stageleft_macro/Cargo.toml index 6912ac8471f1..b9f1b3fba3f7 100644 --- a/stageleft_macro/Cargo.toml +++ b/stageleft_macro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stageleft_macro" publish = true -version = "0.3.0" +version = "0.4.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/stageleft_macro/" @@ -19,7 +19,7 @@ quote = "1.0.35" syn = { version = "2.0.46", features = [ "parsing", "extra-traits", "visit" ] } proc-macro2 = "1.0.74" proc-macro-crate = "1.0.0" -sha256 = "1.0.0" +sha2 = "0.10.0" [dev-dependencies] insta = "1.39" diff --git a/stageleft_macro/src/lib.rs b/stageleft_macro/src/lib.rs index c6972c694c23..b36241554b9d 100644 --- a/stageleft_macro/src/lib.rs +++ b/stageleft_macro/src/lib.rs @@ -1,5 +1,6 @@ use proc_macro2::{Punct, Spacing, Span, TokenStream}; use quote::{quote, quote_spanned, ToTokens}; +use sha2::{Digest, Sha256}; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{AngleBracketedGenericArguments, Token, Type}; @@ -339,7 +340,7 @@ pub fn entry( .chars() .filter(|c| c.is_alphanumeric()) .collect::(); - let input_hash = "macro_".to_string() + &sha256::digest(input_contents); + let input_hash = "macro_".to_string() + &format!("{:X}", Sha256::digest(input_contents)); let input_hash_ident = syn::Ident::new(&input_hash, Span::call_site()); let input_hash_impl_ident = syn::Ident::new(&(input_hash + "_impl"), Span::call_site()); @@ -353,6 +354,7 @@ pub fn entry( #[cfg_attr(not(stageleft_macro), allow(unused))] #[cfg_attr(not(stageleft_macro), doc(hidden))] + #[allow(non_snake_case)] pub(crate) fn #input_hash_impl_ident(input: #root::internal::TokenStream) -> #root::internal::TokenStream { let input_parsed = #root::internal::syn::parse::Parser::parse( #root::internal::syn::punctuated::Punctuated::<#root::internal::syn::Expr, #root::internal::syn::Token![,]>::parse_terminated, @@ -370,7 +372,7 @@ pub fn entry( #root::runtime_support::set_macro_to_crate(macro_crate_name, final_crate_name); let output_core = { - #root::Quoted::splice_untyped(#input_name #passed_generics(#root::QuotedContext::create(), #(#params_to_pass),*)) + #root::QuotedWithContext::splice_untyped_ctx(#input_name #passed_generics(#root::QuotedContext::create(), #(#params_to_pass),*), &()) }; let final_crate_root = #root::runtime_support::get_final_crate_name(final_crate_name); diff --git a/stageleft_macro/src/quote_impl/free_variable/mod.rs b/stageleft_macro/src/quote_impl/free_variable/mod.rs index d323b26ea141..23c6ba85f19c 100644 --- a/stageleft_macro/src/quote_impl/free_variable/mod.rs +++ b/stageleft_macro/src/quote_impl/free_variable/mod.rs @@ -2,6 +2,7 @@ use std::collections::{BTreeSet, HashSet}; mod prelude; use prelude::is_prelude; +use quote::ToTokens; #[derive(Debug)] pub struct ScopeStack { @@ -64,25 +65,25 @@ pub struct FreeVariableVisitor { pub current_scope: ScopeStack, } -impl<'ast> syn::visit::Visit<'ast> for FreeVariableVisitor { - fn visit_expr_closure(&mut self, i: &'ast syn::ExprClosure) { +impl syn::visit_mut::VisitMut for FreeVariableVisitor { + fn visit_expr_closure_mut(&mut self, i: &mut syn::ExprClosure) { self.current_scope.push(); - i.inputs.iter().for_each(|input| { - self.visit_pat(input); + i.inputs.iter_mut().for_each(|input| { + self.visit_pat_mut(input); }); - syn::visit::visit_expr_closure(self, i); + syn::visit_mut::visit_expr_closure_mut(self, i); self.current_scope.pop(); } - fn visit_item_fn(&mut self, i: &'ast syn::ItemFn) { + fn visit_item_fn_mut(&mut self, i: &mut syn::ItemFn) { self.current_scope.push(); - syn::visit::visit_item_fn(self, i); + syn::visit_mut::visit_item_fn_mut(self, i); self.current_scope.pop(); } - fn visit_generic_param(&mut self, i: &'ast syn::GenericParam) { + fn visit_generic_param_mut(&mut self, i: &mut syn::GenericParam) { match i { syn::GenericParam::Type(type_param) => { self.current_scope.insert_type(type_param.ident.clone()); @@ -97,140 +98,157 @@ impl<'ast> syn::visit::Visit<'ast> for FreeVariableVisitor { } } - fn visit_block(&mut self, i: &'ast syn::Block) { + fn visit_block_mut(&mut self, i: &mut syn::Block) { self.current_scope.push(); - syn::visit::visit_block(self, i); + syn::visit_mut::visit_block_mut(self, i); self.current_scope.pop(); } - fn visit_local(&mut self, i: &'ast syn::Local) { - i.init.iter().for_each(|init| { - syn::visit::visit_local_init(self, init); + fn visit_local_mut(&mut self, i: &mut syn::Local) { + i.init.iter_mut().for_each(|init| { + syn::visit_mut::visit_local_init_mut(self, init); }); - match &i.pat { + match &mut i.pat { syn::Pat::Ident(pat_ident) => { self.current_scope.insert_term(pat_ident.ident.clone()); } syn::Pat::Type(pat_type) => { - self.visit_pat(&pat_type.pat); + self.visit_pat_mut(&mut pat_type.pat); } syn::Pat::Wild(_) => { // Do nothing } syn::Pat::Tuple(pat_tuple) => { - for el in &pat_tuple.elems { - self.visit_pat(el); + for el in &mut pat_tuple.elems { + self.visit_pat_mut(el); } } _ => panic!("Local variables must be identifiers, got {:?}", i.pat), } } - fn visit_ident(&mut self, i: &'ast proc_macro2::Ident) { + fn visit_ident_mut(&mut self, i: &mut proc_macro2::Ident) { if !self.current_scope.contains_term(i) { self.free_variables.insert(i.clone()); + *i = syn::Ident::new(&format!("{}__free", i), i.span()); } } - fn visit_lifetime(&mut self, i: &'ast syn::Lifetime) { + fn visit_lifetime_mut(&mut self, i: &mut syn::Lifetime) { if !self.current_scope.contains_type(&i.ident) { self.free_variables.insert(i.ident.clone()); + i.ident = syn::Ident::new(&format!("{}__free", i.ident), i.ident.span()); } } - fn visit_path(&mut self, i: &'ast syn::Path) { + fn visit_path_mut(&mut self, i: &mut syn::Path) { if i.leading_colon.is_none() && !is_prelude(&i.segments.first().unwrap().ident) { - let node = i.segments.first().unwrap(); - if i.segments.len() == 1 && !self.current_scope.contains_term(&node.ident) { + let one_segment = i.segments.len() == 1; + let node = i.segments.first_mut().unwrap(); + if one_segment && !self.current_scope.contains_term(&node.ident) { self.free_variables.insert(node.ident.clone()); + node.ident = syn::Ident::new(&format!("{}__free", node.ident), node.ident.span()); } } - for node in i.segments.iter() { - self.visit_path_arguments(&node.arguments); + for node in i.segments.iter_mut() { + self.visit_path_arguments_mut(&mut node.arguments); } } - fn visit_arm(&mut self, i: &'ast syn::Arm) { + fn visit_arm_mut(&mut self, i: &mut syn::Arm) { self.current_scope.push(); - syn::visit::visit_arm(self, i); + syn::visit_mut::visit_arm_mut(self, i); self.current_scope.pop(); } - fn visit_field_pat(&mut self, i: &'ast syn::FieldPat) { - for it in &i.attrs { - self.visit_attribute(it); + fn visit_field_pat_mut(&mut self, i: &mut syn::FieldPat) { + for it in &mut i.attrs { + self.visit_attribute_mut(it); } - self.visit_pat(&i.pat); + self.visit_pat_mut(&mut i.pat); } - fn visit_pat_ident(&mut self, i: &'ast syn::PatIdent) { + fn visit_pat_ident_mut(&mut self, i: &mut syn::PatIdent) { self.current_scope.insert_term(i.ident.clone()); } - fn visit_expr_method_call(&mut self, i: &'ast syn::ExprMethodCall) { - syn::visit::visit_expr(self, &i.receiver); - for arg in &i.args { - self.visit_expr(arg); + fn visit_expr_method_call_mut(&mut self, i: &mut syn::ExprMethodCall) { + syn::visit_mut::visit_expr_mut(self, &mut i.receiver); + for arg in &mut i.args { + self.visit_expr_mut(arg); } } - fn visit_type(&mut self, _: &'ast syn::Type) {} + fn visit_type_mut(&mut self, _: &mut syn::Type) {} - fn visit_expr_struct(&mut self, node: &'ast syn::ExprStruct) { - for it in &node.attrs { - self.visit_attribute(it); + fn visit_expr_struct_mut(&mut self, node: &mut syn::ExprStruct) { + for it in &mut node.attrs { + self.visit_attribute_mut(it); } - if let Some(it) = &node.qself { - self.visit_qself(it); + if let Some(it) = &mut node.qself { + self.visit_qself_mut(it); } // No need to capture the struct path // self.visit_path(&node.path); - for el in syn::punctuated::Punctuated::pairs(&node.fields) { - let it = el.value(); - self.visit_expr(&it.expr); + for el in syn::punctuated::Punctuated::pairs_mut(&mut node.fields) { + let it = el.into_value(); + self.visit_expr_mut(&mut it.expr); } - if let Some(it) = &node.rest { - self.visit_expr(it); + if let Some(it) = &mut node.rest { + self.visit_expr_mut(it); } } - fn visit_expr_field(&mut self, i: &'ast syn::ExprField) { - self.visit_expr(&i.base); + fn visit_expr_field_mut(&mut self, i: &mut syn::ExprField) { + self.visit_expr_mut(&mut i.base); } - fn visit_macro(&mut self, i: &'ast syn::Macro) { + fn visit_macro_mut(&mut self, i: &mut syn::Macro) { // TODO(shadaj): emit a warning if our guess at parsing fails match i.delimiter { - syn::MacroDelimiter::Paren(_binding_0) => i - .parse_body_with( - syn::punctuated::Punctuated::::parse_terminated, - ) - .ok() - .iter() - .flatten() - .for_each(|expr| { - self.visit_expr(expr); - }), - syn::MacroDelimiter::Brace(_binding_0) => i - .parse_body_with(syn::Block::parse_within) - .ok() - .iter() - .flatten() - .for_each(|stmt| { - self.visit_stmt(stmt); - }), - syn::MacroDelimiter::Bracket(_binding_0) => i - .parse_body_with( - syn::punctuated::Punctuated::::parse_terminated, - ) - .ok() - .iter() - .flatten() - .for_each(|expr| { - self.visit_expr(expr); - }), + syn::MacroDelimiter::Paren(_binding_0) => { + i.tokens = i + .parse_body_with( + syn::punctuated::Punctuated::::parse_terminated, + ) + .ok() + .map(|mut exprs| { + for arg in &mut exprs { + self.visit_expr_mut(arg); + } + exprs.to_token_stream() + }) + .unwrap_or(i.tokens.clone()); + } + syn::MacroDelimiter::Brace(_binding_0) => { + i.tokens = i + .parse_body_with(syn::Block::parse_within) + .ok() + .map(|mut stmts| { + for stmt in &mut stmts { + self.visit_stmt_mut(stmt); + } + syn::punctuated::Punctuated::::from_iter(stmts) + .to_token_stream() + }) + .unwrap_or(i.tokens.clone()); + } + syn::MacroDelimiter::Bracket(_binding_0) => { + i.tokens = i + .parse_body_with( + syn::punctuated::Punctuated::::parse_terminated, + ) + .ok() + .map(|mut exprs| { + for arg in &mut exprs { + self.visit_expr_mut(arg); + } + exprs.to_token_stream() + }) + .unwrap_or(i.tokens.clone()); + } } } } diff --git a/stageleft_macro/src/quote_impl/mod.rs b/stageleft_macro/src/quote_impl/mod.rs index f26b533be7d3..475999680ee1 100644 --- a/stageleft_macro/src/quote_impl/mod.rs +++ b/stageleft_macro/src/quote_impl/mod.rs @@ -1,32 +1,34 @@ use proc_macro2::{Span, TokenStream}; use quote::{quote, ToTokens}; -use syn::visit::Visit; +use syn::visit_mut::VisitMut; use self::free_variable::FreeVariableVisitor; mod free_variable; -pub fn q_impl(root: TokenStream, expr: syn::Expr) -> TokenStream { +pub fn q_impl(root: TokenStream, mut expr: syn::Expr) -> TokenStream { let mut visitor = FreeVariableVisitor::default(); - visitor.visit_expr(&expr); + visitor.visit_expr_mut(&mut expr); let unitialized_free_variables = visitor.free_variables.iter().map(|i| { - let mut i_without_span = i.clone(); - i_without_span.set_span(Span::call_site()); - let ident_str = i.to_string(); + let ident_str = format!("{}__free", i); + + let i_renamed = syn::Ident::new(&ident_str, i.span()); + let mut i_outer = i.clone(); + i_outer.set_span(Span::call_site()); + quote!( #[allow(unused, non_upper_case_globals, non_snake_case)] - let #i = { - let _out = ::#root::runtime_support::FreeVariable::uninitialized(&#i_without_span); - _vec_to_set.push((#ident_str.to_string(), ::#root::runtime_support::FreeVariable::to_tokens(#i_without_span))); + let #i_renamed = { + let _out = ::#root::runtime_support::FreeVariableWithContext::uninitialized(&#i_outer, __stageleft_ctx); + _vec_to_set.push((#ident_str.to_string(), ::#root::runtime_support::FreeVariableWithContext::to_tokens(#i_outer, __stageleft_ctx))); _out }; ) }); let uninit_forgets = visitor.free_variables.iter().map(|i| { - let mut i_without_span = i.clone(); - i_without_span.set_span(Span::call_site()); + let i_without_span = syn::Ident::new(&format!("{}__free", i), Span::call_site()); quote!( #[allow(unused, non_upper_case_globals, non_snake_case)] ::std::mem::forget(#i_without_span); @@ -38,7 +40,7 @@ pub fn q_impl(root: TokenStream, expr: syn::Expr) -> TokenStream { syn::parse_str(&expr.clone().into_token_stream().to_string()).unwrap(); quote!({ - move |set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut #root::internal::TokenStream, _vec_to_set: &mut #root::internal::CaptureVec, run: bool| { + move |__stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut #root::internal::TokenStream, _vec_to_set: &mut #root::internal::CaptureVec, run: bool| { #(#unitialized_free_variables;)* *set_mod = module_path!().to_string(); diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local@macro_tokens.snap index 7a48e3cdfdef..07671ec33863 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,16 +32,17 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - (x + 2) + (x + 2) + (x__free + 2) + (x__free + 2) }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } } - #[allow(unreachable_code, unused_qualifications)] { (x + 2) + (x + 2) } + #[allow(unreachable_code, unused_qualifications)] + { (x__free + 2) + (x__free + 2) } } } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block@macro_tokens.snap index b5f826004f69..3446a20152f0 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,11 +32,11 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - { let _ = x + 2; let _ = x + 2; } + { let _ = x__free + 2; let _ = x__free + 2; } }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } @@ -37,8 +44,8 @@ fn main() { #[allow(unreachable_code, unused_qualifications)] { { - let _ = x + 2; - let _ = x + 2; + let _ = x__free + 2; + let _ = x__free + 2; } } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block_let@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block_let@macro_tokens.snap index 84a8c67dea1d..cecf987e32d9 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block_let@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_copy_local_block_let@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,11 +32,11 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - { let x = x + 2; let _ = x + 2; } + { let x = x__free + 2; let _ = x + 2; } }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } @@ -37,7 +44,7 @@ fn main() { #[allow(unreachable_code, unused_qualifications)] { { - let x = x + 2; + let x = x__free + 2; let _ = x + 2; } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_in_macro@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_in_macro@macro_tokens.snap index 13d47903d640..bca5e0f6058b 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_in_macro@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_in_macro@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,16 +32,16 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - dbg!(x) + dbg!(x__free) }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } } - #[allow(unreachable_code, unused_qualifications)] { dbg!(x) } + #[allow(unreachable_code, unused_qualifications)] { dbg!(x__free) } } } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local@macro_tokens.snap index 1ba7491cf55f..9ac5fe90be4e 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,16 +32,16 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - x + 2 + x__free + 2 }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } } - #[allow(unreachable_code, unused_qualifications)] { x + 2 } + #[allow(unreachable_code, unused_qualifications)] { x__free + 2 } } } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local_mut@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local_mut@macro_tokens.snap index 70bb2d59ba99..90141a59dd71 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local_mut@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__capture_local_mut@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, @@ -12,12 +13,18 @@ fn main() { run: bool| { #[allow(unused, non_upper_case_globals, non_snake_case)] - let x = { - let _out = ::stageleft::runtime_support::FreeVariable::uninitialized(&x); + let x__free = { + let _out = ::stageleft::runtime_support::FreeVariableWithContext::uninitialized( + &x, + __stageleft_ctx, + ); _vec_to_set .push(( - "x".to_string(), - ::stageleft::runtime_support::FreeVariable::to_tokens(x), + "x__free".to_string(), + ::stageleft::runtime_support::FreeVariableWithContext::to_tokens( + x, + __stageleft_ctx, + ), )); _out }; @@ -25,16 +32,16 @@ fn main() { *set_crate_name = option_env!("STAGELEFT_FINAL_CRATE_NAME") .unwrap_or(env!("CARGO_PKG_NAME")); *set_tokens = stageleft::internal::quote! { - x += 2 + x__free += 2 }; if !run { #[allow(unused, non_upper_case_globals, non_snake_case)] - ::std::mem::forget(x); + ::std::mem::forget(x__free); unsafe { return ::std::mem::MaybeUninit::uninit().assume_init(); } } - #[allow(unreachable_code, unused_qualifications)] { x += 2 } + #[allow(unreachable_code, unused_qualifications)] { x__free += 2 } } } } diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_enum_creation@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_enum_creation@macro_tokens.snap index 819cbbd28c3c..1cae8b08b7d5 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_enum_creation@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_enum_creation@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_local@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_local@macro_tokens.snap index 7169ceb62557..3130580842c0 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_local@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_local@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_struct_creation@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_struct_creation@macro_tokens.snap index e72911de50bc..298d31b1ed83 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_struct_creation@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__non_capture_struct_creation@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-2.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-2.snap index 236653f1143e..a2cc7a1d4240 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-2.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-2.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-3.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-3.snap index a7c8bf5a87af..041b3a8a8ddd 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-3.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-3.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-4.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-4.snap index 3a7639ba687a..cca0039f9bfd 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-4.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens-4.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens.snap index 06b3866d73bd..5f02ee3b0f6d 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__prelude_enum_variants@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__simple@macro_tokens.snap b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__simple@macro_tokens.snap index d9143ddb3d98..c80aa9720ce9 100644 --- a/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__simple@macro_tokens.snap +++ b/stageleft_macro/src/quote_impl/snapshots/stageleft_macro__quote_impl__tests__simple@macro_tokens.snap @@ -5,6 +5,7 @@ expression: "prettyplease :: unparse(& wrapped)" fn main() { { move | + __stageleft_ctx: &_, set_mod: &mut String, set_crate_name: &mut &'static str, set_tokens: &mut stageleft::internal::TokenStream, diff --git a/stageleft_test/Cargo.toml b/stageleft_test/Cargo.toml index ef0f6b0113b1..30dbf948227a 100644 --- a/stageleft_test/Cargo.toml +++ b/stageleft_test/Cargo.toml @@ -11,8 +11,8 @@ workspace = true stageleft_devel = [] [dependencies] -stageleft = { path = "../stageleft", version = "^0.4.0" } +stageleft = { path = "../stageleft", version = "^0.5.0" } stageleft_test_macro = { path = "../stageleft_test_macro" } [build-dependencies] -stageleft_tool = { path = "../stageleft_tool", version = "^0.3.0" } +stageleft_tool = { path = "../stageleft_tool", version = "^0.4.0" } diff --git a/stageleft_test_macro/Cargo.toml b/stageleft_test_macro/Cargo.toml index f576ae78d027..57368231137a 100644 --- a/stageleft_test_macro/Cargo.toml +++ b/stageleft_test_macro/Cargo.toml @@ -12,7 +12,7 @@ proc-macro = true path = "../stageleft_test/src/lib.rs" [dependencies] -stageleft = { path = "../stageleft", version = "^0.4.0" } +stageleft = { path = "../stageleft", version = "^0.5.0" } [build-dependencies] -stageleft_tool = { path = "../stageleft_tool", version = "^0.3.0" } +stageleft_tool = { path = "../stageleft_tool", version = "^0.4.0" } diff --git a/stageleft_tool/CHANGELOG.md b/stageleft_tool/CHANGELOG.md index 4a3c7616eb14..8614dcf47336 100644 --- a/stageleft_tool/CHANGELOG.md +++ b/stageleft_tool/CHANGELOG.md @@ -1,7 +1,74 @@ +## v0.4.0 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - add ability to have staged flows inside unit tests + Whenever a Hydroflow+ program is compiled, it depends on a generated + `__staged` module, which contains the entire contents of the crate but + with every type / function made `pub` and exported, so that the compiled + UDFs can resolve local references appropriately. + + Previously, we would not do this for `#[cfg(test)]` modules, since they + may use `dev-dependencies` and therefore the generated module may fail + to compile when not in test mode. To solve this, when running a unit + test (marked with `hydroflow_plus::deploy::init_test()`) that uses + trybuild, we emit a version of the `__staged` module with `#[cfg(test)]` + modules included _into the generated trybuild sources_ because we can + guarantee via trybuild that the appropriate `dev-dependencies` are + available. + + This by itself allows crates depending on `hydroflow_plus` to have local + unit tests with Hydroflow+ logic inside them. But we also want to use + this support for unit tests inside `hydroflow_plus` itself. To enable + that, we eliminate the `hydroflow_plus_deploy` crate and move its + contents directly to `hydroflow_plus` itself so that we can access the + trybuild machinery without incurring a circular dependency. + + Also fixes #1408 + +### Bug Fixes + + - properly handle `crate::` imports + +### Refactor + + - complete split into leader election and sequencing phases + +### Commit Statistics + + + + - 4 commits contributed to the release. + - 69 days passed between releases. + - 4 commits were understood as [conventional](https://www.conventionalcommits.org). + - 4 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1450](https://github.com/hydro-project/hydroflow/issues/1450), [#1486](https://github.com/hydro-project/hydroflow/issues/1486), [#1527](https://github.com/hydro-project/hydroflow/issues/1527) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1450](https://github.com/hydro-project/hydroflow/issues/1450)** + - Add ability to have staged flows inside unit tests ([`afe78c3`](https://github.com/hydro-project/hydroflow/commit/afe78c343658472513b34d28658634b253148aee)) + * **[#1486](https://github.com/hydro-project/hydroflow/issues/1486)** + - Complete split into leader election and sequencing phases ([`8b7b1c6`](https://github.com/hydro-project/hydroflow/commit/8b7b1c60fd33b78f9a4b0873bbbd150260ae2ad5)) + * **[#1527](https://github.com/hydro-project/hydroflow/issues/1527)** + - Properly handle `crate::` imports ([`2faffdb`](https://github.com/hydro-project/hydroflow/commit/2faffdbf2cc886da22e496df64f46aefa380766c)) +
+ ## v0.3.0 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -17,7 +84,8 @@ - - 2 commits contributed to the release. + - 3 commits contributed to the release. + - 97 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1398](https://github.com/hydro-project/hydroflow/issues/1398), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -31,6 +99,8 @@ - Use trybuild to compile subgraph binaries ([`46a8a2c`](https://github.com/hydro-project/hydroflow/commit/46a8a2cb08732bb21096e824bc4542d208c68fb2)) * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## v0.2.0 (2024-05-24) @@ -52,6 +122,7 @@ - 3 commits contributed to the release. + - 44 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1104](https://github.com/hydro-project/hydroflow/issues/1104), [#1192](https://github.com/hydro-project/hydroflow/issues/1192) @@ -96,6 +167,7 @@ - 6 commits contributed to the release. + - 71 days passed between releases. - 4 commits were understood as [conventional](https://www.conventionalcommits.org). - 4 unique issues were worked on: [#1083](https://github.com/hydro-project/hydroflow/issues/1083), [#1090](https://github.com/hydro-project/hydroflow/issues/1090), [#1098](https://github.com/hydro-project/hydroflow/issues/1098), [#1140](https://github.com/hydro-project/hydroflow/issues/1140) diff --git a/stageleft_tool/Cargo.toml b/stageleft_tool/Cargo.toml index bcaae60d8f7a..cca49aa24caf 100644 --- a/stageleft_tool/Cargo.toml +++ b/stageleft_tool/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "stageleft_tool" publish = true -version = "0.3.0" +version = "0.4.0" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/stageleft_macro/" @@ -18,4 +18,4 @@ syn-inline-mod = "0.6.0" quote = "1.0.35" syn = { version = "2.0.46", features = [ "parsing", "extra-traits", "visit" ] } proc-macro2 = "1.0.74" -sha256 = "1.0.0" +sha2 = "0.10.0" diff --git a/stageleft_tool/src/lib.rs b/stageleft_tool/src/lib.rs index 35bbff0f0f06..2af956a2e935 100644 --- a/stageleft_tool/src/lib.rs +++ b/stageleft_tool/src/lib.rs @@ -4,9 +4,10 @@ use std::{env, fs}; use proc_macro2::Span; use quote::ToTokens; -use syn::parse_quote; +use sha2::{Digest, Sha256}; use syn::visit::Visit; use syn::visit_mut::VisitMut; +use syn::{parse_quote, UsePath}; struct GenMacroVistor { exported_macros: BTreeSet<(String, String)>, @@ -41,7 +42,7 @@ impl<'a> Visit<'a> for GenMacroVistor { .chars() .filter(|c| c.is_alphanumeric()) .collect::(); - let contents_hash = sha256::digest(contents); + let contents_hash = format!("{:X}", Sha256::digest(contents)); self.exported_macros .insert((contents_hash, cur_path.to_token_stream().to_string())); } @@ -72,7 +73,7 @@ pub fn gen_macro(staged_path: &Path, crate_name: &str) { let proc_macro_wrapper: syn::ItemFn = parse_quote!( #[proc_macro] - #[expect(unused_qualifications, reason = "generated code")] + #[expect(unused_qualifications, non_snake_case, reason = "generated code")] pub fn #underscored_path(input: ::proc_macro::TokenStream) -> ::proc_macro::TokenStream { let input = ::stageleft::internal::TokenStream::from(input); let out = #exported_from_parsed::#underscored_path_impl(input); @@ -125,6 +126,10 @@ impl VisitMut for GenFinalPubVistor { syn::visit_mut::visit_item_enum_mut(self, i); } + fn visit_variant_mut(&mut self, _i: &mut syn::Variant) { + // variant fields do not have visibility modifiers + } + fn visit_item_struct_mut(&mut self, i: &mut syn::ItemStruct) { i.vis = parse_quote!(pub); syn::visit_mut::visit_item_struct_mut(self, i); @@ -140,6 +145,18 @@ impl VisitMut for GenFinalPubVistor { syn::visit_mut::visit_item_use_mut(self, i); } + fn visit_use_path_mut(&mut self, i: &mut UsePath) { + if i.ident == "crate" { + i.tree = Box::new(syn::UseTree::Path(UsePath { + ident: parse_quote!(__staged), + colon2_token: Default::default(), + tree: i.tree.clone(), + })); + } + + syn::visit_mut::visit_use_path_mut(self, i); + } + fn visit_item_mod_mut(&mut self, i: &mut syn::ItemMod) { let is_runtime_or_test = i.attrs.iter().any(|a| { a.path().to_token_stream().to_string() == "stageleft :: runtime" @@ -228,6 +245,18 @@ impl VisitMut for GenFinalPubVistor { #[cfg(stageleft_macro)] #e ); + } else if let syn::Item::Static(e) = i { + if matches!(e.vis, syn::Visibility::Public(_)) { + let e_name = &e.ident; + *i = parse_quote!(pub use #cur_path::#e_name;); + return; + } + } else if let syn::Item::Const(e) = i { + if matches!(e.vis, syn::Visibility::Public(_)) { + let e_name = &e.ident; + *i = parse_quote!(pub use #cur_path::#e_name;); + return; + } } } diff --git a/template/hydroflow_plus/Cargo.toml b/template/hydroflow_plus/Cargo.toml index 2c521b6155d6..1544bce2112e 100644 --- a/template/hydroflow_plus/Cargo.toml +++ b/template/hydroflow_plus/Cargo.toml @@ -23,3 +23,6 @@ hydroflow_plus = { git = "{{ hydroflow_git | default: 'https://github.com/hydro- "deploy", ] } tokio-stream = { version = "0.1.3", default-features = false } + +[lints.rust] +unsafe_op_in_unsafe_fn = "warn" diff --git a/template/hydroflow_plus/README.md b/template/hydroflow_plus/README.md index d999d91e6a8f..a4f1058c359d 100644 --- a/template/hydroflow_plus/README.md +++ b/template/hydroflow_plus/README.md @@ -7,16 +7,15 @@ cargo generate gh:hydro-project/hydroflow template/hydroflow_plus cd ``` -After `cd`ing into the workspace, ensure the correct nightly version of rust is installed: -```bash -rustup update -``` +After `cd`ing into the workspace, run the sample tests Then test the project: ```bash cargo test ``` +To learn more about the template, see the [Hydroflow+ Quickstart](https://hydro.run/docs/hydroflow_plus/quickstart/first-dataflow). + ## Project Structure The template includes a sample program `first_ten_distributed`. diff --git a/template/hydroflow_plus/examples/first_ten.rs b/template/hydroflow_plus/examples/first_ten.rs new file mode 100644 index 000000000000..51d614431fed --- /dev/null +++ b/template/hydroflow_plus/examples/first_ten.rs @@ -0,0 +1,16 @@ +use hydro_deploy::Deployment; + +#[tokio::main] +async fn main() { + let mut deployment = Deployment::new(); + + let flow = hydroflow_plus::FlowBuilder::new(); + let process = flow.process(); + hydroflow_plus_template::first_ten::first_ten(&process); + + let _nodes = flow + .with_process(&process, deployment.Localhost()) + .deploy(&mut deployment); + + deployment.run_ctrl_c().await.unwrap(); +} diff --git a/template/hydroflow_plus/examples/first_ten_cluster.rs b/template/hydroflow_plus/examples/first_ten_cluster.rs new file mode 100644 index 000000000000..c421570fad88 --- /dev/null +++ b/template/hydroflow_plus/examples/first_ten_cluster.rs @@ -0,0 +1,18 @@ +use hydro_deploy::Deployment; + +#[tokio::main] +async fn main() { + let mut deployment = Deployment::new(); + + let flow = hydroflow_plus::FlowBuilder::new(); + let leader = flow.process(); + let workers = flow.cluster(); + hydroflow_plus_template::first_ten_cluster::first_ten_cluster(&leader, &workers); + + let _nodes = flow + .with_process(&leader, deployment.Localhost()) + .with_cluster(&workers, vec![deployment.Localhost(); 4]) + .deploy(&mut deployment); + + deployment.run_ctrl_c().await.unwrap(); +} diff --git a/template/hydroflow_plus/examples/first_ten_distributed.rs b/template/hydroflow_plus/examples/first_ten_distributed.rs index 6cae922a757d..a84f542c2ad1 100644 --- a/template/hydroflow_plus/examples/first_ten_distributed.rs +++ b/template/hydroflow_plus/examples/first_ten_distributed.rs @@ -1,17 +1,17 @@ use hydro_deploy::Deployment; -use hydroflow_plus::deploy::TrybuildHost; #[tokio::main] async fn main() { let mut deployment = Deployment::new(); let flow = hydroflow_plus::FlowBuilder::new(); - let (p1, p2) = hydroflow_plus_template::first_ten_distributed::first_ten_distributed(&flow); + let p1 = flow.process(); + let p2 = flow.process(); + hydroflow_plus_template::first_ten_distributed::first_ten_distributed(&p1, &p2); let _nodes = flow - .with_default_optimize() - .with_process(&p1, TrybuildHost::new(deployment.Localhost())) - .with_process(&p2, TrybuildHost::new(deployment.Localhost())) + .with_process(&p1, deployment.Localhost()) + .with_process(&p2, deployment.Localhost()) .deploy(&mut deployment); deployment.run_ctrl_c().await.unwrap(); diff --git a/template/hydroflow_plus/examples/first_ten_distributed_gcp.rs b/template/hydroflow_plus/examples/first_ten_distributed_gcp.rs index 3caf775ce50d..1386023e4b95 100644 --- a/template/hydroflow_plus/examples/first_ten_distributed_gcp.rs +++ b/template/hydroflow_plus/examples/first_ten_distributed_gcp.rs @@ -18,10 +18,11 @@ async fn main() { let vpc = Arc::new(RwLock::new(GcpNetwork::new(&gcp_project, None))); let flow = hydroflow_plus::FlowBuilder::new(); - let (p1, p2) = hydroflow_plus_template::first_ten_distributed::first_ten_distributed(&flow); + let p1 = flow.process(); + let p2 = flow.process(); + hydroflow_plus_template::first_ten_distributed::first_ten_distributed(&p1, &p2); let _nodes = flow - .with_default_optimize() .with_process( &p1, TrybuildHost::new( diff --git a/template/hydroflow_plus/src/first_ten.rs b/template/hydroflow_plus/src/first_ten.rs new file mode 100644 index 000000000000..86fe2feb7528 --- /dev/null +++ b/template/hydroflow_plus/src/first_ten.rs @@ -0,0 +1,7 @@ +use hydroflow_plus::*; + +pub fn first_ten(process: &Process) { + process + .source_iter(q!(0..10)) + .for_each(q!(|n| println!("{}", n))); +} diff --git a/template/hydroflow_plus/src/first_ten_cluster.rs b/template/hydroflow_plus/src/first_ten_cluster.rs new file mode 100644 index 000000000000..f328d3b860e8 --- /dev/null +++ b/template/hydroflow_plus/src/first_ten_cluster.rs @@ -0,0 +1,55 @@ +use hydroflow_plus::*; + +pub struct Leader {} +pub struct Worker {} + +pub fn first_ten_cluster<'a>(leader: &Process<'a, Leader>, workers: &Cluster<'a, Worker>) { + leader + .source_iter(q!(0..10)) // : Stream, ...> + .round_robin_bincode(workers) // : Stream, ...> + .map(q!(|n| n * 2)) // : Stream, ...> + .inspect(q!(|n| println!("{}", n))) // : Stream, ...> + .send_bincode_interleaved(leader) // : Stream, ...> + .for_each(q!(|n| println!("{}", n))); +} + +#[cfg(test)] +mod tests { + use hydro_deploy::Deployment; + use hydroflow_plus::deploy::DeployCrateWrapper; + use hydroflow_plus::hydroflow::futures::StreamExt; + use tokio_stream::wrappers::UnboundedReceiverStream; + + #[tokio::test] + async fn first_ten_cluster() { + let mut deployment = Deployment::new(); + let localhost = deployment.Localhost(); + + let flow = hydroflow_plus::FlowBuilder::new(); + let leader = flow.process(); + let workers = flow.cluster(); + super::first_ten_cluster(&leader, &workers); + + let nodes = flow + .with_process(&leader, localhost.clone()) + .with_cluster(&workers, vec![localhost.clone(); 4]) + .deploy(&mut deployment); + + deployment.deploy().await.unwrap(); + + let leader_stdout = nodes.get_process(&leader).stdout().await; + + deployment.start().await.unwrap(); + + let mut out = UnboundedReceiverStream::new(leader_stdout) + .take(10) + .collect::>() + .await; + out.sort(); + + let mut expected = vec!["0", "2", "4", "6", "8", "10", "12", "14", "16", "18"]; + expected.sort(); + + assert_eq!(out, expected); + } +} diff --git a/template/hydroflow_plus/src/first_ten_distributed.rs b/template/hydroflow_plus/src/first_ten_distributed.rs index 5fb1c4b48fff..6445b392b769 100644 --- a/template/hydroflow_plus/src/first_ten_distributed.rs +++ b/template/hydroflow_plus/src/first_ten_distributed.rs @@ -1,26 +1,19 @@ use hydroflow_plus::*; -use stageleft::*; pub struct P1 {} pub struct P2 {} -pub fn first_ten_distributed<'a>(flow: &FlowBuilder<'a>) -> (Process<'a, P1>, Process<'a, P2>) { - let process = flow.process::(); - let second_process = flow.process::(); - - let numbers = process.source_iter(q!(0..10)); - numbers - .send_bincode(&second_process) +pub fn first_ten_distributed<'a>(p1: &Process<'a, P1>, p2: &Process<'a, P2>) { + p1.source_iter(q!(0..10)) // : Stream, ...> + .send_bincode(p2) // : Stream, ...> .for_each(q!(|n| println!("{}", n))); - - (process, second_process) } #[cfg(test)] mod tests { use hydro_deploy::Deployment; - use hydroflow_plus::deploy::{DeployCrateWrapper, TrybuildHost}; - use hydroflow_plus::futures::StreamExt; + use hydroflow_plus::deploy::DeployCrateWrapper; + use hydroflow_plus::hydroflow::futures::StreamExt; use tokio_stream::wrappers::UnboundedReceiverStream; #[tokio::test] @@ -29,12 +22,13 @@ mod tests { let localhost = deployment.Localhost(); let flow = hydroflow_plus::FlowBuilder::new(); - let (p1, p2) = super::first_ten_distributed(&flow); + let p1 = flow.process(); + let p2 = flow.process(); + super::first_ten_distributed(&p1, &p2); let nodes = flow - .with_default_optimize() - .with_process(&p1, TrybuildHost::new(localhost.clone())) - .with_process(&p2, TrybuildHost::new(localhost.clone())) + .with_process(&p1, localhost.clone()) + .with_process(&p2, localhost.clone()) .deploy(&mut deployment); deployment.deploy().await.unwrap(); diff --git a/template/hydroflow_plus/src/lib.rs b/template/hydroflow_plus/src/lib.rs index 17e53184ca7e..4e3abdc4f4cf 100644 --- a/template/hydroflow_plus/src/lib.rs +++ b/template/hydroflow_plus/src/lib.rs @@ -1,3 +1,5 @@ stageleft::stageleft_no_entry_crate!(); +pub mod first_ten; +pub mod first_ten_cluster; pub mod first_ten_distributed; diff --git a/variadics/CHANGELOG.md b/variadics/CHANGELOG.md index 404186fd5224..6dafc30d06b7 100644 --- a/variadics/CHANGELOG.md +++ b/variadics/CHANGELOG.md @@ -5,8 +5,83 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.0.7 (2024-11-08) + +### Chore + + - update pinned rust version, clippy lints, remove some dead code + +### New Features + + - generalized hash trie indexes for relational tuples + Generalized Hash Tries are part of the SIGMOD '23 FreeJoin + [paper](https://dl.acm.org/doi/abs/10.1145/3589295) by + Wang/Willsey/Suciu. They provide a compressed ("factorized") + representation of relations. By operating in the factorized domain, join + algorithms can defer cross-products and achieve asymptotically optimal + performance. + + --------- + - additions to variadics including collection types + adds a number of features: + + collection types for variadics (sets, multisets) that allow search via + RefVars (variadic of refs) + into_option (convert a variadic to a variadic of options) + into_vec (convert a variadic to a variadic of vecs) + - additions to variadics including collection types + adds a number of features: + - collection types for variadics (sets, multisets) that allow search via + RefVars (variadic of refs) + - into_option (convert a variadic to a variadic of options) + - into_vec (convert a variadic to a variadic of vecs) + +### Style + + - fixes for nightly clippy + a couple few spurious `too_many_arguments` and a spurious + `zombie_processes` still on current nightly (`clippy 0.1.84 (4392847410 + 2024-10-21)`) + +### Test + + - ignore trybuild tests inconsistent on latest nightly + +### Commit Statistics + + + + - 7 commits contributed to the release. + - 69 days passed between releases. + - 6 commits were understood as [conventional](https://www.conventionalcommits.org). + - 6 unique issues were worked on: [#1444](https://github.com/hydro-project/hydroflow/issues/1444), [#1473](https://github.com/hydro-project/hydroflow/issues/1473), [#1474](https://github.com/hydro-project/hydroflow/issues/1474), [#1475](https://github.com/hydro-project/hydroflow/issues/1475), [#1503](https://github.com/hydro-project/hydroflow/issues/1503), [#1505](https://github.com/hydro-project/hydroflow/issues/1505) + +### Commit Details + + + +
view details + + * **[#1444](https://github.com/hydro-project/hydroflow/issues/1444)** + - Update pinned rust version, clippy lints, remove some dead code ([`d567760`](https://github.com/hydro-project/hydroflow/commit/d5677604e93c07a5392f4229af94a0b736eca382)) + * **[#1473](https://github.com/hydro-project/hydroflow/issues/1473)** + - Additions to variadics including collection types ([`8afd326`](https://github.com/hydro-project/hydroflow/commit/8afd3266dac43c04c3fc29065a13c9c9a6a55afe)) + * **[#1474](https://github.com/hydro-project/hydroflow/issues/1474)** + - Revert "feat: additions to variadics including collection types" ([`08c2af5`](https://github.com/hydro-project/hydroflow/commit/08c2af538821bbf460d2a52b4f0474082b5de7da)) + * **[#1475](https://github.com/hydro-project/hydroflow/issues/1475)** + - Additions to variadics including collection types ([`1c28259`](https://github.com/hydro-project/hydroflow/commit/1c2825942f8a326699a7fb68b5372b49918851b5)) + * **[#1503](https://github.com/hydro-project/hydroflow/issues/1503)** + - Generalized hash trie indexes for relational tuples ([`f7e740f`](https://github.com/hydro-project/hydroflow/commit/f7e740fb2ba36d0fcf3fd196d60333552911e3a4)) + * **[#1505](https://github.com/hydro-project/hydroflow/issues/1505)** + - Fixes for nightly clippy ([`47cb703`](https://github.com/hydro-project/hydroflow/commit/47cb703e771f7d1c451ceb9d185ada96410949da)) + * **Uncategorized** + - Ignore trybuild tests inconsistent on latest nightly ([`656ee32`](https://github.com/hydro-project/hydroflow/commit/656ee328c8710bce7370c851437a80ca3db46a5a)) +
+ ## 0.0.6 (2024-08-30) + + ### Chore - lower min dependency versions where possible, update `Cargo.lock` @@ -23,7 +98,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - - 2 commits contributed to the release. + - 3 commits contributed to the release. + - 38 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 unique issues were worked on: [#1367](https://github.com/hydro-project/hydroflow/issues/1367), [#1423](https://github.com/hydro-project/hydroflow/issues/1423) @@ -37,6 +113,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Allow `PartialEqVariadic::eq_ref` to take `AsRefVar`s with different lifetimes ([`43ff49d`](https://github.com/hydro-project/hydroflow/commit/43ff49d72789d78535717d2db04cf595cc511274)) * **[#1423](https://github.com/hydro-project/hydroflow/issues/1423)** - Lower min dependency versions where possible, update `Cargo.lock` ([`11af328`](https://github.com/hydro-project/hydroflow/commit/11af32828bab6e4a4264d2635ff71a12bb0bb778)) + * **Uncategorized** + - Release hydroflow_lang v0.9.0, hydroflow_datalog_core v0.9.0, hydroflow_datalog v0.9.0, hydroflow_deploy_integration v0.9.0, hydroflow_macro v0.9.0, lattices_macro v0.5.6, lattices v0.5.7, multiplatform_test v0.2.0, variadics v0.0.6, pusherator v0.0.8, hydroflow v0.9.0, stageleft_macro v0.3.0, stageleft v0.4.0, stageleft_tool v0.3.0, hydroflow_plus v0.9.0, hydro_deploy v0.9.0, hydro_cli v0.9.0, hydroflow_plus_deploy v0.9.0, safety bump 8 crates ([`0750117`](https://github.com/hydro-project/hydroflow/commit/0750117de7088c01a439b102adeb4c832889f171)) ## 0.0.5 (2024-07-23) @@ -65,6 +143,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 6 commits contributed to the release. + - 143 days passed between releases. - 5 commits were understood as [conventional](https://www.conventionalcommits.org). - 5 unique issues were worked on: [#1241](https://github.com/hydro-project/hydroflow/issues/1241), [#1245](https://github.com/hydro-project/hydroflow/issues/1245), [#1324](https://github.com/hydro-project/hydroflow/issues/1324), [#1325](https://github.com/hydro-project/hydroflow/issues/1325), [#1352](https://github.com/hydro-project/hydroflow/issues/1352) @@ -108,6 +187,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 4 commits contributed to the release. + - 32 days passed between releases. - 3 commits were understood as [conventional](https://www.conventionalcommits.org). - 0 issues like '(#ID)' were seen in commit messages @@ -149,6 +229,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 3 commits contributed to the release. + - 253 days passed between releases. - 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#974](https://github.com/hydro-project/hydroflow/issues/974) @@ -178,6 +259,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 2 commits contributed to the release. + - 25 days passed between releases. - 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 unique issue was worked on: [#660](https://github.com/hydro-project/hydroflow/issues/660) diff --git a/variadics/Cargo.toml b/variadics/Cargo.toml index 182161686148..0198c897ba6f 100644 --- a/variadics/Cargo.toml +++ b/variadics/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "variadics" publish = true -version = "0.0.6" +version = "0.0.7" edition = "2021" license = "Apache-2.0" documentation = "https://docs.rs/variadics/" diff --git a/variadics/src/lib.rs b/variadics/src/lib.rs index bd0de27a1a3f..ad08b9fe0a9b 100644 --- a/variadics/src/lib.rs +++ b/variadics/src/lib.rs @@ -209,7 +209,10 @@ where { const LEN: usize = 1 + Rest::LEN; - type Extend = (Item, Rest::Extend) where Suffix: VariadicExt; + type Extend + = (Item, Rest::Extend) + where + Suffix: VariadicExt; fn extend(self, suffix: Suffix) -> Self::Extend where Suffix: VariadicExt, @@ -232,7 +235,8 @@ where out2 } - type AsRefVar<'a> = (&'a Item, Rest::AsRefVar<'a>) + type AsRefVar<'a> + = (&'a Item, Rest::AsRefVar<'a>) where Self: 'a; fn as_ref_var(&self) -> Self::AsRefVar<'_> { @@ -240,7 +244,8 @@ where (item, rest.as_ref_var()) } - type AsMutVar<'a> = (&'a mut Item, Rest::AsMutVar<'a>) + type AsMutVar<'a> + = (&'a mut Item, Rest::AsMutVar<'a>) where Self: 'a; fn as_mut_var(&mut self) -> Self::AsMutVar<'_> { @@ -248,7 +253,8 @@ where (item, rest.as_mut_var()) } - type IterAnyRef<'a> = std::iter::Chain, Rest::IterAnyRef<'a>> + type IterAnyRef<'a> + = std::iter::Chain, Rest::IterAnyRef<'a>> where Self: 'static; fn iter_any_ref(&self) -> Self::IterAnyRef<'_> @@ -260,7 +266,8 @@ where std::iter::once(item).chain(rest.iter_any_ref()) } - type IterAnyMut<'a> = std::iter::Chain, Rest::IterAnyMut<'a>> + type IterAnyMut<'a> + = std::iter::Chain, Rest::IterAnyMut<'a>> where Self: 'static; fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_> @@ -289,7 +296,10 @@ where impl VariadicExt for () { const LEN: usize = 0; - type Extend = Suffix where Suffix: VariadicExt; + type Extend + = Suffix + where + Suffix: VariadicExt; fn extend(self, suffix: Suffix) -> Self::Extend where Suffix: VariadicExt, @@ -307,7 +317,8 @@ impl VariadicExt for () { type AsMutVar<'a> = (); fn as_mut_var(&mut self) -> Self::AsMutVar<'_> {} - type IterAnyRef<'a> = std::iter::Empty<&'a dyn Any> + type IterAnyRef<'a> + = std::iter::Empty<&'a dyn Any> where Self: 'static; fn iter_any_ref(&self) -> Self::IterAnyRef<'_> @@ -317,7 +328,8 @@ impl VariadicExt for () { std::iter::empty() } - type IterAnyMut<'a> = std::iter::Empty<&'a mut dyn Any> + type IterAnyMut<'a> + = std::iter::Empty<&'a mut dyn Any> where Self: 'static; fn iter_any_mut(&mut self) -> Self::IterAnyMut<'_> @@ -820,7 +832,10 @@ where std::iter::zip(this, rest.into_zip()) } - type Drain<'a> = std::iter::Zip, Rest::Drain<'a>> where Self: 'a; + type Drain<'a> + = std::iter::Zip, Rest::Drain<'a>> + where + Self: 'a; fn drain(&mut self, range: R) -> Self::Drain<'_> where R: std::ops::RangeBounds + Clone, @@ -849,7 +864,10 @@ impl VecVariadic for var_type!() { std::iter::repeat(var_expr!()) } - type Drain<'a> = std::iter::Repeat where Self: 'a; + type Drain<'a> + = std::iter::Repeat + where + Self: 'a; fn drain(&mut self, _range: R) -> Self::Drain<'_> where R: std::ops::RangeBounds, diff --git a/variadics/src/variadic_collections.rs b/variadics/src/variadic_collections.rs index 1a1fa28b6de6..5dcc8fb923a4 100644 --- a/variadics/src/variadic_collections.rs +++ b/variadics/src/variadic_collections.rs @@ -6,7 +6,7 @@ use hashbrown::hash_table::{Entry, HashTable}; use crate::{PartialEqVariadic, VariadicExt, VecVariadic}; /// Trait for a set of Variadic Tuples -pub trait VariadicCollection { +pub trait VariadicCollection: Extend { /// The Schema (aka Variadic type) associated with tuples in this set type Schema: PartialEqVariadic; @@ -58,7 +58,7 @@ impl Default for VariadicHashSet { impl fmt::Debug for VariadicHashSet where - T: fmt::Debug + VariadicExt + PartialEqVariadic, + T: fmt::Debug + VariadicExt + PartialEqVariadic + Eq + Hash, for<'a> T::AsRefVar<'a>: Hash + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -82,7 +82,7 @@ where } impl VariadicCollection for VariadicHashSet where - T: VariadicExt + PartialEqVariadic, + T: VariadicExt + PartialEqVariadic + Eq + Hash, for<'a> T::AsRefVar<'a>: Hash, S: BuildHasher, { @@ -127,7 +127,7 @@ where } impl VariadicSet for VariadicHashSet where - T: VariadicExt + PartialEqVariadic, + T: VariadicExt + PartialEqVariadic + Eq + Hash, for<'a> T::AsRefVar<'a>: Hash, S: BuildHasher, { @@ -283,7 +283,7 @@ where impl VariadicCollection for VariadicCountedHashSet where - K: VariadicExt + PartialEqVariadic + Hash + Clone, + K: VariadicExt + PartialEqVariadic + Eq + Hash + Clone, for<'a> K::AsRefVar<'a>: Hash, S: BuildHasher, { @@ -333,7 +333,7 @@ where impl VariadicMultiset for VariadicCountedHashSet where - K: VariadicExt + PartialEqVariadic + Hash + Clone, + K: VariadicExt + PartialEqVariadic + Eq + Hash + Clone, for<'a> K::AsRefVar<'a>: Hash, S: BuildHasher, { @@ -356,6 +356,7 @@ where } /// Iterator helper for [`VariadicCountedHashSet::into_iter`]. +#[derive(Clone)] pub struct DuplicateCounted { iter: Iter, state: Option<(Item, usize)>, @@ -474,9 +475,10 @@ where /// Column storage for Variadic tuples of type Schema /// An alternative to VariadicHashMultiset +#[derive(Clone)] pub struct VariadicColumnMultiset where - Schema: VariadicExt, + Schema: VariadicExt + Eq + Hash, { columns: Schema::IntoVec, last_offset: usize, @@ -484,7 +486,7 @@ where impl VariadicColumnMultiset where - T: VariadicExt, + T: VariadicExt + Eq + Hash, { /// initialize an empty columnar multiset pub fn new() -> Self { @@ -497,7 +499,7 @@ where impl Default for VariadicColumnMultiset where - T: VariadicExt, + T: VariadicExt + Eq + Hash, { fn default() -> Self { Self::new() @@ -506,7 +508,8 @@ where impl VariadicCollection for VariadicColumnMultiset where - Schema: PartialEqVariadic, + Schema: PartialEqVariadic + Eq + Hash, + for<'a> ::AsRefVar<'a>: Hash, { type Schema = Schema; @@ -543,11 +546,16 @@ where } } -impl VariadicMultiset for VariadicColumnMultiset where Schema: PartialEqVariadic {} +impl VariadicMultiset for VariadicColumnMultiset +where + Schema: PartialEqVariadic + Eq + Hash, + for<'a> ::AsRefVar<'a>: Hash, +{ +} impl fmt::Debug for VariadicColumnMultiset where - T: fmt::Debug + VariadicExt + PartialEqVariadic, + T: fmt::Debug + VariadicExt + PartialEqVariadic + Eq + Hash, for<'a> T::AsRefVar<'a>: Hash + fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -557,7 +565,7 @@ where impl IntoIterator for VariadicColumnMultiset where - Schema: PartialEqVariadic, + Schema: PartialEqVariadic + Eq + Hash, { type Item = Schema; type IntoIter = ::IntoZip; diff --git a/variadics/tests/boxed_refed.rs b/variadics/tests/boxed_refed.rs index 17366b177dc5..8d7e44fc9f5c 100644 --- a/variadics/tests/boxed_refed.rs +++ b/variadics/tests/boxed_refed.rs @@ -29,7 +29,8 @@ impl Refed for (Item, Rest) where Rest: Refed, { - type Refed<'a> = (&'a Item, Rest::Refed<'a>) + type Refed<'a> + = (&'a Item, Rest::Refed<'a>) where Self: 'a; fn refed(&self) -> Self::Refed<'_> { diff --git a/variadics/tests/compile-fail/var_expr_missing_comma.rs b/variadics/tests/compile-fail/var_expr_missing_comma.rs.ignore similarity index 100% rename from variadics/tests/compile-fail/var_expr_missing_comma.rs rename to variadics/tests/compile-fail/var_expr_missing_comma.rs.ignore diff --git a/variadics_macro/CHANGELOG.md b/variadics_macro/CHANGELOG.md new file mode 100644 index 000000000000..737a1cf26547 --- /dev/null +++ b/variadics_macro/CHANGELOG.md @@ -0,0 +1,34 @@ + + +## v0.5.5 (2024-11-08) + +### New Features + + - generalized hash trie indexes for relational tuples + Generalized Hash Tries are part of the SIGMOD '23 FreeJoin + [paper](https://dl.acm.org/doi/abs/10.1145/3589295) by + Wang/Willsey/Suciu. They provide a compressed ("factorized") + representation of relations. By operating in the factorized domain, join + algorithms can defer cross-products and achieve asymptotically optimal + performance. + + --------- + +### Commit Statistics + + + + - 1 commit contributed to the release. + - 1 commit was understood as [conventional](https://www.conventionalcommits.org). + - 1 unique issue was worked on: [#1503](https://github.com/hydro-project/hydroflow/issues/1503) + +### Commit Details + + + +
view details + + * **[#1503](https://github.com/hydro-project/hydroflow/issues/1503)** + - Generalized hash trie indexes for relational tuples ([`f7e740f`](https://github.com/hydro-project/hydroflow/commit/f7e740fb2ba36d0fcf3fd196d60333552911e3a4)) +
+ diff --git a/variadics_macro/Cargo.toml b/variadics_macro/Cargo.toml new file mode 100644 index 000000000000..df2ad67be93e --- /dev/null +++ b/variadics_macro/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "variadics_macro" +publish = true +version = "0.5.5" +edition = "2021" +license = "Apache-2.0" +documentation = "https://docs.rs/variadics/" +description = "Procedural macros for the `variadics` crate." + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.63" +proc-macro-crate = "1.1.0" +quote = "1.0.0" +syn = { version = "2.0.0", features = [ "full", "parsing", "visit-mut" ] } +variadics = { path = "../variadics", version = "^0.0.7" } + +[dev-dependencies] +insta = "1.7.1" +prettyplease = "0.2.20" diff --git a/variadics_macro/README.md b/variadics_macro/README.md new file mode 100644 index 000000000000..5f2c0e520895 --- /dev/null +++ b/variadics_macro/README.md @@ -0,0 +1,17 @@ +## `tuple!` Macro + +Create a tuple from a Variadic type known at compile time. + +Example usage: +```rust +use variadics::var_expr; +use variadics_macro::tuple; + +let tup = var_expr!(1, 2, 3, "four"); +let a = tuple!(tup, 4); +assert_eq!(a, (1, 2, 3, "four")); + +let tup = var_expr!(1, 2, var_expr!(3)); +let b = tuple!(tup, 3); +assert_eq!(b, (1, 2, (3, ()))); +``` \ No newline at end of file diff --git a/variadics_macro/src/lib.rs b/variadics_macro/src/lib.rs new file mode 100644 index 000000000000..2583b3584268 --- /dev/null +++ b/variadics_macro/src/lib.rs @@ -0,0 +1,47 @@ +#![doc = include_str!("../README.md")] +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro2::Ident; +use quote::{format_ident, quote}; +use syn::parse::{Parse, ParseStream}; +use syn::{parse_macro_input, LitInt}; + +struct InputLen { + input: Ident, + len: LitInt, +} + +impl Parse for InputLen { + fn parse(ts: ParseStream) -> syn::Result { + let input = ts.parse()?; + ts.parse::()?; + let len = ts.parse()?; + Ok(InputLen { input, len }) + } +} + +#[proc_macro] +pub fn tuple(ts: TokenStream) -> TokenStream { + let InputLen { input, len } = parse_macro_input!(ts as InputLen); + let len = len.base10_parse::().unwrap(); + let pattern = (0..len) + .rev() + .map(|i| format_ident!("x{}", i)) + .fold(quote! { () }, |rest, item| quote! { (#item, #rest) }); + let idents = (0..len).map(|i| format_ident!("x{}", i)); + let tuple = quote! { + ( #( #idents, )* ) + }; + + // Create the assignment statement + let expanded = quote! { + { + let #pattern = #input; + let retval = #tuple; + retval + } + }; + + expanded.into() +}